VirtualBox

Changeset 78691 in vbox for trunk/src/VBox


Ignore:
Timestamp:
May 23, 2019 11:23:39 AM (6 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
130767
Message:

VMM/HMVMXR0: Nested VMX: bugref:9180 Try fix CR0/CR4 read shadows because we merge in the host/hypervisor CR0/CR4 mask with the guest-hypervisor's CR0/CR4 mask. Still needs fixing while importing the nested-guest CR0/CR4. Have to figure that out.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/VMMR0/HMVMXR0.cpp

    r78679 r78691  
    48304830        else
    48314831        {
    4832             PCVMXVVMCS pVmcsNstGst = pVCpu->cpum.GstCtx.hwvirt.vmx.CTX_SUFF(pVmcs);
     4832            /*
     4833             * With nested-guests, we may have extended the guest/host mask here (since we
     4834             * merged in the outer guest's mask, see hmR0VmxMergeVmcsNested). This means, the
     4835             * mask can include more bits (to read from the nested-guest CR0 read-shadow) than
     4836             * the guest hypervisor originally supplied. Thus, we should, in essence, copy
     4837             * those bits from the nested-guest CR0 into the nested-guest CR0 read shadow.
     4838             */
    48334839            HMVMX_CPUMCTX_ASSERT(pVCpu, CPUMCTX_EXTRN_CR0);
    48344840            uint64_t       u64GuestCr0  = pVCpu->cpum.GstCtx.cr0;
    4835             uint64_t const u64ShadowCr0 = pVmcsNstGst->u64Cr0ReadShadow.u;
     4841            uint64_t const u64ShadowCr0 = CPUMGetGuestVmxMaskedCr0(pVCpu, &pVCpu->cpum.GstCtx);
    48364842            Assert(!RT_HI_U32(u64GuestCr0));
    48374843            Assert(u64GuestCr0 & X86_CR0_NE);
     
    48434849
    48444850            /* Commit the CR0 and CR0 read shadow to the nested-guest VMCS. */
    4845             int rc = VMXWriteVmcs32(VMX_VMCS_GUEST_CR0, u64GuestCr0);   /** @todo NSTVMX: Fix to 64-bit when we drop 32-bit. */
     4851            /** @todo NSTVMX: Fix to 64-bit when we drop 32-bit. */
     4852            int rc = VMXWriteVmcs32(VMX_VMCS_GUEST_CR0,              u64GuestCr0);
    48464853            rc    |= VMXWriteVmcsHstN(VMX_VMCS_CTRL_CR0_READ_SHADOW, u64ShadowCr0);
    48474854            AssertRCReturn(rc, rc);
     
    49884995        PCPUMCTX     pCtx        = &pVCpu->cpum.GstCtx;
    49894996        PVMXVMCSINFO pVmcsInfo   = pVmxTransient->pVmcsInfo;
    4990         PCVMXVVMCS   pVmcsNstGst = pVCpu->cpum.GstCtx.hwvirt.vmx.CTX_SUFF(pVmcs);
    49914997
    49924998        /*
     
    49965002        uint64_t const fZapCr4 = pVM->hm.s.vmx.Msrs.u64Cr4Fixed0 | pVM->hm.s.vmx.Msrs.u64Cr4Fixed1;
    49975003
     5004        /*
     5005         * With nested-guests, we may have extended the guest/host mask here (since we
     5006         * merged in the outer guest's mask, see hmR0VmxMergeVmcsNested). This means, the
     5007         * mask can include more bits (to read from the nested-guest CR4 read-shadow) than
     5008         * the guest hypervisor originally supplied. Thus, we should, in essence, copy
     5009         * those bits from the nested-guest CR4 into the nested-guest CR4 read shadow.
     5010         */
    49985011        HMVMX_CPUMCTX_ASSERT(pVCpu, CPUMCTX_EXTRN_CR4);
    49995012        uint64_t       u64GuestCr4  = pCtx->cr4;
    5000         uint64_t const u64ShadowCr4 = !pVmxTransient->fIsNestedGuest ? pCtx->cr4 : pVmcsNstGst->u64Cr4ReadShadow.u;
     5013        uint64_t const u64ShadowCr4 = !pVmxTransient->fIsNestedGuest
     5014                                    ? pCtx->cr4
     5015                                    : CPUMGetGuestVmxMaskedCr4(pVCpu, pCtx);
    50015016        Assert(!RT_HI_U32(u64GuestCr4));
    50025017
     
    50705085
    50715086        /* Commit the CR4 and CR4 read shadow to the guest VMCS. */
    5072         rc  = VMXWriteVmcs32(VMX_VMCS_GUEST_CR4, u64GuestCr4);  /** @todo Fix to 64-bit when we drop 32-bit. */
     5087        /** @todo Fix to 64-bit when we drop 32-bit. */
     5088        rc  = VMXWriteVmcs32(VMX_VMCS_GUEST_CR4,              u64GuestCr4);
    50735089        rc |= VMXWriteVmcsHstN(VMX_VMCS_CTRL_CR4_READ_SHADOW, u64ShadowCr4);
    50745090        AssertRCReturn(rc, rc);
     
    75477563                    VMXLOCAL_BREAK_RC(rc);
    75487564                    u64Val = u32Val;
     7565#if 1
    75497566                    u64Val = (u64Val    & ~pVmcsInfo->u64Cr0Mask)
    75507567                           | (u64Shadow &  pVmcsInfo->u64Cr0Mask);
     7568#else
     7569                    if (!CPUMIsGuestInVmxNonRootMode(pCtx))
     7570                    {
     7571                        u64Val = (u64Val    & ~pVmcsInfo->u64Cr0Mask)
     7572                               | (u64Shadow &  pVmcsInfo->u64Cr0Mask);
     7573                    }
     7574                    else
     7575                    {
     7576                        /** @todo NSTVMX: We need to do some unfudging here because we altered the
     7577                         *        guest/host mask before running the nested-guest. */
     7578                        PCVMXVVMCS pVmcsNstGst = pVCpu->cpum.GstCtx.hwvirt.vmx.CTX_SUFF(pVmcs);
     7579                        Assert(pVmcsNstGst);
     7580
     7581                        uint64_t const uGstCr0Mask = pVmcsNstGst->u64Cr0Mask.u;
     7582                        uint64_t const uHstCr0Mask = hmR0VmxGetFixedCr0Mask(pVCpu);
     7583                    }
     7584#endif
    75517585                    VMMRZCallRing3Disable(pVCpu);   /* May call into PGM which has Log statements. */
    75527586                    CPUMSetGuestCR0(pVCpu, u64Val);
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