[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] [HVM] Fix MSR access code.
# HG changeset patch # User kfraser@xxxxxxxxxxxxxxxxxxxxx # Node ID 62b0b520ea53a7e3bd4e34dc226716a688be698a # Parent 7a5246955bef179fb199329b4646b3eb74489735 [HVM] Fix MSR access code. - rdmsr/wrmsr always use ECX (not RCX) as register index. - SVM still had the function names explicitly in the HVM_DBG_LOG() output - the guest should (at the very minimum) see GP fault for MSRs accesses to which even fault in Xen itself Signed-off-by: Jan Beulich <jbeulich@xxxxxxxxxx> --- xen/arch/x86/hvm/svm/svm.c | 55 ++++++++++++++---------------- xen/arch/x86/hvm/vmx/vmx.c | 80 ++++++++++++++++++++++----------------------- 2 files changed, 65 insertions(+), 70 deletions(-) diff -r 7a5246955bef -r 62b0b520ea53 xen/arch/x86/hvm/svm/svm.c --- a/xen/arch/x86/hvm/svm/svm.c Tue Nov 28 11:35:10 2006 +0000 +++ b/xen/arch/x86/hvm/svm/svm.c Tue Nov 28 11:43:39 2006 +0000 @@ -277,7 +277,7 @@ static inline int long_mode_do_msr_read( struct vcpu *vc = current; struct vmcb_struct *vmcb = vc->arch.hvm_svm.vmcb; - switch (regs->ecx) + switch ((u32)regs->ecx) { case MSR_EFER: msr_content = vmcb->efer; @@ -315,7 +315,7 @@ static inline int long_mode_do_msr_read( return 0; } - HVM_DBG_LOG(DBG_LEVEL_2, "mode_do_msr_read: msr_content: %"PRIx64"\n", + HVM_DBG_LOG(DBG_LEVEL_2, "msr_content: %"PRIx64"\n", msr_content); regs->eax = (u32)(msr_content >> 0); @@ -329,11 +329,10 @@ static inline int long_mode_do_msr_write struct vcpu *v = current; struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb; - HVM_DBG_LOG(DBG_LEVEL_1, "mode_do_msr_write msr %lx " - "msr_content %"PRIx64"\n", - (unsigned long)regs->ecx, msr_content); - - switch ( regs->ecx ) + HVM_DBG_LOG(DBG_LEVEL_1, "msr %x msr_content %"PRIx64"\n", + (u32)regs->ecx, msr_content); + + switch ( (u32)regs->ecx ) { case MSR_EFER: #ifdef __x86_64__ @@ -1855,22 +1854,18 @@ static inline void svm_do_msr_access( struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb; int inst_len; u64 msr_content=0; - u32 eax, edx; + u32 ecx = regs->ecx, eax, edx; ASSERT(vmcb); - HVM_DBG_LOG(DBG_LEVEL_1, "svm_do_msr_access: ecx=%lx, eax=%lx, edx=%lx, " - "exitinfo = %lx", (unsigned long)regs->ecx, - (unsigned long)regs->eax, (unsigned long)regs->edx, + HVM_DBG_LOG(DBG_LEVEL_1, "ecx=%x, eax=%x, edx=%x, exitinfo = %lx", + ecx, (u32)regs->eax, (u32)regs->edx, (unsigned long)vmcb->exitinfo1); /* is it a read? */ if (vmcb->exitinfo1 == 0) { - inst_len = __get_instruction_length(vmcb, INSTR_RDMSR, NULL); - - regs->edx = 0; - switch (regs->ecx) { + switch (ecx) { case MSR_IA32_TIME_STAMP_COUNTER: msr_content = hvm_get_guest_time(v); break; @@ -1890,25 +1885,30 @@ static inline void svm_do_msr_access( if (long_mode_do_msr_read(regs)) goto done; - if ( rdmsr_hypervisor_regs(regs->ecx, &eax, &edx) ) + if ( rdmsr_hypervisor_regs(ecx, &eax, &edx) || + rdmsr_safe(ecx, eax, edx) == 0 ) { regs->eax = eax; regs->edx = edx; goto done; } - - rdmsr_safe(regs->ecx, regs->eax, regs->edx); - break; + svm_inject_exception(v, TRAP_gp_fault, 1, 0); + return; } regs->eax = msr_content & 0xFFFFFFFF; regs->edx = msr_content >> 32; + + done: + HVM_DBG_LOG(DBG_LEVEL_1, "returns: ecx=%x, eax=%lx, edx=%lx", + ecx, (unsigned long)regs->eax, (unsigned long)regs->edx); + + inst_len = __get_instruction_length(vmcb, INSTR_RDMSR, NULL); } else { - inst_len = __get_instruction_length(vmcb, INSTR_WRMSR, NULL); msr_content = (u32)regs->eax | ((u64)regs->edx << 32); - switch (regs->ecx) + switch (ecx) { case MSR_IA32_TIME_STAMP_COUNTER: hvm_set_guest_time(v, msr_content); @@ -1927,17 +1927,12 @@ static inline void svm_do_msr_access( break; default: if ( !long_mode_do_msr_write(regs) ) - wrmsr_hypervisor_regs(regs->ecx, regs->eax, regs->edx); + wrmsr_hypervisor_regs(ecx, regs->eax, regs->edx); break; } - } - - done: - - HVM_DBG_LOG(DBG_LEVEL_1, "svm_do_msr_access returns: " - "ecx=%lx, eax=%lx, edx=%lx", - (unsigned long)regs->ecx, (unsigned long)regs->eax, - (unsigned long)regs->edx); + + inst_len = __get_instruction_length(vmcb, INSTR_WRMSR, NULL); + } __update_guest_eip(vmcb, inst_len); } diff -r 7a5246955bef -r 62b0b520ea53 xen/arch/x86/hvm/vmx/vmx.c --- a/xen/arch/x86/hvm/vmx/vmx.c Tue Nov 28 11:35:10 2006 +0000 +++ b/xen/arch/x86/hvm/vmx/vmx.c Tue Nov 28 11:43:39 2006 +0000 @@ -116,7 +116,7 @@ static inline int long_mode_do_msr_read( struct vcpu *v = current; struct vmx_msr_state *guest_msr_state = &v->arch.hvm_vmx.msr_state; - switch ( regs->ecx ) { + switch ( (u32)regs->ecx ) { case MSR_EFER: HVM_DBG_LOG(DBG_LEVEL_2, "EFER msr_content 0x%"PRIx64, msr_content); msr_content = guest_msr_state->msrs[VMX_INDEX_MSR_EFER]; @@ -169,10 +169,10 @@ static inline int long_mode_do_msr_write struct vmx_msr_state *guest_msr_state = &v->arch.hvm_vmx.msr_state; struct vmx_msr_state *host_msr_state = &this_cpu(host_msr_state); - HVM_DBG_LOG(DBG_LEVEL_1, "msr 0x%lx msr_content 0x%"PRIx64"\n", - (unsigned long)regs->ecx, msr_content); - - switch ( regs->ecx ) { + HVM_DBG_LOG(DBG_LEVEL_1, "msr 0x%x msr_content 0x%"PRIx64"\n", + (u32)regs->ecx, msr_content); + + switch ( (u32)regs->ecx ) { case MSR_EFER: /* offending reserved bit will cause #GP */ if ( msr_content & ~(EFER_LME | EFER_LMA | EFER_NX | EFER_SCE) ) @@ -1790,16 +1790,16 @@ static int vmx_cr_access(unsigned long e return 1; } -static inline void vmx_do_msr_read(struct cpu_user_regs *regs) +static inline int vmx_do_msr_read(struct cpu_user_regs *regs) { u64 msr_content = 0; - u32 eax, edx; + u32 ecx = regs->ecx, eax, edx; struct vcpu *v = current; - HVM_DBG_LOG(DBG_LEVEL_1, "ecx=%lx, eax=%lx, edx=%lx", - (unsigned long)regs->ecx, (unsigned long)regs->eax, - (unsigned long)regs->edx); - switch (regs->ecx) { + HVM_DBG_LOG(DBG_LEVEL_1, "ecx=%x, eax=%x, edx=%x", + ecx, (u32)regs->eax, (u32)regs->edx); + + switch (ecx) { case MSR_IA32_TIME_STAMP_COUNTER: msr_content = hvm_get_guest_time(v); break; @@ -1817,39 +1817,41 @@ static inline void vmx_do_msr_read(struc break; default: if ( long_mode_do_msr_read(regs) ) - return; - - if ( rdmsr_hypervisor_regs(regs->ecx, &eax, &edx) ) + goto done; + + if ( rdmsr_hypervisor_regs(ecx, &eax, &edx) || + rdmsr_safe(ecx, eax, edx) == 0 ) { regs->eax = eax; regs->edx = edx; - return; - } - - rdmsr_safe(regs->ecx, regs->eax, regs->edx); - return; + goto done; + } + vmx_inject_hw_exception(v, TRAP_gp_fault, 0); + return 0; } regs->eax = msr_content & 0xFFFFFFFF; regs->edx = msr_content >> 32; - HVM_DBG_LOG(DBG_LEVEL_1, "returns: ecx=%lx, eax=%lx, edx=%lx", - (unsigned long)regs->ecx, (unsigned long)regs->eax, +done: + HVM_DBG_LOG(DBG_LEVEL_1, "returns: ecx=%x, eax=%lx, edx=%lx", + ecx, (unsigned long)regs->eax, (unsigned long)regs->edx); -} - -static inline void vmx_do_msr_write(struct cpu_user_regs *regs) -{ + return 1; +} + +static inline int vmx_do_msr_write(struct cpu_user_regs *regs) +{ + u32 ecx = regs->ecx; u64 msr_content; struct vcpu *v = current; - HVM_DBG_LOG(DBG_LEVEL_1, "ecx=%lx, eax=%lx, edx=%lx", - (unsigned long)regs->ecx, (unsigned long)regs->eax, - (unsigned long)regs->edx); + HVM_DBG_LOG(DBG_LEVEL_1, "ecx=%x, eax=%x, edx=%x", + ecx, (u32)regs->eax, (u32)regs->edx); msr_content = (u32)regs->eax | ((u64)regs->edx << 32); - switch (regs->ecx) { + switch (ecx) { case MSR_IA32_TIME_STAMP_COUNTER: { struct periodic_time *pt = @@ -1874,13 +1876,11 @@ static inline void vmx_do_msr_write(stru break; default: if ( !long_mode_do_msr_write(regs) ) - wrmsr_hypervisor_regs(regs->ecx, regs->eax, regs->edx); - break; - } - - HVM_DBG_LOG(DBG_LEVEL_1, "returns: ecx=%lx, eax=%lx, edx=%lx", - (unsigned long)regs->ecx, (unsigned long)regs->eax, - (unsigned long)regs->edx); + wrmsr_hypervisor_regs(ecx, regs->eax, regs->edx); + break; + } + + return 1; } static void vmx_do_hlt(void) @@ -2244,16 +2244,16 @@ asmlinkage void vmx_vmexit_handler(struc break; case EXIT_REASON_MSR_READ: inst_len = __get_instruction_length(); /* Safe: RDMSR */ - __update_guest_eip(inst_len); - vmx_do_msr_read(regs); + if ( vmx_do_msr_read(regs) ) + __update_guest_eip(inst_len); TRACE_VMEXIT(1, regs->ecx); TRACE_VMEXIT(2, regs->eax); TRACE_VMEXIT(3, regs->edx); break; case EXIT_REASON_MSR_WRITE: inst_len = __get_instruction_length(); /* Safe: WRMSR */ - __update_guest_eip(inst_len); - vmx_do_msr_write(regs); + if ( vmx_do_msr_write(regs) ) + __update_guest_eip(inst_len); TRACE_VMEXIT(1, regs->ecx); TRACE_VMEXIT(2, regs->eax); TRACE_VMEXIT(3, regs->edx); _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |