VirtualBox

source: vbox/trunk/src/VBox/VMM/testcase/tstMicroRC.cpp@ 96945

Last change on this file since 96945 was 96407, checked in by vboxsync, 2 years ago

scm copyright and license note update

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id Revision
File size: 7.8 KB
Line 
1/* $Id: tstMicroRC.cpp 96407 2022-08-22 17:43:14Z vboxsync $ */
2/** @file
3 * Micro Testcase, profiling special CPU operations - GC Code (hacks).
4 */
5
6/*
7 * Copyright (C) 2006-2022 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#include <VBox/vmm/vm.h>
33#include <VBox/vmm/vmm.h>
34#include <VBox/vmm/selm.h>
35#include "tstMicro.h"
36
37#include <iprt/errcore.h>
38#include <iprt/asm-amd64-x86.h>
39#include <VBox/log.h>
40#include <iprt/assert.h>
41#include <iprt/string.h>
42
43
44/*********************************************************************************************************************************
45* Internal Functions *
46*********************************************************************************************************************************/
47RT_C_DECLS_BEGIN
48DECLEXPORT(int) tstMicroRC(PTSTMICRO pTst, unsigned uTestcase);
49RT_C_DECLS_END
50
51
52/**
53 * Save and load our IDT.
54 *
55 * @param pTst Pointer to the instance data.
56 * @param iIDT The index of the IDT entry which should be hooked.
57 */
58void idtInstall(PTSTMICRO pTst, int iIDT)
59{
60 RTIDTR Idtr;
61 ASMGetIDTR(&Idtr);
62 if (Idtr.pIdt == (uintptr_t)&pTst->aIDT[0])
63 return;
64 pTst->OriginalIDTR.cbIdt = Idtr.cbIdt;
65 pTst->OriginalIDTR.pIdt = Idtr.pIdt;
66
67 /*
68 * Copy the IDT.
69 */
70 if (Idtr.cbIdt >= sizeof(pTst->aIDT))
71 Idtr.cbIdt = sizeof(pTst->aIDT) - 1;
72 memcpy(&pTst->aIDT[0], (void *)Idtr.pIdt, Idtr.cbIdt + 1);
73
74
75 /* Hook up IDT entry. */
76 if (iIDT >= 0)
77 {
78 uintptr_t uHandler = (uintptr_t)tstTrapHandlerNoErr;
79 if ( iIDT == 8
80 || iIDT == 0xa
81 || iIDT == 0xb
82 || iIDT == 0xc
83 || iIDT == 0xd
84 || iIDT == 0xe
85 || iIDT == 0x11)
86 uHandler = (uintptr_t)tstTrapHandler;
87 pTst->aIDT[iIDT].Int.u16OffsetHigh = uHandler >> 16;
88 pTst->aIDT[iIDT].Int.u16OffsetLow = uHandler & 0xffff;
89 pTst->aIDT[iIDT].Int.u16SegSel = SELMGetHyperCS(&g_VM);
90 pTst->aIDT[iIDT].Int.u2DPL = 3;
91 pTst->aIDT[iIDT].Int.u1Present = 1;
92 pTst->aIDT[iIDT].Int.u1Fixed0 = 0;
93 pTst->aIDT[iIDT].Int.u1Fixed1 = 0;
94 pTst->aIDT[iIDT].Int.u1Fixed2 = 0;
95 pTst->aIDT[iIDT].Int.u1Fixed3 = 0;
96 pTst->aIDT[iIDT].Int.u1Fixed4 = 1;
97 pTst->aIDT[iIDT].Int.u1Fixed5 = 1;
98 pTst->aIDT[iIDT].Int.u132BitGate = 1;
99 pTst->aIDT[iIDT].Int.u1Fixed6 = 0;
100 pTst->aIDT[iIDT].Int.u5Reserved2 = 0;
101 }
102
103 /* Install int 42h, R3 gate */
104 pTst->aIDT[0x42].Int.u16OffsetHigh = (uintptr_t)tstInterrupt42 >> 16;
105 pTst->aIDT[0x42].Int.u16OffsetLow = (uintptr_t)tstInterrupt42 & 0xffff;
106 pTst->aIDT[0x42].Int.u16SegSel = SELMGetHyperCS(&g_VM);
107 pTst->aIDT[0x42].Int.u2DPL = 3;
108 pTst->aIDT[0x42].Int.u1Present = 1;
109 pTst->aIDT[0x42].Int.u1Fixed0 = 0;
110 pTst->aIDT[0x42].Int.u1Fixed1 = 0;
111 pTst->aIDT[0x42].Int.u1Fixed2 = 0;
112 pTst->aIDT[0x42].Int.u1Fixed3 = 0;
113 pTst->aIDT[0x42].Int.u1Fixed4 = 1;
114 pTst->aIDT[0x42].Int.u1Fixed5 = 1;
115 pTst->aIDT[0x42].Int.u132BitGate = 1;
116 pTst->aIDT[0x42].Int.u1Fixed6 = 0;
117 pTst->aIDT[0x42].Int.u5Reserved2 = 0;
118
119 /*
120 * Load our IDT.
121 */
122 Idtr.pIdt = (uintptr_t)&pTst->aIDT[0];
123 ASMSetIDTR(&Idtr);
124
125 RTIDTR Idtr2;
126 ASMGetIDTR(&Idtr2);
127 Assert(Idtr2.pIdt == (uintptr_t)&pTst->aIDT[0]);
128}
129
130
131/**
132 * Removes all trap overrides except for gate 42.
133 */
134DECLASM(void) idtOnly42(PTSTMICRO pTst)
135{
136 if (pTst->OriginalIDTR.pIdt)
137 memcpy(&pTst->aIDT[0], (void *)(uintptr_t)pTst->OriginalIDTR.pIdt, sizeof(VBOXIDTE) * 32);
138}
139
140
141
142DECLEXPORT(int) tstMicroRC(PTSTMICRO pTst, unsigned uTestcase)
143{
144 RTLogPrintf("pTst=%p uTestcase=%d\n", pTst, uTestcase);
145
146 /*
147 * Validate input.
148 */
149 if (uTestcase >= TSTMICROTEST_MAX)
150 return VERR_INVALID_PARAMETER;
151
152 /*
153 * Clear the results.
154 */
155 pTst->u64TSCR0Start = 0;
156 pTst->u64TSCRxStart = 0;
157 pTst->u64TSCR0Enter = 0;
158 pTst->u64TSCR0Exit = 0;
159 pTst->u64TSCRxEnd = 0;
160 pTst->u64TSCR0End = 0;
161 pTst->cHits = 0;
162 pTst->offEIPAdd = 0;
163 pTst->u32CR2 = 0;
164 pTst->u32EIP = 0;
165 pTst->u32ErrCd = 0;
166 PTSTMICRORESULT pRes = &pTst->aResults[uTestcase];
167 memset(&pTst->aResults[uTestcase], 0, sizeof(pTst->aResults[uTestcase]));
168
169
170 /*
171 * Do the testcase.
172 */
173 int rc = VINF_SUCCESS;
174 switch (uTestcase)
175 {
176 case TSTMICROTEST_OVERHEAD:
177 {
178 tstOverhead(pTst);
179 break;
180 }
181
182 case TSTMICROTEST_INVLPG_0:
183 {
184 tstInvlpg0(pTst);
185 break;
186 }
187
188 case TSTMICROTEST_INVLPG_EIP:
189 {
190 tstInvlpgEIP(pTst);
191 break;
192 }
193
194 case TSTMICROTEST_INVLPG_ESP:
195 {
196 tstInvlpgESP(pTst);
197 break;
198 }
199
200 case TSTMICROTEST_CR3_RELOAD:
201 {
202 tstCR3Reload(pTst);
203 break;
204 }
205
206 case TSTMICROTEST_WP_DISABLE:
207 {
208 tstWPDisable(pTst);
209 break;
210 }
211
212 case TSTMICROTEST_WP_ENABLE:
213 {
214 tstWPEnable(pTst);
215 break;
216 }
217
218 case TSTMICROTEST_PF_R0:
219 {
220 idtInstall(pTst, 0xe);
221 pTst->offEIPAdd = 2;
222 rc = tstPFR0(pTst);
223 break;
224 }
225
226 case TSTMICROTEST_PF_R1:
227 {
228 idtInstall(pTst, 0xe);
229 pTst->offEIPAdd = 2;
230 rc = tstPFR1(pTst);
231 break;
232 }
233
234 case TSTMICROTEST_PF_R2:
235 {
236 idtInstall(pTst, 0xe);
237 pTst->offEIPAdd = 2;
238 rc = tstPFR2(pTst);
239 break;
240 }
241
242 case TSTMICROTEST_PF_R3:
243 {
244 idtInstall(pTst, 0xe);
245 pTst->offEIPAdd = 2;
246 rc = tstPFR3(pTst);
247 break;
248 }
249
250 }
251
252 /*
253 * Compute the results.
254 */
255 if (pTst->u64TSCR0End && pTst->u64TSCR0Start)
256 pRes->cTotalTicks = pTst->u64TSCR0End - pTst->u64TSCR0Start - pTst->u64Overhead;
257 if (pTst->u64TSCRxStart && pTst->u64TSCR0Start)
258 pRes->cToRxFirstTicks = pTst->u64TSCRxStart - pTst->u64TSCR0Start - pTst->u64Overhead;
259 if (pTst->u64TSCR0Enter && pTst->u64TSCRxStart)
260 pRes->cTrapTicks = pTst->u64TSCR0Enter - pTst->u64TSCRxStart - pTst->u64Overhead;
261 if (pTst->u64TSCRxEnd && pTst->u64TSCR0Exit)
262 pRes->cToRxTrapTicks = pTst->u64TSCRxEnd - pTst->u64TSCR0Exit - pTst->u64Overhead;
263 if (pTst->u64TSCR0End && pTst->u64TSCRxEnd)
264 pRes->cToR0Ticks = pTst->u64TSCR0End - pTst->u64TSCRxEnd - pTst->u64Overhead;
265
266 return rc;
267}
268
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