aboutsummaryrefslogtreecommitdiff
path: root/core
diff options
context:
space:
mode:
authorRyan Grimm <grimm@linux.ibm.com>2020-02-05 15:48:13 -0500
committerOliver O'Halloran <oohall@gmail.com>2020-06-04 09:42:16 +1000
commit37a369bbcb5a3f37de3affb77fc774375b83783e (patch)
tree110748999cb04bc27cb60f79aee88816af8db0e3 /core
parent244a8daca45b3dc22d08e1dd17d201ebdbf62d58 (diff)
downloadskiboot-37a369bbcb5a3f37de3affb77fc774375b83783e.zip
skiboot-37a369bbcb5a3f37de3affb77fc774375b83783e.tar.gz
skiboot-37a369bbcb5a3f37de3affb77fc774375b83783e.tar.bz2
Disable protected execution facility
This patch disables Protected Execution Faciltiy (PEF). This software procedure is needed for the lab because Cronus will be configured to bring the machine up with PEF on. Hostboot has a similar procedure for running with PEF off. Skiboot can run with PEF on but the kernel cannot; the kernel will take a machine check when trying to write a protected resource, such as the PTCR. So, use this until we have an ultravisor, or if we want to use BML with Cronus without UV = 1. Signed-off-by: Ryan Grimm <grimm@linux.ibm.com> Tested-by: Alistair Popple <alistair@popple.id.au> [oliver: replaced bare urfid with a macro for toolchain compatibility] Signed-off-by: Oliver O'Halloran <oohall@gmail.com>
Diffstat (limited to 'core')
-rw-r--r--core/cpu.c59
-rw-r--r--core/init.c3
2 files changed, 62 insertions, 0 deletions
diff --git a/core/cpu.c b/core/cpu.c
index 1b38124..73777dd 100644
--- a/core/cpu.c
+++ b/core/cpu.c
@@ -1646,3 +1646,62 @@ static int64_t opal_nmmu_set_ptcr(uint64_t chip_id, uint64_t ptcr)
return rc;
}
opal_call(OPAL_NMMU_SET_PTCR, opal_nmmu_set_ptcr, 2);
+
+static void _exit_uv_mode(void *data __unused)
+{
+ prlog(PR_DEBUG, "Exit uv mode on cpu pir 0x%04x\n", this_cpu()->pir);
+ /* HW has smfctrl shared between threads but on Mambo it is per-thread */
+ if (chip_quirk(QUIRK_MAMBO_CALLOUTS))
+ exit_uv_mode(1);
+ else
+ exit_uv_mode(cpu_is_thread0(this_cpu()));
+}
+
+void cpu_disable_pef(void)
+{
+ struct cpu_thread *cpu;
+ struct cpu_job **jobs;
+
+ if (!(mfmsr() & MSR_S)) {
+ prlog(PR_DEBUG, "UV mode off on cpu pir 0x%04x\n", this_cpu()->pir);
+ return;
+ }
+
+ jobs = zalloc(sizeof(struct cpu_job *) * (cpu_max_pir + 1));
+ assert(jobs);
+
+ /* Exit uv mode on all secondary threads before touching
+ * smfctrl on thread 0 */
+ for_each_available_cpu(cpu) {
+ if (cpu == this_cpu())
+ continue;
+
+ if (!cpu_is_thread0(cpu))
+ jobs[cpu->pir] = cpu_queue_job(cpu, "exit_uv_mode",
+ _exit_uv_mode, NULL);
+ }
+
+ for_each_available_cpu(cpu)
+ if (jobs[cpu->pir]) {
+ cpu_wait_job(jobs[cpu->pir], true);
+ jobs[cpu->pir] = NULL;
+ }
+
+ /* Exit uv mode and disable smfctrl on primary threads */
+ for_each_available_cpu(cpu) {
+ if (cpu == this_cpu())
+ continue;
+
+ if (cpu_is_thread0(cpu))
+ jobs[cpu->pir] = cpu_queue_job(cpu, "exit_uv_mode",
+ _exit_uv_mode, NULL);
+ }
+
+ for_each_available_cpu(cpu)
+ if (jobs[cpu->pir])
+ cpu_wait_job(jobs[cpu->pir], true);
+
+ free(jobs);
+
+ _exit_uv_mode(NULL);
+}
diff --git a/core/init.c b/core/init.c
index 89240f6..9f3b8c6 100644
--- a/core/init.c
+++ b/core/init.c
@@ -1369,6 +1369,9 @@ void __noreturn __nomcount main_cpu_entry(const void *fdt)
/* Add the list of interrupts going to OPAL */
add_opal_interrupts();
+ /* Disable protected execution facility in BML */
+ cpu_disable_pef();
+
/* Now release parts of memory nodes we haven't used ourselves... */
mem_region_release_unused();