VirtualBox

source: vbox/trunk/src/VBox/VMM/VMMR3/GVMMR3.cpp@ 94319

Last change on this file since 94319 was 93554, checked in by vboxsync, 3 years ago

VMM: Changed PAGE_SIZE -> GUEST_PAGE_SIZE / HOST_PAGE_SIZE, PAGE_SHIFT -> GUEST_PAGE_SHIFT / HOST_PAGE_SHIFT, and PAGE_OFFSET_MASK -> GUEST_PAGE_OFFSET_MASK / HOST_PAGE_OFFSET_MASK. Also removed most usage of ASMMemIsZeroPage and ASMMemZeroPage since the host and guest page size doesn't need to be the same any more. Some work left to do in the page pool code. bugref:9898

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 7.0 KB
Line 
1/* $Id: GVMMR3.cpp 93554 2022-02-02 22:57:02Z vboxsync $ */
2/** @file
3 * GVMM - Global VM Manager, ring-3 request wrappers.
4 */
5
6/*
7 * Copyright (C) 2021-2022 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_GVMM
23#include <VBox/vmm/gvmm.h>
24#include <VBox/vmm/vmm.h>
25#include <VBox/vmm/vmcc.h>
26#include <VBox/vmm/uvm.h>
27#include <VBox/sup.h>
28#include <VBox/err.h>
29
30#include <iprt/mem.h>
31
32
33/**
34 * Driverless: VMMR0_DO_GVMM_CREATE_VM
35 *
36 * @returns VBox status code.
37 * @param pUVM The user mode VM handle.
38 * @param cCpus The number of CPUs to create the VM for.
39 * @param pSession The support driver session handle.
40 * @param ppVM Where to return the pointer to the VM structure.
41 * @param ppVMR0 Where to return the ring-0 address of the VM structure
42 * for use in VMMR0 calls.
43 */
44VMMR3_INT_DECL(int) GVMMR3CreateVM(PUVM pUVM, uint32_t cCpus, PSUPDRVSESSION pSession, PVM *ppVM, PRTR0PTR ppVMR0)
45{
46 AssertReturn(cCpus >= VMM_MIN_CPU_COUNT && cCpus <= VMM_MAX_CPU_COUNT, VERR_INVALID_PARAMETER);
47 AssertCompile((sizeof(VM) & HOST_PAGE_OFFSET_MASK) == 0);
48 AssertCompile((sizeof(VMCPU) & HOST_PAGE_OFFSET_MASK) == 0);
49
50 int rc;
51 if (!SUPR3IsDriverless())
52 {
53 GVMMCREATEVMREQ CreateVMReq;
54 CreateVMReq.Hdr.u32Magic = SUPVMMR0REQHDR_MAGIC;
55 CreateVMReq.Hdr.cbReq = sizeof(CreateVMReq);
56 CreateVMReq.pSession = pSession;
57 CreateVMReq.pVMR0 = NIL_RTR0PTR;
58 CreateVMReq.pVMR3 = NULL;
59 CreateVMReq.cCpus = cCpus;
60 rc = SUPR3CallVMMR0Ex(NIL_RTR0PTR, NIL_VMCPUID, VMMR0_DO_GVMM_CREATE_VM, 0, &CreateVMReq.Hdr);
61 if (RT_SUCCESS(rc))
62 {
63 *ppVM = CreateVMReq.pVMR3;
64 *ppVMR0 = CreateVMReq.pVMR0;
65 }
66 }
67 else
68 {
69 /*
70 * Driverless.
71 */
72 /* Allocate the VM structure: */
73 size_t const cbVM = sizeof(VM) + sizeof(VMCPU) * cCpus;
74 PVM pVM = (PVM)RTMemPageAlloc(cbVM + HOST_PAGE_SIZE * (1 + 2 * cCpus));
75 if (!pVM)
76 return VERR_NO_PAGE_MEMORY;
77
78 /* Set up guard pages: */
79 RTMemProtect(pVM, HOST_PAGE_SIZE, RTMEM_PROT_NONE);
80 pVM = (PVM)((uintptr_t)pVM + HOST_PAGE_SIZE);
81 RTMemProtect(pVM + 1, HOST_PAGE_SIZE, RTMEM_PROT_NONE);
82
83 /* VM: */
84 pVM->enmVMState = VMSTATE_CREATING;
85 pVM->pVMR3 = pVM;
86 pVM->hSelf = _1M;
87 pVM->pSession = pSession;
88 pVM->cCpus = cCpus;
89 pVM->uCpuExecutionCap = 100;
90 pVM->cbSelf = sizeof(VM);
91 pVM->cbVCpu = sizeof(VMCPU);
92 pVM->uStructVersion = 1;
93
94 /* CPUs: */
95 PVMCPU pVCpu = (PVMCPU)((uintptr_t)pVM + sizeof(VM) + HOST_PAGE_SIZE);
96 for (VMCPUID idxCpu = 0; idxCpu < cCpus; idxCpu++)
97 {
98 pVM->apCpusR3[idxCpu] = pVCpu;
99
100 pVCpu->enmState = VMCPUSTATE_STOPPED;
101 pVCpu->pVMR3 = pVM;
102 pVCpu->hNativeThread = NIL_RTNATIVETHREAD;
103 pVCpu->hNativeThreadR0 = NIL_RTNATIVETHREAD;
104 pVCpu->hThread = NIL_RTTHREAD;
105 pVCpu->idCpu = idxCpu;
106
107 RTMemProtect(pVCpu + 1, HOST_PAGE_SIZE, RTMEM_PROT_NONE);
108 pVCpu = (PVMCPU)((uintptr_t)pVCpu + sizeof(VMCPU) + HOST_PAGE_SIZE);
109 }
110
111 *ppVM = pVM;
112 *ppVMR0 = NIL_RTR0PTR;
113 }
114 RT_NOREF(pUVM);
115 return VINF_SUCCESS;
116}
117
118
119/**
120 * Driverless: VMMR0_DO_GVMM_DESTROY_VM
121 *
122 * @returns VBox status code.
123 * @param pUVM The user mode VM handle.
124 * @param pVM The cross context VM structure.
125 */
126VMMR3_INT_DECL(int) GVMMR3DestroyVM(PUVM pUVM, PVM pVM)
127{
128 AssertPtrReturn(pVM, VERR_INVALID_VM_HANDLE);
129 Assert(pUVM->cCpus == pVM->cCpus);
130 RT_NOREF(pUVM);
131
132 int rc;
133 if (!SUPR3IsDriverless())
134 rc = SUPR3CallVMMR0Ex(pVM->pVMR0ForCall, 0 /*idCpu*/, VMMR0_DO_GVMM_DESTROY_VM, 0, NULL);
135 else
136 {
137 RTMemPageFree((uint8_t *)pVM - HOST_PAGE_SIZE,
138 sizeof(VM) + sizeof(VMCPU) * pVM->cCpus + HOST_PAGE_SIZE * (1 + 2 * pVM->cCpus));
139 rc = VINF_SUCCESS;
140 }
141 return rc;
142}
143
144
145/**
146 * Register the calling EMT with GVM.
147 *
148 * @returns VBox status code.
149 * @param pVM The cross context VM structure.
150 * @param idCpu The Virtual CPU ID.
151 * @thread EMT(idCpu)
152 * @see GVMMR0RegisterVCpu
153 */
154VMMR3_INT_DECL(int) GVMMR3RegisterVCpu(PVM pVM, VMCPUID idCpu)
155{
156 Assert(VMMGetCpuId(pVM) == idCpu);
157 int rc;
158 if (!SUPR3IsDriverless())
159 {
160 rc = SUPR3CallVMMR0Ex(VMCC_GET_VMR0_FOR_CALL(pVM), idCpu, VMMR0_DO_GVMM_REGISTER_VMCPU, 0, NULL);
161 if (RT_FAILURE(rc))
162 LogRel(("idCpu=%u rc=%Rrc\n", idCpu, rc));
163 }
164 else
165 rc = VINF_SUCCESS;
166 return rc;
167}
168
169
170/**
171 * Deregister the calling EMT from GVM.
172 *
173 * @returns VBox status code.
174 * @param pVM The cross context VM structure.
175 * @param idCpu The Virtual CPU ID.
176 * @thread EMT(idCpu)
177 * @see GVMMR0DeregisterVCpu
178 */
179VMMR3_INT_DECL(int) GVMMR3DeregisterVCpu(PVM pVM, VMCPUID idCpu)
180{
181 Assert(VMMGetCpuId(pVM) == idCpu);
182 int rc;
183 if (!SUPR3IsDriverless())
184 rc = SUPR3CallVMMR0Ex(VMCC_GET_VMR0_FOR_CALL(pVM), idCpu, VMMR0_DO_GVMM_DEREGISTER_VMCPU, 0, NULL);
185 else
186 rc = VINF_SUCCESS;
187 return rc;
188}
189
190
191/**
192 * @see GVMMR0RegisterWorkerThread
193 */
194VMMR3_INT_DECL(int) GVMMR3RegisterWorkerThread(PVM pVM, GVMMWORKERTHREAD enmWorker)
195{
196 if (SUPR3IsDriverless())
197 return VINF_SUCCESS;
198 GVMMREGISTERWORKERTHREADREQ Req;
199 Req.Hdr.u32Magic = SUPVMMR0REQHDR_MAGIC;
200 Req.Hdr.cbReq = sizeof(Req);
201 Req.hNativeThreadR3 = RTThreadNativeSelf();
202 return SUPR3CallVMMR0Ex(VMCC_GET_VMR0_FOR_CALL(pVM), NIL_VMCPUID,
203 VMMR0_DO_GVMM_REGISTER_WORKER_THREAD, (unsigned)enmWorker, &Req.Hdr);
204}
205
206
207/**
208 * @see GVMMR0DeregisterWorkerThread
209 */
210VMMR3_INT_DECL(int) GVMMR3DeregisterWorkerThread(PVM pVM, GVMMWORKERTHREAD enmWorker)
211{
212 if (SUPR3IsDriverless())
213 return VINF_SUCCESS;
214 return SUPR3CallVMMR0Ex(VMCC_GET_VMR0_FOR_CALL(pVM), NIL_VMCPUID,
215 VMMR0_DO_GVMM_DEREGISTER_WORKER_THREAD, (unsigned)enmWorker, NULL);
216}
217
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