VirtualBox

Changeset 74399 in vbox for trunk/src/VBox/VMM/VMMAll


Ignore:
Timestamp:
Sep 21, 2018 9:10:01 AM (6 years ago)
Author:
vboxsync
Message:

VMM/IEM: Nested VMX: bugref:9180 VM-exit bits.

Location:
trunk/src/VBox/VMM/VMMAll
Files:
2 edited

Legend:

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

    r74389 r74399  
    451451    switch (enmAbort)
    452452    {
    453         case VMXABORT_NONE:                 return "VMXABORT_NONE";
    454         case VMXABORT_SAVE_GUEST_MSRS:      return "VMXABORT_SAVE_GUEST_MSRS";
    455         case VMXBOART_HOST_PDPTE:           return "VMXBOART_HOST_PDPTE";
    456         case VMXABORT_CURRENT_VMCS_CORRUPT: return "VMXABORT_CURRENT_VMCS_CORRUPT";
    457         case VMXABORT_LOAD_HOST_MSR:        return "VMXABORT_LOAD_HOST_MSR";
    458         case VMXABORT_MACHINE_CHECK_XCPT:   return "VMXABORT_MACHINE_CHECK_XCPT";
    459         case VMXABORT_HOST_LONG_MODE:       return "VMXABORT_HOST_LONG_MODE";
     453        case VMXABORT_NONE:                     return "VMXABORT_NONE";
     454        case VMXABORT_SAVE_GUEST_MSRS:          return "VMXABORT_SAVE_GUEST_MSRS";
     455        case VMXBOART_HOST_PDPTE:               return "VMXBOART_HOST_PDPTE";
     456        case VMXABORT_CURRENT_VMCS_CORRUPT:     return "VMXABORT_CURRENT_VMCS_CORRUPT";
     457        case VMXABORT_LOAD_HOST_MSR:            return "VMXABORT_LOAD_HOST_MSR";
     458        case VMXABORT_MACHINE_CHECK_XCPT:       return "VMXABORT_MACHINE_CHECK_XCPT";
     459        case VMXABORT_HOST_NOT_IN_LONG_MODE:    return "VMXABORT_HOST_NOT_IN_LONG_MODE";
    460460        default:
    461461            break;
  • trunk/src/VBox/VMM/VMMAll/IEMAllCImplVmxInstr.cpp.h

    r74398 r74399  
    19671967        }
    19681968
    1969         /* CR0 fixed bits. */
     1969        /* CR0 MB1 bits. */
    19701970        uint64_t const uCr0Fixed0 = CPUMGetGuestIa32VmxCr0Fixed0(pVCpu);
    1971         if ((pVCpu->cpum.GstCtx.cr0 & uCr0Fixed0) != uCr0Fixed0)
     1971        if (~pVCpu->cpum.GstCtx.cr0 & uCr0Fixed0)
    19721972        {
    19731973            Log(("vmxon: CR0 fixed0 bits cleared -> #GP(0)\n"));
     
    19761976        }
    19771977
    1978         /* CR4 fixed bits. */
     1978        /* CR4 MB1 bits. */
    19791979        uint64_t const uCr4Fixed0 = CPUMGetGuestIa32VmxCr4Fixed0(pVCpu);
    1980         if ((pVCpu->cpum.GstCtx.cr4 & uCr4Fixed0) != uCr4Fixed0)
     1980        if (~pVCpu->cpum.GstCtx.cr4 & uCr4Fixed0)
    19811981        {
    19821982            Log(("vmxon: CR4 fixed0 bits cleared -> #GP(0)\n"));
     
    23592359        /* CR0 MB1 bits. */
    23602360        uint64_t u64Cr0Fixed0 = CPUMGetGuestIa32VmxCr0Fixed0(pVCpu);
    2361         Assert(u64Cr0Fixed0 & (X86_CR0_NW | X86_CR0_CD));
     2361        Assert(!(u64Cr0Fixed0 & (X86_CR0_NW | X86_CR0_CD)));
    23622362        if (fUnrestrictedGuest)
    23632363            u64Cr0Fixed0 &= ~(X86_CR0_PE | X86_CR0_PG);
     
    24362436    }
    24372437
    2438     Assert(!(pVmcs->u32EntryCtls & VMX_ENTRY_CTLS_LOAD_PERF_MSR));  /* We don't support loading IA32_PERF_GLOBAL_CTRL MSR yet. */
     2438    /* We don't support IA32_PERF_GLOBAL_CTRL MSR yet. */
     2439    Assert(!(pVmcs->u32EntryCtls & VMX_ENTRY_CTLS_LOAD_PERF_MSR));
    24392440
    24402441    /* PAT MSR. */
     
    24582459        IEM_VMX_VMENTRY_FAILED_RET(pVCpu, pszInstr, pszFailure, kVmxVDiag_Vmentry_GuestEferMsr);
    24592460
    2460     Assert(!(pVmcs->u32EntryCtls & VMX_ENTRY_CTLS_LOAD_BNDCFGS_MSR));   /* We don't support loading IA32_BNDCFGS MSR yet. */
     2461    /* We don't support IA32_BNDCFGS MSR yet. */
     2462    Assert(!(pVmcs->u32EntryCtls & VMX_ENTRY_CTLS_LOAD_BNDCFGS_MSR));
    24612463
    24622464    NOREF(pszInstr);
     
    33813383    }
    33823384
    3383     Assert(!(pVmcs->u32ExitCtls & VMX_EXIT_CTLS_LOAD_PERF_MSR));   /* We don't support loading IA32_PERF_GLOBAL_CTRL MSR yet. */
     3385    /* We don't support IA32_PERF_GLOBAL_CTRL MSR yet. */
     3386    Assert(!(pVmcs->u32ExitCtls & VMX_EXIT_CTLS_LOAD_PERF_MSR));
    33843387
    33853388    /* PAT MSR. */
     
    39473950        pVCpu->cpum.GstCtx.msrEFER = pVmcs->u64GuestEferMsr.u;
    39483951
    3949     Assert(!(pVmcs->u32EntryCtls & VMX_ENTRY_CTLS_LOAD_PERF_MSR));          /* We don't support IA32_PERF_GLOBAL_CTRL MSR yet. */
    3950     Assert(!(pVmcs->u32EntryCtls & VMX_ENTRY_CTLS_LOAD_BNDCFGS_MSR));       /* We don't support IA32_BNDCFGS MSR yet. */
     3952    /* We don't support IA32_PERF_GLOBAL_CTRL MSR yet. */
     3953    Assert(!(pVmcs->u32EntryCtls & VMX_ENTRY_CTLS_LOAD_PERF_MSR));
     3954
     3955    /* We don't support IA32_BNDCFGS MSR yet. */
     3956    Assert(!(pVmcs->u32EntryCtls & VMX_ENTRY_CTLS_LOAD_BNDCFGS_MSR));
     3957
    39513958    /* Nothing to do for SMBASE register - We don't support SMM yet. */
    39523959}
     
    39543961
    39553962/**
    3956  * Loads the guest segment registers as part of VM-entry.
     3963 * Loads the guest segment registers, GDTR, IDTR, LDTR and TR as part of VM-entry.
    39573964 *
    39583965 * @param   pVCpu   The cross context virtual CPU structure.
     
    45954602        pVmcs->u64GuestEferMsr.u = pVCpu->cpum.GstCtx.msrEFER;
    45964603
    4597     Assert(!(pVmcs->u32ExitCtls & VMX_EXIT_CTLS_CLEAR_BNDCFGS_MSR));   /* We don't support clearing IA32_BNDCFGS MSR yet. */
     4604    /* We don't support clearing IA32_BNDCFGS MSR yet. */
     4605    Assert(!(pVmcs->u32ExitCtls & VMX_EXIT_CTLS_CLEAR_BNDCFGS_MSR));
     4606
    45984607    /* Nothing to do for SMBASE register - We don't support SMM yet. */
    45994608}
     
    46014610
    46024611/**
    4603  * Saves guest segment registers as part of VM-exit.
     4612 * Saves guest segment registers, GDTR, IDTR, LDTR, TR as part of VM-exit.
    46044613 *
    46054614 * @param   pVCpu       The cross context virtual CPU structure.
     
    46914700        pVmcs->u32GuestTrAttr   = pSelReg->Attr.u & fValidAttrMask;
    46924701    }
     4702
     4703    /* GDTR. */
     4704    pVmcs->u64GuestGdtrBase.u = pVCpu->cpum.GstCtx.gdtr.pGdt;
     4705    pVmcs->u32GuestGdtrLimit  = pVCpu->cpum.GstCtx.gdtr.cbGdt;
     4706
     4707    /* IDTR. */
     4708    pVmcs->u64GuestIdtrBase.u = pVCpu->cpum.GstCtx.idtr.pIdt;
     4709    pVmcs->u32GuestIdtrLimit  = pVCpu->cpum.GstCtx.idtr.cbIdt;
    46934710}
    46944711
     
    47444761
    47454762    /* PDPTEs. */
    4746     Assert(!(pVmcs->u32ProcCtls2 & VMX_PROC_CTLS2_EPT));    /* We don't support EPT yet. */
     4763    /* We don't support EPT yet. */
     4764    Assert(!(pVmcs->u32ProcCtls2 & VMX_PROC_CTLS2_EPT));
    47474765    pVmcs->u64GuestPdpte0.u = 0;
    47484766    pVmcs->u64GuestPdpte1.u = 0;
     
    48994917
    49004918/**
    4901  * Checks host control registers, debug registers and MSRs as part of VM-exit.
     4919 * Loads host control registers, debug registers and MSRs as part of VM-exit.
    49024920 *
    49034921 * @param   pVCpu   The cross context virtual CPU structure.
     
    49054923IEM_STATIC void iemVmxVmexitLoadHostControlRegsMsrs(PVMCPU pVCpu)
    49064924{
    4907     /** @todo NSTVMX: load host control regs. */
     4925    /*
     4926     * Load host control registers, debug registers and MSRs.
     4927     * See Intel spec. 27.5.1 "Loading Host Control Registers, Debug Registers, MSRs".
     4928     */
     4929    PCVMXVVMCS pVmcs = pVCpu->cpum.GstCtx.hwvirt.vmx.CTX_SUFF(pVmcs);
     4930    bool const fHostInLongMode = RT_BOOL(pVmcs->u32ExitCtls & VMX_EXIT_CTLS_HOST_ADDR_SPACE_SIZE);
     4931
     4932    /* CR0. */
     4933    {
     4934        /* Bits 63:32, 28:19, 17, 15:6, ET, CD, NW and CR0 MB1 bits are not modified. */
     4935        uint64_t const uCr0Fixed0  = CPUMGetGuestIa32VmxCr0Fixed0(pVCpu);
     4936        uint64_t const fCr0IgnMask = UINT64_C(0xffffffff1ff8ffc0) | X86_CR0_ET | X86_CR0_CD | X86_CR0_NW | uCr0Fixed0;
     4937        uint64_t const uHostCr0    = pVmcs->u64HostCr0.u;
     4938        uint64_t const uGuestCr0   = pVCpu->cpum.GstCtx.cr0;
     4939        pVCpu->cpum.GstCtx.cr0     = (uHostCr0 & ~fCr0IgnMask) | (uGuestCr0 & fCr0IgnMask);
     4940    }
     4941
     4942    /* CR4. */
     4943    {
     4944        /* CR4 MB1 bits are not modified. */
     4945        uint64_t const fCr4IgnMask = CPUMGetGuestIa32VmxCr4Fixed0(pVCpu);
     4946        uint64_t const uHostCr4    = pVmcs->u64HostCr4.u;
     4947        uint64_t const uGuestCr4   = pVCpu->cpum.GstCtx.cr4;
     4948        pVCpu->cpum.GstCtx.cr4     = (uHostCr4 & ~fCr4IgnMask) | (uGuestCr4 & fCr4IgnMask);
     4949
     4950        if (fHostInLongMode)
     4951            pVCpu->cpum.GstCtx.cr4 |= X86_CR4_PAE;
     4952        else
     4953            pVCpu->cpum.GstCtx.cr4 &= ~X86_CR4_PCIDE;
     4954    }
     4955
     4956    /* CR3 (host value validated while checking host-state during VM-entry). */
     4957    pVCpu->cpum.GstCtx.cr3 = pVmcs->u64HostCr3.u;
     4958
     4959    /* DR7. */
     4960    pVCpu->cpum.GstCtx.dr[7] = X86_DR7_INIT_VAL;
     4961
     4962    /** @todo NSTVMX: Support IA32_DEBUGCTL MSR */
     4963
     4964    /* Save SYSENTER CS, ESP, EIP (host value validated while checking host-state during VM-entry). */
     4965    pVCpu->cpum.GstCtx.SysEnter.eip = pVmcs->u64HostSysenterEip.u;
     4966    pVCpu->cpum.GstCtx.SysEnter.esp = pVmcs->u64HostSysenterEsp.u;
     4967    pVCpu->cpum.GstCtx.SysEnter.cs  = pVmcs->u32HostSysenterCs;
     4968
     4969    /* FS, GS bases are loaded later while we load host segment registers. */
     4970
     4971    /* EFER MSR (host value validated while checking host-state during VM-entry). */
     4972    if (pVmcs->u32ExitCtls & VMX_EXIT_CTLS_LOAD_EFER_MSR)
     4973        pVCpu->cpum.GstCtx.msrEFER = pVmcs->u64HostEferMsr.u;
     4974    else if (IEM_GET_GUEST_CPU_FEATURES(pVCpu)->fLongMode)
     4975    {
     4976        if (fHostInLongMode)
     4977            pVCpu->cpum.GstCtx.msrEFER |=  (MSR_K6_EFER_LMA | MSR_K6_EFER_LME);
     4978        else
     4979            pVCpu->cpum.GstCtx.msrEFER &= ~(MSR_K6_EFER_LMA | MSR_K6_EFER_LME);
     4980    }
     4981
     4982    /* We don't support IA32_PERF_GLOBAL_CTRL MSR yet. */
     4983
     4984    /* PAT MSR (host value is validated while checking host-state during VM-entry). */
     4985    if (pVmcs->u32ExitCtls & VMX_EXIT_CTLS_LOAD_PAT_MSR)
     4986        pVCpu->cpum.GstCtx.msrPAT = pVmcs->u64HostPatMsr.u;
     4987
     4988    /* We don't support IA32_BNDCFGS MSR yet. */
     4989}
     4990
     4991
     4992/**
     4993 * Loads host segment registers, GDTR, IDTR, LDTR and TR as part of VM-exit.
     4994 *
     4995 *
     4996 * @param
     4997 */
     4998IEM_STATIC void iemVmxVmexitLoadHostSegRegs(PVMCPU pVCpu)
     4999{
    49085000    RT_NOREF(pVCpu);
     5001    /** @todo Load host seg regs. */
    49095002}
    49105003
     
    49175010IEM_STATIC int iemVmxVmexitLoadHostState(PVMCPU pVCpu)
    49185011{
     5012    /*
     5013     * Load host state.
     5014     * See Intel spec. 27.5 "Loading Host State".
     5015     */
     5016    PCVMXVVMCS pVmcs = pVCpu->cpum.GstCtx.hwvirt.vmx.CTX_SUFF(pVmcs);
     5017    bool const fHostInLongMode = RT_BOOL(pVmcs->u32ExitCtls & VMX_EXIT_CTLS_HOST_ADDR_SPACE_SIZE);
     5018
     5019    /* We cannot return from a long-mode guest to a host that is not in long mode. */
     5020    if (    CPUMIsGuestInLongMode(pVCpu)
     5021        && !fHostInLongMode)
     5022    {
     5023        Log(("VM-exit from long-mode guest to host not in long-mode -> VMX-Abort\n"));
     5024        return iemVmxAbort(pVCpu, VMXABORT_HOST_NOT_IN_LONG_MODE);
     5025    }
     5026
    49195027    /*
    49205028     * Load host control, debug, segment, descriptor-table registers and some MSRs.
    49215029     */
    49225030    iemVmxVmexitLoadHostControlRegsMsrs(pVCpu);
     5031    iemVmxVmexitLoadHostSegRegs(pVCpu);
     5032
    49235033    return VINF_SUCCESS;
    49245034}
     
    49585068        else
    49595069        {
    4960             LogFunc(("iemVmxVmexitSaveGuestAutoMsrs failed (rc=%Rrc) -> VMX-Abort\n", rc));
     5070            Log(("VM-Exit: Saving guest auto-store MSRs failed (rc=%Rrc) -> VMX-Abort\n", rc));
    49615071            return iemVmxAbort(pVCpu, VMXABORT_SAVE_GUEST_MSRS);
    49625072        }
    49635073    }
    49645074
    4965     iemVmxVmexitLoadHostState(pVCpu);
     5075    int rc = iemVmxVmexitLoadHostState(pVCpu);
     5076    if (RT_FAILURE(rc))
     5077        return rc;
    49665078
    49675079    /** @todo NSTVMX: rest of VM-exit. */
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