VirtualBox

source: vbox/trunk/src/VBox/VMM/VMMAll/DBGFAllTracer.cpp@ 99654

Last change on this file since 99654 was 98103, checked in by vboxsync, 2 years ago

Copyright year updates by scm.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 29.0 KB
Line 
1/* $Id: DBGFAllTracer.cpp 98103 2023-01-17 14:15:46Z vboxsync $ */
2/** @file
3 * DBGF - Debugger Facility, All Context Code tracing part.
4 */
5
6/*
7 * Copyright (C) 2020-2023 Oracle and/or its affiliates.
8 *
9 * This file is part of VirtualBox base platform packages, as
10 * available from https://www.virtualbox.org.
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation, in version 3 of the
15 * License.
16 *
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, see <https://www.gnu.org/licenses>.
24 *
25 * SPDX-License-Identifier: GPL-3.0-only
26 */
27
28
29/*********************************************************************************************************************************
30* Header Files *
31*********************************************************************************************************************************/
32#define LOG_GROUP LOG_GROUP_DBGF
33#include "DBGFInternal.h"
34#include <VBox/types.h>
35#include <VBox/err.h>
36#include <VBox/vmm/dbgf.h>
37#if defined(IN_RING3)
38# include <VBox/vmm/uvm.h>
39# include <VBox/vmm/vm.h>
40#elif defined(IN_RING0)
41# include <VBox/vmm/gvm.h>
42#else
43# error "Invalid environment"
44#endif
45
46
47/*********************************************************************************************************************************
48* Internal Functions *
49*********************************************************************************************************************************/
50
51/**
52 * Returns the current context tracer instance of the given VM instance.
53 *
54 * @returns Current context pointer to the DBGF tracer instance.
55 */
56DECLINLINE(PDBGFTRACERINSCC) dbgfTracerGetInstance(PVMCC pVM)
57{
58#if defined(IN_RING0)
59 return pVM->dbgfr0.s.pTracerR0;
60#elif defined(IN_RING3)
61 PUVM pUVM = pVM->pUVM;
62 return pUVM->dbgf.s.pTracerR3;
63#elif defined(IN_RC)
64# error "Not implemented"
65#else
66# error "No/Invalid context specified"
67#endif
68}
69
70
71/**
72 * Returns the size of the tracing ring buffer.
73 *
74 * @returns Size of the ring buffer in bytes.
75 * @param pThisCC The event tracer instance current context data.
76 */
77DECLINLINE(size_t) dbgfTracerGetRingBufSz(PDBGFTRACERINSCC pThisCC)
78{
79#if defined(IN_RING0) /* For R0 we are extra cautious and use the ring buffer size stored in R0 memory so R3 can't corrupt it. */
80 return pThisCC->cbRingBuf;
81#else
82 return pThisCC->CTX_SUFF(pShared)->cbRingBuf;
83#endif
84}
85
86
87/**
88 * Posts a single event descriptor to the ring buffer of the given tracer instance - extended version.
89 *
90 * @returns VBox status code.
91 * @param pVM The current context VM instance data.
92 * @param pThisCC The event tracer instance current context data.
93 * @param hEvtSrc The event source for the posted event.
94 * @param enmTraceEvt The trace event type posted.
95 * @param idEvtPrev The previous event ID the posted event links to.
96 * @param pvEvtDesc The event descriptor to copy after the header.
97 * @param cbEvtDesc Size of the event descriptor.
98 * @param pidEvt Where to store the assigned event ID, optional.
99 */
100static int dbgfTracerEvtPostEx(PVMCC pVM, PDBGFTRACERINSCC pThisCC, DBGFTRACEREVTSRC hEvtSrc,
101 DBGFTRACEREVT enmTraceEvt, uint64_t idEvtPrev, const void *pvEvtDesc,
102 size_t cbEvtDesc, uint64_t *pidEvt)
103{
104 LogFlowFunc(("pVM=%p pThisCC=%p hEvtSrc=%llu enmTraceEvt=%u idEvtPrev=%llu pvEvtDesc=%p cbEvtDesc=%zu pidEvt=%p\n",
105 pVM, pThisCC, hEvtSrc, enmTraceEvt, idEvtPrev, pvEvtDesc, cbEvtDesc, pidEvt));
106
107 PDBGFTRACERSHARED pSharedCC = pThisCC->CTX_SUFF(pShared);
108 size_t cRingBufEvts = dbgfTracerGetRingBufSz(pThisCC) / DBGF_TRACER_EVT_SZ;
109 AssertReturn(cRingBufEvts, VERR_DBGF_TRACER_IPE_1);
110 AssertReturn(cbEvtDesc <= DBGF_TRACER_EVT_PAYLOAD_SZ, VERR_DBGF_TRACER_IPE_1);
111
112 /* Grab a new event ID first. */
113 uint64_t idEvt = ASMAtomicIncU64(&pSharedCC->idEvt) - 1;
114 uint64_t idxRingBuf = idEvt % cRingBufEvts; /* This gives the index in the ring buffer for the event. */
115 PDBGFTRACEREVTHDR pEvtHdr = (PDBGFTRACEREVTHDR)(pThisCC->CTX_SUFF(pbRingBuf) + idxRingBuf * DBGF_TRACER_EVT_SZ);
116
117 if (RT_UNLIKELY(ASMAtomicReadU64(&pEvtHdr->idEvt) != DBGF_TRACER_EVT_HDR_ID_INVALID))
118 {
119 /** @todo The event ring buffer is full and we need to go back (from R0 to R3) and wait for the flusher thread to
120 * get its act together.
121 */
122 AssertMsgFailed(("Flush thread can't keep up with event amount!\n"));
123 }
124
125 /* Write the event and kick the flush thread if necessary. */
126 if (cbEvtDesc)
127 memcpy(pEvtHdr + 1, pvEvtDesc, cbEvtDesc);
128 pEvtHdr->idEvtPrev = idEvtPrev;
129 pEvtHdr->hEvtSrc = hEvtSrc;
130 pEvtHdr->enmEvt = enmTraceEvt;
131 pEvtHdr->fFlags = DBGF_TRACER_EVT_HDR_F_DEFAULT;
132 ASMAtomicWriteU64(&pEvtHdr->idEvt, idEvt);
133
134 int rc = VINF_SUCCESS;
135 if (!ASMAtomicXchgBool(&pSharedCC->fEvtsWaiting, true))
136 {
137 if (!ASMAtomicXchgBool(&pSharedCC->fFlushThrdActive, true))
138 rc = SUPSemEventSignal(pVM->pSession, pSharedCC->hSupSemEvtFlush);
139 }
140
141 if (pidEvt)
142 *pidEvt = idEvt;
143 return rc;
144}
145
146
147/**
148 * Posts a single event descriptor to the ring buffer of the given tracer instance.
149 *
150 * @returns VBox status code.
151 * @param pVM The current context VM instance data.
152 * @param pThisCC The event tracer instance current context data.
153 * @param hEvtSrc The event source for the posted event.
154 * @param enmTraceEvt The trace event type posted.
155 * @param pvEvtDesc The event descriptor to copy after the header.
156 * @param pidEvt Where to store the assigned event ID, optional.
157 */
158DECLINLINE(int) dbgfTracerEvtPostSingle(PVMCC pVM, PDBGFTRACERINSCC pThisCC, DBGFTRACEREVTSRC hEvtSrc,
159 DBGFTRACEREVT enmTraceEvt, const void *pvEvtDesc, uint64_t *pidEvt)
160{
161 return dbgfTracerEvtPostEx(pVM, pThisCC, hEvtSrc, enmTraceEvt, DBGF_TRACER_EVT_HDR_ID_INVALID,
162 pvEvtDesc, DBGF_TRACER_EVT_PAYLOAD_SZ, pidEvt);
163}
164
165
166#ifdef IN_RING3
167/**
168 * Posts a single event descriptor to the ring buffer of the given tracer instance - R3 only variant
169 * (used for the register/deregister event source events currently).
170 *
171 * @returns VBox status code.
172 * @param pVM The current context VM instance data.
173 * @param pThisCC The event tracer instance current context data.
174 * @param hEvtSrc The event source for the posted event.
175 * @param enmTraceEvt The trace event type posted.
176 * @param pvEvtDesc The event descriptor to copy after the header.
177 * @param cbEvtDesc Event descriptor size in bytes.
178 * @param pidEvt Where to store the assigned event ID, optional.
179 */
180DECLHIDDEN(int) dbgfTracerR3EvtPostSingle(PVMCC pVM, PDBGFTRACERINSCC pThisCC, DBGFTRACEREVTSRC hEvtSrc,
181 DBGFTRACEREVT enmTraceEvt, const void *pvEvtDesc, size_t cbEvtDesc,
182 uint64_t *pidEvt)
183{
184 return dbgfTracerEvtPostEx(pVM, pThisCC, hEvtSrc, enmTraceEvt, DBGF_TRACER_EVT_HDR_ID_INVALID,
185 pvEvtDesc, cbEvtDesc, pidEvt);
186}
187#endif
188
189/**
190 * Copies the given MMIO value into the event descriptor based on the given size.
191 *
192 * @returns nothing.
193 * @param pEvtMmio Pointer to the MMIO event descriptor to fill.
194 * @param pvVal The value to copy.
195 * @param cbVal Size of the value in bytes.
196 */
197static void dbgfTracerEvtMmioCopyVal(PDBGFTRACEREVTMMIO pEvtMmio, const void *pvVal, size_t cbVal)
198{
199 switch (cbVal)
200 {
201 case 1:
202 pEvtMmio->u64Val = *(uint8_t *)pvVal;
203 break;
204 case 2:
205 pEvtMmio->u64Val = *(uint16_t *)pvVal;
206 break;
207 case 4:
208 pEvtMmio->u64Val = *(uint32_t *)pvVal;
209 break;
210 case 8:
211 pEvtMmio->u64Val = *(uint64_t *)pvVal;
212 break;
213 default:
214 AssertMsgFailed(("The value size %zu is not supported!\n", cbVal));
215 }
216}
217
218
219/**
220 * Copies the given I/O port value into the event descriptor based on the given size.
221 *
222 * @returns nothing.
223 * @param pEvtIoPort Pointer to the I/O port read/write event descriptor to fill.
224 * @param pvVal The value to copy.
225 * @param cbVal Size of the value in bytes.
226 */
227static void dbgfTracerEvtIoPortCopyVal(PDBGFTRACEREVTIOPORT pEvtIoPort, const void *pvVal, size_t cbVal)
228{
229 switch (cbVal)
230 {
231 case 1:
232 pEvtIoPort->u32Val = *(uint8_t *)pvVal;
233 break;
234 case 2:
235 pEvtIoPort->u32Val = *(uint16_t *)pvVal;
236 break;
237 case 4:
238 pEvtIoPort->u32Val = *(uint32_t *)pvVal;
239 break;
240 default:
241 AssertMsgFailed(("The value size %zu is not supported!\n", cbVal));
242 }
243}
244
245
246/**
247 * Handles a guest memory transfer event.
248 *
249 * @returns VBox status code.
250 * @param pVM The current context VM instance data.
251 * @param pThisCC The event tracer instance current context data.
252 * @param enmTraceEvt The trace event type posted.
253 * @param hEvtSrc The event source for the posted event.
254 * @param GCPhys The guest physical address the transfer starts at.
255 * @param pvBuf The data being transfered.
256 * @param cbXfer Number of bytes being transfered.
257 */
258static int dbgfTracerEvtGCPhys(PVMCC pVM, PDBGFTRACERINSCC pThisCC, DBGFTRACEREVT enmTraceEvt, DBGFTRACEREVTSRC hEvtSrc,
259 RTGCPHYS GCPhys, const void *pvBuf, size_t cbXfer)
260{
261 /* Fast path for really small transfers where everything fits into the descriptor. */
262 DBGFTRACEREVTGCPHYS EvtGCPhys;
263 EvtGCPhys.GCPhys = GCPhys;
264 EvtGCPhys.cbXfer = cbXfer;
265 if (cbXfer <= sizeof(EvtGCPhys.abData))
266 {
267 memcpy(&EvtGCPhys.abData[0], pvBuf, cbXfer);
268 return dbgfTracerEvtPostSingle(pVM, pThisCC, hEvtSrc, enmTraceEvt, &EvtGCPhys, NULL /*pidEvt*/);
269 }
270
271 /*
272 * Slow path where we have to split the data into multiple entries.
273 * Each one is linked to the previous one by the previous event ID.
274 */
275 const uint8_t *pbBuf = (const uint8_t *)pvBuf;
276 size_t cbLeft = cbXfer;
277 uint64_t idEvtPrev = 0;
278 memcpy(&EvtGCPhys.abData[0], pbBuf, sizeof(EvtGCPhys.abData));
279 pbBuf += sizeof(EvtGCPhys.abData);
280 cbLeft -= sizeof(EvtGCPhys.abData);
281
282 int rc = dbgfTracerEvtPostSingle(pVM, pThisCC, hEvtSrc, enmTraceEvt, &EvtGCPhys, &idEvtPrev);
283 while ( RT_SUCCESS(rc)
284 && cbLeft)
285 {
286 size_t cbThisXfer = RT_MIN(cbLeft, DBGF_TRACER_EVT_PAYLOAD_SZ);
287 rc = dbgfTracerEvtPostEx(pVM, pThisCC, hEvtSrc, enmTraceEvt, idEvtPrev,
288 pbBuf, cbThisXfer, &idEvtPrev);
289
290 pbBuf += cbThisXfer;
291 cbLeft -= cbThisXfer;
292 }
293
294 return rc;
295}
296
297
298/**
299 * Handles a I/O port string transfer event.
300 *
301 * @returns VBox status code.
302 * @param pVM The current context VM instance data.
303 * @param pThisCC The event tracer instance current context data.
304 * @param enmTraceEvt The trace event type posted.
305 * @param hEvtSrc The event source for the posted event.
306 * @param hIoPorts The I/O port region handle for the transfer.
307 * @param offPort The offset into the region where the transfer happened.
308 * @param pv The data being transfered.
309 * @param cb Number of bytes of valid data in the buffer.
310 * @param cbItem Item size in bytes.
311 * @param cTransfersReq Number of transfers requested.
312 * @param cTransfersRet Number of transfers done.
313 */
314static int dbgfTracerEvtIoPortStr(PVMCC pVM, PDBGFTRACERINSCC pThisCC, DBGFTRACEREVT enmTraceEvt, DBGFTRACEREVTSRC hEvtSrc,
315 uint64_t hIoPorts, RTIOPORT offPort, const void *pv, size_t cb, size_t cbItem, uint32_t cTransfersReq,
316 uint32_t cTransfersRet)
317{
318 /* Fast path for really small transfers where everything fits into the descriptor. */
319 DBGFTRACEREVTIOPORTSTR EvtIoPortStr;
320 EvtIoPortStr.hIoPorts = hIoPorts;
321 EvtIoPortStr.cbItem = (uint32_t)cbItem;
322 EvtIoPortStr.cTransfersReq = cTransfersReq;
323 EvtIoPortStr.cTransfersRet = cTransfersRet;
324 EvtIoPortStr.offPort = offPort;
325 if (cb <= sizeof(EvtIoPortStr.abData))
326 {
327 memcpy(&EvtIoPortStr.abData[0], pv, cb);
328 return dbgfTracerEvtPostSingle(pVM, pThisCC, hEvtSrc, enmTraceEvt, &EvtIoPortStr, NULL /*pidEvt*/);
329 }
330
331 /*
332 * Slow path where we have to split the data into multiple entries.
333 * Each one is linked to the previous one by the previous event ID.
334 */
335 const uint8_t *pbBuf = (const uint8_t *)pv;
336 size_t cbLeft = cb;
337 uint64_t idEvtPrev = 0;
338 memcpy(&EvtIoPortStr.abData[0], pbBuf, sizeof(EvtIoPortStr.abData));
339 pbBuf += sizeof(EvtIoPortStr.abData);
340 cbLeft -= sizeof(EvtIoPortStr.abData);
341
342 int rc = dbgfTracerEvtPostSingle(pVM, pThisCC, hEvtSrc, enmTraceEvt, &EvtIoPortStr, &idEvtPrev);
343 while ( RT_SUCCESS(rc)
344 && cbLeft)
345 {
346 size_t cbThisXfer = RT_MIN(cbLeft, DBGF_TRACER_EVT_PAYLOAD_SZ);
347 rc = dbgfTracerEvtPostEx(pVM, pThisCC, hEvtSrc, enmTraceEvt, idEvtPrev,
348 pbBuf, cbThisXfer, &idEvtPrev);
349
350 pbBuf += cbThisXfer;
351 cbLeft -= cbThisXfer;
352 }
353
354 return rc;
355}
356
357
358/**
359 * Registers an MMIO region mapping event for the given event source.
360 *
361 * @returns VBox status code.
362 * @param pVM The current context VM instance data.
363 * @param hEvtSrc The event source for the posted event.
364 * @param hRegion The MMIO region handle being mapped.
365 * @param GCPhysMmio The guest physical address where the region is mapped.
366 */
367VMM_INT_DECL(int) DBGFTracerEvtMmioMap(PVMCC pVM, DBGFTRACEREVTSRC hEvtSrc, uint64_t hRegion, RTGCPHYS GCPhysMmio)
368{
369 PDBGFTRACERINSCC pThisCC = dbgfTracerGetInstance(pVM);
370 AssertReturn(pThisCC, VERR_DBGF_TRACER_IPE_1);
371
372 DBGFTRACEREVTMMIOMAP EvtMmioMap;
373 EvtMmioMap.hMmioRegion = hRegion;
374 EvtMmioMap.GCPhysMmioBase = GCPhysMmio;
375 EvtMmioMap.au64Pad0[0] = 0;
376 EvtMmioMap.au64Pad0[1] = 0;
377
378 return dbgfTracerEvtPostSingle(pVM, pThisCC, hEvtSrc, DBGFTRACEREVT_MMIO_MAP, &EvtMmioMap, NULL /*pidEvt*/);
379}
380
381
382/**
383 * Registers an MMIO region unmap event for the given event source.
384 *
385 * @returns VBox status code.
386 * @param pVM The current context VM instance data.
387 * @param hEvtSrc The event source for the posted event.
388 * @param hRegion The MMIO region handle being unmapped.
389 */
390VMM_INT_DECL(int) DBGFTracerEvtMmioUnmap(PVMCC pVM, DBGFTRACEREVTSRC hEvtSrc, uint64_t hRegion)
391{
392 PDBGFTRACERINSCC pThisCC = dbgfTracerGetInstance(pVM);
393 AssertReturn(pThisCC, VERR_DBGF_TRACER_IPE_1);
394
395 DBGFTRACEREVTMMIOUNMAP EvtMmioUnmap;
396 EvtMmioUnmap.hMmioRegion = hRegion;
397 EvtMmioUnmap.au64Pad0[0] = 0;
398 EvtMmioUnmap.au64Pad0[1] = 0;
399 EvtMmioUnmap.au64Pad0[2] = 0;
400
401 return dbgfTracerEvtPostSingle(pVM, pThisCC, hEvtSrc, DBGFTRACEREVT_MMIO_UNMAP, &EvtMmioUnmap, NULL /*pidEvt*/);
402}
403
404
405/**
406 * Registers an MMIO region read event for the given event source.
407 *
408 * @returns VBox status code.
409 * @param pVM The current context VM instance data.
410 * @param hEvtSrc The event source for the posted event.
411 * @param hRegion The MMIO region handle being read.
412 * @param offMmio The MMIO offset into the region where the read happened.
413 * @param pvVal The value being read.
414 * @param cbVal Value size in bytes.
415 */
416VMM_INT_DECL(int) DBGFTracerEvtMmioRead(PVMCC pVM, DBGFTRACEREVTSRC hEvtSrc, uint64_t hRegion, RTGCPHYS offMmio, const void *pvVal, size_t cbVal)
417{
418 PDBGFTRACERINSCC pThisCC = dbgfTracerGetInstance(pVM);
419 AssertReturn(pThisCC, VERR_DBGF_TRACER_IPE_1);
420
421 DBGFTRACEREVTMMIO EvtMmio;
422 EvtMmio.hMmioRegion = hRegion;
423 EvtMmio.offMmio = offMmio;
424 EvtMmio.cbXfer = cbVal;
425 dbgfTracerEvtMmioCopyVal(&EvtMmio, pvVal, cbVal);
426
427 return dbgfTracerEvtPostSingle(pVM, pThisCC, hEvtSrc, DBGFTRACEREVT_MMIO_READ, &EvtMmio, NULL /*pidEvt*/);
428}
429
430
431/**
432 * Registers an MMIO region write event for the given event source.
433 *
434 * @returns VBox status code.
435 * @param pVM The current context VM instance data.
436 * @param hEvtSrc The event source for the posted event.
437 * @param hRegion The MMIO region handle being written to.
438 * @param offMmio The MMIO offset into the region where the write happened.
439 * @param pvVal The value being written.
440 * @param cbVal Value size in bytes.
441 */
442VMM_INT_DECL(int) DBGFTracerEvtMmioWrite(PVMCC pVM, DBGFTRACEREVTSRC hEvtSrc, uint64_t hRegion, RTGCPHYS offMmio, const void *pvVal, size_t cbVal)
443{
444 PDBGFTRACERINSCC pThisCC = dbgfTracerGetInstance(pVM);
445 AssertReturn(pThisCC, VERR_DBGF_TRACER_IPE_1);
446
447 DBGFTRACEREVTMMIO EvtMmio;
448 EvtMmio.hMmioRegion = hRegion;
449 EvtMmio.offMmio = offMmio;
450 EvtMmio.cbXfer = cbVal;
451 dbgfTracerEvtMmioCopyVal(&EvtMmio, pvVal, cbVal);
452
453 return dbgfTracerEvtPostSingle(pVM, pThisCC, hEvtSrc, DBGFTRACEREVT_MMIO_WRITE, &EvtMmio, NULL /*pidEvt*/);
454}
455
456
457/**
458 * Registers an MMIO region fill event for the given event source.
459 *
460 * @returns VBox status code.
461 * @param pVM The current context VM instance data.
462 * @param hEvtSrc The event source for the posted event.
463 * @param hRegion The MMIO region handle being filled.
464 * @param offMmio The MMIO offset into the region where the fill starts.
465 * @param u32Item The value being used for filling.
466 * @param cbItem Item size in bytes.
467 * @param cItems Number of items being written.
468 */
469VMM_INT_DECL(int) DBGFTracerEvtMmioFill(PVMCC pVM, DBGFTRACEREVTSRC hEvtSrc, uint64_t hRegion, RTGCPHYS offMmio,
470 uint32_t u32Item, uint32_t cbItem, uint32_t cItems)
471{
472 PDBGFTRACERINSCC pThisCC = dbgfTracerGetInstance(pVM);
473 AssertReturn(pThisCC, VERR_DBGF_TRACER_IPE_1);
474
475 DBGFTRACEREVTMMIOFILL EvtMmioFill;
476 EvtMmioFill.hMmioRegion = hRegion;
477 EvtMmioFill.offMmio = offMmio;
478 EvtMmioFill.cbItem = cbItem;
479 EvtMmioFill.cItems = cItems;
480 EvtMmioFill.u32Item = u32Item;
481 EvtMmioFill.u32Pad0 = 0;
482
483 return dbgfTracerEvtPostSingle(pVM, pThisCC, hEvtSrc, DBGFTRACEREVT_MMIO_FILL, &EvtMmioFill, NULL /*pidEvt*/);
484}
485
486
487/**
488 * Registers an I/O region mapping event for the given event source.
489 *
490 * @returns VBox status code.
491 * @param pVM The current context VM instance data.
492 * @param hEvtSrc The event source for the posted event.
493 * @param hIoPorts The I/O port region handle being mapped.
494 * @param IoPortBase The I/O port base where the region is mapped.
495 */
496VMM_INT_DECL(int) DBGFTracerEvtIoPortMap(PVMCC pVM, DBGFTRACEREVTSRC hEvtSrc, uint64_t hIoPorts, RTIOPORT IoPortBase)
497{
498 PDBGFTRACERINSCC pThisCC = dbgfTracerGetInstance(pVM);
499 AssertReturn(pThisCC, VERR_DBGF_TRACER_IPE_1);
500
501 DBGFTRACEREVTIOPORTMAP EvtIoPortMap;
502 RT_ZERO(EvtIoPortMap);
503 EvtIoPortMap.hIoPorts = hIoPorts;
504 EvtIoPortMap.IoPortBase = IoPortBase;
505
506 return dbgfTracerEvtPostSingle(pVM, pThisCC, hEvtSrc, DBGFTRACEREVT_IOPORT_MAP, &EvtIoPortMap, NULL /*pidEvt*/);
507}
508
509
510/**
511 * Registers an I/O region unmap event for the given event source.
512 *
513 * @returns VBox status code.
514 * @param pVM The current context VM instance data.
515 * @param hEvtSrc The event source for the posted event.
516 * @param hIoPorts The I/O port region handle being unmapped.
517 */
518VMM_INT_DECL(int) DBGFTracerEvtIoPortUnmap(PVMCC pVM, DBGFTRACEREVTSRC hEvtSrc, uint64_t hIoPorts)
519{
520 PDBGFTRACERINSCC pThisCC = dbgfTracerGetInstance(pVM);
521 AssertReturn(pThisCC, VERR_DBGF_TRACER_IPE_1);
522
523 DBGFTRACEREVTIOPORTUNMAP EvtIoPortUnmap;
524 EvtIoPortUnmap.hIoPorts = hIoPorts;
525 EvtIoPortUnmap.au64Pad0[0] = 0;
526 EvtIoPortUnmap.au64Pad0[1] = 0;
527 EvtIoPortUnmap.au64Pad0[2] = 0;
528
529 return dbgfTracerEvtPostSingle(pVM, pThisCC, hEvtSrc, DBGFTRACEREVT_IOPORT_UNMAP, &EvtIoPortUnmap, NULL /*pidEvt*/);
530}
531
532
533/**
534 * Registers an I/O region read event for the given event source.
535 *
536 * @returns VBox status code.
537 * @param pVM The current context VM instance data.
538 * @param hEvtSrc The event source for the posted event.
539 * @param hIoPorts The I/O port region handle being read from.
540 * @param offPort The offset into the region where the read happened.
541 * @param pvVal The value being read.
542 * @param cbVal Value size in bytes.
543 */
544VMM_INT_DECL(int) DBGFTracerEvtIoPortRead(PVMCC pVM, DBGFTRACEREVTSRC hEvtSrc, uint64_t hIoPorts, RTIOPORT offPort, const void *pvVal, size_t cbVal)
545{
546 PDBGFTRACERINSCC pThisCC = dbgfTracerGetInstance(pVM);
547 AssertReturn(pThisCC, VERR_DBGF_TRACER_IPE_1);
548
549 DBGFTRACEREVTIOPORT EvtIoPort;
550 RT_ZERO(EvtIoPort);
551 EvtIoPort.hIoPorts = hIoPorts;
552 EvtIoPort.offPort = offPort;
553 EvtIoPort.cbXfer = cbVal;
554 dbgfTracerEvtIoPortCopyVal(&EvtIoPort, pvVal, cbVal);
555
556 return dbgfTracerEvtPostSingle(pVM, pThisCC, hEvtSrc, DBGFTRACEREVT_IOPORT_READ, &EvtIoPort, NULL /*pidEvt*/);
557}
558
559
560/**
561 * Registers an I/O region string read event for the given event source.
562 *
563 * @returns VBox status code.
564 * @param pVM The current context VM instance data.
565 * @param hEvtSrc The event source for the posted event.
566 * @param hIoPorts The I/O port region handle being read from.
567 * @param offPort The offset into the region where the read happened.
568 * @param pv The data being read.
569 * @param cb Item size in bytes.
570 * @param cTransfersReq Number of transfers requested.
571 * @param cTransfersRet Number of transfers done.
572 */
573VMM_INT_DECL(int) DBGFTracerEvtIoPortReadStr(PVMCC pVM, DBGFTRACEREVTSRC hEvtSrc, uint64_t hIoPorts, RTIOPORT offPort, const void *pv, size_t cb,
574 uint32_t cTransfersReq, uint32_t cTransfersRet)
575{
576 PDBGFTRACERINSCC pThisCC = dbgfTracerGetInstance(pVM);
577 AssertReturn(pThisCC, VERR_DBGF_TRACER_IPE_1);
578
579 return dbgfTracerEvtIoPortStr(pVM, pThisCC, DBGFTRACEREVT_IOPORT_READ_STR, hEvtSrc, hIoPorts, offPort, pv, cTransfersRet * cb,
580 cb, cTransfersReq, cTransfersRet);
581}
582
583
584/**
585 * Registers an I/O region write event for the given event source.
586 *
587 * @returns VBox status code.
588 * @param pVM The current context VM instance data.
589 * @param hEvtSrc The event source for the posted event.
590 * @param hIoPorts The I/O port region handle being written to.
591 * @param offPort The offset into the region where the write happened.
592 * @param pvVal The value being written.
593 * @param cbVal Value size in bytes.
594 */
595VMM_INT_DECL(int) DBGFTracerEvtIoPortWrite(PVMCC pVM, DBGFTRACEREVTSRC hEvtSrc, uint64_t hIoPorts, RTIOPORT offPort, const void *pvVal, size_t cbVal)
596{
597 PDBGFTRACERINSCC pThisCC = dbgfTracerGetInstance(pVM);
598 AssertReturn(pThisCC, VERR_DBGF_TRACER_IPE_1);
599
600 DBGFTRACEREVTIOPORT EvtIoPort;
601 RT_ZERO(EvtIoPort);
602 EvtIoPort.hIoPorts = hIoPorts;
603 EvtIoPort.offPort = offPort;
604 EvtIoPort.cbXfer = cbVal;
605 dbgfTracerEvtIoPortCopyVal(&EvtIoPort, pvVal, cbVal);
606
607 return dbgfTracerEvtPostSingle(pVM, pThisCC, hEvtSrc, DBGFTRACEREVT_IOPORT_WRITE, &EvtIoPort, NULL /*pidEvt*/);
608}
609
610
611/**
612 * Registers an I/O region string write event for the given event source.
613 *
614 * @returns VBox status code.
615 * @param pVM The current context VM instance data.
616 * @param hEvtSrc The event source for the posted event.
617 * @param hIoPorts The I/O port region handle being written to.
618 * @param offPort The offset into the region where the write happened.
619 * @param pv The data being written.
620 * @param cb Item size in bytes.
621 * @param cTransfersReq Number of transfers requested.
622 * @param cTransfersRet Number of transfers done.
623 */
624VMM_INT_DECL(int) DBGFTracerEvtIoPortWriteStr(PVMCC pVM, DBGFTRACEREVTSRC hEvtSrc, uint64_t hIoPorts, RTIOPORT offPort, const void *pv, size_t cb,
625 uint32_t cTransfersReq, uint32_t cTransfersRet)
626{
627 PDBGFTRACERINSCC pThisCC = dbgfTracerGetInstance(pVM);
628 AssertReturn(pThisCC, VERR_DBGF_TRACER_IPE_1);
629
630 return dbgfTracerEvtIoPortStr(pVM, pThisCC, DBGFTRACEREVT_IOPORT_WRITE_STR, hEvtSrc, hIoPorts, offPort, pv, cTransfersReq * cb,
631 cb, cTransfersReq, cTransfersRet);
632}
633
634
635/**
636 * Registers an IRQ change event for the given event source.
637 *
638 * @returns VBox status code.
639 * @param pVM The current context VM instance data.
640 * @param hEvtSrc The event source for the posted event.
641 * @param iIrq The IRQ line changed.
642 * @param fIrqLvl The new IRQ level mask.
643 */
644VMM_INT_DECL(int) DBGFTracerEvtIrq(PVMCC pVM, DBGFTRACEREVTSRC hEvtSrc, int32_t iIrq, int32_t fIrqLvl)
645{
646 PDBGFTRACERINSCC pThisCC = dbgfTracerGetInstance(pVM);
647 AssertReturn(pThisCC, VERR_DBGF_TRACER_IPE_1);
648
649 DBGFTRACEREVTIRQ EvtIrq;
650 RT_ZERO(EvtIrq);
651 EvtIrq.iIrq = iIrq;
652 EvtIrq.fIrqLvl = fIrqLvl;
653
654 return dbgfTracerEvtPostSingle(pVM, pThisCC, hEvtSrc, DBGFTRACEREVT_IRQ, &EvtIrq, NULL /*pidEvt*/);
655}
656
657
658/**
659 * Registers an I/O APIC MSI event for the given event source.
660 *
661 * @returns VBox status code.
662 * @param pVM The current context VM instance data.
663 * @param hEvtSrc The event source for the posted event.
664 * @param GCPhys Guest physical address where the value is written to.
665 * @param u32Val The MSI event value being written.
666 */
667VMM_INT_DECL(int) DBGFTracerEvtIoApicMsi(PVMCC pVM, DBGFTRACEREVTSRC hEvtSrc, RTGCPHYS GCPhys, uint32_t u32Val)
668{
669 PDBGFTRACERINSCC pThisCC = dbgfTracerGetInstance(pVM);
670 AssertReturn(pThisCC, VERR_DBGF_TRACER_IPE_1);
671
672 DBGFTRACEREVTIOAPICMSI EvtMsi;
673 RT_ZERO(EvtMsi);
674 EvtMsi.GCPhys = GCPhys;
675 EvtMsi.u32Val = u32Val;
676
677 return dbgfTracerEvtPostSingle(pVM, pThisCC, hEvtSrc, DBGFTRACEREVT_IOAPIC_MSI, &EvtMsi, NULL /*pidEvt*/);
678}
679
680
681/**
682 * Registers an guest physical memory read event for the given event source.
683 *
684 * @returns VBox status code.
685 * @param pVM The current context VM instance data.
686 * @param hEvtSrc The event source for the posted event.
687 * @param GCPhys Guest physical address the read started at.
688 * @param pvBuf The read data.
689 * @param cbRead Number of bytes read.
690 */
691VMM_INT_DECL(int) DBGFTracerEvtGCPhysRead(PVMCC pVM, DBGFTRACEREVTSRC hEvtSrc, RTGCPHYS GCPhys, const void *pvBuf, size_t cbRead)
692{
693 PDBGFTRACERINSCC pThisCC = dbgfTracerGetInstance(pVM);
694 AssertReturn(pThisCC, VERR_DBGF_TRACER_IPE_1);
695
696 return dbgfTracerEvtGCPhys(pVM, pThisCC, DBGFTRACEREVT_GCPHYS_READ, hEvtSrc, GCPhys, pvBuf, cbRead);
697}
698
699
700/**
701 * Registers an guest physical memory write event for the given event source.
702 *
703 * @returns VBox status code.
704 * @param pVM The current context VM instance data.
705 * @param hEvtSrc The event source for the posted event.
706 * @param GCPhys Guest physical address the write started at.
707 * @param pvBuf The written data.
708 * @param cbWrite Number of bytes written.
709 */
710VMM_INT_DECL(int) DBGFTracerEvtGCPhysWrite(PVMCC pVM, DBGFTRACEREVTSRC hEvtSrc, RTGCPHYS GCPhys, const void *pvBuf, size_t cbWrite)
711{
712 PDBGFTRACERINSCC pThisCC = dbgfTracerGetInstance(pVM);
713 AssertReturn(pThisCC, VERR_DBGF_TRACER_IPE_1);
714
715 return dbgfTracerEvtGCPhys(pVM, pThisCC, DBGFTRACEREVT_GCPHYS_WRITE, hEvtSrc, GCPhys, pvBuf, cbWrite);
716}
717
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette