aboutsummaryrefslogtreecommitdiff
path: root/sys/arm64/arm64/mp_machdep.c
diff options
context:
space:
mode:
authorMichal Meloun <mmel@FreeBSD.org>2020-12-14 11:57:43 +0000
committerMichal Meloun <mmel@FreeBSD.org>2020-12-14 11:57:43 +0000
commit22f5cb76eb4a8eda305e932d39ff0f8a6aec9164 (patch)
treed330a339fc6f53a82e4b04a5b1ef47f5b82a47aa /sys/arm64/arm64/mp_machdep.c
parent10557931153c8e347251b95418fe0f45dc2262dd (diff)
downloadsrc-22f5cb76eb4a8eda305e932d39ff0f8a6aec9164.tar.gz
src-22f5cb76eb4a8eda305e932d39ff0f8a6aec9164.zip
Verify (and fix) the context_id argument passed to the mpentry () by PSCI.
Some older PSCI implementations corrupt (or do not pass) the context_id argument to newly started secondary cores. Although the ideal solution to this problem is u-boot update, we can find the correct value for the argument (cpuid) by comparing of real core mpidr register with the value stored in pcu->mpidr. MFC after: 2 weeks
Notes
Notes: svn path=/head/; revision=368633
Diffstat (limited to 'sys/arm64/arm64/mp_machdep.c')
-rw-r--r--sys/arm64/arm64/mp_machdep.c15
1 files changed, 15 insertions, 0 deletions
diff --git a/sys/arm64/arm64/mp_machdep.c b/sys/arm64/arm64/mp_machdep.c
index 71a3f6ba6529..8f1118d36bf5 100644
--- a/sys/arm64/arm64/mp_machdep.c
+++ b/sys/arm64/arm64/mp_machdep.c
@@ -206,6 +206,21 @@ init_secondary(uint64_t cpu)
{
struct pcpu *pcpup;
pmap_t pmap0;
+ u_int mpidr;
+
+ /*
+ * Verify that the value passed in 'cpu' argument (aka context_id) is
+ * valid. Some older U-Boot based PSCI implementations are buggy,
+ * they can pass random value in it.
+ */
+ mpidr = READ_SPECIALREG(mpidr_el1) & CPU_AFF_MASK;
+ if (cpu >= MAXCPU || __pcpu[cpu].pc_mpidr != mpidr) {
+ for (cpu = 0; cpu < mp_maxid; cpu++)
+ if (__pcpu[cpu].pc_mpidr == mpidr)
+ break;
+ if ( cpu >= MAXCPU)
+ panic("MPIDR for this CPU is not in pcpu table");
+ }
pcpup = &__pcpu[cpu];
/*