VirtualBox

Changeset 24125 in vbox for trunk


Ignore:
Timestamp:
Oct 28, 2009 9:58:41 AM (15 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
54037
Message:

DevAPIC/PDM: Properly route PIC interrupts through local APIC (fixes double time interrupt delivery in some Linux kernels).

Location:
trunk
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/VBox/pdmdev.h

    r23988 r24125  
    10431043                                                uint8_t iVector, uint8_t u8Polarity, uint8_t u8TriggerMode));
    10441044
     1045    /**
     1046     * Deliver a signal to CPU's local interrupt pins (LINT0/LINT1). Used for
     1047     * virtual wire mode when interrupts from the PIC are passed through LAPIC.
     1048     *
     1049     * @returns status code.
     1050     * @param   pDevIns         Device instance of the APIC.
     1051     * @param   u8Pin           Local pin number (0 or 1 for current CPUs).
     1052     */
     1053    DECLR3CALLBACKMEMBER(int,  pfnLocalInterruptR3,(PPDMDEVINS pDevIns, uint8_t u8Pin, uint8_t u8Level));
     1054
    10451055    /** The name of the RC GetInterrupt entry point. */
    10461056    const char         *pszGetInterruptRC;
     
    10611071    /** The name of the RC BusDeliver entry point. */
    10621072    const char         *pszBusDeliverRC;
     1073    /** The name of the RC LocalInterrupt entry point. */
     1074    const char         *pszLocalInterruptRC;
    10631075
    10641076    /** The name of the R0 GetInterrupt entry point. */
     
    10801092    /** The name of the R0 BusDeliver entry point. */
    10811093    const char         *pszBusDeliverR0;
     1094    /** The name of the R0 LocalInterrupt entry point. */
     1095    const char         *pszLocalInterruptR0;
    10821096
    10831097} PDMAPICREG;
     
    11191133    /** SMI. */
    11201134    PDMAPICIRQ_SMI,
     1135    /** ExtINT (HW interrupt via PIC). */
     1136    PDMAPICIRQ_EXTINT,
    11211137    /** The usual 32-bit paranoia. */
    11221138    PDMAPICIRQ_32BIT_HACK = 0x7fffffff
     
    11451161     *
    11461162     * @param   pDevIns         Device instance of the APIC.
     1163     * @param   enmType         IRQ type.
    11471164     * @param   idCpu           Virtual CPU to clear flag upon.
    11481165     */
    1149     DECLRCCALLBACKMEMBER(void, pfnClearInterruptFF,(PPDMDEVINS pDevIns, VMCPUID idCpu));
     1166    DECLRCCALLBACKMEMBER(void, pfnClearInterruptFF,(PPDMDEVINS pDevIns, PDMAPICIRQ enmType, VMCPUID idCpu));
    11501167
    11511168    /**
     
    12141231     *
    12151232     * @param   pDevIns         Device instance of the APIC.
     1233     * @param   enmType         IRQ type.
    12161234     * @param   idCpu           Virtual CPU to clear flag upon.
    12171235     */
    1218     DECLR0CALLBACKMEMBER(void, pfnClearInterruptFF,(PPDMDEVINS pDevIns, VMCPUID idCpu));
     1236    DECLR0CALLBACKMEMBER(void, pfnClearInterruptFF,(PPDMDEVINS pDevIns, PDMAPICIRQ enmType, VMCPUID idCpu));
    12191237
    12201238    /**
     
    12821300     *
    12831301     * @param   pDevIns         Device instance of the APIC.
     1302     * @param   enmType         IRQ type.
    12841303     * @param   idCpu           Virtual CPU to clear flag upon.
    12851304     */
    1286     DECLR3CALLBACKMEMBER(void, pfnClearInterruptFF,(PPDMDEVINS pDevIns, VMCPUID idCpu));
     1305    DECLR3CALLBACKMEMBER(void, pfnClearInterruptFF,(PPDMDEVINS pDevIns, PDMAPICIRQ enmType, VMCPUID idCpu));
    12871306
    12881307    /**
  • trunk/src/VBox/Devices/PC/DevAPIC.cpp

    r24082 r24125  
    390390                                           uint8_t u8DeliveryMode, uint8_t iVector, uint8_t u8Polarity,
    391391                                           uint8_t u8TriggerMode);
     392PDMBOTHCBDECL(int)  apicLocalInterrupt(PPDMDEVINS pDevIns, uint8_t u8Pin, uint8_t u8Level);
    392393PDMBOTHCBDECL(int)  apicWriteMSR(PPDMDEVINS pDevIns, VMCPUID iCpu, uint32_t u32Reg, uint64_t u64Value);
    393394PDMBOTHCBDECL(int)  apicReadMSR(PPDMDEVINS pDevIns, VMCPUID iCpu, uint32_t u32Reg, uint64_t *pu64Value);
     
    446447}
    447448
    448 DECLINLINE(void) cpuClearInterrupt(APICDeviceInfo* dev, APICState *s)
     449DECLINLINE(void) cpuClearInterrupt(APICDeviceInfo* dev, APICState *s, PDMAPICIRQ enmType = PDMAPICIRQ_HARDWARE)
    449450{
    450451    LogFlow(("apic: clear interrupt flag\n"));
    451     dev->CTX_SUFF(pApicHlp)->pfnClearInterruptFF(dev->CTX_SUFF(pDevIns),
     452    dev->CTX_SUFF(pApicHlp)->pfnClearInterruptFF(dev->CTX_SUFF(pDevIns), enmType,
    452453                                                 getCpuFromLapic(dev, s));
    453454}
     
    961962    return apic_bus_deliver(dev, apic_get_delivery_bitmask(dev, u8Dest, u8DestMode),
    962963                            u8DeliveryMode, iVector, u8Polarity, u8TriggerMode);
     964}
     965
     966/**
     967 * Local interrupt delivery, for devices attached to the CPU's LINT0/LINT1 pin.
     968 * Normally used for 8259A PIC and NMI.
     969 */
     970PDMBOTHCBDECL(int) apicLocalInterrupt(PPDMDEVINS pDevIns, uint8_t u8Pin, uint8_t u8Level)
     971{
     972    APICDeviceInfo  *dev = PDMINS_2_DATA(pDevIns, APICDeviceInfo *);
     973    APICState       *s = getLapicById(dev, 0);
     974
     975    Assert(PDMCritSectIsOwner(dev->CTX_SUFF(pCritSect)));
     976    LogFlow(("apicLocalInterrupt: pDevIns=%p u8Pin=%x\n", pDevIns, u8Pin));
     977
     978    /* If LAPIC is disabled, go straight to the CPU. */
     979    if (!(s->spurious_vec & APIC_SV_ENABLE))
     980    {
     981        LogFlow(("apicLocalInterrupt: LAPIC disabled, delivering directly to CPU core.\n"));
     982        if (u8Level)
     983            cpuSetInterrupt(dev, s, PDMAPICIRQ_EXTINT);
     984        else
     985            cpuClearInterrupt(dev, s, PDMAPICIRQ_EXTINT);
     986
     987        return VINF_SUCCESS;
     988    }
     989
     990    /* If LAPIC is enabled, interrupts are subject to LVT programming. */
     991    if (u8Pin > 1)
     992    {
     993        /* There are only two local interrupt pins. */
     994        AssertMsgFailed(("Invalid LAPIC pin %d\n", u8Pin));
     995        return VERR_INVALID_PARAMETER;
     996    }
     997
     998    /* NB: We currently only deliver local interrupts to the first CPU. In theory they
     999     * should be delivered to all CPUs and it is the guest's responsibility to ensure
     1000     * no more than one CPU has the interrupt unmasked.
     1001     */
     1002    uint32_t    u32Lvec;
     1003
     1004    u32Lvec = s->lvt[APIC_LVT_LINT0 + u8Pin];   /* Fetch corresponding LVT entry. */
     1005    /* Drop int if entry is masked. May not be correct for level-triggered interrupts. */
     1006    if (!(u32Lvec & APIC_LVT_MASKED))
     1007    {   uint8_t     u8Delivery;
     1008        PDMAPICIRQ  enmType;
     1009
     1010        u8Delivery = (u32Lvec >> 8) & 7;
     1011        switch (u8Delivery)
     1012        {
     1013        case APIC_DM_EXTINT:
     1014            Assert(u8Pin == 0); /* PIC should be wired to LINT0. */
     1015            enmType = PDMAPICIRQ_EXTINT;
     1016            break;
     1017        case APIC_DM_NMI:
     1018            Assert(u8Pin == 0); /* NMI should be wired to LINT1. */
     1019            enmType = PDMAPICIRQ_NMI;
     1020            break;
     1021        case APIC_DM_SMI:
     1022            enmType = PDMAPICIRQ_SMI;
     1023            break;
     1024
     1025        }
     1026        LogFlow(("apicLocalInterrupt: setting local interrupt type %d\n", enmType));
     1027        cpuSetInterrupt(dev, s, enmType);
     1028    }
     1029    return VINF_SUCCESS;
    9631030}
    9641031
     
    27442811    ApicReg.pfnReadMSRR3            = apicReadMSR;
    27452812    ApicReg.pfnBusDeliverR3         = apicBusDeliverCallback;
     2813    ApicReg.pfnLocalInterruptR3     = apicLocalInterrupt;
    27462814    if (fGCEnabled) {
    27472815        ApicReg.pszGetInterruptRC   = "apicGetInterrupt";
     
    27542822        ApicReg.pszReadMSRRC        = "apicReadMSR";
    27552823        ApicReg.pszBusDeliverRC     = "apicBusDeliverCallback";
     2824        ApicReg.pszLocalInterruptRC = "apicLocalInterrupt";
    27562825    } else {
    27572826        ApicReg.pszGetInterruptRC   = NULL;
     
    27642833        ApicReg.pszReadMSRRC        = NULL;
    27652834        ApicReg.pszBusDeliverRC     = NULL;
     2835        ApicReg.pszLocalInterruptRC = NULL;
    27662836    }
    27672837    if (fR0Enabled) {
     
    27752845        ApicReg.pszReadMSRR0        = "apicReadMSR";
    27762846        ApicReg.pszBusDeliverR0     = "apicBusDeliverCallback";
     2847        ApicReg.pszLocalInterruptR0 = "apicLocalInterrupt";
    27772848    } else {
    27782849        ApicReg.pszGetInterruptR0   = NULL;
     
    27852856        ApicReg.pszReadMSRR0        = NULL;
    27862857        ApicReg.pszBusDeliverR0     = NULL;
     2858        ApicReg.pszLocalInterruptR0 = NULL;
    27872859    }
    27882860
  • trunk/src/VBox/VMM/PDM.cpp

    r23716 r24125  
    424424        pVM->pdm.s.Apic.pfnGetTPRRC         += offDelta;
    425425        pVM->pdm.s.Apic.pfnBusDeliverRC     += offDelta;
     426        pVM->pdm.s.Apic.pfnLocalInterruptRC += offDelta;
    426427        pVM->pdm.s.Apic.pfnWriteMSRRC       += offDelta;
    427428        pVM->pdm.s.Apic.pfnReadMSRRC        += offDelta;
  • trunk/src/VBox/VMM/PDMDevHlp.cpp

    r23915 r24125  
    16181618    VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);
    16191619    LogFlow(("pdmR3DevHlp_APICRegister: caller='%s'/%d: pApicReg=%p:{.u32Version=%#x, .pfnGetInterruptR3=%p, .pfnSetBaseR3=%p, .pfnGetBaseR3=%p, "
    1620              ".pfnSetTPRR3=%p, .pfnGetTPRR3=%p, .pfnWriteMSR3=%p, .pfnReadMSR3=%p, .pfnBusDeliverR3=%p, pszGetInterruptRC=%p:{%s}, pszSetBaseRC=%p:{%s}, pszGetBaseRC=%p:{%s}, "
    1621              ".pszSetTPRRC=%p:{%s}, .pszGetTPRRC=%p:{%s}, .pszWriteMSRRC=%p:{%s}, .pszReadMSRRC=%p:{%s}, .pszBusDeliverRC=%p:{%s}} ppApicHlpR3=%p\n",
     1620             ".pfnSetTPRR3=%p, .pfnGetTPRR3=%p, .pfnWriteMSR3=%p, .pfnReadMSR3=%p, .pfnBusDeliverR3=%p, .pfnLocalInterruptR3=%p, pszGetInterruptRC=%p:{%s}, pszSetBaseRC=%p:{%s}, pszGetBaseRC=%p:{%s}, "
     1621             ".pszSetTPRRC=%p:{%s}, .pszGetTPRRC=%p:{%s}, .pszWriteMSRRC=%p:{%s}, .pszReadMSRRC=%p:{%s}, .pszBusDeliverRC=%p:{%s}, .pszLocalInterruptRC=%p:{%s}} ppApicHlpR3=%p\n",
    16221622             pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pApicReg, pApicReg->u32Version, pApicReg->pfnGetInterruptR3, pApicReg->pfnSetBaseR3,
    1623              pApicReg->pfnGetBaseR3, pApicReg->pfnSetTPRR3, pApicReg->pfnGetTPRR3, pApicReg->pfnWriteMSRR3, pApicReg->pfnReadMSRR3, pApicReg->pfnBusDeliverR3, pApicReg->pszGetInterruptRC,
     1623             pApicReg->pfnGetBaseR3, pApicReg->pfnSetTPRR3, pApicReg->pfnGetTPRR3, pApicReg->pfnWriteMSRR3, pApicReg->pfnReadMSRR3, pApicReg->pfnBusDeliverR3, pApicReg->pfnLocalInterruptR3, pApicReg->pszGetInterruptRC,
    16241624             pApicReg->pszGetInterruptRC, pApicReg->pszSetBaseRC, pApicReg->pszSetBaseRC, pApicReg->pszGetBaseRC, pApicReg->pszGetBaseRC,
    16251625             pApicReg->pszSetTPRRC, pApicReg->pszSetTPRRC, pApicReg->pszGetTPRRC, pApicReg->pszGetTPRRC, pApicReg->pszWriteMSRRC, pApicReg->pszWriteMSRRC, pApicReg->pszReadMSRRC, pApicReg->pszReadMSRRC, pApicReg->pszBusDeliverRC,
    1626              pApicReg->pszBusDeliverRC, ppApicHlpR3));
     1626             pApicReg->pszBusDeliverRC, pApicReg->pszLocalInterruptRC, pApicReg->pszLocalInterruptRC, ppApicHlpR3));
    16271627
    16281628    /*
     
    16431643        ||  !pApicReg->pfnWriteMSRR3
    16441644        ||  !pApicReg->pfnReadMSRR3
    1645         ||  !pApicReg->pfnBusDeliverR3)
     1645        ||  !pApicReg->pfnBusDeliverR3
     1646        ||  !pApicReg->pfnLocalInterruptR3)
    16461647    {
    16471648        Assert(pApicReg->pfnGetInterruptR3);
     
    16541655        Assert(pApicReg->pfnReadMSRR3);
    16551656        Assert(pApicReg->pfnBusDeliverR3);
     1657        Assert(pApicReg->pfnLocalInterruptR3);
    16561658        LogFlow(("pdmR3DevHlp_APICRegister: caller='%s'/%d: returns %Rrc (R3 callbacks)\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
    16571659        return VERR_INVALID_PARAMETER;
     
    16651667            ||  pApicReg->pszWriteMSRRC
    16661668            ||  pApicReg->pszReadMSRRC
    1667             ||  pApicReg->pszBusDeliverRC)
     1669            ||  pApicReg->pszBusDeliverRC
     1670            ||  pApicReg->pszLocalInterruptRC)
    16681671        &&  (   !VALID_PTR(pApicReg->pszGetInterruptRC)
    16691672            ||  !VALID_PTR(pApicReg->pszHasPendingIrqRC)
     
    16741677            ||  !VALID_PTR(pApicReg->pszWriteMSRRC)
    16751678            ||  !VALID_PTR(pApicReg->pszReadMSRRC)
    1676             ||  !VALID_PTR(pApicReg->pszBusDeliverRC))
     1679            ||  !VALID_PTR(pApicReg->pszBusDeliverRC)
     1680            ||  !VALID_PTR(pApicReg->pszLocalInterruptRC))
    16771681       )
    16781682    {
     
    16861690        Assert(VALID_PTR(pApicReg->pszWriteMSRRC));
    16871691        Assert(VALID_PTR(pApicReg->pszBusDeliverRC));
     1692        Assert(VALID_PTR(pApicReg->pszLocalInterruptRC));
    16881693        LogFlow(("pdmR3DevHlp_APICRegister: caller='%s'/%d: returns %Rrc (RC callbacks)\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
    16891694        return VERR_INVALID_PARAMETER;
     
    16971702            ||  pApicReg->pszWriteMSRR0
    16981703            ||  pApicReg->pszReadMSRR0
    1699             ||  pApicReg->pszBusDeliverR0)
     1704            ||  pApicReg->pszBusDeliverR0
     1705            ||  pApicReg->pszLocalInterruptR0)
    17001706        &&  (   !VALID_PTR(pApicReg->pszGetInterruptR0)
    17011707            ||  !VALID_PTR(pApicReg->pszHasPendingIrqR0)
     
    17061712            ||  !VALID_PTR(pApicReg->pszReadMSRR0)
    17071713            ||  !VALID_PTR(pApicReg->pszWriteMSRR0)
    1708             ||  !VALID_PTR(pApicReg->pszBusDeliverR0))
     1714            ||  !VALID_PTR(pApicReg->pszBusDeliverR0)
     1715            ||  !VALID_PTR(pApicReg->pszLocalInterruptR0))
    17091716       )
    17101717    {
     
    17181725        Assert(VALID_PTR(pApicReg->pszWriteMSRR0));
    17191726        Assert(VALID_PTR(pApicReg->pszBusDeliverR0));
     1727        Assert(VALID_PTR(pApicReg->pszLocalInterruptR0));
    17201728        LogFlow(("pdmR3DevHlp_APICRegister: caller='%s'/%d: returns %Rrc (R0 callbacks)\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
    17211729        return VERR_INVALID_PARAMETER;
     
    17861794            rc = PDMR3LdrGetSymbolRCLazy(pVM, pDevIns->pDevReg->szRCMod, pApicReg->pszBusDeliverRC, &pVM->pdm.s.Apic.pfnBusDeliverRC);
    17871795            AssertMsgRC(rc, ("%s::%s rc=%Rrc\n", pDevIns->pDevReg->szRCMod, pApicReg->pszBusDeliverRC, rc));
     1796        }
     1797        if (RT_SUCCESS(rc))
     1798        {
     1799            rc = PDMR3LdrGetSymbolRCLazy(pVM, pDevIns->pDevReg->szRCMod, pApicReg->pszLocalInterruptRC, &pVM->pdm.s.Apic.pfnLocalInterruptRC);
     1800            AssertMsgRC(rc, ("%s::%s rc=%Rrc\n", pDevIns->pDevReg->szRCMod, pApicReg->pszLocalInterruptRC, rc));
    17881801        }
    17891802        if (RT_FAILURE(rc))
     
    18061819        pVM->pdm.s.Apic.pfnReadMSRRC        = 0;
    18071820        pVM->pdm.s.Apic.pfnBusDeliverRC     = 0;
     1821        pVM->pdm.s.Apic.pfnLocalInterruptRC = 0;
    18081822    }
    18091823
     
    18541868            rc = PDMR3LdrGetSymbolR0Lazy(pVM, pDevIns->pDevReg->szR0Mod, pApicReg->pszBusDeliverR0, &pVM->pdm.s.Apic.pfnBusDeliverR0);
    18551869            AssertMsgRC(rc, ("%s::%s rc=%Rrc\n", pDevIns->pDevReg->szR0Mod, pApicReg->pszBusDeliverR0, rc));
     1870        }
     1871        if (RT_SUCCESS(rc))
     1872        {
     1873            rc = PDMR3LdrGetSymbolR0Lazy(pVM, pDevIns->pDevReg->szR0Mod, pApicReg->pszLocalInterruptR0, &pVM->pdm.s.Apic.pfnLocalInterruptR0);
     1874            AssertMsgRC(rc, ("%s::%s rc=%Rrc\n", pDevIns->pDevReg->szR0Mod, pApicReg->pszLocalInterruptR0, rc));
    18561875        }
    18571876        if (RT_FAILURE(rc))
     
    18741893        pVM->pdm.s.Apic.pfnReadMSRR0        = 0;
    18751894        pVM->pdm.s.Apic.pfnBusDeliverR0     = 0;
     1895        pVM->pdm.s.Apic.pfnLocalInterruptR0 = 0;
    18761896        pVM->pdm.s.Apic.pDevInsR0           = 0;
    18771897    }
     
    18901910    pVM->pdm.s.Apic.pfnReadMSRR3        = pApicReg->pfnReadMSRR3;
    18911911    pVM->pdm.s.Apic.pfnBusDeliverR3     = pApicReg->pfnBusDeliverR3;
     1912    pVM->pdm.s.Apic.pfnLocalInterruptR3 = pApicReg->pfnLocalInterruptR3;
    18921913    Log(("PDM: Registered APIC device '%s'/%d pDevIns=%p\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pDevIns));
    18931914
  • trunk/src/VBox/VMM/PDMDevMiscHlp.cpp

    r23901 r24125  
    4848    PDMDEV_ASSERT_DEVINS(pDevIns);
    4949    PVM pVM = pDevIns->Internal.s.pVMR3;
     50
     51    if (pVM->pdm.s.Apic.pfnLocalInterruptR3)
     52    {
     53        LogFlow(("pdmR3PicHlp_SetInterruptFF: caller='%s'/%d: Setting local interrupt on LAPIC\n",
     54                 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance));
     55        /* Raise the LAPIC's LINT0 line instead of signaling the CPU directly. */
     56        pVM->pdm.s.Apic.pfnLocalInterruptR3(pVM->pdm.s.Apic.pDevInsR3, 0, 1);
     57        return;
     58    }
     59 
    5060    PVMCPU pVCpu = &pVM->aCpus[0];  /* for PIC we always deliver to CPU 0, MP use APIC */
    5161
     
    6575    PVM pVM = pDevIns->Internal.s.pVMR3;
    6676    PVMCPU pVCpu = &pVM->aCpus[0];  /* for PIC we always deliver to CPU 0, MP use APIC */
     77
     78    if (pVM->pdm.s.Apic.pfnLocalInterruptR3)
     79    {
     80        /* Raise the LAPIC's LINT0 line instead of signaling the CPU directly. */
     81        LogFlow(("pdmR3PicHlp_ClearInterruptFF: caller='%s'/%d: Clearing local interrupt on LAPIC\n",
     82                 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance));
     83        /* Lower the LAPIC's LINT0 line instead of signaling the CPU directly. */
     84        pVM->pdm.s.Apic.pfnLocalInterruptR3(pVM->pdm.s.Apic.pDevInsR3, 0, 0);
     85        return;
     86    }
    6787
    6888    LogFlow(("pdmR3PicHlp_ClearInterruptFF: caller='%s'/%d: VM_FF_INTERRUPT_PIC %d -> 0\n",
     
    167187            VMCPU_FF_SET(pVCpu, VMCPU_FF_INTERRUPT_SMI);
    168188            break;
     189        case PDMAPICIRQ_EXTINT:
     190            VMCPU_FF_SET(pVCpu, VMCPU_FF_INTERRUPT_PIC);
     191            break;
    169192        default:
    170193            AssertMsgFailed(("enmType=%d\n", enmType));
     
    177200
    178201/** @copydoc PDMAPICHLPR3::pfnClearInterruptFF */
    179 static DECLCALLBACK(void) pdmR3ApicHlp_ClearInterruptFF(PPDMDEVINS pDevIns, VMCPUID idCpu)
     202static DECLCALLBACK(void) pdmR3ApicHlp_ClearInterruptFF(PPDMDEVINS pDevIns, PDMAPICIRQ enmType, VMCPUID idCpu)
    180203{
    181204    PDMDEV_ASSERT_DEVINS(pDevIns);
     
    188211             pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, idCpu, VMCPU_FF_ISSET(pVCpu, VMCPU_FF_INTERRUPT_APIC)));
    189212
    190     VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_INTERRUPT_APIC);
     213    /* Note: NMI/SMI can't be cleared. */
     214    switch (enmType)
     215    {
     216        case PDMAPICIRQ_HARDWARE:
     217            VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_INTERRUPT_APIC);
     218            break;
     219        case PDMAPICIRQ_EXTINT:
     220            VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_INTERRUPT_PIC);
     221            break;
     222        default:
     223            AssertMsgFailed(("enmType=%d\n", enmType));
     224            break;
     225    }
    191226    REMR3NotifyInterruptClear(pVM, pVCpu);
    192227}
  • trunk/src/VBox/VMM/PDMInternal.h

    r23584 r24125  
    438438    DECLR3CALLBACKMEMBER(int,       pfnBusDeliverR3,(PPDMDEVINS pDevIns, uint8_t u8Dest, uint8_t u8DestMode, uint8_t u8DeliveryMode,
    439439                                                     uint8_t iVector, uint8_t u8Polarity, uint8_t u8TriggerMode));
     440    /** @copydoc PDMAPICREG::pfnLocalInterruptR3 */
     441    DECLR3CALLBACKMEMBER(int,       pfnLocalInterruptR3,(PPDMDEVINS pDevIns, uint8_t u8Pin, uint8_t u8Level));
    440442
    441443    /** Pointer to the APIC device instance - R0 Ptr. */
     
    460462    DECLR0CALLBACKMEMBER(int,       pfnBusDeliverR0,(PPDMDEVINS pDevIns, uint8_t u8Dest, uint8_t u8DestMode, uint8_t u8DeliveryMode,
    461463                                                     uint8_t iVector, uint8_t u8Polarity, uint8_t u8TriggerMode));
     464    /** @copydoc PDMAPICREG::pfnLocalInterruptR3 */
     465    DECLR0CALLBACKMEMBER(int,       pfnLocalInterruptR0,(PPDMDEVINS pDevIns, uint8_t u8Pin, uint8_t u8Level));
    462466
    463467    /** Pointer to the APIC device instance - RC Ptr. */
     
    482486    DECLRCCALLBACKMEMBER(int,       pfnBusDeliverRC,(PPDMDEVINS pDevIns, uint8_t u8Dest, uint8_t u8DestMode, uint8_t u8DeliveryMode,
    483487                                                     uint8_t iVector, uint8_t u8Polarity, uint8_t u8TriggerMode));
     488    /** @copydoc PDMAPICREG::pfnLocalInterruptR3 */
     489    DECLRCCALLBACKMEMBER(int,       pfnLocalInterruptRC,(PPDMDEVINS pDevIns, uint8_t u8Pin, uint8_t u8Level));
     490
    484491} PDMAPIC;
    485492
  • trunk/src/VBox/VMM/VMMGC/PDMGCDevice.cpp

    r22890 r24125  
    8787 */
    8888static DECLCALLBACK(void) pdmRCApicHlp_SetInterruptFF(PPDMDEVINS pDevIns, PDMAPICIRQ enmType, VMCPUID idCpu);
    89 static DECLCALLBACK(void) pdmRCApicHlp_ClearInterruptFF(PPDMDEVINS pDevIns, VMCPUID idCpu);
     89static DECLCALLBACK(void) pdmRCApicHlp_ClearInterruptFF(PPDMDEVINS pDevIns, PDMAPICIRQ enmType, VMCPUID idCpu);
    9090static DECLCALLBACK(void) pdmRCApicHlp_ChangeFeature(PPDMDEVINS pDevIns, PDMAPICVERSION enmVersion);
    9191static DECLCALLBACK(int) pdmRCApicHlp_Lock(PPDMDEVINS pDevIns, int rc);
     
    441441
    442442/** @copydoc PDMAPICHLPRC::pfnClearInterruptFF */
    443 static DECLCALLBACK(void) pdmRCApicHlp_ClearInterruptFF(PPDMDEVINS pDevIns, VMCPUID idCpu)
     443static DECLCALLBACK(void) pdmRCApicHlp_ClearInterruptFF(PPDMDEVINS pDevIns, PDMAPICIRQ enmType, VMCPUID idCpu)
    444444{
    445445    PDMDEV_ASSERT_DEVINS(pDevIns);
     
    451451    LogFlow(("pdmRCApicHlp_ClearInterruptFF: caller=%p/%d: VM_FF_INTERRUPT %d -> 0\n",
    452452             pDevIns, pDevIns->iInstance, VMCPU_FF_ISSET(pVCpu, VMCPU_FF_INTERRUPT_APIC)));
    453     VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_INTERRUPT_APIC);
     453
     454    /* Note: NMI/SMI can't be cleared. */
     455    switch (enmType)
     456    {
     457        case PDMAPICIRQ_HARDWARE:
     458            VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_INTERRUPT_APIC);
     459            break;
     460        case PDMAPICIRQ_EXTINT:
     461            VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_INTERRUPT_PIC);
     462            break;
     463        default:
     464            AssertMsgFailed(("enmType=%d\n", enmType));
     465            break;
     466    }
    454467}
    455468
  • trunk/src/VBox/VMM/VMMR0/PDMR0Device.cpp

    r22890 r24125  
    9090 */
    9191static DECLCALLBACK(void) pdmR0ApicHlp_SetInterruptFF(PPDMDEVINS pDevIns, PDMAPICIRQ enmType, VMCPUID idCpu);
    92 static DECLCALLBACK(void) pdmR0ApicHlp_ClearInterruptFF(PPDMDEVINS pDevIns, VMCPUID idCpu);
     92static DECLCALLBACK(void) pdmR0ApicHlp_ClearInterruptFF(PPDMDEVINS pDevIns, PDMAPICIRQ enmType, VMCPUID idCpu);
    9393static DECLCALLBACK(void) pdmR0ApicHlp_ChangeFeature(PPDMDEVINS pDevIns, PDMAPICVERSION enmVersion);
    9494static DECLCALLBACK(int)  pdmR0ApicHlp_Lock(PPDMDEVINS pDevIns, int rc);
     
    475475
    476476/** @copydoc PDMAPICHLPR0::pfnClearInterruptFF */
    477 static DECLCALLBACK(void) pdmR0ApicHlp_ClearInterruptFF(PPDMDEVINS pDevIns, VMCPUID idCpu)
     477static DECLCALLBACK(void) pdmR0ApicHlp_ClearInterruptFF(PPDMDEVINS pDevIns, PDMAPICIRQ enmType, VMCPUID idCpu)
    478478{
    479479    PDMDEV_ASSERT_DEVINS(pDevIns);
     
    485485    LogFlow(("pdmR0ApicHlp_ClearInterruptFF: caller=%p/%d: VM_FF_INTERRUPT %d -> 0\n",
    486486             pDevIns, pDevIns->iInstance, VMCPU_FF_ISSET(pVCpu, VMCPU_FF_INTERRUPT_APIC)));
    487     VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_INTERRUPT_APIC);
     487
     488    /* Note: NMI/SMI can't be cleared. */
     489    switch (enmType)
     490    {
     491        case PDMAPICIRQ_HARDWARE:
     492            VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_INTERRUPT_APIC);
     493            break;
     494        case PDMAPICIRQ_EXTINT:
     495            VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_INTERRUPT_PIC);
     496            break;
     497        default:
     498            AssertMsgFailed(("enmType=%d\n", enmType));
     499            break;
     500    }
    488501}
    489502
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