Skip to contentSkip to conversation

x86: vmclear vmcss on all cpus when doing kdump if necessary

PATCH Superseded Zhang Yanfei 2 participants 9 messages Nov 21, 2012 – Nov 22, 2012

Subsystems (5)
x86 KVM KVM x86 Live update +1 more subsystems

v5 of 10 Superseded Latest is v10 →

lore
Share & tools
lore
#0 lore raw

v5 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 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 on all cpus if necessary
KVM-INTEL: add a notifier and a bitmap to support VMCLEAR in kdump

 arch/x86/include/asm/kexec.h |    2 +
 arch/x86/kernel/crash.c      |   25 ++++++++++++
 arch/x86/kvm/vmx.c           |   85 ++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 112 insertions(+), 0 deletions(-)
#1 lore raw

PATCH v5 1/2 x86/kexec: VMCLEAR vmcss on all cpus if necessary

This patch adds an atomic notifier list named crash_notifier_list. When loading kvm-intel module, a notifier will be registered in the list to enable vmcss loaded on all cpus to be VMCLEAR'd if needed.

---
 arch/x86/include/asm/kexec.h |    2 ++
 arch/x86/kernel/crash.c      |   25 +++++++++++++++++++++++++
 2 files changed, 27 insertions(+), 0 deletions(-)
arch/x86/include/asm/kexec.h +2 -0
index 317ff17..5e22b00 100644
@@ -163,6 +163,8 @@ struct kimage_arch {
 };
 #endif
 
+extern struct atomic_notifier_head crash_notifier_list;
+
 #endif /* __ASSEMBLY__ */
 
 #endif /* _ASM_X86_KEXEC_H */
arch/x86/kernel/crash.c +25 -0
index 13ad899..0f3d5b4 100644
@@ -16,6 +16,8 @@
 #include <linux/delay.h>
 #include <linux/elf.h>
 #include <linux/elfcore.h>
+#include <linux/module.h>
+#include <linux/notifier.h>
 
 #include <asm/processor.h>
 #include <asm/hardirq.h>
@@ -30,6 +32,19 @@
 
 int in_crash_kexec;
 
+/*
+ * The list is used to VMCLEAR vmcss loaded on all
+ * cpus. And when loading kvm_intel module, the
+ * vmclear function will be registered in the list.
+ */
+ATOMIC_NOTIFIER_HEAD(crash_notifier_list);
+EXPORT_SYMBOL_GPL(crash_notifier_list);
+
+static inline void cpu_emergency_vmclear_loaded_vmcss(void)
+{
+	atomic_notifier_call_chain(&crash_notifier_list, 0, NULL);
+}
+
 #if defined(CONFIG_SMP) && defined(CONFIG_X86_LOCAL_APIC)
 
 static void kdump_nmi_callback(int cpu, struct pt_regs *regs)
@@ -46,6 +61,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_emergency_vmclear_loaded_vmcss();
+
 	/* Disable VMX or SVM if needed.
 	 *
 	 * We need to disable virtualization on all CPUs.
@@ -88,6 +108,11 @@ void native_machine_crash_shutdown(struct pt_regs *regs)
 
 	kdump_nmi_shootdown_cpus();
 
+	/*
+	 * VMCLEAR vmcss loaded on this cpu if needed.
+	 */
+	cpu_emergency_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
#2 lore raw

Re: [PATCH v5 1/2] x86/kexec: VMCLEAR vmcss on all cpus if necessary

Quoted 44 lines · Zhang Yanfei

This patch adds an atomic notifier list named crash_notifier_list. When loading kvm-intel module, a notifier will be registered in the list to enable vmcss loaded on all cpus to be VMCLEAR'd if needed.

---
 arch/x86/include/asm/kexec.h |    2 ++
 arch/x86/kernel/crash.c      |   25 +++++++++++++++++++++++++
 2 files changed, 27 insertions(+), 0 deletions(-)
