Changeset 97693 in vbox for trunk/src/VBox/VMM/VMMAll
- Timestamp:
- Nov 28, 2022 10:03:17 PM (2 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMAll/DBGFAll.cpp
r96407 r97693 31 31 *********************************************************************************************************************************/ 32 32 #define LOG_GROUP LOG_GROUP_DBGF 33 #define VMCPU_INCL_CPUM_GST_CTX 33 34 #include <VBox/vmm/dbgf.h> 34 35 #include "DBGFInternal.h" 36 #include <VBox/vmm/cpum.h> 35 37 #include <VBox/vmm/vmcc.h> 36 38 #include <VBox/err.h> … … 169 171 170 172 /** 171 * Checks I/O access for guest or hypervisor breakpoints. 173 * Checks instruction boundrary for guest or hypervisor hardware breakpoints. 174 * 175 * @returns Strict VBox status code. May return DRx register import errors in 176 * addition to the ones detailed. 177 * @retval VINF_SUCCESS no breakpoint. 178 * @retval VINF_EM_DBG_BREAKPOINT hypervisor breakpoint triggered. 179 * @retval VINF_EM_RAW_GUEST_TRAP caller must trigger \#DB trap, DR6 and DR7 180 * have been updated appropriately. 181 * 182 * @param pVM The cross context VM structure. 183 * @param pVCpu The cross context virtual CPU structure of the calling EMT. 184 * @param GCPtrPC The unsegmented PC address. 185 */ 186 VMM_INT_DECL(VBOXSTRICTRC) DBGFBpCheckInstruction(PVMCC pVM, PVMCPUCC pVCpu, RTGCPTR GCPtrPC) 187 { 188 CPUM_ASSERT_NOT_EXTRN(pVCpu, CPUMCTX_EXTRN_DR7); 189 190 /* 191 * Check hyper breakpoints first as the VMM debugger has priority over 192 * the guest. 193 */ 194 if (pVM->dbgf.s.cEnabledHwIoBreakpoints > 0) 195 for (unsigned iBp = 0; iBp < RT_ELEMENTS(pVM->dbgf.s.aHwBreakpoints); iBp++) 196 { 197 if ( pVM->dbgf.s.aHwBreakpoints[iBp].GCPtr != GCPtrPC 198 || pVM->dbgf.s.aHwBreakpoints[iBp].fType != X86_DR7_RW_EO 199 || pVM->dbgf.s.aHwBreakpoints[iBp].cb != 1 200 || !pVM->dbgf.s.aHwBreakpoints[iBp].fEnabled 201 || pVM->dbgf.s.aHwBreakpoints[iBp].hBp == NIL_DBGFBP) 202 { /*likely*/ } 203 else 204 { 205 /* (See also DBGFRZTrap01Handler.) */ 206 pVCpu->dbgf.s.hBpActive = pVM->dbgf.s.aHwBreakpoints[iBp].hBp; 207 pVCpu->dbgf.s.fSingleSteppingRaw = false; 208 209 LogFlow(("DBGFBpCheckInstruction: hit hw breakpoint %u at %04x:%RGv (%RGv)\n", 210 iBp, pVCpu->cpum.GstCtx.cs.Sel, pVCpu->cpum.GstCtx.rip, GCPtrPC)); 211 return VINF_EM_DBG_BREAKPOINT; 212 } 213 } 214 215 /* 216 * Check the guest. 217 */ 218 uint32_t const fDr7 = (uint32_t)pVCpu->cpum.GstCtx.dr[7]; 219 if (X86_DR7_ANY_EO_ENABLED(fDr7)) 220 { 221 /* 222 * The CPU (10980XE & 6700K at least) will set the DR6.BPx bits for any 223 * DRx that matches the current PC and is configured as an execution 224 * breakpoint (RWx=EO, LENx=1byte). They don't have to be enabled, 225 * however one that is enabled must match for the #DB to be raised and 226 * DR6 to be modified, of course. 227 */ 228 CPUM_IMPORT_EXTRN_RET(pVCpu, CPUMCTX_EXTRN_DR0_DR3); 229 uint32_t fMatched = 0; 230 uint32_t fEnabled = 0; 231 for (unsigned iBp = 0, iBpMask = 1; iBp < 4; iBp++, iBpMask <<= 1) 232 if (X86_DR7_IS_EO_CFG(fDr7, iBp)) 233 { 234 if (fDr7 & X86_DR7_L_G(iBp)) 235 fEnabled |= iBpMask; 236 if (pVCpu->cpum.GstCtx.dr[iBp] == GCPtrPC) 237 fMatched |= iBpMask; 238 } 239 if (!(fEnabled & fMatched)) 240 { /*likely*/ } 241 else if (fEnabled & fMatched) 242 { 243 /* 244 * Update DR6 and DR7. 245 * 246 * See "AMD64 Architecture Programmer's Manual Volume 2", chapter 247 * 13.1.1.3 for details on DR6 bits. The basics is that the B0..B3 248 * bits are always cleared while the others must be cleared by software. 249 * 250 * The following sub chapters says the GD bit is always cleared when 251 * generating a #DB so the handler can safely access the debug registers. 252 */ 253 CPUM_IMPORT_EXTRN_RET(pVCpu, CPUMCTX_EXTRN_DR6); 254 pVCpu->cpum.GstCtx.dr[6] &= ~X86_DR6_B_MASK; 255 pVCpu->cpum.GstCtx.dr[6] |= fMatched; /* All matched */ 256 pVCpu->cpum.GstCtx.dr[7] &= ~X86_DR7_GD; 257 LogFlow(("DBGFBpCheckInstruction: hit hw breakpoints %#x at %04x:%RGv (%RGv)\n", 258 fMatched, pVCpu->cpum.GstCtx.cs.Sel, pVCpu->cpum.GstCtx.rip, GCPtrPC)); 259 return VINF_EM_RAW_GUEST_TRAP; 260 } 261 } 262 return VINF_SUCCESS; 263 } 264 265 266 /** 267 * Checks I/O access for guest or hypervisor hardware breakpoints. 172 268 * 173 269 * @returns Strict VBox status code
Note:
See TracChangeset
for help on using the changeset viewer.