From ebb814a80369adee82a509d50d41d56674ea68e4 Mon Sep 17 00:00:00 2001 From: Nicholas Piggin Date: Tue, 8 Jan 2019 00:04:22 +1000 Subject: core/init: enable machine check on secondaries Secondary CPUs currently run with MSR[ME]=0 during boot, whih means if they take a machine check, the system will checkstop. Enable ME where possible and allow them to print registers. Signed-off-by: Nicholas Piggin Signed-off-by: Stewart Smith --- core/fast-reboot.c | 2 ++ core/init.c | 38 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 40 insertions(+) (limited to 'core') diff --git a/core/fast-reboot.c b/core/fast-reboot.c index eb1b348..d3cc8cf 100644 --- a/core/fast-reboot.c +++ b/core/fast-reboot.c @@ -362,6 +362,8 @@ void __noreturn fast_reboot_entry(void) } sync(); cleanup_cpu_state(); + enable_machine_check(); + __secondary_cpu_entry(); } diff --git a/core/init.c b/core/init.c index 0ad2bfb..3f7dd14 100644 --- a/core/init.c +++ b/core/init.c @@ -475,6 +475,39 @@ static void load_initramfs(void) } } +static void cpu_disable_ME_one(void *param __unused) +{ + disable_machine_check(); +} + +static int64_t cpu_disable_ME_all(void) +{ + struct cpu_thread *cpu; + struct cpu_job **jobs; + + jobs = zalloc(sizeof(struct cpu_job *) * (cpu_max_pir + 1)); + assert(jobs); + + for_each_available_cpu(cpu) { + if (cpu == this_cpu()) + continue; + jobs[cpu->pir] = cpu_queue_job(cpu, "cpu_disable_ME", + cpu_disable_ME_one, NULL); + } + + /* this cpu */ + cpu_disable_ME_one(NULL); + + for_each_available_cpu(cpu) { + if (jobs[cpu->pir]) + cpu_wait_job(jobs[cpu->pir], true); + } + + free(jobs); + + return OPAL_SUCCESS; +} + void *fdt; void __noreturn load_and_boot_kernel(bool is_reboot) @@ -586,6 +619,9 @@ void __noreturn load_and_boot_kernel(bool is_reboot) printf("INIT: Starting kernel at 0x%llx, fdt at %p %u bytes\n", kernel_entry, fdt, fdt_totalsize(fdt)); + /* Disable machine checks on all */ + cpu_disable_ME_all(); + debug_descriptor.state_flags |= OPAL_BOOT_COMPLETE; cpu_give_self_os(); @@ -1234,6 +1270,8 @@ void __noreturn __secondary_cpu_entry(void) /* Secondary CPU called in */ cpu_callin(cpu); + enable_machine_check(); + /* Some XIVE setup */ xive_cpu_callin(cpu); -- cgit v1.1