Changeset 86729 in vbox for trunk/src/VBox/VMM/VMMRZ
- Timestamp:
- Oct 28, 2020 10:31:49 AM (4 years ago)
- svn:sync-xref-src-repo-rev:
- 141117
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMRZ/DBGFRZ.cpp
r86726 r86729 23 23 #include <VBox/vmm/dbgf.h> 24 24 #include <VBox/vmm/selm.h> 25 #ifdef IN_RC26 # include <VBox/vmm/trpm.h>27 #endif28 25 #include <VBox/log.h> 29 26 #include "DBGFInternal.h" … … 32 29 #include <iprt/assert.h> 33 30 31 34 32 #ifdef IN_RC 35 DECLASM(void) TRPMRCHandlerAsmTrap03(void); 33 # error "You lucky person have the pleasure to implement the raw mode part for this!" 36 34 #endif 35 36 37 /********************************************************************************************************************************* 38 * Internal Functions * 39 *********************************************************************************************************************************/ 40 41 #ifdef VBOX_WITH_LOTS_OF_DBGF_BPS 42 # ifdef IN_RING0 43 /** 44 * Returns the internal breakpoint state for the given handle. 45 * 46 * @returns Pointer to the internal breakpoint state or NULL if the handle is invalid. 47 * @param pVM The ring-0 VM structure pointer. 48 * @param hBp The breakpoint handle to resolve. 49 * @param ppBpR0 Where to store the pointer to the ring-0 only part of the breakpoint 50 * on success, optional. 51 */ 52 DECLINLINE(PDBGFBPINT) dbgfR0BpGetByHnd(PVMCC pVM, DBGFBP hBp, PDBGFBPINTR0 *ppBpR0) 53 { 54 uint32_t idChunk = DBGF_BP_HND_GET_CHUNK_ID(hBp); 55 uint32_t idxEntry = DBGF_BP_HND_GET_ENTRY(hBp); 56 57 AssertReturn(idChunk < DBGF_BP_CHUNK_COUNT, NULL); 58 AssertReturn(idxEntry < DBGF_BP_COUNT_PER_CHUNK, NULL); 59 60 PDBGFBPCHUNKR0 pBpChunk = &pVM->dbgfr0.s.aBpChunks[idChunk]; 61 AssertPtrReturn(pBpChunk->paBpBaseSharedR0, NULL); 62 63 if (ppBpR0) 64 *ppBpR0 = &pBpChunk->paBpBaseR0Only[idxEntry]; 65 return &pBpChunk->paBpBaseSharedR0[idxEntry]; 66 } 67 # endif 68 69 70 /** 71 * Executes the actions associated with the given breakpoint. 72 * 73 * @returns VBox status code. 74 * @param pVM The cross context VM structure. 75 * @param pVCpu The cross context virtual CPU structure. 76 * @param pRegFrame Pointer to the register frame for the trap. 77 * @param hBp The breakpoint handle which hit. 78 * @param pBp The shared breakpoint state. 79 * @param pBpR0 The ring-0 only breakpoint state. 80 */ 81 DECLINLINE(int) dbgfRZBpHit(PVMCC pVM, PVMCPUCC pVCpu, PCPUMCTXCORE pRegFrame, 82 DBGFBP hBp, PDBGFBPINT pBp, PDBGFBPINTR0 pBpR0) 83 { 84 uint64_t cHits = ASMAtomicIncU64(&pBp->Pub.cHits); 85 pVCpu->dbgf.s.hBpActive = hBp; 86 87 /** @todo Owner handling. */ 88 RT_NOREF(pVM, pRegFrame, pBpR0); 89 90 LogFlow(("dbgfRZBpHit: hit breakpoint %u at %04x:%RGv cHits=0x%RX64\n", 91 hBp, pRegFrame->cs.Sel, pRegFrame->rip, cHits)); 92 return VINF_EM_DBG_BREAKPOINT; 93 } 94 95 96 /** 97 * Returns the pointer to the L2 table entry from the given index. 98 * 99 * @returns Current context pointer to the L2 table entry or NULL if the provided index value is invalid. 100 * @param pVM The cross context VM structure. 101 * @param idxL2 The L2 table index to resolve. 102 * 103 * @note The content of the resolved L2 table entry is not validated!. 104 */ 105 DECLINLINE(PCDBGFBPL2ENTRY) dbgfRZBpL2GetByIdx(PVMCC pVM, uint32_t idxL2) 106 { 107 uint32_t idChunk = DBGF_BP_L2_IDX_GET_CHUNK_ID(idxL2); 108 uint32_t idxEntry = DBGF_BP_L2_IDX_GET_ENTRY(idxL2); 109 110 AssertReturn(idChunk < DBGF_BP_L2_TBL_CHUNK_COUNT, NULL); 111 AssertReturn(idxEntry < DBGF_BP_L2_TBL_ENTRIES_PER_CHUNK, NULL); 112 113 PDBGFBPL2TBLCHUNKR0 pL2Chunk = &pVM->dbgfr0.s.aBpL2TblChunks[idChunk]; 114 AssertPtrReturn(pL2Chunk->paBpL2TblBaseSharedR0, NULL); 115 116 return &pL2Chunk->CTX_SUFF(paBpL2TblBaseShared)[idxEntry]; 117 } 118 119 120 /** 121 * Walks the L2 table starting at the given root index searching for the given key. 122 * 123 * @returns VBox status code. 124 * @param pVM The cross context VM structure. 125 * @param pVCpu The cross context virtual CPU structure. 126 * @param pRegFrame Pointer to the register frame for the trap. 127 * @param idxL2Root L2 table index of the table root. 128 * @param GCPtrKey The key to search for. 129 */ 130 static int dbgfRZBpL2Walk(PVMCC pVM, PVMCPUCC pVCpu, PCPUMCTXCORE pRegFrame, 131 uint32_t idxL2Root, RTGCUINTPTR GCPtrKey) 132 { 133 /** @todo We don't use the depth right now but abort the walking after a fixed amount of levels. */ 134 uint8_t iDepth = 32; 135 PCDBGFBPL2ENTRY pL2Entry = dbgfRZBpL2GetByIdx(pVM, idxL2Root); 136 137 while (RT_LIKELY( iDepth-- > 0 138 && pL2Entry)) 139 { 140 /* Make a copy of the entry before verification. */ 141 DBGFBPL2ENTRY L2Entry; 142 L2Entry.u64GCPtrKeyAndBpHnd1 = ASMAtomicReadU64((volatile uint64_t *)&pL2Entry->u64GCPtrKeyAndBpHnd1); 143 L2Entry.u64LeftRightIdxDepthBpHnd2 = ASMAtomicReadU64((volatile uint64_t *)&pL2Entry->u64LeftRightIdxDepthBpHnd2); 144 145 RTGCUINTPTR GCPtrL2Entry = DBGF_BP_L2_ENTRY_GET_GCPTR(L2Entry.u64GCPtrKeyAndBpHnd1); 146 if (GCPtrKey == GCPtrL2Entry) 147 { 148 DBGFBP hBp = DBGF_BP_L2_ENTRY_GET_BP_HND(L2Entry.u64GCPtrKeyAndBpHnd1, L2Entry.u64LeftRightIdxDepthBpHnd2); 149 150 /* Query the internal breakpoint state from the handle. */ 151 PDBGFBPINTR0 pBpR0 = NULL; 152 PDBGFBPINT pBp = dbgfR0BpGetByHnd(pVM, hBp, &pBpR0); 153 if ( pBp 154 && DBGF_BP_PUB_GET_TYPE(pBp->Pub.fFlagsAndType) == DBGFBPTYPE_INT3) 155 return dbgfRZBpHit(pVM, pVCpu, pRegFrame, hBp, pBp, pBpR0); 156 157 /* The entry got corrupted, just abort. */ 158 return VERR_DBGF_BP_L2_LOOKUP_FAILED; 159 } 160 161 /* Not found, get to the next level. */ 162 uint32_t idxL2Next = (GCPtrKey < GCPtrL2Entry) 163 ? DBGF_BP_L2_ENTRY_GET_IDX_LEFT(L2Entry.u64LeftRightIdxDepthBpHnd2) 164 : DBGF_BP_L2_ENTRY_GET_IDX_RIGHT(L2Entry.u64LeftRightIdxDepthBpHnd2); 165 /* It is genuine guest trap or we hit some assertion if we are at the end. */ 166 if (idxL2Next == DBGF_BP_L2_ENTRY_IDX_END) 167 return VINF_EM_RAW_GUEST_TRAP; 168 169 pL2Entry = dbgfRZBpL2GetByIdx(pVM, idxL2Next); 170 } 171 172 return VERR_DBGF_BP_L2_LOOKUP_FAILED; 173 } 174 #endif /* !VBOX_WITH_LOTS_OF_DBGF_BPS */ 37 175 38 176 … … 52 190 VMMRZ_INT_DECL(int) DBGFRZTrap01Handler(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame, RTGCUINTREG uDr6, bool fAltStepping) 53 191 { 54 #ifdef IN_RC55 const bool fInHyper = !(pRegFrame->ss.Sel & X86_SEL_RPL) && !pRegFrame->eflags.Bits.u1VM;56 #else57 NOREF(pRegFrame);58 const bool fInHyper = false;59 #endif60 61 192 /** @todo Intel docs say that X86_DR6_BS has the highest priority... */ 193 RT_NOREF(pRegFrame); 194 62 195 /* 63 196 * A breakpoint? … … 78 211 pVM->dbgf.s.aHwBreakpoints[iBp].iBp, pRegFrame->cs.Sel, pRegFrame->rip)); 79 212 80 return fInHyper ? VINF_EM_DBG_HYPER_BREAKPOINT :VINF_EM_DBG_BREAKPOINT;213 return VINF_EM_DBG_BREAKPOINT; 81 214 } 82 215 #else … … 89 222 pVM->dbgf.s.aHwBreakpoints[iBp].hBp, pRegFrame->cs.Sel, pRegFrame->rip)); 90 223 91 return fInHyper ? VINF_EM_DBG_HYPER_BREAKPOINT :VINF_EM_DBG_BREAKPOINT;224 return VINF_EM_DBG_BREAKPOINT; 92 225 } 93 226 #endif … … 100 233 */ 101 234 if ( (uDr6 & X86_DR6_BS) 102 && ( fInHyper ||pVCpu->dbgf.s.fSingleSteppingRaw || fAltStepping))235 && (pVCpu->dbgf.s.fSingleSteppingRaw || fAltStepping)) 103 236 { 104 237 pVCpu->dbgf.s.fSingleSteppingRaw = false; 105 238 LogFlow(("DBGFRZTrap01Handler: single step at %04x:%RGv\n", pRegFrame->cs.Sel, pRegFrame->rip)); 106 return fInHyper ? VINF_EM_DBG_HYPER_STEPPED : VINF_EM_DBG_STEPPED; 107 } 108 109 #ifdef IN_RC 110 /* 111 * Either an ICEBP in hypervisor code or a guest related debug exception 112 * of sorts. 113 */ 114 if (RT_UNLIKELY(fInHyper)) 115 { 116 /* 117 * Is this a guest debug event that was delayed past a ring transition? 118 * 119 * Since we do no allow sysenter/syscall in raw-mode, the only 120 * non-trap/fault type transitions that can occur are thru interrupt gates. 121 * Of those, only INT3 (#BP) has a DPL other than 0 with a CS.RPL of 0. 122 * See bugref:9171 and bs3-cpu-weird-1 for more details. 123 * 124 * We need to reconstruct the guest register state from the hypervisor one 125 * here, so here is the layout of the IRET frame on the stack: 126 * 20:[8] GS (V86 only) 127 * 1C:[7] FS (V86 only) 128 * 18:[6] DS (V86 only) 129 * 14:[5] ES (V86 only) 130 * 10:[4] SS 131 * 0c:[3] ESP 132 * 08:[2] EFLAGS 133 * 04:[1] CS 134 * 00:[0] EIP 135 */ 136 if (pRegFrame->rip == (uintptr_t)TRPMRCHandlerAsmTrap03) 137 { 138 uint32_t const *pu32Stack = (uint32_t const *)pRegFrame->esp; 139 if ( (pu32Stack[2] & X86_EFL_VM) 140 || (pu32Stack[1] & X86_SEL_RPL)) 141 { 142 LogFlow(("DBGFRZTrap01Handler: Detected guest #DB delayed past ring transition %04x:%RX32 %#x\n", 143 pu32Stack[1] & 0xffff, pu32Stack[0], pu32Stack[2])); 144 PCPUMCTX pGstCtx = CPUMQueryGuestCtxPtr(pVCpu); 145 pGstCtx->rip = pu32Stack[0]; 146 pGstCtx->cs.Sel = pu32Stack[1]; 147 pGstCtx->eflags.u = pu32Stack[2]; 148 pGstCtx->rsp = pu32Stack[3]; 149 pGstCtx->ss.Sel = pu32Stack[4]; 150 if (pu32Stack[2] & X86_EFL_VM) 151 { 152 pGstCtx->es.Sel = pu32Stack[5]; 153 pGstCtx->ds.Sel = pu32Stack[6]; 154 pGstCtx->fs.Sel = pu32Stack[7]; 155 pGstCtx->gs.Sel = pu32Stack[8]; 156 } 157 else 158 { 159 pGstCtx->es.Sel = pRegFrame->es.Sel; 160 pGstCtx->ds.Sel = pRegFrame->ds.Sel; 161 pGstCtx->fs.Sel = pRegFrame->fs.Sel; 162 pGstCtx->gs.Sel = pRegFrame->gs.Sel; 163 } 164 pGstCtx->rax = pRegFrame->rax; 165 pGstCtx->rcx = pRegFrame->rcx; 166 pGstCtx->rdx = pRegFrame->rdx; 167 pGstCtx->rbx = pRegFrame->rbx; 168 pGstCtx->rsi = pRegFrame->rsi; 169 pGstCtx->rdi = pRegFrame->rdi; 170 pGstCtx->rbp = pRegFrame->rbp; 171 172 /* 173 * We should assert a #BP followed by a #DB here, but TRPM cannot 174 * do that. So, we'll just assert the #BP and ignore the #DB, even 175 * if that isn't strictly correct. 176 */ 177 TRPMResetTrap(pVCpu); 178 TRPMAssertTrap(pVCpu, X86_XCPT_BP, TRPM_SOFTWARE_INT); 179 return VINF_EM_RAW_GUEST_TRAP; 180 } 181 } 182 183 LogFlow(("DBGFRZTrap01Handler: Unknown bp at %04x:%RGv\n", pRegFrame->cs.Sel, pRegFrame->rip)); 184 return VERR_DBGF_HYPER_DB_XCPT; 185 } 186 #endif 239 return VINF_EM_DBG_STEPPED; 240 } 187 241 188 242 LogFlow(("DBGFRZTrap01Handler: guest debug event %#x at %04x:%RGv!\n", (uint32_t)uDr6, pRegFrame->cs.Sel, pRegFrame->rip)); … … 190 244 } 191 245 192 #ifdef VBOX_WITH_LOTS_OF_DBGF_BPS 193 # ifdef IN_RING0 194 /** 195 * Returns the internal breakpoint state for the given handle. 196 * 197 * @returns Pointer to the internal breakpoint state or NULL if the handle is invalid. 198 * @param pVM The ring-0 VM structure pointer. 199 * @param hBp The breakpoint handle to resolve. 200 * @param ppBpR0 Where to store the pointer to the ring-0 only part of the breakpoint 201 * on success, optional. 202 */ 203 DECLINLINE(PDBGFBPINT) dbgfR0BpGetByHnd(PVMCC pVM, DBGFBP hBp, PDBGFBPINTR0 *ppBpR0) 204 { 205 uint32_t idChunk = DBGF_BP_HND_GET_CHUNK_ID(hBp); 206 uint32_t idxEntry = DBGF_BP_HND_GET_ENTRY(hBp); 207 208 AssertReturn(idChunk < DBGF_BP_CHUNK_COUNT, NULL); 209 AssertReturn(idxEntry < DBGF_BP_COUNT_PER_CHUNK, NULL); 210 211 PDBGFBPCHUNKR0 pBpChunk = &pVM->dbgfr0.s.aBpChunks[idChunk]; 212 AssertPtrReturn(pBpChunk->paBpBaseSharedR0, NULL); 213 214 if (ppBpR0) 215 *ppBpR0 = &pBpChunk->paBpBaseR0Only[idxEntry]; 216 return &pBpChunk->paBpBaseSharedR0[idxEntry]; 217 } 218 # endif 219 220 221 /** 222 * Executes the actions associated with the given breakpoint. 246 247 /** 248 * \#BP (Breakpoint) handler. 223 249 * 224 250 * @returns VBox status code. 251 * VINF_SUCCESS means we completely handled this trap, 252 * other codes are passed execution to host context. 253 * 225 254 * @param pVM The cross context VM structure. 226 255 * @param pVCpu The cross context virtual CPU structure. 227 256 * @param pRegFrame Pointer to the register frame for the trap. 228 * @param hBp The breakpoint handle which hit.229 * @param pBp The shared breakpoint state.230 * @param pBpR0 The ring-0 only breakpoint state.231 * @param fInHyper Flag whether the breakpoint triggered in hypervisor code.232 */233 DECLINLINE(int) dbgfRZBpHit(PVMCC pVM, PVMCPUCC pVCpu, PCPUMCTXCORE pRegFrame,234 DBGFBP hBp, PDBGFBPINT pBp, PDBGFBPINTR0 pBpR0, bool fInHyper)235 {236 uint64_t cHits = ASMAtomicIncU64(&pBp->Pub.cHits);237 pVCpu->dbgf.s.hBpActive = hBp;238 239 /** @todo Owner handling. */240 RT_NOREF(pVM, pRegFrame, pBpR0);241 242 LogFlow(("dbgfRZBpHit: hit breakpoint %u at %04x:%RGv cHits=0x%RX64\n",243 hBp, pRegFrame->cs.Sel, pRegFrame->rip, cHits));244 return fInHyper245 ? VINF_EM_DBG_HYPER_BREAKPOINT246 : VINF_EM_DBG_BREAKPOINT;247 }248 249 250 /**251 * Returns the pointer to the L2 table entry from the given index.252 *253 * @returns Current context pointer to the L2 table entry or NULL if the provided index value is invalid.254 * @param pVM The cross context VM structure.255 * @param idxL2 The L2 table index to resolve.256 *257 * @note The content of the resolved L2 table entry is not validated!.258 */259 DECLINLINE(PCDBGFBPL2ENTRY) dbgfRZBpL2GetByIdx(PVMCC pVM, uint32_t idxL2)260 {261 uint32_t idChunk = DBGF_BP_L2_IDX_GET_CHUNK_ID(idxL2);262 uint32_t idxEntry = DBGF_BP_L2_IDX_GET_ENTRY(idxL2);263 264 AssertReturn(idChunk < DBGF_BP_L2_TBL_CHUNK_COUNT, NULL);265 AssertReturn(idxEntry < DBGF_BP_L2_TBL_ENTRIES_PER_CHUNK, NULL);266 267 PDBGFBPL2TBLCHUNKR0 pL2Chunk = &pVM->dbgfr0.s.aBpL2TblChunks[idChunk];268 AssertPtrReturn(pL2Chunk->paBpL2TblBaseSharedR0, NULL);269 270 return &pL2Chunk->CTX_SUFF(paBpL2TblBaseShared)[idxEntry];271 }272 273 274 /**275 * Walks the L2 table starting at the given root index searching for the given key.276 *277 * @returns VBox status code.278 * @param pVM The cross context VM structure.279 * @param pVCpu The cross context virtual CPU structure.280 * @param pRegFrame Pointer to the register frame for the trap.281 * @param fInHyper Flag whether the breakpoint triggered in hypervisor code.282 * @param idxL2Root L2 table index of the table root.283 * @param GCPtrKey The key to search for.284 */285 static int dbgfRZBpL2Walk(PVMCC pVM, PVMCPUCC pVCpu, PCPUMCTXCORE pRegFrame, bool fInHyper,286 uint32_t idxL2Root, RTGCUINTPTR GCPtrKey)287 {288 /** @todo We don't use the depth right now but abort the walking after a fixed amount of levels. */289 uint8_t iDepth = 32;290 PCDBGFBPL2ENTRY pL2Entry = dbgfRZBpL2GetByIdx(pVM, idxL2Root);291 292 while (RT_LIKELY( iDepth-- > 0293 && pL2Entry))294 {295 /* Make a copy of the entry before verification. */296 DBGFBPL2ENTRY L2Entry;297 L2Entry.u64GCPtrKeyAndBpHnd1 = ASMAtomicReadU64((volatile uint64_t *)&pL2Entry->u64GCPtrKeyAndBpHnd1);298 L2Entry.u64LeftRightIdxDepthBpHnd2 = ASMAtomicReadU64((volatile uint64_t *)&pL2Entry->u64LeftRightIdxDepthBpHnd2);299 300 RTGCUINTPTR GCPtrL2Entry = DBGF_BP_L2_ENTRY_GET_GCPTR(L2Entry.u64GCPtrKeyAndBpHnd1);301 if (GCPtrKey == GCPtrL2Entry)302 {303 DBGFBP hBp = DBGF_BP_L2_ENTRY_GET_BP_HND(L2Entry.u64GCPtrKeyAndBpHnd1, L2Entry.u64LeftRightIdxDepthBpHnd2);304 305 /* Query the internal breakpoint state from the handle. */306 PDBGFBPINTR0 pBpR0 = NULL;307 PDBGFBPINT pBp = dbgfR0BpGetByHnd(pVM, hBp, &pBpR0);308 if ( pBp309 && DBGF_BP_PUB_GET_TYPE(pBp->Pub.fFlagsAndType) == DBGFBPTYPE_INT3)310 return dbgfRZBpHit(pVM, pVCpu, pRegFrame, hBp, pBp, pBpR0, fInHyper);311 312 /* The entry got corrupted, just abort. */313 return VERR_DBGF_BP_L2_LOOKUP_FAILED;314 }315 316 /* Not found, get to the next level. */317 uint32_t idxL2Next = (GCPtrKey < GCPtrL2Entry)318 ? DBGF_BP_L2_ENTRY_GET_IDX_LEFT(L2Entry.u64LeftRightIdxDepthBpHnd2)319 : DBGF_BP_L2_ENTRY_GET_IDX_RIGHT(L2Entry.u64LeftRightIdxDepthBpHnd2);320 /* It is genuine guest trap or we hit some assertion if we are at the end. */321 if (idxL2Next == DBGF_BP_L2_ENTRY_IDX_END)322 return fInHyper323 ? VINF_EM_DBG_HYPER_ASSERTION324 : VINF_EM_RAW_GUEST_TRAP;325 326 pL2Entry = dbgfRZBpL2GetByIdx(pVM, idxL2Next);327 }328 329 return VERR_DBGF_BP_L2_LOOKUP_FAILED;330 }331 #endif /* !VBOX_WITH_LOTS_OF_DBGF_BPS */332 333 /**334 * \#BP (Breakpoint) handler.335 *336 * @returns VBox status code.337 * VINF_SUCCESS means we completely handled this trap,338 * other codes are passed execution to host context.339 *340 * @param pVM The cross context VM structure.341 * @param pVCpu The cross context virtual CPU structure.342 * @param pRegFrame Pointer to the register frame for the trap.343 257 */ 344 258 VMMRZ_INT_DECL(int) DBGFRZTrap03Handler(PVMCC pVM, PVMCPUCC pVCpu, PCPUMCTXCORE pRegFrame) 345 259 { 346 #ifdef IN_RC347 const bool fInHyper = !(pRegFrame->ss.Sel & X86_SEL_RPL) && !pRegFrame->eflags.Bits.u1VM;348 #else349 const bool fInHyper = false;350 #endif351 352 260 #ifndef VBOX_WITH_LOTS_OF_DBGF_BPS 353 261 /* … … 360 268 RTGCPTR pPc; 361 269 int rc = SELMValidateAndConvertCSAddr(pVCpu, pRegFrame->eflags, pRegFrame->ss.Sel, pRegFrame->cs.Sel, &pRegFrame->cs, 362 # ifdef IN_RC363 pRegFrame->eip - 1,364 # else365 270 pRegFrame->rip /* no -1 in R0 */, 366 # endif367 271 &pPc); 368 272 AssertRCReturn(rc, rc); … … 380 284 pVM->dbgf.s.aBreakpoints[iBp].iBp, pPc, pRegFrame->cs.Sel, pRegFrame->rip, 381 285 pVM->dbgf.s.aBreakpoints[iBp].cHits)); 382 return fInHyper 383 ? VINF_EM_DBG_HYPER_BREAKPOINT 384 : VINF_EM_DBG_BREAKPOINT; 286 return VINF_EM_DBG_BREAKPOINT; 385 287 } 386 288 iBp++; … … 388 290 } 389 291 #else 390 # ifdef IN_RC391 # error "You lucky person have the pleasure to implement the raw mode part for this!"392 # endif393 394 292 if (pVM->dbgfr0.s.CTX_SUFF(paBpLocL1)) 395 293 { 396 294 RTGCPTR GCPtrBp; 397 295 int rc = SELMValidateAndConvertCSAddr(pVCpu, pRegFrame->eflags, pRegFrame->ss.Sel, pRegFrame->cs.Sel, &pRegFrame->cs, 398 # ifdef IN_RC399 pRegFrame->eip - 1,400 # else401 296 pRegFrame->rip /* no -1 in R0 */, 402 # endif403 297 &GCPtrBp); 404 298 AssertRCReturn(rc, rc); … … 408 302 409 303 LogFlowFunc(("GCPtrBp=%RGv idxL1=%u u32L1Entry=%#x\n", GCPtrBp, idxL1, u32L1Entry)); 304 rc = VINF_EM_RAW_GUEST_TRAP; 410 305 if (u32L1Entry != DBGF_BP_INT3_L1_ENTRY_TYPE_NULL) 411 306 { … … 422 317 { 423 318 if (pBp->Pub.u.Int3.GCPtr == (RTGCUINTPTR)GCPtrBp) 424 r eturn dbgfRZBpHit(pVM, pVCpu, pRegFrame, hBp, pBp, pBpR0, fInHyper);425 /* else Genuine guest trap. */319 rc = dbgfRZBpHit(pVM, pVCpu, pRegFrame, hBp, pBp, pBpR0); 320 /* else: Genuine guest trap. */ 426 321 } 427 428 returnVERR_DBGF_BP_L1_LOOKUP_FAILED;322 else /* Invalid breakpoint handle or not an int3 breakpoint. */ 323 rc = VERR_DBGF_BP_L1_LOOKUP_FAILED; 429 324 } 430 325 else if (u8Type == DBGF_BP_INT3_L1_ENTRY_TYPE_L2_IDX) 431 return dbgfRZBpL2Walk(pVM, pVCpu, pRegFrame, fInHyper, DBGF_BP_INT3_L1_ENTRY_GET_L2_IDX(u32L1Entry), 432 DBGF_BP_INT3_L2_KEY_EXTRACT_FROM_ADDR((RTGCUINTPTR)GCPtrBp)); 433 434 /* Some invalid type. */ 435 return VERR_DBGF_BP_L1_LOOKUP_FAILED; 326 rc = dbgfRZBpL2Walk(pVM, pVCpu, pRegFrame, DBGF_BP_INT3_L1_ENTRY_GET_L2_IDX(u32L1Entry), 327 DBGF_BP_INT3_L2_KEY_EXTRACT_FROM_ADDR((RTGCUINTPTR)GCPtrBp)); 328 else /* Some invalid type. */ 329 rc = VERR_DBGF_BP_L1_LOOKUP_FAILED; 436 330 } 331 /* else: Genuine guest trap. */ 437 332 } 438 333 #endif /* !VBOX_WITH_LOTS_OF_DBGF_BPS */ 439 334 440 return fInHyper 441 ? VINF_EM_DBG_HYPER_ASSERTION 442 : VINF_EM_RAW_GUEST_TRAP; 443 } 444 335 return VINF_EM_RAW_GUEST_TRAP; 336 } 337
Note:
See TracChangeset
for help on using the changeset viewer.