VirtualBox

Changeset 79143 in vbox


Ignore:
Timestamp:
Jun 14, 2019 4:56:11 AM (6 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
131310
Message:

VMM/IEM: Nested VMX: bugref:9180 Fix loading host CR0/CR4 on VM-exit (both MB0, MB1 bits must be ignored).
Import the entire guest-CPU state on VM-exit, more explanation in the comments.
Comments.

File:
1 edited

Legend:

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

    r79116 r79143  
    19811981    /* CR0. */
    19821982    {
    1983         /* Bits 63:32, 28:19, 17, 15:6, ET, CD, NW and CR0 MB1 bits are not modified. */
    1984         uint64_t const uCr0Fixed0  = pVCpu->cpum.GstCtx.hwvirt.vmx.Msrs.u64Cr0Fixed0;
    1985         uint64_t const fCr0IgnMask = UINT64_C(0xffffffff1ff8ffc0) | X86_CR0_ET | X86_CR0_CD | X86_CR0_NW | uCr0Fixed0;
    1986         uint64_t const uHostCr0    = pVmcs->u64HostCr0.u;
    1987         uint64_t const uGuestCr0   = pVCpu->cpum.GstCtx.cr0;
    1988         uint64_t const uValidCr0   = (uHostCr0 & ~fCr0IgnMask) | (uGuestCr0 & fCr0IgnMask);
    1989         CPUMSetGuestCR0(pVCpu, uValidCr0);
     1983        /* Bits 63:32, 28:19, 17, 15:6, ET, CD, NW and fixed CR0 bits are not modified. */
     1984        uint64_t const uCr0Mb1       = pVCpu->cpum.GstCtx.hwvirt.vmx.Msrs.u64Cr0Fixed0;
     1985        uint64_t const uCr0Mb0       = pVCpu->cpum.GstCtx.hwvirt.vmx.Msrs.u64Cr0Fixed1;
     1986        uint64_t const fCr0IgnMask   = UINT64_C(0xffffffff1ffaffc0) | X86_CR0_ET | X86_CR0_CD | X86_CR0_NW | uCr0Mb1 | ~uCr0Mb0;
     1987        uint64_t const uHostCr0      = pVmcs->u64HostCr0.u;
     1988        uint64_t const uGuestCr0     = pVCpu->cpum.GstCtx.cr0;
     1989        uint64_t const uValidHostCr0 = (uHostCr0 & ~fCr0IgnMask) | (uGuestCr0 & fCr0IgnMask);
     1990        CPUMSetGuestCR0(pVCpu, uValidHostCr0);
    19901991    }
    19911992
    19921993    /* CR4. */
    19931994    {
    1994         /* CR4 MB1 bits are not modified. */
    1995         uint64_t const fCr4IgnMask = pVCpu->cpum.GstCtx.hwvirt.vmx.Msrs.u64Cr4Fixed0;
    1996         uint64_t const uHostCr4    = pVmcs->u64HostCr4.u;
    1997         uint64_t const uGuestCr4   = pVCpu->cpum.GstCtx.cr4;
    1998         uint64_t       uValidCr4   = (uHostCr4 & ~fCr4IgnMask) | (uGuestCr4 & fCr4IgnMask);
     1995        /* Fixed CR4 bits are not modified. */
     1996        uint64_t const uCr4Mb1       = pVCpu->cpum.GstCtx.hwvirt.vmx.Msrs.u64Cr4Fixed0;
     1997        uint64_t const uCr4Mb0       = pVCpu->cpum.GstCtx.hwvirt.vmx.Msrs.u64Cr4Fixed1;
     1998        uint64_t const fCr4IgnMask   = uCr4Mb1 | ~uCr4Mb0;
     1999        uint64_t const uHostCr4      = pVmcs->u64HostCr4.u;
     2000        uint64_t const uGuestCr4     = pVCpu->cpum.GstCtx.cr4;
     2001        uint64_t       uValidHostCr4 = (uHostCr4 & ~fCr4IgnMask) | (uGuestCr4 & fCr4IgnMask);
    19992002        if (fHostInLongMode)
    2000             uValidCr4 |= X86_CR4_PAE;
    2001         else
    2002             uValidCr4 &= ~X86_CR4_PCIDE;
    2003         CPUMSetGuestCR4(pVCpu, uValidCr4);
     2003            uValidHostCr4 |= X86_CR4_PAE;
     2004        else
     2005            uValidHostCr4 &= ~X86_CR4_PCIDE;
     2006        CPUMSetGuestCR4(pVCpu, uValidHostCr4);
    20042007    }
    20052008
     
    27212724    Assert(pVmcs);
    27222725
    2723     /* Import all the guest-CPU state required for the VM-exit. */
    2724     IEM_CTX_IMPORT_RET(pVCpu, IEM_CPUMCTX_EXTRN_VMX_VMEXIT_MASK);
     2726    /*
     2727     * Import all the guest-CPU state.
     2728     *
     2729     * HM on returning to guest execution would have to reset up a whole lot of state
     2730     * anyway, (e.g., VM-entry/VM-exit controls) and we do not ever import a part of
     2731     * the state and flag reloading the entire state on re-entry. So import the entire
     2732     * state here, see HMNotifyVmxNstGstVmexit() for more comments.
     2733     */
     2734    IEM_CTX_IMPORT_RET(pVCpu, CPUMCTX_EXTRN_ALL);
    27252735
    27262736    /* Ensure VM-entry interruption information valid bit isn't set. */
     
    66636673        /** @todo r=ramshankar: This is done primarily to simplify recursion scenarios while
    66646674         *        redirecting accesses between the APIC-access page and the virtual-APIC
    6665          *        page. If any nested hypervisor requires this, we can implement it later. */
     6675         *        page. If any guest hypervisor requires this, we can implement it later. */
    66666676        if (pVmcs->u32ProcCtls & VMX_PROC_CTLS_USE_TPR_SHADOW)
    66676677        {
     
    74457455    /*
    74467456     * Any VMCS field which we do not establish on every VM-exit but may potentially
    7447      * be used on the VM-exit path of a nested hypervisor -and- is not explicitly
     7457     * be used on the VM-exit path of a guest hypervisor -and- is not explicitly
    74487458     * specified to be undefined needs to be initialized here.
    74497459     *
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