# HG changeset patch
# User kaf24@xxxxxxxxxxxxxxxxxxxx
# Node ID 5b56d1e1ac8b9aa8d6b13545de772936efdfcaae
# Parent e3c7b1e974597596c842837fddba3658ee13670b
Fix VMX EFER write logic. Also some cleanups.
Signed-off-by: Xin Li <xin.b.li@xxxxxxxxx>
diff -r e3c7b1e97459 -r 5b56d1e1ac8b xen/arch/x86/hvm/vmx/vmx.c
--- a/xen/arch/x86/hvm/vmx/vmx.c Sun Mar 19 11:41:28 2006
+++ b/xen/arch/x86/hvm/vmx/vmx.c Sun Mar 19 11:48:51 2006
@@ -166,113 +166,139 @@
#define IS_CANO_ADDRESS(add) 1
static inline int long_mode_do_msr_read(struct cpu_user_regs *regs)
{
- u64 msr_content = 0;
- struct vcpu *vc = current;
- struct vmx_msr_state * msr = &vc->arch.hvm_vmx.msr_content;
- switch(regs->ecx){
+ u64 msr_content = 0;
+ struct vcpu *v = current;
+ struct vmx_msr_state *msr = &v->arch.hvm_vmx.msr_content;
+
+ switch ( regs->ecx ) {
case MSR_EFER:
+ HVM_DBG_LOG(DBG_LEVEL_2, "EFER msr_content 0x%"PRIx64, msr_content);
msr_content = msr->msr_items[VMX_INDEX_MSR_EFER];
- HVM_DBG_LOG(DBG_LEVEL_2, "EFER msr_content %"PRIx64"\n", msr_content);
- if (test_bit(VMX_CPU_STATE_LME_ENABLED,
- &vc->arch.hvm_vmx.cpu_state))
- msr_content |= 1 << _EFER_LME;
-
- if (VMX_LONG_GUEST(vc))
- msr_content |= 1 << _EFER_LMA;
- break;
+
+ /* the following code may be not needed */
+ if ( test_bit(VMX_CPU_STATE_LME_ENABLED, &v->arch.hvm_vmx.cpu_state) )
+ msr_content |= EFER_LME;
+ else
+ msr_content &= ~EFER_LME;
+
+ if ( VMX_LONG_GUEST(v) )
+ msr_content |= EFER_LMA;
+ else
+ msr_content &= ~EFER_LMA;
+ break;
+
case MSR_FS_BASE:
- if (!(VMX_LONG_GUEST(vc)))
+ if ( !(VMX_LONG_GUEST(v)) )
/* XXX should it be GP fault */
domain_crash_synchronous();
+
__vmread(GUEST_FS_BASE, &msr_content);
break;
+
case MSR_GS_BASE:
- if (!(VMX_LONG_GUEST(vc)))
+ if ( !(VMX_LONG_GUEST(v)) )
domain_crash_synchronous();
+
__vmread(GUEST_GS_BASE, &msr_content);
break;
+
case MSR_SHADOW_GS_BASE:
msr_content = msr->shadow_gs;
break;
- CASE_READ_MSR(STAR);
- CASE_READ_MSR(LSTAR);
- CASE_READ_MSR(CSTAR);
- CASE_READ_MSR(SYSCALL_MASK);
+ CASE_READ_MSR(STAR);
+ CASE_READ_MSR(LSTAR);
+ CASE_READ_MSR(CSTAR);
+ CASE_READ_MSR(SYSCALL_MASK);
+
default:
return 0;
}
- HVM_DBG_LOG(DBG_LEVEL_2, "mode_do_msr_read: msr_content: %"PRIx64"\n",
- msr_content);
+
+ HVM_DBG_LOG(DBG_LEVEL_2, "msr_content: 0x%"PRIx64, msr_content);
+
regs->eax = msr_content & 0xffffffff;
regs->edx = msr_content >> 32;
+
return 1;
}
static inline int long_mode_do_msr_write(struct cpu_user_regs *regs)
{
- u64 msr_content = regs->eax | ((u64)regs->edx << 32);
- struct vcpu *vc = current;
- struct vmx_msr_state * msr = &vc->arch.hvm_vmx.msr_content;
- struct vmx_msr_state * host_state =
- &percpu_msr[smp_processor_id()];
-
- HVM_DBG_LOG(DBG_LEVEL_1, " mode_do_msr_write msr %lx "
- "msr_content %"PRIx64"\n",
+ u64 msr_content = regs->eax | ((u64)regs->edx << 32);
+ struct vcpu *v = current;
+ struct vmx_msr_state *msr = &v->arch.hvm_vmx.msr_content;
+ struct vmx_msr_state *host_state = &percpu_msr[smp_processor_id()];
+
+ HVM_DBG_LOG(DBG_LEVEL_1, "msr 0x%lx msr_content 0x%"PRIx64"\n",
(unsigned long)regs->ecx, msr_content);
- switch (regs->ecx){
+ switch ( regs->ecx ) {
case MSR_EFER:
/* offending reserved bit will cause #GP */
- if ( msr_content &
- ~( EFER_LME | EFER_LMA | EFER_NX | EFER_SCE ) )
- vmx_inject_exception(vc, TRAP_gp_fault, 0);
-
- if ((msr_content & EFER_LME) ^
- test_bit(VMX_CPU_STATE_LME_ENABLED,
- &vc->arch.hvm_vmx.cpu_state)){
- if ( vmx_paging_enabled(vc) ||
+ if ( msr_content & ~(EFER_LME | EFER_LMA | EFER_NX | EFER_SCE) )
+ {
+ printk("trying to set reserved bit in EFER\n");
+ vmx_inject_exception(v, TRAP_gp_fault, 0);
+ return 0;
+ }
+
+ /* LME: 0 -> 1 */
+ if ( msr_content & EFER_LME &&
+ !test_bit(VMX_CPU_STATE_LME_ENABLED, &v->arch.hvm_vmx.cpu_state) )
+ {
+ if ( vmx_paging_enabled(v) ||
!test_bit(VMX_CPU_STATE_PAE_ENABLED,
- &vc->arch.hvm_vmx.cpu_state)) {
- vmx_inject_exception(vc, TRAP_gp_fault, 0);
+ &v->arch.hvm_vmx.cpu_state) )
+ {
+ printk("trying to set LME bit when "
+ "in paging mode or PAE bit is not set\n");
+ vmx_inject_exception(v, TRAP_gp_fault, 0);
+ return 0;
}
- }
- if (msr_content & EFER_LME)
- set_bit(VMX_CPU_STATE_LME_ENABLED,
- &vc->arch.hvm_vmx.cpu_state);
-
- msr->msr_items[VMX_INDEX_MSR_EFER] =
- msr_content;
+
+ set_bit(VMX_CPU_STATE_LME_ENABLED, &v->arch.hvm_vmx.cpu_state);
+ }
+
+ msr->msr_items[VMX_INDEX_MSR_EFER] = msr_content;
break;
case MSR_FS_BASE:
case MSR_GS_BASE:
- if (!(VMX_LONG_GUEST(vc)))
+ if ( !(VMX_LONG_GUEST(v)) )
domain_crash_synchronous();
- if (!IS_CANO_ADDRESS(msr_content)){
+
+ if ( !IS_CANO_ADDRESS(msr_content) )
+ {
HVM_DBG_LOG(DBG_LEVEL_1, "Not cano address of msr write\n");
- vmx_inject_exception(vc, TRAP_gp_fault, 0);
- }
- if (regs->ecx == MSR_FS_BASE)
+ vmx_inject_exception(v, TRAP_gp_fault, 0);
+ return 0;
+ }
+
+ if ( regs->ecx == MSR_FS_BASE )
__vmwrite(GUEST_FS_BASE, msr_content);
else
__vmwrite(GUEST_GS_BASE, msr_content);
+
break;
case MSR_SHADOW_GS_BASE:
- if (!(VMX_LONG_GUEST(vc)))
+ if ( !(VMX_LONG_GUEST(v)) )
domain_crash_synchronous();
- vc->arch.hvm_vmx.msr_content.shadow_gs = msr_content;
+
+ v->arch.hvm_vmx.msr_content.shadow_gs = msr_content;
wrmsrl(MSR_SHADOW_GS_BASE, msr_content);
break;
- CASE_WRITE_MSR(STAR);
- CASE_WRITE_MSR(LSTAR);
- CASE_WRITE_MSR(CSTAR);
- CASE_WRITE_MSR(SYSCALL_MASK);
+ CASE_WRITE_MSR(STAR);
+ CASE_WRITE_MSR(LSTAR);
+ CASE_WRITE_MSR(CSTAR);
+ CASE_WRITE_MSR(SYSCALL_MASK);
+
default:
return 0;
}
+
return 1;
}
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|