x86: vmclear vmcss on all cpus when doing kdump if necessary
Subsystems (5)
v10 cover x86: vmclear vmcss on all cpus when doing kdump if necessary
Currently, kdump just makes all the logical processors leave VMX operation by executing VMXOFF instruction, so any VMCSs active on the logical processors may be corrupted. But, sometimes, we need the VMCSs to debug guest images contained in the host vmcore. To prevent the corruption, we should VMCLEAR the VMCSs before executing the VMXOFF instruction.
The patch set provides a way to VMCLEAR vmcss related to guests on all cpus before executing the VMXOFF when doing kdump. This is used to ensure the VMCSs in the vmcore updated and non-corrupted.
Changelog from v9 to v10:
1. add rcu protect to the callback function
Changelog from v8 to v9:
1. KEXEC: use a callback function instead of a notifier.
2. KVM-INTEL: use a new vmclear function instead of just calling vmclear_local_loaded_vmcss to make sure we just do the core vmclear operation in kdump.
Changelog from v7 to v8:
1. KEXEC: regression for using name crash_notifier_list and remove comments related to KVM
and just call function atomic_notifier_call_chain directly.
Changelog from v6 to v7:
1. KVM-INTEL: in hardware_disable, we needn't disable the vmclear, so remove it.
Changelog from v5 to v6:
1. KEXEC: the atomic notifier list renamed:
crash_notifier_list --> vmclear_notifier_list
2. KVM-INTEL: provide empty functions if CONFIG_KEXEC is not defined and remove unnecessary #ifdef's.
Changelog from v4 to v5:
1. use an atomic notifier instead of function call, so have all the vmclear codes in vmx.c.
Changelog from v3 to v4:
1. add a new percpu variable vmclear_skipped to skip vmclear in kdump in some conditions.
Changelog from v2 to v3:
1. remove unnecessary conditions in function cpu_emergency_clear_loaded_vmcss as Marcelo suggested.
Changelog from v1 to v2:
1. remove the sysctl and clear VMCSs unconditionally.
Zhang Yanfei (2):
x86/kexec: VMCLEAR VMCSs loaded on all cpus if necessary
KVM-INTEL: provide the vmclear function and a bitmap to support
VMCLEAR in kdump
arch/x86/include/asm/kexec.h | 2 + arch/x86/kernel/crash.c | 32 ++++++++++++++++++++ arch/x86/kvm/vmx.c | 67 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 101 insertions(+), 0 deletions(-)
PATCH v10 1/2 x86/kexec: VMCLEAR VMCSs loaded on all cpus if necessary
This patch provides a way to VMCLEAR VMCSs related to guests on all cpus before executing the VMXOFF when doing kdump. This is used to ensure the VMCSs in the vmcore updated and non-corrupted.
--- arch/x86/include/asm/kexec.h | 2 ++ arch/x86/kernel/crash.c | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 34 insertions(+), 0 deletions(-)
arch/x86/include/asm/kexec.h +2 -0
@@ -163,6 +163,8 @@ struct kimage_arch { };#endif +extern void (*crash_vmclear_loaded_vmcss)(void ); +#endif /* __ASSEMBLY__ */ #endif /* _ASM_X86_KEXEC_H */
arch/x86/kernel/crash.c +32 -0
@@ -16,6 +16,7 @@#include <linux/delay.h> #include <linux/elf.h> #include <linux/elfcore.h> +#include <linux/module.h> #include <asm/processor.h> #include <asm/hardirq.h>
@@ -30,6 +31,27 @@int in_crash_kexec; +/* +* This is used to VMCLEAR all VMCSs loaded on the +* processor. And when loading kvm_intel module, the +* callback function pointer will be assigned. +* +* protected by rcu. +*/ +void (*crash_vmclear_loaded_vmcss)(void ) =NULL ; +EXPORT_SYMBOL_GPL (crash_vmclear_loaded_vmcss); + +static inline void cpu_crash_vmclear_loaded_vmcss (void ) +{ +void (*do_vmclear_operation)(void ) =NULL ; + + rcu_read_lock() + do_vmclear_operation =rcu_dereference (crash_vmclear_loaded_vmcss); +if (do_vmclear_operation) +do_vmclear_opertaion (); +rcu_read_unlock (); +} +#if defined(CONFIG_SMP ) && defined(CONFIG_X86_LOCAL_APIC )static void kdump_nmi_callback (int cpu,struct pt_regs *regs)
@@ -46,6 +68,11 @@ static void kdump_nmi_callback(int cpu, struct pt_regs *regs)#endif crash_save_cpu (regs, cpu); +/* +* VMCLEAR VMCSs loaded on all cpus if needed. +*/ +cpu_crash_vmclear_loaded_vmcss (); +/* Disable VMX or SVM if needed. * * We need to disable virtualization on all CPUs.
@@ -88,6 +115,11 @@ void native_machine_crash_shutdown(struct pt_regs *regs)kdump_nmi_shootdown_cpus (); +/* +* VMCLEAR VMCSs loaded on this cpu if needed. +*/ +cpu_crash_vmclear_loaded_vmcss (); +/* Booting kdump kernel with VMX or SVM enabled won't work, * because (among other limitations) we can't disable paging * with the virt flags.
Signature · 1 line
1.7.1
Re: [PATCH v10 2/2] KVM-INTEL: provide the vmclear function and a bitmap to support VMCLEAR in kdump
In reply to Zhang YanfeiThe vmclear function will be assigned to the callback function pointer when loading kvm-intel module. And the bitmap indicates whether we should do VMCLEAR operation in kdump. The bits in the bitmap are set/unset according to different conditions.
--- arch/x86/kvm/vmx.c | 67 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 67 insertions(+), 0 deletions(-)
arch/x86/kvm/vmx.c +67 -0
@@ -42,6 +42,7 @@#include <asm/i387.h> #include <asm/xcr.h> #include <asm/perf_event.h> +#include <asm/kexec.h> #include "trace.h"
@@ -992,6 +993,46 @@ static void vmcs_load(struct vmcs *vmcs) vmcs, phys_addr); } +#ifdef CONFIG_KEXEC +/* +* This bitmap is used to indicate whether the vmclear +* operation is enabled on all cpus. All disabled by +* default. +*/ +static cpumask_t crash_vmclear_enabled_bitmap =CPU_MASK_NONE ; + +static inline void crash_enable_local_vmclear (int cpu) +{ +cpumask_set_cpu (cpu, &crash_vmclear_enabled_bitmap); +} + +static inline void crash_disable_local_vmclear (int cpu) +{ +cpumask_clear_cpu (cpu, &crash_vmclear_enabled_bitmap); +} + +static inline int crash_local_vmclear_enabled (int cpu) +{ +return cpumask_test_cpu (cpu, &crash_vmclear_enabled_bitmap); +} + +static void crash_vmclear_local_loaded_vmcss (void ) +{ +int cpu =raw_smp_processor_id (); +struct loaded_vmcs *v; + +if (!crash_local_vmclear_enabled (cpu)) +return ; + +list_for_each_entry (v, &per_cpu (loaded_vmcss_on_cpu, cpu), + loaded_vmcss_on_cpu_link) +vmcs_clear (v->vmcs); +} +#else +static inline void crash_enable_local_vmclear (int cpu) { } +static inline void crash_disable_local_vmclear (int cpu) { } +#endif /* CONFIG_KEXEC */ +static void __loaded_vmcs_clear (void *arg) {struct loaded_vmcs *loaded_vmcs = arg;
@@ -1001,8 +1042,10 @@ static void __loaded_vmcs_clear(void *arg)return ;/* vcpu migration can race with cpu offline */ if (per_cpu (current_vmcs, cpu) == loaded_vmcs->vmcs)per_cpu (current_vmcs, cpu) =NULL ; +crash_disable_local_vmclear (cpu);list_del (&loaded_vmcs->loaded_vmcss_on_cpu_link);loaded_vmcs_init (loaded_vmcs); +crash_enable_local_vmclear (cpu); }static void loaded_vmcs_clear (struct loaded_vmcs *loaded_vmcs)
@@ -1535,8 +1578,10 @@ static void vmx_vcpu_load(struct kvm_vcpu *vcpu, int cpu)kvm_make_request (KVM_REQ_TLB_FLUSH , vcpu);local_irq_disable (); +crash_disable_local_vmclear (cpu);list_add (&vmx->loaded_vmcs->loaded_vmcss_on_cpu_link, &per_cpu (loaded_vmcss_on_cpu, cpu)); +crash_enable_local_vmclear (cpu);local_irq_enable ();/*
@@ -2341,6 +2386,18 @@ static int hardware_enable(void *garbage)return -EBUSY ;INIT_LIST_HEAD (&per_cpu (loaded_vmcss_on_cpu, cpu)); + +/* +* Now we can enable the vmclear operation in kdump +* since the loaded_vmcss_on_cpu list on this cpu +* has been initialized. +* +* Though the cpu is not in VMX operation now, there +* is no problem to enable the vmclear operation +* for the loaded_vmcss_on_cpu list is empty! +*/ +crash_enable_local_vmclear (cpu); +rdmsrl (MSR_IA32_FEATURE_CONTROL , old); test_bits =FEATURE_CONTROL_LOCKED ;
@@ -7367,6 +7424,11 @@ static int __init vmx_init(void)if (r) goto out3; +#ifdef CONFIG_KEXEC +rcu_assign_pointer (crash_vmclear_loaded_vmcss, + crash_vmclear_local_loaded_vmcss); +#endif +vmx_disable_intercept_for_msr (MSR_FS_BASE , false);vmx_disable_intercept_for_msr (MSR_GS_BASE , false);vmx_disable_intercept_for_msr (MSR_KERNEL_GS_BASE , true);
@@ -7404,6 +7466,11 @@ static void __exit vmx_exit(void)free_page ((unsigned long )vmx_io_bitmap_b);free_page ((unsigned long )vmx_io_bitmap_a); +#ifdef CONFIG_KEXEC +rcu_assign_pointer (crash_vmclear_loaded_vmcss,NULL ); +synchronize_rcu (); +#endif +kvm_exit (); }
Signature · 1 line
1.7.1
Quoted 9 lines · Zhang Yanfei
Currently, kdump just makes all the logical processors leave VMX operation by executing VMXOFF instruction, so any VMCSs active on the logical processors may be corrupted. But, sometimes, we need the VMCSs to debug guest images contained in the host vmcore. To prevent the corruption, we should VMCLEAR the VMCSs before executing the VMXOFF instruction.
The patch set provides a way to VMCLEAR vmcss related to guests on all cpus before executing the VMXOFF when doing kdump. This is used to ensure the VMCSs in the vmcore updated and non-corrupted.
Skimming through it looks like the important things have been addressed.
Quoted 48 lines
Changelog from v9 to v10:
1. add rcu protect to the callback functionChangelog from v8 to v9:
1. KEXEC: use a callback function instead of a notifier.
2. KVM-INTEL: use a new vmclear function instead of just callingvmclear_local_loaded_vmcssto make sure we just do the core vmclear operation in kdump.Changelog from v7 to v8:
1. KEXEC: regression for using namecrash_notifier_listand remove comments related to KVM
and just call functionatomic_notifier_call_chaindirectly.Changelog from v6 to v7:
1. KVM-INTEL: inhardware_disable, we needn't disable the vmclear, so remove it.Changelog from v5 to v6:
1. KEXEC: the atomic notifier list renamed:crash_notifier_list --> vmclear_notifier_list2. KVM-INTEL: provide empty functions if
CONFIG_KEXECis not defined and remove unnecessary #ifdef's.Changelog from v4 to v5:
1. use an atomic notifier instead of function call, so have all the vmclear codes invmx.c.Changelog from v3 to v4:
1. add a new percpu variablevmclear_skippedto skip vmclear in kdump in some conditions.Changelog from v2 to v3:
1. remove unnecessary conditions in functioncpu_emergency_clear_loaded_vmcssas Marcelo suggested.Changelog from v1 to v2:
1. remove the sysctl and clear VMCSs unconditionally.Zhang Yanfei (2):
x86/kexec: VMCLEAR VMCSs loaded on all cpus if necessary
KVM-INTEL: provide the vmclear function and a bitmap to support
VMCLEAR in kdumparch/x86/include/asm/kexec.h | 2 + arch/x86/kernel/crash.c | 32 ++++++++++++++++++++ arch/x86/kvm/vmx.c | 67 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 101 insertions(+), 0 deletions(-)
Can you regenerate against current queue branch ingit://git.kernel.org/pub/scm/virt/kvm/kvm.git please?
Quoted 54 lines · Zhang Yanfei
Currently, kdump just makes all the logical processors leave VMX operation by executing VMXOFF instruction, so any VMCSs active on the logical processors may be corrupted. But, sometimes, we need the VMCSs to debug guest images contained in the host vmcore. To prevent the corruption, we should VMCLEAR the VMCSs before executing the VMXOFF instruction.
The patch set provides a way to VMCLEAR vmcss related to guests on all cpus before executing the VMXOFF when doing kdump. This is used to ensure the VMCSs in the vmcore updated and non-corrupted.
Changelog from v9 to v10:
1. add rcu protect to the callback functionChangelog from v8 to v9:
1. KEXEC: use a callback function instead of a notifier.
2. KVM-INTEL: use a new vmclear function instead of just callingvmclear_local_loaded_vmcssto make sure we just do the core vmclear operation in kdump.Changelog from v7 to v8:
1. KEXEC: regression for using namecrash_notifier_listand remove comments related to KVM
and just call functionatomic_notifier_call_chaindirectly.Changelog from v6 to v7:
1. KVM-INTEL: inhardware_disable, we needn't disable the vmclear, so remove it.Changelog from v5 to v6:
1. KEXEC: the atomic notifier list renamed:crash_notifier_list --> vmclear_notifier_list2. KVM-INTEL: provide empty functions if
CONFIG_KEXECis not defined and remove unnecessary #ifdef's.Changelog from v4 to v5:
1. use an atomic notifier instead of function call, so have all the vmclear codes invmx.c.Changelog from v3 to v4:
1. add a new percpu variablevmclear_skippedto skip vmclear in kdump in some conditions.Changelog from v2 to v3:
1. remove unnecessary conditions in functioncpu_emergency_clear_loaded_vmcssas Marcelo suggested.Changelog from v1 to v2:
1. remove the sysctl and clear VMCSs unconditionally.Zhang Yanfei (2):
x86/kexec: VMCLEAR VMCSs loaded on all cpus if necessary
KVM-INTEL: provide the vmclear function and a bitmap to support
VMCLEAR in kdump
Quoted 4 lines
arch/x86/include/asm/kexec.h | 2 + arch/x86/kernel/crash.c | 32 ++++++++++++++++++++ arch/x86/kvm/vmx.c | 67 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 101 insertions(+), 0 deletions(-)
--
Gleb.