Changeset 89912 in vbox for trunk/src/VBox/VMM
- Timestamp:
- Jun 25, 2021 11:24:49 AM (4 years ago)
- svn:sync-xref-src-repo-rev:
- 145370
- Location:
- trunk/src/VBox/VMM
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMR0/DBGFR0Bp.cpp
r87600 r89912 75 75 } 76 76 77 pGVM->dbgfr0.s.hMemObjBpLocL1 = NIL_RTR0MEMOBJ; 78 //pGVM->dbgfr0.s.paBpLocL1R0 = NULL; 79 //pGVM->dbgfr0.s.fInit = false; 77 pGVM->dbgfr0.s.hMemObjBpLocL1 = NIL_RTR0MEMOBJ; 78 pGVM->dbgfr0.s.hMapObjBpLocL1 = NIL_RTR0MEMOBJ; 79 pGVM->dbgfr0.s.hMemObjBpLocPortIo = NIL_RTR0MEMOBJ; 80 pGVM->dbgfr0.s.hMapObjBpLocPortIo = NIL_RTR0MEMOBJ; 81 //pGVM->dbgfr0.s.paBpLocL1R0 = NULL; 82 //pGVM->dbgfr0.s.paBpLocPortIoR0 = NULL; 83 //pGVM->dbgfr0.s.fInit = false; 80 84 } 81 85 … … 118 122 RTR0MemObjFree(hMemObj, true); 119 123 124 if (pGVM->dbgfr0.s.paBpLocPortIoR0) 125 { 126 Assert(pGVM->dbgfr0.s.hMemObjBpLocPortIo != NIL_RTR0MEMOBJ); 127 Assert(pGVM->dbgfr0.s.hMapObjBpLocPortIo != NIL_RTR0MEMOBJ); 128 129 hMemObj = pGVM->dbgfr0.s.hMapObjBpLocPortIo; 130 pGVM->dbgfr0.s.hMapObjBpLocPortIo = NIL_RTR0MEMOBJ; 131 RTR0MemObjFree(hMemObj, true); 132 133 hMemObj = pGVM->dbgfr0.s.hMemObjBpLocPortIo; 134 pGVM->dbgfr0.s.hMemObjBpLocPortIo = NIL_RTR0MEMOBJ; 135 pGVM->dbgfr0.s.paBpLocPortIoR0 = NULL; 136 RTR0MemObjFree(hMemObj, true); 137 } 138 120 139 for (uint32_t i = 0; i < RT_ELEMENTS(pGVM->dbgfr0.s.aBpChunks); i++) 121 140 { … … 167 186 Assert(!pGVM->dbgfr0.s.paBpLocL1R0); 168 187 188 Assert(pGVM->dbgfr0.s.hMemObjBpLocPortIo == NIL_RTR0MEMOBJ); 189 Assert(!pGVM->dbgfr0.s.paBpLocPortIoR0); 190 169 191 for (uint32_t i = 0; i < RT_ELEMENTS(pGVM->dbgfr0.s.aBpChunks); i++) 170 192 { … … 226 248 *ppaBpLocL1R3 = RTR0MemObjAddressR3(hMapObj); 227 249 pGVM->dbgfr0.s.fInit = true; 250 return rc; 251 } 252 253 RTR0MemObjFree(hMemObj, true); 254 return rc; 255 } 256 257 258 /** 259 * Worker for DBGFR0BpPortIoInitReqHandler() that does the actual initialization. 260 * 261 * @returns VBox status code. 262 * @param pGVM The global (ring-0) VM structure. 263 * @param ppaBpLocPortIoR3 Where to return the ring-3 L1 lookup table address on success. 264 * @thread EMT(0) 265 */ 266 static int dbgfR0BpPortIoInitWorker(PGVM pGVM, R3PTRTYPE(volatile uint32_t *) *ppaBpLocPortIoR3) 267 { 268 /* 269 * Figure out how much memory we need for the I/O port breakpoint lookup table and allocate it. 270 */ 271 uint32_t const cbPortIoLoc = RT_ALIGN_32(UINT16_MAX * sizeof(uint32_t), PAGE_SIZE); 272 273 RTR0MEMOBJ hMemObj; 274 int rc = RTR0MemObjAllocPage(&hMemObj, cbPortIoLoc, false /*fExecutable*/); 275 if (RT_FAILURE(rc)) 276 return rc; 277 RT_BZERO(RTR0MemObjAddress(hMemObj), cbPortIoLoc); 278 279 /* Map it. */ 280 RTR0MEMOBJ hMapObj; 281 rc = RTR0MemObjMapUserEx(&hMapObj, hMemObj, (RTR3PTR)-1, 0, RTMEM_PROT_READ | RTMEM_PROT_WRITE, RTR0ProcHandleSelf(), 282 0 /*offSub*/, cbPortIoLoc); 283 if (RT_SUCCESS(rc)) 284 { 285 pGVM->dbgfr0.s.hMemObjBpLocPortIo = hMemObj; 286 pGVM->dbgfr0.s.hMapObjBpLocPortIo = hMapObj; 287 pGVM->dbgfr0.s.paBpLocPortIoR0 = (volatile uint32_t *)RTR0MemObjAddress(hMemObj); 288 289 /* 290 * We're done. 291 */ 292 *ppaBpLocPortIoR3 = RTR0MemObjAddressR3(hMapObj); 228 293 return rc; 229 294 } … … 412 477 413 478 /** 414 * Used by ring-3 DBGF to initialize the breakpoint owner table foroperation.479 * Used by ring-3 DBGF to initialize the breakpoint manager for port I/O breakpoint operation. 415 480 * 416 481 * @returns VBox status code. … … 419 484 * @thread EMT(0) 420 485 */ 421 VMMR0_INT_DECL(int) DBGFR0Bp OwnerInitReqHandler(PGVM pGVM, PDBGFBPOWNERINITREQ pReq)422 { 423 LogFlow(("DBGFR0Bp OwnerInitReqHandler:\n"));486 VMMR0_INT_DECL(int) DBGFR0BpPortIoInitReqHandler(PGVM pGVM, PDBGFBPINITREQ pReq) 487 { 488 LogFlow(("DBGFR0BpPortIoInitReqHandler:\n")); 424 489 425 490 /* … … 431 496 AssertRCReturn(rc, rc); 432 497 433 AssertReturn(!pGVM->dbgfr0.s.paBpOwnersR0, VERR_WRONG_ORDER); 434 435 return dbgfR0BpOwnerInitWorker(pGVM, &pReq->paBpOwnerR3); 436 } 437 438 439 /** 440 * Used by ring-3 DBGF to allocate a given chunk in the global breakpoint table. 498 AssertReturn(!pGVM->dbgfr0.s.fInit, VERR_WRONG_ORDER); 499 AssertReturn(!pGVM->dbgfr0.s.paBpLocPortIoR0, VERR_WRONG_ORDER); 500 501 return dbgfR0BpPortIoInitWorker(pGVM, &pReq->paBpLocL1R3); 502 } 503 504 505 /** 506 * Used by ring-3 DBGF to initialize the breakpoint owner table for operation. 441 507 * 442 508 * @returns VBox status code. … … 445 511 * @thread EMT(0) 446 512 */ 513 VMMR0_INT_DECL(int) DBGFR0BpOwnerInitReqHandler(PGVM pGVM, PDBGFBPOWNERINITREQ pReq) 514 { 515 LogFlow(("DBGFR0BpOwnerInitReqHandler:\n")); 516 517 /* 518 * Validate the request. 519 */ 520 AssertReturn(pReq->Hdr.cbReq == sizeof(*pReq), VERR_INVALID_PARAMETER); 521 522 int rc = GVMMR0ValidateGVMandEMT(pGVM, 0); 523 AssertRCReturn(rc, rc); 524 525 AssertReturn(!pGVM->dbgfr0.s.paBpOwnersR0, VERR_WRONG_ORDER); 526 527 return dbgfR0BpOwnerInitWorker(pGVM, &pReq->paBpOwnerR3); 528 } 529 530 531 /** 532 * Used by ring-3 DBGF to allocate a given chunk in the global breakpoint table. 533 * 534 * @returns VBox status code. 535 * @param pGVM The global (ring-0) VM structure. 536 * @param pReq Pointer to the request buffer. 537 * @thread EMT(0) 538 */ 447 539 VMMR0_INT_DECL(int) DBGFR0BpChunkAllocReqHandler(PGVM pGVM, PDBGFBPCHUNKALLOCREQ pReq) 448 540 { -
trunk/src/VBox/VMM/VMMR0/VMMR0.cpp
r88347 r89912 2379 2379 } 2380 2380 2381 case VMMR0_DO_DBGF_BP_PORTIO_INIT: 2382 { 2383 if (!pReqHdr || u64Arg || idCpu != 0) 2384 return VERR_INVALID_PARAMETER; 2385 rc = DBGFR0BpPortIoInitReqHandler(pGVM, (PDBGFBPINITREQ)pReqHdr); 2386 VMM_CHECK_SMAP_CHECK2(pGVM, RT_NOTHING); 2387 break; 2388 } 2389 2390 2381 2391 /* 2382 2392 * TM requests. -
trunk/src/VBox/VMM/VMMR3/DBGFR3Bp.cpp
r87832 r89912 113 113 * Each entry in the L2 table is 16 bytes big and densly packed to avoid excessive memory usage. 114 114 * 115 * @section sec_dbgf_bp_ioport Handling I/O port breakpoints 116 * 117 * Because of the limited amount of I/O ports being available (65536) a single table with 65536 entries, 118 * each 4 byte big will be allocated. This amounts to 256KiB of memory being used additionally as soon as 119 * an I/O breakpoint is enabled. The entries contain the breakpoint handle directly allowing only one breakpoint 120 * per port right now, which is something we accept as a limitation right now to keep things relatively simple. 121 * When there is at least one I/O breakpoint active IOM will be notified and it will afterwards call the DBGF API 122 * whenever the guest does an I/O port access to decide whether a breakpoint was hit. This keeps the overhead small 123 * when there is no I/O port breakpoint enabled. 115 124 * 116 125 * @section sec_dbgf_bp_note Random thoughts and notes for the implementation … … 217 226 } 218 227 219 //pUVM->dbgf.s.paBpLocL1R3 = NULL; 228 //pUVM->dbgf.s.paBpLocL1R3 = NULL; 229 //pUVM->dbgf.s.paBpLocPortIoR3 = NULL; 220 230 pUVM->dbgf.s.hMtxBpL2Wr = NIL_RTSEMFASTMUTEX; 221 231 return RTSemFastMutexCreate(&pUVM->dbgf.s.hMtxBpL2Wr); … … 324 334 /* Gather all EMTs and call into ring-0 to initialize the breakpoint manager. */ 325 335 return VMMR3EmtRendezvous(pUVM->pVM, VMMEMTRENDEZVOUS_FLAGS_TYPE_ALL_AT_ONCE, dbgfR3BpInitEmtWorker, NULL /*pvUser*/); 336 } 337 338 339 /** 340 * @callback_method_impl{FNVMMEMTRENDEZVOUS} 341 */ 342 static DECLCALLBACK(VBOXSTRICTRC) dbgfR3BpPortIoInitEmtWorker(PVM pVM, PVMCPU pVCpu, void *pvUser) 343 { 344 RT_NOREF(pvUser); 345 346 VMCPU_ASSERT_EMT(pVCpu); 347 VM_ASSERT_VALID_EXT_RETURN(pVM, VERR_INVALID_VM_HANDLE); 348 349 /* 350 * The initialization will be done on EMT(0). It is possible that multiple 351 * initialization attempts are done because dbgfR3BpPortIoEnsureInit() can be called 352 * from racing non EMT threads when trying to set a breakpoint for the first time. 353 * Just fake success if the L1 is already present which means that a previous rendezvous 354 * successfully initialized the breakpoint manager. 355 */ 356 PUVM pUVM = pVM->pUVM; 357 if ( pVCpu->idCpu == 0 358 && !pUVM->dbgf.s.paBpLocPortIoR3) 359 { 360 DBGFBPINITREQ Req; 361 Req.Hdr.u32Magic = SUPVMMR0REQHDR_MAGIC; 362 Req.Hdr.cbReq = sizeof(Req); 363 Req.paBpLocL1R3 = NULL; 364 int rc = VMMR3CallR0Emt(pVM, pVCpu, VMMR0_DO_DBGF_BP_PORTIO_INIT, 0 /*u64Arg*/, &Req.Hdr); 365 AssertLogRelMsgRCReturn(rc, ("VMMR0_DO_DBGF_BP_PORTIO_INIT failed: %Rrc\n", rc), rc); 366 pUVM->dbgf.s.paBpLocPortIoR3 = Req.paBpLocL1R3; 367 } 368 369 return VINF_SUCCESS; 370 } 371 372 373 /** 374 * Ensures that the breakpoint manager is initialized to handle I/O port breakpoint. 375 * 376 * @returns VBox status code. 377 * @param pUVM The user mode VM handle. 378 * 379 * @thread Any thread. 380 */ 381 static int dbgfR3BpPortIoEnsureInit(PUVM pUVM) 382 { 383 /* If the L1 lookup table is allocated initialization succeeded before. */ 384 if (RT_LIKELY(pUVM->dbgf.s.paBpLocPortIoR3)) 385 return VINF_SUCCESS; 386 387 /* Ensure that the breakpoint manager is initialized. */ 388 int rc = dbgfR3BpEnsureInit(pUVM); 389 if (RT_FAILURE(rc)) 390 return rc; 391 392 /* Gather all EMTs and call into ring-0 to initialize the breakpoint manager. */ 393 return VMMR3EmtRendezvous(pUVM->pVM, VMMEMTRENDEZVOUS_FLAGS_TYPE_ALL_AT_ONCE, dbgfR3BpPortIoInitEmtWorker, NULL /*pvUser*/); 326 394 } 327 395 … … 1358 1426 1359 1427 /** 1428 * Adds the given port I/O breakpoint to the appropriate lookup tables. 1429 * 1430 * @returns VBox status code. 1431 * @param pUVM The user mode VM handle. 1432 * @param hBp The breakpoint handle to add. 1433 * @param pBp The internal breakpoint state. 1434 */ 1435 static int dbgfR3BpPortIoAdd(PUVM pUVM, DBGFBP hBp, PDBGFBPINT pBp) 1436 { 1437 AssertReturn(DBGF_BP_PUB_GET_TYPE(&pBp->Pub) == DBGFBPTYPE_PORT_IO, VERR_DBGF_BP_IPE_3); 1438 1439 uint16_t uPortExcl = pBp->Pub.u.PortIo.uPort + pBp->Pub.u.PortIo.cPorts; 1440 uint32_t u32Entry = DBGF_BP_INT3_L1_ENTRY_CREATE_BP_HND(hBp); 1441 for (uint16_t idxPort = pBp->Pub.u.PortIo.uPort; idxPort < uPortExcl; idxPort++) 1442 { 1443 bool fXchg = ASMAtomicCmpXchgU32(&pUVM->dbgf.s.paBpLocPortIoR3[idxPort], u32Entry, DBGF_BP_INT3_L1_ENTRY_TYPE_NULL); 1444 if (!fXchg) 1445 { 1446 /* Something raced us, so roll back the other registrations. */ 1447 while (idxPort > pBp->Pub.u.PortIo.uPort) 1448 { 1449 fXchg = ASMAtomicCmpXchgU32(&pUVM->dbgf.s.paBpLocPortIoR3[idxPort], DBGF_BP_INT3_L1_ENTRY_TYPE_NULL, u32Entry); 1450 Assert(fXchg); RT_NOREF(fXchg); 1451 } 1452 1453 return VERR_DBGF_BP_INT3_ADD_TRIES_REACHED; /** @todo New status code */ 1454 } 1455 } 1456 1457 return VINF_SUCCESS; 1458 } 1459 1460 1461 /** 1360 1462 * Get a breakpoint give by address. 1361 1463 * … … 1438 1540 AssertMsgFailed(("enmType=%d\n", enmType)); 1439 1541 break; 1542 } 1543 1544 if ( hBp != NIL_DBGFBP 1545 && ppBp) 1546 *ppBp = dbgfR3BpGetByHnd(pUVM, hBp); 1547 return hBp; 1548 } 1549 1550 1551 /** 1552 * Get a port I/O breakpoint given by the range. 1553 * 1554 * @returns The breakpoint handle on success or NIL_DBGF if not found. 1555 * @param pUVM The user mode VM handle. 1556 * @param uPort First port in the range. 1557 * @param cPorts Number of ports in the range. 1558 * @param ppBp Where to store the pointer to the internal breakpoint state on success, optional. 1559 */ 1560 static DBGFBP dbgfR3BpPortIoGetByRange(PUVM pUVM, RTIOPORT uPort, RTIOPORT cPorts, PDBGFBPINT *ppBp) 1561 { 1562 DBGFBP hBp = NIL_DBGFBP; 1563 1564 for (RTIOPORT idxPort = uPort; idxPort < uPort + cPorts; idxPort) 1565 { 1566 const uint32_t u32Entry = ASMAtomicReadU32(&pUVM->dbgf.s.CTX_SUFF(paBpLocPortIo)[idxPort]); 1567 if (u32Entry != DBGF_BP_INT3_L1_ENTRY_TYPE_NULL) 1568 { 1569 hBp = DBGF_BP_INT3_L1_ENTRY_GET_BP_HND(u32Entry); 1570 break; 1571 } 1440 1572 } 1441 1573 … … 1517 1649 */ 1518 1650 return VMMR3EmtRendezvous(pUVM->pVM, VMMEMTRENDEZVOUS_FLAGS_TYPE_ALL_AT_ONCE, dbgfR3BpInt3RemoveEmtWorker, (void *)(uintptr_t)hBp); 1651 } 1652 1653 1654 /** 1655 * @callback_method_impl{FNVMMEMTRENDEZVOUS} 1656 */ 1657 static DECLCALLBACK(VBOXSTRICTRC) dbgfR3BpPortIoRemoveEmtWorker(PVM pVM, PVMCPU pVCpu, void *pvUser) 1658 { 1659 DBGFBP hBp = (DBGFBP)(uintptr_t)pvUser; 1660 1661 VMCPU_ASSERT_EMT(pVCpu); 1662 VM_ASSERT_VALID_EXT_RETURN(pVM, VERR_INVALID_VM_HANDLE); 1663 1664 PUVM pUVM = pVM->pUVM; 1665 PDBGFBPINT pBp = dbgfR3BpGetByHnd(pUVM, hBp); 1666 AssertPtrReturn(pBp, VERR_DBGF_BP_IPE_8); 1667 1668 int rc = VINF_SUCCESS; 1669 if (pVCpu->idCpu == 0) 1670 { 1671 /* 1672 * Remove the whole range, there shouldn't be any other breakpoint configured for this range as this is not 1673 * allowed right now. 1674 */ 1675 uint16_t uPortExcl = pBp->Pub.u.PortIo.uPort + pBp->Pub.u.PortIo.cPorts; 1676 for (uint16_t idxPort = pBp->Pub.u.PortIo.uPort; idxPort < uPortExcl; idxPort++) 1677 { 1678 uint32_t u32Entry = ASMAtomicReadU32(&pUVM->dbgf.s.paBpLocPortIoR3[idxPort]); 1679 AssertReturn(u32Entry != DBGF_BP_INT3_L1_ENTRY_TYPE_NULL, VERR_DBGF_BP_IPE_6); 1680 1681 uint8_t u8Type = DBGF_BP_INT3_L1_ENTRY_GET_TYPE(u32Entry); 1682 AssertReturn(u8Type == DBGF_BP_INT3_L1_ENTRY_TYPE_BP_HND, VERR_DBGF_BP_IPE_7); 1683 1684 bool fXchg = ASMAtomicCmpXchgU32(&pUVM->dbgf.s.paBpLocL1R3[idxPort], DBGF_BP_INT3_L1_ENTRY_TYPE_NULL, u32Entry); 1685 Assert(fXchg); RT_NOREF(fXchg); 1686 } 1687 } 1688 1689 return rc; 1690 } 1691 1692 1693 /** 1694 * Removes the given port I/O breakpoint from all lookup tables. 1695 * 1696 * @returns VBox status code. 1697 * @param pUVM The user mode VM handle. 1698 * @param hBp The breakpoint handle to remove. 1699 * @param pBp The internal breakpoint state. 1700 */ 1701 static int dbgfR3BpPortIoRemove(PUVM pUVM, DBGFBP hBp, PDBGFBPINT pBp) 1702 { 1703 AssertReturn(DBGF_BP_PUB_GET_TYPE(&pBp->Pub) == DBGFBPTYPE_PORT_IO, VERR_DBGF_BP_IPE_3); 1704 1705 /* 1706 * This has to be done by an EMT rendezvous in order to not have an EMT accessing 1707 * the breakpoint while it is removed. 1708 */ 1709 return VMMR3EmtRendezvous(pUVM->pVM, VMMEMTRENDEZVOUS_FLAGS_TYPE_ALL_AT_ONCE, dbgfR3BpPortIoRemoveEmtWorker, (void *)(uintptr_t)hBp); 1519 1710 } 1520 1711 … … 2063 2254 { 2064 2255 return DBGFR3BpSetPortIoEx(pUVM, NIL_DBGFBPOWNER, NULL /*pvUser*/, uPort, cPorts, 2065 fAccess, iHitTrigger, iHitDisable, phBp);2256 DBGF_BP_F_DEFAULT, fAccess, iHitTrigger, iHitDisable, phBp); 2066 2257 } 2067 2258 … … 2077 2268 * @param cPorts The number of I/O ports, see DBGFBPIOACCESS_XXX. 2078 2269 * @param fAccess The access we want to break on. 2270 * @param fFlags Combination of DBGF_BP_F_XXX. 2079 2271 * @param iHitTrigger The hit count at which the breakpoint start 2080 2272 * triggering. Use 0 (or 1) if it's gonna trigger at … … 2088 2280 VMMR3DECL(int) DBGFR3BpSetPortIoEx(PUVM pUVM, DBGFBPOWNER hOwner, void *pvUser, 2089 2281 RTIOPORT uPort, RTIOPORT cPorts, uint32_t fAccess, 2090 uint 64_t iHitTrigger, uint64_t iHitDisable, PDBGFBP phBp)2282 uint32_t fFlags, uint64_t iHitTrigger, uint64_t iHitDisable, PDBGFBP phBp) 2091 2283 { 2092 2284 UVM_ASSERT_VALID_EXT_RETURN(pUVM, VERR_INVALID_VM_HANDLE); … … 2099 2291 AssertReturn((RTIOPORT)(uPort + cPorts) < uPort, VERR_OUT_OF_RANGE); 2100 2292 2101 int rc = dbgfR3Bp EnsureInit(pUVM);2293 int rc = dbgfR3BpPortIoEnsureInit(pUVM); 2102 2294 AssertRCReturn(rc, rc); 2103 2295 2104 return VERR_NOT_IMPLEMENTED; 2296 PDBGFBPINT pBp = NULL; 2297 DBGFBP hBp = dbgfR3BpPortIoGetByRange(pUVM, uPort, cPorts, &pBp); 2298 if ( hBp != NIL_DBGFBP 2299 && pBp->Pub.u.PortIo.uPort == uPort 2300 && pBp->Pub.u.PortIo.cPorts == cPorts 2301 && pBp->Pub.u.PortIo.fAccess == fAccess) 2302 { 2303 rc = VINF_SUCCESS; 2304 if (!DBGF_BP_PUB_IS_ENABLED(&pBp->Pub)) 2305 rc = dbgfR3BpArm(pUVM, hBp, pBp); 2306 if (RT_SUCCESS(rc)) 2307 { 2308 rc = VINF_DBGF_BP_ALREADY_EXIST; 2309 if (phBp) 2310 *phBp = hBp; 2311 } 2312 return rc; 2313 } 2314 2315 rc = dbgfR3BpAlloc(pUVM, hOwner, pvUser, DBGFBPTYPE_PORT_IO, fFlags, iHitTrigger, iHitDisable, &hBp, &pBp); 2316 if (RT_SUCCESS(rc)) 2317 { 2318 pBp->Pub.u.PortIo.uPort = uPort; 2319 pBp->Pub.u.PortIo.cPorts = cPorts; 2320 pBp->Pub.u.PortIo.fAccess = fAccess; 2321 2322 /* Add the breakpoint to the lookup tables. */ 2323 rc = dbgfR3BpPortIoAdd(pUVM, hBp, pBp); 2324 if (RT_SUCCESS(rc)) 2325 { 2326 /* Enable the breakpoint if requested. */ 2327 if (fFlags & DBGF_BP_F_ENABLED) 2328 rc = dbgfR3BpArm(pUVM, hBp, pBp); 2329 if (RT_SUCCESS(rc)) 2330 { 2331 *phBp = hBp; 2332 return VINF_SUCCESS; 2333 } 2334 2335 int rc2 = dbgfR3BpPortIoRemove(pUVM, hBp, pBp); AssertRC(rc2); 2336 } 2337 2338 dbgfR3BpFree(pUVM, hBp, pBp); 2339 } 2340 2341 return rc; 2105 2342 } 2106 2343 … … 2205 2442 { 2206 2443 int rc = dbgfR3BpInt3Remove(pUVM, hBp, pBp); 2444 AssertRC(rc); 2445 break; 2446 } 2447 case DBGFBPTYPE_PORT_IO: 2448 { 2449 int rc = dbgfR3BpPortIoRemove(pUVM, hBp, pBp); 2207 2450 AssertRC(rc); 2208 2451 break; -
trunk/src/VBox/VMM/include/DBGFInternal.h
r87594 r89912 1288 1288 /** The L1 lookup tables mapping object. */ 1289 1289 RTR0MEMOBJ hMapObjBpLocL1; 1290 /** The I/O port breakpoint lookup tables memory object. */ 1291 RTR0MEMOBJ hMemObjBpLocPortIo; 1292 /** The I/O port breakpoint lookup tables mapping object. */ 1293 RTR0MEMOBJ hMapObjBpLocPortIo; 1290 1294 /** Base pointer to the L1 locator table. */ 1291 1295 R0PTRTYPE(volatile uint32_t *) paBpLocL1R0; 1296 /** Base pointer to the L1 locator table. */ 1297 R0PTRTYPE(volatile uint32_t *) paBpLocPortIoR0; 1292 1298 /** Flag whether the breakpoint manager was initialized (on demand). */ 1293 1299 bool fInit; … … 1380 1386 /** Base pointer to the L1 locator table. */ 1381 1387 R3PTRTYPE(volatile uint32_t *) paBpLocL1R3; 1388 /** Base pointer to the Port I/O breakpoint locator table. */ 1389 R3PTRTYPE(volatile uint32_t *) paBpLocPortIoR3; 1382 1390 /** Fast mutex protecting the L2 table from concurrent write accesses (EMTs 1383 1391 * can still do read accesses without holding it while traversing the trees). */
Note:
See TracChangeset
for help on using the changeset viewer.