VirtualBox

Changeset 10661 in vbox for trunk/src/VBox


Ignore:
Timestamp:
Jul 15, 2008 2:21:04 PM (16 years ago)
Author:
vboxsync
Message:

Reduce the number of world switches caused by cr8 writes by checking if we really need to be notified. (only when
an interrupt is pending and masked by the TRP value)

Location:
trunk/src/VBox/VMM
Files:
4 edited

Legend:

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

    r10473 r10661  
    17261726    {
    17271727        val64 = 0;
    1728         rc = PDMApicGetTPR(pVM, (uint8_t *)&val64);
     1728        rc = PDMApicGetTPR(pVM, (uint8_t *)&val64, NULL);
    17291729        AssertMsgRCReturn(rc, ("PDMApicGetTPR failed\n"), VERR_EM_INTERPRETER);
    17301730    }
  • trunk/src/VBox/VMM/VMMAll/PDMAll.cpp

    r10520 r10661  
    230230
    231231/**
    232  * Get the TPR (task priority register?).
     232 * Get the TPR (task priority register).
    233233 *
    234234 * @returns The current TPR.
    235235 * @param   pVM             VM handle.
    236236 * @param   pu8TPR          Where to store the TRP.
    237  */
    238 PDMDECL(int) PDMApicGetTPR(PVM pVM, uint8_t *pu8TPR)
     237 * @param   pfPending       Pending interrupt state (out).
     238*/
     239PDMDECL(int) PDMApicGetTPR(PVM pVM, uint8_t *pu8TPR, bool *pfPending)
    239240{
    240241    if (pVM->pdm.s.Apic.CTXALLSUFF(pDevIns))
     
    243244        pdmLock(pVM);
    244245        *pu8TPR = pVM->pdm.s.Apic.CTXALLSUFF(pfnGetTPR)(pVM->pdm.s.Apic.CTXALLSUFF(pDevIns));
     246        if (pfPending)
     247            *pfPending = pVM->pdm.s.Apic.CTXALLSUFF(pfnHasPendingIrq)(pVM->pdm.s.Apic.CTXALLSUFF(pDevIns));
    245248        pdmUnlock(pVM);
    246249        return VINF_SUCCESS;
  • trunk/src/VBox/VMM/VMMR0/HWSVMR0.cpp

    r10647 r10661  
    269269     */
    270270    if (!pVM->hwaccm.s.fNestedPaging)
    271         pVMCB->ctrl.u16InterceptWrCRx = RT_BIT(0) | RT_BIT(3) | RT_BIT(4) | RT_BIT(8);
     271        pVMCB->ctrl.u16InterceptWrCRx = RT_BIT(0) | RT_BIT(3) | RT_BIT(4);
    272272    else
    273273        pVMCB->ctrl.u16InterceptWrCRx = RT_BIT(0) | RT_BIT(4) | RT_BIT(8);
     
    861861    if (pCtx->msrEFER & MSR_K6_EFER_LMA)
    862862    {
     863        bool fPending;
     864
    863865        /* TPR caching in CR8 */
    864         int rc = PDMApicGetTPR(pVM, &u8LastVTPR);
     866        int rc = PDMApicGetTPR(pVM, &u8LastVTPR, &fPending);
    865867        AssertRC(rc);
    866868        pVMCB->ctrl.IntCtrl.n.u8VTPR = u8LastVTPR;
     869
     870        if (fPending)
     871        {
     872            /* A TPR change could activate a pending interrupt, so catch cr8 writes. */
     873            pVMCB->ctrl.u16InterceptWrCRx |= RT_BIT(8);
     874        }
     875        else
     876            /* No interrupts are pending, so we don't need to be explicitely notified.
     877             * There are enough world switches for detecting pending interrupts.
     878             */
     879            pVMCB->ctrl.u16InterceptWrCRx &= ~RT_BIT(8);
    867880    }
    868881
  • trunk/src/VBox/VMM/VMMR0/HWVMXR0.cpp

    r10647 r10661  
    11821182        /* TPR caching in CR8 */
    11831183        uint8_t u8TPR;
    1184         int rc = PDMApicGetTPR(pVM, &u8TPR);
     1184        bool    fPending;
     1185
     1186        int rc = PDMApicGetTPR(pVM, &u8TPR, &fPending);
    11851187        AssertRC(rc);
    11861188        /* The TPR can be found at offset 0x80 in the APIC mmio page. */
    11871189        pVM->hwaccm.s.vmx.pAPIC[0x80] = u8TPR << 4; /* bits 7-4 contain the task priority */
    11881190
    1189         /* CR8 updates that lower the TPR value to below the current value should cause an exit. */
    1190         rc  = VMXWriteVMCS(VMX_VMCS_CTRL_TPR_THRESHOLD, u8TPR);
     1191        /* Two options here:
     1192         * - external interrupt pending, but masked by the TPR value.
     1193         *   -> CR8 updates that lower the TPR value to below the current value should cause an exit
     1194         * - no pending interrupts
     1195         *   -> We don't need to be explicitely notified. There are enough world switches for detecting pending interrupts.
     1196         */
     1197        rc  = VMXWriteVMCS(VMX_VMCS_CTRL_TPR_THRESHOLD, (fPending) ? u8TPR : 0);
    11911198        AssertRC(rc);
    11921199    }
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