[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <1549590681-24125-9-git-send-email-atish.patra@wdc.com>
Date: Thu, 7 Feb 2019 17:51:21 -0800
From: Atish Patra <atish.patra@....com>
To: linux-riscv@...ts.infradead.org
Cc: Atish Patra <atish.patra@....com>,
Alan Kao <alankao@...estech.com>,
Albert Ou <aou@...s.berkeley.edu>,
Andreas Schwab <schwab@...e.de>,
Anup Patel <anup@...infault.org>,
Daniel Lezcano <daniel.lezcano@...aro.org>,
Dmitriy Cherkasov <dmitriy@...-tech.org>,
Jason Cooper <jason@...edaemon.net>,
linux-kernel@...r.kernel.org, Marc Zyngier <marc.zyngier@....com>,
Palmer Dabbelt <palmer@...ive.com>,
Patrick Stählin <me@...ki.ch>,
Paul Walmsley <paul.walmsley@...ive.com>,
Thomas Gleixner <tglx@...utronix.de>,
Zong Li <zongbox@...il.com>,
Damien Le Moal <Damien.LeMoal@....com>
Subject: [v3 PATCH 8/8] RISC-V: Assign hwcap only according to boot cpu.
Currently, we set hwcap based on first valid cpu from
DT. This may not be correct always as that CPU might not
be current booting cpu.
Set hwcap based on the boot cpu instead of first
valid CPU from DT. Add a sanity check to identify if any
hwcap do not match.
Signed-off-by: Atish Patra <atish.patra@....com>
---
arch/riscv/kernel/cpufeature.c | 52 +++++++++++++++++++++++++++++-------------
1 file changed, 36 insertions(+), 16 deletions(-)
diff --git a/arch/riscv/kernel/cpufeature.c b/arch/riscv/kernel/cpufeature.c
index a6e369ed..ed8f0c28 100644
--- a/arch/riscv/kernel/cpufeature.c
+++ b/arch/riscv/kernel/cpufeature.c
@@ -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
@@ -32,6 +33,8 @@ void riscv_fill_hwcap(void)
const char *isa;
size_t i;
static unsigned long isa2hwcap[256] = {0};
+ int hartid;
+ unsigned long temp_hwcap = 0, boot_hwcap = 0;
isa2hwcap['i'] = isa2hwcap['I'] = COMPAT_HWCAP_ISA_I;
isa2hwcap['m'] = isa2hwcap['M'] = COMPAT_HWCAP_ISA_M;
@@ -43,27 +46,44 @@ 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.
+ * We don't support running Linux on hertergenous ISA systems.
+ * But first "okay" processor might not be the boot cpu.
+ * Check the ISA of boot cpu.
*/
- while ((node = of_find_node_by_type(node, "cpu")))
- if (riscv_of_processor_hartid(node) >= 0)
- break;
- if (!node) {
- pr_warning("Unable to find \"cpu\" devicetree entry");
- return;
- }
+ while ((node = of_find_node_by_type(node, "cpu"))) {
+ if (!node) {
+ pr_warn("Unable to find \"cpu\" devicetree entry");
+ return;
+ }
+
+ hartid = riscv_of_processor_hartid(node);
+ if (hartid < 0)
+ continue;
- if (of_property_read_string(node, "riscv,isa", &isa)) {
- pr_warning("Unable to find \"riscv,isa\" devicetree entry");
+ if (of_property_read_string(node, "riscv,isa", &isa)) {
+ pr_warn("Unable to find \"riscv,isa\" devicetree entry");
+ of_node_put(node);
+ return;
+ }
of_node_put(node);
- return;
- }
- of_node_put(node);
- for (i = 0; i < strlen(isa); ++i)
- elf_hwcap |= isa2hwcap[(unsigned char)(isa[i])];
+ for (i = 0; i < strlen(isa); ++i)
+ temp_hwcap |= isa2hwcap[(unsigned char)(isa[i])];
+ /*
+ * All "okay" hart should have same isa. We don't know how to
+ * handle if they don't. Throw a warning for now.
+ */
+ if (elf_hwcap && temp_hwcap != elf_hwcap)
+ pr_warn("isa mismatch: 0x%lx != 0x%lx\n",
+ elf_hwcap, temp_hwcap);
+
+ if (hartid == boot_cpu_hartid)
+ boot_hwcap = temp_hwcap;
+ elf_hwcap = temp_hwcap;
+ temp_hwcap = 0;
+ }
+ elf_hwcap = boot_hwcap;
/* 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)) {
--
2.7.4
Powered by blists - more mailing lists