diff options
author | Hongren Zheng <i@zenithal.me> | 2024-04-17 17:21:53 +0800 |
---|---|---|
committer | Tomas Mraz <tomas@openssl.org> | 2024-05-09 10:50:42 +0200 |
commit | 66ad636b979554ddde5cd5908feabda79d07317b (patch) | |
tree | ebb5e855913788905fd7cd2b09153a1d9796e5f1 /crypto | |
parent | 13d37d8f7557ee7935032ea832eab3e3c5540158 (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.c | 43 |
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(); |