Changeset 59084 in vbox for trunk/src/VBox/VMM/VMMR3
- Timestamp:
- Dec 11, 2015 12:43:04 AM (9 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMR3/DBGF.cpp
r59074 r59084 516 516 517 517 518 /** 519 * Processes a pending event on the current CPU. 520 * 521 * This is called by EM in response to VINF_EM_DBG_EVENT. 522 * 523 * @returns Strict VBox status code. 524 * @param pVM The cross context VM structure. 525 * @param pVCpu The cross context per CPU structure. 526 * 527 * @thread EMT(pVCpu) 528 */ 518 529 VMMR3_INT_DECL(VBOXSTRICTRC) DBGFR3EventHandlePending(PVM pVM, PVMCPU pVCpu) 519 530 { 520 return VINF_SUCCESS; 531 VMCPU_ASSERT_EMT(pVCpu); 532 533 /* 534 * Check that we've got an event first. 535 */ 536 AssertReturn(pVCpu->dbgf.s.cEvents > 0, VINF_SUCCESS); 537 AssertReturn(pVCpu->dbgf.s.aEvents[pVCpu->dbgf.s.cEvents - 1].enmState == DBGFEVENTSTATE_CURRENT, VINF_SUCCESS); 538 PDBGFEVENT pEvent = &pVCpu->dbgf.s.aEvents[pVCpu->dbgf.s.cEvents - 1].Event; 539 540 /* 541 * Make sure we've got a debugger and is allowed to speak to it. 542 */ 543 int rc = dbgfR3EventPrologue(pVM, pEvent->enmType); 544 if (RT_FAILURE(rc)) 545 return rc; 546 547 /** @todo SMP + debugger speaker logic */ 548 /* 549 * Copy the event over and mark it as ignore. 550 */ 551 pVM->dbgf.s.DbgEvent = *pEvent; 552 pVCpu->dbgf.s.aEvents[pVCpu->dbgf.s.cEvents - 1].enmState = DBGFEVENTSTATE_IGNORE; 553 return dbgfR3SendEvent(pVM); 521 554 } 522 555 … … 1224 1257 1225 1258 1226 /** 1227 * @callback_method_impl{FNVMMEMTRENDEZVOUS} 1228 */ 1229 static DECLCALLBACK(VBOXSTRICTRC) dbgfR3EventConfigNotifyAllCpus(PVM pVM, PVMCPU pVCpu, void *pvUser) 1230 { 1231 if (pvUser /*fIsHmEnabled*/) 1259 1260 /** 1261 * dbgfR3EventConfigEx argument packet. 1262 */ 1263 typedef struct DBGFR3EVENTCONFIGEXARGS 1264 { 1265 PCDBGFEVENTCONFIG paConfigs; 1266 size_t cConfigs; 1267 int rc; 1268 } DBGFR3EVENTCONFIGEXARGS; 1269 /** Pointer to a dbgfR3EventConfigEx argument packet. */ 1270 typedef DBGFR3EVENTCONFIGEXARGS *PDBGFR3EVENTCONFIGEXARGS; 1271 1272 1273 /** 1274 * @callback_method_impl{FNVMMEMTRENDEZVOUS, Worker for DBGFR3EventConfigEx.} 1275 */ 1276 static DECLCALLBACK(VBOXSTRICTRC) dbgfR3EventConfigEx(PVM pVM, PVMCPU pVCpu, void *pvUser) 1277 { 1278 if (pVCpu->idCpu == 0) 1279 { 1280 PDBGFR3EVENTCONFIGEXARGS pArgs = (PDBGFR3EVENTCONFIGEXARGS)pvUser; 1281 DBGFEVENTCONFIG volatile const *paConfigs = pArgs->paConfigs; 1282 size_t cConfigs = pArgs->cConfigs; 1283 1284 /* 1285 * Apply the changes. 1286 */ 1287 unsigned cChanges = 0; 1288 for (uint32_t i = 0; i < cConfigs; i++) 1289 { 1290 DBGFEVENTTYPE enmType = paConfigs[i].enmType; 1291 AssertReturn(enmType >= DBGFEVENT_FIRST_SELECTABLE && enmType < DBGFEVENT_END, VERR_INVALID_PARAMETER); 1292 if (paConfigs[i].fEnabled) 1293 cChanges += ASMAtomicBitTestAndSet(&pVM->dbgf.s.bmSelectedEvents, enmType) == false; 1294 else 1295 cChanges += ASMAtomicBitTestAndClear(&pVM->dbgf.s.bmSelectedEvents, enmType) == true; 1296 } 1297 1298 /* 1299 * Inform HM about changes. 1300 */ 1301 if (cChanges > 0 && HMIsEnabled(pVM)) 1302 { 1303 HMR3NotifyDebugEventChanged(pVM); 1304 HMR3NotifyDebugEventChangedPerCpu(pVM, pVCpu); 1305 } 1306 } 1307 else if (HMIsEnabled(pVM)) 1232 1308 HMR3NotifyDebugEventChangedPerCpu(pVM, pVCpu); 1309 1233 1310 return VINF_SUCCESS; 1234 1311 } … … 1236 1313 1237 1314 /** 1238 * Worker for DBGFR3EventConfigEx.1239 * 1240 * @returns VBox status code. Will not return VBOX_INTERRUPTED.1315 * Configures (enables/disables) multiple selectable debug events. 1316 * 1317 * @returns VBox status code. 1241 1318 * @param pUVM The user mode VM handle. 1242 1319 * @param paConfigs The event to configure and their new state. 1243 1320 * @param cConfigs Number of entries in @a paConfigs. 1244 1321 */ 1245 static DECLCALLBACK(int) dbgfR3EventConfigEx(PUVM pUVM, DBGFEVENTCONFIG volatile const *paConfigs, size_t cConfigs) 1246 { 1322 VMMR3DECL(int) DBGFR3EventConfigEx(PUVM pUVM, PCDBGFEVENTCONFIG paConfigs, size_t cConfigs) 1323 { 1324 /* 1325 * Validate input. 1326 */ 1327 size_t i = cConfigs; 1328 while (i-- > 0) 1329 { 1330 AssertReturn(paConfigs[i].enmType >= DBGFEVENT_FIRST_SELECTABLE, VERR_INVALID_PARAMETER); 1331 AssertReturn(paConfigs[i].enmType < DBGFEVENT_END, VERR_INVALID_PARAMETER); 1332 } 1333 UVM_ASSERT_VALID_EXT_RETURN(pUVM, VERR_INVALID_VM_HANDLE); 1247 1334 PVM pVM = pUVM->pVM; 1248 1335 VM_ASSERT_VALID_EXT_RETURN(pVM, VERR_INVALID_VM_HANDLE); 1249 1336 1250 1337 /* 1251 * Apply the changes. 1252 */ 1253 unsigned cChanges = 0; 1254 for (uint32_t i = 0; i < cConfigs; i++) 1255 { 1256 DBGFEVENTTYPE enmType = paConfigs[i].enmType; 1257 AssertReturn(enmType >= DBGFEVENT_FIRST_SELECTABLE && enmType < DBGFEVENT_END, VERR_INVALID_PARAMETER); 1258 if (paConfigs[i].fEnabled) 1259 cChanges += ASMAtomicBitTestAndSet(&pVM->dbgf.s.bmSelectedEvents, enmType) == false; 1260 else 1261 cChanges += ASMAtomicBitTestAndClear(&pVM->dbgf.s.bmSelectedEvents, enmType) == true; 1262 } 1263 1264 /* 1265 * Inform HM about changes. In an SMP setup, interrupt execution on the 1266 * other CPUs so their execution loop can be reselected. 1267 */ 1268 int rc = VINF_SUCCESS; 1269 if (cChanges > 0) 1270 { 1271 bool const fIsHmEnabled = HMIsEnabled(pVM); 1272 if (fIsHmEnabled) 1273 HMR3NotifyDebugEventChanged(pVM); 1274 if (pVM->cCpus > 1 || fIsHmEnabled) 1275 rc = VMMR3EmtRendezvous(pVM, VMMEMTRENDEZVOUS_FLAGS_TYPE_ALL_AT_ONCE, dbgfR3EventConfigNotifyAllCpus, 1276 (void *)(uintptr_t)fIsHmEnabled); 1277 } 1338 * Apply the changes in EMT(0) and rendezvous with the other CPUs so they 1339 * can sync their data and execution with new debug state. 1340 */ 1341 DBGFR3EVENTCONFIGEXARGS Args = { paConfigs, cConfigs, VINF_SUCCESS }; 1342 int rc = VMMR3EmtRendezvous(pVM, VMMEMTRENDEZVOUS_FLAGS_TYPE_ASCENDING, dbgfR3EventConfigEx, &Args); 1343 if (RT_SUCCESS(rc)) 1344 rc = Args.rc; 1278 1345 return rc; 1279 }1280 1281 1282 /**1283 * Configures (enables/disables) multiple selectable debug events.1284 *1285 * @returns VBox status code.1286 * @param pUVM The user mode VM handle.1287 * @param paConfigs The event to configure and their new state.1288 * @param cConfigs Number of entries in @a paConfigs.1289 */1290 VMMR3DECL(int) DBGFR3EventConfigEx(PUVM pUVM, PCDBGFEVENTCONFIG paConfigs, size_t cConfigs)1291 {1292 /*1293 * Validate input.1294 */1295 UVM_ASSERT_VALID_EXT_RETURN(pUVM, VERR_INVALID_VM_HANDLE);1296 size_t i = cConfigs;1297 while (i-- > 0)1298 {1299 AssertReturn(paConfigs[i].enmType >= DBGFEVENT_FIRST_SELECTABLE, VERR_INVALID_PARAMETER);1300 AssertReturn(paConfigs[i].enmType < DBGFEVENT_END, VERR_INVALID_PARAMETER);1301 }1302 1303 /*1304 * Apply the changes in EMT(0).1305 */1306 return VMR3ReqPriorityCallWaitU(pUVM, VMCPUID_ANY, (PFNRT)dbgfR3EventConfigEx, 3, pUVM, paConfigs, cConfigs);1307 1346 } 1308 1347 … … 1371 1410 * Validate input. 1372 1411 */ 1373 UVM_ASSERT_VALID_EXT_RETURN(pUVM, false);1412 UVM_ASSERT_VALID_EXT_RETURN(pUVM, VERR_INVALID_VM_HANDLE); 1374 1413 PVM pVM = pUVM->pVM; 1375 VM_ASSERT_VALID_EXT_RETURN(pVM, false);1414 VM_ASSERT_VALID_EXT_RETURN(pVM, VERR_INVALID_VM_HANDLE); 1376 1415 1377 1416 for (size_t i = 0; i < cConfigs; i++) … … 1392 1431 1393 1432 /** 1394 * Worker for DBGFR3InterruptConfigEx. 1395 * 1396 * @returns VBox status code. Will not return VBOX_INTERRUPTED. 1397 * @param pUVM The user mode VM handle. 1398 * @param paConfigs The event to configure and their new state. 1399 * @param cConfigs Number of entries in @a paConfigs. 1400 */ 1401 static DECLCALLBACK(int) dbgfR3InterruptConfigEx(PUVM pUVM, PCDBGFINTERRUPTCONFIG paConfigs, size_t cConfigs) 1402 { 1403 PVM pVM = pUVM->pVM; 1404 VM_ASSERT_VALID_EXT_RETURN(pVM, VERR_INVALID_VM_HANDLE); 1405 1406 /* 1407 * Apply the changes. 1408 */ 1409 bool fChanged = false; 1410 bool fThis; 1411 for (uint32_t i = 0; i < cConfigs; i++) 1412 { 1433 * dbgfR3InterruptConfigEx argument packet. 1434 */ 1435 typedef struct DBGFR3INTERRUPTCONFIGEXARGS 1436 { 1437 PCDBGFINTERRUPTCONFIG paConfigs; 1438 size_t cConfigs; 1439 int rc; 1440 } DBGFR3INTERRUPTCONFIGEXARGS; 1441 /** Pointer to a dbgfR3InterruptConfigEx argument packet. */ 1442 typedef DBGFR3INTERRUPTCONFIGEXARGS *PDBGFR3INTERRUPTCONFIGEXARGS; 1443 1444 /** 1445 * @callback_method_impl{FNVMMEMTRENDEZVOUS, 1446 * Worker for DBGFR3InterruptConfigEx.} 1447 */ 1448 static DECLCALLBACK(VBOXSTRICTRC) dbgfR3InterruptConfigEx(PVM pVM, PVMCPU pVCpu, void *pvUser) 1449 { 1450 if (pVCpu->idCpu == 0) 1451 { 1452 PDBGFR3INTERRUPTCONFIGEXARGS pArgs = (PDBGFR3INTERRUPTCONFIGEXARGS)pvUser; 1453 PCDBGFINTERRUPTCONFIG paConfigs = pArgs->paConfigs; 1454 size_t cConfigs = pArgs->cConfigs; 1455 1413 1456 /* 1414 * Hardware interrupts.1457 * Apply the changes. 1415 1458 */ 1416 if (paConfigs[i].enmHardState == DBGFINTERRUPTSTATE_ENABLED) 1417 { 1418 fChanged |= fThis = ASMAtomicBitTestAndSet(&pVM->dbgf.s.bmHardIntBreakpoints, paConfigs[i].iInterrupt) == false; 1419 if (fThis) 1459 bool fChanged = false; 1460 bool fThis; 1461 for (uint32_t i = 0; i < cConfigs; i++) 1462 { 1463 /* 1464 * Hardware interrupts. 1465 */ 1466 if (paConfigs[i].enmHardState == DBGFINTERRUPTSTATE_ENABLED) 1420 1467 { 1421 Assert(pVM->dbgf.s.cHardIntBreakpoints < 256); 1422 pVM->dbgf.s.cHardIntBreakpoints++; 1468 fChanged |= fThis = ASMAtomicBitTestAndSet(&pVM->dbgf.s.bmHardIntBreakpoints, paConfigs[i].iInterrupt) == false; 1469 if (fThis) 1470 { 1471 Assert(pVM->dbgf.s.cHardIntBreakpoints < 256); 1472 pVM->dbgf.s.cHardIntBreakpoints++; 1473 } 1423 1474 } 1424 } 1425 else if (paConfigs[i].enmHardState == DBGFINTERRUPTSTATE_DISABLED) 1426 { 1427 fChanged |= fThis = ASMAtomicBitTestAndClear(&pVM->dbgf.s.bmHardIntBreakpoints, paConfigs[i].iInterrupt) == true; 1428 if (fThis) 1475 else if (paConfigs[i].enmHardState == DBGFINTERRUPTSTATE_DISABLED) 1429 1476 { 1430 Assert(pVM->dbgf.s.cHardIntBreakpoints > 0); 1431 pVM->dbgf.s.cHardIntBreakpoints--; 1477 fChanged |= fThis = ASMAtomicBitTestAndClear(&pVM->dbgf.s.bmHardIntBreakpoints, paConfigs[i].iInterrupt) == true; 1478 if (fThis) 1479 { 1480 Assert(pVM->dbgf.s.cHardIntBreakpoints > 0); 1481 pVM->dbgf.s.cHardIntBreakpoints--; 1482 } 1432 1483 } 1484 1485 /* 1486 * Software interrupts. 1487 */ 1488 if (paConfigs[i].enmHardState == DBGFINTERRUPTSTATE_ENABLED) 1489 { 1490 fChanged |= fThis = ASMAtomicBitTestAndSet(&pVM->dbgf.s.bmSoftIntBreakpoints, paConfigs[i].iInterrupt) == false; 1491 if (fThis) 1492 { 1493 Assert(pVM->dbgf.s.cSoftIntBreakpoints < 256); 1494 pVM->dbgf.s.cSoftIntBreakpoints++; 1495 } 1496 } 1497 else if (paConfigs[i].enmSoftState == DBGFINTERRUPTSTATE_DISABLED) 1498 { 1499 fChanged |= fThis = ASMAtomicBitTestAndClear(&pVM->dbgf.s.bmSoftIntBreakpoints, paConfigs[i].iInterrupt) == true; 1500 if (fThis) 1501 { 1502 Assert(pVM->dbgf.s.cSoftIntBreakpoints > 0); 1503 pVM->dbgf.s.cSoftIntBreakpoints--; 1504 } 1505 } 1433 1506 } 1434 1507 1435 1508 /* 1436 * Software interrupts.1509 * Update the event bitmap entries. 1437 1510 */ 1438 if (paConfigs[i].enmHardState == DBGFINTERRUPTSTATE_ENABLED) 1439 { 1440 fChanged |= fThis = ASMAtomicBitTestAndSet(&pVM->dbgf.s.bmSoftIntBreakpoints, paConfigs[i].iInterrupt) == false; 1441 if (fThis) 1442 { 1443 Assert(pVM->dbgf.s.cSoftIntBreakpoints < 256); 1444 pVM->dbgf.s.cSoftIntBreakpoints++; 1445 } 1446 } 1447 else if (paConfigs[i].enmSoftState == DBGFINTERRUPTSTATE_DISABLED) 1448 { 1449 fChanged |= fThis = ASMAtomicBitTestAndClear(&pVM->dbgf.s.bmSoftIntBreakpoints, paConfigs[i].iInterrupt) == true; 1450 if (fThis) 1451 { 1452 Assert(pVM->dbgf.s.cSoftIntBreakpoints > 0); 1453 pVM->dbgf.s.cSoftIntBreakpoints--; 1454 } 1455 } 1456 } 1457 1458 /* 1459 * Update the event bitmap entries. 1460 */ 1461 if (pVM->dbgf.s.cHardIntBreakpoints > 0) 1462 fChanged |= ASMAtomicBitTestAndSet(&pVM->dbgf.s.bmSelectedEvents, DBGFEVENT_INTERRUPT_HARDWARE) == false; 1463 else 1464 fChanged |= ASMAtomicBitTestAndClear(&pVM->dbgf.s.bmSelectedEvents, DBGFEVENT_INTERRUPT_HARDWARE) == true; 1465 1466 if (pVM->dbgf.s.cSoftIntBreakpoints > 0) 1467 fChanged |= ASMAtomicBitTestAndSet(&pVM->dbgf.s.bmSelectedEvents, DBGFEVENT_INTERRUPT_SOFTWARE) == false; 1468 else 1469 fChanged |= ASMAtomicBitTestAndClear(&pVM->dbgf.s.bmSelectedEvents, DBGFEVENT_INTERRUPT_SOFTWARE) == true; 1470 1471 1472 /* 1473 * Inform HM about changes. In an SMP setup, interrupt execution on the 1474 * other CPUs so their execution loop can be reselected. 1475 */ 1476 int rc = VINF_SUCCESS; 1477 if (fChanged) 1478 { 1479 bool const fIsHmEnabled = HMIsEnabled(pVM); 1480 if (fIsHmEnabled) 1511 if (pVM->dbgf.s.cHardIntBreakpoints > 0) 1512 fChanged |= ASMAtomicBitTestAndSet(&pVM->dbgf.s.bmSelectedEvents, DBGFEVENT_INTERRUPT_HARDWARE) == false; 1513 else 1514 fChanged |= ASMAtomicBitTestAndClear(&pVM->dbgf.s.bmSelectedEvents, DBGFEVENT_INTERRUPT_HARDWARE) == true; 1515 1516 if (pVM->dbgf.s.cSoftIntBreakpoints > 0) 1517 fChanged |= ASMAtomicBitTestAndSet(&pVM->dbgf.s.bmSelectedEvents, DBGFEVENT_INTERRUPT_SOFTWARE) == false; 1518 else 1519 fChanged |= ASMAtomicBitTestAndClear(&pVM->dbgf.s.bmSelectedEvents, DBGFEVENT_INTERRUPT_SOFTWARE) == true; 1520 1521 /* 1522 * Inform HM about changes. 1523 */ 1524 if (fChanged && HMIsEnabled(pVM)) 1525 { 1481 1526 HMR3NotifyDebugEventChanged(pVM); 1482 if (pVM->cCpus > 1 || fIsHmEnabled) 1483 rc = VMMR3EmtRendezvous(pVM, VMMEMTRENDEZVOUS_FLAGS_TYPE_ALL_AT_ONCE, dbgfR3EventConfigNotifyAllCpus, 1484 (void *)(uintptr_t)fIsHmEnabled); 1485 } 1486 return rc; 1527 HMR3NotifyDebugEventChangedPerCpu(pVM, pVCpu); 1528 } 1529 } 1530 else if (HMIsEnabled(pVM)) 1531 HMR3NotifyDebugEventChangedPerCpu(pVM, pVCpu); 1532 1533 return VINF_SUCCESS; 1487 1534 } 1488 1535 … … 1502 1549 * Validate input. 1503 1550 */ 1504 UVM_ASSERT_VALID_EXT_RETURN(pUVM, VERR_INVALID_VM_HANDLE);1505 1551 size_t i = cConfigs; 1506 1552 while (i-- > 0) … … 1510 1556 } 1511 1557 1512 /* 1513 * Apply the changes in EMT(0). 1514 */ 1515 return VMR3ReqPriorityCallWaitU(pUVM, VMCPUID_ANY, (PFNRT)dbgfR3InterruptConfigEx, 3, pUVM, paConfigs, cConfigs); 1558 UVM_ASSERT_VALID_EXT_RETURN(pUVM, VERR_INVALID_VM_HANDLE); 1559 PVM pVM = pUVM->pVM; 1560 VM_ASSERT_VALID_EXT_RETURN(pVM, VERR_INVALID_VM_HANDLE); 1561 1562 /* 1563 * Apply the changes in EMT(0) and rendezvous with the other CPUs so they 1564 * can sync their data and execution with new debug state. 1565 */ 1566 DBGFR3INTERRUPTCONFIGEXARGS Args = { paConfigs, cConfigs, VINF_SUCCESS }; 1567 int rc = VMMR3EmtRendezvous(pVM, VMMEMTRENDEZVOUS_FLAGS_TYPE_ASCENDING, dbgfR3InterruptConfigEx, &Args); 1568 if (RT_SUCCESS(rc)) 1569 rc = Args.rc; 1570 return rc; 1516 1571 } 1517 1572
Note:
See TracChangeset
for help on using the changeset viewer.