arch/x86/include/asm/kexec.h +2 -0
index 317ff17..5e22b00 100644
@@ -163,6 +163,8 @@ struct kimage_arch {
 };
 #endif
 
+extern struct atomic_notifier_head crash_notifier_list;
+
 #endif /* __ASSEMBLY__ */
 
 #endif /* _ASM_X86_KEXEC_H */
arch/x86/kernel/crash.c +5 -0
index 13ad899..0f3d5b4 100644
@@ -16,6 +16,8 @@
 #include <linux/delay.h>
 #include <linux/elf.h>
 #include <linux/elfcore.h>
+#include <linux/module.h>
+#include <linux/notifier.h>
 
 #include <asm/processor.h>
 #include <asm/hardirq.h>
@@ -30,6 +32,19 @@
 
 int in_crash_kexec;
 
+/*
+ * The list is used to VMCLEAR vmcss loaded on all
+ * cpus. And when loading kvm_intel module, the

arch/x86/kernel/crash.c line 47

Quoted 10 lines
arch/x86/kernel/crash.c +10 -0
+ * vmclear function will be registered in the list.
+ */
+ATOMIC_NOTIFIER_HEAD(crash_notifier_list);
+EXPORT_SYMBOL_GPL(crash_notifier_list);
+
+static inline void cpu_emergency_vmclear_loaded_vmcss(void)
+{
+	atomic_notifier_call_chain(&crash_notifier_list, 0, NULL);
+}
+

The notifier list is not VMX specific. It may be used for other purposes, so please use better name or just open code it.

ACKs from kexec side are needed.

Quoted 35 lines
arch/x86/kernel/crash.c +10 -0
 #if defined(CONFIG_SMP) && defined(CONFIG_X86_LOCAL_APIC)
 
 static void kdump_nmi_callback(int cpu, struct pt_regs *regs)
@@ -46,6 +61,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_emergency_vmclear_loaded_vmcss();
+
 	/* Disable VMX or SVM if needed.
 	 *
 	 * We need to disable virtualization on all CPUs.
@@ -88,6 +108,11 @@ void native_machine_crash_shutdown(struct pt_regs *regs)
 
 	kdump_nmi_shootdown_cpus();
 
+	/*
+	 * VMCLEAR vmcss loaded on this cpu if needed.
+	 */
+	cpu_emergency_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 · 7 lines
1.7.1

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

--
Gleb.

#3 lore raw

Re: [PATCH v5 1/2] x86/kexec: VMCLEAR vmcss on all cpus if necessary

Quoted 42 lines · Gleb Natapov
Quoted 41 lines · Zhang Yanfei

This patch adds an atomic notifier list named crash_notifier_list. When loading kvm-intel module, a notifier will be registered in the list to enable vmcss loaded on all cpus to be VMCLEAR'd if needed.

---
 arch/x86/include/asm/kexec.h |    2 ++
 arch/x86/kernel/crash.c      |   25 +++++++++++++++++++++++++
 2 files changed, 27 insertions(+), 0 deletions(-)
arch/x86/include/asm/kexec.h +2 -0
index 317ff17..5e22b00 100644
@@ -163,6 +163,8 @@ struct kimage_arch {
 };
 #endif
 
+extern struct atomic_notifier_head crash_notifier_list;
+
 #endif /* __ASSEMBLY__ */
 
 #endif /* _ASM_X86_KEXEC_H */
arch/x86/kernel/crash.c +2 -0
index 13ad899..0f3d5b4 100644
@@ -16,6 +16,8 @@
 #include <linux/delay.h>
 #include <linux/elf.h>
 #include <linux/elfcore.h>
+#include <linux/module.h>
+#include <linux/notifier.h>
 
 #include <asm/processor.h>
 #include <asm/hardirq.h>
@@ -30,6 +32,19 @@
 
 int in_crash_kexec;
 
