On Mon, May 11, 2026 at 09:34:53PM -0400, Guodong Xu wrote: > Introduce a per-hart and host-wide bitmap of conformant ISA "bases" -- > named profile-class sets such as IMA and RVA23U64 -- and compute > both at init time. > > This is the cache that subsequent consumers (hwprobe's > RVA23U64 base behavior bit, /proc/cpuinfo's "isa bases" lines, etc.) > read without recomputing. > > riscv_init_isa_bases() iterates over all possible cpus to populate > each hart_isa[cpu].isa_bases, then computes the host-wide > riscv_isa_bases against the AND-across-harts riscv_isa bitmap. It is > registered as a subsys_initcall so it executes after > core_initcall(tagged_addr_init), which probes senvcfg.PMM and > populates have_user_pmlen_*. Without that ordering, > riscv_have_user_pmlen(7) would still return its default false and the > RVA23U64 detection path would always bail. > > The detection itself is encapsulated in riscv_set_isa_bases(), which > takes an output bases bitmap and an input ISA bitmap. > > Signed-off-by: Andrew Jones <[email protected]> > Signed-off-by: Guodong Xu <[email protected]> > --- > v2: > - Implement riscv_init_isa_bases() that runs at system init time, > after tagged_addr_init() populates have_user_pmlen_*. > - Split RVA23S64 placeholder into a future patch. > --- > arch/riscv/include/asm/cpufeature.h | 14 ++++++ > arch/riscv/kernel/cpufeature.c | 92 > +++++++++++++++++++++++++++++++++++++ > 2 files changed, 106 insertions(+)
Sashiko points out a few things about this patch which I think I agree with https://sashiko.dev/#/patchset/20260511-rva23u64-hwprobe-v2-v2-0-21c5a544f1dc%40riscstar.com?part=8 Additional nit below. > > diff --git a/arch/riscv/include/asm/cpufeature.h > b/arch/riscv/include/asm/cpufeature.h > index 739fcc84bf7b2..facc31b2960c6 100644 > --- a/arch/riscv/include/asm/cpufeature.h > +++ b/arch/riscv/include/asm/cpufeature.h > @@ -25,10 +25,24 @@ struct riscv_cpuinfo { > unsigned long mimpid; > }; > > +enum { > + RISCV_ISA_BASE_IMA, > + RISCV_ISA_BASE_RVA23U64, > + RISCV_NR_ISA_BASES, > +}; > + > +/** > + * struct riscv_isainfo - per-hart ISA state > + * @isa: bitmap of ISA extensions this hart implements > + * @isa_bases: bitmap of profile bases this hart conforms to > + */ > struct riscv_isainfo { > DECLARE_BITMAP(isa, RISCV_ISA_EXT_MAX); > + DECLARE_BITMAP(isa_bases, RISCV_NR_ISA_BASES); > }; > > +extern unsigned long riscv_isa_bases[BITS_TO_LONGS(RISCV_NR_ISA_BASES)]; > + > DECLARE_PER_CPU(struct riscv_cpuinfo, riscv_cpuinfo); > > extern const struct seq_operations cpuinfo_op; > diff --git a/arch/riscv/kernel/cpufeature.c b/arch/riscv/kernel/cpufeature.c > index 81145621dc378..6e8dd33aa3888 100644 > --- a/arch/riscv/kernel/cpufeature.c > +++ b/arch/riscv/kernel/cpufeature.c > @@ -41,6 +41,9 @@ unsigned long elf_hwcap __read_mostly; > /* Host ISA bitmap */ > static DECLARE_BITMAP(riscv_isa, RISCV_ISA_EXT_MAX) __read_mostly; > > +/* Host ISA bases bitmap */ > +DECLARE_BITMAP(riscv_isa_bases, RISCV_NR_ISA_BASES) __read_mostly; > + > /* Per-cpu ISA extensions. */ > struct riscv_isainfo hart_isa[NR_CPUS]; > > @@ -1305,3 +1308,92 @@ void __init_or_module > riscv_cpufeature_patch_func(struct alt_entry *begin, > } > } > #endif > + > +/* > + * Compute the set of profile bases (IMA, RVA23U64, ...) a hart > + * conforms to, given its resolved ISA bitmap. > + * > + * If @isa_bitmap is NULL, the host ISA bitmap (the AND across all harts) is > + * used. > + */ > +static void riscv_set_isa_bases(unsigned long *bases, const unsigned long > *isa_bitmap) > +{ > + const unsigned long *isa = isa_bitmap ? isa_bitmap : riscv_isa; > + DECLARE_BITMAP(ext_mask, RISCV_ISA_EXT_MAX) = { 0 }; > + DECLARE_BITMAP(tmp, RISCV_ISA_EXT_MAX); > + > + /* IMA */ > + set_bit(RISCV_ISA_EXT_I, ext_mask); > + set_bit(RISCV_ISA_EXT_M, ext_mask); > + set_bit(RISCV_ISA_EXT_A, ext_mask); > + > + if (bitmap_andnot(tmp, ext_mask, isa, RISCV_ISA_EXT_MAX)) > + return; > + > + set_bit(RISCV_ISA_BASE_IMA, bases); > + > + /* RVA23U64 */ > + > + /* Zic64b and Supm with PMLEN=7 */ > + if (riscv_cbom_block_size != 64 || > + riscv_cbop_block_size != 64 || > + riscv_cboz_block_size != 64 || > + !riscv_have_user_pmlen(7)) > + return; > + > + set_bit(RISCV_ISA_EXT_F, ext_mask); > + set_bit(RISCV_ISA_EXT_D, ext_mask); > + set_bit(RISCV_ISA_EXT_C, ext_mask); > + set_bit(RISCV_ISA_EXT_B, ext_mask); > + set_bit(RISCV_ISA_EXT_ZICSR, ext_mask); > + set_bit(RISCV_ISA_EXT_ZICNTR, ext_mask); > + set_bit(RISCV_ISA_EXT_ZIHPM, ext_mask); > + set_bit(RISCV_ISA_EXT_ZICCIF, ext_mask); > + set_bit(RISCV_ISA_EXT_ZICCRSE, ext_mask); > + set_bit(RISCV_ISA_EXT_ZICCAMOA, ext_mask); > + set_bit(RISCV_ISA_EXT_ZICCLSM, ext_mask); > + set_bit(RISCV_ISA_EXT_ZA64RS, ext_mask); > + set_bit(RISCV_ISA_EXT_ZIHINTPAUSE, ext_mask); > + set_bit(RISCV_ISA_EXT_ZICBOM, ext_mask); > + set_bit(RISCV_ISA_EXT_ZICBOP, ext_mask); > + set_bit(RISCV_ISA_EXT_ZICBOZ, ext_mask); > + set_bit(RISCV_ISA_EXT_ZFHMIN, ext_mask); > + set_bit(RISCV_ISA_EXT_ZKT, ext_mask); > + set_bit(RISCV_ISA_EXT_V, ext_mask); > + set_bit(RISCV_ISA_EXT_ZVFHMIN, ext_mask); > + set_bit(RISCV_ISA_EXT_ZVBB, ext_mask); > + set_bit(RISCV_ISA_EXT_ZVKT, ext_mask); > + set_bit(RISCV_ISA_EXT_ZIHINTNTL, ext_mask); > + set_bit(RISCV_ISA_EXT_ZICOND, ext_mask); > + set_bit(RISCV_ISA_EXT_ZIMOP, ext_mask); > + set_bit(RISCV_ISA_EXT_ZCMOP, ext_mask); > + set_bit(RISCV_ISA_EXT_ZCB, ext_mask); > + set_bit(RISCV_ISA_EXT_ZFA, ext_mask); > + set_bit(RISCV_ISA_EXT_ZAWRS, ext_mask); > + set_bit(RISCV_ISA_EXT_SUPM, ext_mask); > + > + if (bitmap_andnot(tmp, ext_mask, isa, RISCV_ISA_EXT_MAX)) > + return; > + > + set_bit(RISCV_ISA_BASE_RVA23U64, bases); > +} > + > +/* > + * Populate the host ISA bases bitmap (riscv_isa_bases) and each > + * hart's per-cpu isa_bases. > + */ > +static int __init riscv_init_isa_bases(void) > +{ > + int cpu; > + > + for_each_possible_cpu(cpu) > + riscv_set_isa_bases(hart_isa[cpu].isa_bases, hart_isa[cpu].isa); > + > + riscv_set_isa_bases(riscv_isa_bases, NULL); > + return 0; > +} Missing blank line here. Thanks, drew > +/* > + * Registered as subsys_initcall so it runs after > + * core_initcall(tagged_addr_init) populates have_user_pmlen_*. > + */ > +subsys_initcall(riscv_init_isa_bases); > > -- > 2.43.0 >

