]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
RISC-V: Assign hwcap as per comman capabilities.
authorAtish Patra <atish.patra@wdc.com>
Fri, 22 Feb 2019 19:41:40 +0000 (11:41 -0800)
committerPalmer Dabbelt <palmer@sifive.com>
Mon, 4 Mar 2019 18:40:39 +0000 (10:40 -0800)
Currently, we set hwcap based on first valid hart from DT. This may not
be correct always as that hart might not be current booting cpu or may
have a different capability.

Set hwcap as the capabilities supported by all possible harts with "okay"
status.

Signed-off-by: Atish Patra <atish.patra@wdc.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
Reviewed-by: Johan Hovold <johan@kernel.org>
Signed-off-by: Palmer Dabbelt <palmer@sifive.com>
arch/riscv/kernel/cpufeature.c

index e7a4701f02563504f2f8cfd7b773c422b4424fe6..bc29b010b722f62d18fac0b7bd79c5adb77d4d4f 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/of.h>
 #include <asm/processor.h>
 #include <asm/hwcap.h>
+#include <asm/smp.h>
 
 unsigned long elf_hwcap __read_mostly;
 #ifdef CONFIG_FPU
@@ -42,28 +43,30 @@ void riscv_fill_hwcap(void)
 
        elf_hwcap = 0;
 
-       /*
-        * We don't support running Linux on hertergenous ISA systems.  For
-        * now, we just check the ISA of the first "okay" processor.
-        */
        for_each_of_cpu_node(node) {
-               if (riscv_of_processor_hartid(node) >= 0)
-                       break;
-       }
-       if (!node) {
-               pr_warn("Unable to find \"cpu\" devicetree entry\n");
-               return;
-       }
+               unsigned long this_hwcap = 0;
 
-       if (of_property_read_string(node, "riscv,isa", &isa)) {
-               pr_warn("Unable to find \"riscv,isa\" devicetree entry\n");
-               of_node_put(node);
-               return;
-       }
-       of_node_put(node);
+               if (riscv_of_processor_hartid(node) < 0)
+                       continue;
 
-       for (i = 0; i < strlen(isa); ++i)
-               elf_hwcap |= isa2hwcap[(unsigned char)(isa[i])];
+               if (of_property_read_string(node, "riscv,isa", &isa)) {
+                       pr_warn("Unable to find \"riscv,isa\" devicetree entry\n");
+                       continue;
+               }
+
+               for (i = 0; i < strlen(isa); ++i)
+                       this_hwcap |= isa2hwcap[(unsigned char)(isa[i])];
+
+               /*
+                * All "okay" hart should have same isa. Set HWCAP based on
+                * common capabilities of every "okay" hart, in case they don't
+                * have.
+                */
+               if (elf_hwcap)
+                       elf_hwcap &= this_hwcap;
+               else
+                       elf_hwcap = this_hwcap;
+       }
 
        /* We don't support systems with F but without D, so mask those out
         * here. */