VirtualBox

Changeset 84458 in vbox


Ignore:
Timestamp:
May 22, 2020 12:51:49 PM (5 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
138165
Message:

VMM/DBGF: First commit of new tracing facility, bugref:9210

The new DBGF tracing facility allows efficient capturing of events to a compact binary
trace log for later analysis. It is primarily intended for recording device/guest
interactions for now but can be extended easily for other types of events later on.
It supports capturing events happening in both R0 and R3 by using a shared ring buffer
to post events to. The events are processed by a dedicated I/O thread which writes
new events into the binary trace log file.

This is only the core VMM/DBGF part providing the API, the integration with PDM
comes in a separate commit.

Disabled by default for now because it is still work in progress,
enable with VBOX_WITH_DBGF_TRACING.

Location:
trunk
Files:
3 added
11 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/VBox/err.h

    r84317 r84458  
    321321/** No trace buffer available, please change the VM config. */
    322322#define VERR_DBGF_NO_TRACE_BUFFER           (-1220)
     323/** Internal processing error \#1 in the DBGF event tracing code. */
     324#define VERR_DBGF_TRACER_IPE_1              (-1221)
    323325/** @} */
    324326
  • trunk/include/VBox/types.h

    r82968 r84458  
    498498typedef const struct CPUMSELREG *PCCPUMSELREGHID;
    499499
     500/** A cross context DBGF tracer event source handle. */
     501typedef uint64_t                DBGFTRACEREVTSRC;
     502/** Pointer to a cross context DBGF tracer event source handle. */
     503typedef DBGFTRACEREVTSRC        *PDBGFTRACEREVTSRC;
     504/** A NIL DBGF tracer event source handle. */
     505#define NIL_DBGFTRACEREVTSRC    ((uint64_t)UINT64_MAX)
     506
     507/** Pointer to a DBGF tracer instance for the current context. */
     508#ifdef IN_RING3
     509typedef struct DBGFTRACERINSR3 *PDBGFTRACERINSCC;
     510#elif defined(IN_RING0) || defined(DOXYGEN_RUNNING)
     511typedef struct DBGFTRACERINSR0 *PDBGFTRACERINSCC;
     512#else
     513typedef struct DBGFTRACERINSRC *PDBGFTRACERINSCC;
     514#endif
     515/** Pointer to a pointer a DBGF tracer instance for the current context. */
     516typedef PDBGFTRACERINSCC *PPDBGFTRACERINSCC;
     517/** R3 pointer to a DBGF tracer instance. */
     518typedef R3PTRTYPE(struct DBGFTRACERINSR3 *) PDBGFTRACERINSR3;
     519/** R0 pointer to a DBGF tracer instance. */
     520typedef R0PTRTYPE(struct DBGFTRACERINSR0 *) PDBGFTRACERINSR0;
     521/** RC pointer to a DBGF tracer instance. */
     522typedef RCPTRTYPE(struct DBGFTRACERINSRC *) PDBGFTRACERINSRC;
    500523/** @} */
    501524
  • trunk/include/VBox/vmm/dbgf.h

    r82968 r84458  
    5555#endif
    5656
     57
     58/** @defgroup grp_dbgf_r0  The R0 DBGF API
     59 * @{
     60 */
     61/**
     62 * Request buffer for DBGFR0TracerCreateReqHandler / VMMR0_DO_DBGF_TRACER_CREATE.
     63 * @see DBGFR0TracerCreateReqHandler.
     64 */
     65typedef struct DBGFTRACERCREATEREQ
     66{
     67    /** The header. */
     68    SUPVMMR0REQHDR          Hdr;
     69    /** Out: Where to return the address of the ring-3 tracer instance. */
     70    PDBGFTRACERINSR3        pTracerInsR3;
     71
     72    /** Number of bytes for the shared event ring buffer. */
     73    uint32_t                cbRingBuf;
     74
     75    /** Set if the raw-mode component is desired. */
     76    bool                    fRCEnabled;
     77    /** Explicit padding. */
     78    bool                    afReserved[3];
     79
     80} DBGFTRACERCREATEREQ;
     81/** Pointer to a DBGFR0TracerCreate / VMMR0_DO_DBGF_TRACER_CREATE request buffer. */
     82typedef DBGFTRACERCREATEREQ *PDBGFTRACERCREATEREQ;
     83
     84VMMR0_INT_DECL(int) DBGFR0TracerCreateReqHandler(PGVM pGVM, PDBGFTRACERCREATEREQ pReq);
     85/** @} */
    5786
    5887
     
    27892818#endif /* IN_RING3 */
    27902819
     2820
     2821/** @defgroup grp_dbgf_tracer  DBGF event tracing.
     2822 * @{ */
     2823#ifdef IN_RING3
     2824VMMR3_INT_DECL(int) DBGFR3TracerRegisterEvtSrc(PVM pVM, const char *pszName, PDBGFTRACEREVTSRC phEvtSrc);
     2825VMMR3_INT_DECL(int) DBGFR3TracerDeregisterEvtSrc(PVM pVM, DBGFTRACEREVTSRC hEvtSrc);
     2826#endif
     2827
     2828VMM_INT_DECL(int)   DBGFTracerEvtMmioMap(PVMCC pVM, DBGFTRACEREVTSRC hEvtSrc, uint64_t hRegion, RTGCPHYS GCPhysMmio);
     2829VMM_INT_DECL(int)   DBGFTracerEvtMmioUnmap(PVMCC pVM, DBGFTRACEREVTSRC hEvtSrc, uint64_t hRegion);
     2830VMM_INT_DECL(int)   DBGFTracerEvtMmioRead(PVMCC pVM, DBGFTRACEREVTSRC hEvtSrc, uint64_t hRegion, RTGCPHYS offMmio, const void *pvVal, size_t cbVal);
     2831VMM_INT_DECL(int)   DBGFTracerEvtMmioWrite(PVMCC pVM, DBGFTRACEREVTSRC hEvtSrc, uint64_t hRegion, RTGCPHYS offMmio, const void *pvVal, size_t cbVal);
     2832VMM_INT_DECL(int)   DBGFTracerEvtMmioFill(PVMCC pVM, DBGFTRACEREVTSRC hEvtSrc, uint64_t hRegion, RTGCPHYS offMmio, uint32_t u32Item, uint32_t cbItem, uint32_t cItems);
     2833VMM_INT_DECL(int)   DBGFTracerEvtIoPortMap(PVMCC pVM, DBGFTRACEREVTSRC hEvtSrc, uint64_t hIoPorts, RTIOPORT IoPortBase);
     2834VMM_INT_DECL(int)   DBGFTracerEvtIoPortUnmap(PVMCC pVM, DBGFTRACEREVTSRC hEvtSrc, uint64_t hIoPorts);
     2835VMM_INT_DECL(int)   DBGFTracerEvtIoPortRead(PVMCC pVM, DBGFTRACEREVTSRC hEvtSrc, uint64_t hIoPorts, RTIOPORT offPort, const void *pvVal, size_t cbVal);
     2836VMM_INT_DECL(int)   DBGFTracerEvtIoPortWrite(PVMCC pVM, DBGFTRACEREVTSRC hEvtSrc, uint64_t hIoPorts, RTIOPORT offPort, const void *pvVal, size_t cbVal);
     2837VMM_INT_DECL(int)   DBGFTracerEvtIrq(PVMCC pVM, DBGFTRACEREVTSRC hEvtSrc, int32_t iIrq, int32_t fIrqLvl);
     2838VMM_INT_DECL(int)   DBGFTracerEvtIoApicMsi(PVMCC pVM, DBGFTRACEREVTSRC hEvtSrc, RTGCPHYS GCPhys, uint32_t u32Val);
     2839VMM_INT_DECL(int)   DBGFTracerEvtGCPhysRead(PVMCC pVM, DBGFTRACEREVTSRC hEvtSrc, RTGCPHYS GCPhys, const void *pvBuf, size_t cbRead);
     2840VMM_INT_DECL(int)   DBGFTracerEvtGCPhysWrite(PVMCC pVM, DBGFTRACEREVTSRC hEvtSrc, RTGCPHYS GCPhys, const void *pvBuf, size_t cbWrite);
    27912841/** @} */
    27922842
     2843/** @} */
    27932844
    27942845RT_C_DECLS_END
  • trunk/include/VBox/vmm/gvm.h

    r83941 r84458  
    229229    } apicr0;
    230230
     231    union
     232    {
     233#if defined(VMM_INCLUDED_SRC_include_DBGFInternal_h) && defined(IN_RING0)
     234        struct DBGFR0PERVM   s;
     235#endif
     236        uint8_t             padding[64];
     237    } dbgfr0;
     238
    231239    /** Padding so aCpus starts on a page boundrary.  */
    232240#ifdef VBOX_WITH_NEM_R0
    233     uint8_t         abPadding2[4096*2 - 64 - 256 - 1024 - 256 - 64 - 2176 - 640 - 512 - 64 - sizeof(PGVMCPU) * VMM_MAX_CPU_COUNT];
    234 #else
    235     uint8_t         abPadding2[4096*2 - 64 - 256 - 1024       - 64 - 2176 - 640 - 512 - 64 - sizeof(PGVMCPU) * VMM_MAX_CPU_COUNT];
     241    uint8_t         abPadding2[4096*2 - 64 - 256 - 1024 - 256 - 64 - 2176 - 640 - 512 - 64 - 64 - sizeof(PGVMCPU) * VMM_MAX_CPU_COUNT];
     242#else
     243    uint8_t         abPadding2[4096*2 - 64 - 256 - 1024       - 64 - 2176 - 640 - 512 - 64 - 64 - sizeof(PGVMCPU) * VMM_MAX_CPU_COUNT];
    236244#endif
    237245
  • trunk/include/VBox/vmm/mm.h

    r82968 r84458  
    7979    MM_TAG_DBGF_SYMBOL_DUP,
    8080    MM_TAG_DBGF_TYPE,
     81    MM_TAG_DBGF_TRACER,
    8182
    8283    MM_TAG_EM,
  • trunk/include/VBox/vmm/vmm.h

    r82968 r84458  
    426426    /** Official call we use for testing Ring-0 APIs. */
    427427    VMMR0_DO_TESTS = 704,
     428
     429    /** Call DBGFR0TraceCreateReqHandler. */
     430    VMMR0_DO_DBGF_TRACER_CREATE = 710,
     431    /** Call DBGFR0TraceCallReqHandler. */
     432    VMMR0_DO_DBGF_TRACER_CALL_REQ_HANDLER,
    428433
    429434    /** The usual 32-bit type blow up. */
  • trunk/src/VBox/VMM/Makefile.kmk

    r84007 r84458  
    6868ifdef VBOX_WITH_IOMMU_AMD
    6969VBoxVMM_DEFS    += VBOX_WITH_IOMMU_AMD
     70endif
     71ifdef VBOX_WITH_DBGF_TRACING
     72VBoxVMM_DEFS    += VBOX_WITH_DBGF_TRACING
    7073endif
    7174ifdef VBOX_WITH_RAW_MODE
     
    112115        VMMR3/DBGFR3Flow.cpp \
    113116        VMMR3/DBGFR3Trace.cpp \
     117        $(if-expr defined(VBOX_WITH_DBGF_TRACING), VMMR3/DBGFR3Tracer.cpp,) \
    114118        VMMR3/DBGFR3Type.cpp \
    115119        VMMR3/EM.cpp \
     
    177181        VMMAll/CPUMAllMsrs.cpp \
    178182        VMMAll/DBGFAll.cpp \
     183        $(if-expr defined(VBOX_WITH_DBGF_TRACING), VMMAll/DBGFAllTracer.cpp,) \
    179184        VMMAll/HMAll.cpp \
    180185        VMMAll/HMSVMAll.cpp \
     
    487492        VMMR0/CPUMR0.cpp \
    488493        VMMR0/CPUMR0A.asm \
     494        $(if-expr defined(VBOX_WITH_DBGF_TRACING), VMMR0/DBGFR0Tracer.cpp,) \
    489495        VMMR0/GIMR0.cpp \
    490496        VMMR0/GIMR0Hv.cpp \
     
    515521        VMMAll/CPUMAllMsrs.cpp \
    516522        VMMAll/DBGFAll.cpp \
     523        $(if-expr defined(VBOX_WITH_DBGF_TRACING), VMMAll/DBGFAllTracer.cpp,) \
    517524        VMMAll/EMAll.cpp \
    518525        VMMAll/GIMAll.cpp \
  • trunk/src/VBox/VMM/VMMAll/MMAll.cpp

    r82968 r84458  
    585585        TAG2STR(DBGF_SYMBOL_DUP);
    586586        TAG2STR(DBGF_TYPE);
     587        TAG2STR(DBGF_TRACER);
    587588
    588589        TAG2STR(EM);
  • trunk/src/VBox/VMM/VMMR0/VMMR0.cpp

    r82968 r84458  
    22262226        }
    22272227
     2228#ifdef VBOX_WITH_DBGF_TRACING
     2229        case VMMR0_DO_DBGF_TRACER_CREATE:
     2230        {
     2231            if (!pReqHdr || u64Arg || idCpu != 0)
     2232                return VERR_INVALID_PARAMETER;
     2233            rc = DBGFR0TracerCreateReqHandler(pGVM, (PDBGFTRACERCREATEREQ)pReqHdr);
     2234            VMM_CHECK_SMAP_CHECK2(pGVM, RT_NOTHING);
     2235            break;
     2236        }
     2237
     2238        case VMMR0_DO_DBGF_TRACER_CALL_REQ_HANDLER:
     2239        {
     2240            if (!pReqHdr || u64Arg)
     2241                return VERR_INVALID_PARAMETER;
     2242#if 0 /** @todo */
     2243            rc = DBGFR0TracerGenCallReqHandler(pGVM, (PDBGFTRACERGENCALLREQ)pReqHdr, idCpu);
     2244#else
     2245            rc = VERR_NOT_IMPLEMENTED;
     2246#endif
     2247            VMM_CHECK_SMAP_CHECK2(pGVM, RT_NOTHING);
     2248            break;
     2249        }
     2250#endif
     2251
    22282252        /*
    22292253         * For profiling.
  • trunk/src/VBox/VMM/VMMR3/DBGF.cpp

    r82968 r84458  
    186186                                if (RT_SUCCESS(rc))
    187187                                {
    188                                     return VINF_SUCCESS;
     188#ifdef VBOX_WITH_DBGF_TRACING
     189                                    rc = dbgfR3TracerInit(pVM);
     190#endif
     191                                    if (RT_SUCCESS(rc))
     192                                    {
     193                                        return VINF_SUCCESS;
     194                                    }
    189195                                }
    190196                                dbgfR3PlugInTerm(pUVM);
     
    216222    PUVM pUVM = pVM->pUVM;
    217223
     224#ifdef VBOX_WITH_DBGF_TRACING
     225    dbgfR3TracerTerm(pVM);
     226#endif
    218227    dbgfR3OSTermPart1(pUVM);
    219228    dbgfR3PlugInTerm(pUVM);
  • trunk/src/VBox/VMM/include/DBGFInternal.h

    r82968 r84458  
    3232#include <iprt/avl.h>
    3333#include <iprt/dbg.h>
     34#include <iprt/tracelog.h>
    3435#include <VBox/vmm/dbgf.h>
    3536
     
    4142 * @{
    4243 */
     44
     45/** The maximum tracer instance (total) size, ring-0/raw-mode capable tracers. */
     46#define DBGF_MAX_TRACER_INSTANCE_SIZE    _8M
     47/** The maximum tracers instance (total) size, ring-3 only tracers. */
     48#define DBGF_MAX_TRACER_INSTANCE_SIZE_R3 _16M
     49/** Event ringbuffer header size. */
     50#define DBGF_TRACER_EVT_HDR_SZ           (32)
     51/** Event ringbuffer payload size. */
     52#define DBGF_TRACER_EVT_PAYLOAD_SZ       (32)
     53/** Event ringbuffer entry size. */
     54#define DBGF_TRACER_EVT_SZ               (DBGF_TRACER_EVT_HDR_SZ + DBGF_TRACER_EVT_PAYLOAD_SZ)
     55
     56
     57
     58/*******************************************************************************
     59*   Structures and Typedefs                                                    *
     60*******************************************************************************/
     61
     62/**
     63 * Event entry types.
     64 */
     65typedef enum DBGFTRACEREVT
     66{
     67    /** Invalid type. */
     68    DBGFTRACEREVT_INVALID = 0,
     69    /** MMIO map region event. */
     70    DBGFTRACEREVT_MMIO_MAP,
     71    /** MMIO unmap region event. */
     72    DBGFTRACEREVT_MMIO_UNMAP,
     73    /** MMIO read event. */
     74    DBGFTRACEREVT_MMIO_READ,
     75    /** MMIO write event. */
     76    DBGFTRACEREVT_MMIO_WRITE,
     77    /** MMIO fill event. */
     78    DBGFTRACEREVT_MMIO_FILL,
     79    /** I/O port map event. */
     80    DBGFTRACEREVT_IOPORT_MAP,
     81    /** I/O port unmap event. */
     82    DBGFTRACEREVT_IOPORT_UNMAP,
     83    /** I/O port read event. */
     84    DBGFTRACEREVT_IOPORT_READ,
     85    /** I/O port write event. */
     86    DBGFTRACEREVT_IOPORT_WRITE,
     87    /** IRQ event. */
     88    DBGFTRACEREVT_IRQ,
     89    /** I/O APIC MSI event. */
     90    DBGFTRACEREVT_IOAPIC_MSI,
     91    /** Read from guest physical memory. */
     92    DBGFTRACEREVT_GCPHYS_READ,
     93    /** Write to guest physical memory. */
     94    DBGFTRACEREVT_GCPHYS_WRITE,
     95    /** 32bit hack. */
     96    DBGFTRACEREVT_32BIT_HACK
     97} DBGFTRACEREVT;
     98/** Pointer to a trace event entry type. */
     99typedef DBGFTRACEREVT *PDBGFTRACEREVT;
     100
     101
     102/**
     103 * MMIO region map event.
     104 */
     105typedef struct DBGFTRACEREVTMMIOMAP
     106{
     107    /** Unique region handle for the event source. */
     108    uint64_t                                hMmioRegion;
     109    /** The base guest physical address of the MMIO region. */
     110    RTGCPHYS                                GCPhysMmioBase;
     111    /** Padding to 32byte. */
     112    uint64_t                                au64Pad0[2];
     113} DBGFTRACEREVTMMIOMAP;
     114/** Pointer to a MMIO map event. */
     115typedef DBGFTRACEREVTMMIOMAP *PDBGFTRACEREVTMMIOMAP;
     116/** Pointer to a const MMIO map event. */
     117typedef const DBGFTRACEREVTMMIOMAP *PCDBGFTRACEREVTMMIOMAP;
     118
     119AssertCompileSize(DBGFTRACEREVTMMIOMAP, DBGF_TRACER_EVT_PAYLOAD_SZ);
     120
     121
     122/**
     123 * MMIO region unmap event.
     124 */
     125typedef struct DBGFTRACEREVTMMIOUNMAP
     126{
     127    /** Unique region handle for the event source. */
     128    uint64_t                                hMmioRegion;
     129    /** Padding to 32byte. */
     130    uint64_t                                au64Pad0[3];
     131} DBGFTRACEREVTMMIOUNMAP;
     132/** Pointer to a MMIO map event. */
     133typedef DBGFTRACEREVTMMIOUNMAP *PDBGFTRACEREVTMMIOUNMAP;
     134/** Pointer to a const MMIO map event. */
     135typedef const DBGFTRACEREVTMMIOUNMAP *PCDBGFTRACEREVTMMIOUNMAP;
     136
     137AssertCompileSize(DBGFTRACEREVTMMIOUNMAP, DBGF_TRACER_EVT_PAYLOAD_SZ);
     138
     139
     140/**
     141 * MMIO event.
     142 */
     143typedef struct DBGFTRACEREVTMMIO
     144{
     145    /** Unique region handle for the event source. */
     146    uint64_t                                hMmioRegion;
     147    /** Offset into the region the access happened. */
     148    RTGCPHYS                                offMmio;
     149    /** Number of bytes transfered (the direction is in the event header). */
     150    uint64_t                                cbXfer;
     151    /** The value transfered. */
     152    uint64_t                                u64Val;
     153} DBGFTRACEREVTMMIO;
     154/** Pointer to a MMIO event. */
     155typedef DBGFTRACEREVTMMIO *PDBGFTRACEREVTMMIO;
     156/** Pointer to a const MMIO event. */
     157typedef const DBGFTRACEREVTMMIO *PCDBGFTRACEREVTMMIO;
     158
     159AssertCompileSize(DBGFTRACEREVTMMIO, DBGF_TRACER_EVT_PAYLOAD_SZ);
     160
     161
     162/**
     163 * MMIO fill event.
     164 */
     165typedef struct DBGFTRACEREVTMMIOFILL
     166{
     167    /** Unique region handle for the event source. */
     168    uint64_t                                hMmioRegion;
     169    /** Offset into the region the access happened. */
     170    RTGCPHYS                                offMmio;
     171    /** Item size in bytes. */
     172    uint32_t                                cbItem;
     173    /** Amount of items being filled. */
     174    uint32_t                                cItems;
     175    /** The fill value. */
     176    uint32_t                                u32Item;
     177    /** Padding to 32bytes. */
     178    uint32_t                                u32Pad0;
     179} DBGFTRACEREVTMMIOFILL;
     180/** Pointer to a MMIO event. */
     181typedef DBGFTRACEREVTMMIOFILL *PDBGFTRACEREVTMMIOFILL;
     182/** Pointer to a const MMIO event. */
     183typedef const DBGFTRACEREVTMMIOFILL *PCDBGFTRACEREVTMMIOFILL;
     184
     185AssertCompileSize(DBGFTRACEREVTMMIOFILL, DBGF_TRACER_EVT_PAYLOAD_SZ);
     186
     187
     188/**
     189 * I/O port region map event.
     190 */
     191typedef struct DBGFTRACEREVTIOPORTMAP
     192{
     193    /** Unique I/O port region handle for the event source. */
     194    uint64_t                                hIoPorts;
     195    /** The base I/O port for the region. */
     196    RTIOPORT                                IoPortBase;
     197    /** Padding to 32byte. */
     198    uint16_t                                au16Pad0[11];
     199} DBGFTRACEREVTIOPORTMAP;
     200/** Pointer to a MMIO map event. */
     201typedef DBGFTRACEREVTIOPORTMAP *PDBGFTRACEREVTIOPORTMAP;
     202/** Pointer to a const MMIO map event. */
     203typedef const DBGFTRACEREVTIOPORTMAP *PCDBGFTRACEREVTIOPORTMAP;
     204
     205AssertCompileSize(DBGFTRACEREVTIOPORTMAP, DBGF_TRACER_EVT_PAYLOAD_SZ);
     206
     207
     208/**
     209 * MMIO region unmap event.
     210 */
     211typedef struct DBGFTRACEREVTIOPORTUNMAP
     212{
     213    /** Unique region handle for the event source. */
     214    uint64_t                                hIoPorts;
     215    /** Padding to 32byte. */
     216    uint64_t                                au64Pad0[3];
     217} DBGFTRACEREVTIOPORTUNMAP;
     218/** Pointer to a MMIO map event. */
     219typedef DBGFTRACEREVTIOPORTUNMAP *PDBGFTRACEREVTIOPORTUNMAP;
     220/** Pointer to a const MMIO map event. */
     221typedef const DBGFTRACEREVTIOPORTUNMAP *PCDBGFTRACEREVTIOPORTUNMAP;
     222
     223AssertCompileSize(DBGFTRACEREVTIOPORTUNMAP, DBGF_TRACER_EVT_PAYLOAD_SZ);
     224
     225
     226/**
     227 * I/O port event.
     228 */
     229typedef struct DBGFTRACEREVTIOPORT
     230{
     231    /** Unique region handle for the event source. */
     232    uint64_t                                hIoPorts;
     233    /** Offset into the I/O port region. */
     234    RTIOPORT                                offPort;
     235    /** 8 byte alignment. */
     236    uint8_t                                 abPad0[6];
     237    /** Number of bytes transfered (the direction is in the event header). */
     238    uint64_t                                cbXfer;
     239    /** The value transfered. */
     240    uint32_t                                u32Val;
     241    /** Padding to 32bytes. */
     242    uint8_t                                 abPad1[4];
     243} DBGFTRACEREVTIOPORT;
     244/** Pointer to a MMIO event. */
     245typedef DBGFTRACEREVTIOPORT *PDBGFTRACEREVTIOPORT;
     246/** Pointer to a const MMIO event. */
     247typedef const DBGFTRACEREVTIOPORT *PCDBGFTRACEREVTIOPORT;
     248
     249AssertCompileSize(DBGFTRACEREVTIOPORT, DBGF_TRACER_EVT_PAYLOAD_SZ);
     250
     251
     252/**
     253 * IRQ event.
     254 */
     255typedef struct DBGFTRACEREVTIRQ
     256{
     257    /** The IRQ line. */
     258    int32_t                                 iIrq;
     259    /** IRQ level flags. */
     260    int32_t                                 fIrqLvl;
     261    /** Padding to 32bytes. */
     262    uint32_t                                au32Pad0[6];
     263} DBGFTRACEREVTIRQ;
     264/** Pointer to a MMIO event. */
     265typedef DBGFTRACEREVTIRQ *PDBGFTRACEREVTIRQ;
     266/** Pointer to a const MMIO event. */
     267typedef const DBGFTRACEREVTIRQ *PCDBGFTRACEREVTIRQ;
     268
     269AssertCompileSize(DBGFTRACEREVTIRQ, DBGF_TRACER_EVT_PAYLOAD_SZ);
     270
     271
     272/**
     273 * I/O APIC MSI event.
     274 */
     275typedef struct DBGFTRACEREVTIOAPICMSI
     276{
     277    /** The guest physical address being written. */
     278    RTGCPHYS                                GCPhys;
     279    /** The value being written. */
     280    uint32_t                                u32Val;
     281    /** Padding to 32bytes. */
     282    uint32_t                                au32Pad0[5];
     283} DBGFTRACEREVTIOAPICMSI;
     284/** Pointer to a MMIO event. */
     285typedef DBGFTRACEREVTIOAPICMSI *PDBGFTRACEREVTIOAPICMSI;
     286/** Pointer to a const MMIO event. */
     287typedef const DBGFTRACEREVTIOAPICMSI *PCDBGFTRACEREVTIOAPICMSI;
     288
     289AssertCompileSize(DBGFTRACEREVTIOAPICMSI, DBGF_TRACER_EVT_PAYLOAD_SZ);
     290
     291
     292/**
     293 * Guest physical memory transfer.
     294 */
     295typedef struct DBGFTRACEREVTGCPHYS
     296{
     297    /** Guest physical address of the access. */
     298    RTGCPHYS                                GCPhys;
     299    /** Number of bytes transfered (the direction is in the event header).
     300     * If the number is small enough to fit into the remaining space of the entry
     301     * it is stored here, otherwise it will be stored in the next entry (and following
     302     * entries). */
     303    uint64_t                                cbXfer;
     304    /** Guest data being transfered. */
     305    uint8_t                                 abData[16];
     306} DBGFTRACEREVTGCPHYS;
     307/** Pointer to a guest physical memory transfer event. */
     308typedef DBGFTRACEREVTGCPHYS *PDBGFTRACEREVTGCPHYS;
     309/** Pointer to a const uest physical memory transfer event. */
     310typedef const DBGFTRACEREVTGCPHYS *PCDBGFTRACEREVTGCPHYS;
     311
     312AssertCompileSize(DBGFTRACEREVTGCPHYS, DBGF_TRACER_EVT_PAYLOAD_SZ);
     313
     314
     315/**
     316 * A trace event header in the shared ring buffer.
     317 */
     318typedef struct DBGFTRACEREVTHDR
     319{
     320    /** Event ID. */
     321    volatile uint64_t                       idEvt;
     322    /** The previous event ID this one links to,
     323     * DBGF_TRACER_EVT_HDR_ID_INVALID if it links to no other event. */
     324    uint64_t                                idEvtPrev;
     325    /** Event source. */
     326    DBGFTRACEREVTSRC                        hEvtSrc;
     327    /** The event entry type. */
     328    DBGFTRACEREVT                           enmEvt;
     329    /** Flags for this event. */
     330    uint32_t                                fFlags;
     331} DBGFTRACEREVTHDR;
     332/** Pointer to a trace event header. */
     333typedef DBGFTRACEREVTHDR *PDBGFTRACEREVTHDR;
     334/** Pointer to a const trace event header. */
     335typedef const DBGFTRACEREVTHDR *PCDBGFTRACEREVTHDR;
     336
     337AssertCompileSize(DBGFTRACEREVTHDR, DBGF_TRACER_EVT_HDR_SZ);
     338
     339/** Invalid event ID, this is always set by the flush thread after processing one entry
     340 * so the producers know when they are about to overwrite not yet processed entries in the ring buffer. */
     341#define DBGF_TRACER_EVT_HDR_ID_INVALID      UINT64_C(0xffffffffffffffff)
     342
     343/** The event came from R0. */
     344#define DBGF_TRACER_EVT_HDR_F_R0            RT_BIT(0)
     345
     346/** Default event header tracer flags. */
     347#ifdef IN_RING0
     348# define DBGF_TRACER_EVT_HDR_F_DEFAULT      DBGF_TRACER_EVT_HDR_F_R0
     349#else
     350# define DBGF_TRACER_EVT_HDR_F_DEFAULT      (0)
     351#endif
     352
     353
     354/**
     355 * Tracer instance data, shared structure.
     356 */
     357typedef struct DBGFTRACERSHARED
     358{
     359    /** The global event ID counter, monotonically increasing.
     360     * Accessed by all threads causing a trace event. */
     361    volatile uint64_t                       idEvt;
     362    /** The SUP event semaphore for poking the flush thread. */
     363    SUPSEMEVENT                             hSupSemEvtFlush;
     364    /** Ring buffer size. */
     365    size_t                                  cbRingBuf;
     366    /** Flag whether there are events in the ring buffer to get processed. */
     367    volatile bool                           fEvtsWaiting;
     368    /** Flag whether the flush thread is actively running or was kicked. */
     369    volatile bool                           fFlushThrdActive;
     370    /** Padding to a 64byte alignment. */
     371    uint8_t                                 abAlignment0[32];
     372} DBGFTRACERSHARED;
     373/** Pointer to the shared tarcer instance data. */
     374typedef DBGFTRACERSHARED *PDBGFTRACERSHARED;
     375
     376AssertCompileSizeAlignment(DBGFTRACERSHARED, 64);
     377
     378
     379/**
     380 * Tracer instance data, ring-3
     381 */
     382typedef struct DBGFTRACERINSR3
     383{
     384    /** Pointer to the next instance.
     385     * (Head is pointed to by PDM::pTracerInstances.) */
     386    R3PTRTYPE(struct DBGFTRACERINSR3 *)     pNextR3;
     387    /** R3 pointer to the VM this instance was created for. */
     388    PVMR3                                   pVMR3;
     389    /** Tracer instance number. */
     390    uint32_t                                idTracer;
     391    /** Flag whether the tracer has the R0 part enabled. */
     392    bool                                    fR0Enabled;
     393    /** Flag whether the tracer flush thread should shut down. */
     394    volatile bool                           fShutdown;
     395    /** Padding. */
     396    bool                                    afPad0[6];
     397    /** Next event source ID to return for a source registration. */
     398    volatile DBGFTRACEREVTSRC               hEvtSrcNext;
     399    /** Pointer to the shared tracer instance data. */
     400    R3PTRTYPE(PDBGFTRACERSHARED)            pSharedR3;
     401    /** The I/O thread writing the log from the shared event ringbuffer. */
     402    RTTHREAD                                hThrdFlush;
     403    /** Pointer to the start of the ring buffer. */
     404    R3PTRTYPE(uint8_t *)                    pbRingBufR3;
     405    /** The last processed event ID. */
     406    uint64_t                                idEvtLast;
     407    /** The trace log writer handle. */
     408    RTTRACELOGWR                            hTraceLog;
     409} DBGFTRACERINSR3;
     410/** Pointer to a tarcer instance - Ring-3 Ptr. */
     411typedef R3PTRTYPE(DBGFTRACERINSR3 *) PDBGFTRACERINSR3;
     412
     413
     414/**
     415 * Private tracer instance data, ring-0
     416 */
     417typedef struct DBGFTRACERINSR0
     418{
     419    /** Pointer to the VM this instance was created for. */
     420    R0PTRTYPE(PGVM)                         pGVM;
     421    /** The tracer instance memory. */
     422    RTR0MEMOBJ                              hMemObj;
     423    /** The ring-3 mapping object. */
     424    RTR0MEMOBJ                              hMapObj;
     425    /** Pointer to the shared tracer instance data. */
     426    R0PTRTYPE(PDBGFTRACERSHARED)            pSharedR0;
     427    /** Size of the ring buffer in bytes, kept here so R3 can not manipulate the ring buffer
     428     * size afterwards to trick R0 into doing something harmful. */
     429    size_t                                  cbRingBuf;
     430    /** Pointer to the start of the ring buffer. */
     431    R0PTRTYPE(uint8_t *)                    pbRingBufR0;
     432} DBGFTRACERINSR0;
     433/** Pointer to a VM - Ring-0 Ptr. */
     434typedef R0PTRTYPE(DBGFTRACERINSR0 *) PDBGFTRACERINSR0;
     435
     436
     437/**
     438 * Private device instance data, raw-mode
     439 */
     440typedef struct DBGFTRACERINSRC
     441{
     442    /** Pointer to the VM this instance was created for. */
     443    RGPTRTYPE(PVM)                          pVMRC;
     444} DBGFTRACERINSRC;
    43445
    44446
     
    482884
    483885/**
     886 * DBGF data kept in the ring-0 GVM.
     887 */
     888typedef struct DBGFR0PERVM
     889{
     890    /** Pointer to the tracer instance if enabled. */
     891    R0PTRTYPE(struct DBGFTRACERINSR0 *) pTracerR0;
     892} DBGFR0PERVM;
     893
     894/**
    484895 * The DBGF data kept in the UVM.
    485896 */
     
    529940    /** List of registered info handlers. */
    530941    R3PTRTYPE(PDBGFINFO)        pInfoFirst;
     942
     943    /** The configured tracer. */
     944    PDBGFTRACERINSR3            pTracerR3;
    531945
    532946    /** The type database lock. */
     
    577991void dbgfR3PlugInTerm(PUVM pUVM);
    578992int  dbgfR3BugCheckInit(PVM pVM);
     993DECLHIDDEN(int) dbgfR3TracerInit(PVM pVM);
     994DECLHIDDEN(void) dbgfR3TracerTerm(PVM pVM);
    579995
    580996/**
Note: See TracChangeset for help on using the changeset viewer.

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