aboutsummaryrefslogtreecommitdiff
path: root/core
diff options
context:
space:
mode:
Diffstat (limited to 'core')
-rw-r--r--core/fast-reboot.c2
-rw-r--r--core/init.c38
2 files changed, 40 insertions, 0 deletions
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);