Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
SUSE:SLE-12-SP1:GA
xen.10697
5ae06fad-SVM-fix-intercepts-for-SYS-CALL-ENTER-...
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File 5ae06fad-SVM-fix-intercepts-for-SYS-CALL-ENTER-MSRs.patch of Package xen.10697
# Commit c04c1866e5131e450ddcd114e32401477c60b816 # Date 2018-04-25 13:08:13 +0100 # Author Andrew Cooper <andrew.cooper3@citrix.com> # Committer Andrew Cooper <andrew.cooper3@citrix.com> x86/SVM: Fix intercepted {RD,WR}MSR for the SYS{CALL,ENTER} MSRs By default, the SYSCALL MSRs are not intercepted, and accesses are completed by hardware. The SYSENTER MSRs are intercepted for cross-vendor purposes (albeit needlessly in the common case), and are fully emulated. However, {RD,WR}MSR instructions which happen to be emulated (FEP, introspection, or older versions of Xen which intercepted #UD), or when the MSRs are explicitly intercepted (introspection), will be completed incorrectly. svm_msr_read_intercept() appears to return the correct values, but only because of the default read-everything case (which is going to disappear), and that in vcpu context, hardware should have the guest values in context. Update the read path to explicitly sync the VMCB and complete the accesses, rather than falling all the way through to the default case. svm_msr_write_intercept() silently discard all updates. Synchronise the VMCB for all applicable MSRs, and implement suitable checks. The actual behaviour of AMD hardware is to truncate the SYSENTER and SFMASK MSRs at 32 bits, but this isn't implemented yet to remain compatible with the cross-vendor case. Drop one bit of trailing whitespace while modifing this area of the code. Reported-by: Razvan Cojocaru <rcojocaru@bitdefender.com> Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com> Reviewed-by: Boris Ostrovsky <boris.ostrovsky@oracle.com> --- a/xen/arch/x86/hvm/svm/svm.c +++ b/xen/arch/x86/hvm/svm/svm.c @@ -1523,6 +1523,25 @@ static int svm_msr_read_intercept(unsign switch ( msr ) { + /* + * Sync not needed while the cross-vendor logic is in unilateral effect. + case MSR_IA32_SYSENTER_CS: + case MSR_IA32_SYSENTER_ESP: + case MSR_IA32_SYSENTER_EIP: + */ + case MSR_STAR: + case MSR_LSTAR: + case MSR_CSTAR: + case MSR_SYSCALL_MASK: + case MSR_FS_BASE: + case MSR_GS_BASE: + case MSR_SHADOW_GS_BASE: + svm_sync_vmcb(v); + break; + } + + switch ( msr ) + { case MSR_IA32_SYSENTER_CS: *msr_content = v->arch.hvm_svm.guest_sysenter_cs; break; @@ -1533,6 +1552,34 @@ static int svm_msr_read_intercept(unsign *msr_content = v->arch.hvm_svm.guest_sysenter_eip; break; + case MSR_STAR: + *msr_content = vmcb->star; + break; + + case MSR_LSTAR: + *msr_content = vmcb->lstar; + break; + + case MSR_CSTAR: + *msr_content = vmcb->cstar; + break; + + case MSR_SYSCALL_MASK: + *msr_content = vmcb->sfmask; + break; + + case MSR_FS_BASE: + *msr_content = vmcb->fs.base; + break; + + case MSR_GS_BASE: + *msr_content = vmcb->gs.base; + break; + + case MSR_SHADOW_GS_BASE: + *msr_content = vmcb->kerngsbase; + break; + case MSR_IA32_MCx_MISC(4): /* Threshold register */ case MSR_F10_MC4_MISC1 ... MSR_F10_MC4_MISC3: /* @@ -1648,32 +1695,81 @@ static int svm_msr_write_intercept(unsig int ret, result = X86EMUL_OKAY; struct vcpu *v = current; struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb; - int sync = 0; + bool_t sync = 0; switch ( msr ) { case MSR_IA32_SYSENTER_CS: case MSR_IA32_SYSENTER_ESP: case MSR_IA32_SYSENTER_EIP: + case MSR_STAR: + case MSR_LSTAR: + case MSR_CSTAR: + case MSR_SYSCALL_MASK: + case MSR_FS_BASE: + case MSR_GS_BASE: + case MSR_SHADOW_GS_BASE: sync = 1; break; - default: - break; } if ( sync ) - svm_sync_vmcb(v); + svm_sync_vmcb(v); switch ( msr ) { + case MSR_IA32_SYSENTER_ESP: + case MSR_IA32_SYSENTER_EIP: + case MSR_LSTAR: + case MSR_CSTAR: + case MSR_FS_BASE: + case MSR_GS_BASE: + case MSR_SHADOW_GS_BASE: + if ( !is_canonical_address(msr_content) ) + goto gpf; + + switch ( msr ) + { + case MSR_IA32_SYSENTER_ESP: + vmcb->sysenter_esp = v->arch.hvm_svm.guest_sysenter_esp = msr_content; + break; + + case MSR_IA32_SYSENTER_EIP: + vmcb->sysenter_eip = v->arch.hvm_svm.guest_sysenter_eip = msr_content; + break; + + case MSR_LSTAR: + vmcb->lstar = msr_content; + break; + + case MSR_CSTAR: + vmcb->cstar = msr_content; + break; + + case MSR_FS_BASE: + vmcb->fs.base = msr_content; + break; + + case MSR_GS_BASE: + vmcb->gs.base = msr_content; + break; + + case MSR_SHADOW_GS_BASE: + vmcb->kerngsbase = msr_content; + break; + } + break; + case MSR_IA32_SYSENTER_CS: vmcb->sysenter_cs = v->arch.hvm_svm.guest_sysenter_cs = msr_content; break; - case MSR_IA32_SYSENTER_ESP: - vmcb->sysenter_esp = v->arch.hvm_svm.guest_sysenter_esp = msr_content; + + case MSR_STAR: + vmcb->star = msr_content; break; - case MSR_IA32_SYSENTER_EIP: - vmcb->sysenter_eip = v->arch.hvm_svm.guest_sysenter_eip = msr_content; + + case MSR_SYSCALL_MASK: + vmcb->sfmask = msr_content; break; case MSR_IA32_DEBUGCTLMSR:
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor