VirtualBox

Changeset 52065 in vbox


Ignore:
Timestamp:
Jul 17, 2014 6:38:17 AM (11 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
95067
Message:

VMM/HMVMXR0: Fix NMI re-injection when NMI injection caused a faulting VM-exit and blocking NMIs until IRET completes if the IRET caused a fault.

File:
1 edited

Legend:

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

    r52054 r52065  
    55
    66/*
    7  * Copyright (C) 2012-2013 Oracle Corporation
     7 * Copyright (C) 2012-2014 Oracle Corporation
    88 *
    99 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    24042404
    24052405        val |= VMX_VMCS_CTRL_PROC_EXEC_USE_TPR_SHADOW;         /* CR8 reads from the Virtual-APIC page. */
    2406                                                                /* CR8 writes causes a VM-exit based on TPR threshold. */
     2406                                                               /* CR8 writes cause a VM-exit based on TPR threshold. */
    24072407        Assert(!(val & VMX_VMCS_CTRL_PROC_EXEC_CR8_STORE_EXIT));
    24082408        Assert(!(val & VMX_VMCS_CTRL_PROC_EXEC_CR8_LOAD_EXIT));
     
    24162416        if (pVM->hm.s.fAllow64BitGuests)
    24172417        {
    2418             val |=   VMX_VMCS_CTRL_PROC_EXEC_CR8_STORE_EXIT    /* CR8 reads causes a VM-exit. */
    2419                    | VMX_VMCS_CTRL_PROC_EXEC_CR8_LOAD_EXIT;    /* CR8 writes causes a VM-exit. */
     2418            val |=   VMX_VMCS_CTRL_PROC_EXEC_CR8_STORE_EXIT    /* CR8 reads cause a VM-exit. */
     2419                   | VMX_VMCS_CTRL_PROC_EXEC_CR8_LOAD_EXIT;    /* CR8 writes cause a VM-exit. */
    24202420        }
    24212421    }
     
    24332433        /*
    24342434         * The guest can access the following MSRs (read, write) without causing VM-exits; they are loaded/stored
    2435          * automatically as dedicated fields in the VMCS.
     2435         * automatically using dedicated fields in the VMCS.
    24362436         */
    24372437        hmR0VmxSetMsrPermission(pVCpu, MSR_IA32_SYSENTER_CS,  VMXMSREXIT_PASSTHRU_READ, VMXMSREXIT_PASSTHRU_WRITE);
     
    57735773static int hmR0VmxCheckExitDueToEventDelivery(PVMCPU pVCpu, PCPUMCTX pMixedCtx, PVMXTRANSIENT pVmxTransient)
    57745774{
     5775    uint32_t uExitVector = VMX_EXIT_INTERRUPTION_INFO_VECTOR(pVmxTransient->uExitIntInfo);
     5776
    57755777    int rc = hmR0VmxReadIdtVectoringInfoVmcs(pVmxTransient);
    57765778    AssertRCReturn(rc, rc);
     
    57815783
    57825784        uint32_t uIntType    = VMX_IDT_VECTORING_INFO_TYPE(pVmxTransient->uIdtVectoringInfo);
    5783         uint32_t uExitVector = VMX_EXIT_INTERRUPTION_INFO_VECTOR(pVmxTransient->uExitIntInfo);
    57845785        uint32_t uIdtVector  = VMX_IDT_VECTORING_INFO_VECTOR(pVmxTransient->uIdtVectoringInfo);
    57855786
     
    58225823                    enmReflect = VMXREFLECTXCPT_TF;
    58235824            }
     5825            else if (   uIntType == VMX_IDT_VECTORING_INFO_TYPE_NMI
     5826                     && (pVCpu->hm.s.vmx.u32PinCtls & VMX_VMCS_CTRL_PIN_EXEC_VIRTUAL_NMI))
     5827            {
     5828                /*
     5829                 * If this exception occurred while delivering the NMI, we need to clear the block-by-NMI field in the
     5830                 * guest interruptibility-state before re-delivering the NMI, otherwise the subsequent VM-entry would fail.
     5831                 * See Intel spec. 30.7.1.2 "Resuming Guest Software after Handling an Exception". See @bugref{7445}.
     5832                 */
     5833                Assert(VMCPU_FF_IS_PENDING(pVCpu, VMCPU_FF_INHIBIT_NMIS));
     5834                VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_INHIBIT_NMIS);
     5835                enmReflect = VMXREFLECTXCPT_XCPT;
     5836            }
    58245837            else if (   uIntType == VMX_IDT_VECTORING_INFO_TYPE_HW_XCPT
    58255838                     || uIntType == VMX_IDT_VECTORING_INFO_TYPE_EXT_INT
     
    58975910        }
    58985911    }
     5912    else if (    VMX_EXIT_INTERRUPTION_INFO_NMI_UNBLOCK_IRET(pVmxTransient->uExitIntInfo)
     5913             &&  uExitVector != X86_XCPT_DF
     5914             && (pVCpu->hm.s.vmx.u32PinCtls & VMX_VMCS_CTRL_PIN_EXEC_VIRTUAL_NMI))
     5915    {
     5916        /*
     5917         * Execution of IRET caused this fault when NMI blocking was in effect. We need to reset the block-by-NMI field so
     5918         * that NMIs remain blocked until the IRET execution is completed.
     5919         * See Intel spec. 30.7.1.2 "Resuming guest software after handling an exception".
     5920         */
     5921        if (!VMCPU_FF_IS_PENDING(pVCpu, VMCPU_FF_INHIBIT_NMIS))
     5922            VMCPU_FF_SET(pVCpu, VMCPU_FF_INHIBIT_NMIS);
     5923    }
     5924
    58995925    Assert(rc == VINF_SUCCESS || rc == VINF_HM_DOUBLE_FAULT || rc == VINF_EM_RESET);
    59005926    return rc;
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