VirtualBox

source: vbox/trunk/src/VBox/VMM/VMMR0/DBGFR0Tracer.cpp@ 85972

Last change on this file since 85972 was 84823, checked in by vboxsync, 5 years ago

VMM/DBGFTracer: Windows build fixes, bugref:9210

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 7.8 KB
Line 
1/* $Id: DBGFR0Tracer.cpp 84823 2020-06-15 06:58:36Z vboxsync $ */
2/** @file
3 * DBGF - Debugger Facility, R0 tracing part.
4 */
5
6/*
7 * Copyright (C) 2020 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 */
17
18
19/*********************************************************************************************************************************
20* Header Files *
21*********************************************************************************************************************************/
22#define LOG_GROUP LOG_GROUP_DBGF
23#include "DBGFInternal.h"
24#include <VBox/vmm/gvm.h>
25#include <VBox/vmm/gvmm.h>
26#include <VBox/vmm/vmm.h>
27
28#include <VBox/log.h>
29#include <VBox/sup.h>
30#include <iprt/asm.h>
31#include <iprt/assert.h>
32#include <iprt/errcore.h>
33#include <iprt/ctype.h>
34#include <iprt/mem.h>
35#include <iprt/memobj.h>
36#include <iprt/process.h>
37#include <iprt/string.h>
38
39#include "dtrace/VBoxVMM.h"
40
41
42/*********************************************************************************************************************************
43* Internal Functions *
44*********************************************************************************************************************************/
45
46
47/**
48 * Used by DBGFR0CleanupVM to destroy a tracer instance.
49 *
50 * This is done during VM cleanup so that we're sure there are no active threads
51 * using the tracer code.
52 *
53 * @param pGVM The global (ring-0) VM structure.
54 * @param pTracer The device instance.
55 */
56DECLHIDDEN(int) dbgfR0TracerDestroy(PGVM pGVM, PDBGFTRACERINSR0 pTracer)
57{
58 RT_NOREF(pGVM);
59
60 /*
61 * Free the ring-3 mapping and instance memory.
62 */
63 RTR0MEMOBJ hMemObj = pTracer->hMapObj;
64 pTracer->hMapObj = NIL_RTR0MEMOBJ;
65 RTR0MemObjFree(hMemObj, true);
66
67 hMemObj = pTracer->hMemObj;
68 pTracer->hMemObj = NIL_RTR0MEMOBJ;
69 RTR0MemObjFree(hMemObj, true);
70
71 return VINF_SUCCESS;
72}
73
74
75/**
76 * Worker for DBGFR0TracerCreate that does the actual instantiation.
77 *
78 * Allocates a memory object and divides it up as follows:
79 * @verbatim
80 --------------------------------------
81 ring-0 tracerins
82 --------------------------------------
83 page alignment padding
84 --------------------------------------
85 ring-3 tracerins
86 --------------------------------------
87 [page alignment padding ] -+
88 [--------------------------------------] |- Optional, only when raw-mode is enabled.
89 [raw-mode tracerins ] -+
90 [--------------------------------------]
91 shared tracer data
92 --------------------------------------
93 @endverbatim
94 *
95 * @returns VBox status code.
96 * @param pGVM The global (ring-0) VM structure.
97 * @param cbRingBuf Size of the ring buffer in bytes.
98 * @param RCPtrMapping The raw-mode context mapping address, NIL_RTGCPTR if
99 * not to include raw-mode.
100 * @param ppTracerInsR3 Where to return the ring-3 tracer instance address.
101 * @thread EMT(0)
102 */
103static int dbgfR0TracerCreateWorker(PGVM pGVM, uint32_t cbRingBuf, RTRGPTR RCPtrMapping, PDBGFTRACERINSR3 *ppTracerInsR3)
104{
105 /*
106 * Figure out how much memory we need and allocate it.
107 */
108 uint32_t const cbRing0 = RT_ALIGN_32(sizeof(DBGFTRACERINSR0), PAGE_SIZE);
109 uint32_t const cbRing3 = RT_ALIGN_32(sizeof(DBGFTRACERINSR3), RCPtrMapping != NIL_RTRGPTR ? PAGE_SIZE : 64);
110 uint32_t const cbRC = RCPtrMapping != NIL_RTRGPTR ? 0
111 : RT_ALIGN_32(sizeof(DBGFTRACERINSRC), 64);
112 uint32_t const cbShared = RT_ALIGN_32(sizeof(DBGFTRACERSHARED) + cbRingBuf, 64);
113 uint32_t const offShared = cbRing0 + cbRing3 + cbRC;
114 uint32_t const cbTotal = RT_ALIGN_32(cbRing0 + cbRing3 + cbRC + cbShared, PAGE_SIZE);
115 AssertLogRelMsgReturn(cbTotal <= DBGF_MAX_TRACER_INSTANCE_SIZE,
116 ("Instance of tracer is too big: cbTotal=%u, max %u\n", cbTotal, DBGF_MAX_TRACER_INSTANCE_SIZE),
117 VERR_OUT_OF_RANGE);
118
119 RTR0MEMOBJ hMemObj;
120 int rc = RTR0MemObjAllocPage(&hMemObj, cbTotal, false /*fExecutable*/);
121 if (RT_FAILURE(rc))
122 return rc;
123 RT_BZERO(RTR0MemObjAddress(hMemObj), cbTotal);
124
125 /* Map it. */
126 RTR0MEMOBJ hMapObj;
127 rc = RTR0MemObjMapUserEx(&hMapObj, hMemObj, (RTR3PTR)-1, 0, RTMEM_PROT_READ | RTMEM_PROT_WRITE, RTR0ProcHandleSelf(),
128 cbRing0, cbTotal - cbRing0);
129 if (RT_SUCCESS(rc))
130 {
131 PDBGFTRACERINSR0 pTracerIns = (PDBGFTRACERINSR0)RTR0MemObjAddress(hMemObj);
132 struct DBGFTRACERINSR3 *pTracerInsR3 = (struct DBGFTRACERINSR3 *)((uint8_t *)pTracerIns + cbRing0);
133
134 /*
135 * Initialize the ring-0 instance.
136 */
137 pTracerIns->pGVM = pGVM;
138 pTracerIns->hMemObj = hMemObj;
139 pTracerIns->hMapObj = hMapObj;
140 pTracerIns->pSharedR0 = (PDBGFTRACERSHARED)((uint8_t *)pTracerIns + offShared);
141 pTracerIns->cbRingBuf = cbRingBuf;
142 pTracerIns->pbRingBufR0 = (uint8_t *)(pTracerIns->pSharedR0 + 1);
143
144 /*
145 * Initialize the ring-3 instance data as much as we can.
146 * Note! DBGFR3Tracer.cpp does this job for ring-3 only tracers. Keep in sync.
147 */
148 pTracerInsR3->pVMR3 = pGVM->pVMR3;
149 pTracerInsR3->fR0Enabled = true;
150 pTracerInsR3->pSharedR3 = RTR0MemObjAddressR3(hMapObj) + cbRing3 + cbRC;
151 pTracerInsR3->pbRingBufR3 = RTR0MemObjAddressR3(hMapObj) + cbRing3 + cbRC + sizeof(DBGFTRACERSHARED);
152
153 pTracerIns->pSharedR0->idEvt = 0;
154 pTracerIns->pSharedR0->cbRingBuf = cbRingBuf;
155 pTracerIns->pSharedR0->fEvtsWaiting = false;
156 pTracerIns->pSharedR0->fFlushThrdActive = false;
157
158 /*
159 * Initialize the raw-mode instance data as much as possible.
160 */
161 if (RCPtrMapping != NIL_RTRCPTR)
162 {
163 struct DBGFTRACERINSRC *pTracerInsRC = RCPtrMapping == NIL_RTRCPTR ? NULL
164 : (struct DBGFTRACERINSRC *)((uint8_t *)pTracerIns + cbRing0 + cbRing3);
165
166 pTracerInsRC->pVMRC = pGVM->pVMRC;
167 }
168
169 pGVM->dbgfr0.s.pTracerR0 = pTracerIns;
170
171 /*
172 * We're done.
173 */
174 *ppTracerInsR3 = RTR0MemObjAddressR3(hMapObj);
175 return rc;
176 }
177
178 RTR0MemObjFree(hMemObj, true);
179 return rc;
180}
181
182
183/**
184 * Used by ring-3 DBGF to create a tracer instance that operates both in ring-3
185 * and ring-0.
186 *
187 * Creates an instance of a tracer (for both ring-3 and ring-0, and optionally
188 * raw-mode context).
189 *
190 * @returns VBox status code.
191 * @param pGVM The global (ring-0) VM structure.
192 * @param pReq Pointer to the request buffer.
193 * @thread EMT(0)
194 */
195VMMR0_INT_DECL(int) DBGFR0TracerCreateReqHandler(PGVM pGVM, PDBGFTRACERCREATEREQ pReq)
196{
197 LogFlow(("DBGFR0TracerCreateReqHandler:\n"));
198
199 /*
200 * Validate the request.
201 */
202 AssertReturn(pReq->Hdr.cbReq == sizeof(*pReq), VERR_INVALID_PARAMETER);
203 pReq->pTracerInsR3 = NIL_RTR3PTR;
204
205 int rc = GVMMR0ValidateGVMandEMT(pGVM, 0);
206 AssertRCReturn(rc, rc);
207
208 AssertReturn(pReq->cbRingBuf <= DBGF_MAX_TRACER_INSTANCE_SIZE, VERR_OUT_OF_RANGE);
209
210 return dbgfR0TracerCreateWorker(pGVM, pReq->cbRingBuf, NIL_RTRCPTR /** @todo new raw-mode */, &pReq->pTracerInsR3);
211}
212
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