summaryrefslogtreecommitdiffstats
path: root/crypto
diff options
context:
space:
mode:
authorHongren Zheng <i@zenithal.me>2024-04-17 17:21:53 +0800
committerTomas Mraz <tomas@openssl.org>2024-05-09 10:50:42 +0200
commit66ad636b979554ddde5cd5908feabda79d07317b (patch)
treeebb5e855913788905fd7cd2b09153a1d9796e5f1 /crypto
parent13d37d8f7557ee7935032ea832eab3e3c5540158 (diff)
riscv: use hwprobe syscall for capability detection
Reviewed-by: Paul Dale <ppzgs1@gmail.com> Reviewed-by: Tomas Mraz <tomas@openssl.org> (Merged from https://github.com/openssl/openssl/pull/24172)
Diffstat (limited to 'crypto')
-rw-r--r--crypto/riscvcap.c43
1 files changed, 43 insertions, 0 deletions
diff --git a/crypto/riscvcap.c b/crypto/riscvcap.c
index db75c21b28..7683bf0fb8 100644
--- a/crypto/riscvcap.c
+++ b/crypto/riscvcap.c
@@ -17,6 +17,12 @@
#define OPENSSL_RISCVCAP_IMPL
#include "crypto/riscv_arch.h"
+#ifdef OSSL_RISCV_HWPROBE
+# include <unistd.h>
+# include <sys/syscall.h>
+# include <asm/hwprobe.h>
+#endif
+
extern size_t riscv_vlen_asm(void);
static void parse_env(const char *envstr);
@@ -71,6 +77,38 @@ static void parse_env(const char *envstr)
}
}
+#ifdef OSSL_RISCV_HWPROBE
+static long riscv_hwprobe(struct riscv_hwprobe *pairs, size_t pair_count,
+ size_t cpu_count, unsigned long *cpus,
+ unsigned int flags)
+{
+ return syscall(__NR_riscv_hwprobe, pairs, pair_count, cpu_count, cpus, flags);
+}
+
+static void hwprobe_to_cap()
+{
+ long ret;
+ struct riscv_hwprobe pairs[OSSL_RISCV_HWPROBE_PAIR_COUNT] = {
+ OSSL_RISCV_HWPROBE_PAIR_CONTENT
+ };
+
+ ret = riscv_hwprobe(pairs, OSSL_RISCV_HWPROBE_PAIR_COUNT, 0, NULL, 0);
+ /* if hwprobe syscall does not exist, ret would be -ENOSYS */
+ if (ret == 0) {
+ for (size_t i = 0; i < kRISCVNumCaps; ++i) {
+ for (size_t j = 0; j != OSSL_RISCV_HWPROBE_PAIR_COUNT; ++j) {
+ if (pairs[j].key == RISCV_capabilities[i].hwprobe_key
+ && (pairs[j].value & RISCV_capabilities[i].hwprobe_value)
+ != 0)
+ /* Match, set relevant bit in OPENSSL_riscvcap_P[] */
+ OPENSSL_riscvcap_P[RISCV_capabilities[i].index] |=
+ (1 << RISCV_capabilities[i].bit_offset);
+ }
+ }
+ }
+}
+#endif /* OSSL_RISCV_HWPROBE */
+
size_t riscv_vlen(void)
{
return vlen;
@@ -91,6 +129,11 @@ void OPENSSL_cpuid_setup(void)
if ((e = getenv("OPENSSL_riscvcap"))) {
parse_env(e);
}
+#ifdef OSSL_RISCV_HWPROBE
+ else {
+ hwprobe_to_cap();
+ }
+#endif
if (RISCV_HAS_V()) {
vlen = riscv_vlen_asm();