VirtualBox

Changeset 74630 in vbox


Ignore:
Timestamp:
Oct 5, 2018 4:54:25 PM (7 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
125520
Message:

VMM/IEM: Nested VMX: bugref:9180 VM-exit bits; Added Mov from CR8 intercept.

Location:
trunk
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/VBox/err.h

    r74603 r74630  
    21072107 *  nested-guest execution mode. */
    21082108#define VINF_VMX_INTERCEPT_NOT_ACTIVE               4035
     2109/** The behavior of the instruction/operation is modified/needs modification
     2110 *  in VMX non-root mode. */
     2111#define VINF_VMX_MODIFIES_BEHAVIOR                  4036
    21092112/** @} */
    21102113
  • trunk/src/VBox/VMM/VMMAll/IEMAllCImpl.cpp.h

    r74621 r74630  
    51875187        {
    51885188            IEM_CTX_ASSERT(pVCpu, CPUMCTX_EXTRN_APIC_TPR);
     5189#ifdef VBOX_WITH_NESTED_HWVIRT_VMX
     5190            if (IEM_VMX_IS_NON_ROOT_MODE(pVCpu))
     5191            {
     5192                VBOXSTRICTRC rcStrict = iemVmxVmexitInstrMovFromCr8(pVCpu, iGReg, cbInstr);
     5193                if (rcStrict != VINF_VMX_INTERCEPT_NOT_ACTIVE)
     5194                    return rcStrict;
     5195
     5196                /*
     5197                 * If the Mov-from-CR8 doesn't cause a VM-exit, bits 7:4 of the VTPR is copied
     5198                 * to bits 0:3 of the destination operand and bits 63:4 are cleared.
     5199                 *
     5200                 * See Intel Spec. 25.3 "Changes To Instruction Behavior In VMX Non-root Operation".
     5201                 */
     5202                if (IEM_VMX_IS_PROCCTLS_SET(pVCpu, VMX_PROC_CTLS_USE_TPR_SHADOW))
     5203                {
     5204                    uint32_t const uVTpr = iemVmxVirtApicReadRaw32(pVCpu, XAPIC_OFF_TPR);
     5205                    crX = (uVTpr << 4) & 0xf;
     5206                    break;
     5207                }
     5208            }
     5209#endif
    51895210#ifdef VBOX_WITH_NESTED_HWVIRT_SVM
    51905211            if (CPUMIsGuestInSvmNestedHwVirtMode(IEM_GET_CTX(pVCpu)))
     
    58315852
    58325853    IEM_CTX_ASSERT(pVCpu, CPUMCTX_EXTRN_CR0);
     5854    uint64_t uNewCr0 = pVCpu->cpum.GstCtx.cr0;
     5855    uNewCr0 &= ~X86_CR0_TS;
    58335856
    58345857#ifdef VBOX_WITH_NESTED_HWVIRT_VMX
    5835     /* Check nested-guest VMX intercept. */
    58365858    if (IEM_VMX_IS_NON_ROOT_MODE(pVCpu))
    58375859    {
    58385860        VBOXSTRICTRC rcStrict = iemVmxVmexitInstrClts(pVCpu, cbInstr);
    5839         if (rcStrict == VINF_PERMISSION_DENIED)
    5840         {
    5841             iemRegAddToRipAndClearRF(pVCpu, cbInstr);
    5842             return VINF_SUCCESS;
    5843         }
     5861        if (rcStrict == VINF_VMX_MODIFIES_BEHAVIOR)
     5862            uNewCr0 |= (pVCpu->cpum.GstCtx.cr0 & X86_CR0_TS);
    58445863        else if (rcStrict != VINF_VMX_INTERCEPT_NOT_ACTIVE)
    58455864            return rcStrict;
     
    58475866#endif
    58485867
    5849     uint64_t uNewCr0 = pVCpu->cpum.GstCtx.cr0;
    5850     uNewCr0 &= ~X86_CR0_TS;
    58515868    return IEM_CIMPL_CALL_4(iemCImpl_load_CrX, /*cr*/ 0, uNewCr0, IEMACCESSCRX_CLTS, UINT8_MAX /* iGReg */);
    58525869}
  • trunk/src/VBox/VMM/VMMAll/IEMAllCImplVmxInstr.cpp.h

    r74624 r74630  
    927927
    928928/**
     929 * Reads a 32-bit register from the virtual-APIC page at the given offset.
     930 *
     931 * @returns The register from the virtual-APIC page.
     932 * @param   pVCpu       The cross context virtual CPU structure.
     933 * @param   offReg      The offset of the register being read.
     934 */
     935DECLINLINE(uint32_t) iemVmxVirtApicReadRaw32(PVMCPU pVCpu, uint8_t offReg)
     936{
     937    Assert(offReg <= VMX_V_VIRT_APIC_SIZE - sizeof(uint32_t));
     938
     939    uint8_t  const *pbVirtApic = (const uint8_t *)pVCpu->cpum.GstCtx.hwvirt.vmx.CTX_SUFF(pvVirtApicPage);
     940    Assert(pVCpu->cpum.GstCtx.hwvirt.vmx.CTX_SUFF(pvVirtApicPage));
     941    uint32_t const uValue      = *(const uint32_t *)(pbVirtApic + offReg);
     942    return uValue;
     943}
     944
     945
     946/**
    929947 * Masks the nested-guest CR0/CR4 mask subjected to the corresponding guest/host
    930948 * mask and the read-shadow (CR0/CR4 read).
     
    29252943 *
    29262944 * @returns Strict VBox status code.
    2927  * @retval VINF_PERMISSION_DENIED if the CLTS instruction did not cause a VM-exit
    2928  *         but must not modify the guest CR0.TS bit.
     2945 * @retval VINF_VMX_MODIFIES_BEHAVIOR if the CLTS instruction did not cause a
     2946 *         VM-exit but must not modify the guest CR0.TS bit.
    29292947 * @retval VINF_VMX_INTERCEPT_NOT_ACTIVE if the CLTS instruction did not cause a
    2930  *         VM-exit but modification to the guest CR0.TS bit is allowed (subject to
     2948 *         VM-exit and modification to the guest CR0.TS bit is allowed (subject to
    29312949 *         CR0 fixed bits in VMX operation).
    2932  *
    2933  * @param   pVCpu           The cross context virtual CPU structure.
    2934  * @param   cbInstr         The instruction length in bytes.
     2950 * @param   pVCpu       The cross context virtual CPU structure.
     2951 * @param   cbInstr     The instruction length in bytes.
    29352952 */
    29362953IEM_STATIC VBOXSTRICTRC iemVmxVmexitInstrClts(PVMCPU pVCpu, uint8_t cbInstr)
     
    29452962     * If CR0.TS is owned by the host:
    29462963     *   - If CR0.TS is set in the read-shadow, we must cause a VM-exit.
    2947      *   - If CR0.TS is cleared in the read-shadow, no VM-exit is caused, however
    2948      *     the CLTS instruction is not allowed to modify CR0.TS.
     2964     *   - If CR0.TS is cleared in the read-shadow, no VM-exit is caused and the
     2965     *     CLTS instruction completes without clearing CR0.TS.
    29492966     *
    29502967     * See Intel spec. 25.1.3 "Instructions That Cause VM Exits Conditionally".
     
    29662983        }
    29672984
    2968         return VINF_PERMISSION_DENIED;
     2985        return VINF_VMX_MODIFIES_BEHAVIOR;
    29692986    }
    29702987
     
    31333150            }
    31343151        }
     3152    }
     3153
     3154    return VINF_VMX_INTERCEPT_NOT_ACTIVE;
     3155}
     3156
     3157
     3158/**
     3159 * VMX VM-exit handler for VM-exits due to 'Mov GReg,CR8' (CR8 read).
     3160 *
     3161 * @returns VBox strict status code.
     3162 * @param   pVCpu       The cross context virtual CPU structure.
     3163 * @param   iGReg       The general register to which the CR8 value is being stored.
     3164 * @param   cbInstr     The instruction length in bytes.
     3165 */
     3166IEM_STATIC VBOXSTRICTRC iemVmxVmexitInstrMovFromCr8(PVMCPU pVCpu, uint8_t iGReg, uint8_t cbInstr)
     3167{
     3168    PCVMXVVMCS pVmcs = pVCpu->cpum.GstCtx.hwvirt.vmx.CTX_SUFF(pVmcs);
     3169    Assert(pVmcs);
     3170
     3171    /*
     3172     * If the CR8-store exiting control is set, we must cause a VM-exit.
     3173     * See Intel spec. 25.1.3 "Instructions That Cause VM Exits Conditionally".
     3174     */
     3175    if (pVmcs->u32ProcCtls & VMX_PROC_CTLS_CR8_STORE_EXIT)
     3176    {
     3177        Log2(("mov_Rd_Cr: (CR8) Guest intercept -> VM-exit\n"));
     3178
     3179        VMXVEXITINFO ExitInfo;
     3180        RT_ZERO(ExitInfo);
     3181        ExitInfo.uReason = VMX_EXIT_MOV_CRX;
     3182        ExitInfo.cbInstr = cbInstr;
     3183
     3184        ExitInfo.u64Qual = RT_BF_MAKE(VMX_BF_EXIT_QUAL_CRX_REGISTER, 8) /* CR8 */
     3185                         | RT_BF_MAKE(VMX_BF_EXIT_QUAL_CRX_ACCESS,   VMX_EXIT_QUAL_CRX_ACCESS_READ)
     3186                         | RT_BF_MAKE(VMX_BF_EXIT_QUAL_CRX_GENREG,   iGReg);
     3187        return iemVmxVmexitInstrWithInfo(pVCpu, &ExitInfo);
    31353188    }
    31363189
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