Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 14 Dec 2020 11:57:43 +0000 (UTC)
From:      Michal Meloun <mmel@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r368633 - head/sys/arm64/arm64
Message-ID:  <202012141157.0BEBvhI9069471@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: mmel
Date: Mon Dec 14 11:57:43 2020
New Revision: 368633
URL: https://svnweb.freebsd.org/changeset/base/368633

Log:
  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

Modified:
  head/sys/arm64/arm64/mp_machdep.c

Modified: head/sys/arm64/arm64/mp_machdep.c
==============================================================================
--- head/sys/arm64/arm64/mp_machdep.c	Mon Dec 14 11:56:16 2020	(r368632)
+++ head/sys/arm64/arm64/mp_machdep.c	Mon Dec 14 11:57:43 2020	(r368633)
@@ -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];
 	/*



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202012141157.0BEBvhI9069471>