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/machdep.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 	 * Don't risk a hypervisor call if we're crashing
24 	 * XXX: Why? The hypervisor is not crashing. It might be better
25 	 * to at least attempt unregister to avoid the hypervisor stepping
26 	 * on our memory.
27 	 */
28 	if (firmware_has_feature(FW_FEATURE_SPLPAR) && !crash_shutdown) {
29 		int ret;
30 		int cpu = smp_processor_id();
31 		int hwcpu = hard_smp_processor_id();
32 
33 		if (get_lppaca()->dtl_enable_mask) {
34 			ret = unregister_dtl(hwcpu);
35 			if (ret) {
36 				pr_err("WARNING: DTL deregistration for cpu "
37 				       "%d (hw %d) failed with %d\n",
38 				       cpu, hwcpu, ret);
39 			}
40 		}
41 
42 		ret = unregister_slb_shadow(hwcpu);
43 		if (ret) {
44 			pr_err("WARNING: SLB shadow buffer deregistration "
45 			       "for cpu %d (hw %d) failed with %d\n",
46 			       cpu, hwcpu, ret);
47 		}
48 
49 		ret = unregister_vpa(hwcpu);
50 		if (ret) {
51 			pr_err("WARNING: VPA deregistration for cpu %d "
52 			       "(hw %d) failed with %d\n", cpu, hwcpu, ret);
53 		}
54 	}
55 
56 	if (xive_enabled()) {
57 		xive_teardown_cpu();
58 
59 		if (!secondary)
60 			xive_shutdown();
61 	} else
62 		xics_kexec_teardown_cpu(secondary);
63 }
64