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 kvm-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/kvm-devel