* [PATCH v10 1/2] x86/kexec: VMCLEAR VMCSs loaded on all cpus if necessary
2012-12-05 7:58 [PATCH v10 0/2] x86: vmclear vmcss on all cpus when doing kdump if necessary Zhang Yanfei
@ 2012-12-05 8:03 ` Zhang Yanfei
2012-12-05 8:06 ` [PATCH v10 2/2] KVM-INTEL: provide the vmclear function and a bitmap to support VMCLEAR in kdump Zhang Yanfei
` (2 subsequent siblings)
3 siblings, 0 replies; 5+ messages in thread
From: Zhang Yanfei @ 2012-12-05 8:03 UTC (permalink / raw)
To: Marcelo Tosatti, Gleb Natapov, Eric W. Biederman
Cc: kexec@lists.infradead.org, kvm@vger.kernel.org,
linux-kernel@vger.kernel.org
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.
Signed-off-by: Zhang Yanfei <zhangyanfei@cn.fujitsu.com>
---
arch/x86/include/asm/kexec.h | 2 ++
arch/x86/kernel/crash.c | 32 ++++++++++++++++++++++++++++++++
2 files changed, 34 insertions(+), 0 deletions(-)
diff --git a/arch/x86/include/asm/kexec.h b/arch/x86/include/asm/kexec.h
index 317ff17..28feeba 100644
--- a/arch/x86/include/asm/kexec.h
+++ b/arch/x86/include/asm/kexec.h
@@ -163,6 +163,8 @@ struct kimage_arch {
};
#endif
+extern void (*crash_vmclear_loaded_vmcss)(void);
+
#endif /* __ASSEMBLY__ */
#endif /* _ASM_X86_KEXEC_H */
diff --git a/arch/x86/kernel/crash.c b/arch/x86/kernel/crash.c
index 13ad899..b914b7f 100644
--- a/arch/x86/kernel/crash.c
+++ b/arch/x86/kernel/crash.c
@@ -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.
--
1.7.1
^ permalink raw reply related [flat|nested] 5+ messages in thread* Re: [PATCH v10 2/2] KVM-INTEL: provide the vmclear function and a bitmap to support VMCLEAR in kdump
2012-12-05 7:58 [PATCH v10 0/2] x86: vmclear vmcss on all cpus when doing kdump if necessary Zhang Yanfei
2012-12-05 8:03 ` [PATCH v10 1/2] x86/kexec: VMCLEAR VMCSs loaded on all cpus " Zhang Yanfei
@ 2012-12-05 8:06 ` Zhang Yanfei
2012-12-05 19:35 ` [PATCH v10 0/2] x86: vmclear vmcss on all cpus when doing kdump if necessary Eric W. Biederman
2012-12-06 9:39 ` Gleb Natapov
3 siblings, 0 replies; 5+ messages in thread
From: Zhang Yanfei @ 2012-12-05 8:06 UTC (permalink / raw)
To: Marcelo Tosatti, Gleb Natapov, Eric W. Biederman
Cc: kexec@lists.infradead.org, kvm@vger.kernel.org,
linux-kernel@vger.kernel.org
The 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.
Signed-off-by: Zhang Yanfei <zhangyanfei@cn.fujitsu.com>
---
arch/x86/kvm/vmx.c | 67 ++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 67 insertions(+), 0 deletions(-)
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
index f858159..2d5226a 100644
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -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();
}
--
1.7.1
^ permalink raw reply related [flat|nested] 5+ messages in thread* Re: [PATCH v10 0/2] x86: vmclear vmcss on all cpus when doing kdump if necessary
2012-12-05 7:58 [PATCH v10 0/2] x86: vmclear vmcss on all cpus when doing kdump if necessary Zhang Yanfei
2012-12-05 8:03 ` [PATCH v10 1/2] x86/kexec: VMCLEAR VMCSs loaded on all cpus " Zhang Yanfei
2012-12-05 8:06 ` [PATCH v10 2/2] KVM-INTEL: provide the vmclear function and a bitmap to support VMCLEAR in kdump Zhang Yanfei
@ 2012-12-05 19:35 ` Eric W. Biederman
2012-12-06 9:39 ` Gleb Natapov
3 siblings, 0 replies; 5+ messages in thread
From: Eric W. Biederman @ 2012-12-05 19:35 UTC (permalink / raw)
To: Zhang Yanfei
Cc: Marcelo Tosatti, Gleb Natapov, kexec@lists.infradead.org,
kvm@vger.kernel.org, linux-kernel@vger.kernel.org
Zhang Yanfei <zhangyanfei@cn.fujitsu.com> writes:
> 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.
Acked-by: "Eric W. Biederman" <ebiederm@xmission.com>
> 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(-)
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH v10 0/2] x86: vmclear vmcss on all cpus when doing kdump if necessary
2012-12-05 7:58 [PATCH v10 0/2] x86: vmclear vmcss on all cpus when doing kdump if necessary Zhang Yanfei
` (2 preceding siblings ...)
2012-12-05 19:35 ` [PATCH v10 0/2] x86: vmclear vmcss on all cpus when doing kdump if necessary Eric W. Biederman
@ 2012-12-06 9:39 ` Gleb Natapov
3 siblings, 0 replies; 5+ messages in thread
From: Gleb Natapov @ 2012-12-06 9:39 UTC (permalink / raw)
To: Zhang Yanfei
Cc: Marcelo Tosatti, Eric W. Biederman, kexec@lists.infradead.org,
kvm@vger.kernel.org, linux-kernel@vger.kernel.org
Can you regenerate against current queue branch in
git://git.kernel.org/pub/scm/virt/kvm/kvm.git please?
On Wed, Dec 05, 2012 at 03:58:50PM +0800, Zhang Yanfei wrote:
> 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(-)
--
Gleb.
^ permalink raw reply [flat|nested] 5+ messages in thread