@@ -934,6 +934,16 @@ npy__cpu_init_features(void)
934934 // https://github.com/torvalds/linux/blob/v6.8/arch/riscv/include/uapi/asm/hwcap.h#L24
935935 #define COMPAT_HWCAP_ISA_V (1 << ('V' - 'A'))
936936 #endif
937+
938+ #ifdef __linux__
939+ #include <asm/unistd.h>
940+ #include <unistd.h>
941+
942+ #if defined(__has_include ) && __has_include (< asm /hwprobe .h > )
943+ #include <asm/hwprobe.h>
944+ #define HAS_RISCV_HWPROBE
945+ #endif
946+ #endif
937947#endif
938948
939949static void
@@ -942,15 +952,40 @@ npy__cpu_init_features(void)
942952 memset (npy__cpu_have , 0 , sizeof (npy__cpu_have [0 ]) * NPY_CPU_FEATURE_MAX );
943953#if defined(__linux__ ) || defined(__FreeBSD__ ) || defined(__OpenBSD__ )
944954#ifdef __linux__
955+ #ifdef HAS_RISCV_HWPROBE
956+ /*
957+ * RISCV_HWPROBE_IMA_V reports the ratified RVV 1.0 extension.
958+ * HWCAP's V bit may also be set for pre-standard vector extensions,
959+ * so prefer hwprobe and keep HWCAP only as a compatibility fallback
960+ * when hwprobe is unavailable or cannot answer the query.
961+ */
962+ struct riscv_hwprobe probe ;
963+ probe .key = RISCV_HWPROBE_KEY_IMA_EXT_0 ;
964+ probe .value = 0 ;
965+
966+ int ret = syscall (__NR_riscv_hwprobe , & probe , 1 , 0 , NULL , 0 );
967+ if (0 == ret ) {
968+ if (probe .value & RISCV_HWPROBE_IMA_V ){
969+ npy__cpu_have [NPY_CPU_FEATURE_RVV ] = 1 ;
970+ }
971+ return ;
972+ }
973+ #endif
974+
945975 unsigned int hwcap = getauxval (AT_HWCAP );
946- #else
976+ if (hwcap & COMPAT_HWCAP_ISA_V ) {
977+ npy__cpu_have [NPY_CPU_FEATURE_RVV ] = 1 ;
978+ }
979+
980+ #else // __FreeBSD__|| __OpenBSD__
947981 unsigned long hwcap ;
948982 elf_aux_info (AT_HWCAP , & hwcap , sizeof (hwcap ));
949- #endif
950983 if (hwcap & COMPAT_HWCAP_ISA_V ) {
951984 npy__cpu_have [NPY_CPU_FEATURE_RVV ] = 1 ;
952985 }
953986#endif
987+
988+ #endif
954989}
955990
956991/*********** Unsupported ARCH ***********/
0 commit comments