VirtualBox

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

Last change on this file was 106061, checked in by vboxsync, 3 months ago

Copyright year updates by scm.

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