Changeset 89620 in vbox
- Timestamp:
- Jun 11, 2021 8:51:10 AM (4 years ago)
- Location:
- trunk
- Files:
-
- 9 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/VBox/vmm/pdmapi.h
r89600 r89620 54 54 VMM_INT_DECL(bool) PDMHasApic(PVM pVM); 55 55 VMM_INT_DECL(int) PDMIoApicSetIrq(PVM pVM, PCIBDF uBusDevFn, uint8_t u8Irq, uint8_t u8Level, uint32_t uTagSrc); 56 VMM_INT_DECL( VBOXSTRICTRC) PDMIoApicBroadcastEoi(PVMpVM, uint8_t uVector);57 VMM_INT_DECL(void) PDMIoApicSendMsi(P PDMDEVINS pDevIns, PCIBDF uBusDevFn, PCMSIMSG pMsi, uint32_t uTagSrc);56 VMM_INT_DECL(void) PDMIoApicBroadcastEoi(PVMCC pVM, uint8_t uVector); 57 VMM_INT_DECL(void) PDMIoApicSendMsi(PVMCC pVM, PCIBDF uBusDevFn, PCMSIMSG pMsi, uint32_t uTagSrc); 58 58 VMM_INT_DECL(int) PDMVmmDevHeapR3ToGCPhys(PVM pVM, RTR3PTR pv, RTGCPHYS *pGCPhys); 59 59 VMM_INT_DECL(bool) PDMVmmDevHeapIsEnabled(PVM pVM); -
trunk/include/VBox/vmm/pdmdev.h
r89200 r89620 1869 1869 * Set the EOI for an interrupt vector. 1870 1870 * 1871 * @returns Strict VBox status code - only the following informational status codes:1872 * @retval VINF_IOM_R3_MMIO_WRITE if the I/O APIC lock is contenteded and we're in R0 or RC.1873 * @retval VINF_SUCCESS1874 *1875 1871 * @param pDevIns Device instance of the I/O APIC. 1876 1872 * @param u8Vector The vector. … … 1879 1875 * Actually, as per 2018-07-21 this isn't true (bird). 1880 1876 */ 1881 DECLCALLBACKMEMBER( VBOXSTRICTRC, pfnSetEoi,(PPDMDEVINS pDevIns, uint8_t u8Vector));1877 DECLCALLBACKMEMBER(void, pfnSetEoi,(PPDMDEVINS pDevIns, uint8_t u8Vector)); 1882 1878 1883 1879 /** Just a safety precaution. */ … … 1888 1884 1889 1885 /** Current PDMAPICREG version number. */ 1890 #define PDM_IOAPICREG_VERSION PDM_VERSION_MAKE(0xfff2, 7, 0)1886 #define PDM_IOAPICREG_VERSION PDM_VERSION_MAKE(0xfff2, 8, 0) 1891 1887 1892 1888 -
trunk/src/VBox/Devices/PC/DevIoApic.cpp
r89098 r89620 313 313 /** Number of IOMMU denied or failed MSIs. */ 314 314 STAMCOUNTER StatIommuDiscardedMsi; 315 /** Number of returns to ring-3 due to EOI broadcast lock contention. */316 STAMCOUNTER StatEoiContention;317 315 /** Number of returns to ring-3 due to Set RTE lock contention. */ 318 316 STAMCOUNTER StatSetRteContention; … … 845 843 * @interface_method_impl{PDMIOAPICREG,pfnSetEoi} 846 844 */ 847 static DECLCALLBACK( VBOXSTRICTRC) ioapicSetEoi(PPDMDEVINS pDevIns, uint8_t u8Vector)845 static DECLCALLBACK(void) ioapicSetEoi(PPDMDEVINS pDevIns, uint8_t u8Vector) 848 846 { 849 847 PIOAPIC pThis = PDMDEVINS_2_DATA(pDevIns, PIOAPIC); 850 848 PIOAPICCC pThisCC = PDMDEVINS_2_DATA_CC(pDevIns, PIOAPICCC); 849 850 LogFlow(("IOAPIC: ioapicSetEoi: u8Vector=%#x (%u)\n", u8Vector, u8Vector)); 851 851 STAM_COUNTER_INC(&pThis->CTX_SUFF_Z(StatSetEoi)); 852 LogFlow(("IOAPIC: ioapicSetEoi: u8Vector=%#x (%u)\n", u8Vector, u8Vector));853 852 854 853 bool fRemoteIrrCleared = false; 855 VBOXSTRICTRC rc = IOAPIC_LOCK(pDevIns, pThis, pThisCC, VINF_IOM_R3_MMIO_WRITE); 856 if (rc == VINF_SUCCESS) 857 { 858 for (uint8_t idxRte = 0; idxRte < RT_ELEMENTS(pThis->au64RedirTable); idxRte++) 854 int rc = IOAPIC_LOCK(pDevIns, pThis, pThisCC, VINF_SUCCESS); 855 AssertRC(rc); 856 857 for (uint8_t idxRte = 0; idxRte < RT_ELEMENTS(pThis->au64RedirTable); idxRte++) 858 { 859 uint64_t const u64Rte = pThis->au64RedirTable[idxRte]; 860 if (IOAPIC_RTE_GET_VECTOR(u64Rte) == u8Vector) 859 861 { 860 uint64_t const u64Rte = pThis->au64RedirTable[idxRte];861 if (IOAPIC_RTE_GET_VECTOR(u64Rte) == u8Vector)862 {863 862 #ifdef DEBUG_ramshankar 864 865 863 /* This assertion may trigger when restoring saved-states created using the old, incorrect I/O APIC code. */ 864 Assert(IOAPIC_RTE_GET_REMOTE_IRR(u64Rte)); 866 865 #endif 867 pThis->au64RedirTable[idxRte] &= ~IOAPIC_RTE_REMOTE_IRR; 868 fRemoteIrrCleared = true; 869 STAM_COUNTER_INC(&pThis->StatEoiReceived); 870 Log2(("IOAPIC: ioapicSetEoi: Cleared remote IRR, idxRte=%u vector=%#x (%u)\n", idxRte, u8Vector, u8Vector)); 871 872 /* 873 * Signal the next pending interrupt for this RTE. 874 */ 875 uint32_t const uPinMask = UINT32_C(1) << idxRte; 876 if (pThis->uIrr & uPinMask) 877 ioapicSignalIntrForRte(pDevIns, pThis, pThisCC, idxRte); 878 } 866 pThis->au64RedirTable[idxRte] &= ~IOAPIC_RTE_REMOTE_IRR; 867 fRemoteIrrCleared = true; 868 STAM_COUNTER_INC(&pThis->StatEoiReceived); 869 Log2(("IOAPIC: ioapicSetEoi: Cleared remote IRR, idxRte=%u vector=%#x (%u)\n", idxRte, u8Vector, u8Vector)); 870 871 /* 872 * Signal the next pending interrupt for this RTE. 873 */ 874 uint32_t const uPinMask = UINT32_C(1) << idxRte; 875 if (pThis->uIrr & uPinMask) 876 ioapicSignalIntrForRte(pDevIns, pThis, pThisCC, idxRte); 879 877 } 880 881 IOAPIC_UNLOCK(pDevIns, pThis, pThisCC); 878 } 879 880 IOAPIC_UNLOCK(pDevIns, pThis, pThisCC); 881 882 882 #ifndef VBOX_WITH_IOMMU_AMD 883 883 AssertMsg(fRemoteIrrCleared, ("Failed to clear remote IRR for vector %#x (%u)\n", u8Vector, u8Vector)); 884 884 #endif 885 }886 else887 STAM_COUNTER_INC(&pThis->StatEoiContention);888 889 return rc;890 885 } 891 886 … … 1119 1114 case IOAPIC_DIRECT_OFF_EOI: 1120 1115 if (pThis->u8ApicVer == IOAPIC_VERSION_ICH9) 1121 rc =ioapicSetEoi(pDevIns, uValue);1116 ioapicSetEoi(pDevIns, uValue); 1122 1117 else 1123 1118 Log(("IOAPIC: ioapicMmioWrite: Write to EOI register ignored!\n")); … … 1668 1663 PDMDevHlpSTAMRegister(pDevIns, &pThis->StatIommuDiscardedMsi, STAMTYPE_COUNTER, "Iommu/DiscardedMsi", STAMUNIT_OCCURENCES, "Number of MSIs discarded by the IOMMU."); 1669 1664 1670 PDMDevHlpSTAMRegister(pDevIns, &pThis->StatEoiContention, STAMTYPE_COUNTER, "CritSect/ContentionSetEoi", STAMUNIT_OCCURENCES, "Number of times the critsect is busy during EOI writes causing trips to R3.");1671 1665 PDMDevHlpSTAMRegister(pDevIns, &pThis->StatSetRteContention, STAMTYPE_COUNTER, "CritSect/ContentionSetRte", STAMUNIT_OCCURENCES, "Number of times the critsect is busy during RTE writes causing trips to R3."); 1672 1666 -
trunk/src/VBox/VMM/VMMAll/APICAll.cpp
r88670 r89620 1233 1233 * @param pVCpu The cross context virtual CPU structure. 1234 1234 * @param uEoi The EOI value. 1235 * @param rcBusy The busy return code when the write cannot1236 * be completed successfully in this context.1237 1235 * @param fForceX2ApicBehaviour Pretend the APIC is in x2APIC mode during 1238 1236 * this write. 1239 1237 */ 1240 static VBOXSTRICTRC apicSetEoi(PVMCPUCC pVCpu, uint32_t uEoi, int rcBusy,bool fForceX2ApicBehaviour)1238 static VBOXSTRICTRC apicSetEoi(PVMCPUCC pVCpu, uint32_t uEoi, bool fForceX2ApicBehaviour) 1241 1239 { 1242 1240 VMCPU_ASSERT_EMT(pVCpu); … … 1266 1264 if (fLevelTriggered) 1267 1265 { 1268 VBOXSTRICTRC rc = PDMIoApicBroadcastEoi(pVCpu->CTX_SUFF(pVM), uVector); 1269 if (rc == VINF_SUCCESS) 1270 { /* likely */ } 1271 else 1272 return rcBusy; 1266 PDMIoApicBroadcastEoi(pVCpu->CTX_SUFF(pVM), uVector); 1273 1267 1274 1268 /* … … 1789 1783 case XAPIC_OFF_EOI: 1790 1784 { 1791 rcStrict = apicSetEoi(pVCpu, uValue, VINF_IOM_R3_MMIO_WRITE,false /* fForceX2ApicBehaviour */);1785 rcStrict = apicSetEoi(pVCpu, uValue, false /* fForceX2ApicBehaviour */); 1792 1786 break; 1793 1787 } … … 2135 2129 case MSR_IA32_X2APIC_EOI: 2136 2130 { 2137 rcStrict = apicSetEoi(pVCpu, u32Value, VINF_CPUM_R3_MSR_WRITE,false /* fForceX2ApicBehaviour */);2131 rcStrict = apicSetEoi(pVCpu, u32Value, false /* fForceX2ApicBehaviour */); 2138 2132 break; 2139 2133 } … … 3503 3497 Assert(pVCpu); 3504 3498 VMCPU_ASSERT_EMT_OR_NOT_RUNNING(pVCpu); 3505 return apicSetEoi(pVCpu, uEoi, VINF_CPUM_R3_MSR_WRITE,true /* fForceX2ApicBehaviour */);3499 return apicSetEoi(pVCpu, uEoi, true /* fForceX2ApicBehaviour */); 3506 3500 } 3507 3501 -
trunk/src/VBox/VMM/VMMAll/PDMAll.cpp
r89602 r89620 191 191 192 192 /** 193 * Broadcasts an EOI to the I/O APICs. 194 * 195 * @returns Strict VBox status code - only the following informational status codes: 196 * @retval VINF_IOM_R3_MMIO_WRITE if the I/O APIC lock is contenteded and we're in R0 or RC. 197 * @retval VINF_SUCCESS 198 * 199 * @param pVM The cross context VM structure. 200 * @param uVector The interrupt vector corresponding to the EOI. 201 */ 202 VMM_INT_DECL(VBOXSTRICTRC) PDMIoApicBroadcastEoi(PVM pVM, uint8_t uVector) 203 { 204 /* At present, we support only a maximum of one I/O APIC per-VM. If we ever implement having 205 multiple I/O APICs per-VM, we'll have to broadcast this EOI to all of the I/O APICs. */ 206 if (pVM->pdm.s.IoApic.CTX_SUFF(pDevIns)) 207 { 208 Assert(pVM->pdm.s.IoApic.CTX_SUFF(pfnSetEoi)); 209 return pVM->pdm.s.IoApic.CTX_SUFF(pfnSetEoi)(pVM->pdm.s.IoApic.CTX_SUFF(pDevIns), uVector); 210 } 211 212 /* We shouldn't return failure if no I/O APIC is present. */ 213 return VINF_SUCCESS; 193 * Broadcasts an EOI to the I/O APIC(s). 194 * 195 * @param pVM The cross context VM structure. 196 * @param uVector The interrupt vector corresponding to the EOI. 197 */ 198 VMM_INT_DECL(void) PDMIoApicBroadcastEoi(PVMCC pVM, uint8_t uVector) 199 { 200 /* 201 * At present, we support only a maximum of one I/O APIC per-VM. If we ever implement having 202 * multiple I/O APICs per-VM, we'll have to broadcast this EOI to all of the I/O APICs. 203 */ 204 PCPDMIOAPIC pIoApic = &pVM->pdm.s.IoApic; 205 #ifdef IN_RING0 206 if (pIoApic->pDevInsR0) 207 { 208 Assert(pIoApic->pfnSetEoiR0); 209 pIoApic->pfnSetEoiR0(pIoApic->pDevInsR0, uVector); 210 } 211 else if (pIoApic->pDevInsR3) 212 { 213 /* Queue for ring-3 execution. */ 214 PPDMDEVHLPTASK pTask = (PPDMDEVHLPTASK)PDMQueueAlloc(pVM->pdm.s.pDevHlpQueueR0); 215 if (pTask) 216 { 217 pTask->enmOp = PDMDEVHLPTASKOP_IOAPIC_SET_EOI; 218 pTask->pDevInsR3 = NIL_RTR3PTR; /* not required */ 219 pTask->u.IoApicSetEoi.uVector = uVector; 220 PDMQueueInsertEx(pVM->pdm.s.pDevHlpQueueR0, &pTask->Core, 0); 221 } 222 else 223 AssertMsgFailed(("We're out of devhlp queue items!!!\n")); 224 } 225 #else 226 if (pIoApic->pDevInsR3) 227 { 228 Assert(pIoApic->pfnSetEoiR3); 229 pIoApic->pfnSetEoiR3(pIoApic->pDevInsR3, uVector); 230 } 231 #endif 214 232 } 215 233 … … 218 236 * Send a MSI to an I/O APIC. 219 237 * 220 * @param p DevIns The PCI device instance.238 * @param pVM The cross context VM structure. 221 239 * @param uBusDevFn The bus:device:function of the device initiating the MSI. 222 * Cannot be NIL_PCIBDF.223 240 * @param pMsi The MSI to send. 224 241 * @param uTagSrc The IRQ tag and source tracer ID. 225 242 */ 226 VMM_INT_DECL(void) PDMIoApicSendMsi(PPDMDEVINS pDevIns, PCIBDF uBusDevFn, PCMSIMSG pMsi, uint32_t uTagSrc) 227 { 243 VMM_INT_DECL(void) PDMIoApicSendMsi(PVMCC pVM, PCIBDF uBusDevFn, PCMSIMSG pMsi, uint32_t uTagSrc) 244 { 245 PCPDMIOAPIC pIoApic = &pVM->pdm.s.IoApic; 228 246 #ifdef IN_RING0 229 PGVM pGVM = pDevIns->Internal.s.pGVM;230 PCPDMIOAPIC pIoApic = &pGVM->pdm.s.IoApic;231 247 if (pIoApic->pDevInsR0) 232 248 pIoApic->pfnSendMsiR0(pIoApic->pDevInsR0, uBusDevFn, pMsi, uTagSrc); … … 234 250 { 235 251 /* Queue for ring-3 execution. */ 236 PPDMDEVHLPTASK pTask = (PPDMDEVHLPTASK)PDMQueueAlloc(p GVM->pdm.s.pDevHlpQueueR0);252 PPDMDEVHLPTASK pTask = (PPDMDEVHLPTASK)PDMQueueAlloc(pVM->pdm.s.pDevHlpQueueR0); 237 253 if (pTask) 238 254 { 239 255 pTask->enmOp = PDMDEVHLPTASKOP_IOAPIC_SEND_MSI; 240 pTask->pDevInsR3 = PDMDEVINS_2_R3PTR(pDevIns);256 pTask->pDevInsR3 = NIL_RTR3PTR; /* not required */ 241 257 pTask->u.IoApicSendMsi.uBusDevFn = uBusDevFn; 242 258 pTask->u.IoApicSendMsi.Msi = *pMsi; 243 259 pTask->u.IoApicSendMsi.uTagSrc = uTagSrc; 244 245 PDMQueueInsertEx(pGVM->pdm.s.pDevHlpQueueR0, &pTask->Core, 0); 260 PDMQueueInsertEx(pVM->pdm.s.pDevHlpQueueR0, &pTask->Core, 0); 246 261 } 247 262 else … … 249 264 } 250 265 #else 251 PVM pVM = pDevIns->Internal.s.pVMR3;252 PCPDMIOAPIC pIoApic = &pVM->pdm.s.IoApic;253 266 if (pIoApic->pDevInsR3) 254 267 { -
trunk/src/VBox/VMM/VMMR0/PDMR0DevHlp.cpp
r89600 r89620 1633 1633 Log4(("pdmR0PciHlp_IoApicSendMsi: uBusDevFn=%#x Msi=(Addr:%#RX64 Data:%#RX32) uTagSrc=%#x\n", uBusDevFn, pMsi->Addr.u64, 1634 1634 pMsi->Data.u32, uTagSrc)); 1635 PDMIoApicSendMsi(pDevIns , uBusDevFn, pMsi, uTagSrc);1635 PDMIoApicSendMsi(pDevIns->Internal.s.pGVM, uBusDevFn, pMsi, uTagSrc); 1636 1636 } 1637 1637 … … 1715 1715 { 1716 1716 PDMDEV_ASSERT_DEVINS(pDevIns); 1717 PDMIoApicSendMsi(pDevIns , NIL_PCIBDF, pMsi, uTagSrc);1717 PDMIoApicSendMsi(pDevIns->Internal.s.pGVM, NIL_PCIBDF, pMsi, uTagSrc); 1718 1718 } 1719 1719 -
trunk/src/VBox/VMM/VMMR3/PDMDevHlp.cpp
r89602 r89620 5371 5371 if (pPciDev) 5372 5372 { 5373 size_t const 5373 size_t const idxBus = pPciDev->Int.s.idxPdmBus; 5374 5374 AssertBreak(idxBus < RT_ELEMENTS(pVM->pdm.s.aPciBuses)); 5375 PPDMPCIBUS 5375 PPDMPCIBUS pBus = &pVM->pdm.s.aPciBuses[idxBus]; 5376 5376 5377 5377 pdmLock(pVM); … … 5394 5394 case PDMDEVHLPTASKOP_IOAPIC_SEND_MSI: 5395 5395 { 5396 Assert(pTask->pDevInsR3); 5397 PDMIoApicSendMsi(pTask->pDevInsR3, pTask->u.IoApicSendMsi.uBusDevFn, &pTask->u.IoApicSendMsi.Msi, 5398 pTask->u.IoApicSendMsi.uTagSrc); 5396 PDMIoApicSendMsi(pVM, pTask->u.IoApicSendMsi.uBusDevFn, &pTask->u.IoApicSendMsi.Msi, pTask->u.IoApicSendMsi.uTagSrc); 5397 break; 5398 } 5399 5400 case PDMDEVHLPTASKOP_IOAPIC_SET_EOI: 5401 { 5402 PDMIoApicBroadcastEoi(pVM, pTask->u.IoApicSetEoi.uVector); 5399 5403 break; 5400 5404 } -
trunk/src/VBox/VMM/VMMR3/PDMDevMiscHlp.cpp
r89600 r89620 215 215 Log4(("pdmR3PciHlp_IoApicSendMsi: uBusDevFn=%#x Msi (Addr=%#RX64 Data=%#x) uTagSrc=%#x\n", uBusDevFn, 216 216 pMsi->Addr.u64, pMsi->Data.u32, uTagSrc)); 217 PDMIoApicSendMsi(pDevIns , uBusDevFn, pMsi, uTagSrc);217 PDMIoApicSendMsi(pDevIns->Internal.s.pVMR3, uBusDevFn, pMsi, uTagSrc); 218 218 } 219 219 … … 303 303 PDMDEV_ASSERT_DEVINS(pDevIns); 304 304 LogFlowFunc(("caller='%s'/%d:\n", pDevIns->pReg->szName, pDevIns->iInstance)); 305 PDMIoApicSendMsi(pDevIns , NIL_PCIBDF, pMsi, uTagSrc);305 PDMIoApicSendMsi(pDevIns->Internal.s.pVMR3, NIL_PCIBDF, pMsi, uTagSrc); 306 306 } 307 307 -
trunk/src/VBox/VMM/include/PDMInternal.h
r89600 r89620 799 799 DECLR3CALLBACKMEMBER(void, pfnSendMsiR3,(PPDMDEVINS pDevIns, PCIBDF uBusDevFn, PCMSIMSG pMsi, uint32_t uTagSrc)); 800 800 /** @copydoc PDMIOAPICREG::pfnSetEoi */ 801 DECLR3CALLBACKMEMBER( VBOXSTRICTRC,pfnSetEoiR3,(PPDMDEVINS pDevIns, uint8_t u8Vector));801 DECLR3CALLBACKMEMBER(void, pfnSetEoiR3,(PPDMDEVINS pDevIns, uint8_t u8Vector)); 802 802 803 803 /** Pointer to the I/O APIC device instance - R0. */ … … 808 808 DECLR0CALLBACKMEMBER(void, pfnSendMsiR0,(PPDMDEVINS pDevIns, PCIBDF uBusDevFn, PCMSIMSG pMsi, uint32_t uTagSrc)); 809 809 /** @copydoc PDMIOAPICREG::pfnSetEoi */ 810 DECLR0CALLBACKMEMBER( VBOXSTRICTRC,pfnSetEoiR0,(PPDMDEVINS pDevIns, uint8_t u8Vector));810 DECLR0CALLBACKMEMBER(void, pfnSetEoiR0,(PPDMDEVINS pDevIns, uint8_t u8Vector)); 811 811 812 812 /** Pointer to the I/O APIC device instance - RC Ptr. */ … … 817 817 DECLRCCALLBACKMEMBER(void, pfnSendMsiRC,(PPDMDEVINS pDevIns, PCIBDF uBusDevFn, PCMSIMSG pMsi, uint32_t uTagSrc)); 818 818 /** @copydoc PDMIOAPICREG::pfnSendMsi */ 819 DECLRCCALLBACKMEMBER( VBOXSTRICTRC,pfnSetEoiRC,(PPDMDEVINS pDevIns, uint8_t u8Vector));819 DECLRCCALLBACKMEMBER(void, pfnSetEoiRC,(PPDMDEVINS pDevIns, uint8_t u8Vector)); 820 820 } PDMIOAPIC; 821 821 /** Pointer to a PDM IOAPIC instance. */ … … 1215 1215 /** IoApicSendMsi */ 1216 1216 PDMDEVHLPTASKOP_IOAPIC_SEND_MSI, 1217 /** IoApicBroadcastEoi */ 1218 PDMDEVHLPTASKOP_IOAPIC_SET_EOI, 1217 1219 /** The usual 32-bit hack. */ 1218 1220 PDMDEVHLPTASKOP_32BIT_HACK = 0x7fffffff … … 1278 1280 uint32_t uTagSrc; 1279 1281 } IoApicSendMsi; 1282 1283 /** 1284 * PDMDEVHLPTASKOP_IOAPIC_SET_EOI 1285 */ 1286 struct PDMDEVHLPTASKIOAPICSETEOI 1287 { 1288 /** The vector corresponding to the EOI. */ 1289 uint8_t uVector; 1290 } IoApicSetEoi; 1280 1291 1281 1292 /** Expanding the structure. */
Note:
See TracChangeset
for help on using the changeset viewer.