Quoted 15 lines

arch/x86/kernel/crash.c line 47

Quoted 13 lines
arch/x86/kernel/crash.c +13 -0
+/*
+ * The list is used to VMCLEAR vmcss loaded on all
+ * cpus. And when loading kvm_intel module, the
+ * vmclear function will be registered in the list.
+ */
+ATOMIC_NOTIFIER_HEAD(crash_notifier_list);
+EXPORT_SYMBOL_GPL(crash_notifier_list);
+
+static inline void cpu_emergency_vmclear_loaded_vmcss(void)
+{
+	atomic_notifier_call_chain(&crash_notifier_list, 0, NULL);
+}
+

The notifier list is not VMX specific. It may be used for other purposes, so please use better name or just open code it.

OK, thanks. crash_notifier_list --> vmclear_notifier_list? the new v6 version has been sent, any comments are welcome.

Quoted 33 lines

ACKs from kexec side are needed.

Quoted 30 lines
arch/x86/kernel/crash.c +10 -0
 #if defined(CONFIG_SMP) && defined(CONFIG_X86_LOCAL_APIC)
 
 static void kdump_nmi_callback(int cpu, struct pt_regs *regs)
@@ -46,6 +61,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_emergency_vmclear_loaded_vmcss();
+
 	/* Disable VMX or SVM if needed.
 	 *
 	 * We need to disable virtualization on all CPUs.
@@ -88,6 +108,11 @@ void native_machine_crash_shutdown(struct pt_regs *regs)
 
 	kdump_nmi_shootdown_cpus();
 
+	/*
+	 * VMCLEAR vmcss loaded on this cpu if needed.
+	 */
+	cpu_emergency_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
Quoted 9 lines
Quoted 5 lines

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/

--
Gleb.

_______________________________________________
kexec mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/kexec

#4 lore raw

Re: [PATCH v5 1/2] x86/kexec: VMCLEAR vmcss on all cpus if necessary

Quoted 59 lines · Zhang Yanfei
Quoted 42 lines · Gleb Natapov
Quoted 41 lines · Zhang Yanfei

This patch adds an atomic notifier list named crash_notifier_list. When loading kvm-intel module, a notifier will be registered in the list to enable vmcss loaded on all cpus to be VMCLEAR'd if needed.

---
 arch/x86/include/asm/kexec.h |    2 ++
 arch/x86/kernel/crash.c      |   25 +++++++++++++++++++++++++
 2 files changed, 27 insertions(+), 0 deletions(-)
arch/x86/include/asm/kexec.h +2 -0
index 317ff17..5e22b00 100644
@@ -163,6 +163,8 @@ struct kimage_arch {
 };
 #endif
 
+extern struct atomic_notifier_head crash_notifier_list;
+
 #endif /* __ASSEMBLY__ */
 
 #endif /* _ASM_X86_KEXEC_H */
arch/x86/kernel/crash.c +2 -0
index 13ad899..0f3d5b4 100644
@@ -16,6 +16,8 @@
 #include <linux/delay.h>
 #include <linux/elf.h>
 #include <linux/elfcore.h>
+#include <linux/module.h>
+#include <linux/notifier.h>
 
 #include <asm/processor.h>
 #include <asm/hardirq.h>
@@ -30,6 +32,19 @@
 
 int in_crash_kexec;
 
Quoted 15 lines

arch/x86/kernel/crash.c line 47

Quoted 13 lines
arch/x86/kernel/crash.c +13 -0
+/*
+ * The list is used to VMCLEAR vmcss loaded on all
+ * cpus. And when loading kvm_intel module, the
+ * vmclear function will be registered in the list.
+ */
+ATOMIC_NOTIFIER_HEAD(crash_notifier_list);
+EXPORT_SYMBOL_GPL(crash_notifier_list);
+
+static inline void cpu_emergency_vmclear_loaded_vmcss(void)
+{
+	atomic_notifier_call_chain(&crash_notifier_list, 0, NULL);
+}
+

