about summary refs log tree commit diff
diff options
context:
space:
mode:
authorTsukasa OI <floss_rust@irq.a4lg.com>2025-05-31 12:27:22 +0000
committerAmanieu d'Antras <amanieu@gmail.com>2025-06-01 22:58:42 +0000
commitbc4333545a01502aed7c059f75789fd2d01757b3 (patch)
treebeb8be93fcd127d6ce46d8f41b7f0e052b1bf4a6
parent52115419a3504ba7b3e17e679b5a96d6080ba18b (diff)
downloadrust-bc4333545a01502aed7c059f75789fd2d01757b3.tar.gz
rust-bc4333545a01502aed7c059f75789fd2d01757b3.zip
RISC-V: Linux 6.15 `riscv_hwprobe` support
This commit adds support for `riscv_hwprobe` on the Linux kernel 6.15.
It adds feature detection of 8 extensions (4 of them are new in this).

Existing RISC-V Extensions:

1.  "Zicntr"
2.  "Zihpm"
3.  "Zalrsc"
4.  "Zaamo"

New RISC-V Extensions:

5.  "Zicbom"
6.  "Zfbfmin"
7.  "Zvfbfmin"
8.  "Zvfbfwma"
-rw-r--r--library/stdarch/crates/std_detect/src/detect/arch/riscv.rs12
-rw-r--r--library/stdarch/crates/std_detect/src/detect/os/linux/riscv.rs23
-rw-r--r--library/stdarch/crates/std_detect/src/detect/os/riscv.rs3
-rw-r--r--library/stdarch/crates/std_detect/tests/cpu-detection.rs4
4 files changed, 39 insertions, 3 deletions
diff --git a/library/stdarch/crates/std_detect/src/detect/arch/riscv.rs b/library/stdarch/crates/std_detect/src/detect/arch/riscv.rs
index 1eaae9a9c2f..b86190d7bbf 100644
--- a/library/stdarch/crates/std_detect/src/detect/arch/riscv.rs
+++ b/library/stdarch/crates/std_detect/src/detect/arch/riscv.rs
@@ -63,6 +63,7 @@ features! {
     ///   * Zve64x: `"zve64x"`
     ///   * Zve64f: `"zve64f"`
     ///   * Zve64d: `"zve64d"`
+    /// * Zicbom: `"zicbom"`
     /// * Zicboz: `"zicboz"`
     /// * Zicntr: `"zicntr"`
     /// * Zicond: `"zicond"`
@@ -75,6 +76,7 @@ features! {
     /// * Zacas: `"zacas"`
     /// * Zawrs: `"zawrs"`
     /// * Zfa: `"zfa"`
+    /// * Zfbfmin: `"zfbfmin"`
     /// * Zfh: `"zfh"`
     ///   * Zfhmin: `"zfhmin"`
     /// * Zfinx: `"zfinx"`
@@ -99,6 +101,8 @@ features! {
     /// * Zkt: `"zkt"`
     /// * Zvbb: `"zvbb"`
     /// * Zvbc: `"zvbc"`
+    /// * Zvfbfmin: `"zvfbfmin"`
+    /// * Zvfbfwma: `"zvfbfwma"`
     /// * Zvfh: `"zvfh"`
     ///   * Zvfhmin: `"zvfhmin"`
     /// * Zvkb: `"zvkb"`
@@ -173,6 +177,8 @@ features! {
     /// "Zihintpause" Extension for Pause Hint
     @FEATURE: #[unstable(feature = "stdarch_riscv_feature_detection", issue = "111192")] zimop: "zimop";
     /// "Zimop" Extension for May-Be-Operations
+    @FEATURE: #[unstable(feature = "stdarch_riscv_feature_detection", issue = "111192")] zicbom: "zicbom";
+    /// "Zicbom" Extension for Cache-Block Management Instructions
     @FEATURE: #[unstable(feature = "stdarch_riscv_feature_detection", issue = "111192")] zicboz: "zicboz";
     /// "Zicboz" Extension for Cache-Block Zero Instruction
     @FEATURE: #[unstable(feature = "stdarch_riscv_feature_detection", issue = "111192")] zicond: "zicond";
@@ -210,6 +216,8 @@ features! {
     /// "Zfhmin" Extension for Minimal Half-Precision Floating-Point
     @FEATURE: #[unstable(feature = "stdarch_riscv_feature_detection", issue = "111192")] zfa: "zfa";
     /// "Zfa" Extension for Additional Floating-Point Instructions
+    @FEATURE: #[unstable(feature = "stdarch_riscv_feature_detection", issue = "111192")] zfbfmin: "zfbfmin";
+    /// "Zfbfmin" Extension for Scalar BF16 Converts
 
     @FEATURE: #[unstable(feature = "stdarch_riscv_feature_detection", issue = "111192")] zfinx: "zfinx";
     /// "Zfinx" Extension for Single-Precision Floating-Point in Integer Registers
@@ -289,6 +297,10 @@ features! {
     /// "Zvfh" Vector Extension for Half-Precision Floating-Point
     @FEATURE: #[unstable(feature = "stdarch_riscv_feature_detection", issue = "111192")] zvfhmin: "zvfhmin";
     /// "Zvfhmin" Vector Extension for Minimal Half-Precision Floating-Point
+    @FEATURE: #[unstable(feature = "stdarch_riscv_feature_detection", issue = "111192")] zvfbfmin: "zvfbfmin";
+    /// "Zvfbfmin" Vector Extension for BF16 Converts
+    @FEATURE: #[unstable(feature = "stdarch_riscv_feature_detection", issue = "111192")] zvfbfwma: "zvfbfwma";
+    /// "Zvfbfwma" Vector Extension for BF16 Widening Multiply-Add
 
     @FEATURE: #[unstable(feature = "stdarch_riscv_feature_detection", issue = "111192")] zvbb: "zvbb";
     /// "Zvbb" Extension for Vector Basic Bit-Manipulation
diff --git a/library/stdarch/crates/std_detect/src/detect/os/linux/riscv.rs b/library/stdarch/crates/std_detect/src/detect/os/linux/riscv.rs
index b836724dca3..5506ff31fc7 100644
--- a/library/stdarch/crates/std_detect/src/detect/os/linux/riscv.rs
+++ b/library/stdarch/crates/std_detect/src/detect/os/linux/riscv.rs
@@ -10,13 +10,13 @@ use super::super::riscv::imply_features;
 use super::auxvec;
 use crate::detect::{Feature, bit, cache};
 
-// See <https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/include/uapi/linux/prctl.h?h=v6.14>
+// See <https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/include/uapi/linux/prctl.h?h=v6.15>
 // for runtime status query constants.
 const PR_RISCV_V_GET_CONTROL: libc::c_int = 70;
 const PR_RISCV_V_VSTATE_CTRL_ON: libc::c_int = 2;
 const PR_RISCV_V_VSTATE_CTRL_CUR_MASK: libc::c_int = 3;
 
-// See <https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/arch/riscv/include/uapi/asm/hwprobe.h?h=v6.14>
+// See <https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/arch/riscv/include/uapi/asm/hwprobe.h?h=v6.15>
 // for riscv_hwprobe struct and hardware probing constants.
 
 #[repr(C)]
@@ -83,6 +83,14 @@ const RISCV_HWPROBE_EXT_ZCMOP: u64 = 1 << 47;
 const RISCV_HWPROBE_EXT_ZAWRS: u64 = 1 << 48;
 // Excluded because it only reports the existence of `prctl`-based pointer masking control.
 // const RISCV_HWPROBE_EXT_SUPM: u64 = 1 << 49;
+const RISCV_HWPROBE_EXT_ZICNTR: u64 = 1 << 50;
+const RISCV_HWPROBE_EXT_ZIHPM: u64 = 1 << 51;
+const RISCV_HWPROBE_EXT_ZFBFMIN: u64 = 1 << 52;
+const RISCV_HWPROBE_EXT_ZVFBFMIN: u64 = 1 << 53;
+const RISCV_HWPROBE_EXT_ZVFBFWMA: u64 = 1 << 54;
+const RISCV_HWPROBE_EXT_ZICBOM: u64 = 1 << 55;
+const RISCV_HWPROBE_EXT_ZAAMO: u64 = 1 << 56;
+const RISCV_HWPROBE_EXT_ZALRSC: u64 = 1 << 57;
 
 const RISCV_HWPROBE_KEY_CPUPERF_0: i64 = 5;
 const RISCV_HWPROBE_MISALIGNED_FAST: u64 = 3;
@@ -133,7 +141,7 @@ pub(crate) fn detect_features() -> cache::Initializer {
     // Use auxiliary vector to enable single-letter ISA extensions.
     // The values are part of the platform-specific [asm/hwcap.h][hwcap]
     //
-    // [hwcap]: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/arch/riscv/include/uapi/asm/hwcap.h?h=v6.14
+    // [hwcap]: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/arch/riscv/include/uapi/asm/hwcap.h?h=v6.15
     let auxv = auxvec::auxv().expect("read auxvec"); // should not fail on RISC-V platform
     let mut has_i = bit::test(auxv.hwcap, (b'i' - b'a').into());
     #[allow(clippy::eq_op)]
@@ -221,12 +229,18 @@ pub(crate) fn detect_features() -> cache::Initializer {
         enable_feature(Feature::d, test(RISCV_HWPROBE_IMA_FD)); // F is implied.
         enable_feature(Feature::c, test(RISCV_HWPROBE_IMA_C));
 
+        enable_feature(Feature::zicntr, test(RISCV_HWPROBE_EXT_ZICNTR));
+        enable_feature(Feature::zihpm, test(RISCV_HWPROBE_EXT_ZIHPM));
+
         enable_feature(Feature::zihintntl, test(RISCV_HWPROBE_EXT_ZIHINTNTL));
         enable_feature(Feature::zihintpause, test(RISCV_HWPROBE_EXT_ZIHINTPAUSE));
         enable_feature(Feature::zimop, test(RISCV_HWPROBE_EXT_ZIMOP));
+        enable_feature(Feature::zicbom, test(RISCV_HWPROBE_EXT_ZICBOM));
         enable_feature(Feature::zicboz, test(RISCV_HWPROBE_EXT_ZICBOZ));
         enable_feature(Feature::zicond, test(RISCV_HWPROBE_EXT_ZICOND));
 
+        enable_feature(Feature::zalrsc, test(RISCV_HWPROBE_EXT_ZALRSC));
+        enable_feature(Feature::zaamo, test(RISCV_HWPROBE_EXT_ZAAMO));
         enable_feature(Feature::zawrs, test(RISCV_HWPROBE_EXT_ZAWRS));
         enable_feature(Feature::zacas, test(RISCV_HWPROBE_EXT_ZACAS));
         enable_feature(Feature::ztso, test(RISCV_HWPROBE_EXT_ZTSO));
@@ -255,6 +269,7 @@ pub(crate) fn detect_features() -> cache::Initializer {
         enable_feature(Feature::zfh, test(RISCV_HWPROBE_EXT_ZFH));
         enable_feature(Feature::zfhmin, test(RISCV_HWPROBE_EXT_ZFHMIN));
         enable_feature(Feature::zfa, test(RISCV_HWPROBE_EXT_ZFA));
+        enable_feature(Feature::zfbfmin, test(RISCV_HWPROBE_EXT_ZFBFMIN));
 
         // Use prctl (if any) to determine whether the vector extension
         // is enabled on the current thread (assuming the entire process
@@ -290,6 +305,8 @@ pub(crate) fn detect_features() -> cache::Initializer {
 
             enable_feature(Feature::zvfh, test(RISCV_HWPROBE_EXT_ZVFH));
             enable_feature(Feature::zvfhmin, test(RISCV_HWPROBE_EXT_ZVFHMIN));
+            enable_feature(Feature::zvfbfmin, test(RISCV_HWPROBE_EXT_ZVFBFMIN));
+            enable_feature(Feature::zvfbfwma, test(RISCV_HWPROBE_EXT_ZVFBFWMA));
         }
         is_v_set = true;
     };
diff --git a/library/stdarch/crates/std_detect/src/detect/os/riscv.rs b/library/stdarch/crates/std_detect/src/detect/os/riscv.rs
index 97496df8938..4c59ede8029 100644
--- a/library/stdarch/crates/std_detect/src/detect/os/riscv.rs
+++ b/library/stdarch/crates/std_detect/src/detect/os/riscv.rs
@@ -105,6 +105,8 @@ pub(crate) fn imply_features(mut value: cache::Initializer) -> cache::Initialize
         imply!(zvfh => zvfhmin); // functional
         imply!(zvfh => zve32f & zfhmin);
         imply!(zvfhmin => zve32f);
+        imply!(zvfbfwma => zvfbfmin & zfbfmin);
+        imply!(zvfbfmin => zve32f);
 
         imply!(v => zve64d);
         imply!(zve64d => zve64f & d);
@@ -115,6 +117,7 @@ pub(crate) fn imply_features(mut value: cache::Initializer) -> cache::Initialize
         imply!(zfh => zfhmin);
         imply!(q => d);
         imply!(d | zfhmin | zfa => f);
+        imply!(zfbfmin => f); // and some of (not all) "Zfh" instructions.
 
         // Relatively complex implication rules from the "C" extension.
         imply!(c => zca);
diff --git a/library/stdarch/crates/std_detect/tests/cpu-detection.rs b/library/stdarch/crates/std_detect/tests/cpu-detection.rs
index bbc289a6a0a..7976aedc758 100644
--- a/library/stdarch/crates/std_detect/tests/cpu-detection.rs
+++ b/library/stdarch/crates/std_detect/tests/cpu-detection.rs
@@ -251,6 +251,7 @@ fn riscv_linux() {
     println!("zihintntl: {}", is_riscv_feature_detected!("zihintntl"));
     println!("zihintpause: {}", is_riscv_feature_detected!("zihintpause"));
     println!("zimop: {}", is_riscv_feature_detected!("zimop"));
+    println!("zicbom: {}", is_riscv_feature_detected!("zicbom"));
     println!("zicboz: {}", is_riscv_feature_detected!("zicboz"));
     println!("zicond: {}", is_riscv_feature_detected!("zicond"));
     println!("m: {}", is_riscv_feature_detected!("m"));
@@ -267,6 +268,7 @@ fn riscv_linux() {
     println!("zfh: {}", is_riscv_feature_detected!("zfh"));
     println!("zfhmin: {}", is_riscv_feature_detected!("zfhmin"));
     println!("zfa: {}", is_riscv_feature_detected!("zfa"));
+    println!("zfbfmin: {}", is_riscv_feature_detected!("zfbfmin"));
     println!("zfinx: {}", is_riscv_feature_detected!("zfinx"));
     println!("zdinx: {}", is_riscv_feature_detected!("zdinx"));
     println!("zhinx: {}", is_riscv_feature_detected!("zhinx"));
@@ -303,6 +305,8 @@ fn riscv_linux() {
     println!("zve64d: {}", is_riscv_feature_detected!("zve64d"));
     println!("zvfh: {}", is_riscv_feature_detected!("zvfh"));
     println!("zvfhmin: {}", is_riscv_feature_detected!("zvfhmin"));
+    println!("zvfbfmin: {}", is_riscv_feature_detected!("zvfbfmin"));
+    println!("zvfbfwma: {}", is_riscv_feature_detected!("zvfbfwma"));
     println!("zvbb: {}", is_riscv_feature_detected!("zvbb"));
     println!("zvbc: {}", is_riscv_feature_detected!("zvbc"));
     println!("zvkb: {}", is_riscv_feature_detected!("zvkb"));