VirtualBox

Changeset 80689 in vbox


Ignore:
Timestamp:
Sep 10, 2019 9:48:10 AM (5 years ago)
Author:
vboxsync
Message:

VMM/HMVMXR0: Nested VMX: bugref:9180 Fix re-constructing the guest hypervisor's CR0 and CR4 VMCS fields on the nested-guest VM-exit when using hardware-assisted VMX execution.

File:
1 edited

Legend:

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

    r80661 r80689  
    39163916        if (pVCpu->CTX_SUFF(pVM)->hm.s.vmx.Msrs.ProcCtls.n.allowed1 & VMX_PROC_CTLS_USE_MSR_BITMAPS)
    39173917            hmR0VmxSetupVmcsMsrBitmapAddr(pVmcsInfo);
     3918
     3919        /* Paranoia - We've not yet initialized these, they shall be done while merging the VMCS. */
     3920        Assert(!pVmcsInfo->u64Cr0Mask);
     3921        Assert(!pVmcsInfo->u64Cr4Mask);
    39183922        return VINF_SUCCESS;
    39193923    }
     
    54515455            Assert(u64GuestCr0 & X86_CR0_NE);
    54525456
    5453             /*
    5454              * Apply the hardware specified fixed CR0 bits and enable caching.
    5455              * Note! We could be altering our VMX emulation's fixed bits. We thus
    5456              *       need to re-apply them while importing CR0.
    5457              */
     5457            /* Apply the hardware specified fixed CR0 bits and enable caching. */
    54585458            u64GuestCr0 |= fSetCr0;
    54595459            u64GuestCr0 &= fZapCr0;
     
    56945694        }
    56955695
    5696         /*
    5697          * Apply the hardware specified fixed CR4 bits (mainly CR4.VMXE).
    5698          * Note! For nested-guests, we could be altering our VMX emulation's
    5699          *       fixed bits. We thus need to re-apply them while importing CR4.
    5700          */
     5696        /* Apply the hardware specified fixed CR4 bits (mainly CR4.VMXE). */
    57015697        u64GuestCr4 |= fSetCr4;
    57025698        u64GuestCr4 &= fZapCr4;
     
    74957491                    rc = VMXReadVmcsNw(VMX_VMCS_GUEST_CR0,            &u64Cr0);       AssertRC(rc);
    74967492                    rc = VMXReadVmcsNw(VMX_VMCS_CTRL_CR0_READ_SHADOW, &u64Shadow);    AssertRC(rc);
     7493#ifndef VBOX_WITH_NESTED_HWVIRT_VMX
    74977494                    u64Cr0 = (u64Cr0    & ~pVmcsInfo->u64Cr0Mask)
    74987495                           | (u64Shadow &  pVmcsInfo->u64Cr0Mask);
    7499 #ifdef VBOX_WITH_NESTED_HWVIRT_VMX
    7500                     /*
    7501                      * Reapply the nested-guest's CR0 fixed bits that might have been altered while
    7502                      * exporting the nested-guest CR0 for executing using hardware-assisted VMX.
    7503                      */
    7504                     if (CPUMIsGuestInVmxNonRootMode(pCtx))
     7496#else
     7497                    if (!CPUMIsGuestInVmxNonRootMode(pCtx))
    75057498                    {
    7506                         u64Cr0 |= pCtx->hwvirt.vmx.Msrs.u64Cr0Fixed0;
    7507                         u64Cr0 &= pCtx->hwvirt.vmx.Msrs.u64Cr0Fixed1;
     7499                        u64Cr0 = (u64Cr0    & ~pVmcsInfo->u64Cr0Mask)
     7500                               | (u64Shadow &  pVmcsInfo->u64Cr0Mask);
     7501                    }
     7502                    else
     7503                    {
     7504                        /*
     7505                         * We've merged the guest and nested-guest's CR0 guest/host mask while executing
     7506                         * the nested-guest using hardware-assisted VMX. Accordingly we need to
     7507                         * re-construct CR0. See @bugref{9180#c95} for details.
     7508                         */
     7509                        PCVMXVMCSINFO pVmcsInfoGst = &pVCpu->hm.s.vmx.VmcsInfo;
     7510                        PCVMXVVMCS    pVmcsNstGst  = pVCpu->cpum.GstCtx.hwvirt.vmx.CTX_SUFF(pVmcs);
     7511                        u64Cr0 = (u64Cr0                     & ~pVmcsInfo->u64Cr0Mask)
     7512                               | (pVmcsNstGst->u64GuestCr0.u &  pVmcsNstGst->u64Cr0Mask.u)
     7513                               | (u64Shadow                  & (pVmcsInfoGst->u64Cr0Mask   & ~pVmcsNstGst->u64Cr0Mask.u));
    75087514                    }
    75097515#endif
     
    75197525                    rc  = VMXReadVmcsNw(VMX_VMCS_GUEST_CR4,            &u64Cr4);      AssertRC(rc);
    75207526                    rc |= VMXReadVmcsNw(VMX_VMCS_CTRL_CR4_READ_SHADOW, &u64Shadow);   AssertRC(rc);
     7527#ifndef VBOX_WITH_NESTED_HWVIRT_VMX
    75217528                    u64Cr4 = (u64Cr4    & ~pVmcsInfo->u64Cr4Mask)
    75227529                           | (u64Shadow &  pVmcsInfo->u64Cr4Mask);
    7523 #ifdef VBOX_WITH_NESTED_HWVIRT_VMX
    7524                     /*
    7525                      * Reapply the nested-guest's CR4 fixed bits that might have been altered while
    7526                      * exporting the nested-guest CR4 for executing using hardware-assisted VMX.
    7527                      */
    7528                     if (CPUMIsGuestInVmxNonRootMode(pCtx))
     7530#else
     7531                    if (!CPUMIsGuestInVmxNonRootMode(pCtx))
    75297532                    {
    7530                         u64Cr4 |= pCtx->hwvirt.vmx.Msrs.u64Cr4Fixed0;
    7531                         u64Cr4 &= pCtx->hwvirt.vmx.Msrs.u64Cr4Fixed1;
     7533                        u64Cr4 = (u64Cr4    & ~pVmcsInfo->u64Cr4Mask)
     7534                               | (u64Shadow &  pVmcsInfo->u64Cr4Mask);
     7535                    }
     7536                    else
     7537                    {
     7538                        /*
     7539                         * We've merged the guest and nested-guest's CR4 guest/host mask while executing
     7540                         * the nested-guest using hardware-assisted VMX. Accordingly we need to
     7541                         * re-construct CR4. See @bugref{9180#c95} for details.
     7542                         */
     7543                        PCVMXVMCSINFO pVmcsInfoGst = &pVCpu->hm.s.vmx.VmcsInfo;
     7544                        PCVMXVVMCS    pVmcsNstGst  = pVCpu->cpum.GstCtx.hwvirt.vmx.CTX_SUFF(pVmcs);
     7545                        u64Cr4 = (u64Cr4                     & ~pVmcsInfo->u64Cr4Mask)
     7546                               | (pVmcsNstGst->u64GuestCr4.u &  pVmcsNstGst->u64Cr4Mask.u)
     7547                               | (u64Shadow                  & (pVmcsInfoGst->u64Cr4Mask & ~pVmcsNstGst->u64Cr4Mask.u));
    75327548                    }
    75337549#endif
Note: See TracChangeset for help on using the changeset viewer.

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