On Mon, Jun 26, 2023 at 12:19:46PM +0100, Conor Dooley wrote: > Add support for parsing the new riscv,isa-extensions property in > riscv_fill_hwcap(), by means of a new "property" member of the > riscv_isa_ext_data struct. For now, this shadows the name of the > extension, however this may not be the case for all extensions. > For the sake of backwards compatibility, fall back to the old scheme > if the new properties are not detected. For now, just inform, rather > than warn, when that happens. > > Signed-off-by: Conor Dooley <conor.dooley@xxxxxxxxxxxxx> > --- > Naming things is hard, didn't know what to call the new function... riscv_fill_hwcap_from_isa_extensions() ? _new() won't age well. > --- > arch/riscv/include/asm/hwcap.h | 1 + > arch/riscv/kernel/cpufeature.c | 80 ++++++++++++++++++++++++++++++---- > 2 files changed, 72 insertions(+), 9 deletions(-) > > diff --git a/arch/riscv/include/asm/hwcap.h b/arch/riscv/include/asm/hwcap.h > index 6ad896dc4342..e7f235868aa2 100644 > --- a/arch/riscv/include/asm/hwcap.h > +++ b/arch/riscv/include/asm/hwcap.h > @@ -77,6 +77,7 @@ unsigned long riscv_get_elf_hwcap(void); > struct riscv_isa_ext_data { > const unsigned int id; > const char *name; > + const char *property; > const bool multi_letter; > }; > > diff --git a/arch/riscv/kernel/cpufeature.c b/arch/riscv/kernel/cpufeature.c > index 366477ba1eea..72eb757ad871 100644 > --- a/arch/riscv/kernel/cpufeature.c > +++ b/arch/riscv/kernel/cpufeature.c > @@ -101,6 +101,7 @@ static bool riscv_isa_extension_check(int id) > > #define __RISCV_ISA_EXT_DATA(_name, _id, _multi) { \ > .name = #_name, \ > + .property = #_name, \ > .id = _id, \ > .multi_letter = _multi, \ > } > @@ -416,16 +417,66 @@ static void __init riscv_fill_hwcap_from_isa_string(unsigned long *isa2hwcap) > acpi_put_table((struct acpi_table_header *)rhct); > } > > +static int __init riscv_fill_hwcap_new(unsigned long *isa2hwcap) > +{ > + unsigned int cpu; > + > + for_each_possible_cpu(cpu) { > + unsigned long this_hwcap = 0; > + struct device_node *cpu_node; > + DECLARE_BITMAP(this_isa, RISCV_ISA_EXT_MAX); > + > + cpu_node = of_cpu_device_node_get(cpu); > + if (!cpu_node) { > + pr_warn("Unable to find cpu node\n"); > + continue; > + } > + > + if (!of_property_present(cpu_node, "riscv,isa-extensions")) > + continue; > + > + for (int i = 0; i < riscv_isa_ext_count; i++) { > + if (of_property_match_string(cpu_node, "riscv,isa-extensions", > + riscv_isa_ext[i].name) < 0) > + continue; > + > + if (!riscv_isa_extension_check(riscv_isa_ext[i].id)) > + continue; > + > + if (!riscv_isa_ext[i].multi_letter) > + this_hwcap |= isa2hwcap[riscv_isa_ext[i].id]; > + > + set_bit(riscv_isa_ext[i].id, this_isa); > + } > + > + of_node_put(cpu_node); > + > + /* > + * All "okay" harts should have same isa. Set HWCAP based on > + * common capabilities of every "okay" hart, in case they don't. > + */ > + if (elf_hwcap) > + elf_hwcap &= this_hwcap; > + else > + elf_hwcap = this_hwcap; > + > + if (bitmap_empty(riscv_isa, RISCV_ISA_EXT_MAX)) > + bitmap_copy(riscv_isa, this_isa, RISCV_ISA_EXT_MAX); > + else > + bitmap_and(riscv_isa, riscv_isa, this_isa, RISCV_ISA_EXT_MAX); > + } > + > + if (bitmap_empty(riscv_isa, RISCV_ISA_EXT_MAX)) > + return -ENOENT; > + > + return 0; > +} > + > void __init riscv_fill_hwcap(void) > { > - struct device_node *node; > - const char *isa; > char print_str[NUM_ALPHA_EXTS + 1]; > - int i, j, rc; > unsigned long isa2hwcap[26] = {0}; > - struct acpi_table_header *rhct; > - acpi_status status; > - unsigned int cpu; > + int i, j; > > isa2hwcap['i' - 'a'] = COMPAT_HWCAP_ISA_I; > isa2hwcap['m' - 'a'] = COMPAT_HWCAP_ISA_M; > @@ -435,10 +486,21 @@ void __init riscv_fill_hwcap(void) > isa2hwcap['c' - 'a'] = COMPAT_HWCAP_ISA_C; > isa2hwcap['v' - 'a'] = COMPAT_HWCAP_ISA_V; > > - riscv_fill_hwcap_from_isa_string(isa2hwcap); > + if (!acpi_disabled) { > + riscv_fill_hwcap_from_isa_string(isa2hwcap); > + } else { > + int ret = riscv_fill_hwcap_new(isa2hwcap); > > - /* We don't support systems with F but without D, so mask those out > - * here. */ > + if (ret) { > + pr_info("Falling back to deprecated \"riscv,isa\"\n"); > + riscv_fill_hwcap_from_isa_string(isa2hwcap); > + } > + } > + > + /* > + * We don't support systems with F but without D, so mask those out > + * here. > + */ > if ((elf_hwcap & COMPAT_HWCAP_ISA_F) && !(elf_hwcap & COMPAT_HWCAP_ISA_D)) { > pr_info("This kernel does not support systems with F but not D\n"); > elf_hwcap &= ~COMPAT_HWCAP_ISA_F; > -- > 2.40.1 > Other than the name and moving the removal of the unused declarations to the previous patch, Reviewed-by: Andrew Jones <ajones@xxxxxxxxxxxxxxxx> Thanks, drew