VirtualBox

Changeset 74620 in vbox for trunk/src/VBox/VMM


Ignore:
Timestamp:
Oct 5, 2018 4:14:45 AM (6 years ago)
Author:
vboxsync
Message:

VMM/IEM: Nested VMX: bugref:9180 VM-exit bits; CR4 write intercept.

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

Legend:

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

    r74618 r74620  
    52155215        if (   iCrReg == 0
    52165216            || iCrReg == 4)
    5217             crX = iemVmxGetMaskedCrX(pVCpu, iCrReg, crX);
     5217            crX = iemVmxMaskCr0CR4(pVCpu, iCrReg, crX);
    52185218    }
    52195219#endif
     
    57495749    if (IEM_VMX_IS_NON_ROOT_MODE(pVCpu))
    57505750    {
    5751         if (iCrReg == 0)
    5752         {
    5753             IEM_CTX_ASSERT(pVCpu, CPUMCTX_EXTRN_CR0);
    5754             VBOXSTRICTRC rcStrict = iemVmxVmexitInstrMovCr0Write(pVCpu, pVCpu->cpum.GstCtx.cr0, &uNewCrX, iGReg, cbInstr);
     5751        if (   iCrReg == 0
     5752            || iCrReg == 4)
     5753        {
     5754            VBOXSTRICTRC rcStrict = iemVmxVmexitInstrMovToCr0Cr4(pVCpu, iCrReg, &uNewCrX, iGReg, cbInstr);
    57555755            if (rcStrict != VINF_VMX_INTERCEPT_NOT_ACTIVE)
    57565756                return rcStrict;
  • trunk/src/VBox/VMM/VMMAll/IEMAllCImplVmxInstr.cpp.h

    r74619 r74620  
    901901
    902902/**
    903  * Gets the nested-guest CR0/CR4 mask subjected to the corresponding guest/host mask
    904  * and the read-shadow.
     903 * Masks the nested-guest CR0/CR4 mask subjected to the corresponding guest/host
     904 * mask and the read-shadow.
    905905 *
    906906 * @returns The masked CR0/CR4.
     
    909909 * @param   uGuestCrX   The current guest CR0 or guest CR4.
    910910 */
    911 IEM_STATIC uint64_t iemVmxGetMaskedCrX(PVMCPU pVCpu, uint8_t iCrReg, uint64_t uGuestCrX)
     911IEM_STATIC uint64_t iemVmxMaskCr0CR4(PVMCPU pVCpu, uint8_t iCrReg, uint64_t uGuestCrX)
    912912{
    913913    Assert(IEM_VMX_IS_NON_ROOT_MODE(pVCpu));
     
    29522952
    29532953/**
    2954  * VMX VM-exit handler for VM-exits due to 'Mov CR0, GReg' (CR0 write).
     2954 * VMX VM-exit handler for VM-exits due to 'Mov CR0, GReg' and 'Mov CR4, GReg'
     2955 * (CR0/CR4 write).
    29552956 *
    29562957 * @returns Strict VBox status code.
    29572958 * @param   pVCpu           The cross context virtual CPU structure.
    2958  * @param   puNewCr0        Pointer to the new CR0 value. Will be updated if no
    2959  *                          VM-exit is triggered.
    2960  * @param   iGReg           The general register to load the CR0 value from.
     2959 * @param   iCrReg          The control register (either CR0 or CR4).
     2960 * @param   uGuestCrX       The current guest CR0/CR4.
     2961 * @param   puNewCrX        Pointer to the new CR0/CR4 value. Will be updated
     2962 *                          if no VM-exit is triggered.
     2963 * @param   iGReg           The general register to load the CR0/CR4 value from.
    29612964 * @param   cbInstr         The instruction length in bytes.
    29622965 */
    2963 IEM_STATIC VBOXSTRICTRC iemVmxVmexitInstrMovCr0Write(PVMCPU pVCpu, uint64_t uGuestCr0, uint64_t *puNewCr0, uint8_t iGReg,
     2966IEM_STATIC VBOXSTRICTRC iemVmxVmexitInstrMovToCr0Cr4(PVMCPU pVCpu, uint8_t iCrReg, uint64_t *puNewCrX, uint8_t iGReg,
    29642967                                                     uint8_t cbInstr)
    29652968{
     2969    Assert(puNewCrX);
     2970    Assert(iCrReg == 0 || iCrReg == 4);
     2971
    29662972    PCVMXVVMCS pVmcs = pVCpu->cpum.GstCtx.hwvirt.vmx.CTX_SUFF(pVmcs);
    29672973    Assert(pVmcs);
    2968     Assert(puNewCr0);
    2969 
    2970     uint32_t const fGstHostMask = pVmcs->u64Cr0Mask.u;
    2971     uint32_t const fReadShadow  = pVmcs->u64Cr0ReadShadow.u;
    2972 
    2973     /*
    2974      * For any CR0 bit owned by the host (in the CR0 guest/host mask), if the
     2974
     2975    uint64_t uGuestCrX;
     2976    uint64_t fGstHostMask;
     2977    uint64_t fReadShadow;
     2978    if (iCrReg == 0)
     2979    {
     2980        IEM_CTX_ASSERT(pVCpu, CPUMCTX_EXTRN_CR0);
     2981        uGuestCrX    = pVCpu->cpum.GstCtx.cr0;
     2982        fGstHostMask = pVmcs->u64Cr0Mask.u;
     2983        fReadShadow  = pVmcs->u64Cr0ReadShadow.u;
     2984    }
     2985    else
     2986    {
     2987        IEM_CTX_ASSERT(pVCpu, CPUMCTX_EXTRN_CR4);
     2988        uGuestCrX    = pVCpu->cpum.GstCtx.cr4;
     2989        fGstHostMask = pVmcs->u64Cr4Mask.u;
     2990        fReadShadow  = pVmcs->u64Cr4ReadShadow.u;
     2991    }
     2992
     2993    /*
     2994     * For any CR0/CR4 bit owned by the host (in the CR0/CR4 guest/host mask), if the
    29752995     * corresponding bits differ between the source operand and the read-shadow,
    29762996     * we must cause a VM-exit.
     
    29782998     * See Intel spec. 25.1.3 "Instructions That Cause VM Exits Conditionally".
    29792999     */
    2980     if ((fReadShadow & fGstHostMask) != (*puNewCr0 & fGstHostMask))
    2981     {
    2982         Log2(("mov_Cr_Rd: Guest intercept -> VM-exit\n"));
     3000    if ((fReadShadow & fGstHostMask) != (*puNewCrX & fGstHostMask))
     3001    {
     3002        Log2(("mov_Cr_Rd: (CR%u) Guest intercept -> VM-exit\n", iCrReg));
    29833003
    29843004        VMXVEXITINFO ExitInfo;
     
    29873007        ExitInfo.cbInstr = cbInstr;
    29883008
    2989         ExitInfo.u64Qual = RT_BF_MAKE(VMX_BF_EXIT_QUAL_CRX_REGISTER, 0) /* CR0 */
     3009        ExitInfo.u64Qual = RT_BF_MAKE(VMX_BF_EXIT_QUAL_CRX_REGISTER, iCrReg)
    29903010                         | RT_BF_MAKE(VMX_BF_EXIT_QUAL_CRX_ACCESS,   VMX_EXIT_QUAL_CRX_ACCESS_WRITE)
    29913011                         | RT_BF_MAKE(VMX_BF_EXIT_QUAL_CRX_GENREG,   iGReg);
     
    29943014
    29953015    /*
    2996      * If Mov-to-CR0 did not cause a VM-exit, any bits owned by the host must not
    2997      * be modified the instruction.
     3016     * If the Mov-to-CR0/CR4 did not cause a VM-exit, any bits owned by the host
     3017     * must not be modified the instruction.
    29983018     *
    29993019     * See Intel Spec. 25.3 "Changes To Instruction Behavior In VMX Non-root Operation".
    30003020     */
    3001     *puNewCr0 = (uGuestCr0 & fGstHostMask) | (*puNewCr0 & ~fGstHostMask);
     3021    *puNewCrX = (uGuestCrX & fGstHostMask) | (*puNewCrX & ~fGstHostMask);
    30023022
    30033023    return VINF_VMX_INTERCEPT_NOT_ACTIVE;
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