VirtualBox

source: vbox/trunk/src/VBox/VMM/VMMR3/VMMTests.cpp@ 103583

Last change on this file since 103583 was 98103, checked in by vboxsync, 23 months ago

Copyright year updates by scm.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id Revision
File size: 7.5 KB
Line 
1/* $Id: VMMTests.cpp 98103 2023-01-17 14:15:46Z vboxsync $ */
2/** @file
3 * VMM - The Virtual Machine Monitor Core, Tests.
4 */
5
6/*
7 * Copyright (C) 2006-2023 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//#define NO_SUPCALLR0VMM
29
30
31/*********************************************************************************************************************************
32* Header Files *
33*********************************************************************************************************************************/
34#define LOG_GROUP LOG_GROUP_VMM
35#include <VBox/vmm/vmm.h>
36#include <VBox/vmm/pdmapi.h>
37#include <VBox/vmm/cpum.h>
38#include <VBox/dbg.h>
39#include <VBox/vmm/hm.h>
40#include <VBox/vmm/mm.h>
41#include <VBox/vmm/trpm.h>
42#include <VBox/vmm/selm.h>
43#include "VMMInternal.h"
44#include <VBox/vmm/vm.h>
45#include <iprt/errcore.h>
46#include <VBox/param.h>
47
48#include <iprt/assert.h>
49#include <iprt/asm.h>
50#include <iprt/time.h>
51#include <iprt/stream.h>
52#include <iprt/string.h>
53#include <iprt/x86.h>
54
55
56#define SYNC_SEL(pHyperCtx, reg) \
57 if (pHyperCtx->reg.Sel) \
58 { \
59 DBGFSELINFO selInfo; \
60 int rc2 = SELMR3GetShadowSelectorInfo(pVM, pHyperCtx->reg.Sel, &selInfo); \
61 AssertRC(rc2); \
62 \
63 pHyperCtx->reg.u64Base = selInfo.GCPtrBase; \
64 pHyperCtx->reg.u32Limit = selInfo.cbLimit; \
65 pHyperCtx->reg.Attr.n.u1Present = selInfo.u.Raw.Gen.u1Present; \
66 pHyperCtx->reg.Attr.n.u1DefBig = selInfo.u.Raw.Gen.u1DefBig; \
67 pHyperCtx->reg.Attr.n.u1Granularity = selInfo.u.Raw.Gen.u1Granularity; \
68 pHyperCtx->reg.Attr.n.u4Type = selInfo.u.Raw.Gen.u4Type; \
69 pHyperCtx->reg.Attr.n.u2Dpl = selInfo.u.Raw.Gen.u2Dpl; \
70 pHyperCtx->reg.Attr.n.u1DescType = selInfo.u.Raw.Gen.u1DescType; \
71 pHyperCtx->reg.Attr.n.u1Long = selInfo.u.Raw.Gen.u1Long; \
72 }
73
74/* execute the switch. */
75VMMR3DECL(int) VMMDoHmTest(PVM pVM)
76{
77#if 1
78 RTPrintf("FIXME!\n");
79 RT_NOREF(pVM);
80 return 0;
81#else
82
83 uint32_t i;
84 int rc;
85 PCPUMCTX pHyperCtx, pGuestCtx;
86 RTGCPHYS CR3Phys = 0x0; /* fake address */
87 PVMCPU pVCpu = &pVM->aCpus[0];
88
89 if (!HMIsEnabled(pVM))
90 {
91 RTPrintf("VMM: Hardware accelerated test not available!\n");
92 return VERR_ACCESS_DENIED;
93 }
94
95 /* Enable mapping of the hypervisor into the shadow page table. */
96 uint32_t cb;
97 rc = PGMR3MappingsSize(pVM, &cb);
98 AssertRCReturn(rc, rc);
99
100 /* Pretend the mappings are now fixed; to force a refresh of the reserved PDEs. */
101 rc = PGMR3MappingsFix(pVM, MM_HYPER_AREA_ADDRESS, cb);
102 AssertRCReturn(rc, rc);
103
104 pHyperCtx = CPUMGetHyperCtxPtr(pVCpu);
105
106 pHyperCtx->cr0 = X86_CR0_PE | X86_CR0_WP | X86_CR0_PG | X86_CR0_TS | X86_CR0_ET | X86_CR0_NE | X86_CR0_MP;
107 pHyperCtx->cr4 = X86_CR4_PGE | X86_CR4_OSFXSR | X86_CR4_OSXMMEEXCPT;
108 PGMChangeMode(pVCpu, pHyperCtx->cr0, pHyperCtx->cr4, pHyperCtx->msrEFER);
109 PGMSyncCR3(pVCpu, pHyperCtx->cr0, CR3Phys, pHyperCtx->cr4, true);
110
111 VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_TO_R3);
112 VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_TIMER);
113 VM_FF_CLEAR(pVM, VM_FF_TM_VIRTUAL_SYNC);
114 VM_FF_CLEAR(pVM, VM_FF_REQUEST);
115
116 /*
117 * Setup stack for calling VMMRCEntry().
118 */
119 RTRCPTR RCPtrEP;
120 rc = PDMR3LdrGetSymbolRC(pVM, VMMRC_MAIN_MODULE_NAME, "VMMRCEntry", &RCPtrEP);
121 if (RT_SUCCESS(rc))
122 {
123 RTPrintf("VMM: VMMRCEntry=%RRv\n", RCPtrEP);
124
125 pHyperCtx = CPUMGetHyperCtxPtr(pVCpu);
126
127 /* Fill in hidden selector registers for the hypervisor state. */
128 SYNC_SEL(pHyperCtx, cs);
129 SYNC_SEL(pHyperCtx, ds);
130 SYNC_SEL(pHyperCtx, es);
131 SYNC_SEL(pHyperCtx, fs);
132 SYNC_SEL(pHyperCtx, gs);
133 SYNC_SEL(pHyperCtx, ss);
134 SYNC_SEL(pHyperCtx, tr);
135
136 /*
137 * Profile switching.
138 */
139 RTPrintf("VMM: profiling switcher...\n");
140 Log(("VMM: profiling switcher...\n"));
141 uint64_t TickMin = UINT64_MAX;
142 uint64_t tsBegin = RTTimeNanoTS();
143 uint64_t TickStart = ASMReadTSC();
144 for (i = 0; i < 1000000; i++)
145 {
146 CPUMSetHyperState(pVCpu, pVM->vmm.s.pfnCallTrampolineRC, pVCpu->vmm.s.pbEMTStackBottomRC, 0, 0);
147 CPUMPushHyper(pVCpu, 0);
148 CPUMPushHyper(pVCpu, VMMRC_DO_TESTCASE_HM_NOP);
149 CPUMPushHyper(pVCpu, pVM->pVMRC);
150 CPUMPushHyper(pVCpu, 3 * sizeof(RTRCPTR)); /* stack frame size */
151 CPUMPushHyper(pVCpu, RCPtrEP); /* what to call */
152
153 pHyperCtx = CPUMGetHyperCtxPtr(pVCpu);
154 pGuestCtx = CPUMQueryGuestCtxPtr(pVCpu);
155
156 /* Copy the hypervisor context to make sure we have a valid guest context. */
157 *pGuestCtx = *pHyperCtx;
158 pGuestCtx->cr3 = CR3Phys;
159
160 VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_TO_R3);
161 VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_TIMER);
162 VM_FF_CLEAR(pVM, VM_FF_TM_VIRTUAL_SYNC);
163
164 uint64_t TickThisStart = ASMReadTSC();
165 rc = SUPR3CallVMMR0Fast(pVM->pVMR0, VMMR0_DO_HM_RUN, 0);
166 uint64_t TickThisElapsed = ASMReadTSC() - TickThisStart;
167 if (RT_FAILURE(rc))
168 {
169 Log(("VMM: R0 returned fatal %Rrc in iteration %d\n", rc, i));
170 VMMR3FatalDump(pVM, pVCpu, rc);
171 return rc;
172 }
173 if (TickThisElapsed < TickMin)
174 TickMin = TickThisElapsed;
175 }
176 uint64_t TickEnd = ASMReadTSC();
177 uint64_t tsEnd = RTTimeNanoTS();
178
179 uint64_t Elapsed = tsEnd - tsBegin;
180 uint64_t PerIteration = Elapsed / (uint64_t)i;
181 uint64_t cTicksElapsed = TickEnd - TickStart;
182 uint64_t cTicksPerIteration = cTicksElapsed / (uint64_t)i;
183
184 RTPrintf("VMM: %8d cycles in %11llu ns (%11lld ticks), %10llu ns/iteration (%11lld ticks) Min %11lld ticks\n",
185 i, Elapsed, cTicksElapsed, PerIteration, cTicksPerIteration, TickMin);
186 Log(("VMM: %8d cycles in %11llu ns (%11lld ticks), %10llu ns/iteration (%11lld ticks) Min %11lld ticks\n",
187 i, Elapsed, cTicksElapsed, PerIteration, cTicksPerIteration, TickMin));
188
189 rc = VINF_SUCCESS;
190 }
191 else
192 AssertMsgFailed(("Failed to resolved VMMRC.rc::VMMRCEntry(), rc=%Rrc\n", rc));
193
194 return rc;
195#endif
196}
197
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