aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKeir Fraser <keir@xensource.com>2007-03-30 18:42:49 +0100
committerKeir Fraser <keir@xensource.com>2007-03-30 18:42:49 +0100
commitfe9aa493d4179d5b01572465bca8229c5f9224a9 (patch)
tree0262fb54ab02fe70b47b143c4076592600dfbbea
parent671d1e2c93c5f6f0790bc566c0a47c205e08ff9e (diff)
downloadxen-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.c4
-rw-r--r--xen/arch/x86/hvm/svm/svm.c18
-rw-r--r--xen/arch/x86/hvm/vmx/vmcs.c32
-rw-r--r--xen/arch/x86/hvm/vmx/vmx.c33
-rw-r--r--xen/include/asm-ia64/vmx_vpd.h3
-rw-r--r--xen/include/asm-x86/hvm/hvm.h2
-rw-r--r--xen/include/asm-x86/hvm/vmx/vmcs.h15
-rw-r--r--xen/include/asm-x86/hvm/vmx/vmx.h2
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
*/