1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3 * Copyright 2006 Michael Ellerman, IBM Corporation
4 */
5
6 #include <linux/kernel.h>
7 #include <linux/interrupt.h>
8
9 #include <asm/setup.h>
10 #include <asm/page.h>
11 #include <asm/firmware.h>
12 #include <asm/kexec.h>
13 #include <asm/xics.h>
14 #include <asm/xive.h>
15 #include <asm/smp.h>
16 #include <asm/plpar_wrappers.h>
17
18 #include "pseries.h"
19
pseries_kexec_cpu_down(int crash_shutdown,int secondary)20 void pseries_kexec_cpu_down(int crash_shutdown, int secondary)
21 {
22 /*
23 * Ensure vpa/slb_shadow/dtl cleanup even while we are crashing.
24 * Why? The hypervisor is not crashing so at least attempt unregister to
25 * avoid the hypervisor stepping on our memory. If hypervisor or kexec
26 * kernel steps on the old memory allocated to these areas before the
27 * new kexec-kernel happens to allocate and register new areas,
28 * the hypervisor will see invalid content which may cause
29 * unexpected behavior.
30 */
31 if (firmware_has_feature(FW_FEATURE_SPLPAR)) {
32 int ret;
33 int cpu = smp_processor_id();
34 int hwcpu = hard_smp_processor_id();
35
36 if (get_lppaca()->dtl_enable_mask) {
37 ret = unregister_dtl(hwcpu);
38 if (ret) {
39 pr_err("WARNING: DTL deregistration for cpu "
40 "%d (hw %d) failed with %d\n",
41 cpu, hwcpu, ret);
42 }
43 }
44
45 ret = unregister_slb_shadow(hwcpu);
46 if (ret) {
47 pr_err("WARNING: SLB shadow buffer deregistration "
48 "for cpu %d (hw %d) failed with %d\n",
49 cpu, hwcpu, ret);
50 }
51
52 ret = unregister_vpa(hwcpu);
53 if (ret) {
54 pr_err("WARNING: VPA deregistration for cpu %d "
55 "(hw %d) failed with %d\n", cpu, hwcpu, ret);
56 }
57 }
58
59 if (xive_enabled()) {
60 xive_teardown_cpu();
61
62 if (!secondary)
63 xive_shutdown();
64 } else
65 xics_kexec_teardown_cpu(secondary);
66 }
67