From: Palmer Dabbelt Date: Mon, 19 Jun 2023 21:34:40 +0000 (-0700) Subject: Merge patch series "RISC-V: Export Zba, Zbb to usermode via hwprobe" X-Git-Tag: v6.6.7~2493^2~9 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=16252e018a30486eedcfec81fc313445cac25bea;p=platform%2Fkernel%2Flinux-starfive.git Merge patch series "RISC-V: Export Zba, Zbb to usermode via hwprobe" Evan Green 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 --- 16252e018a30486eedcfec81fc313445cac25bea diff --cc Documentation/riscv/hwprobe.rst index 7431d9d,fb25670..19165eb --- a/Documentation/riscv/hwprobe.rst +++ b/Documentation/riscv/hwprobe.rst @@@ -64,9 -64,16 +64,19 @@@ The following keys are defined * :c:macro:`RISCV_HWPROBE_IMA_C`: The C extension is supported, as defined by version 2.2 of the RISC-V ISA manual. + * :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. diff --cc arch/riscv/include/uapi/asm/hwprobe.h index 7c6fdcf,853f8f6..006bfb4 --- a/arch/riscv/include/uapi/asm/hwprobe.h +++ b/arch/riscv/include/uapi/asm/hwprobe.h @@@ -25,7 -25,9 +25,10 @@@ struct riscv_hwprobe #define RISCV_HWPROBE_KEY_IMA_EXT_0 4 #define RISCV_HWPROBE_IMA_FD (1 << 0) #define RISCV_HWPROBE_IMA_C (1 << 1) -#define RISCV_HWPROBE_EXT_ZBA (1 << 2) -#define RISCV_HWPROBE_EXT_ZBB (1 << 3) -#define RISCV_HWPROBE_EXT_ZBS (1 << 4) +#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) diff --cc arch/riscv/kernel/cpufeature.c index d1e9e87,e8b7b4b..f8dc577 --- a/arch/riscv/kernel/cpufeature.c +++ b/arch/riscv/kernel/cpufeature.c @@@ -119,36 -115,22 +122,36 @@@ void __init riscv_fill_hwcap(void bitmap_zero(riscv_isa, RISCV_ISA_EXT_MAX); - for_each_of_cpu_node(node) { - struct riscv_isainfo *isainfo; + if (!acpi_disabled) { + status = acpi_get_table(ACPI_SIG_RHCT, 0, &rhct); + if (ACPI_FAILURE(status)) + return; + } + + 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; - unsigned int cpu_id; - - rc = riscv_of_processor_hartid(node, &hartid); - if (rc < 0) - continue; - cpu_id = riscv_hartid_to_cpuid(hartid); - isainfo = &hart_isa[cpu_id]; + if (acpi_disabled) { + node = of_cpu_device_node_get(cpu); + if (!node) { + pr_warn("Unable to find cpu node\n"); + continue; + } - if (of_property_read_string(node, "riscv,isa", &isa)) { - pr_warn("Unable to find \"riscv,isa\" devicetree entry\n"); - continue; + rc = of_property_read_string(node, "riscv,isa", &isa); + of_node_put(node); + if (rc) { + pr_warn("Unable to find \"riscv,isa\" devicetree entry\n"); + continue; + } + } else { + rc = acpi_get_riscv_isa(rhct, cpu, &isa); + if (rc < 0) { + pr_warn("Unable to get ISA for the hart - %d\n", cpu); + continue; + } } temp = isa; @@@ -234,13 -216,13 +236,13 @@@ if (*isa != '_') --isa; -#define SET_ISA_EXT_MAP(name, bit) \ - do { \ - if ((ext_end - ext == sizeof(name) - 1) && \ - !memcmp(ext, name, sizeof(name) - 1) && \ - riscv_isa_extension_check(bit)) \ - set_bit(bit, isainfo->isa); \ - } while (false) \ +#define SET_ISA_EXT_MAP(name, bit) \ + do { \ + 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)) continue; @@@ -279,14 -263,11 +283,14 @@@ 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) + acpi_put_table((struct acpi_table_header *)rhct); + /* 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)) { diff --cc arch/riscv/kernel/sys_riscv.c index 88357a8,fe655db..26ef552 --- a/arch/riscv/kernel/sys_riscv.c +++ b/arch/riscv/kernel/sys_riscv.c @@@ -122,6 -121,46 +122,49 @@@ static void hwprobe_arch_id(struct risc 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;