162a31a03SHiroshi Shimamoto /* 262a31a03SHiroshi Shimamoto * Architecture specific (i386/x86_64) functions for kexec based crash dumps. 362a31a03SHiroshi Shimamoto * 462a31a03SHiroshi Shimamoto * Created by: Hariprasad Nellitheertha (hari@in.ibm.com) 562a31a03SHiroshi Shimamoto * 662a31a03SHiroshi Shimamoto * Copyright (C) IBM Corporation, 2004. All rights reserved. 762a31a03SHiroshi Shimamoto * 862a31a03SHiroshi Shimamoto */ 962a31a03SHiroshi Shimamoto 1062a31a03SHiroshi Shimamoto #include <linux/init.h> 1162a31a03SHiroshi Shimamoto #include <linux/types.h> 1262a31a03SHiroshi Shimamoto #include <linux/kernel.h> 1362a31a03SHiroshi Shimamoto #include <linux/smp.h> 1462a31a03SHiroshi Shimamoto #include <linux/reboot.h> 1562a31a03SHiroshi Shimamoto #include <linux/kexec.h> 1662a31a03SHiroshi Shimamoto #include <linux/delay.h> 1762a31a03SHiroshi Shimamoto #include <linux/elf.h> 1862a31a03SHiroshi Shimamoto #include <linux/elfcore.h> 19f23d1f4aSZhang Yanfei #include <linux/module.h> 2062a31a03SHiroshi Shimamoto 2162a31a03SHiroshi Shimamoto #include <asm/processor.h> 2262a31a03SHiroshi Shimamoto #include <asm/hardirq.h> 2362a31a03SHiroshi Shimamoto #include <asm/nmi.h> 2462a31a03SHiroshi Shimamoto #include <asm/hw_irq.h> 2562a31a03SHiroshi Shimamoto #include <asm/apic.h> 260c1b2724SOGAWA Hirofumi #include <asm/hpet.h> 2762a31a03SHiroshi Shimamoto #include <linux/kdebug.h> 2896b89dc6SJaswinder Singh Rajput #include <asm/cpu.h> 29ed23dc6fSGlauber Costa #include <asm/reboot.h> 302340b62fSEduardo Habkost #include <asm/virtext.h> 318e294786SEduardo Habkost 325edd19afSCliff Wickman int in_crash_kexec; 335edd19afSCliff Wickman 34f23d1f4aSZhang Yanfei /* 35f23d1f4aSZhang Yanfei * This is used to VMCLEAR all VMCSs loaded on the 36f23d1f4aSZhang Yanfei * processor. And when loading kvm_intel module, the 37f23d1f4aSZhang Yanfei * callback function pointer will be assigned. 38f23d1f4aSZhang Yanfei * 39f23d1f4aSZhang Yanfei * protected by rcu. 40f23d1f4aSZhang Yanfei */ 410ca0d818SZhang Yanfei crash_vmclear_fn __rcu *crash_vmclear_loaded_vmcss = NULL; 42f23d1f4aSZhang Yanfei EXPORT_SYMBOL_GPL(crash_vmclear_loaded_vmcss); 43f23d1f4aSZhang Yanfei 44f23d1f4aSZhang Yanfei static inline void cpu_crash_vmclear_loaded_vmcss(void) 45f23d1f4aSZhang Yanfei { 460ca0d818SZhang Yanfei crash_vmclear_fn *do_vmclear_operation = NULL; 47f23d1f4aSZhang Yanfei 48f23d1f4aSZhang Yanfei rcu_read_lock(); 49f23d1f4aSZhang Yanfei do_vmclear_operation = rcu_dereference(crash_vmclear_loaded_vmcss); 50f23d1f4aSZhang Yanfei if (do_vmclear_operation) 51f23d1f4aSZhang Yanfei do_vmclear_operation(); 52f23d1f4aSZhang Yanfei rcu_read_unlock(); 53f23d1f4aSZhang Yanfei } 54f23d1f4aSZhang Yanfei 55b2bbe71bSEduardo Habkost #if defined(CONFIG_SMP) && defined(CONFIG_X86_LOCAL_APIC) 56b2bbe71bSEduardo Habkost 579c48f1c6SDon Zickus static void kdump_nmi_callback(int cpu, struct pt_regs *regs) 5862a31a03SHiroshi Shimamoto { 591fb473d8SMike Galbraith #ifdef CONFIG_X86_32 6062a31a03SHiroshi Shimamoto struct pt_regs fixed_regs; 6162a31a03SHiroshi Shimamoto #endif 62a7d41820SEduardo Habkost 63a7d41820SEduardo Habkost #ifdef CONFIG_X86_32 64a7d41820SEduardo Habkost if (!user_mode_vm(regs)) { 65a7d41820SEduardo Habkost crash_fixup_ss_esp(&fixed_regs, regs); 66a7d41820SEduardo Habkost regs = &fixed_regs; 67a7d41820SEduardo Habkost } 68a7d41820SEduardo Habkost #endif 69a7d41820SEduardo Habkost crash_save_cpu(regs, cpu); 70a7d41820SEduardo Habkost 71f23d1f4aSZhang Yanfei /* 72f23d1f4aSZhang Yanfei * VMCLEAR VMCSs loaded on all cpus if needed. 73f23d1f4aSZhang Yanfei */ 74f23d1f4aSZhang Yanfei cpu_crash_vmclear_loaded_vmcss(); 75f23d1f4aSZhang Yanfei 762340b62fSEduardo Habkost /* Disable VMX or SVM if needed. 772340b62fSEduardo Habkost * 782340b62fSEduardo Habkost * We need to disable virtualization on all CPUs. 792340b62fSEduardo Habkost * Having VMX or SVM enabled on any CPU may break rebooting 802340b62fSEduardo Habkost * after the kdump kernel has finished its task. 812340b62fSEduardo Habkost */ 822340b62fSEduardo Habkost cpu_emergency_vmxoff(); 832340b62fSEduardo Habkost cpu_emergency_svm_disable(); 842340b62fSEduardo Habkost 85a7d41820SEduardo Habkost disable_local_APIC(); 86a7d41820SEduardo Habkost } 87a7d41820SEduardo Habkost 88d1e7b91cSEduardo Habkost static void kdump_nmi_shootdown_cpus(void) 89d1e7b91cSEduardo Habkost { 905edd19afSCliff Wickman in_crash_kexec = 1; 918e294786SEduardo Habkost nmi_shootdown_cpus(kdump_nmi_callback); 92d1e7b91cSEduardo Habkost 9362a31a03SHiroshi Shimamoto disable_local_APIC(); 9462a31a03SHiroshi Shimamoto } 95d1e7b91cSEduardo Habkost 9662a31a03SHiroshi Shimamoto #else 97d1e7b91cSEduardo Habkost static void kdump_nmi_shootdown_cpus(void) 9862a31a03SHiroshi Shimamoto { 9962a31a03SHiroshi Shimamoto /* There are no cpus to shootdown */ 10062a31a03SHiroshi Shimamoto } 10162a31a03SHiroshi Shimamoto #endif 10262a31a03SHiroshi Shimamoto 103ed23dc6fSGlauber Costa void native_machine_crash_shutdown(struct pt_regs *regs) 10462a31a03SHiroshi Shimamoto { 10562a31a03SHiroshi Shimamoto /* This function is only called after the system 10662a31a03SHiroshi Shimamoto * has panicked or is otherwise in a critical state. 10762a31a03SHiroshi Shimamoto * The minimum amount of code to allow a kexec'd kernel 10862a31a03SHiroshi Shimamoto * to run successfully needs to happen here. 10962a31a03SHiroshi Shimamoto * 11062a31a03SHiroshi Shimamoto * In practice this means shooting down the other cpus in 11162a31a03SHiroshi Shimamoto * an SMP system. 11262a31a03SHiroshi Shimamoto */ 11362a31a03SHiroshi Shimamoto /* The kernel is broken so disable interrupts */ 11462a31a03SHiroshi Shimamoto local_irq_disable(); 11562a31a03SHiroshi Shimamoto 116d1e7b91cSEduardo Habkost kdump_nmi_shootdown_cpus(); 1172340b62fSEduardo Habkost 118f23d1f4aSZhang Yanfei /* 119f23d1f4aSZhang Yanfei * VMCLEAR VMCSs loaded on this cpu if needed. 120f23d1f4aSZhang Yanfei */ 121f23d1f4aSZhang Yanfei cpu_crash_vmclear_loaded_vmcss(); 122f23d1f4aSZhang Yanfei 1232340b62fSEduardo Habkost /* Booting kdump kernel with VMX or SVM enabled won't work, 1242340b62fSEduardo Habkost * because (among other limitations) we can't disable paging 1252340b62fSEduardo Habkost * with the virt flags. 1262340b62fSEduardo Habkost */ 1272340b62fSEduardo Habkost cpu_emergency_vmxoff(); 1282340b62fSEduardo Habkost cpu_emergency_svm_disable(); 1292340b62fSEduardo Habkost 13017405453SYoshihiro YUNOMAE #ifdef CONFIG_X86_IO_APIC 13117405453SYoshihiro YUNOMAE /* Prevent crash_kexec() from deadlocking on ioapic_lock. */ 13217405453SYoshihiro YUNOMAE ioapic_zap_locks(); 13362a31a03SHiroshi Shimamoto disable_IO_APIC(); 13462a31a03SHiroshi Shimamoto #endif 135522e6646SFenghua Yu lapic_shutdown(); 1360c1b2724SOGAWA Hirofumi #ifdef CONFIG_HPET_TIMER 1370c1b2724SOGAWA Hirofumi hpet_disable(); 1380c1b2724SOGAWA Hirofumi #endif 13962a31a03SHiroshi Shimamoto crash_save_cpu(regs, safe_smp_processor_id()); 14062a31a03SHiroshi Shimamoto } 141