Merge patch series "RISC-V: Export Zba, Zbb to usermode via hwprobe"
Evan Green <evan@rivosinc.com> says: This change detects the presence of Zba, Zbb, and Zbs extensions and exports them per-hart to userspace via the hwprobe mechanism. Glibc can then use these in setting up hwcaps-based library search paths. There's a little bit of extra housekeeping here: the first change adds Zba and Zbs to the set of extensions the kernel recognizes, and the second change starts tracking ISA features per-hart (in addition to the ANDed mask of features across all harts which the kernel uses to make decisions). Now that we track the ISA information per-hart, we could even fix up /proc/cpuinfo to accurately report extension per-hart, though I've left that out of this series for now. * b4-shazam-merge: RISC-V: hwprobe: Expose Zba, Zbb, and Zbs RISC-V: Track ISA extensions per hart RISC-V: Add Zba, Zbs extension probing Link: https://lore.kernel.org/r/20230509182504.2997252-1-evan@rivosinc.com Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>
This commit is contained in:
commit
16252e018a
|
@ -67,6 +67,16 @@ The following keys are defined:
|
|||
* :c:macro:`RISCV_HWPROBE_IMA_V`: The V extension is supported, as defined by
|
||||
version 1.0 of the RISC-V Vector extension manual.
|
||||
|
||||
* :c:macro:`RISCV_HWPROBE_EXT_ZBA`: The Zba address generation extension is
|
||||
supported, as defined in version 1.0 of the Bit-Manipulation ISA
|
||||
extensions.
|
||||
|
||||
* :c:macro:`RISCV_HWPROBE_EXT_ZBB`: The Zbb extension is supported, as defined
|
||||
in version 1.0 of the Bit-Manipulation ISA extensions.
|
||||
|
||||
* :c:macro:`RISCV_HWPROBE_EXT_ZBS`: The Zbs extension is supported, as defined
|
||||
in version 1.0 of the Bit-Manipulation ISA extensions.
|
||||
|
||||
* :c:macro:`RISCV_HWPROBE_KEY_CPUPERF_0`: A bitmask that contains performance
|
||||
information about the selected set of processors.
|
||||
|
||||
|
|
|
@ -6,6 +6,9 @@
|
|||
#ifndef _ASM_CPUFEATURE_H
|
||||
#define _ASM_CPUFEATURE_H
|
||||
|
||||
#include <linux/bitmap.h>
|
||||
#include <asm/hwcap.h>
|
||||
|
||||
/*
|
||||
* These are probed via a device_initcall(), via either the SBI or directly
|
||||
* from the corresponding CSRs.
|
||||
|
@ -16,8 +19,15 @@ struct riscv_cpuinfo {
|
|||
unsigned long mimpid;
|
||||
};
|
||||
|
||||
struct riscv_isainfo {
|
||||
DECLARE_BITMAP(isa, RISCV_ISA_EXT_MAX);
|
||||
};
|
||||
|
||||
DECLARE_PER_CPU(struct riscv_cpuinfo, riscv_cpuinfo);
|
||||
|
||||
DECLARE_PER_CPU(long, misaligned_access_speed);
|
||||
|
||||
/* Per-cpu ISA extensions. */
|
||||
extern struct riscv_isainfo hart_isa[NR_CPUS];
|
||||
|
||||
#endif
|
||||
|
|
|
@ -47,6 +47,8 @@
|
|||
#define RISCV_ISA_EXT_ZICBOZ 34
|
||||
#define RISCV_ISA_EXT_SMAIA 35
|
||||
#define RISCV_ISA_EXT_SSAIA 36
|
||||
#define RISCV_ISA_EXT_ZBA 37
|
||||
#define RISCV_ISA_EXT_ZBS 38
|
||||
|
||||
#define RISCV_ISA_EXT_MAX 64
|
||||
#define RISCV_ISA_EXT_NAME_LEN_MAX 32
|
||||
|
|
|
@ -26,6 +26,9 @@ struct riscv_hwprobe {
|
|||
#define RISCV_HWPROBE_IMA_FD (1 << 0)
|
||||
#define RISCV_HWPROBE_IMA_C (1 << 1)
|
||||
#define RISCV_HWPROBE_IMA_V (1 << 2)
|
||||
#define RISCV_HWPROBE_EXT_ZBA (1 << 3)
|
||||
#define RISCV_HWPROBE_EXT_ZBB (1 << 4)
|
||||
#define RISCV_HWPROBE_EXT_ZBS (1 << 5)
|
||||
#define RISCV_HWPROBE_KEY_CPUPERF_0 5
|
||||
#define RISCV_HWPROBE_MISALIGNED_UNKNOWN (0 << 0)
|
||||
#define RISCV_HWPROBE_MISALIGNED_EMULATED (1 << 0)
|
||||
|
|
|
@ -187,7 +187,9 @@ static struct riscv_isa_ext_data isa_ext_arr[] = {
|
|||
__RISCV_ISA_EXT_DATA(zicbom, RISCV_ISA_EXT_ZICBOM),
|
||||
__RISCV_ISA_EXT_DATA(zicboz, RISCV_ISA_EXT_ZICBOZ),
|
||||
__RISCV_ISA_EXT_DATA(zihintpause, RISCV_ISA_EXT_ZIHINTPAUSE),
|
||||
__RISCV_ISA_EXT_DATA(zba, RISCV_ISA_EXT_ZBA),
|
||||
__RISCV_ISA_EXT_DATA(zbb, RISCV_ISA_EXT_ZBB),
|
||||
__RISCV_ISA_EXT_DATA(zbs, RISCV_ISA_EXT_ZBS),
|
||||
__RISCV_ISA_EXT_DATA(smaia, RISCV_ISA_EXT_SMAIA),
|
||||
__RISCV_ISA_EXT_DATA(ssaia, RISCV_ISA_EXT_SSAIA),
|
||||
__RISCV_ISA_EXT_DATA(sscofpmf, RISCV_ISA_EXT_SSCOFPMF),
|
||||
|
|
|
@ -30,6 +30,9 @@ unsigned long elf_hwcap __read_mostly;
|
|||
/* Host ISA bitmap */
|
||||
static DECLARE_BITMAP(riscv_isa, RISCV_ISA_EXT_MAX) __read_mostly;
|
||||
|
||||
/* Per-cpu ISA extensions. */
|
||||
struct riscv_isainfo hart_isa[NR_CPUS];
|
||||
|
||||
/* Performance information */
|
||||
DEFINE_PER_CPU(long, misaligned_access_speed);
|
||||
|
||||
|
@ -126,8 +129,8 @@ void __init riscv_fill_hwcap(void)
|
|||
}
|
||||
|
||||
for_each_possible_cpu(cpu) {
|
||||
struct riscv_isainfo *isainfo = &hart_isa[cpu];
|
||||
unsigned long this_hwcap = 0;
|
||||
DECLARE_BITMAP(this_isa, RISCV_ISA_EXT_MAX);
|
||||
const char *temp;
|
||||
|
||||
if (acpi_disabled) {
|
||||
|
@ -159,7 +162,6 @@ void __init riscv_fill_hwcap(void)
|
|||
/* The riscv,isa DT property must start with rv64 or rv32 */
|
||||
if (temp == isa)
|
||||
continue;
|
||||
bitmap_zero(this_isa, RISCV_ISA_EXT_MAX);
|
||||
for (; *isa; ++isa) {
|
||||
const char *ext = isa++;
|
||||
const char *ext_end = isa;
|
||||
|
@ -239,7 +241,7 @@ void __init riscv_fill_hwcap(void)
|
|||
if ((ext_end - ext == sizeof(name) - 1) && \
|
||||
!strncasecmp(ext, name, sizeof(name) - 1) && \
|
||||
riscv_isa_extension_check(bit)) \
|
||||
set_bit(bit, this_isa); \
|
||||
set_bit(bit, isainfo->isa); \
|
||||
} while (false) \
|
||||
|
||||
if (unlikely(ext_err))
|
||||
|
@ -249,7 +251,7 @@ void __init riscv_fill_hwcap(void)
|
|||
|
||||
if (riscv_isa_extension_check(nr)) {
|
||||
this_hwcap |= isa2hwcap[nr];
|
||||
set_bit(nr, this_isa);
|
||||
set_bit(nr, isainfo->isa);
|
||||
}
|
||||
} else {
|
||||
/* sorted alphabetically */
|
||||
|
@ -260,7 +262,9 @@ void __init riscv_fill_hwcap(void)
|
|||
SET_ISA_EXT_MAP("svinval", RISCV_ISA_EXT_SVINVAL);
|
||||
SET_ISA_EXT_MAP("svnapot", RISCV_ISA_EXT_SVNAPOT);
|
||||
SET_ISA_EXT_MAP("svpbmt", RISCV_ISA_EXT_SVPBMT);
|
||||
SET_ISA_EXT_MAP("zba", RISCV_ISA_EXT_ZBA);
|
||||
SET_ISA_EXT_MAP("zbb", RISCV_ISA_EXT_ZBB);
|
||||
SET_ISA_EXT_MAP("zbs", RISCV_ISA_EXT_ZBS);
|
||||
SET_ISA_EXT_MAP("zicbom", RISCV_ISA_EXT_ZICBOM);
|
||||
SET_ISA_EXT_MAP("zicboz", RISCV_ISA_EXT_ZICBOZ);
|
||||
SET_ISA_EXT_MAP("zihintpause", RISCV_ISA_EXT_ZIHINTPAUSE);
|
||||
|
@ -279,9 +283,9 @@ void __init riscv_fill_hwcap(void)
|
|||
elf_hwcap = this_hwcap;
|
||||
|
||||
if (bitmap_empty(riscv_isa, RISCV_ISA_EXT_MAX))
|
||||
bitmap_copy(riscv_isa, this_isa, RISCV_ISA_EXT_MAX);
|
||||
bitmap_copy(riscv_isa, isainfo->isa, RISCV_ISA_EXT_MAX);
|
||||
else
|
||||
bitmap_and(riscv_isa, riscv_isa, this_isa, RISCV_ISA_EXT_MAX);
|
||||
bitmap_and(riscv_isa, riscv_isa, isainfo->isa, RISCV_ISA_EXT_MAX);
|
||||
}
|
||||
|
||||
if (!acpi_disabled && rhct)
|
||||
|
|
|
@ -122,6 +122,49 @@ static void hwprobe_arch_id(struct riscv_hwprobe *pair,
|
|||
pair->value = id;
|
||||
}
|
||||
|
||||
static void hwprobe_isa_ext0(struct riscv_hwprobe *pair,
|
||||
const struct cpumask *cpus)
|
||||
{
|
||||
int cpu;
|
||||
u64 missing = 0;
|
||||
|
||||
pair->value = 0;
|
||||
if (has_fpu())
|
||||
pair->value |= RISCV_HWPROBE_IMA_FD;
|
||||
|
||||
if (riscv_isa_extension_available(NULL, c))
|
||||
pair->value |= RISCV_HWPROBE_IMA_C;
|
||||
|
||||
if (has_vector())
|
||||
pair->value |= RISCV_HWPROBE_IMA_V;
|
||||
|
||||
/*
|
||||
* Loop through and record extensions that 1) anyone has, and 2) anyone
|
||||
* doesn't have.
|
||||
*/
|
||||
for_each_cpu(cpu, cpus) {
|
||||
struct riscv_isainfo *isainfo = &hart_isa[cpu];
|
||||
|
||||
if (riscv_isa_extension_available(isainfo->isa, ZBA))
|
||||
pair->value |= RISCV_HWPROBE_EXT_ZBA;
|
||||
else
|
||||
missing |= RISCV_HWPROBE_EXT_ZBA;
|
||||
|
||||
if (riscv_isa_extension_available(isainfo->isa, ZBB))
|
||||
pair->value |= RISCV_HWPROBE_EXT_ZBB;
|
||||
else
|
||||
missing |= RISCV_HWPROBE_EXT_ZBB;
|
||||
|
||||
if (riscv_isa_extension_available(isainfo->isa, ZBS))
|
||||
pair->value |= RISCV_HWPROBE_EXT_ZBS;
|
||||
else
|
||||
missing |= RISCV_HWPROBE_EXT_ZBS;
|
||||
}
|
||||
|
||||
/* Now turn off reporting features if any CPU is missing it. */
|
||||
pair->value &= ~missing;
|
||||
}
|
||||
|
||||
static u64 hwprobe_misaligned(const struct cpumask *cpus)
|
||||
{
|
||||
int cpu;
|
||||
|
@ -165,16 +208,7 @@ static void hwprobe_one_pair(struct riscv_hwprobe *pair,
|
|||
break;
|
||||
|
||||
case RISCV_HWPROBE_KEY_IMA_EXT_0:
|
||||
pair->value = 0;
|
||||
if (has_fpu())
|
||||
pair->value |= RISCV_HWPROBE_IMA_FD;
|
||||
|
||||
if (riscv_isa_extension_available(NULL, c))
|
||||
pair->value |= RISCV_HWPROBE_IMA_C;
|
||||
|
||||
if (has_vector())
|
||||
pair->value |= RISCV_HWPROBE_IMA_V;
|
||||
|
||||
hwprobe_isa_ext0(pair, cpus);
|
||||
break;
|
||||
|
||||
case RISCV_HWPROBE_KEY_CPUPERF_0:
|
||||
|
|
Loading…
Reference in New Issue