[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-4.0-testing] hvm amd: Fix 32bit guest VM save/restore issues associated with SYSENTER MSRs
# HG changeset patch # User Keir Fraser <keir@xxxxxxx> # Date 1297013950 0 # Node ID 3e47933c9623b594ca9b44d845acef6e51bd2f4c # Parent 0b16e1d60871aaeb94ca1e8e83a41b54b4579f07 hvm amd: Fix 32bit guest VM save/restore issues associated with SYSENTER MSRs This patch turn-on SYSENTER MSRs interception for 32bit guest VMs on AMD CPUs. With it, hvm_svm.guest_sysenter_xx fields always contain the canonical version of SYSENTER MSRs and are used in guest save/restore. The data fields in VMCB save area are updated as necessary. Reported-by: James Harper <james.harper@xxxxxxxxxxxxxxxx> Signed-off-by: Wei Huang <wei.huang2@xxxxxxx> xen-unstable changeset: 22873:186162762071 xen-unstable date: Sun Feb 06 17:03:09 2011 +0000 --- xen/arch/x86/hvm/svm/svm.c | 41 ++++++++++++++++++++++++++--------------- 1 files changed, 26 insertions(+), 15 deletions(-) diff -r 0b16e1d60871 -r 3e47933c9623 xen/arch/x86/hvm/svm/svm.c --- a/xen/arch/x86/hvm/svm/svm.c Wed Jan 26 09:05:53 2011 +0000 +++ b/xen/arch/x86/hvm/svm/svm.c Sun Feb 06 17:39:10 2011 +0000 @@ -251,10 +251,11 @@ static int svm_vmcb_restore(struct vcpu hvm_update_guest_cr(v, 2); hvm_update_guest_cr(v, 4); - v->arch.hvm_svm.guest_sysenter_cs = c->sysenter_cs; - v->arch.hvm_svm.guest_sysenter_esp = c->sysenter_esp; - v->arch.hvm_svm.guest_sysenter_eip = c->sysenter_eip; - + /* Load sysenter MSRs into both VMCB save area and VCPU fields. */ + vmcb->sysenter_cs = v->arch.hvm_svm.guest_sysenter_cs = c->sysenter_cs; + vmcb->sysenter_esp = v->arch.hvm_svm.guest_sysenter_esp = c->sysenter_esp; + vmcb->sysenter_eip = v->arch.hvm_svm.guest_sysenter_eip = c->sysenter_eip; + if ( paging_mode_hap(v->domain) ) { vmcb->np_enable = 1; @@ -449,14 +450,6 @@ static void svm_update_guest_efer(struct vmcb->efer = (v->arch.hvm_vcpu.guest_efer | EFER_SVME) & ~EFER_LME; if ( lma ) vmcb->efer |= EFER_LME; - - /* - * In legacy mode (EFER.LMA=0) we natively support SYSENTER/SYSEXIT with - * no need for MSR intercepts. When EFER.LMA=1 we must trap and emulate. - */ - svm_intercept_msr(v, MSR_IA32_SYSENTER_CS, lma); - svm_intercept_msr(v, MSR_IA32_SYSENTER_ESP, lma); - svm_intercept_msr(v, MSR_IA32_SYSENTER_EIP, lma); } static void svm_sync_vmcb(struct vcpu *v) @@ -1099,6 +1092,21 @@ static int svm_msr_write_intercept(struc u32 ecx = regs->ecx; struct vcpu *v = current; struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb; + int sync = 0; + + switch ( ecx ) + { + case MSR_IA32_SYSENTER_CS: + case MSR_IA32_SYSENTER_ESP: + case MSR_IA32_SYSENTER_EIP: + sync = 1; + break; + default: + break; + } + + if ( sync ) + svm_sync_vmcb(v); msr_content = (u32)regs->eax | ((u64)regs->edx << 32); @@ -1110,13 +1118,13 @@ static int svm_msr_write_intercept(struc goto gpf; case MSR_IA32_SYSENTER_CS: - v->arch.hvm_svm.guest_sysenter_cs = msr_content; + vmcb->sysenter_cs = v->arch.hvm_svm.guest_sysenter_cs = msr_content; break; case MSR_IA32_SYSENTER_ESP: - v->arch.hvm_svm.guest_sysenter_esp = msr_content; + vmcb->sysenter_esp = v->arch.hvm_svm.guest_sysenter_esp = msr_content; break; case MSR_IA32_SYSENTER_EIP: - v->arch.hvm_svm.guest_sysenter_eip = msr_content; + vmcb->sysenter_eip = v->arch.hvm_svm.guest_sysenter_eip = msr_content; break; case MSR_IA32_DEBUGCTLMSR: @@ -1163,6 +1171,9 @@ static int svm_msr_write_intercept(struc } break; } + + if ( sync ) + svm_vmload(vmcb); return X86EMUL_OKAY; _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |