VirtualBox

source: vbox/trunk/src/VBox/Additions/common/VBoxGuest/lib/VBoxGuestR0LibInit.cpp@ 68642

Last change on this file since 68642 was 68641, checked in by vboxsync, 8 years ago

VBoxGuestLib: Renaming ring-0 files.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 9.2 KB
Line 
1/* $Id: VBoxGuestR0LibInit.cpp 68641 2017-09-05 13:51:06Z vboxsync $ */
2/** @file
3 * VBoxGuestLibR0 - Library initialization.
4 */
5
6/*
7 * Copyright (C) 2006-2016 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 * The contents of this file may alternatively be used under the terms
18 * of the Common Development and Distribution License Version 1.0
19 * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
20 * VirtualBox OSE distribution, in which case the provisions of the
21 * CDDL are applicable instead of those of the GPL.
22 *
23 * You may elect to license modified versions of this file under the
24 * terms and conditions of either the GPL or the CDDL or both.
25 */
26
27
28/*********************************************************************************************************************************
29* Header Files *
30*********************************************************************************************************************************/
31#define VBGL_DECL_DATA
32#include "VBGLInternal.h"
33
34#include <iprt/string.h>
35#include <iprt/assert.h>
36#include <iprt/semaphore.h>
37
38
39/*********************************************************************************************************************************
40* Global Variables *
41*********************************************************************************************************************************/
42/** The global VBGL instance data. */
43VBGLDATA g_vbgldata;
44
45
46/**
47 * Used by vbglQueryDriverInfo and VbglInit to try get the host feature mask and
48 * version information (g_vbgldata::hostVersion).
49 *
50 * This was first implemented by the host in 3.1 and we quietly ignore failures
51 * for that reason.
52 */
53static void vbglR0QueryHostVersion(void)
54{
55 VMMDevReqHostVersion *pReq;
56 int rc = VbglGRAlloc((VMMDevRequestHeader **) &pReq, sizeof (*pReq), VMMDevReq_GetHostVersion);
57 if (RT_SUCCESS(rc))
58 {
59 rc = VbglGRPerform(&pReq->header);
60 if (RT_SUCCESS(rc))
61 {
62 g_vbgldata.hostVersion = *pReq;
63 Log(("vbglR0QueryHostVersion: %u.%u.%ur%u %#x\n",
64 pReq->major, pReq->minor, pReq->build, pReq->revision, pReq->features));
65 }
66
67 VbglGRFree(&pReq->header);
68 }
69}
70
71
72#ifndef VBGL_VBOXGUEST
73/**
74 * The guest library uses lazy initialization for VMMDev port and memory,
75 * because these values are provided by the VBoxGuest driver and it might
76 * be loaded later than other drivers.
77 *
78 * The VbglEnter checks the current library status, tries to retrieve these
79 * values and fails if they are unavailable.
80 */
81static void vbglQueryDriverInfo(void)
82{
83# ifdef VBGLDATA_USE_FAST_MUTEX
84 int rc = RTSemFastMutexRequest(g_vbgldata.hMtxIdcSetup);
85# else
86 int rc = RTSemMutexRequest(g_vbgldata.hMtxIdcSetup, RT_INDEFINITE_WAIT);
87# endif
88 if (RT_SUCCESS(rc))
89 {
90 if (g_vbgldata.status == VbglStatusReady)
91 { /* likely */ }
92 else
93 {
94 rc = VbglR0IdcOpen(&g_vbgldata.IdcHandle,
95 VBGL_IOC_VERSION /*uReqVersion*/,
96 VBGL_IOC_VERSION & UINT32_C(0xffff0000) /*uMinVersion*/,
97 NULL /*puSessionVersion*/, NULL /*puDriverVersion*/, NULL /*puDriverRevision*/);
98 if (RT_SUCCESS(rc))
99 {
100 /*
101 * Try query the port info.
102 */
103 VBGLIOCGETVMMDEVIOINFO PortInfo;
104 RT_ZERO(PortInfo);
105 VBGLREQHDR_INIT(&PortInfo.Hdr, GET_VMMDEV_IO_INFO);
106 rc = VbglR0IdcCall(&g_vbgldata.IdcHandle, VBGL_IOCTL_GET_VMMDEV_IO_INFO, &PortInfo.Hdr, sizeof(PortInfo));
107 if (RT_SUCCESS(rc))
108 {
109 dprintf(("Port I/O = 0x%04x, MMIO = %p\n", PortInfo.u.Out.IoPort, PortInfo.u.Out.pvVmmDevMapping));
110
111 g_vbgldata.portVMMDev = PortInfo.u.Out.IoPort;
112 g_vbgldata.pVMMDevMemory = (VMMDevMemory *)PortInfo.u.Out.pvVmmDevMapping;
113 g_vbgldata.status = VbglStatusReady;
114
115 vbglR0QueryHostVersion();
116 }
117 }
118
119 dprintf(("vbglQueryDriverInfo rc = %Rrc\n", rc));
120 }
121
122# ifdef VBGLDATA_USE_FAST_MUTEX
123 RTSemFastMutexRelease(g_vbgldata.hMtxIdcSetup);
124# else
125 RTSemMutexRelease(g_vbgldata.hMtxIdcSetup);
126# endif
127 }
128}
129#endif /* !VBGL_VBOXGUEST */
130
131/**
132 * Checks if VBGL has been initialized.
133 *
134 * The client library, this will lazily complete the initialization.
135 *
136 * @return VINF_SUCCESS or VERR_VBGL_NOT_INITIALIZED.
137 */
138int vbglR0Enter(void)
139{
140 if (g_vbgldata.status == VbglStatusReady)
141 return VINF_SUCCESS;
142
143#ifndef VBGL_VBOXGUEST
144 if (g_vbgldata.status == VbglStatusInitializing)
145 {
146 vbglQueryDriverInfo();
147 if (g_vbgldata.status == VbglStatusReady)
148 return VINF_SUCCESS;
149 }
150#endif
151 return VERR_VBGL_NOT_INITIALIZED;
152}
153
154
155static int vbglInitCommon(void)
156{
157 int rc;
158
159 RT_ZERO(g_vbgldata);
160 g_vbgldata.status = VbglStatusInitializing;
161
162 rc = VbglPhysHeapInit();
163 if (RT_SUCCESS(rc))
164 {
165 dprintf(("vbglInitCommon: returns rc = %d\n", rc));
166 return rc;
167 }
168
169 LogRel(("vbglInitCommon: VbglPhysHeapInit failed: rc=%Rrc\n", rc));
170 g_vbgldata.status = VbglStatusNotInitialized;
171 return rc;
172}
173
174
175static void vbglTerminateCommon(void)
176{
177 VbglPhysHeapTerminate();
178 g_vbgldata.status = VbglStatusNotInitialized;
179}
180
181#ifdef VBGL_VBOXGUEST
182
183DECLVBGL(int) VbglInitPrimary(RTIOPORT portVMMDev, VMMDevMemory *pVMMDevMemory)
184{
185 int rc;
186
187# ifdef RT_OS_WINDOWS /** @todo r=bird: this doesn't make sense. Is there something special going on on windows? */
188 dprintf(("vbglInit: starts g_vbgldata.status %d\n", g_vbgldata.status));
189
190 if ( g_vbgldata.status == VbglStatusInitializing
191 || g_vbgldata.status == VbglStatusReady)
192 {
193 /* Initialization is already in process. */
194 return VINF_SUCCESS;
195 }
196# else
197 dprintf(("vbglInit: starts\n"));
198# endif
199
200 rc = vbglInitCommon();
201 if (RT_SUCCESS(rc))
202 {
203 g_vbgldata.portVMMDev = portVMMDev;
204 g_vbgldata.pVMMDevMemory = pVMMDevMemory;
205 g_vbgldata.status = VbglStatusReady;
206
207 vbglR0QueryHostVersion();
208 return VINF_SUCCESS;
209 }
210
211 g_vbgldata.status = VbglStatusNotInitialized;
212 return rc;
213}
214
215DECLVBGL(void) VbglR0TerminatePrimary(void)
216{
217 vbglTerminateCommon();
218}
219
220
221#else /* !VBGL_VBOXGUEST */
222
223DECLVBGL(int) VbglR0InitClient(void)
224{
225 int rc;
226
227 /** @todo r=bird: explain why we need to be doing this, please... */
228 if ( g_vbgldata.status == VbglStatusInitializing
229 || g_vbgldata.status == VbglStatusReady)
230 {
231 /* Initialization is already in process. */
232 return VINF_SUCCESS;
233 }
234
235 rc = vbglInitCommon();
236 if (RT_SUCCESS(rc))
237 {
238# ifdef VBGLDATA_USE_FAST_MUTEX
239 rc = RTSemFastMutexCreate(&g_vbgldata.hMtxIdcSetup);
240# else
241 rc = RTSemMutexCreate(&g_vbgldata.hMtxIdcSetup);
242# endif
243 if (RT_SUCCESS(rc))
244 {
245 /* Try to obtain VMMDev port via IOCTL to VBoxGuest main driver. */
246 vbglQueryDriverInfo();
247
248# ifdef VBOX_WITH_HGCM
249 rc = VbglR0HGCMInit();
250# endif
251 if (RT_SUCCESS(rc))
252 return VINF_SUCCESS;
253
254# ifdef VBGLDATA_USE_FAST_MUTEX
255 RTSemFastMutexDestroy(g_vbgldata.hMtxIdcSetup);
256 g_vbgldata.hMtxIdcSetup = NIL_RTSEMFASTMUTEX;
257# else
258 RTSemMutexDestroy(g_vbgldata.hMtxIdcSetup);
259 g_vbgldata.hMtxIdcSetup = NIL_RTSEMMUTEX;
260# endif
261 }
262 vbglTerminateCommon();
263 }
264
265 return rc;
266}
267
268DECLVBGL(void) VbglR0TerminateClient(void)
269{
270# ifdef VBOX_WITH_HGCM
271 VbglR0HGCMTerminate();
272# endif
273
274 /* driver open could fail, which does not prevent VbglInit from succeeding,
275 * close the driver only if it is opened */
276 VbglR0IdcClose(&g_vbgldata.IdcHandle);
277# ifdef VBGLDATA_USE_FAST_MUTEX
278 RTSemFastMutexDestroy(g_vbgldata.hMtxIdcSetup);
279 g_vbgldata.hMtxIdcSetup = NIL_RTSEMFASTMUTEX;
280# else
281 RTSemMutexDestroy(g_vbgldata.hMtxIdcSetup);
282 g_vbgldata.hMtxIdcSetup = NIL_RTSEMMUTEX;
283# endif
284
285 /* note: do vbglTerminateCommon as a last step since it zeroez up the g_vbgldata
286 * conceptually, doing vbglTerminateCommon last is correct
287 * since this is the reverse order to how init is done */
288 vbglTerminateCommon();
289}
290
291
292int VBOXCALL vbglR0QueryIdcHandle(PVBGLIDCHANDLE *ppIdcHandle)
293{
294 if (g_vbgldata.status == VbglStatusReady)
295 { /* likely */ }
296 else
297 {
298 vbglQueryDriverInfo();
299 if (g_vbgldata.status != VbglStatusReady)
300 {
301 *ppIdcHandle = NULL;
302 return VERR_TRY_AGAIN;
303 }
304 }
305
306 *ppIdcHandle = &g_vbgldata.IdcHandle;
307 return VINF_SUCCESS;
308}
309
310#endif /* !VBGL_VBOXGUEST */
Note: See TracBrowser for help on using the repository browser.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette