VirtualBox

source: vbox/trunk/src/VBox/HostDrivers/Support/os2/SUPDrv-os2.cpp@ 68033

Last change on this file since 68033 was 62490, checked in by vboxsync, 8 years ago

(C) 2016

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 15.8 KB
Line 
1/* $Id: SUPDrv-os2.cpp 62490 2016-07-22 18:41:49Z vboxsync $ */
2/** @file
3 * VBoxDrv - The VirtualBox Support Driver - OS/2 specifics.
4 */
5
6/*
7 * Copyright (c) 2007 knut st. osmundsen <bird-src-spam@anduin.net>
8 *
9 * Permission is hereby granted, free of charge, to any person
10 * obtaining a copy of this software and associated documentation
11 * files (the "Software"), to deal in the Software without
12 * restriction, including without limitation the rights to use,
13 * copy, modify, merge, publish, distribute, sublicense, and/or sell
14 * copies of the Software, and to permit persons to whom the
15 * Software is furnished to do so, subject to the following
16 * conditions:
17 *
18 * The above copyright notice and this permission notice shall be
19 * included in all copies or substantial portions of the Software.
20 *
21 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
22 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
23 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
24 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
25 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
26 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
27 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
28 * OTHER DEALINGS IN THE SOFTWARE.
29 */
30
31
32/*********************************************************************************************************************************
33* Header Files *
34*********************************************************************************************************************************/
35#define LOG_GROUP LOG_GROUP_SUP_DRV
36#define __STDC_CONSTANT_MACROS
37#define __STDC_LIMIT_MACROS
38
39#include <os2ddk/bsekee.h>
40#undef RT_MAX
41
42#include "SUPDrvInternal.h"
43#include <VBox/version.h>
44#include <iprt/initterm.h>
45#include <iprt/string.h>
46#include <iprt/spinlock.h>
47#include <iprt/process.h>
48#include <iprt/assert.h>
49#include <VBox/log.h>
50#include <iprt/param.h>
51
52
53/*********************************************************************************************************************************
54* Global Variables *
55*********************************************************************************************************************************/
56/**
57 * Device extention & session data association structure.
58 */
59static SUPDRVDEVEXT g_DevExt;
60/** Spinlock protecting g_apSessionHashTab. */
61static RTSPINLOCK g_Spinlock = NIL_RTSPINLOCK;
62/** Hash table */
63static PSUPDRVSESSION g_apSessionHashTab[19];
64/** Calculates the index into g_apSessionHashTab.*/
65#define SESSION_HASH(sfn) ((sfn) % RT_ELEMENTS(g_apSessionHashTab))
66
67RT_C_DECLS_BEGIN
68/* Defined in SUPDrvA-os2.asm */
69extern uint16_t g_offLogHead;
70extern uint16_t volatile g_offLogTail;
71extern uint16_t const g_cchLogMax;
72extern char g_szLog[];
73/* (init only:) */
74extern char g_szInitText[];
75extern uint16_t g_cchInitText;
76extern uint16_t g_cchInitTextMax;
77RT_C_DECLS_END
78
79
80/*********************************************************************************************************************************
81* Internal Functions *
82*********************************************************************************************************************************/
83
84
85
86/**
87 * 32-bit Ring-0 initialization.
88 *
89 * @returns 0 on success, non-zero on failure.
90 * @param pszArgs Pointer to the device arguments.
91 */
92DECLASM(int) VBoxDrvInit(const char *pszArgs)
93{
94 /*
95 * Initialize the runtime.
96 */
97 int rc = RTR0Init(0);
98 if (RT_SUCCESS(rc))
99 {
100 Log(("VBoxDrvInit: pszArgs=%s\n", pszArgs));
101
102 /*
103 * Initialize the device extension.
104 */
105 rc = supdrvInitDevExt(&g_DevExt, sizeof(SUPDRVSESSION));
106 if (RT_SUCCESS(rc))
107 {
108 /*
109 * Initialize the session hash table.
110 */
111 rc = RTSpinlockCreate(&g_Spinlock, RTSPINLOCK_FLAGS_INTERRUPT_SAFE, "VBoxDrvOS2");
112 if (RT_SUCCESS(rc))
113 {
114 /*
115 * Process the commandline. Later.
116 */
117 bool fVerbose = true;
118
119 /*
120 * Success
121 */
122 if (fVerbose)
123 {
124 strcpy(&g_szInitText[0],
125 "\r\n"
126 "VirtualBox.org Support Driver for OS/2 version " VBOX_VERSION_STRING "\r\n"
127 "Copyright (C) 2007 Knut St. Osmundsen\r\n"
128 "Copyright (C) 2007-2016 Oracle Corporation\r\n");
129 g_cchInitText = strlen(&g_szInitText[0]);
130 }
131 return VINF_SUCCESS;
132 }
133 g_cchInitText = RTStrPrintf(&g_szInitText[0], g_cchInitTextMax, "VBoxDrv.sys: RTSpinlockCreate failed, rc=%Rrc\n", rc);
134 supdrvDeleteDevExt(&g_DevExt);
135 }
136 else
137 g_cchInitText = RTStrPrintf(&g_szInitText[0], g_cchInitTextMax, "VBoxDrv.sys: supdrvInitDevExt failed, rc=%Rrc\n", rc);
138 RTR0Term();
139 }
140 else
141 g_cchInitText = RTStrPrintf(&g_szInitText[0], g_cchInitTextMax, "VBoxDrv.sys: RTR0Init failed, rc=%Rrc\n", rc);
142 return rc;
143}
144
145
146DECLASM(int) VBoxDrvOpen(uint16_t sfn)
147{
148 int rc;
149 PSUPDRVSESSION pSession;
150
151 /*
152 * Create a new session.
153 */
154 rc = supdrvCreateSession(&g_DevExt, true /* fUser */, true /*fUnrestricted*/, &pSession);
155 if (RT_SUCCESS(rc))
156 {
157 pSession->sfn = sfn;
158
159 /*
160 * Insert it into the hash table.
161 */
162 unsigned iHash = SESSION_HASH(sfn);
163 RTSpinlockAcquire(g_Spinlock);
164 pSession->pNextHash = g_apSessionHashTab[iHash];
165 g_apSessionHashTab[iHash] = pSession;
166 RTSpinlockRelease(g_Spinlock);
167 }
168
169 Log(("VBoxDrvOpen: g_DevExt=%p pSession=%p rc=%d pid=%d\n", &g_DevExt, pSession, rc, (int)RTProcSelf()));
170 return rc;
171}
172
173
174DECLASM(int) VBoxDrvClose(uint16_t sfn)
175{
176 Log(("VBoxDrvClose: pid=%d sfn=%d\n", (int)RTProcSelf(), sfn));
177
178 /*
179 * Remove from the hash table.
180 */
181 PSUPDRVSESSION pSession;
182 const RTPROCESS Process = RTProcSelf();
183 const unsigned iHash = SESSION_HASH(sfn);
184 RTSpinlockAcquire(g_Spinlock);
185
186 pSession = g_apSessionHashTab[iHash];
187 if (pSession)
188 {
189 if ( pSession->sfn == sfn
190 && pSession->Process == Process)
191 {
192 g_apSessionHashTab[iHash] = pSession->pNextHash;
193 pSession->pNextHash = NULL;
194 }
195 else
196 {
197 PSUPDRVSESSION pPrev = pSession;
198 pSession = pSession->pNextHash;
199 while (pSession)
200 {
201 if ( pSession->sfn == sfn
202 && pSession->Process == Process)
203 {
204 pPrev->pNextHash = pSession->pNextHash;
205 pSession->pNextHash = NULL;
206 break;
207 }
208
209 /* next */
210 pPrev = pSession;
211 pSession = pSession->pNextHash;
212 }
213 }
214 }
215 RTSpinlockRelease(g_Spinlock);
216 if (!pSession)
217 {
218 OSDBGPRINT(("VBoxDrvIoctl: WHUT?!? pSession == NULL! This must be a mistake... pid=%d sfn=%d\n", (int)Process, sfn));
219 return VERR_INVALID_PARAMETER;
220 }
221
222 /*
223 * Close the session.
224 */
225 supdrvSessionRelease(pSession);
226 return 0;
227}
228
229
230DECLASM(int) VBoxDrvIOCtlFast(uint16_t sfn, uint8_t iFunction)
231{
232 /*
233 * Find the session.
234 */
235 const RTPROCESS Process = RTProcSelf();
236 const unsigned iHash = SESSION_HASH(sfn);
237 PSUPDRVSESSION pSession;
238
239 RTSpinlockAcquire(g_Spinlock);
240 pSession = g_apSessionHashTab[iHash];
241 if (pSession && pSession->Process != Process)
242 {
243 do pSession = pSession->pNextHash;
244 while ( pSession
245 && ( pSession->sfn != sfn
246 || pSession->Process != Process));
247
248 if (RT_LIKELY(pSession))
249 supdrvSessionRetain(pSession);
250 }
251 RTSpinlockRelease(g_Spinlock);
252 if (RT_UNLIKELY(!pSession))
253 {
254 OSDBGPRINT(("VBoxDrvIoctl: WHUT?!? pSession == NULL! This must be a mistake... pid=%d\n", (int)Process));
255 return VERR_INVALID_PARAMETER;
256 }
257
258 /*
259 * Dispatch the fast IOCtl.
260 */
261 supdrvIOCtlFast(iFunction, 0, &g_DevExt, pSession);
262 supdrvSessionRelease(pSession);
263 return 0;
264}
265
266
267DECLASM(int) VBoxDrvIOCtl(uint16_t sfn, uint8_t iCat, uint8_t iFunction, void *pvParm, void *pvData, uint16_t *pcbParm, uint16_t *pcbData)
268{
269 /*
270 * Find the session.
271 */
272 const RTPROCESS Process = RTProcSelf();
273 const unsigned iHash = SESSION_HASH(sfn);
274 PSUPDRVSESSION pSession;
275
276 RTSpinlockAcquire(g_Spinlock);
277 pSession = g_apSessionHashTab[iHash];
278 if (pSession && pSession->Process != Process)
279 {
280 do pSession = pSession->pNextHash;
281 while ( pSession
282 && ( pSession->sfn != sfn
283 || pSession->Process != Process));
284
285 if (RT_LIKELY(pSession))
286 supdrvSessionRetain(pSession);
287 }
288 RTSpinlockRelease(g_Spinlock);
289 if (!pSession)
290 {
291 OSDBGPRINT(("VBoxDrvIoctl: WHUT?!? pSession == NULL! This must be a mistake... pid=%d\n", (int)Process));
292 return VERR_INVALID_PARAMETER;
293 }
294
295 /*
296 * Verify the category and dispatch the IOCtl.
297 */
298 if (RT_LIKELY(iCat == SUP_CTL_CATEGORY))
299 {
300 Log(("VBoxDrvIOCtl: pSession=%p iFunction=%#x pvParm=%p pvData=%p *pcbParm=%d *pcbData=%d\n", pSession, iFunction, pvParm, pvData, *pcbParm, *pcbData));
301 Assert(pvParm);
302 Assert(!pvData);
303
304 /*
305 * Lock the header.
306 */
307 PSUPREQHDR pHdr = (PSUPREQHDR)pvParm;
308 AssertReturn(*pcbParm == sizeof(*pHdr), VERR_INVALID_PARAMETER);
309 KernVMLock_t Lock;
310 int rc = KernVMLock(VMDHL_WRITE, pHdr, *pcbParm, &Lock, (KernPageList_t *)-1, NULL);
311 AssertMsgReturn(!rc, ("KernVMLock(VMDHL_WRITE, %p, %#x, &p, NULL, NULL) -> %d\n", pHdr, *pcbParm, &Lock, rc), VERR_LOCK_FAILED);
312
313 /*
314 * Validate the header.
315 */
316 if (RT_LIKELY((pHdr->fFlags & SUPREQHDR_FLAGS_MAGIC_MASK) == SUPREQHDR_FLAGS_MAGIC))
317 {
318 uint32_t cbReq = RT_MAX(pHdr->cbIn, pHdr->cbOut);
319 if (RT_LIKELY( pHdr->cbIn >= sizeof(*pHdr)
320 && pHdr->cbOut >= sizeof(*pHdr)
321 && cbReq <= _1M*16))
322 {
323 /*
324 * Lock the rest of the buffer if necessary.
325 */
326 if (((uintptr_t)pHdr & PAGE_OFFSET_MASK) + cbReq > PAGE_SIZE)
327 {
328 rc = KernVMUnlock(&Lock);
329 AssertMsgReturn(!rc, ("KernVMUnlock(Lock) -> %#x\n", rc), VERR_LOCK_FAILED);
330
331 rc = KernVMLock(VMDHL_WRITE, pHdr, cbReq, &Lock, (KernPageList_t *)-1, NULL);
332 AssertMsgReturn(!rc, ("KernVMLock(VMDHL_WRITE, %p, %#x, &p, NULL, NULL) -> %d\n", pHdr, cbReq, &Lock, rc), VERR_LOCK_FAILED);
333 }
334
335 /*
336 * Process the IOCtl.
337 */
338 rc = supdrvIOCtl(iFunction, &g_DevExt, pSession, pHdr, cbReq);
339 }
340 else
341 {
342 OSDBGPRINT(("VBoxDrvIOCtl: max(%#x,%#x); iCmd=%#x\n", pHdr->cbIn, pHdr->cbOut, iFunction));
343 rc = VERR_INVALID_PARAMETER;
344 }
345 }
346 else
347 {
348 OSDBGPRINT(("VBoxDrvIOCtl: bad magic fFlags=%#x; iCmd=%#x\n", pHdr->fFlags, iFunction));
349 rc = VERR_INVALID_PARAMETER;
350 }
351
352 /*
353 * Unlock and return.
354 */
355 int rc2 = KernVMUnlock(&Lock);
356 AssertMsg(!rc2, ("rc2=%d\n", rc2)); NOREF(rc2);s
357 }
358 else
359 rc = VERR_NOT_SUPPORTED;
360
361 supdrvSessionRelease(pSession);
362 Log2(("VBoxDrvIOCtl: returns %d\n", rc));
363 return rc;
364}
365
366
367void VBOXCALL supdrvOSCleanupSession(PSUPDRVDEVEXT pDevExt, PSUPDRVSESSION pSession)
368{
369 NOREF(pDevExt);
370 NOREF(pSession);
371}
372
373
374void VBOXCALL supdrvOSSessionHashTabInserted(PSUPDRVDEVEXT pDevExt, PSUPDRVSESSION pSession, void *pvUser)
375{
376 NOREF(pDevExt); NOREF(pSession); NOREF(pvUser);
377}
378
379
380void VBOXCALL supdrvOSSessionHashTabRemoved(PSUPDRVDEVEXT pDevExt, PSUPDRVSESSION pSession, void *pvUser)
381{
382 NOREF(pDevExt); NOREF(pSession); NOREF(pvUser);
383}
384
385
386void VBOXCALL supdrvOSObjInitCreator(PSUPDRVOBJ pObj, PSUPDRVSESSION pSession)
387{
388 NOREF(pObj);
389 NOREF(pSession);
390}
391
392
393bool VBOXCALL supdrvOSObjCanAccess(PSUPDRVOBJ pObj, PSUPDRVSESSION pSession, const char *pszObjName, int *prc)
394{
395 NOREF(pObj);
396 NOREF(pSession);
397 NOREF(pszObjName);
398 NOREF(prc);
399 return false;
400}
401
402
403bool VBOXCALL supdrvOSGetForcedAsyncTscMode(PSUPDRVDEVEXT pDevExt)
404{
405 NOREF(pDevExt);
406 return false;
407}
408
409
410bool VBOXCALL supdrvOSAreCpusOfflinedOnSuspend(void)
411{
412 return false;
413}
414
415
416bool VBOXCALL supdrvOSAreTscDeltasInSync(void)
417{
418 NOREF(pDevExt);
419 return false;
420}
421
422
423int VBOXCALL supdrvOSLdrOpen(PSUPDRVDEVEXT pDevExt, PSUPDRVLDRIMAGE pImage, const char *pszFilename)
424{
425 NOREF(pDevExt); NOREF(pImage); NOREF(pszFilename);
426 return VERR_NOT_SUPPORTED;
427}
428
429
430int VBOXCALL supdrvOSLdrValidatePointer(PSUPDRVDEVEXT pDevExt, PSUPDRVLDRIMAGE pImage, void *pv, const uint8_t *pbImageBits)
431{
432 NOREF(pDevExt); NOREF(pImage); NOREF(pv); NOREF(pbImageBits);
433 return VERR_NOT_SUPPORTED;
434}
435
436
437int VBOXCALL supdrvOSLdrLoad(PSUPDRVDEVEXT pDevExt, PSUPDRVLDRIMAGE pImage, const uint8_t *pbImageBits, PSUPLDRLOAD pReq)
438{
439 NOREF(pDevExt); NOREF(pImage); NOREF(pbImageBits); NOREF(pReq);
440 return VERR_NOT_SUPPORTED;
441}
442
443
444void VBOXCALL supdrvOSLdrUnload(PSUPDRVDEVEXT pDevExt, PSUPDRVLDRIMAGE pImage)
445{
446 NOREF(pDevExt); NOREF(pImage);
447}
448
449
450void VBOXCALL supdrvOSLdrNotifyOpened(PSUPDRVDEVEXT pDevExt, PSUPDRVLDRIMAGE pImage, const char *pszFilename)
451{
452 NOREF(pDevExt); NOREF(pImage); NOREF(pszFilename);
453}
454
455
456void VBOXCALL supdrvOSLdrNotifyUnloaded(PSUPDRVDEVEXT pDevExt, PSUPDRVLDRIMAGE pImage)
457{
458 NOREF(pDevExt); NOREF(pImage);
459}
460
461
462#ifdef SUPDRV_WITH_MSR_PROBER
463
464int VBOXCALL supdrvOSMsrProberRead(uint32_t uMsr, RTCPUID idCpu, uint64_t *puValue)
465{
466 NOREF(uMsr); NOREF(idCpu); NOREF(puValue);
467 return VERR_NOT_SUPPORTED;
468}
469
470
471int VBOXCALL supdrvOSMsrProberWrite(uint32_t uMsr, RTCPUID idCpu, uint64_t uValue)
472{
473 NOREF(uMsr); NOREF(idCpu); NOREF(uValue);
474 return VERR_NOT_SUPPORTED;
475}
476
477
478int VBOXCALL supdrvOSMsrProberModify(RTCPUID idCpu, PSUPMSRPROBER pReq)
479{
480 NOREF(idCpu); NOREF(pReq);
481 return VERR_NOT_SUPPORTED;
482}
483
484#endif /* SUPDRV_WITH_MSR_PROBER */
485
486
487/**
488 * Callback for writing to the log buffer.
489 *
490 * @returns number of bytes written.
491 * @param pvArg Unused.
492 * @param pachChars Pointer to an array of utf-8 characters.
493 * @param cbChars Number of bytes in the character array pointed to by pachChars.
494 */
495static DECLCALLBACK(size_t) VBoxDrvLogOutput(void *pvArg, const char *pachChars, size_t cbChars)
496{
497 size_t cchWritten = 0;
498 while (cbChars-- > 0)
499 {
500 const uint16_t offLogHead = g_offLogHead;
501 const uint16_t offLogHeadNext = (offLogHead + 1) & (g_cchLogMax - 1);
502 if (offLogHeadNext == g_offLogTail)
503 break; /* no */
504 g_szLog[offLogHead] = *pachChars++;
505 g_offLogHead = offLogHeadNext;
506 cchWritten++;
507 }
508 return cchWritten;
509}
510
511
512SUPR0DECL(int) SUPR0Printf(const char *pszFormat, ...)
513{
514 va_list va;
515
516#if 0 //def DEBUG_bird
517 va_start(va, pszFormat);
518 RTLogComPrintfV(pszFormat, va);
519 va_end(va);
520#endif
521
522 va_start(va, pszFormat);
523 int cch = RTLogFormatV(VBoxDrvLogOutput, NULL, pszFormat, va);
524 va_end(va);
525
526 return cch;
527}
528
529
530SUPR0DECL(uint32_t) SUPR0GetKernelFeatures(void)
531{
532 return 0;
533}
534
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