VirtualBox

Changeset 60716 in vbox


Ignore:
Timestamp:
Apr 27, 2016 1:11:46 PM (9 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
106902
Message:

VMM: Fixed TPR thresholding and related PDM interfaces.
Cleaned up the PDM interface and merged apicHasPendingIrq with apicGetTpr.
Fixed raw-mode with the new APIC code due to busted GC mapping relocation.

This finally fixes the NT4 VM boot-up issue with the new APIC code.

Location:
trunk
Files:
15 edited

Legend:

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

    r60622 r60716  
    27362736
    27372737
     2738/** @name APIC Status Codes
     2739 * @{
     2740 */
     2741/** No pending interrupt. */
     2742#define VERR_APIC_INTR_NOT_PENDING                  (-6700)
     2743/** Pending interrupt is masked by TPR. */
     2744#define VERR_APIC_INTR_MASKED_BY_TPR                (-6701)
     2745/** @} */
     2746
    27382747/* SED-END */
    27392748
  • TabularUnified trunk/include/VBox/vmm/pdmapi.h

    r60405 r60716  
    5151VMM_INT_DECL(int)       PDMIoApicSendMsi(PVM pVM, RTGCPHYS GCAddr, uint32_t uValue, uint32_t uTagSrc);
    5252VMM_INT_DECL(bool)      PDMHasApic(PVM pVM);
    53 VMM_INT_DECL(int)       PDMApicHasPendingIrq(PVM pVM, bool *pfPending);
    5453VMMDECL(VBOXSTRICTRC)   PDMApicSetBaseMsr(PVMCPU pVCpu, uint64_t u64Base);
    5554VMMDECL(VBOXSTRICTRC)   PDMApicGetBaseMsr(PVMCPU pVCpu, uint64_t *pu64Base, bool fIgnoreErrors);
    5655VMMDECL(int)            PDMApicSetTPR(PVMCPU pVCpu, uint8_t u8TPR);
    57 VMMDECL(int)            PDMApicGetTPR(PVMCPU pVCpu, uint8_t *pu8TPR, bool *pfPending, uint8_t *pu8PendingIrq);
     56VMMDECL(int)            PDMApicGetTPR(PVMCPU pVCpu, uint8_t *pu8TPR, bool *pfPending, uint8_t *pu8PendingIntr);
    5857VMM_INT_DECL(VBOXSTRICTRC) PDMApicWriteMsr(PVMCPU pVCpu, uint32_t u32Reg, uint64_t u64Value);
    5958VMM_INT_DECL(VBOXSTRICTRC) PDMApicReadMsr(PVMCPU pVCpu, uint32_t u32Reg, uint64_t *pu64Value);
  • TabularUnified trunk/include/VBox/vmm/pdmdev.h

    r60406 r60716  
    11541154     * Get a pending interrupt.
    11551155     *
    1156      * @returns Pending interrupt number, -1 if no interrupt is
    1157      *          pending.
     1156     * @returns VBox status code.
    11581157     * @param   pDevIns         Device instance of the APIC.
    11591158     * @param   pVCpu           The cross context virtual CPU structure.
    1160      * @param   puTagSrc        Where to return the tag source (tracing purposes).
    1161      * @remarks Caller enters the PDM critical section
    1162      */
    1163     DECLR3CALLBACKMEMBER(int, pfnGetInterruptR3,(PPDMDEVINS pDevIns, PVMCPU pVCpu, uint32_t *puTagSrc));
    1164 
    1165     /**
    1166      * Check if the APIC has a pending interrupt/if a TPR change would activate one.
    1167      *
    1168      * @returns true if an interrupt is pending, false otherwise.
    1169      * @param   pDevIns         Device instance of the APIC.
    1170      * @param   pVCpu           The cross context virtual CPU structure.
    1171      * @param   pu8PendingIrq   Where to store the highest priority pending IRQ
    1172      *                          (optional, can be NULL).
    1173      * @remarks Unlike the other callbacks, the PDM lock may not always be entered
    1174      *          prior to calling this method.
    1175      */
    1176     DECLR3CALLBACKMEMBER(bool, pfnHasPendingIrqR3,(PPDMDEVINS pDevIns, PVMCPU pVCpu, uint8_t *pu8PendingIrq));
     1159     * @param   pu8Vector       Where to store the vector.
     1160     * @param   pu32TagSrc      Where to return the tag source (tracing
     1161     *                          purposes).
     1162     * @remarks Caller enters the PDM critical section.
     1163     */
     1164    DECLR3CALLBACKMEMBER(int, pfnGetInterruptR3,(PPDMDEVINS pDevIns, PVMCPU pVCpu, uint8_t *pu8Vector, uint32_t *pu32TagSrc));
    11771165
    11781166    /**
     
    12131201     * @param   pDevIns         Device instance of the APIC.
    12141202     * @param   pVCpu           The cross context virtual CPU structure.
     1203     * @param   pfPending       Where to store if there is an interrupt pending
     1204     *                          (optional, can be NULL).
     1205     * @param   pu8PendingIntr  Where to store the pending interrupt vector
     1206     *                          (optional, can be NULL).
    12151207     * @remarks Caller enters the PDM critical section.
    12161208     */
    1217     DECLR3CALLBACKMEMBER(uint8_t, pfnGetTprR3,(PPDMDEVINS pDevIns, PVMCPU pVCpu));
     1209    DECLR3CALLBACKMEMBER(uint8_t, pfnGetTprR3,(PPDMDEVINS pDevIns, PVMCPU pVCpu, bool *pfPending, uint8_t *pu8PendingIntr));
    12181210
    12191211    /**
     
    12961288    /** The name of the RC GetInterrupt entry point. */
    12971289    const char         *pszGetInterruptRC;
    1298     /** The name of the RC HasPendingIrq entry point. */
    1299     const char         *pszHasPendingIrqRC;
    13001290    /** The name of the RC SetBaseMsr entry point. */
    13011291    const char         *pszSetBaseMsrRC;
     
    13191309    /** The name of the R0 GetInterrupt entry point. */
    13201310    const char         *pszGetInterruptR0;
    1321     /** The name of the R0 HasPendingIrq entry point. */
    1322     const char         *pszHasPendingIrqR0;
    13231311    /** The name of the R0 SetBaseMsr entry point. */
    13241312    const char         *pszSetBaseMsrR0;
     
    13441332
    13451333/** Current PDMAPICREG version number. */
    1346 #define PDM_APICREG_VERSION                     PDM_VERSION_MAKE(0xfff6, 3, 0)
     1334#define PDM_APICREG_VERSION                     PDM_VERSION_MAKE(0xfff6, 4, 0)
    13471335
    13481336
  • TabularUnified trunk/src/VBox/Devices/PC/DevAPIC.cpp

    r60695 r60716  
    520520    }
    521521}
     522
     523
     524static int apic_get_ppr_zero_tpr(APICState *pApic)
     525{
     526    return Apic256BitReg_FindLastSetBit(&pApic->isr, 0);
     527}
     528
     529
     530/* Check if the APIC has a pending interrupt/if a TPR change would active one. */
     531static bool apicHasPendingIntr(PPDMDEVINS pDevIns, PVMCPU pVCpu, uint8_t *pu8PendingIrq)
     532{
     533    APICDeviceInfo *pDev = PDMINS_2_DATA(pDevIns, APICDeviceInfo *);
     534    if (!pDev)
     535        return false;
     536
     537    /* We don't perform any locking here as that would cause a lot of contention for VT-x/AMD-V. */
     538
     539    APICState *pApic = apicGetStateById(pDev, pVCpu->idCpu);
     540
     541    /*
     542     * All our callbacks now come from single IOAPIC, thus locking
     543     * seems to be excessive now
     544     */
     545    /** @todo check excessive locking whatever... */
     546    int irrv = Apic256BitReg_FindLastSetBit(&pApic->irr, -1);
     547    if (irrv < 0)
     548        return false;
     549
     550    int isrv = apic_get_ppr_zero_tpr(pApic);
     551
     552    if (isrv && (irrv & 0xf0) <= (isrv & 0xf0))
     553        return false;
     554
     555    if (pu8PendingIrq)
     556    {
     557        Assert(irrv >= 0 && irrv <= (int)UINT8_MAX);
     558        *pu8PendingIrq = (uint8_t)irrv;
     559    }
     560    return true;
     561}
     562
    522563
    523564static int apic_bus_deliver(APICDeviceInfo *pDev,
     
    653694}
    654695
    655 PDMBOTHCBDECL(uint8_t) apicGetTPR(PPDMDEVINS pDevIns, PVMCPU pVCpu)
     696PDMBOTHCBDECL(uint8_t) apicGetTPR(PPDMDEVINS pDevIns, PVMCPU pVCpu, bool *pfPending, uint8_t *pu8PendingIntr)
    656697{
    657698    /* We don't perform any locking here as that would cause a lot of contention for VT-x/AMD-V. */
     
    659700    APICState *pApic = apicGetStateById(pDev, pVCpu->idCpu);
    660701    Log2(("apicGetTPR: returns %#x\n", pApic->tpr));
     702
     703    if (pfPending)
     704        *pfPending = apicHasPendingIntr(pDevIns, pVCpu, pu8PendingIntr);
    661705    return pApic->tpr;
    662706}
     
    12031247}
    12041248
    1205 static int apic_get_ppr_zero_tpr(APICState *pApic)
    1206 {
    1207     return Apic256BitReg_FindLastSetBit(&pApic->isr, 0);
    1208 }
    1209 
    12101249static int apic_get_arb_pri(APICState const *pApic)
    12111250{
     
    12311270        return false;
    12321271    apicCpuSetInterrupt(pDev, pApic);
    1233     return true;
    1234 }
    1235 
    1236 /* Check if the APIC has a pending interrupt/if a TPR change would active one. */
    1237 PDMBOTHCBDECL(bool) apicHasPendingIrq(PPDMDEVINS pDevIns, PVMCPU pVCpu, uint8_t *pu8PendingIrq)
    1238 {
    1239     APICDeviceInfo *pDev = PDMINS_2_DATA(pDevIns, APICDeviceInfo *);
    1240     if (!pDev)
    1241         return false;
    1242 
    1243     /* We don't perform any locking here as that would cause a lot of contention for VT-x/AMD-V. */
    1244 
    1245     APICState *pApic = apicGetStateById(pDev, pVCpu->idCpu);
    1246 
    1247     /*
    1248      * All our callbacks now come from single IOAPIC, thus locking
    1249      * seems to be excessive now
    1250      */
    1251     /** @todo check excessive locking whatever... */
    1252     int irrv = Apic256BitReg_FindLastSetBit(&pApic->irr, -1);
    1253     if (irrv < 0)
    1254         return false;
    1255 
    1256     int ppr = apic_get_ppr_zero_tpr(pApic);
    1257 
    1258     if (ppr && (irrv & 0xf0) <= (ppr & 0xf0))
    1259         return false;
    1260 
    1261     if (pu8PendingIrq)
    1262     {
    1263         Assert(irrv >= 0 && irrv <= (int)UINT8_MAX);
    1264         *pu8PendingIrq = (uint8_t)irrv;
    1265     }
    12661272    return true;
    12671273}
     
    14501456
    14511457
    1452 PDMBOTHCBDECL(int) apicGetInterrupt(PPDMDEVINS pDevIns, PVMCPU pVCpu, uint32_t *puTagSrc)
     1458PDMBOTHCBDECL(int) apicGetInterrupt(PPDMDEVINS pDevIns, PVMCPU pVCpu, uint8_t *pu8Vector, uint32_t *pu32TagSrc)
    14531459{
    14541460    APICDeviceInfo *pDev = PDMINS_2_DATA(pDevIns, APICDeviceInfo *);
     
    14571463    {
    14581464        Log(("apic_get_interrupt: returns -1 (!pDev)\n"));
    1459         return -1;
     1465        return VERR_APIC_INTR_NOT_PENDING;
    14601466    }
    14611467
     
    14671473    {
    14681474        Log(("CPU%d: apic_get_interrupt: returns -1 (APIC_SV_ENABLE)\n", pApic->phys_id));
    1469         return -1;
     1475        return VERR_APIC_INTR_NOT_PENDING;
    14701476    }
    14711477
     
    14751481    {
    14761482        Log(("CPU%d: apic_get_interrupt: returns -1 (irr)\n", pApic->phys_id));
    1477         return -1;
     1483        return VERR_APIC_INTR_NOT_PENDING;
    14781484    }
    14791485
    14801486    if (pApic->tpr && (uint32_t)intno <= pApic->tpr)
    14811487    {
    1482         *puTagSrc = 0;
    1483         Log(("apic_get_interrupt: returns %d (sp)\n", pApic->spurious_vec & 0xff));
    1484         return pApic->spurious_vec & 0xff;
     1488        *pu32TagSrc = 0;
     1489        *pu8Vector = pApic->spurious_vec & 0xff;
     1490        Log(("apic_get_interrupt: returns %d (sp)\n", *pu8Vector));
     1491        return VINF_SUCCESS;
    14851492    }
    14861493
     
    14881495    Apic256BitReg_SetBit(&pApic->isr, intno);
    14891496
    1490     *puTagSrc = pApic->auTags[intno];
     1497    *pu32TagSrc = pApic->auTags[intno];
    14911498    pApic->auTags[intno] = 0;
    14921499
    14931500    apic_update_irq(pDev, pApic);
    14941501
    1495     LogFlow(("CPU%d: apic_get_interrupt: returns %d / %#x\n", pApic->phys_id, intno, *puTagSrc));
    1496     return intno;
     1502    LogFlow(("CPU%d: apic_get_interrupt: returns %d / %#x\n", pApic->phys_id, intno, *pu32TagSrc));
     1503    *pu8Vector = (uint8_t)intno;
     1504    return VINF_SUCCESS;
    14971505}
    14981506
     
    24092417    ApicReg.u32Version              = PDM_APICREG_VERSION;
    24102418    ApicReg.pfnGetInterruptR3       = apicGetInterrupt;
    2411     ApicReg.pfnHasPendingIrqR3      = apicHasPendingIrq;
    24122419    ApicReg.pfnSetBaseMsrR3         = apicSetBase;
    24132420    ApicReg.pfnGetBaseMsrR3         = apicGetBase;
     
    24222429    {
    24232430        ApicReg.pszGetInterruptRC   = "apicGetInterrupt";
    2424         ApicReg.pszHasPendingIrqRC  = "apicHasPendingIrq";
    24252431        ApicReg.pszSetBaseMsrRC     = "apicSetBase";
    24262432        ApicReg.pszGetBaseMsrRC     = "apicGetBase";
     
    24342440
    24352441        ApicReg.pszGetInterruptR0   = "apicGetInterrupt";
    2436         ApicReg.pszHasPendingIrqR0  = "apicHasPendingIrq";
    24372442        ApicReg.pszSetBaseMsrR0     = "apicSetBase";
    24382443        ApicReg.pszGetBaseMsrR0     = "apicGetBase";
     
    24482453    {
    24492454        ApicReg.pszGetInterruptRC   = NULL;
    2450         ApicReg.pszHasPendingIrqRC  = NULL;
    24512455        ApicReg.pszSetBaseMsrRC     = NULL;
    24522456        ApicReg.pszGetBaseMsrRC     = NULL;
     
    24602464
    24612465        ApicReg.pszGetInterruptR0   = NULL;
    2462         ApicReg.pszHasPendingIrqR0  = NULL;
    24632466        ApicReg.pszSetBaseMsrR0     = NULL;
    24642467        ApicReg.pszGetBaseMsrR0     = NULL;
  • TabularUnified trunk/src/VBox/VMM/VMMAll/APICAll.cpp

    r60707 r60716  
    429429    }
    430430    return rcNotFound;
    431 }
    432 
    433 
    434 /**
    435  * Gets the highest priority pending interrupt.
    436  *
    437  * @returns true if any interrupt is pending, false otherwise.
    438  * @param   pVCpu               The cross context virtual CPU structure.
    439  * @param   pu8PendingIntr      Where to store the interrupt vector if the
    440  *                              interrupt is pending, optional can be NULL.
    441  */
    442 static bool apicGetHighestPendingInterrupt(PVMCPU pVCpu, uint8_t *pu8PendingIntr)
    443 {
    444     PCXAPICPAGE pXApicPage = VMCPU_TO_CXAPICPAGE(pVCpu);
    445     int const irrv = apicGetLastSetBit(&pXApicPage->irr, -1);
    446     if (irrv >= 0)
    447     {
    448         Assert(irrv <= (int)UINT8_MAX);
    449         if (pu8PendingIntr)
    450             *pu8PendingIntr = (uint8_t)irrv;
    451         return true;
    452     }
    453     return false;
    454431}
    455432
     
    21122089
    21132090/**
     2091 * Gets the highest priority pending interrupt.
     2092 *
     2093 * @returns true if any interrupt is pending, false otherwise.
     2094 * @param   pVCpu               The cross context virtual CPU structure.
     2095 * @param   pu8PendingIntr      Where to store the interrupt vector if the
     2096 *                              interrupt is pending (optional, can be NULL).
     2097 */
     2098static bool apicGetHighestPendingInterrupt(PVMCPU pVCpu, uint8_t *pu8PendingIntr)
     2099{
     2100    PCXAPICPAGE pXApicPage = VMCPU_TO_CXAPICPAGE(pVCpu);
     2101    int const irrv = apicGetLastSetBit(&pXApicPage->irr, -1);
     2102    if (irrv >= 0)
     2103    {
     2104        Assert(irrv <= (int)UINT8_MAX);
     2105        if (pu8PendingIntr)
     2106            *pu8PendingIntr = (uint8_t)irrv;
     2107        return true;
     2108    }
     2109    return false;
     2110}
     2111
     2112
     2113/**
    21142114 * @interface_method_impl{PDMAPICREG,pfnGetTprR3}
    21152115 */
    2116 VMMDECL(uint8_t) APICGetTpr(PPDMDEVINS pDevIns, PVMCPU pVCpu)
     2116VMMDECL(uint8_t) APICGetTpr(PPDMDEVINS pDevIns, PVMCPU pVCpu, bool *pfPending, uint8_t *pu8PendingIntr)
    21172117{
    21182118    VMCPU_ASSERT_EMT(pVCpu);
    21192119    PCXAPICPAGE pXApicPage = VMCPU_TO_CXAPICPAGE(pVCpu);
     2120
     2121    if (pfPending)
     2122    {
     2123        /*
     2124         * Just return whatever the highest pending interrupt is in the IRR.
     2125         * The caller is responsible for figuring out if it's masked by the TPR etc.
     2126         */
     2127        *pfPending = apicGetHighestPendingInterrupt(pVCpu, pu8PendingIntr);
     2128    }
     2129
    21202130    return pXApicPage->tpr.u8Tpr;
    21212131}
     
    22822292
    22832293/**
    2284  * @interface_method_impl{PDMAPICREG,pfnHasPendingIrqR3}
    2285  */
    2286 VMMDECL(bool) APICHasPendingIrq(PPDMDEVINS pDevIns, PVMCPU pVCpu, uint8_t *pu8PendingIrq)
    2287 {
    2288     return apicGetHighestPendingInterrupt(pVCpu, pu8PendingIrq);
    2289 }
    2290 
    2291 
    2292 /**
    22932294 * @interface_method_impl{PDMAPICREG,pfnGetInterruptR3}
    22942295 */
    2295 VMMDECL(int) APICGetInterrupt(PPDMDEVINS pDevIns, PVMCPU pVCpu, uint32_t *puTagSrc)
    2296 {
    2297     VMCPU_ASSERT_EMT(pVCpu);
     2296VMMDECL(int) APICGetInterrupt(PPDMDEVINS pDevIns, PVMCPU pVCpu, uint8_t *pu8Vector, uint32_t *pu32TagSrc)
     2297{
     2298    VMCPU_ASSERT_EMT(pVCpu);
     2299    Assert(pu8Vector);
     2300    NOREF(pu32TagSrc);
    22982301
    22992302    LogFlow(("APIC%u: APICGetInterrupt\n", pVCpu->idCpu));
     
    23062309        APICUpdatePendingInterrupts(pVCpu);
    23072310        int const irrv = apicGetLastSetBit(&pXApicPage->irr, -1);
    2308         if (irrv >= 0)
     2311        if (RT_LIKELY(irrv >= 0))
    23092312        {
    23102313            Assert(irrv <= (int)UINT8_MAX);
     
    23162319             */
    23172320            uint8_t const uTpr = pXApicPage->tpr.u8Tpr;
    2318             if (uTpr > 0 && uVector <= uTpr)
    2319             {
    2320                 Log2(("APIC%u: APICGetInterrupt: Spurious interrupt. uVector=%#x uTpr=%#x SpuriousVector=%#x\n", pVCpu->idCpu,
     2321            if (uTpr > 0 && XAPIC_TPR_GET_TP(uVector) <= XAPIC_TPR_GET_TP(uTpr))
     2322            {
     2323                Log2(("APIC%u: APICGetInterrupt: Interrupt masked. uVector=%#x uTpr=%#x SpuriousVector=%#x\n", pVCpu->idCpu,
    23212324                      uVector, uTpr, pXApicPage->svr.u.u8SpuriousVector));
    2322                 return pXApicPage->svr.u.u8SpuriousVector;
    2323             }
    2324 
     2325                *pu8Vector = uVector;
     2326                return VERR_APIC_INTR_MASKED_BY_TPR;
     2327            }
     2328
     2329            /*
     2330             * The PPR should be up-to-date at this point and we're on EMT (so no parallel updates).
     2331             * Subject the pending vector to PPR prioritization.
     2332             */
    23252333            uint8_t const uPpr = pXApicPage->ppr.u8Ppr;
    23262334            if (   !uPpr
    2327                 ||  XAPIC_PPR_GET_PP(uVector) > XAPIC_PPR_GET_PP(uPpr))
     2335                || XAPIC_PPR_GET_PP(uVector) > XAPIC_PPR_GET_PP(uPpr))
    23282336            {
    23292337                apicClearVectorInReg(&pXApicPage->irr, uVector);
     
    23332341
    23342342                Log2(("APIC%u: APICGetInterrupt: Valid Interrupt. uVector=%#x\n", pVCpu->idCpu, uVector));
    2335                 return uVector;
     2343                *pu8Vector = uVector;
     2344                return VINF_SUCCESS;
    23362345            }
    23372346            else
    2338                 Log2(("APIC%u: APICGetInterrupt: Interrupt's priority is not higher than the PPR uVector=%#x PPR=%#x\n",
     2347                Log2(("APIC%u: APICGetInterrupt: Interrupt's priority is not higher than the PPR. uVector=%#x PPR=%#x\n",
    23392348                      pVCpu->idCpu, uVector, uPpr));
    23402349        }
     
    23452354        Log2(("APIC%u: APICGetInterrupt: APIC %s disabled\n", pVCpu->idCpu, !fApicHwEnabled ? "hardware" : "software"));
    23462355
    2347     return -1;
     2356    return VERR_APIC_INTR_NOT_PENDING;
    23482357}
    23492358
  • TabularUnified trunk/src/VBox/VMM/VMMAll/PDMAll.cpp

    r60573 r60716  
    4040 *
    4141 * @returns VBox status code.
     42 * @retval  VINF_SUCCESS on success.
     43 * @retval  VERR_APIC_INTR_MASKED_BY_TPR when an APIC interrupt is pending but
     44 *          can't be delivered due to TPR priority.
     45 * @retval  VERR_NO_DATA if there is no interrupt to be delivered (either APIC
     46 *          has been software-disabled since it flagged something was pending,
     47 *          or other reasons).
     48 *
    4249 * @param   pVCpu           The cross context virtual CPU structure.
    4350 * @param   pu8Interrupt    Where to store the interrupt on success.
     
    6067        Assert(pVM->pdm.s.Apic.CTX_SUFF(pfnGetInterrupt));
    6168        uint32_t uTagSrc;
    62         int i = pVM->pdm.s.Apic.CTX_SUFF(pfnGetInterrupt)(pVM->pdm.s.Apic.CTX_SUFF(pDevIns), pVCpu, &uTagSrc);
    63 #ifndef VBOX_WITH_NEW_APIC
    64         AssertMsg(i <= 255 && i >= 0, ("i=%d\n", i));
    65 #endif
    66         if (i >= 0)
     69        uint8_t  uVector;
     70        int rc = pVM->pdm.s.Apic.CTX_SUFF(pfnGetInterrupt)(pVM->pdm.s.Apic.CTX_SUFF(pDevIns), pVCpu, &uVector, &uTagSrc);
     71        if (   rc == VINF_SUCCESS
     72            || rc == VERR_APIC_INTR_MASKED_BY_TPR)
    6773        {
    6874#ifndef VBOX_WITH_NEW_APIC
    6975            pdmUnlock(pVM);
    7076#endif
    71             *pu8Interrupt = (uint8_t)i;
    72             VBOXVMM_PDM_IRQ_GET(pVCpu, RT_LOWORD(uTagSrc), RT_HIWORD(uTagSrc), i);
    73             return VINF_SUCCESS;
     77            *pu8Interrupt = uVector;
     78            if (rc == VINF_SUCCESS)
     79                VBOXVMM_PDM_IRQ_GET(pVCpu, RT_LOWORD(uTagSrc), RT_HIWORD(uTagSrc), uVector);
     80            return rc;
    7481        }
    7582    }
     
    99106    }
    100107
    101     /** @todo Figure out exactly why we can get here without anything being set. (REM) */
     108    /*
     109     * One scenario where we may possibly get here is if the APIC signalled a pending interrupt,
     110     * got an APIC MMIO/MSR VM-exit which disabled the APIC. We could, in theory, clear the APIC
     111     * force-flag from all the places which disables the APIC but letting PDMGetInterrupt() fail
     112     * without returning a valid interrupt still needs to be handled for the TPR masked case,
     113     * so we shall just handle it here regardless if we choose to update the APIC code in the future.
     114     */
    102115
    103116    pdmUnlock(pVM);
     
    313326
    314327/**
    315  * Check if the APIC has a pending interrupt/if a TPR change would active one.
    316  *
    317  * @returns VINF_SUCCESS or VERR_PDM_NO_APIC_INSTANCE.
    318  * @param   pVCpu       The cross context virtual CPU structure.
    319  * @param   pfPending   Pending state (out).
    320  */
    321 VMM_INT_DECL(int) PDMApicHasPendingIrq(PVMCPU pVCpu, bool *pfPending)
     328 * Set the TPR (Task Priority Register).
     329 *
     330 * @returns VBox status code.
     331 * @param   pVCpu           The cross context virtual CPU structure.
     332 * @param   u8TPR           The new TPR.
     333 */
     334VMMDECL(int) PDMApicSetTPR(PVMCPU pVCpu, uint8_t u8TPR)
    322335{
    323336    PVM pVM = pVCpu->CTX_SUFF(pVM);
    324337    if (pVM->pdm.s.Apic.CTX_SUFF(pDevIns))
    325338    {
    326         Assert(pVM->pdm.s.Apic.CTX_SUFF(pfnHasPendingIrq));
    327         pdmLock(pVM);
    328         *pfPending = pVM->pdm.s.Apic.CTX_SUFF(pfnHasPendingIrq)(pVM->pdm.s.Apic.CTX_SUFF(pDevIns), pVCpu, NULL /*pu8PendingIrq*/);
    329         pdmUnlock(pVM);
    330         return VINF_SUCCESS;
    331     }
    332     return VERR_PDM_NO_APIC_INSTANCE;
    333 }
    334 
    335 
    336 /**
    337  * Set the TPR (task priority register).
    338  *
    339  * @returns VBox status code.
    340  * @param   pVCpu           The cross context virtual CPU structure.
    341  * @param   u8TPR           The new TPR.
    342  */
    343 VMMDECL(int) PDMApicSetTPR(PVMCPU pVCpu, uint8_t u8TPR)
    344 {
    345     PVM pVM = pVCpu->CTX_SUFF(pVM);
    346     if (pVM->pdm.s.Apic.CTX_SUFF(pDevIns))
    347     {
    348339        Assert(pVM->pdm.s.Apic.CTX_SUFF(pfnSetTpr));
     340#ifdef VBOX_WITH_NEW_APIC
     341        pVM->pdm.s.Apic.CTX_SUFF(pfnSetTpr)(pVM->pdm.s.Apic.CTX_SUFF(pDevIns), pVCpu, u8TPR);
     342#else
    349343        pdmLock(pVM);
    350344        pVM->pdm.s.Apic.CTX_SUFF(pfnSetTpr)(pVM->pdm.s.Apic.CTX_SUFF(pDevIns), pVCpu, u8TPR);
    351345        pdmUnlock(pVM);
     346#endif
    352347        return VINF_SUCCESS;
    353348    }
     
    357352
    358353/**
    359  * Get the TPR (task priority register).
     354 * Get the TPR (Task Priority Register).
    360355 *
    361356 * @returns VINF_SUCCESS or VERR_PDM_NO_APIC_INSTANCE.
    362357 * @param   pVCpu           The cross context virtual CPU structure.
    363358 * @param   pu8TPR          Where to store the TRP.
    364  * @param   pfPending       Pending interrupt state (out, optional).
    365  * @param   pu8PendingIrq   Where to store the highest-priority pending IRQ
     359 * @param   pfPending       Where to store whether there is a pending interrupt
    366360 *                          (out, optional).
     361 * @param   pu8PendingIntr  Where to store the highest-priority pending
     362 *                          interrupt (out, optional).
    367363 *
    368364 * @remarks No-long-jump zone!!!
    369365 */
    370 VMMDECL(int) PDMApicGetTPR(PVMCPU pVCpu, uint8_t *pu8TPR, bool *pfPending, uint8_t *pu8PendingIrq)
     366VMMDECL(int) PDMApicGetTPR(PVMCPU pVCpu, uint8_t *pu8TPR, bool *pfPending, uint8_t *pu8PendingIntr)
    371367{
    372368    PVM        pVM      = pVCpu->CTX_SUFF(pVM);
     
    380376         */
    381377        Assert(pVM->pdm.s.Apic.CTX_SUFF(pfnGetTpr));
    382         *pu8TPR = pVM->pdm.s.Apic.CTX_SUFF(pfnGetTpr)(pApicIns, pVCpu);
    383         if (pfPending)
    384             *pfPending = pVM->pdm.s.Apic.CTX_SUFF(pfnHasPendingIrq)(pApicIns, pVCpu, pu8PendingIrq);
     378        *pu8TPR = pVM->pdm.s.Apic.CTX_SUFF(pfnGetTpr)(pApicIns, pVCpu, pfPending, pu8PendingIntr);
    385379        return VINF_SUCCESS;
    386380    }
  • TabularUnified trunk/src/VBox/VMM/VMMR0/HMSVMR0.cpp

    r60574 r60716  
    26702670            uint8_t u8Interrupt;
    26712671            int rc = PDMGetInterrupt(pVCpu, &u8Interrupt);
    2672             if (RT_SUCCESS(rc))
     2672            if (rc == VINF_SUCCESS)
    26732673            {
    26742674                Log4(("Injecting external interrupt u8Interrupt=%#x\n", u8Interrupt));
     
    26802680                hmR0SvmSetPendingEvent(pVCpu, &Event, 0 /* GCPtrFaultAddress */);
    26812681            }
     2682            else if (rc == VERR_APIC_INTR_MASKED_BY_TPR)
     2683            {
     2684                /*
     2685                 * AMD-V has no TPR thresholding feature. We just avoid posting the interrupt.
     2686                 * We just avoid delivering the TPR-masked interrupt here. TPR will be updated
     2687                 * always via hmR0SvmLoadGuestState() -> hmR0SvmLoadGuestApicState().
     2688                 */
     2689                Assert(!VMCPU_FF_IS_PENDING(pVCpu, (VMCPU_FF_INTERRUPT_APIC)));
     2690            }
    26822691            else
    26832692            {
    2684                 /* This can happen with the new APIC code. */
    2685 #ifndef VBOX_WITH_NEW_APIC
    26862693                Assert(!VMCPU_FF_IS_PENDING(pVCpu, (VMCPU_FF_INTERRUPT_APIC | VMCPU_FF_INTERRUPT_PIC)));
    2687 #endif
    26882694                STAM_COUNTER_INC(&pVCpu->hm.s.StatSwitchGuestIrq);
    26892695            }
  • TabularUnified trunk/src/VBox/VMM/VMMR0/HMVMXR0.cpp

    r60573 r60716  
    33433343
    33443344/**
     3345 * Sets the TPR threshold in the VMCS.
     3346 *
     3347 * @returns VBox status code.
     3348 * @param   pVCpu               The cross context virtual CPU structure.
     3349 * @param   u32TprThreshold     The TPR threshold (task-priority class only).
     3350 */
     3351DECLINLINE(int) hmR0VmxApicSetTprThreshold(PVMCPU pVCpu, uint32_t u32TprThreshold)
     3352{
     3353    Assert(!(u32TprThreshold & 0xfffffff0));         /* Bits 31:4 MBZ. */
     3354    Assert(pVCpu->hm.s.vmx.u32ProcCtls & VMX_VMCS_CTRL_PROC_EXEC_USE_TPR_SHADOW);
     3355    return VMXWriteVmcs32(VMX_VMCS32_CTRL_TPR_THRESHOLD, u32TprThreshold);
     3356}
     3357
     3358
     3359/**
    33453360 * Loads the guest APIC and related state.
    33463361 *
     
    33873402                    u32TprThreshold = u8TprPriority;             /* Required for Vista 64-bit guest, see @bugref{6398}. */
    33883403            }
    3389             Assert(!(u32TprThreshold & 0xfffffff0));             /* Bits 31:4 MBZ. */
    3390 
    3391             rc = VMXWriteVmcs32(VMX_VMCS32_CTRL_TPR_THRESHOLD, u32TprThreshold);
     3404
     3405            rc = hmR0VmxApicSetTprThreshold(pVCpu, u32TprThreshold);
    33923406            AssertRCReturn(rc, rc);
    33933407        }
     
    74347448            uint8_t u8Interrupt;
    74357449            rc = PDMGetInterrupt(pVCpu, &u8Interrupt);
    7436             if (RT_SUCCESS(rc))
     7450            if (rc == VINF_SUCCESS)
    74377451            {
    74387452                Log4(("Pending interrupt vcpu[%RU32] u8Interrupt=%#x \n", pVCpu->idCpu, u8Interrupt));
     
    74427456                hmR0VmxSetPendingEvent(pVCpu, u32IntInfo, 0 /* cbInstr */, 0 /* u32ErrCode */, 0 /* GCPtrfaultAddress */);
    74437457            }
     7458            else if (rc == VERR_APIC_INTR_MASKED_BY_TPR)
     7459            {
     7460                Assert(!VMCPU_FF_IS_PENDING(pVCpu, (VMCPU_FF_INTERRUPT_APIC)));
     7461                if (pVCpu->hm.s.vmx.u32ProcCtls & VMX_VMCS_CTRL_PROC_EXEC_USE_TPR_SHADOW)
     7462                    hmR0VmxApicSetTprThreshold(pVCpu, u8Interrupt >> 4);
     7463            }
    74447464            else
    74457465            {
    7446                 /* This can happen with the new APIC code. */
    7447 #ifndef VBOX_WITH_NEW_APIC
    74487466                Assert(!VMCPU_FF_IS_PENDING(pVCpu, (VMCPU_FF_INTERRUPT_APIC | VMCPU_FF_INTERRUPT_PIC)));
    7449 #endif
    74507467                STAM_COUNTER_INC(&pVCpu->hm.s.StatSwitchGuestIrq);
    74517468            }
  • TabularUnified trunk/src/VBox/VMM/VMMR3/APIC.cpp

    r60695 r60716  
    815815    AssertRCReturn(rc, rc);
    816816    pApicCpu->uApicBaseMsr = uApicBaseLo;
     817    Log2(("APIC%u: apicR3LoadLegacyVCpuData: uApicBaseMsr=%#RX64\n", pVCpu->idCpu, pApicCpu->uApicBaseMsr));
    817818
    818819    switch (uVersion)
    819820    {
    820         case APIC_SAVED_STATE_VERSION_ANCIENT:
    821         {
    822             uint8_t uPhysApicId;
    823             SSMR3GetU8(pSSM, &pXApicPage->id.u8ApicId);
    824             SSMR3GetU8(pSSM, &uPhysApicId);   NOREF(uPhysApicId); /* PhysId == pVCpu->idCpu */
    825             break;
    826         }
    827 
    828821        case APIC_SAVED_STATE_VERSION_VBOX_50:
    829822        case APIC_SAVED_STATE_VERSION_VBOX_30:
     
    833826            SSMR3GetU32(pSSM, &uPhysApicId);  NOREF(uPhysApicId); /* PhysId == pVCpu->idCpu */
    834827            SSMR3GetU32(pSSM, &uArbId);       NOREF(uArbId);      /* ArbID is & was unused. */
     828            break;
     829        }
     830
     831        case APIC_SAVED_STATE_VERSION_ANCIENT:
     832        {
     833            uint8_t uPhysApicId;
     834            SSMR3GetU8(pSSM, &pXApicPage->id.u8ApicId);
     835            SSMR3GetU8(pSSM, &uPhysApicId);   NOREF(uPhysApicId); /* PhysId == pVCpu->idCpu */
    835836            break;
    836837        }
     
    11601161    pApicDev->pCritSectRC = pApicDev->pApicHlpR3->pfnGetRCCritSect(pDevIns);
    11611162
    1162     pApic->pApicDevRC = PDMINS_2_DATA_RCPTR(pDevIns);
    1163     if (pApic->pvApicPibRC != NIL_RTRCPTR)
    1164         pApic->pvApicPibRC = MMHyperR3ToRC(pVM, (RTR3PTR)pApic->pvApicPibR3);
     1163    pApic->pApicDevRC   = PDMINS_2_DATA_RCPTR(pDevIns);
     1164    pApic->pvApicPibRC += offDelta;
    11651165
    11661166    for (VMCPUID idCpu = 0; idCpu < pVM->cCpus; idCpu++)
     
    11701170        pApicCpu->pTimerRC     = TMTimerRCPtr(pApicCpu->pTimerR3);
    11711171
    1172         if (pApicCpu->pvApicPageRC != NIL_RTRCPTR)
    1173             pApicCpu->pvApicPageRC = MMHyperR3ToRC(pVM, (RTR3PTR)pApicCpu->pvApicPageR3);
    1174         if (pApicCpu->pvApicPibRC != NIL_RTRCPTR)
    1175             pApicCpu->pvApicPibRC  = MMHyperR3ToRC(pVM, (RTR3PTR)pApicCpu->pvApicPibR3);
     1172        pApicCpu->pvApicPageRC += offDelta;
     1173        pApicCpu->pvApicPibRC  += offDelta;
     1174        Log2(("APIC%u: apicR3Relocate: APIC PIB at %RGv\n", pVCpu->idCpu, pApicCpu->pvApicPibRC));
    11761175    }
    11771176}
     
    13391338                pApicCpu->pvApicPibR3      = (RTR3PTR)((RTR3UINTPTR)pApic->pvApicPibR3 + offApicPib);
    13401339                if (fNeedsGCMapping)
    1341                     pApicCpu->pvApicPibRC += offApicPib;
     1340                    pApicCpu->pvApicPibRC  = (RTRCPTR)((RTRCUINTPTR)pApic->pvApicPibRC + offApicPib);
    13421341
    13431342                /* Initialize the virtual-APIC state. */
     
    13521351                Assert(pApicCpu->pvApicPageR0 != NIL_RTR0PTR);
    13531352                Assert(!fNeedsGCMapping || pApicCpu->pvApicPageRC != NIL_RTRCPTR);
     1353                Assert(!fNeedsGCMapping || pApic->pvApicPibRC == pVM->aCpus[0].apic.s.pvApicPibRC);
    13541354#endif
    13551355            }
     
    14901490    ApicReg.u32Version              = PDM_APICREG_VERSION;
    14911491    ApicReg.pfnGetInterruptR3       = APICGetInterrupt;
    1492     ApicReg.pfnHasPendingIrqR3      = APICHasPendingIrq;
    14931492    ApicReg.pfnSetBaseMsrR3         = APICSetBaseMsr;
    14941493    ApicReg.pfnGetBaseMsrR3         = APICGetBaseMsr;
     
    15081507    {
    15091508        ApicReg.pszGetInterruptRC   = "APICGetInterrupt";
    1510         ApicReg.pszHasPendingIrqRC  = "APICHasPendingIrq";
    15111509        ApicReg.pszSetBaseMsrRC     = "APICSetBaseMsr";
    15121510        ApicReg.pszGetBaseMsrRC     = "APICGetBaseMsr";
     
    15201518
    15211519        ApicReg.pszGetInterruptR0   = "APICGetInterrupt";
    1522         ApicReg.pszHasPendingIrqR0  = "APICHasPendingIrq";
    15231520        ApicReg.pszSetBaseMsrR0     = "APICSetBaseMsr";
    15241521        ApicReg.pszGetBaseMsrR0     = "APICGetBaseMsr";
  • TabularUnified trunk/src/VBox/VMM/VMMR3/PDM.cpp

    r60404 r60716  
    509509        pVM->pdm.s.Apic.pDevInsRC           += offDelta;
    510510        pVM->pdm.s.Apic.pfnGetInterruptRC   += offDelta;
    511         pVM->pdm.s.Apic.pfnHasPendingIrqRC  += offDelta;
    512511        pVM->pdm.s.Apic.pfnSetBaseMsrRC     += offDelta;
    513512        pVM->pdm.s.Apic.pfnGetBaseMsrRC     += offDelta;
  • TabularUnified trunk/src/VBox/VMM/VMMR3/PDMDevHlp.cpp

    r60407 r60716  
    26442644    }
    26452645    if (    !pApicReg->pfnGetInterruptR3
    2646         ||  !pApicReg->pfnHasPendingIrqR3
    26472646        ||  !pApicReg->pfnSetBaseMsrR3
    26482647        ||  !pApicReg->pfnGetBaseMsrR3
     
    26562655    {
    26572656        Assert(pApicReg->pfnGetInterruptR3);
    2658         Assert(pApicReg->pfnHasPendingIrqR3);
    26592657        Assert(pApicReg->pfnSetBaseMsrR3);
    26602658        Assert(pApicReg->pfnGetBaseMsrR3);
     
    26702668    }
    26712669    if (   (    pApicReg->pszGetInterruptRC
    2672             ||  pApicReg->pszHasPendingIrqRC
    26732670            ||  pApicReg->pszSetBaseMsrRC
    26742671            ||  pApicReg->pszGetBaseMsrRC
     
    26812678            ||  pApicReg->pszGetTimerFreqRC)
    26822679        &&  (   !VALID_PTR(pApicReg->pszGetInterruptRC)
    2683             ||  !VALID_PTR(pApicReg->pszHasPendingIrqRC)
    26842680            ||  !VALID_PTR(pApicReg->pszSetBaseMsrRC)
    26852681            ||  !VALID_PTR(pApicReg->pszGetBaseMsrRC)
     
    26942690    {
    26952691        Assert(VALID_PTR(pApicReg->pszGetInterruptRC));
    2696         Assert(VALID_PTR(pApicReg->pszHasPendingIrqRC));
    26972692        Assert(VALID_PTR(pApicReg->pszSetBaseMsrRC));
    26982693        Assert(VALID_PTR(pApicReg->pszGetBaseMsrRC));
     
    27082703    }
    27092704    if (   (    pApicReg->pszGetInterruptR0
    2710             ||  pApicReg->pszHasPendingIrqR0
    27112705            ||  pApicReg->pszSetBaseMsrR0
    27122706            ||  pApicReg->pszGetBaseMsrR0
     
    27192713            ||  pApicReg->pszGetTimerFreqR0)
    27202714        &&  (   !VALID_PTR(pApicReg->pszGetInterruptR0)
    2721             ||  !VALID_PTR(pApicReg->pszHasPendingIrqR0)
    27222715            ||  !VALID_PTR(pApicReg->pszSetBaseMsrR0)
    27232716            ||  !VALID_PTR(pApicReg->pszGetBaseMsrR0)
     
    27322725    {
    27332726        Assert(VALID_PTR(pApicReg->pszGetInterruptR0));
    2734         Assert(VALID_PTR(pApicReg->pszHasPendingIrqR0));
    27352727        Assert(VALID_PTR(pApicReg->pszSetBaseMsrR0));
    27362728        Assert(VALID_PTR(pApicReg->pszGetBaseMsrR0));
     
    27732765        if (RT_SUCCESS(rc))
    27742766        {
    2775             rc = pdmR3DevGetSymbolRCLazy(pDevIns, pApicReg->pszHasPendingIrqRC, &pVM->pdm.s.Apic.pfnHasPendingIrqRC);
    2776             AssertMsgRC(rc, ("%s::%s rc=%Rrc\n", pDevIns->pReg->szRCMod, pApicReg->pszHasPendingIrqRC, rc));
    2777         }
    2778         if (RT_SUCCESS(rc))
    2779         {
    27802767            rc = pdmR3DevGetSymbolRCLazy(pDevIns, pApicReg->pszSetBaseMsrRC, &pVM->pdm.s.Apic.pfnSetBaseMsrRC);
    27812768            AssertMsgRC(rc, ("%s::%s rc=%Rrc\n", pDevIns->pReg->szRCMod, pApicReg->pszSetBaseMsrRC, rc));
     
    28322819        pVM->pdm.s.Apic.pDevInsRC           = 0;
    28332820        pVM->pdm.s.Apic.pfnGetInterruptRC   = 0;
    2834         pVM->pdm.s.Apic.pfnHasPendingIrqRC  = 0;
    28352821        pVM->pdm.s.Apic.pfnSetBaseMsrRC     = 0;
    28362822        pVM->pdm.s.Apic.pfnGetBaseMsrRC     = 0;
     
    28532839        if (RT_SUCCESS(rc))
    28542840        {
    2855             rc = pdmR3DevGetSymbolR0Lazy(pDevIns, pApicReg->pszHasPendingIrqR0, &pVM->pdm.s.Apic.pfnHasPendingIrqR0);
    2856             AssertMsgRC(rc, ("%s::%s rc=%Rrc\n", pDevIns->pReg->szR0Mod, pApicReg->pszHasPendingIrqR0, rc));
    2857         }
    2858         if (RT_SUCCESS(rc))
    2859         {
    28602841            rc = pdmR3DevGetSymbolR0Lazy(pDevIns, pApicReg->pszSetBaseMsrR0, &pVM->pdm.s.Apic.pfnSetBaseMsrR0);
    28612842            AssertMsgRC(rc, ("%s::%s rc=%Rrc\n", pDevIns->pReg->szR0Mod, pApicReg->pszSetBaseMsrR0, rc));
     
    29122893    {
    29132894        pVM->pdm.s.Apic.pfnGetInterruptR0   = 0;
    2914         pVM->pdm.s.Apic.pfnHasPendingIrqR0  = 0;
    29152895        pVM->pdm.s.Apic.pfnSetBaseMsrR0     = 0;
    29162896        pVM->pdm.s.Apic.pfnGetBaseMsrR0     = 0;
     
    29302910    pVM->pdm.s.Apic.pDevInsR3           = pDevIns;
    29312911    pVM->pdm.s.Apic.pfnGetInterruptR3   = pApicReg->pfnGetInterruptR3;
    2932     pVM->pdm.s.Apic.pfnHasPendingIrqR3  = pApicReg->pfnHasPendingIrqR3;
    29332912    pVM->pdm.s.Apic.pfnSetBaseMsrR3     = pApicReg->pfnSetBaseMsrR3;
    29342913    pVM->pdm.s.Apic.pfnGetBaseMsrR3     = pApicReg->pfnGetBaseMsrR3;
  • TabularUnified trunk/src/VBox/VMM/VMMR3/TRPM.cpp

    r60573 r60716  
    15091509# endif
    15101510
    1511         uint8_t u8Interrupt;
     1511        uint8_t u8Interrupt = 0;
    15121512        int rc = PDMGetInterrupt(pVCpu, &u8Interrupt);
    15131513        Log(("TRPMR3InjectEvent: CPU%d u8Interrupt=%d (%#x) rc=%Rrc\n", pVCpu->idCpu, u8Interrupt, u8Interrupt, rc));
     
    15551555        else
    15561556        {
    1557 #ifndef VBOX_WITH_NEW_APIC
    1558             AssertRC(rc);
    1559 #endif
     1557            /* Can happen if the interrupt is masked by TPR or APIC is disabled. */
     1558            AssertMsg(rc == VERR_APIC_INTR_MASKED_BY_TPR || rc == VERR_NO_DATA, ("PDMGetInterrupt failed. rc=%Rrc\n", rc));
    15601559            return HMR3IsActive(pVCpu) ? VINF_EM_RESCHEDULE_HM : VINF_EM_RESCHEDULE_REM; /* (Heed the halted state if this is changed!) */
    15611560        }
    15621561#else /* !TRPM_FORWARD_TRAPS_IN_GC */
    1563         uint8_t u8Interrupt;
     1562        uint8_t u8Interrupt = 0;
    15641563        int rc = PDMGetInterrupt(pVCpu, &u8Interrupt);
    15651564        Log(("TRPMR3InjectEvent: u8Interrupt=%d (%#x) rc=%Rrc\n", u8Interrupt, u8Interrupt, rc));
     
    15691568            AssertRC(rc);
    15701569            STAM_COUNTER_INC(&pVM->trpm.s.paStatForwardedIRQR3[u8Interrupt]);
    1571             return HMR3IsActive(pVCpu) ? VINF_EM_RESCHEDULE_HM : VINF_EM_RESCHEDULE_REM;
    1572         }
     1570        }
     1571        else
     1572        {
     1573            /* Can happen if the interrupt is masked by TPR or APIC is disabled. */
     1574            AssertMsg(rc == VERR_APIC_INTR_MASKED_BY_TPR || rc == VERR_NO_DATA, ("PDMGetInterrupt failed. rc=%Rrc\n", rc));
     1575        }
     1576        return HMR3IsActive(pVCpu) ? VINF_EM_RESCHEDULE_HM : VINF_EM_RESCHEDULE_REM; /* (Heed the halted state if this is changed!) */
    15731577#endif /* !TRPM_FORWARD_TRAPS_IN_GC */
    15741578    }
  • TabularUnified trunk/src/VBox/VMM/VMMRC/TRPMRCHandlers.cpp

    r58123 r60716  
    249249        else if (VMCPU_FF_IS_PENDING(pVCpu, VMCPU_FF_TRPM_SYNC_IDT))
    250250            rc = VINF_EM_RAW_TO_R3;
    251         /* Pending interrupt: dispatch it. */
     251        /* Possibly pending interrupt: dispatch it. */
    252252        else if (    VMCPU_FF_IS_PENDING(pVCpu, VMCPU_FF_INTERRUPT_APIC | VMCPU_FF_INTERRUPT_PIC)
    253253                 && !VMCPU_FF_IS_SET(pVCpu, VMCPU_FF_INHIBIT_INTERRUPTS)
     
    258258            rc = PDMGetInterrupt(pVCpu, &u8Interrupt);
    259259            Log(("trpmGCExitTrap: u8Interrupt=%d (%#x) rc=%Rrc\n", u8Interrupt, u8Interrupt, rc));
    260             AssertFatalMsgRC(rc, ("PDMGetInterrupt failed with %Rrc\n", rc));
    261             rc = TRPMForwardTrap(pVCpu, pRegFrame, (uint32_t)u8Interrupt, 0, TRPM_TRAP_NO_ERRORCODE, TRPM_HARDWARE_INT, uOldActiveVector);
    262             /* can't return if successful */
    263             Assert(rc != VINF_SUCCESS);
    264 
    265             /* Stop the profile counter that was started in TRPMGCHandlersA.asm */
    266             Assert(uOldActiveVector <= 16);
    267             STAM_PROFILE_ADV_STOP(&pVM->trpm.s.aStatGCTraps[uOldActiveVector], a);
    268 
    269             /* Assert the trap and go to the recompiler to dispatch it. */
    270             TRPMAssertTrap(pVCpu, u8Interrupt, TRPM_HARDWARE_INT);
    271 
    272             STAM_PROFILE_ADV_START(&pVM->trpm.s.aStatGCTraps[uOldActiveVector], a);
    273             rc = VINF_EM_RAW_INTERRUPT_PENDING;
     260            if (RT_SUCCESS(rc))
     261            {
     262                rc = TRPMForwardTrap(pVCpu, pRegFrame, (uint32_t)u8Interrupt, 0, TRPM_TRAP_NO_ERRORCODE, TRPM_HARDWARE_INT, uOldActiveVector);
     263                /* can't return if successful */
     264                Assert(rc != VINF_SUCCESS);
     265
     266                /* Stop the profile counter that was started in TRPMRCHandlersA.asm */
     267                Assert(uOldActiveVector <= 16);
     268                STAM_PROFILE_ADV_STOP(&pVM->trpm.s.aStatGCTraps[uOldActiveVector], a);
     269
     270                /* Assert the trap and go to the recompiler to dispatch it. */
     271                TRPMAssertTrap(pVCpu, u8Interrupt, TRPM_HARDWARE_INT);
     272
     273                STAM_PROFILE_ADV_START(&pVM->trpm.s.aStatGCTraps[uOldActiveVector], a);
     274                rc = VINF_EM_RAW_INTERRUPT_PENDING;
     275            }
     276            else if (   rc == VERR_APIC_INTR_MASKED_BY_TPR  /* Can happen if TPR is too high for the newly arrived interrupt. */
     277                     || rc == VERR_NO_DATA)                 /* Can happen if the APIC is disabled. */
     278            {
     279                STAM_PROFILE_ADV_STOP(&pVM->trpm.s.aStatGCTraps[uOldActiveVector], a);
     280                rc = VINF_SUCCESS;
     281            }
     282            else
     283                AssertFatalMsgRC(rc, ("PDMGetInterrupt failed. rc=%Rrc\n", rc));
    274284        }
    275285        /*
  • TabularUnified trunk/src/VBox/VMM/include/APICInternal.h

    r60695 r60716  
    633633VMMDECL(uint64_t)       APICGetBaseMsr(PPDMDEVINS pDevIns, PVMCPU pVCpu);
    634634VMMDECL(VBOXSTRICTRC)   APICSetBaseMsr(PPDMDEVINS pDevIns, PVMCPU pVCpu, uint64_t uBase);
    635 VMMDECL(uint8_t)        APICGetTpr(PPDMDEVINS pDevIns, PVMCPU pVCpu);
     635VMMDECL(uint8_t)        APICGetTpr(PPDMDEVINS pDevIns, PVMCPU pVCpu, bool *pfPending, uint8_t *pu8PendingIntr);
    636636VMMDECL(void)           APICSetTpr(PPDMDEVINS pDevIns, PVMCPU pVCpu, uint8_t u8Tpr);
    637637VMMDECL(uint64_t)       APICGetTimerFreq(PPDMDEVINS pDevIns);
     
    640640VMMDECL(VBOXSTRICTRC)   APICReadMsr(PPDMDEVINS pDevIns,  PVMCPU pVCpu, uint32_t u32Reg, uint64_t *pu64Val);
    641641VMMDECL(VBOXSTRICTRC)   APICWriteMsr(PPDMDEVINS pDevIns, PVMCPU pVCpu, uint32_t u32Reg, uint64_t u64Val);
    642 VMMDECL(bool)           APICHasPendingIrq(PPDMDEVINS pDevIns, PVMCPU pVCpu, uint8_t *pu8PendingIrq);
    643 VMMDECL(int)            APICGetInterrupt(PPDMDEVINS pDevIns,  PVMCPU pVCpu, uint32_t *puTagSrc);
     642VMMDECL(int)            APICGetInterrupt(PPDMDEVINS pDevIns,  PVMCPU pVCpu, uint8_t *puVector, uint32_t *puTagSrc);
    644643VMMDECL(void)           APICSetInterruptFF(PVMCPU pVCpu, PDMAPICIRQ enmType);
    645644VMMDECL(void)           APICClearInterruptFF(PVMCPU pVCpu, PDMAPICIRQ enmType);
  • TabularUnified trunk/src/VBox/VMM/include/PDMInternal.h

    r60404 r60716  
    563563{
    564564    /** Pointer to the APIC device instance - R3 Ptr. */
    565     PPDMDEVINSR3                    pDevInsR3;
     565    PPDMDEVINSR3                       pDevInsR3;
    566566    /** @copydoc PDMAPICREG::pfnGetInterruptR3 */
    567     DECLR3CALLBACKMEMBER(int,       pfnGetInterruptR3,(PPDMDEVINS pDevIns, PVMCPU pVCpu, uint32_t *puTagSrc));
    568     /** @copydoc PDMAPICREG::pfnHasPendingIrqR3 */
    569     DECLR3CALLBACKMEMBER(bool,      pfnHasPendingIrqR3,(PPDMDEVINS pDevIns, PVMCPU pVCpu, uint8_t *pu8PendingIrq));
     567    DECLR3CALLBACKMEMBER(int,          pfnGetInterruptR3,(PPDMDEVINS pDevIns, PVMCPU pVCpu, uint8_t *pu8Vector,
     568                                                          uint32_t *pu32TagSrc));
    570569    /** @copydoc PDMAPICREG::pfnSetBaseMsrR3 */
    571570    DECLR3CALLBACKMEMBER(VBOXSTRICTRC, pfnSetBaseMsrR3,(PPDMDEVINS pDevIns, PVMCPU pVCpu, uint64_t u64Base));
    572571    /** @copydoc PDMAPICREG::pfnGetBaseMsrR3 */
    573     DECLR3CALLBACKMEMBER(uint64_t,  pfnGetBaseMsrR3,(PPDMDEVINS pDevIns, PVMCPU pVCpu));
     572    DECLR3CALLBACKMEMBER(uint64_t,     pfnGetBaseMsrR3,(PPDMDEVINS pDevIns, PVMCPU pVCpu));
    574573    /** @copydoc PDMAPICREG::pfnSetTprR3 */
    575     DECLR3CALLBACKMEMBER(void,      pfnSetTprR3,(PPDMDEVINS pDevIns, PVMCPU pVCpu, uint8_t u8Tpr));
     574    DECLR3CALLBACKMEMBER(void,         pfnSetTprR3,(PPDMDEVINS pDevIns, PVMCPU pVCpu, uint8_t u8Tpr));
    576575    /** @copydoc PDMAPICREG::pfnGetTprR3 */
    577     DECLR3CALLBACKMEMBER(uint8_t,   pfnGetTprR3,(PPDMDEVINS pDevIns, PVMCPU pVCpu));
     576    DECLR3CALLBACKMEMBER(uint8_t,      pfnGetTprR3,(PPDMDEVINS pDevIns, PVMCPU pVCpu, bool *pfPending, uint8_t *pu8PendingIntr));
    578577    /** @copydoc PDMAPICREG::pfnWriteMsrR3 */
    579     DECLR3CALLBACKMEMBER(VBOXSTRICTRC, pfnWriteMsrR3, (PPDMDEVINS pDevIns, PVMCPU pVCpu, uint32_t u32Reg, uint64_t u64Value));
     578    DECLR3CALLBACKMEMBER(VBOXSTRICTRC, pfnWriteMsrR3,(PPDMDEVINS pDevIns, PVMCPU pVCpu, uint32_t u32Reg, uint64_t u64Value));
    580579    /** @copydoc PDMAPICREG::pfnReadMsrR3 */
    581     DECLR3CALLBACKMEMBER(VBOXSTRICTRC, pfnReadMsrR3, (PPDMDEVINS pDevIns, PVMCPU pVCpu, uint32_t u32Reg, uint64_t *pu64Value));
     580    DECLR3CALLBACKMEMBER(VBOXSTRICTRC, pfnReadMsrR3,(PPDMDEVINS pDevIns, PVMCPU pVCpu, uint32_t u32Reg, uint64_t *pu64Value));
    582581    /** @copydoc PDMAPICREG::pfnBusDeliverR3 */
    583     DECLR3CALLBACKMEMBER(int,       pfnBusDeliverR3,(PPDMDEVINS pDevIns, uint8_t uDest, uint8_t uDestMode, uint8_t uDeliveryMode,
    584                                                      uint8_t uVector, uint8_t uPolarity, uint8_t uTriggerMode, uint32_t uTagSrc));
     582    DECLR3CALLBACKMEMBER(int,          pfnBusDeliverR3,(PPDMDEVINS pDevIns, uint8_t uDest, uint8_t uDestMode,
     583                                                        uint8_t uDeliveryMode, uint8_t uVector, uint8_t uPolarity,
     584                                                        uint8_t uTriggerMode, uint32_t uTagSrc));
    585585    /** @copydoc PDMAPICREG::pfnLocalInterruptR3 */
    586586    DECLR3CALLBACKMEMBER(VBOXSTRICTRC, pfnLocalInterruptR3,(PPDMDEVINS pDevIns, PVMCPU pVCpu, uint8_t u8Pin, uint8_t u8Level,
    587587                                                            int rcRZ));
    588588    /** @copydoc PDMAPICREG::pfnGetTimerFreqR3 */
    589     DECLR3CALLBACKMEMBER(uint64_t,  pfnGetTimerFreqR3,(PPDMDEVINS pDevIns));
     589    DECLR3CALLBACKMEMBER(uint64_t,     pfnGetTimerFreqR3,(PPDMDEVINS pDevIns));
    590590
    591591    /** Pointer to the APIC device instance - R0 Ptr. */
    592     PPDMDEVINSR0                    pDevInsR0;
     592    PPDMDEVINSR0                       pDevInsR0;
    593593    /** @copydoc PDMAPICREG::pfnGetInterruptR3 */
    594     DECLR0CALLBACKMEMBER(int,       pfnGetInterruptR0,(PPDMDEVINS pDevIns, PVMCPU pVCpu, uint32_t *puTagSrc));
    595     /** @copydoc PDMAPICREG::pfnHasPendingIrqR3 */
    596     DECLR0CALLBACKMEMBER(bool,      pfnHasPendingIrqR0,(PPDMDEVINS pDevIns, PVMCPU pVCpu, uint8_t *pu8PendingIrq));
     594    DECLR0CALLBACKMEMBER(int,          pfnGetInterruptR0,(PPDMDEVINS pDevIns, PVMCPU pVCpu, uint8_t *pu8Vector,
     595                                                          uint32_t *pu32TagSrc));
    597596    /** @copydoc PDMAPICREG::pfnSetBaseMsrR3 */
    598597    DECLR0CALLBACKMEMBER(VBOXSTRICTRC, pfnSetBaseMsrR0,(PPDMDEVINS pDevIns, PVMCPU pVCpu, uint64_t u64Base));
    599598    /** @copydoc PDMAPICREG::pfnGetBaseMsrR3 */
    600     DECLR0CALLBACKMEMBER(uint64_t,  pfnGetBaseMsrR0,(PPDMDEVINS pDevIns, PVMCPU pVCpu));
     599    DECLR0CALLBACKMEMBER(uint64_t,     pfnGetBaseMsrR0,(PPDMDEVINS pDevIns, PVMCPU pVCpu));
    601600    /** @copydoc PDMAPICREG::pfnSetTprR3 */
    602     DECLR0CALLBACKMEMBER(void,      pfnSetTprR0,(PPDMDEVINS pDevIns, PVMCPU pVCpu, uint8_t u8Tpr));
     601    DECLR0CALLBACKMEMBER(void,         pfnSetTprR0,(PPDMDEVINS pDevIns, PVMCPU pVCpu, uint8_t u8Tpr));
    603602    /** @copydoc PDMAPICREG::pfnGetTprR3 */
    604     DECLR0CALLBACKMEMBER(uint8_t,   pfnGetTprR0,(PPDMDEVINS pDevIns, PVMCPU pVCpu));
     603    DECLR0CALLBACKMEMBER(uint8_t,      pfnGetTprR0,(PPDMDEVINS pDevIns, PVMCPU pVCpu, bool *pfPending, uint8_t *pu8PendingIntr));
    605604     /** @copydoc PDMAPICREG::pfnWriteMsrR3 */
    606     DECLR0CALLBACKMEMBER(VBOXSTRICTRC, pfnWriteMsrR0, (PPDMDEVINS pDevIns, PVMCPU pVCpu, uint32_t u32Reg, uint64_t u64Value));
     605    DECLR0CALLBACKMEMBER(VBOXSTRICTRC, pfnWriteMsrR0,(PPDMDEVINS pDevIns, PVMCPU pVCpu, uint32_t u32Reg, uint64_t u64Value));
    607606    /** @copydoc PDMAPICREG::pfnReadMsrR3 */
    608     DECLR0CALLBACKMEMBER(VBOXSTRICTRC, pfnReadMsrR0, (PPDMDEVINS pDevIns, PVMCPU pVCpu, uint32_t u32Reg, uint64_t *pu64Value));
     607    DECLR0CALLBACKMEMBER(VBOXSTRICTRC, pfnReadMsrR0,(PPDMDEVINS pDevIns, PVMCPU pVCpu, uint32_t u32Reg, uint64_t *pu64Value));
    609608    /** @copydoc PDMAPICREG::pfnBusDeliverR3 */
    610     DECLR0CALLBACKMEMBER(int,       pfnBusDeliverR0,(PPDMDEVINS pDevIns, uint8_t u8Dest, uint8_t u8DestMode, uint8_t u8DeliveryMode,
    611                                                      uint8_t iVector, uint8_t u8Polarity, uint8_t u8TriggerMode, uint32_t uTagSrc));
     609    DECLR0CALLBACKMEMBER(int,          pfnBusDeliverR0,(PPDMDEVINS pDevIns, uint8_t u8Dest, uint8_t u8DestMode,
     610                                                        uint8_t u8DeliveryMode, uint8_t iVector, uint8_t u8Polarity,
     611                                                        uint8_t u8TriggerMode, uint32_t uTagSrc));
    612612    /** @copydoc PDMAPICREG::pfnLocalInterruptR3 */
    613613    DECLR0CALLBACKMEMBER(VBOXSTRICTRC, pfnLocalInterruptR0,(PPDMDEVINS pDevIns, PVMCPU pVCpu, uint8_t u8Pin, uint8_t u8Level,
    614614                                                            int rcRZ));
    615615    /** @copydoc PDMAPICREG::pfnGetTimerFreqR3 */
    616     DECLR0CALLBACKMEMBER(uint64_t,  pfnGetTimerFreqR0,(PPDMDEVINS pDevIns));
     616    DECLR0CALLBACKMEMBER(uint64_t,     pfnGetTimerFreqR0,(PPDMDEVINS pDevIns));
    617617
    618618    /** Pointer to the APIC device instance - RC Ptr. */
    619     PPDMDEVINSRC                    pDevInsRC;
     619    PPDMDEVINSRC                       pDevInsRC;
    620620    /** @copydoc PDMAPICREG::pfnGetInterruptR3 */
    621     DECLRCCALLBACKMEMBER(int,       pfnGetInterruptRC,(PPDMDEVINS pDevIns, PVMCPU pVCpu, uint32_t *puTagSrc));
    622     /** @copydoc PDMAPICREG::pfnHasPendingIrqR3 */
    623     DECLRCCALLBACKMEMBER(bool,      pfnHasPendingIrqRC,(PPDMDEVINS pDevIns, PVMCPU pVCpu, uint8_t *pu8PendingIrq));
     621    DECLRCCALLBACKMEMBER(int,          pfnGetInterruptRC,(PPDMDEVINS pDevIns, PVMCPU pVCpu, uint8_t *pu8Vector,
     622                                                          uint32_t *pu32TagSrc));
    624623    /** @copydoc PDMAPICREG::pfnSetBaseMsrR3 */
    625624    DECLRCCALLBACKMEMBER(VBOXSTRICTRC, pfnSetBaseMsrRC,(PPDMDEVINS pDevIns, PVMCPU pVCpu, uint64_t u64Base));
    626625    /** @copydoc PDMAPICREG::pfnGetBaseMsrR3 */
    627     DECLRCCALLBACKMEMBER(uint64_t,  pfnGetBaseMsrRC,(PPDMDEVINS pDevIns, PVMCPU pVCpu));
     626    DECLRCCALLBACKMEMBER(uint64_t,     pfnGetBaseMsrRC,(PPDMDEVINS pDevIns, PVMCPU pVCpu));
    628627    /** @copydoc PDMAPICREG::pfnSetTprR3 */
    629     DECLRCCALLBACKMEMBER(void,      pfnSetTprRC,(PPDMDEVINS pDevIns, PVMCPU pVCpu, uint8_t u8Tpr));
     628    DECLRCCALLBACKMEMBER(void,         pfnSetTprRC,(PPDMDEVINS pDevIns, PVMCPU pVCpu, uint8_t u8Tpr));
    630629    /** @copydoc PDMAPICREG::pfnGetTprR3 */
    631     DECLRCCALLBACKMEMBER(uint8_t,   pfnGetTprRC,(PPDMDEVINS pDevIns, PVMCPU pVCpu));
     630    DECLRCCALLBACKMEMBER(uint8_t,      pfnGetTprRC,(PPDMDEVINS pDevIns, PVMCPU pVCpu, bool *pfPending, uint8_t *pu8PendingIntr));
    632631    /** @copydoc PDMAPICREG::pfnWriteMsrR3 */
    633     DECLRCCALLBACKMEMBER(VBOXSTRICTRC, pfnWriteMsrRC, (PPDMDEVINS pDevIns, PVMCPU pVCpu, uint32_t u32Reg, uint64_t u64Value));
     632    DECLRCCALLBACKMEMBER(VBOXSTRICTRC, pfnWriteMsrRC,(PPDMDEVINS pDevIns, PVMCPU pVCpu, uint32_t u32Reg, uint64_t u64Value));
    634633    /** @copydoc PDMAPICREG::pfnReadMsrR3 */
    635     DECLRCCALLBACKMEMBER(VBOXSTRICTRC, pfnReadMsrRC, (PPDMDEVINS pDevIns, PVMCPU pVCpu, uint32_t u32Reg, uint64_t *pu64Value));
     634    DECLRCCALLBACKMEMBER(VBOXSTRICTRC, pfnReadMsrRC,(PPDMDEVINS pDevIns, PVMCPU pVCpu, uint32_t u32Reg, uint64_t *pu64Value));
    636635    /** @copydoc PDMAPICREG::pfnBusDeliverR3 */
    637     DECLRCCALLBACKMEMBER(int,       pfnBusDeliverRC,(PPDMDEVINS pDevIns, uint8_t u8Dest, uint8_t u8DestMode, uint8_t u8DeliveryMode,
    638                                                      uint8_t iVector, uint8_t u8Polarity, uint8_t u8TriggerMode, uint32_t uTagSrc));
     636    DECLRCCALLBACKMEMBER(int,          pfnBusDeliverRC,(PPDMDEVINS pDevIns, uint8_t u8Dest, uint8_t u8DestMode,
     637                                                        uint8_t u8DeliveryMode, uint8_t iVector, uint8_t u8Polarity,
     638                                                        uint8_t u8TriggerMode, uint32_t uTagSrc));
    639639    /** @copydoc PDMAPICREG::pfnLocalInterruptR3 */
    640640    DECLRCCALLBACKMEMBER(VBOXSTRICTRC, pfnLocalInterruptRC,(PPDMDEVINS pDevIns, PVMCPU pVCpu, uint8_t u8Pin, uint8_t u8Level,
    641641                                                            int rcRZ));
    642642    /** @copydoc PDMAPICREG::pfnGetTimerFreqR3 */
    643     DECLRCCALLBACKMEMBER(uint64_t,  pfnGetTimerFreqRC,(PPDMDEVINS pDevIns));
     643    DECLRCCALLBACKMEMBER(uint64_t,     pfnGetTimerFreqRC,(PPDMDEVINS pDevIns));
     644
     645    uint8_t                            Alignment[4];
    644646} PDMAPIC;
    645647
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