Changeset 89924 in vbox for trunk/src/VBox/VMM/VMMAll
- Timestamp:
- Jun 28, 2021 8:16:29 AM (4 years ago)
- svn:sync-xref-src-repo-rev:
- 145382
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMAll/DBGFAllBp.cpp
r87776 r89924 169 169 if (pBpOwnerR0) 170 170 { 171 AssertReturn(pBpOwnerR0->pfnBpIoHitR0, VERR_DBGF_BP_IPE_1); 172 171 173 VBOXSTRICTRC rcStrict = VINF_SUCCESS; 172 174 … … 234 236 235 237 /** 238 * Executes the actions associated with the given port I/O breakpoint. 239 * 240 * @returns VBox status code. 241 * @param pVM The cross context VM structure. 242 * @param pVCpu The cross context virtual CPU structure. 243 * @param fBefore Flag whether the check is done before the access is carried out, 244 * false if it is done after the access. 245 * @param fAccess Access flags, see DBGFBPIOACCESS_XXX. 246 * @param uAddr The address of the access, for port I/O this will hold the port number. 247 * @param uValue The value read or written (the value for reads is only valid when DBGF_BP_F_HIT_EXEC_AFTER is set). 248 * @param hBp The breakpoint handle which hit. 249 * @param pBp The shared breakpoint state. 250 * @param pBpR0 The ring-0 only breakpoint state. 251 */ 252 #ifdef IN_RING0 253 DECLINLINE(VBOXSTRICTRC) dbgfBpPortIoHit(PVMCC pVM, PVMCPU pVCpu, bool fBefore, uint32_t fAccess, uint64_t uAddr, uint64_t uValue, 254 DBGFBP hBp, PDBGFBPINT pBp, PDBGFBPINTR0 pBpR0) 255 #else 256 DECLINLINE(VBOXSTRICTRC) dbgfBpPortIoHit(PVMCC pVM, PVMCPU pVCpu, bool fBefore, uint32_t fAccess, uint64_t uAddr, uint64_t uValue, 257 DBGFBP hBp, PDBGFBPINT pBp) 258 #endif 259 { 260 ASMAtomicIncU64(&pBp->Pub.cHits); 261 262 VBOXSTRICTRC rcStrict = VINF_EM_DBG_BREAKPOINT; 263 #ifdef IN_RING0 264 PCDBGFBPOWNERINTR0 pBpOwnerR0 = dbgfR0BpOwnerGetByHnd(pVM, 265 pBpR0->fInUse 266 ? pBpR0->hOwner 267 : NIL_DBGFBPOWNER); 268 if (pBpOwnerR0) 269 { 270 AssertReturn(pBpOwnerR0->pfnBpIoHitR0, VERR_DBGF_BP_IPE_1); 271 rcStrict = pBpOwnerR0->pfnBpIoHitR0(pVM, pVCpu->idCpuUnsafe, pBpR0->pvUserR0, hBp, &pBp->Pub, 272 fBefore 273 ? DBGF_BP_F_HIT_EXEC_BEFORE 274 : DBGF_BP_F_HIT_EXEC_AFTER, 275 fAccess, uAddr, uValue); 276 } 277 else 278 { 279 pVCpu->dbgf.s.fBpInvokeOwnerCallback = true; /* Need to check this for ring-3 only owners. */ 280 pVCpu->dbgf.s.hBpActive = hBp; 281 pVCpu->dbgf.s.fBpIoActive = true; 282 pVCpu->dbgf.s.fBpIoBefore = fBefore; 283 pVCpu->dbgf.s.uBpIoAddress = uAddr; 284 pVCpu->dbgf.s.fBpIoAccess = fAccess; 285 pVCpu->dbgf.s.uBpIoValue = uValue; 286 } 287 #else 288 /* Resolve owner (can be NIL_DBGFBPOWNER) and invoke callback if there is one. */ 289 if (pBp->Pub.hOwner != NIL_DBGFBPOWNER) 290 { 291 PCDBGFBPOWNERINT pBpOwner = dbgfR3BpOwnerGetByHnd(pVM->pUVM, pBp->Pub.hOwner); 292 if (pBpOwner) 293 { 294 AssertReturn(pBpOwner->pfnBpIoHitR3, VERR_DBGF_BP_IPE_1); 295 rcStrict = pBpOwner->pfnBpIoHitR3(pVM, pVCpu->idCpu, pBp->pvUserR3, hBp, &pBp->Pub, 296 fBefore 297 ? DBGF_BP_F_HIT_EXEC_BEFORE 298 : DBGF_BP_F_HIT_EXEC_AFTER, 299 fAccess, uAddr, uValue); 300 } 301 } 302 #endif 303 if ( rcStrict == VINF_DBGF_BP_HALT 304 || rcStrict == VINF_DBGF_R3_BP_OWNER_DEFER) 305 { 306 pVCpu->dbgf.s.hBpActive = hBp; 307 if (rcStrict == VINF_DBGF_R3_BP_OWNER_DEFER) 308 pVCpu->dbgf.s.fBpInvokeOwnerCallback = true; 309 else 310 pVCpu->dbgf.s.fBpInvokeOwnerCallback = false; 311 rcStrict = VINF_EM_DBG_BREAKPOINT; 312 } 313 else if ( rcStrict != VINF_SUCCESS 314 && rcStrict != VINF_EM_DBG_BREAKPOINT) 315 rcStrict = VERR_DBGF_BP_OWNER_CALLBACK_WRONG_STATUS; /* Guru meditation. */ 316 317 return rcStrict; 318 } 319 320 321 /** 236 322 * Walks the L2 table starting at the given root index searching for the given key. 237 323 * … … 294 380 295 381 return VERR_DBGF_BP_L2_LOOKUP_FAILED; 382 } 383 384 385 /** 386 * Checks whether there is a port I/O breakpoint for the given range and access size. 387 * 388 * @returns VBox status code. 389 * @retval VINF_EM_DBG_BREAKPOINT means there is a breakpoint pending. 390 * @retval VINF_SUCCESS means everything is fine to continue. 391 * @retval anything else means a fatal error causing a guru meditation. 392 * 393 * @param pVM The current context VM structure. 394 * @param pVCpu The cross context virtual CPU structure. 395 * @param uIoPort The I/O port being accessed. 396 * @param fAccess Appropriate DBGFBPIOACCESS_XXX. 397 * @param uValue The value being written to or read from the device 398 * (The value is only valid for a read when the 399 * call is made after the access, writes are always valid). 400 * @param fBefore Flag whether the check is done before the access is carried out, 401 * false if it is done after the access. 402 */ 403 VMM_INT_DECL(VBOXSTRICTRC) DBGFBpCheckPortIo(PVMCC pVM, PVMCPU pVCpu, RTIOPORT uIoPort, 404 uint32_t fAccess, uint32_t uValue, bool fBefore) 405 { 406 RT_NOREF(uValue); /** @todo Trigger only on specific values. */ 407 408 /* Don't trigger in single stepping mode. */ 409 if (pVCpu->dbgf.s.fSingleSteppingRaw) 410 return VINF_SUCCESS; 411 412 #if defined(IN_RING0) 413 uint32_t volatile *paBpLocPortIo = pVM->dbgfr0.s.CTX_SUFF(paBpLocPortIo); 414 #elif defined(IN_RING3) 415 PUVM pUVM = pVM->pUVM; 416 uint32_t volatile *paBpLocPortIo = pUVM->dbgf.s.CTX_SUFF(paBpLocPortIo); 417 #else 418 # error "Unsupported host context" 419 #endif 420 if (paBpLocPortIo) 421 { 422 const uint32_t u32Entry = ASMAtomicReadU32(&paBpLocPortIo[uIoPort]); 423 if (u32Entry != DBGF_BP_INT3_L1_ENTRY_TYPE_NULL) 424 { 425 uint8_t u8Type = DBGF_BP_INT3_L1_ENTRY_GET_TYPE(u32Entry); 426 if (RT_LIKELY(u8Type == DBGF_BP_INT3_L1_ENTRY_TYPE_BP_HND)) 427 { 428 DBGFBP hBp = DBGF_BP_INT3_L1_ENTRY_GET_BP_HND(u32Entry); 429 430 /* Query the internal breakpoint state from the handle. */ 431 #ifdef IN_RING3 432 PDBGFBPINT pBp = dbgfBpGetByHnd(pVM, hBp); 433 #else 434 PDBGFBPINTR0 pBpR0 = NULL; 435 PDBGFBPINT pBp = dbgfBpGetByHnd(pVM, hBp, &pBpR0); 436 #endif 437 if ( pBp 438 && DBGF_BP_PUB_GET_TYPE(&pBp->Pub) == DBGFBPTYPE_PORT_IO) 439 { 440 if ( uIoPort >= pBp->Pub.u.PortIo.uPort 441 && uIoPort < pBp->Pub.u.PortIo.uPort + pBp->Pub.u.PortIo.cPorts 442 && pBp->Pub.u.PortIo.fAccess & fAccess 443 && ( ( fBefore 444 && DBGF_BP_PUB_IS_EXEC_BEFORE(&pBp->Pub)) 445 || ( !fBefore 446 && DBGF_BP_PUB_IS_EXEC_AFTER(&pBp->Pub)))) 447 #ifdef IN_RING3 448 return dbgfBpPortIoHit(pVM, pVCpu, fBefore, fAccess, uIoPort, uValue, hBp, pBp); 449 #else 450 return dbgfBpPortIoHit(pVM, pVCpu, fBefore, fAccess, uIoPort, uValue, hBp, pBp, pBpR0); 451 #endif 452 /* else: No matching port I/O breakpoint. */ 453 } 454 else /* Invalid breakpoint handle or not an port I/O breakpoint. */ 455 return VERR_DBGF_BP_L1_LOOKUP_FAILED; 456 } 457 else /* Some invalid type. */ 458 return VERR_DBGF_BP_L1_LOOKUP_FAILED; 459 } 460 } 461 462 return VINF_SUCCESS; 296 463 } 297 464
Note:
See TracChangeset
for help on using the changeset viewer.