162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * Copyright 2006 Michael Ellerman, IBM Corporation 462306a36Sopenharmony_ci */ 562306a36Sopenharmony_ci 662306a36Sopenharmony_ci#include <linux/kernel.h> 762306a36Sopenharmony_ci#include <linux/interrupt.h> 862306a36Sopenharmony_ci 962306a36Sopenharmony_ci#include <asm/setup.h> 1062306a36Sopenharmony_ci#include <asm/page.h> 1162306a36Sopenharmony_ci#include <asm/firmware.h> 1262306a36Sopenharmony_ci#include <asm/kexec.h> 1362306a36Sopenharmony_ci#include <asm/xics.h> 1462306a36Sopenharmony_ci#include <asm/xive.h> 1562306a36Sopenharmony_ci#include <asm/smp.h> 1662306a36Sopenharmony_ci#include <asm/plpar_wrappers.h> 1762306a36Sopenharmony_ci 1862306a36Sopenharmony_ci#include "pseries.h" 1962306a36Sopenharmony_ci 2062306a36Sopenharmony_civoid pseries_kexec_cpu_down(int crash_shutdown, int secondary) 2162306a36Sopenharmony_ci{ 2262306a36Sopenharmony_ci /* 2362306a36Sopenharmony_ci * Don't risk a hypervisor call if we're crashing 2462306a36Sopenharmony_ci * XXX: Why? The hypervisor is not crashing. It might be better 2562306a36Sopenharmony_ci * to at least attempt unregister to avoid the hypervisor stepping 2662306a36Sopenharmony_ci * on our memory. 2762306a36Sopenharmony_ci */ 2862306a36Sopenharmony_ci if (firmware_has_feature(FW_FEATURE_SPLPAR) && !crash_shutdown) { 2962306a36Sopenharmony_ci int ret; 3062306a36Sopenharmony_ci int cpu = smp_processor_id(); 3162306a36Sopenharmony_ci int hwcpu = hard_smp_processor_id(); 3262306a36Sopenharmony_ci 3362306a36Sopenharmony_ci if (get_lppaca()->dtl_enable_mask) { 3462306a36Sopenharmony_ci ret = unregister_dtl(hwcpu); 3562306a36Sopenharmony_ci if (ret) { 3662306a36Sopenharmony_ci pr_err("WARNING: DTL deregistration for cpu " 3762306a36Sopenharmony_ci "%d (hw %d) failed with %d\n", 3862306a36Sopenharmony_ci cpu, hwcpu, ret); 3962306a36Sopenharmony_ci } 4062306a36Sopenharmony_ci } 4162306a36Sopenharmony_ci 4262306a36Sopenharmony_ci ret = unregister_slb_shadow(hwcpu); 4362306a36Sopenharmony_ci if (ret) { 4462306a36Sopenharmony_ci pr_err("WARNING: SLB shadow buffer deregistration " 4562306a36Sopenharmony_ci "for cpu %d (hw %d) failed with %d\n", 4662306a36Sopenharmony_ci cpu, hwcpu, ret); 4762306a36Sopenharmony_ci } 4862306a36Sopenharmony_ci 4962306a36Sopenharmony_ci ret = unregister_vpa(hwcpu); 5062306a36Sopenharmony_ci if (ret) { 5162306a36Sopenharmony_ci pr_err("WARNING: VPA deregistration for cpu %d " 5262306a36Sopenharmony_ci "(hw %d) failed with %d\n", cpu, hwcpu, ret); 5362306a36Sopenharmony_ci } 5462306a36Sopenharmony_ci } 5562306a36Sopenharmony_ci 5662306a36Sopenharmony_ci if (xive_enabled()) { 5762306a36Sopenharmony_ci xive_teardown_cpu(); 5862306a36Sopenharmony_ci 5962306a36Sopenharmony_ci if (!secondary) 6062306a36Sopenharmony_ci xive_shutdown(); 6162306a36Sopenharmony_ci } else 6262306a36Sopenharmony_ci xics_kexec_teardown_cpu(secondary); 6362306a36Sopenharmony_ci} 6462306a36Sopenharmony_ci 6562306a36Sopenharmony_civoid pseries_machine_kexec(struct kimage *image) 6662306a36Sopenharmony_ci{ 6762306a36Sopenharmony_ci if (firmware_has_feature(FW_FEATURE_SET_MODE)) 6862306a36Sopenharmony_ci pseries_disable_reloc_on_exc(); 6962306a36Sopenharmony_ci 7062306a36Sopenharmony_ci default_machine_kexec(image); 7162306a36Sopenharmony_ci} 72