VirtualBox

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

Last change on this file since 87606 was 86683, checked in by vboxsync, 4 years ago

VMM/DBGF: Missing tracer destruction in R0 when the VM terminates, bugref:9210

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 7.7 KB
Line 
1/* $Id: DBGFR0Tracer.cpp 86683 2020-10-23 09:06:16Z 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(void) 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
72
73/**
74 * Worker for DBGFR0TracerCreate that does the actual instantiation.
75 *
76 * Allocates a memory object and divides it up as follows:
77 * @verbatim
78 --------------------------------------
79 ring-0 tracerins
80 --------------------------------------
81 page alignment padding
82 --------------------------------------
83 ring-3 tracerins
84 --------------------------------------
85 [page alignment padding ] -+
86 [--------------------------------------] |- Optional, only when raw-mode is enabled.
87 [raw-mode tracerins ] -+
88 [--------------------------------------]
89 shared tracer data
90 --------------------------------------
91 @endverbatim
92 *
93 * @returns VBox status code.
94 * @param pGVM The global (ring-0) VM structure.
95 * @param cbRingBuf Size of the ring buffer in bytes.
96 * @param RCPtrMapping The raw-mode context mapping address, NIL_RTGCPTR if
97 * not to include raw-mode.
98 * @param ppTracerInsR3 Where to return the ring-3 tracer instance address.
99 * @thread EMT(0)
100 */
101static int dbgfR0TracerCreateWorker(PGVM pGVM, uint32_t cbRingBuf, RTRGPTR RCPtrMapping, PDBGFTRACERINSR3 *ppTracerInsR3)
102{
103 /*
104 * Figure out how much memory we need and allocate it.
105 */
106 uint32_t const cbRing0 = RT_ALIGN_32(sizeof(DBGFTRACERINSR0), PAGE_SIZE);
107 uint32_t const cbRing3 = RT_ALIGN_32(sizeof(DBGFTRACERINSR3), RCPtrMapping != NIL_RTRGPTR ? PAGE_SIZE : 64);
108 uint32_t const cbRC = RCPtrMapping != NIL_RTRGPTR ? 0
109 : RT_ALIGN_32(sizeof(DBGFTRACERINSRC), 64);
110 uint32_t const cbShared = RT_ALIGN_32(sizeof(DBGFTRACERSHARED) + cbRingBuf, 64);
111 uint32_t const offShared = cbRing0 + cbRing3 + cbRC;
112 uint32_t const cbTotal = RT_ALIGN_32(cbRing0 + cbRing3 + cbRC + cbShared, PAGE_SIZE);
113 AssertLogRelMsgReturn(cbTotal <= DBGF_MAX_TRACER_INSTANCE_SIZE,
114 ("Instance of tracer is too big: cbTotal=%u, max %u\n", cbTotal, DBGF_MAX_TRACER_INSTANCE_SIZE),
115 VERR_OUT_OF_RANGE);
116
117 RTR0MEMOBJ hMemObj;
118 int rc = RTR0MemObjAllocPage(&hMemObj, cbTotal, false /*fExecutable*/);
119 if (RT_FAILURE(rc))
120 return rc;
121 RT_BZERO(RTR0MemObjAddress(hMemObj), cbTotal);
122
123 /* Map it. */
124 RTR0MEMOBJ hMapObj;
125 rc = RTR0MemObjMapUserEx(&hMapObj, hMemObj, (RTR3PTR)-1, 0, RTMEM_PROT_READ | RTMEM_PROT_WRITE, RTR0ProcHandleSelf(),
126 cbRing0, cbTotal - cbRing0);
127 if (RT_SUCCESS(rc))
128 {
129 PDBGFTRACERINSR0 pTracerIns = (PDBGFTRACERINSR0)RTR0MemObjAddress(hMemObj);
130 struct DBGFTRACERINSR3 *pTracerInsR3 = (struct DBGFTRACERINSR3 *)((uint8_t *)pTracerIns + cbRing0);
131
132 /*
133 * Initialize the ring-0 instance.
134 */
135 pTracerIns->pGVM = pGVM;
136 pTracerIns->hMemObj = hMemObj;
137 pTracerIns->hMapObj = hMapObj;
138 pTracerIns->pSharedR0 = (PDBGFTRACERSHARED)((uint8_t *)pTracerIns + offShared);
139 pTracerIns->cbRingBuf = cbRingBuf;
140 pTracerIns->pbRingBufR0 = (uint8_t *)(pTracerIns->pSharedR0 + 1);
141
142 /*
143 * Initialize the ring-3 instance data as much as we can.
144 * Note! DBGFR3Tracer.cpp does this job for ring-3 only tracers. Keep in sync.
145 */
146 pTracerInsR3->pVMR3 = pGVM->pVMR3;
147 pTracerInsR3->fR0Enabled = true;
148 pTracerInsR3->pSharedR3 = RTR0MemObjAddressR3(hMapObj) + cbRing3 + cbRC;
149 pTracerInsR3->pbRingBufR3 = RTR0MemObjAddressR3(hMapObj) + cbRing3 + cbRC + sizeof(DBGFTRACERSHARED);
150
151 pTracerIns->pSharedR0->idEvt = 0;
152 pTracerIns->pSharedR0->cbRingBuf = cbRingBuf;
153 pTracerIns->pSharedR0->fEvtsWaiting = false;
154 pTracerIns->pSharedR0->fFlushThrdActive = false;
155
156 /*
157 * Initialize the raw-mode instance data as much as possible.
158 */
159 if (RCPtrMapping != NIL_RTRCPTR)
160 {
161 struct DBGFTRACERINSRC *pTracerInsRC = RCPtrMapping == NIL_RTRCPTR ? NULL
162 : (struct DBGFTRACERINSRC *)((uint8_t *)pTracerIns + cbRing0 + cbRing3);
163
164 pTracerInsRC->pVMRC = pGVM->pVMRC;
165 }
166
167 pGVM->dbgfr0.s.pTracerR0 = pTracerIns;
168
169 /*
170 * We're done.
171 */
172 *ppTracerInsR3 = RTR0MemObjAddressR3(hMapObj);
173 return rc;
174 }
175
176 RTR0MemObjFree(hMemObj, true);
177 return rc;
178}
179
180
181/**
182 * Used by ring-3 DBGF to create a tracer instance that operates both in ring-3
183 * and ring-0.
184 *
185 * Creates an instance of a tracer (for both ring-3 and ring-0, and optionally
186 * raw-mode context).
187 *
188 * @returns VBox status code.
189 * @param pGVM The global (ring-0) VM structure.
190 * @param pReq Pointer to the request buffer.
191 * @thread EMT(0)
192 */
193VMMR0_INT_DECL(int) DBGFR0TracerCreateReqHandler(PGVM pGVM, PDBGFTRACERCREATEREQ pReq)
194{
195 LogFlow(("DBGFR0TracerCreateReqHandler:\n"));
196
197 /*
198 * Validate the request.
199 */
200 AssertReturn(pReq->Hdr.cbReq == sizeof(*pReq), VERR_INVALID_PARAMETER);
201 pReq->pTracerInsR3 = NIL_RTR3PTR;
202
203 int rc = GVMMR0ValidateGVMandEMT(pGVM, 0);
204 AssertRCReturn(rc, rc);
205
206 AssertReturn(pReq->cbRingBuf <= DBGF_MAX_TRACER_INSTANCE_SIZE, VERR_OUT_OF_RANGE);
207
208 return dbgfR0TracerCreateWorker(pGVM, pReq->cbRingBuf, NIL_RTRCPTR /** @todo new raw-mode */, &pReq->pTracerInsR3);
209}
210
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