The notifier list is not VMX specific. It may be used for other purposes, so please use better name or just open code it.

Quoted 1 line

OK, thanks. crash_notifier_list --> vmclear_notifier_list?

It is even worse. You are adding general infrastructure here, not related to KVM at all. Choose neutral names, drop all comments about VMCLEAR.

Quoted 45 lines

the new v6 version has been sent, any comments are welcome.

Quoted 42 lines

ACKs from kexec side are needed.

Quoted 35 lines
arch/x86/kernel/crash.c +10 -0
 #if defined(CONFIG_SMP) && defined(CONFIG_X86_LOCAL_APIC)
 
 static void kdump_nmi_callback(int cpu, struct pt_regs *regs)
@@ -46,6 +61,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_emergency_vmclear_loaded_vmcss();
+
 	/* Disable VMX or SVM if needed.
 	 *
 	 * We need to disable virtualization on all CPUs.
@@ -88,6 +108,11 @@ void native_machine_crash_shutdown(struct pt_regs *regs)
 
 	kdump_nmi_shootdown_cpus();
 
+	/*
+	 * VMCLEAR vmcss loaded on this cpu if needed.
+	 */
+	cpu_emergency_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 · 7 lines
1.7.1

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

--
Gleb.

--
Gleb.

_______________________________________________
kexec mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/kexec

#5 lore raw

Re: [PATCH v5 1/2] x86/kexec: VMCLEAR vmcss on all cpus if necessary

Quoted 60 lines · Gleb Natapov
Quoted 59 lines · Zhang Yanfei
Quoted 57 lines · Gleb Natapov
Quoted 44 lines · Zhang Yanfei

This patch adds an atomic notifier list named crash_notifier_list. When loading kvm-intel module, a notifier will be registered in the list to enable vmcss loaded on all cpus to be VMCLEAR'd if needed.

---
 arch/x86/include/asm/kexec.h |    2 ++
 arch/x86/kernel/crash.c      |   25 +++++++++++++++++++++++++
 2 files changed, 27 insertions(+), 0 deletions(-)
arch/x86/include/asm/kexec.h +2 -0
index 317ff17..5e22b00 100644
@@ -163,6 +163,8 @@ struct kimage_arch {
 };
 #endif
 
+extern struct atomic_notifier_head crash_notifier_list;
+
 #endif /* __ASSEMBLY__ */
 
 #endif /* _ASM_X86_KEXEC_H */
arch/x86/kernel/crash.c +5 -0
index 13ad899..0f3d5b4 100644
@@ -16,6 +16,8 @@
 #include <linux/delay.h>
 #include <linux/elf.h>
 #include <linux/elfcore.h>
+#include <linux/module.h>
+#include <linux/notifier.h>
 
 #include <asm/processor.h>
 #include <asm/hardirq.h>
@@ -30,6 +32,19 @@
 
 int in_crash_kexec;
 
+/*
+ * The list is used to VMCLEAR vmcss loaded on all
+ * cpus. And when loading kvm_intel module, the

arch/x86/kernel/crash.c line 47

Quoted 10 lines
arch/x86/kernel/crash.c +10 -0
+ * vmclear function will be registered in the list.
+ */
+ATOMIC_NOTIFIER_HEAD(crash_notifier_list);
+EXPORT_SYMBOL_GPL(crash_notifier_list);
+
+static inline void cpu_emergency_vmclear_loaded_vmcss(void)
+{
+	atomic_notifier_call_chain(&crash_notifier_list, 0, NULL);
+}
+

The notifier list is not VMX specific. It may be used for other purposes, so please use better name or just open code it.

Quoted 4 lines
Quoted 1 line

OK, thanks. crash_notifier_list --> vmclear_notifier_list?

