* [PATCH v11 1/2] x86/kexec: VMCLEAR VMCSs loaded on all cpus if necessary
2012-12-06 15:36 [PATCH v11 0/2] x86: vmclear vmcss on all cpus when doing kdump if necessary Zhang Yanfei
@ 2012-12-06 15:40 ` Zhang Yanfei
2012-12-06 15:43 ` [PATCH v11 2/2] KVM-INTEL: provide the vmclear function and a bitmap to support VMCLEAR in kdump Zhang Yanfei
2012-12-06 16:28 ` [PATCH v11 0/2] x86: vmclear vmcss on all cpus when doing kdump if necessary Gleb Natapov
2 siblings, 0 replies; 4+ messages in thread
From: Zhang Yanfei @ 2012-12-06 15:40 UTC (permalink / raw)
To: Marcelo Tosatti, Gleb Natapov, Eric W. Biederman; +Cc: kexec, kvm, linux-kernel
From: Zhang Yanfei <zhangyanfei@cn.fujitsu.com>
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>
Acked-by: Eric W. Biederman <ebiederm@xmission.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_operation();
+ 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] 4+ messages in thread
* Re: [PATCH v11 2/2] KVM-INTEL: provide the vmclear function and a bitmap to support VMCLEAR in kdump
2012-12-06 15:36 [PATCH v11 0/2] x86: vmclear vmcss on all cpus when doing kdump if necessary Zhang Yanfei
2012-12-06 15:40 ` [PATCH v11 1/2] x86/kexec: VMCLEAR VMCSs loaded on all cpus " Zhang Yanfei
@ 2012-12-06 15:43 ` Zhang Yanfei
2012-12-06 16:28 ` [PATCH v11 0/2] x86: vmclear vmcss on all cpus when doing kdump if necessary Gleb Natapov
2 siblings, 0 replies; 4+ messages in thread
From: Zhang Yanfei @ 2012-12-06 15:43 UTC (permalink / raw)
To: Marcelo Tosatti, Gleb Natapov, Eric W. Biederman; +Cc: kexec, kvm, linux-kernel
From: Zhang Yanfei <zhangyanfei@cn.fujitsu.com>
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 94833e2..1a30fd5 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"
@@ -987,6 +988,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;
@@ -996,6 +1037,7 @@ 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);
/*
@@ -1007,6 +1049,7 @@ static void __loaded_vmcs_clear(void *arg)
smp_wmb();
loaded_vmcs_init(loaded_vmcs);
+ crash_enable_local_vmclear(cpu);
}
static void loaded_vmcs_clear(struct loaded_vmcs *loaded_vmcs)
@@ -1530,6 +1573,7 @@ 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);
/*
* Read loaded_vmcs->cpu should be before fetching
@@ -1540,6 +1584,7 @@ static void vmx_vcpu_load(struct kvm_vcpu *vcpu, int 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();
/*
@@ -2353,6 +2398,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;
@@ -7383,6 +7440,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);
@@ -7420,6 +7482,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] 4+ messages in thread
* Re: [PATCH v11 0/2] x86: vmclear vmcss on all cpus when doing kdump if necessary
2012-12-06 15:36 [PATCH v11 0/2] x86: vmclear vmcss on all cpus when doing kdump if necessary Zhang Yanfei
2012-12-06 15:40 ` [PATCH v11 1/2] x86/kexec: VMCLEAR VMCSs loaded on all cpus " Zhang Yanfei
2012-12-06 15:43 ` [PATCH v11 2/2] KVM-INTEL: provide the vmclear function and a bitmap to support VMCLEAR in kdump Zhang Yanfei
@ 2012-12-06 16:28 ` Gleb Natapov
2 siblings, 0 replies; 4+ messages in thread
From: Gleb Natapov @ 2012-12-06 16:28 UTC (permalink / raw)
To: Zhang Yanfei; +Cc: Marcelo Tosatti, Eric W. Biederman, kexec, kvm, linux-kernel
On Thu, Dec 06, 2012 at 11:36:48PM +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.
>
Applied to queue. Thanks.
> Changelog from v10 to v11:
> 1. regenerate the patch set against current queue branch in
> git://git.kernel.org/pub/scm/virt/kvm/kvm.git
>
> 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] 4+ messages in thread