VirtualBox

Changeset 79757 in vbox for trunk/src/VBox


Ignore:
Timestamp:
Jul 13, 2019 4:18:24 PM (5 years ago)
Author:
vboxsync
Message:

VMM/HMVMXR0: Nested VMX: bugref:9180 If execution of IRET causes an EPT violation VM-exit, the NMI-unblocking information bit is in the Exit qualification (bit 12) field and -not- in VM-exit interruption information field.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/VMMR0/HMVMXR0.cpp

    r79753 r79757  
    1362513625 * @param   pVmxTransient   The VMX-transient structure.
    1362613626 *
     13627 * @remarks Requires all fields in HMVMX_READ_XCPT_INFO to be read from the VMCS.
    1362713628 * @remarks No-long-jump zone!!!
    1362813629 */
     
    1376013761 * @param   pVmxTransient   The VMX-transient structure.
    1376113762 *
     13763 * @remarks Requires all fields in HMVMX_READ_XCPT_INFO to be read from the VMCS.
     13764 *          Additionally, HMVMX_READ_EXIT_QUALIFICATION is required if the VM-exit
     13765 *          is due to an EPT violation, PML-full and SPP-related event.
     13766 *
    1376213767 * @remarks No-long-jump zone!!!
    1376313768 */
     
    1393413939        }
    1393513940    }
    13936     else if (   VMX_EXIT_INT_INFO_IS_VALID(uExitIntInfo)
    13937              && VMX_EXIT_INT_INFO_IS_NMI_UNBLOCK_IRET(uExitIntInfo)
    13938              && uExitVector != X86_XCPT_DF
    13939              && hmR0VmxIsPinCtlsSet(pVCpu, pVmxTransient, VMX_PIN_CTLS_VIRT_NMI))
    13940     {
    13941         Assert(!VMX_IDT_VECTORING_INFO_IS_VALID(uIdtVectorInfo));
    13942 
    13943         /*
    13944          * Execution of IRET caused this fault when NMI blocking was in effect (i.e we're in the guest NMI handler).
    13945          * We need to set the block-by-NMI field so that NMIs remain blocked until the IRET execution is restarted.
    13946          * See Intel spec. 30.7.1.2 "Resuming guest software after handling an exception".
    13947          */
    13948         CPUMSetGuestNmiBlocking(pVCpu, true);
    13949         Log4Func(("Set NMI blocking. uExitReason=%u\n", pVmxTransient->uExitReason));
     13941    else if (hmR0VmxIsPinCtlsSet(pVCpu, pVmxTransient, VMX_PIN_CTLS_VIRT_NMI))
     13942    {
     13943        if (    VMX_EXIT_INT_INFO_IS_VALID(uExitIntInfo)
     13944             && VMX_EXIT_INT_INFO_VECTOR(uExitIntInfo) != X86_XCPT_DF
     13945             && VMX_EXIT_INT_INFO_IS_NMI_UNBLOCK_IRET(uExitIntInfo))
     13946        {
     13947            /*
     13948             * Execution of IRET caused a fault when NMI blocking was in effect (i.e we're in
     13949             * the guest or nested-guest NMI handler). We need to set the block-by-NMI field so
     13950             * that NMIs remain blocked until the IRET execution is completed.
     13951             *
     13952             * See Intel spec. 31.7.1.2 "Resuming Guest Software After Handling An Exception".
     13953             */
     13954            CPUMSetGuestNmiBlocking(pVCpu, true);
     13955            Log4Func(("Set NMI blocking. uExitReason=%u\n", pVmxTransient->uExitReason));
     13956        }
     13957        else if (   pVmxTransient->uExitReason == VMX_EXIT_EPT_VIOLATION
     13958                 || pVmxTransient->uExitReason == VMX_EXIT_PML_FULL
     13959                 || pVmxTransient->uExitReason == VMX_EXIT_SPP_EVENT)
     13960        {
     13961#ifdef VBOX_STRICT
     13962            /*
     13963             * Validate we have read the Exit qualification from the VMCS.
     13964             */
     13965            uint32_t const fVmcsFieldRead = ASMAtomicUoReadU32(&pVmxTransient->fVmcsFieldsRead);
     13966            RT_UNTRUSTED_NONVOLATILE_COPY_FENCE();
     13967            Assert(fVmcsFieldRead & HMVMX_READ_EXIT_QUALIFICATION);
     13968#endif
     13969            /*
     13970             * Execution of IRET caused an EPT violation, page-modification log-full event or
     13971             * SPP-related event VM-exit when NMI blocking was in effect (i.e. we're in the
     13972             * guest or nested-guest NMI handler). We need to set the block-by-NMI field so
     13973             * that NMIs remain blocked until the IRET execution is completed.
     13974             *
     13975             * See Intel spec. 27.2.3 "Information about NMI unblocking due to IRET"
     13976             */
     13977            if (VMX_EXIT_QUAL_EPT_IS_NMI_UNBLOCK_IRET(pVmxTransient->uExitQual))
     13978            {
     13979                CPUMSetGuestNmiBlocking(pVCpu, true);
     13980                Log4Func(("Set NMI blocking. uExitReason=%u\n", pVmxTransient->uExitReason));
     13981            }
     13982        }
    1395013983    }
    1395113984
     
    1658316616    Assert(pVCpu->CTX_SUFF(pVM)->hm.s.fNestedPaging);
    1658416617
    16585     int rc  = hmR0VmxReadExitIntInfoVmcs(pVmxTransient);
     16618    int rc  = hmR0VmxReadExitQualVmcs(pVCpu, pVmxTransient);
     16619    rc     |= hmR0VmxReadExitIntInfoVmcs(pVmxTransient);
    1658616620    rc     |= hmR0VmxReadExitIntErrorCodeVmcs(pVmxTransient);
    1658716621    rc     |= hmR0VmxReadExitInstrLenVmcs(pVmxTransient);
     
    1661216646    PVMXVMCSINFO pVmcsInfo = pVmxTransient->pVmcsInfo;
    1661316647    rc  = VMXReadVmcs64(VMX_VMCS64_RO_GUEST_PHYS_ADDR_FULL, &GCPhys);
    16614     rc |= hmR0VmxReadExitQualVmcs(pVCpu, pVmxTransient);
    1661516648    rc |= hmR0VmxImportGuestState(pVCpu, pVmcsInfo, IEM_CPUMCTX_EXTRN_MUST_MASK);
    1661616649    AssertRCReturn(rc, rc);
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