VirtualBox

Changeset 74303 in vbox


Ignore:
Timestamp:
Sep 17, 2018 9:33:58 AM (7 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
125109
Message:

VMM/CPUM, IEM: Nested VMX: bugref:9180 vmlaunch/vmresume bits.

Location:
trunk
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/VBox/vmm/cpum.mac

    r72643 r74303  
    280280    alignb 8
    281281    .hwvirt.svm.HCPhysVmcb             RTHCPHYS_RES  1
     282    .hwvirt.uInhibitRip                resq          1
    282283    .hwvirt.fLocalForcedActions        resd          1
    283284    .hwvirt.fGif                       resb          1
  • trunk/include/VBox/vmm/cpumctx.h

    r74287 r74303  
    618618        } CPUM_UNION_NM(s);
    619619
    620         /** 0x3f0 - A subset of force flags that are preserved while running the nested-guest. */
     620        /** 0x3f0 - Saved guest's interrupt-inhibited RIP (if any) - Intel only. */
     621        uint64_t                uInhibitRip;
     622        /** 0x3f8 - A subset of guest force flags that are saved while running the
     623         *  nested-guest. */
    621624        uint32_t                fLocalForcedActions;
    622         /** 0x3f4 - Global interrupt flag (always true on nested VMX). */
     625        /** 0x3fc - Global interrupt flag - AMD only (always true on Intel). */
    623626        bool                    fGif;
    624         /** 0x3f5 - Padding. */
    625         uint8_t                 abPadding1[11];
     627        /** 0x3fd - Padding. */
     628        uint8_t                 abPadding1[3];
    626629    } hwvirt;
    627630    /** @} */
     
    687690AssertCompileMemberOffset(CPUMCTX, hwvirt.CPUM_UNION_NM(s.) svm.pvIoBitmapR3,           0x3e0);
    688691AssertCompileMemberOffset(CPUMCTX, hwvirt.CPUM_UNION_NM(s.) svm.HCPhysVmcb,             0x3e8);
    689 AssertCompileMemberOffset(CPUMCTX, hwvirt.fLocalForcedActions, 0x3f0);
     692AssertCompileMemberOffset(CPUMCTX, hwvirt.uInhibitRip,         0x3f0);
     693AssertCompileMemberOffset(CPUMCTX, hwvirt.fLocalForcedActions, 0x3f8);
     694AssertCompileMemberOffset(CPUMCTX, hwvirt.fGif,                0x3fc);
    690695AssertCompileMemberAlignment(CPUMCTX, hwvirt.CPUM_UNION_NM(s.) svm.pVmcbR0,       8);
    691696AssertCompileMemberAlignment(CPUMCTX, hwvirt.CPUM_UNION_NM(s.) svm.pvMsrBitmapR0, 8);
  • trunk/include/VBox/vmm/hm_vmx.h

    r74287 r74303  
    24402440#define VMX_IDT_VECTORING_INFO_IS_VALID(a)                      (((a) >> 31) & 1)
    24412441
     2442/** Construct an IDT-vectoring information field from an VM-entry interruption
     2443 *  information field (same except that bit 12 is reserved). */
     2444#define VMX_EXIT_IDT_INFO_FROM_ENTRY_INT_INFO(a)                ((a) & ~RT_BIT(12))
     2445
    24422446/** Bit fields for IDT-vectoring information. */
    24432447/** The IDT-vectoring info vector. */
     
    27952799/** @name Format of Pending-Debug-Exceptions.
    27962800 * Bits 4-11, 13, 15 and 17-63 are reserved.
     2801 * Similar to DR6 except bit 12 (breakpoint enabled) and bit 16 (RTM) are both
     2802 * possibly valid here but not in DR6.
    27972803 * @{
    27982804 */
  • trunk/src/VBox/VMM/VMMAll/IEMAllCImplVmxInstr.cpp.h

    r74287 r74303  
    40704070
    40714071/**
     4072 * Loads the guest-state non-register state as part of VM-entry.
     4073 *
     4074 * @returns VBox status code.
     4075 * @param   pVCpu           The cross context virtual CPU structure.
     4076 *
     4077 * @remarks This must be called only after loading the nested-guest register state
     4078 *          (especially nested-guest RIP).
     4079 */
     4080IEM_STATIC void iemVmxVmentryLoadGuestNonRegState(PVMCPU pVCpu)
     4081{
     4082    /*
     4083     * Load guest non-register state.
     4084     * See Intel spec. 26.6 "Special Features of VM Entry"
     4085     */
     4086    PCVMXVVMCS pVmcs = pVCpu->cpum.GstCtx.hwvirt.vmx.CTX_SUFF(pVmcs);
     4087    uint32_t const uEntryIntInfo = pVmcs->u32EntryIntInfo;
     4088    if (VMX_ENTRY_INT_INFO_IS_VALID(uEntryIntInfo))
     4089    {
     4090        /** @todo NSTVMX: Pending debug exceptions. */
     4091        Assert(!(pVmcs->u64GuestPendingDbgXcpt.u));
     4092
     4093        if (pVmcs->u32GuestIntrState == VMX_VMCS_GUEST_INT_STATE_BLOCK_NMI)
     4094        {
     4095            /** @todo NSTVMX: Virtual-NMIs doesn't affect NMI blocking in the normal sense.
     4096             *        We probably need a different force flag for virtual-NMI
     4097             *        pending/blocking. */
     4098            Assert(!(pVmcs->u32PinCtls & VMX_PIN_CTLS_VIRT_NMI));
     4099            VMCPU_FF_SET(pVCpu, VMCPU_FF_BLOCK_NMIS);
     4100        }
     4101        else if (   pVmcs->u32GuestIntrState == VMX_VMCS_GUEST_INT_STATE_BLOCK_STI
     4102                 || pVmcs->u32GuestIntrState == VMX_VMCS_GUEST_INT_STATE_BLOCK_MOVSS)
     4103        {
     4104            EMSetInhibitInterruptsPC(pVCpu, pVCpu->cpum.GstCtx.rip);
     4105        }
     4106
     4107        /* SMI blocking is irrelevant. We don't support SMIs yet. */
     4108    }
     4109
     4110    /* Loading PDPTEs will be taken care when we switch modes. We don't support EPT yet. */
     4111    Assert(!(pVmcs->u32ProcCtls2 & VMX_PROC_CTLS2_EPT));
     4112
     4113    /* VPID is irrelevant. We don't support VPID yet. */
     4114
     4115    /* Clear address-range monitoring. */
     4116    EMMonitorWaitClear(pVCpu);
     4117}
     4118
     4119
     4120/**
     4121 * Saves the guest force-flags in prepartion of entering the nested-guest.
     4122 *
     4123 * @param   pVCpu       The cross context virtual CPU structure.
     4124 */
     4125IEM_STATIC void iemVmxVmentrySaveForceFlags(PVMCPU pVCpu)
     4126{
     4127    /* Assert that we are not called multiple times during VM-entry. */
     4128    Assert(pVCpu->cpum.GstCtx.hwvirt.fLocalForcedActions == 0);
     4129
     4130    /*
     4131     * Preserve the required force-flags.
     4132     *
     4133     * We only preserve the force-flags that would affect the execution of the
     4134     * nested-guest (or the guest).
     4135     *
     4136     *   - VMCPU_FF_INHIBIT_INTERRUPTS and RIP needs be preserved as there is no
     4137     *     implicit Global Interrupt Flag (GIF) handling as with AMD-V's VMRUN
     4138     *     instruction and the interrupt inhibition is in effect until the
     4139     *     completion of this VMLAUNCH/VMRESUME instruction.
     4140     *
     4141     *   - VMCPU_FF_BLOCK_NMIS needs to be preserved as it blocks NMI until the
     4142     *     execution of a subsequent IRET instruction in the guest.
     4143     *
     4144     *   - MTF needs to be preserved as it's for a single instruction boundary
     4145     *     which follows the return from VMLAUNCH/VMRESUME instruction.
     4146     *
     4147     * The remaining FFs (e.g. timers) can stay in place so that we will be able to
     4148     * generate interrupts that should cause #VMEXITs for the nested-guest.
     4149     */
     4150    if (VMCPU_FF_IS_PENDING(pVCpu, VMCPU_FF_INHIBIT_INTERRUPTS))
     4151        pVCpu->cpum.GstCtx.hwvirt.uInhibitRip = EMGetInhibitInterruptsPC(pVCpu);
     4152
     4153    uint32_t const fGuestFFMask = VMCPU_FF_INHIBIT_INTERRUPTS | VMCPU_FF_BLOCK_NMIS | VMCPU_FF_MTF;
     4154    pVCpu->cpum.GstCtx.hwvirt.fLocalForcedActions = pVCpu->fLocalForcedActions & fGuestFFMask;
     4155    VMCPU_FF_CLEAR(pVCpu, fGuestFFMask);
     4156}
     4157
     4158
     4159#if 0
     4160/**
     4161 * Restores the guest force-flags in prepartion of exiting the nested-guest.
     4162 *
     4163 * @param   pVCpu       The cross context virtual CPU structure.
     4164 */
     4165IEM_STATIC void iemVmxVmexitRestoreForceFlags(PVMCPU pVCpu)
     4166{
     4167    if (pVCpu->cpum.GstCtx.hwvirt.fLocalForcedActions)
     4168    {
     4169        VMCPU_FF_SET(pVCpu, pVCpu->cpum.GstCtx.hwvirt.fLocalForcedActions);
     4170        pVCpu->cpum.GstCtx.hwvirt.fLocalForcedActions = 0;
     4171    }
     4172}
     4173#endif
     4174
     4175
     4176/**
    40724177 * Loads the guest-state as part of VM-entry.
    40734178 *
     
    40964201    pVCpu->cpum.GstCtx.rflags.u = pVmcs->u64GuestRFlags.u;
    40974202
    4098     /* Loading PDPTEs will be taken care when we switch modes. We don't support EPT yet. */
    4099     Assert(!(pVmcs->u32ProcCtls2 & VMX_PROC_CTLS2_EPT));
    4100 
    4101     /* Nothing to do for VPID. */
    4102 
    4103     /* Clear address-range monitoring. */
    4104     EMMonitorWaitClear(pVCpu);
     4203    /* Load guest non-register state. */
     4204    iemVmxVmentryLoadGuestNonRegState(pVCpu);
    41054205
    41064206    NOREF(pszInstr);
     
    41254225    if (VMX_ENTRY_INT_INFO_IS_VALID(uEntryIntInfo))
    41264226    {
     4227        /*
     4228         * The event that is going to be made pending for injection is not subject to VMX intercepts,
     4229         * thus we flag ignoring of intercepts. However, recursive exceptions if any during delivery
     4230         * of the current event -are- subject to intercepts, hence this flag will be flipped during
     4231         * the actually delivery of this event.
     4232         */
     4233        pVCpu->cpum.GstCtx.hwvirt.vmx.fInterceptEvents = false;
     4234
    41274235        uint8_t const uType = VMX_ENTRY_INT_INFO_TYPE(uEntryIntInfo);
    41284236        if (uType == VMX_ENTRY_INT_INFO_TYPE_OTHER_EVENT)
     
    41334241        }
    41344242
    4135         /** @todo NSTVMX: Is it safe to update IDT-vectoring information in the VMCS
    4136          *        here? */
    4137 
    4138         pVCpu->cpum.GstCtx.hwvirt.vmx.fInterceptEvents = false;
    41394243        int rc = HMVmxEntryIntInfoInjectTrpmEvent(pVCpu, uEntryIntInfo, pVmcs->u32EntryXcptErrCode, pVmcs->u32EntryInstrLen,
    41404244                                                  pVCpu->cpum.GstCtx.cr2);
     
    42984402                if (RT_SUCCESS(rc))
    42994403                {
     4404                    /* Save the (outer) guest force-flags as VM-exits can occur from this point on. */
     4405                    iemVmxVmentrySaveForceFlags(pVCpu);
     4406
    43004407                    /* Check guest-state fields. */
    43014408                    rc = iemVmxVmentryCheckGuestState(pVCpu, pszInstr);
     
    43424449                                return VINF_SUCCESS;
    43434450                            }
    4344 
    43454451                            /** @todo NSTVMX: VMExit with VMX_EXIT_ERR_MSR_LOAD and set
    43464452                             *        VMX_BF_EXIT_REASON_ENTRY_FAILED. */
  • trunk/src/VBox/VMM/include/CPUMInternal.mac

    r74163 r74303  
    253253    alignb 8
    254254    .Guest.hwvirt.svm.HCPhysVmcb             RTHCPHYS_RES 1
     255    .Guest.hwvirt.uInhibitRip                resq         1
    255256    .Guest.hwvirt.fLocalForcedActions        resd         1
    256257    .Guest.hwvirt.fGif                       resb         1
     
    540541    alignb 8
    541542    .Hyper.hwvirt.svm.HCPhysVmcb             RTHCPHYS_RES 1
     543    .Hyper.hwvirt.uInhibitRip                resq         1
    542544    .Hyper.hwvirt.fLocalForcedActions        resd         1
    543545    .Hyper.hwvirt.fGif                       resb         1
  • trunk/src/VBox/VMM/testcase/tstVMStruct.h

    r74287 r74303  
    164164    GEN_CHECK_OFF(CPUMCTX, hwvirt.vmx.pAutoMsrAreaR0);
    165165    GEN_CHECK_OFF(CPUMCTX, hwvirt.vmx.pAutoMsrAreaR3);
     166    GEN_CHECK_OFF(CPUMCTX, hwvirt.uInhibitRip);
    166167    GEN_CHECK_OFF(CPUMCTX, hwvirt.fLocalForcedActions);
    167168    GEN_CHECK_OFF(CPUMCTX, hwvirt.fGif);
    168     /** @todo add rest of hwvirt fields when code is more
     169    /** @todo NSTVMX: add rest of hwvirt fields when code is more
    169170     *        finalized. */
    170171    GEN_CHECK_OFF(CPUMCTX, pXStateR0);
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