It is even worse. You are adding general infrastructure here, not related to KVM at all. Choose neutral names, drop all comments about VMCLEAR.

Ah, I think I misunderstood what you mean before.
OK, I know what you mean now: make crash_notifier_list unchanged and remove the comments related to VMX
and open code the atomic_notifier_call_chain function.

Thanks

_______________________________________________
kexec mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/kexec

#6 lore raw

PATCH v5 2/2 KVM-INTEL: add a notifier and a bitmap to support VMCLEAR in kdump

In reply to Zhang Yanfei

The notifier will be registered in crash_notifier_list 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 |   85 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 85 insertions(+), 0 deletions(-)
arch/x86/kvm/vmx.c +85 -0
index 4ff0ab9..3bbdd75 100644
@@ -41,6 +41,7 @@
 #include <asm/i387.h>
 #include <asm/xcr.h>
 #include <asm/perf_event.h>
+#include <asm/kexec.h>
 
 #include "trace.h"
 
@@ -963,6 +964,30 @@ 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);
+}
+#endif
+
 static void __loaded_vmcs_clear(void *arg)
 {
 	struct loaded_vmcs *loaded_vmcs = arg;
@@ -972,8 +997,14 @@ 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;
+#ifdef CONFIG_KEXEC
+	crash_disable_local_vmclear(cpu);
+#endif
 	list_del(&loaded_vmcs->loaded_vmcss_on_cpu_link);
 	loaded_vmcs_init(loaded_vmcs);
+#ifdef CONFIG_KEXEC
+	crash_enable_local_vmclear(cpu);
+#endif
 }
 
 static void loaded_vmcs_clear(struct loaded_vmcs *loaded_vmcs)
@@ -1491,8 +1522,14 @@ static void vmx_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
 
 		kvm_make_request(KVM_REQ_TLB_FLUSH, vcpu);
 		local_irq_disable();
+#ifdef CONFIG_KEXEC
+		crash_disable_local_vmclear(cpu);
+#endif
 		list_add(&vmx->loaded_vmcs->loaded_vmcss_on_cpu_link,
 			 &per_cpu(loaded_vmcss_on_cpu, cpu));
+#ifdef CONFIG_KEXEC
+		crash_enable_local_vmclear(cpu);
+#endif
 		local_irq_enable();
 
 		/*
@@ -2302,6 +2339,20 @@ static int hardware_enable(void *garbage)
 		return -EBUSY;
 
 	INIT_LIST_HEAD(&per_cpu(loaded_vmcss_on_cpu, cpu));
+
+#ifdef CONFIG_KEXEC
+	/*
+	 * 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);
+#endif
+
 	rdmsrl(MSR_IA32_FEATURE_CONTROL, old);
 
 	test_bits = FEATURE_CONTROL_LOCKED;
@@ -2335,6 +2386,22 @@ static void vmclear_local_loaded_vmcss(void)
 		__loaded_vmcs_clear(v);
 }
 
+#ifdef CONFIG_KEXEC
+static int crash_vmclear_local_loaded_vmcss(struct notifier_block *this,
+					    unsigned long val, void *ptr)
+{
+	int cpu = raw_smp_processor_id();
+
+	if (crash_local_vmclear_enabled(cpu))
+		vmclear_local_loaded_vmcss();
+
+	return NOTIFY_DONE;
+}
+
+static struct notifier_block crash_vmclear_notifier = {
+	.notifier_call = crash_vmclear_local_loaded_vmcss,
+};
+#endif
 
 /* Just like cpu_vmxoff(), but with the __kvm_handle_fault_on_reboot()
  * tricks.
@@ -2348,6 +2415,14 @@ static void hardware_disable(void *garbage)
 {
 	if (vmm_exclusive) {
 		vmclear_local_loaded_vmcss();
+#ifdef CONFIG_KEXEC
+		/*
+		 * vmclear operation in kdump should be disabled here
+		 * because the cpu is going to exit VMX operation
+		 * and the loaded_vmcss_on_cpu list may not be empty!
+		 */
+		crash_disable_local_vmclear(raw_smp_processor_id());
+#endif
 		kvm_cpu_vmxoff();
 	}
 	write_cr4(read_cr4() & ~X86_CR4_VMXE);
