From d1d736c4e00d07ee646233de91520e3f9757f5c6 Mon Sep 17 00:00:00 2001 From: kianalikasana Date: Thu, 8 Oct 2026 10:53:17 +0800 Subject: [PATCH 1/3] Add safety sections to fxsave/xsave/bittest intrinsics --- crates/core_arch/src/x86/bt.rs | 28 ++++++++++++++ crates/core_arch/src/x86/fxsr.rs | 16 ++++++++ crates/core_arch/src/x86/xsave.rs | 58 ++++++++++++++++++++++++++++ crates/core_arch/src/x86_64/bt.rs | 28 ++++++++++++++ crates/core_arch/src/x86_64/fxsr.rs | 16 ++++++++ crates/core_arch/src/x86_64/xsave.rs | 46 ++++++++++++++++++++++ 6 files changed, 192 insertions(+) diff --git a/crates/core_arch/src/x86/bt.rs b/crates/core_arch/src/x86/bt.rs index 06cc2833f4..bd7477cec4 100644 --- a/crates/core_arch/src/x86/bt.rs +++ b/crates/core_arch/src/x86/bt.rs @@ -21,6 +21,13 @@ macro_rules! bt { /// Returns the bit in position `b` of the memory addressed by `p`. /// /// [Intel's documentation](https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_bittest) +/// +/// # Safety +/// +/// `p` must be valid for reads. `b` is a signed bit index: when it +/// falls outside the pointed-to integer, the instruction accesses +/// the word at `p + (b / bits) * (bits / 8)`, and that address must +/// be valid for reads as well. #[inline] #[cfg_attr(test, assert_instr(bt))] #[stable(feature = "simd_x86_bittest", since = "1.55.0")] @@ -40,6 +47,13 @@ pub unsafe fn _bittest(p: *const i32, b: i32) -> u8 { /// Returns the bit in position `b` of the memory addressed by `p`, then sets the bit to `1`. /// /// [Intel's documentation](https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_bittestandset) +/// +/// # Safety +/// +/// `p` must be valid for reads and writes. `b` is a signed bit +/// index: when it falls outside the pointed-to integer, the +/// instruction accesses the word at `p + (b / bits) * (bits / 8)`, +/// and that address must be valid for read-modify-write as well. #[inline] #[cfg_attr(test, assert_instr(bts))] #[stable(feature = "simd_x86_bittest", since = "1.55.0")] @@ -59,6 +73,13 @@ pub unsafe fn _bittestandset(p: *mut i32, b: i32) -> u8 { /// Returns the bit in position `b` of the memory addressed by `p`, then resets that bit to `0`. /// /// [Intel's documentation](https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_bittestandreset) +/// +/// # Safety +/// +/// `p` must be valid for reads and writes. `b` is a signed bit +/// index: when it falls outside the pointed-to integer, the +/// instruction accesses the word at `p + (b / bits) * (bits / 8)`, +/// and that address must be valid for read-modify-write as well. #[inline] #[cfg_attr(test, assert_instr(btr))] #[stable(feature = "simd_x86_bittest", since = "1.55.0")] @@ -78,6 +99,13 @@ pub unsafe fn _bittestandreset(p: *mut i32, b: i32) -> u8 { /// Returns the bit in position `b` of the memory addressed by `p`, then inverts that bit. /// /// [Intel's documentation](https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_bittestandcomplement) +/// +/// # Safety +/// +/// `p` must be valid for reads and writes. `b` is a signed bit +/// index: when it falls outside the pointed-to integer, the +/// instruction accesses the word at `p + (b / bits) * (bits / 8)`, +/// and that address must be valid for read-modify-write as well. #[inline] #[cfg_attr(test, assert_instr(btc))] #[stable(feature = "simd_x86_bittest", since = "1.55.0")] diff --git a/crates/core_arch/src/x86/fxsr.rs b/crates/core_arch/src/x86/fxsr.rs index ffac5cda0c..6e1391d055 100644 --- a/crates/core_arch/src/x86/fxsr.rs +++ b/crates/core_arch/src/x86/fxsr.rs @@ -23,6 +23,12 @@ unsafe extern "llvm-intrinsic" { /// [fxrstor]: http://www.felixcloutier.com/x86/FXRSTOR.html /// /// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_fxsave) +/// +/// # Safety +/// +/// `mem_addr` must be valid for writes of 512 bytes and must be +/// 16-byte aligned; misaligned stores raise a general-protection +/// (#GP) exception. #[inline] #[target_feature(enable = "fxsr")] #[cfg_attr(test, assert_instr(fxsave))] @@ -47,6 +53,16 @@ pub unsafe fn _fxsave(mem_addr: *mut u8) { /// [fxrstor]: http://www.felixcloutier.com/x86/FXRSTOR.html /// /// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_fxrstor) +/// +/// # Safety +/// +/// `mem_addr` must be valid for reads of 512 bytes and must be +/// 16-byte aligned. +/// +/// The 512 bytes at `mem_addr` must form a valid `FXSAVE`-format +/// image, e.g. one written by a prior `_fxsave`/`_fxsave64`. In +/// particular the `MXCSR` portion must hold a value legal for +/// `FXRSTOR`, otherwise the instruction raises a #GP. #[inline] #[target_feature(enable = "fxsr")] #[cfg_attr(test, assert_instr(fxrstor))] diff --git a/crates/core_arch/src/x86/xsave.rs b/crates/core_arch/src/x86/xsave.rs index cb0c83ecdf..86a9ad8321 100644 --- a/crates/core_arch/src/x86/xsave.rs +++ b/crates/core_arch/src/x86/xsave.rs @@ -34,6 +34,13 @@ unsafe extern "llvm-intrinsic" { /// Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 1. /// /// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_xsave) +/// +/// # Safety +/// +/// `mem_addr` must be valid for writes of the whole `XSAVE` area +/// required by `save_mask` and `XCR0` (at least 512 bytes plus the +/// enabled extended region, see the referenced Intel SDM section) +/// and must be 64-byte aligned. #[inline] #[target_feature(enable = "xsave")] #[cfg_attr(test, assert_instr(xsave))] @@ -50,6 +57,15 @@ pub unsafe fn _xsave(mem_addr: *mut u8, save_mask: u64) { /// boundary. /// /// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_xrstor) +/// +/// # Safety +/// +/// `mem_addr` must be valid for reads of the whole `XSAVE` area it +/// describes and must be 64-byte aligned. +/// +/// The memory must contain a valid `XSAVE` area produced by a prior +/// save (or otherwise matching the format in the referenced Intel +/// SDM section); restoring reserved or malformed state raises a #GP. #[inline] #[target_feature(enable = "xsave")] #[cfg_attr(test, assert_instr(xrstor))] @@ -70,6 +86,12 @@ pub const _XCR_XFEATURE_ENABLED_MASK: u32 = 0; /// Currently only `XFEATURE_ENABLED_MASK` `XCR` is supported. /// /// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_xsetbv) +/// +/// # Safety +/// +/// `a` must identify a supported extended control register +/// (currently only `XCR0`), and `val` must be a legal value for +/// that register (setting reserved bits raises a #GP). #[inline] #[target_feature(enable = "xsave")] #[cfg_attr(test, assert_instr(xsetbv))] @@ -82,6 +104,12 @@ pub unsafe fn _xsetbv(a: u32, val: u64) { /// specified in `xcr_no`. /// /// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_xgetbv) +/// +/// # Safety +/// +/// `xcr_no` must identify a supported extended control register +/// (currently only `XCR0`); reading an unsupported register raises +/// a #GP. #[inline] #[target_feature(enable = "xsave")] #[cfg_attr(test, assert_instr(xgetbv))] @@ -99,6 +127,13 @@ pub unsafe fn _xgetbv(xcr_no: u32) -> u64 { /// be equal to or better than using the `XSAVE` instruction. /// /// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_xsaveopt) +/// +/// # Safety +/// +/// `mem_addr` must be valid for writes of the whole `XSAVE` area +/// required by `save_mask` and `XCR0` (at least 512 bytes plus the +/// enabled extended region, see the referenced Intel SDM section) +/// and must be 64-byte aligned. #[inline] #[target_feature(enable = "xsave,xsaveopt")] #[cfg_attr(test, assert_instr(xsaveopt))] @@ -115,6 +150,13 @@ pub unsafe fn _xsaveopt(mem_addr: *mut u8, save_mask: u64) { /// and `XCR0`. `mem_addr` must be aligned on a 64-byte boundary. /// /// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_xsavec) +/// +/// # Safety +/// +/// `mem_addr` must be valid for writes of the whole `XSAVE` area +/// required by `save_mask` and `XCR0` (at least 512 bytes plus the +/// enabled extended region, see the referenced Intel SDM section) +/// and must be 64-byte aligned. #[inline] #[target_feature(enable = "xsave,xsavec")] #[cfg_attr(test, assert_instr(xsavec))] @@ -132,6 +174,13 @@ pub unsafe fn _xsavec(mem_addr: *mut u8, save_mask: u64) { /// and `XCR0`. `mem_addr` must be aligned on a 64-byte boundary. /// /// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_xsaves) +/// +/// # Safety +/// +/// `mem_addr` must be valid for writes of the whole `XSAVE` area +/// required by `save_mask` and `XCR0` (at least 512 bytes plus the +/// enabled extended region, see the referenced Intel SDM section) +/// and must be 64-byte aligned. #[inline] #[target_feature(enable = "xsave,xsaves")] #[cfg_attr(test, assert_instr(xsaves))] @@ -151,6 +200,15 @@ pub unsafe fn _xsaves(mem_addr: *mut u8, save_mask: u64) { /// boundary. /// /// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_xrstors) +/// +/// # Safety +/// +/// `mem_addr` must be valid for reads of the whole `XSAVE` area it +/// describes and must be 64-byte aligned. +/// +/// The memory must contain a valid `XSAVE` area produced by a prior +/// save (or otherwise matching the format in the referenced Intel +/// SDM section); restoring reserved or malformed state raises a #GP. #[inline] #[target_feature(enable = "xsave,xsaves")] #[cfg_attr(test, assert_instr(xrstors))] diff --git a/crates/core_arch/src/x86_64/bt.rs b/crates/core_arch/src/x86_64/bt.rs index f9aa3e16cc..84bd336621 100644 --- a/crates/core_arch/src/x86_64/bt.rs +++ b/crates/core_arch/src/x86_64/bt.rs @@ -21,6 +21,13 @@ macro_rules! bt { /// Returns the bit in position `b` of the memory addressed by `p`. /// /// [Intel's documentation](https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_bittest64) +/// +/// # Safety +/// +/// `p` must be valid for reads. `b` is a signed bit index: when it +/// falls outside the pointed-to integer, the instruction accesses +/// the word at `p + (b / bits) * (bits / 8)`, and that address must +/// be valid for reads as well. #[inline] #[cfg_attr(test, assert_instr(bt))] #[stable(feature = "simd_x86_bittest", since = "1.55.0")] @@ -40,6 +47,13 @@ pub unsafe fn _bittest64(p: *const i64, b: i64) -> u8 { /// Returns the bit in position `b` of the memory addressed by `p`, then sets the bit to `1`. /// /// [Intel's documentation](https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_bittestandset64) +/// +/// # Safety +/// +/// `p` must be valid for reads and writes. `b` is a signed bit +/// index: when it falls outside the pointed-to integer, the +/// instruction accesses the word at `p + (b / bits) * (bits / 8)`, +/// and that address must be valid for read-modify-write as well. #[inline] #[cfg_attr(test, assert_instr(bts))] #[stable(feature = "simd_x86_bittest", since = "1.55.0")] @@ -59,6 +73,13 @@ pub unsafe fn _bittestandset64(p: *mut i64, b: i64) -> u8 { /// Returns the bit in position `b` of the memory addressed by `p`, then resets that bit to `0`. /// /// [Intel's documentation](https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_bittestandreset64) +/// +/// # Safety +/// +/// `p` must be valid for reads and writes. `b` is a signed bit +/// index: when it falls outside the pointed-to integer, the +/// instruction accesses the word at `p + (b / bits) * (bits / 8)`, +/// and that address must be valid for read-modify-write as well. #[inline] #[cfg_attr(test, assert_instr(btr))] #[stable(feature = "simd_x86_bittest", since = "1.55.0")] @@ -78,6 +99,13 @@ pub unsafe fn _bittestandreset64(p: *mut i64, b: i64) -> u8 { /// Returns the bit in position `b` of the memory addressed by `p`, then inverts that bit. /// /// [Intel's documentation](https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_bittestandcomplement64) +/// +/// # Safety +/// +/// `p` must be valid for reads and writes. `b` is a signed bit +/// index: when it falls outside the pointed-to integer, the +/// instruction accesses the word at `p + (b / bits) * (bits / 8)`, +/// and that address must be valid for read-modify-write as well. #[inline] #[cfg_attr(test, assert_instr(btc))] #[stable(feature = "simd_x86_bittest", since = "1.55.0")] diff --git a/crates/core_arch/src/x86_64/fxsr.rs b/crates/core_arch/src/x86_64/fxsr.rs index 4710ea5a82..082616abe8 100644 --- a/crates/core_arch/src/x86_64/fxsr.rs +++ b/crates/core_arch/src/x86_64/fxsr.rs @@ -23,6 +23,12 @@ unsafe extern "llvm-intrinsic" { /// [fxrstor]: http://www.felixcloutier.com/x86/FXRSTOR.html /// /// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_fxsave64) +/// +/// # Safety +/// +/// `mem_addr` must be valid for writes of 512 bytes and must be +/// 16-byte aligned; misaligned stores raise a general-protection +/// (#GP) exception. #[inline] #[target_feature(enable = "fxsr")] #[cfg_attr(test, assert_instr(fxsave64))] @@ -47,6 +53,16 @@ pub unsafe fn _fxsave64(mem_addr: *mut u8) { /// [fxrstor]: http://www.felixcloutier.com/x86/FXRSTOR.html /// /// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_fxrstor64) +/// +/// # Safety +/// +/// `mem_addr` must be valid for reads of 512 bytes and must be +/// 16-byte aligned. +/// +/// The 512 bytes at `mem_addr` must form a valid `FXSAVE`-format +/// image, e.g. one written by a prior `_fxsave`/`_fxsave64`. In +/// particular the `MXCSR` portion must hold a value legal for +/// `FXRSTOR`, otherwise the instruction raises a #GP. #[inline] #[target_feature(enable = "fxsr")] #[cfg_attr(test, assert_instr(fxrstor64))] diff --git a/crates/core_arch/src/x86_64/xsave.rs b/crates/core_arch/src/x86_64/xsave.rs index 4b4768f9a5..955b64af31 100644 --- a/crates/core_arch/src/x86_64/xsave.rs +++ b/crates/core_arch/src/x86_64/xsave.rs @@ -31,6 +31,13 @@ unsafe extern "llvm-intrinsic" { /// Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 1. /// /// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_xsave64) +/// +/// # Safety +/// +/// `mem_addr` must be valid for writes of the whole `XSAVE` area +/// required by `save_mask` and `XCR0` (at least 512 bytes plus the +/// enabled extended region, see the referenced Intel SDM section) +/// and must be 64-byte aligned. #[inline] #[target_feature(enable = "xsave")] #[cfg_attr(test, assert_instr(xsave64))] @@ -47,6 +54,15 @@ pub unsafe fn _xsave64(mem_addr: *mut u8, save_mask: u64) { /// boundary. /// /// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_xrstor64) +/// +/// # Safety +/// +/// `mem_addr` must be valid for reads of the whole `XSAVE` area it +/// describes and must be 64-byte aligned. +/// +/// The memory must contain a valid `XSAVE` area produced by a prior +/// save (or otherwise matching the format in the referenced Intel +/// SDM section); restoring reserved or malformed state raises a #GP. #[inline] #[target_feature(enable = "xsave")] #[cfg_attr(test, assert_instr(xrstor64))] @@ -64,6 +80,13 @@ pub unsafe fn _xrstor64(mem_addr: *const u8, rs_mask: u64) { /// be equal to or better than using the `XSAVE64` instruction. /// /// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_xsaveopt64) +/// +/// # Safety +/// +/// `mem_addr` must be valid for writes of the whole `XSAVE` area +/// required by `save_mask` and `XCR0` (at least 512 bytes plus the +/// enabled extended region, see the referenced Intel SDM section) +/// and must be 64-byte aligned. #[inline] #[target_feature(enable = "xsave,xsaveopt")] #[cfg_attr(test, assert_instr(xsaveopt64))] @@ -80,6 +103,13 @@ pub unsafe fn _xsaveopt64(mem_addr: *mut u8, save_mask: u64) { /// and `XCR0`. `mem_addr` must be aligned on a 64-byte boundary. /// /// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_xsavec64) +/// +/// # Safety +/// +/// `mem_addr` must be valid for writes of the whole `XSAVE` area +/// required by `save_mask` and `XCR0` (at least 512 bytes plus the +/// enabled extended region, see the referenced Intel SDM section) +/// and must be 64-byte aligned. #[inline] #[target_feature(enable = "xsave,xsavec")] #[cfg_attr(test, assert_instr(xsavec64))] @@ -97,6 +127,13 @@ pub unsafe fn _xsavec64(mem_addr: *mut u8, save_mask: u64) { /// and `XCR0`. `mem_addr` must be aligned on a 64-byte boundary. /// /// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_xsaves64) +/// +/// # Safety +/// +/// `mem_addr` must be valid for writes of the whole `XSAVE` area +/// required by `save_mask` and `XCR0` (at least 512 bytes plus the +/// enabled extended region, see the referenced Intel SDM section) +/// and must be 64-byte aligned. #[inline] #[target_feature(enable = "xsave,xsaves")] #[cfg_attr(test, assert_instr(xsaves64))] @@ -116,6 +153,15 @@ pub unsafe fn _xsaves64(mem_addr: *mut u8, save_mask: u64) { /// boundary. /// /// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_xrstors64) +/// +/// # Safety +/// +/// `mem_addr` must be valid for reads of the whole `XSAVE` area it +/// describes and must be 64-byte aligned. +/// +/// The memory must contain a valid `XSAVE` area produced by a prior +/// save (or otherwise matching the format in the referenced Intel +/// SDM section); restoring reserved or malformed state raises a #GP. #[inline] #[target_feature(enable = "xsave,xsaves")] #[cfg_attr(test, assert_instr(xrstors64))] From 839f18d36aa15b58423358a23b248d6d722dac3b Mon Sep 17 00:00:00 2001 From: kianalikasana Date: Thu, 8 Oct 2026 11:28:36 +0800 Subject: [PATCH 2/3] Retry flaky CI job From 2853d85c6f6beccdc677f703bfb23d97df58f117 Mon Sep 17 00:00:00 2001 From: kianalikasana Date: Thu, 8 Oct 2026 17:10:38 +0800 Subject: [PATCH 3/3] Re-run CI