All the physical CPUs on the board should support the same VMX feature set. The hardware_enable() do the per-cpu check now. In case of vmx/svm enabling failure, transfer a variable in hardware_enable() for error report.
Signed-off-by: Sheng Yang <[EMAIL PROTECTED]>
---
drivers/kvm/kvm_main.c | 9 +++--
drivers/kvm/svm.c | 3 +-
drivers/kvm/vmx.c | 84
+++++++++++++++++++++++++++++-------------------
3 files changed, 59 insertions(+), 37 deletions(-)
diff --git a/drivers/kvm/kvm_main.c b/drivers/kvm/kvm_main.c
index bc11c2d..10443ea 100644
--- a/drivers/kvm/kvm_main.c
+++ b/drivers/kvm/kvm_main.c
@@ -2974,14 +2974,14 @@ static void decache_vcpus_on_cpu(int cpu)
spin_unlock(&kvm_lock);
}
-static void hardware_enable(void *junk)
+static void hardware_enable(void *rtn)
{
int cpu = raw_smp_processor_id();
if (cpu_isset(cpu, cpus_hardware_enabled))
return;
cpu_set(cpu, cpus_hardware_enabled);
- kvm_arch_ops->hardware_enable(NULL);
+ kvm_arch_ops->hardware_enable(rtn);
}
static void hardware_disable(void *junk)
@@ -3173,7 +3173,10 @@ int kvm_init_arch(struct kvm_arch_ops *ops,
struct module *module)
if (r < 0)
goto out;
- on_each_cpu(hardware_enable, NULL, 0, 1);
+ on_each_cpu(hardware_enable, &r, 0, 1);
+ if (r < 0)
+ goto out;
+
r = register_cpu_notifier(&kvm_cpu_notifier);
if (r)
goto out_free_1;
diff --git a/drivers/kvm/svm.c b/drivers/kvm/svm.c
index 850a1b1..1e76417 100644
--- a/drivers/kvm/svm.c
+++ b/drivers/kvm/svm.c
@@ -285,7 +285,7 @@ static void svm_hardware_disable(void *garbage)
}
}
-static void svm_hardware_enable(void *garbage)
+static void svm_hardware_enable(void *rtn)
{
struct svm_cpu_data *svm_data;
@@ -298,6 +298,7 @@ static void svm_hardware_enable(void *garbage)
struct desc_struct *gdt;
int me = raw_smp_processor_id();
+ *(int*)rtn = 0;
if (!has_svm()) {
printk(KERN_ERR "svm_cpu_init: err EOPNOTSUPP on %d\n",
me);
return;
diff --git a/drivers/kvm/vmx.c b/drivers/kvm/vmx.c
index e5721a5..8032c7e 100644
--- a/drivers/kvm/vmx.c
+++ b/drivers/kvm/vmx.c
@@ -756,31 +756,6 @@ static __init int vmx_disabled_by_bios(void)
/* locked but not enabled */
}
-static void hardware_enable(void *garbage)
-{
- int cpu = raw_smp_processor_id();
- u64 phys_addr = __pa(per_cpu(vmxarea, cpu));
- u64 old;
-
- rdmsrl(MSR_IA32_FEATURE_CONTROL, old);
- if ((old & (MSR_IA32_FEATURE_CONTROL_LOCKED |
- MSR_IA32_FEATURE_CONTROL_VMXON_ENABLED))
- != (MSR_IA32_FEATURE_CONTROL_LOCKED |
- MSR_IA32_FEATURE_CONTROL_VMXON_ENABLED))
- /* enable and lock */
- wrmsrl(MSR_IA32_FEATURE_CONTROL, old |
- MSR_IA32_FEATURE_CONTROL_LOCKED |
- MSR_IA32_FEATURE_CONTROL_VMXON_ENABLED);
- write_cr4(read_cr4() | X86_CR4_VMXE); /* FIXME: not cpu hotplug
safe */
- asm volatile (ASM_VMX_VMXON_RAX : : "a"(&phys_addr),
"m"(phys_addr)
- : "memory", "cc");
-}
-
-static void hardware_disable(void *garbage)
-{
- asm volatile (ASM_VMX_VMXOFF : : : "cc");
-}
-
static __init int adjust_vmx_controls(u32 ctl_min, u32 ctl_opt,
u32 msr, u32* result)
{
@@ -856,18 +831,61 @@ static __init int setup_vmcs_config(void)
if (((vmx_msr_high >> 18) & 15) != 6)
return -1;
- vmcs_config.size = vmx_msr_high & 0x1fff;
- vmcs_config.order = get_order(vmcs_config.size);
- vmcs_config.revision_id = vmx_msr_low;
-
- vmcs_config.pin_based_exec_ctrl = _pin_based_exec_control;
- vmcs_config.cpu_based_exec_ctrl = _cpu_based_exec_control;
- vmcs_config.vmexit_ctrl = _vmexit_control;
- vmcs_config.vmentry_ctrl = _vmentry_control;
+ if (vmcs_config.size == 0) {
+ /* called in hardware_setup(), initialization */
+ vmcs_config.size = vmx_msr_high & 0x1fff;
+ vmcs_config.order = get_order(vmcs_config.size);
+ vmcs_config.revision_id = vmx_msr_low;
+
+ vmcs_config.pin_based_exec_ctrl =
_pin_based_exec_control;
+ vmcs_config.cpu_based_exec_ctrl =
_cpu_based_exec_control;
+ vmcs_config.vmexit_ctrl = _vmexit_control;
+ vmcs_config.vmentry_ctrl = _vmentry_control;
+ } else if ((vmcs_config.size != (vmx_msr_high & 0x1fff))
+ || (vmcs_config.revision_id != vmx_msr_low)
+ || (vmcs_config.pin_based_exec_ctrl !=
_pin_based_exec_control)
+ || (vmcs_config.cpu_based_exec_ctrl !=
_cpu_based_exec_control)
+ || (vmcs_config.vmexit_ctrl != _vmexit_control)
+ || (vmcs_config.vmentry_ctrl != _vmentry_control)) {
+ /* called in hardware_enable(), check consistence */
+ printk(KERN_ERR "kvm: CPUs feature inconsistence!\n");
+ return -1;
+ }
return 0;
}
+static void hardware_enable(void *rtn)
+{
+ int cpu = raw_smp_processor_id();
+ u64 phys_addr = __pa(per_cpu(vmxarea, cpu));
+ u64 old;
+
+ rdmsrl(MSR_IA32_FEATURE_CONTROL, old);
+ if ((old & (MSR_IA32_FEATURE_CONTROL_LOCKED |
+ MSR_IA32_FEATURE_CONTROL_VMXON_ENABLED))
+ != (MSR_IA32_FEATURE_CONTROL_LOCKED |
+ MSR_IA32_FEATURE_CONTROL_VMXON_ENABLED))
+ /* enable and lock */
+ wrmsrl(MSR_IA32_FEATURE_CONTROL, old |
+ MSR_IA32_FEATURE_CONTROL_LOCKED |
+ MSR_IA32_FEATURE_CONTROL_VMXON_ENABLED);
+
+ *(int*)rtn = setup_vmcs_config(); /* check cpus' feature
consistence */
+ if (rtn < 0)
+ return;
+
+ write_cr4(read_cr4() | X86_CR4_VMXE); /* FIXME: not cpu hotplug
safe */
+ asm volatile (ASM_VMX_VMXON_RAX : : "a"(&phys_addr),
"m"(phys_addr)
+ : "memory", "cc");
+
+}
+
+static void hardware_disable(void *garbage)
+{
+ asm volatile (ASM_VMX_VMXOFF : : : "cc");
+}
+
static struct vmcs *alloc_vmcs_cpu(int cpu)
{
int node = cpu_to_node(cpu);
--
1.5.2
Add-cpu-consistence-check-in-vmx.patch
Description: Add-cpu-consistence-check-in-vmx.patch
------------------------------------------------------------------------- This SF.net email is sponsored by: Splunk Inc. Still grepping through log files to find problems? Stop. Now Search log events and configuration files using AJAX and a browser. Download your FREE copy of Splunk now >> http://get.splunk.com/
_______________________________________________ kvm-devel mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/kvm-devel