@@ -7230,6 +7305,11 @@ static int __init vmx_init(void)
 	if (r)
 		goto out3;
 
+#ifdef CONFIG_KEXEC
+	atomic_notifier_chain_register(&crash_notifier_list,
+				       &crash_vmclear_notifier);
+#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);
@@ -7265,6 +7345,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
+	atomic_notifier_chain_unregister(&crash_notifier_list,
+					 &crash_vmclear_notifier);
+#endif
+
 	kvm_exit();
 }
 
Signature · 1 line
1.7.1
#7 lore raw

Re: [PATCH v5 2/2] KVM-INTEL: add a notifier and a bitmap to support VMCLEAR in kdump

Quoted 54 lines · Zhang Yanfei

The notifier will be registered in crash_notifier_list 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 |   85 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 85 insertions(+), 0 deletions(-)
arch/x86/kvm/vmx.c +25 -0
index 4ff0ab9..3bbdd75 100644
@@ -41,6 +41,7 @@
 #include <asm/i387.h>
 #include <asm/xcr.h>
 #include <asm/perf_event.h>
+#include <asm/kexec.h>
 
 #include "trace.h"
 
@@ -963,6 +964,30 @@ 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);
+}
+#endif
+
 static void __loaded_vmcs_clear(void *arg)
 {
 	struct loaded_vmcs *loaded_vmcs = arg;

arch/x86/kvm/vmx.c static void __loaded_vmcs_clear(void *arg) · line 1002

Quoted 6 lines
arch/x86/kvm/vmx.c +3 -0
@@ -972,8 +997,14 @@ 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;
+#ifdef CONFIG_KEXEC
+	crash_disable_local_vmclear(cpu);
+#endif

No need for this #ifdef's. Provide empty function if CONFIG_KEXEC is not defined.

Quoted 54 lines
arch/x86/kvm/vmx.c +29 -0
 	list_del(&loaded_vmcs->loaded_vmcss_on_cpu_link);
 	loaded_vmcs_init(loaded_vmcs);
+#ifdef CONFIG_KEXEC
+	crash_enable_local_vmclear(cpu);
+#endif
 }
 
 static void loaded_vmcs_clear(struct loaded_vmcs *loaded_vmcs)
@@ -1491,8 +1522,14 @@ static void vmx_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
 
 		kvm_make_request(KVM_REQ_TLB_FLUSH, vcpu);
 		local_irq_disable();
+#ifdef CONFIG_KEXEC
+		crash_disable_local_vmclear(cpu);
+#endif
 		list_add(&vmx->loaded_vmcs->loaded_vmcss_on_cpu_link,
 			 &per_cpu(loaded_vmcss_on_cpu, cpu));
