VirtualBox

Changeset 74562 in vbox for trunk


Ignore:
Timestamp:
Oct 2, 2018 4:01:54 AM (7 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
125431
Message:

VMM/IEM: Nested VMX: bugref:9180 VM-exit bits; added function to checking MSR intercepts consulting MSR bitmap if needed.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/VMMAll/IEMAllCImplVmxInstr.cpp.h

    r74543 r74562  
    48584858
    48594859/**
     4860 * Checks whether an RDMSR or WRMSR instruction for the given MSR is intercepted
     4861 * (causes a VM-exit)  or not.
     4862 *
     4863 * @returns @c true if the instruction is intercepted, @c false otherwise.
     4864 * @param   pVCpu           The cross context virtual CPU structure.
     4865 * @param   uExitReason     The VM-exit exit reason (VMX_EXIT_RDMSR or
     4866 *                          VMX_EXIT_WRMSR).
     4867 * @param   idMsr           The MSR.
     4868 */
     4869IEM_STATIC bool iemVmxIsRdmsrWrmsrInterceptSet(PVMCPU pVCpu, uint32_t uExitReason, uint32_t idMsr)
     4870{
     4871    Assert(IEM_VMX_IS_NON_ROOT_MODE(pVCpu));
     4872    Assert(   uExitReason == VMX_EXIT_RDMSR
     4873           || uExitReason == VMX_EXIT_WRMSR);
     4874
     4875    /* Consult the MSR bitmap if the feature is supported. */
     4876    if (IEM_VMX_IS_PROCCTLS_SET(pVCpu, VMX_PROC_CTLS_USE_MSR_BITMAPS))
     4877    {
     4878        Assert(pVCpu->cpum.GstCtx.hwvirt.vmx.CTX_SUFF(pvMsrBitmap));
     4879        if (uExitReason == VMX_EXIT_RDMSR)
     4880        {
     4881            VMXMSREXITREAD enmRead;
     4882            int rc = HMVmxGetMsrPermission(pVCpu->cpum.GstCtx.hwvirt.vmx.CTX_SUFF(pvMsrBitmap), idMsr, &enmRead,
     4883                                           NULL /* penmWrite */);
     4884            AssertRC(rc);
     4885            if (enmRead == VMXMSREXIT_INTERCEPT_READ)
     4886                return true;
     4887        }
     4888        else
     4889        {
     4890            VMXMSREXITWRITE enmWrite;
     4891            int rc = HMVmxGetMsrPermission(pVCpu->cpum.GstCtx.hwvirt.vmx.CTX_SUFF(pvMsrBitmap), idMsr, NULL /* penmRead */,
     4892                                           &enmWrite);
     4893            AssertRC(rc);
     4894            if (enmWrite == VMXMSREXIT_INTERCEPT_WRITE)
     4895                return true;
     4896        }
     4897        return false;
     4898    }
     4899
     4900    /* Without MSR bitmaps, all MSR accesses are intercepted. */
     4901    return true;
     4902}
     4903
     4904
     4905/**
    48604906 * Checks whether a VMREAD or VMWRITE instruction for the given VMCS field is
    48614907 * intercepted (causes a VM-exit) or not.
    48624908 *
    4863  * @returns @c true if the intercepted is set, @c false otherwise.
     4909 * @returns @c true if the instruction is intercepted, @c false otherwise.
    48644910 * @param   pVCpu           The cross context virtual CPU structure.
    48654911 * @param   u64FieldEnc     The VMCS field encoding.
    4866  * @param   uInstrId        The VM-exit instruction identity (VMXINSTRID_VMREAD or
    4867  *                          VMXINSTRID_VMWRITE).
    4868  */
    4869 IEM_STATIC bool iemVmxIsVmreadVmwriteInterceptSet(PVMCPU pVCpu, uint64_t u64FieldEnc, VMXINSTRID uInstrId)
    4870 {
    4871     Assert(   uInstrId == VMXINSTRID_VMREAD
    4872            || uInstrId == VMXINSTRID_VMWRITE);
    4873 
    4874     /*
    4875      * Without VMCS shadowing, all VMREAD and VMWRITE instructions are intercepted.
    4876      */
     4912 * @param   uExitReason     The VM-exit exit reason (VMX_EXIT_VMREAD or
     4913 *                          VMX_EXIT_VMREAD).
     4914 */
     4915IEM_STATIC bool iemVmxIsVmreadVmwriteInterceptSet(PVMCPU pVCpu, uint32_t uExitReason, uint64_t u64FieldEnc)
     4916{
     4917    Assert(IEM_VMX_IS_NON_ROOT_MODE(pVCpu));
     4918    Assert(   uExitReason == VMX_EXIT_VMREAD
     4919           || uExitReason == VMX_EXIT_VMWRITE);
     4920
     4921    /* Without VMCS shadowing, all VMREAD and VMWRITE instructions are intercepted. */
    48774922    if (!IEM_GET_GUEST_CPU_FEATURES(pVCpu)->fVmxVmcsShadowing)
    48784923        return true;
     
    48854930        return true;
    48864931
    4887     /*
    4888      * Finally, consult the VMREAD/VMWRITE bitmap whether to intercept the instruction or not.
    4889      */
     4932    /* Finally, consult the VMREAD/VMWRITE bitmap whether to intercept the instruction or not. */
    48904933    uint32_t u32FieldEnc = RT_LO_U32(u64FieldEnc);
    48914934    Assert(u32FieldEnc >> 3 < VMX_V_VMREAD_VMWRITE_BITMAP_SIZE);
    48924935    Assert(pVCpu->cpum.GstCtx.hwvirt.vmx.CTX_SUFF(pvVmreadBitmap));
    4893     uint8_t const *pbBitmap = uInstrId == VMXINSTRID_VMREAD
     4936    uint8_t const *pbBitmap = uExitReason == VMX_EXIT_VMREAD
    48944937                            ? (uint8_t const *)pVCpu->cpum.GstCtx.hwvirt.vmx.CTX_SUFF(pvVmreadBitmap)
    48954938                            : (uint8_t const *)pVCpu->cpum.GstCtx.hwvirt.vmx.CTX_SUFF(pvVmwriteBitmap);
     
    49194962    /* Nested-guest intercept. */
    49204963    if (   IEM_VMX_IS_NON_ROOT_MODE(pVCpu)
    4921         && iemVmxIsVmreadVmwriteInterceptSet(pVCpu, u64FieldEnc, VMXINSTRID_VMREAD))
     4964        && iemVmxIsVmreadVmwriteInterceptSet(pVCpu, VMX_EXIT_VMREAD, u64FieldEnc))
    49224965    {
    49234966        if (pExitInfo)
     
    51375180    /* Nested-guest intercept. */
    51385181    if (   IEM_VMX_IS_NON_ROOT_MODE(pVCpu)
    5139         && iemVmxIsVmreadVmwriteInterceptSet(pVCpu, u64FieldEnc, VMXINSTRID_VMWRITE))
     5182        && iemVmxIsVmreadVmwriteInterceptSet(pVCpu, VMX_EXIT_VMWRITE, u64FieldEnc))
    51405183    {
    51415184        if (pExitInfo)
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette