diff options
author | Paul Burton <paul.burton@imgtec.com> | 2017-06-02 14:48:55 -0700 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2017-06-29 02:42:28 +0200 |
commit | fa7a3b4a7217b40bf58c4f38e5ee573b43a8aa2f (patch) | |
tree | b2c80cbfe9cc7691e86981673b4ea71ccc9c79be /arch | |
parent | 4ad755c9e39c0eeae16f96b97602f1954f582c66 (diff) | |
download | linux-fa7a3b4a7217b40bf58c4f38e5ee573b43a8aa2f.tar.gz linux-fa7a3b4a7217b40bf58c4f38e5ee573b43a8aa2f.tar.bz2 linux-fa7a3b4a7217b40bf58c4f38e5ee573b43a8aa2f.zip |
MIPS: CPS: Handle spurious VP starts more gracefully
On pre-r6 systems with the MT ASE the CPS SMP code included checks to
halt the VPE running mips_cps_boot_vpes() if its bit in the struct
core_boot_config vpe_mask field is clear. This was largely done in order
to allow us to start arbitrary VPEs within a core despite the fact that
hardware is typically configured to run only VPE0 after powering up a
core. VPE0 would start the desired other VPEs, halt itself, and the fact
that VPE0 started would be largely hidden & irrelevant.
In MIPSr6 multithreading we have control over which VPs start executing
when a core powers up via the cores CPC registers accessed remotely
through the redirect block. For this reason the MIPSr6 multithreading
path in mips_cps_boot_vpes() hasn't bothered up until now to handle
halting the VP running it.
However it is possible to power up cores entirely in hardware by using a
pwr_up pin associated with the core. Unfortunately some systems wire
this pin to a logic 1, which means that it is possible for a core to
power up at a point that software doesn't expect. The result is that we
generally go execute the kernel on a CPU that ought not to be running &
the results can be unpredictable.
Handle this case by stopping VPs that we don't expect to be running in
mips_cps_boot_vpes() - with this change even if a core powers up it will
do nothing useful & all VPs within it will stop running before they
proceed to run general kernel code & do any damage. Ideally we would
produce some sort of warning here, but given the stage of core bringup
this happens at that would be non-trivial. We also will only hit this if
a core starts up after being offlined via hotplug, and when that happens
we will already produce a warning that the CPU didn't power down in
cps_cpu_die() which seems sufficient.
Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: linux-mips@linux-mips.org
Patchwork: https://patchwork.linux-mips.org/patch/16198/
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/mips/kernel/cps-vec.S | 7 |
1 files changed, 6 insertions, 1 deletions
diff --git a/arch/mips/kernel/cps-vec.S b/arch/mips/kernel/cps-vec.S index a00e87b0256d..b849fe6aad94 100644 --- a/arch/mips/kernel/cps-vec.S +++ b/arch/mips/kernel/cps-vec.S @@ -22,6 +22,7 @@ #define GCR_CL_COHERENCE_OFS 0x2008 #define GCR_CL_ID_OFS 0x2028 +#define CPC_CL_VC_STOP_OFS 0x2020 #define CPC_CL_VC_RUN_OFS 0x2028 .extern mips_cm_base @@ -376,8 +377,12 @@ LEAF(mips_cps_boot_vpes) PTR_LI t2, UNCAC_BASE PTR_ADD t1, t1, t2 - /* Set VC_RUN to the VPE mask */ + /* Start any other VPs that ought to be running */ PTR_S ta2, CPC_CL_VC_RUN_OFS(t1) + + /* Ensure this VP stops running if it shouldn't be */ + not ta2 + PTR_S ta2, CPC_CL_VC_STOP_OFS(t1) ehb #elif defined(CONFIG_MIPS_MT) |