diff options
author | Keir Fraser <keir@xensource.com> | 2007-03-30 18:42:49 +0100 |
---|---|---|
committer | Keir Fraser <keir@xensource.com> | 2007-03-30 18:42:49 +0100 |
commit | fe9aa493d4179d5b01572465bca8229c5f9224a9 (patch) | |
tree | 0262fb54ab02fe70b47b143c4076592600dfbbea | |
parent | 671d1e2c93c5f6f0790bc566c0a47c205e08ff9e (diff) | |
download | xen-fe9aa493d4179d5b01572465bca8229c5f9224a9.tar.gz xen-fe9aa493d4179d5b01572465bca8229c5f9224a9.tar.bz2 xen-fe9aa493d4179d5b01572465bca8229c5f9224a9.zip |
hvm vmx: Fix MSR-intercept bitmap initialisation (two bitmap offsets
are documented the wrong way round in the current PRM Vol.3). Clear
bits in the bitmap only /after/ it has been initialised to
all-1s. Clean up start-of-day info printing.
Signed-off-by: Keir Fraser <keir@xensource.com>
-rw-r--r-- | xen/arch/x86/hvm/hvm.c | 4 | ||||
-rw-r--r-- | xen/arch/x86/hvm/svm/svm.c | 18 | ||||
-rw-r--r-- | xen/arch/x86/hvm/vmx/vmcs.c | 32 | ||||
-rw-r--r-- | xen/arch/x86/hvm/vmx/vmx.c | 33 | ||||
-rw-r--r-- | xen/include/asm-ia64/vmx_vpd.h | 3 | ||||
-rw-r--r-- | xen/include/asm-x86/hvm/hvm.h | 2 | ||||
-rw-r--r-- | xen/include/asm-x86/hvm/vmx/vmcs.h | 15 | ||||
-rw-r--r-- | xen/include/asm-x86/hvm/vmx/vmx.h | 2 |
8 files changed, 57 insertions, 52 deletions
diff --git a/xen/arch/x86/hvm/hvm.c b/xen/arch/x86/hvm/hvm.c index 3a40d69c01..60b415ea15 100644 --- a/xen/arch/x86/hvm/hvm.c +++ b/xen/arch/x86/hvm/hvm.c @@ -65,8 +65,8 @@ char __attribute__ ((__section__ (".bss.page_aligned"))) void hvm_enable(struct hvm_function_table *fns) { - if ( hvm_enabled ) - return; + BUG_ON(hvm_enabled); + printk("HVM: %s enabled\n", fns->name); /* * Allow direct access to the PC debug port (it is often used for I/O diff --git a/xen/arch/x86/hvm/svm/svm.c b/xen/arch/x86/hvm/svm/svm.c index c54d1272bd..99f3e87713 100644 --- a/xen/arch/x86/hvm/svm/svm.c +++ b/xen/arch/x86/hvm/svm/svm.c @@ -890,6 +890,7 @@ static int svm_event_injection_faulted(struct vcpu *v) } static struct hvm_function_table svm_function_table = { + .name = "SVM", .disable = stop_svm, .vcpu_initialise = svm_vcpu_initialise, .vcpu_destroy = svm_vcpu_destroy, @@ -954,9 +955,8 @@ int start_svm(void) return 0; } - if (!hsa[cpu]) - if (!(hsa[cpu] = alloc_host_save_area())) - return 0; + if ( (hsa[cpu] == NULL) && ((hsa[cpu] = alloc_host_save_area()) == NULL) ) + return 0; rdmsr(MSR_EFER, eax, edx); eax |= EFER_SVME; @@ -971,13 +971,15 @@ int start_svm(void) phys_hsa_hi = (u32) (phys_hsa >> 32); wrmsr(MSR_K8_VM_HSAVE_PA, phys_hsa_lo, phys_hsa_hi); - if (!root_vmcb[cpu]) - if (!(root_vmcb[cpu] = alloc_vmcb())) - return 0; + if ( (root_vmcb[cpu] == NULL) && + ((root_vmcb[cpu] = alloc_vmcb()) == NULL) ) + return 0; root_vmcb_pa[cpu] = virt_to_maddr(root_vmcb[cpu]); - if (cpu == 0) - setup_vmcb_dump(); + if ( cpu != 0 ) + return 1; + + setup_vmcb_dump(); hvm_enable(&svm_function_table); diff --git a/xen/arch/x86/hvm/vmx/vmcs.c b/xen/arch/x86/hvm/vmx/vmcs.c index a8d92dd1cf..beed602f9b 100644 --- a/xen/arch/x86/hvm/vmx/vmcs.c +++ b/xen/arch/x86/hvm/vmx/vmcs.c @@ -38,10 +38,10 @@ #include <asm/shadow.h> /* Dynamic (run-time adjusted) execution control flags. */ -static u32 vmx_pin_based_exec_control; -static u32 vmx_cpu_based_exec_control; -static u32 vmx_vmexit_control; -static u32 vmx_vmentry_control; +u32 vmx_pin_based_exec_control; +u32 vmx_cpu_based_exec_control; +u32 vmx_vmexit_control; +u32 vmx_vmentry_control; static u32 vmcs_revision_id; @@ -61,25 +61,6 @@ static u32 adjust_vmx_controls(u32 ctl_min, u32 ctl_max, u32 msr) return ctl; } -static void disable_intercept_for_msr(u32 msr) -{ - /* - * See Intel PRM Vol. 3, 20.6.9 (MSR-Bitmap Address). - * We can control MSRs 0x00000000-0x00001fff and 0xc0000000-0xc0001fff. - */ - if ( msr <= 0x1fff ) - { - __clear_bit(msr, hvm_msr_bitmap + 0x000); /* read-low */ - __clear_bit(msr, hvm_msr_bitmap + 0x400); /* write-low */ - } - else if ( (msr >= 0xc0000000) && (msr <= 0xc0001fff) ) - { - msr &= 0x1fff; - __clear_bit(msr, hvm_msr_bitmap + 0x800); /* read-high */ - __clear_bit(msr, hvm_msr_bitmap + 0xc00); /* write-high */ - } -} - void vmx_init_vmcs_config(void) { u32 vmx_msr_low, vmx_msr_high, min, max; @@ -125,9 +106,6 @@ void vmx_init_vmcs_config(void) vmx_cpu_based_exec_control = _vmx_cpu_based_exec_control; vmx_vmexit_control = _vmx_vmexit_control; vmx_vmentry_control = _vmx_vmentry_control; - - disable_intercept_for_msr(MSR_FS_BASE); - disable_intercept_for_msr(MSR_GS_BASE); } else { @@ -310,7 +288,7 @@ static void construct_vmcs(struct vcpu *v) __vmwrite(CPU_BASED_VM_EXEC_CONTROL, vmx_cpu_based_exec_control); v->arch.hvm_vcpu.u.vmx.exec_control = vmx_cpu_based_exec_control; - if ( vmx_cpu_based_exec_control & CPU_BASED_ACTIVATE_MSR_BITMAP ) + if ( cpu_has_vmx_msr_bitmap ) __vmwrite(MSR_BITMAP, virt_to_maddr(hvm_msr_bitmap)); /* I/O access bitmap. */ diff --git a/xen/arch/x86/hvm/vmx/vmx.c b/xen/arch/x86/hvm/vmx/vmx.c index 3856a31e96..368733c1a6 100644 --- a/xen/arch/x86/hvm/vmx/vmx.c +++ b/xen/arch/x86/hvm/vmx/vmx.c @@ -996,7 +996,28 @@ static int vmx_event_injection_faulted(struct vcpu *v) return (idtv_info_field & INTR_INFO_VALID_MASK); } +static void disable_intercept_for_msr(u32 msr) +{ + /* + * See Intel PRM Vol. 3, 20.6.9 (MSR-Bitmap Address). Early manuals + * have the write-low and read-high bitmap offsets the wrong way round. + * We can control MSRs 0x00000000-0x00001fff and 0xc0000000-0xc0001fff. + */ + if ( msr <= 0x1fff ) + { + __clear_bit(msr, hvm_msr_bitmap + 0x000); /* read-low */ + __clear_bit(msr, hvm_msr_bitmap + 0x800); /* write-low */ + } + else if ( (msr >= 0xc0000000) && (msr <= 0xc0001fff) ) + { + msr &= 0x1fff; + __clear_bit(msr, hvm_msr_bitmap + 0x400); /* read-high */ + __clear_bit(msr, hvm_msr_bitmap + 0xc00); /* write-high */ + } +} + static struct hvm_function_table vmx_function_table = { + .name = "VMX", .disable = stop_vmx, .vcpu_initialise = vmx_vcpu_initialise, .vcpu_destroy = vmx_vcpu_destroy, @@ -1074,12 +1095,20 @@ int start_vmx(void) return 0; } - printk("VMXON is done\n"); - vmx_save_host_msrs(); + if ( smp_processor_id() != 0 ) + return 1; + hvm_enable(&vmx_function_table); + if ( cpu_has_vmx_msr_bitmap ) + { + printk("VMX: MSR intercept bitmap enabled\n"); + disable_intercept_for_msr(MSR_FS_BASE); + disable_intercept_for_msr(MSR_GS_BASE); + } + return 1; } diff --git a/xen/include/asm-ia64/vmx_vpd.h b/xen/include/asm-ia64/vmx_vpd.h index 85bd0b1b0b..39acbd1c23 100644 --- a/xen/include/asm-ia64/vmx_vpd.h +++ b/xen/include/asm-ia64/vmx_vpd.h @@ -97,9 +97,6 @@ struct arch_vmx_struct { #endif }; -#define vmx_schedule_tail(next) \ - (next)->thread.arch_vmx.arch_vmx_schedule_tail((next)) - #define VMX_DOMAIN(v) v->arch.arch_vmx.flags #define ARCH_VMX_IO_WAIT 3 /* Waiting for I/O completion */ diff --git a/xen/include/asm-x86/hvm/hvm.h b/xen/include/asm-x86/hvm/hvm.h index 3d3aa35683..4872505ef3 100644 --- a/xen/include/asm-x86/hvm/hvm.h +++ b/xen/include/asm-x86/hvm/hvm.h @@ -61,6 +61,8 @@ typedef struct segment_register { * supports Intel's VT-x and AMD's SVM extensions. */ struct hvm_function_table { + char *name; + /* * Disable HVM functionality */ diff --git a/xen/include/asm-x86/hvm/vmx/vmcs.h b/xen/include/asm-x86/hvm/vmx/vmcs.h index 077dd61919..23a0b71be0 100644 --- a/xen/include/asm-x86/hvm/vmx/vmcs.h +++ b/xen/include/asm-x86/hvm/vmx/vmcs.h @@ -80,9 +80,6 @@ struct arch_vmx_struct { unsigned long vmxassist_enabled:1; }; -#define vmx_schedule_tail(next) \ - (next)->thread.arch_vmx.arch_vmx_schedule_tail((next)) - struct vmcs_struct *vmx_alloc_host_vmcs(void); void vmx_free_host_vmcs(struct vmcs_struct *vmcs); @@ -91,11 +88,6 @@ void vmx_destroy_vmcs(struct vcpu *v); void vmx_vmcs_enter(struct vcpu *v); void vmx_vmcs_exit(struct vcpu *v); -#define VMCS_USE_HOST_ENV 1 -#define VMCS_USE_SEPARATE_ENV 0 - -extern int vmcs_version; - #define CPU_BASED_VIRTUAL_INTR_PENDING 0x00000004 #define CPU_BASED_USE_TSC_OFFSETING 0x00000008 #define CPU_BASED_HLT_EXITING 0x00000080 @@ -112,16 +104,23 @@ extern int vmcs_version; #define CPU_BASED_ACTIVATE_MSR_BITMAP 0x10000000 #define CPU_BASED_MONITOR_EXITING 0x20000000 #define CPU_BASED_PAUSE_EXITING 0x40000000 +extern u32 vmx_cpu_based_exec_control; #define PIN_BASED_EXT_INTR_MASK 0x00000001 #define PIN_BASED_NMI_EXITING 0x00000008 +extern u32 vmx_pin_based_exec_control; #define VM_EXIT_IA32E_MODE 0x00000200 #define VM_EXIT_ACK_INTR_ON_EXIT 0x00008000 +extern u32 vmx_vmexit_control; #define VM_ENTRY_IA32E_MODE 0x00000200 #define VM_ENTRY_SMM 0x00000400 #define VM_ENTRY_DEACT_DUAL_MONITOR 0x00000800 +extern u32 vmx_vmentry_control; + +#define cpu_has_vmx_msr_bitmap \ + (vmx_cpu_based_exec_control & CPU_BASED_ACTIVATE_MSR_BITMAP) /* VMCS Encordings */ enum vmcs_field { diff --git a/xen/include/asm-x86/hvm/vmx/vmx.h b/xen/include/asm-x86/hvm/vmx/vmx.h index 5ee44f9650..38ad5e25bd 100644 --- a/xen/include/asm-x86/hvm/vmx/vmx.h +++ b/xen/include/asm-x86/hvm/vmx/vmx.h @@ -33,8 +33,6 @@ void vmx_intr_assist(void); void vmx_do_resume(struct vcpu *); void set_guest_time(struct vcpu *v, u64 gtime); -extern unsigned int cpu_rev; - /* * Exit Reasons */ |