+#ifdef CONFIG_KEXEC
+		crash_enable_local_vmclear(cpu);
+#endif
 		local_irq_enable();
 
 		/*
@@ -2302,6 +2339,20 @@ static int hardware_enable(void *garbage)
 		return -EBUSY;
 
 	INIT_LIST_HEAD(&per_cpu(loaded_vmcss_on_cpu, cpu));
+
+#ifdef CONFIG_KEXEC
+	/*
+	 * 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);
+#endif
+
 	rdmsrl(MSR_IA32_FEATURE_CONTROL, old);
 
 	test_bits = FEATURE_CONTROL_LOCKED;
@@ -2335,6 +2386,22 @@ static void vmclear_local_loaded_vmcss(void)
 		__loaded_vmcs_clear(v);
 }
 
+#ifdef CONFIG_KEXEC
+static int crash_vmclear_local_loaded_vmcss(struct notifier_block *this,
+					    unsigned long val, void *ptr)
+{
+	int cpu = raw_smp_processor_id();
+

arch/x86/kvm/vmx.c static void vmclear_local_loaded_vmcss(void) · line 2404

Quoted 10 lines
arch/x86/kvm/vmx.c +10 -0
+	if (crash_local_vmclear_enabled(cpu))
+		vmclear_local_loaded_vmcss();
+
+	return NOTIFY_DONE;
+}
+
+static struct notifier_block crash_vmclear_notifier = {
+	.notifier_call = crash_vmclear_local_loaded_vmcss,
+};
+#endif

Move the function under #ifdef CONFIG_KEXEC above.

Quoted 44 lines
arch/x86/kvm/vmx.c +18 -0
 /* Just like cpu_vmxoff(), but with the __kvm_handle_fault_on_reboot()
  * tricks.
@@ -2348,6 +2415,14 @@ static void hardware_disable(void *garbage)
 {
 	if (vmm_exclusive) {
 		vmclear_local_loaded_vmcss();
+#ifdef CONFIG_KEXEC
+		/*
+		 * vmclear operation in kdump should be disabled here
+		 * because the cpu is going to exit VMX operation
+		 * and the loaded_vmcss_on_cpu list may not be empty!
+		 */
+		crash_disable_local_vmclear(raw_smp_processor_id());
+#endif
 		kvm_cpu_vmxoff();
 	}
 	write_cr4(read_cr4() & ~X86_CR4_VMXE);
@@ -7230,6 +7305,11 @@ static int __init vmx_init(void)
 	if (r)
 		goto out3;
 
+#ifdef CONFIG_KEXEC
+	atomic_notifier_chain_register(&crash_notifier_list,
+				       &crash_vmclear_notifier);
+#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);
@@ -7265,6 +7345,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
+	atomic_notifier_chain_unregister(&crash_notifier_list,
+					 &crash_vmclear_notifier);
+#endif
+
 	kvm_exit();
 }
 
Signature · 1 line
1.7.1

--
Gleb.

#8 lore raw

Re: [PATCH v5 2/2] KVM-INTEL: add a notifier and a bitmap to support VMCLEAR in kdump

Quoted 55 lines · Gleb Natapov
Quoted 54 lines · Zhang Yanfei

The notifier will be registered in crash_notifier_list 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 |   85 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 85 insertions(+), 0 deletions(-)
arch/x86/kvm/vmx.c +25 -0
index 4ff0ab9..3bbdd75 100644
@@ -41,6 +41,7 @@
 #include <asm/i387.h>
 #include <asm/xcr.h>
 #include <asm/perf_event.h>
+#include <asm/kexec.h>
 
 #include "trace.h"
 
@@ -963,6 +964,30 @@ 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);
+}
+#endif
+
 static void __loaded_vmcs_clear(void *arg)
 {
 	struct loaded_vmcs *loaded_vmcs = arg;
@@ -972,8 +997,14 @@ static void __loaded_vmcs_clear(void *arg)
Quoted 8 lines

arch/x86/kvm/vmx.c static void __loaded_vmcs_clear(void *arg) · line 1002

Quoted 6 lines
arch/x86/kvm/vmx.c +3 -0
 		return; /* vcpu migration can race with cpu offline */
 	if (per_cpu(current_vmcs, cpu) == loaded_vmcs->vmcs)
 		per_cpu(current_vmcs, cpu) = NULL;
+#ifdef CONFIG_KEXEC
+	crash_disable_local_vmclear(cpu);
+#endif

No need for this #ifdef's. Provide empty function if CONFIG_KEXEC is not defined.

OK.
the new v6 version has been sent, any comments are welcome.

Quoted 58 lines
Quoted 58 lines
arch/x86/kvm/vmx.c +32 -0
 	list_del(&loaded_vmcs->loaded_vmcss_on_cpu_link);
 	loaded_vmcs_init(loaded_vmcs);
+#ifdef CONFIG_KEXEC
+	crash_enable_local_vmclear(cpu);
+#endif
 }
 
 static void loaded_vmcs_clear(struct loaded_vmcs *loaded_vmcs)
@@ -1491,8 +1522,14 @@ static void vmx_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
 
 		kvm_make_request(KVM_REQ_TLB_FLUSH, vcpu);
 		local_irq_disable();
+#ifdef CONFIG_KEXEC
+		crash_disable_local_vmclear(cpu);
+#endif
 		list_add(&vmx->loaded_vmcs->loaded_vmcss_on_cpu_link,
 			 &per_cpu(loaded_vmcss_on_cpu, cpu));
+#ifdef CONFIG_KEXEC
+		crash_enable_local_vmclear(cpu);
+#endif
 		local_irq_enable();
 
 		/*
@@ -2302,6 +2339,20 @@ static int hardware_enable(void *garbage)
 		return -EBUSY;
 
 	INIT_LIST_HEAD(&per_cpu(loaded_vmcss_on_cpu, cpu));
+
+#ifdef CONFIG_KEXEC
+	/*
+	 * 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);
+#endif
+
 	rdmsrl(MSR_IA32_FEATURE_CONTROL, old);
 
 	test_bits = FEATURE_CONTROL_LOCKED;
@@ -2335,6 +2386,22 @@ static void vmclear_local_loaded_vmcss(void)
 		__loaded_vmcs_clear(v);
 }
 
+#ifdef CONFIG_KEXEC
+static int crash_vmclear_local_loaded_vmcss(struct notifier_block *this,
+					    unsigned long val, void *ptr)
+{
+	int cpu = raw_smp_processor_id();
+
+	if (crash_local_vmclear_enabled(cpu))
+		vmclear_local_loaded_vmcss();
+
Quoted 8 lines

arch/x86/kvm/vmx.c static void vmclear_local_loaded_vmcss(void) · line 2404

Quoted 7 lines
arch/x86/kvm/vmx.c +7 -0
+	return NOTIFY_DONE;
+}
+
+static struct notifier_block crash_vmclear_notifier = {
+	.notifier_call = crash_vmclear_local_loaded_vmcss,
+};
+#endif

Move the function under #ifdef CONFIG_KEXEC above.

ok.

Quoted 43 lines
Quoted 43 lines
arch/x86/kvm/vmx.c +18 -0
 /* Just like cpu_vmxoff(), but with the __kvm_handle_fault_on_reboot()
  * tricks.
@@ -2348,6 +2415,14 @@ static void hardware_disable(void *garbage)
 {
 	if (vmm_exclusive) {
 		vmclear_local_loaded_vmcss();
+#ifdef CONFIG_KEXEC
+		/*
+		 * vmclear operation in kdump should be disabled here
+		 * because the cpu is going to exit VMX operation
+		 * and the loaded_vmcss_on_cpu list may not be empty!
+		 */
+		crash_disable_local_vmclear(raw_smp_processor_id());
+#endif
 		kvm_cpu_vmxoff();
 	}
 	write_cr4(read_cr4() & ~X86_CR4_VMXE);
@@ -7230,6 +7305,11 @@ static int __init vmx_init(void)
 	if (r)
 		goto out3;
 
+#ifdef CONFIG_KEXEC
+	atomic_notifier_chain_register(&crash_notifier_list,
+				       &crash_vmclear_notifier);
+#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);
@@ -7265,6 +7345,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
+	atomic_notifier_chain_unregister(&crash_notifier_list,
+					 &crash_vmclear_notifier);
+#endif
+
 	kvm_exit();
 }
 
Quoted 11 lines
Quoted 2 lines
Signature · 1 line
1.7.1

--
Gleb.
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/

_______________________________________________
kexec mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/kexec