VirtualBox

source: vbox/trunk/src/VBox/HostDrivers/Support/freebsd/SUPDrv-freebsd.c

Last change on this file was 99739, checked in by vboxsync, 19 months ago

*: doxygen corrections (mostly about removing @returns from functions returning void).

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 19.3 KB
Line 
1/* $Id: SUPDrv-freebsd.c 99739 2023-05-11 01:01:08Z vboxsync $ */
2/** @file
3 * VBoxDrv - The VirtualBox Support Driver - FreeBSD specifics.
4 */
5
6/*
7 * Copyright (c) 2007 knut st. osmundsen <[email protected]>
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/* Deal with conflicts first. */
37#include <sys/param.h>
38#undef PVM
39#include <sys/types.h>
40#include <sys/module.h>
41#include <sys/systm.h>
42#include <sys/errno.h>
43#include <sys/kernel.h>
44#include <sys/fcntl.h>
45#include <sys/conf.h>
46#include <sys/uio.h>
47#include <vm/pmap.h> /* for pmap_map() */
48
49#include "../SUPDrvInternal.h"
50#include <VBox/version.h>
51#include <iprt/initterm.h>
52#include <iprt/string.h>
53#include <iprt/spinlock.h>
54#include <iprt/process.h>
55#include <iprt/assert.h>
56#include <iprt/uuid.h>
57#include <VBox/log.h>
58#include <iprt/alloc.h>
59#include <iprt/err.h>
60#include <iprt/asm.h>
61
62#ifdef VBOX_WITH_HARDENING
63# define VBOXDRV_PERM 0600
64#else
65# define VBOXDRV_PERM 0666
66#endif
67
68
69/*********************************************************************************************************************************
70* Internal Functions *
71*********************************************************************************************************************************/
72static int VBoxDrvFreeBSDModuleEvent(struct module *pMod, int enmEventType, void *pvArg);
73static int VBoxDrvFreeBSDLoad(void);
74static int VBoxDrvFreeBSDUnload(void);
75
76static d_open_t VBoxDrvFreeBSDOpenUsr;
77static d_open_t VBoxDrvFreeBSDOpenSys;
78static void vboxdrvFreeBSDDtr(void *pvData);
79static d_ioctl_t VBoxDrvFreeBSDIOCtl;
80static int VBoxDrvFreeBSDIOCtlSlow(PSUPDRVSESSION pSession, u_long ulCmd, caddr_t pvData, struct thread *pTd);
81
82
83/*********************************************************************************************************************************
84* Global Variables *
85*********************************************************************************************************************************/
86/**
87 * Module info structure used by the kernel.
88 */
89static moduledata_t g_VBoxDrvFreeBSDModule =
90{
91 "vboxdrv",
92 VBoxDrvFreeBSDModuleEvent,
93 NULL
94};
95
96/** Declare the module as a pseudo device. */
97DECLARE_MODULE(vboxdrv, g_VBoxDrvFreeBSDModule, SI_SUB_PSEUDO, SI_ORDER_ANY);
98MODULE_VERSION(vboxdrv, 1);
99
100/**
101 * The /dev/vboxdrv character device entry points.
102 */
103static struct cdevsw g_VBoxDrvFreeBSDChrDevSwSys =
104{
105 .d_version = D_VERSION,
106 .d_open = VBoxDrvFreeBSDOpenSys,
107 .d_ioctl = VBoxDrvFreeBSDIOCtl,
108 .d_name = "vboxdrv"
109};
110/** The /dev/vboxdrv character device. */
111static struct cdev *g_pVBoxDrvFreeBSDChrDevSys;
112
113/**
114 * The /dev/vboxdrvu character device entry points.
115 */
116static struct cdevsw g_VBoxDrvFreeBSDChrDevSwUsr =
117{
118 .d_version = D_VERSION,
119 .d_open = VBoxDrvFreeBSDOpenUsr,
120 .d_ioctl = VBoxDrvFreeBSDIOCtl,
121 .d_name = "vboxdrvu"
122};
123/** The /dev/vboxdrvu character device. */
124static struct cdev *g_pVBoxDrvFreeBSDChrDevUsr;
125
126/** Reference counter. */
127static volatile uint32_t g_cUsers;
128
129/** The device extention. */
130static SUPDRVDEVEXT g_VBoxDrvFreeBSDDevExt;
131
132/**
133 * Module event handler.
134 *
135 * @param pMod The module structure.
136 * @param enmEventType The event type (modeventtype_t).
137 * @param pvArg Module argument. NULL.
138 *
139 * @return 0 on success, errno.h status code on failure.
140 */
141static int VBoxDrvFreeBSDModuleEvent(struct module *pMod, int enmEventType, void *pvArg)
142{
143 int rc;
144 switch (enmEventType)
145 {
146 case MOD_LOAD:
147 rc = VBoxDrvFreeBSDLoad();
148 break;
149
150 case MOD_UNLOAD:
151 mtx_unlock(&Giant);
152 rc = VBoxDrvFreeBSDUnload();
153 mtx_lock(&Giant);
154 break;
155
156 case MOD_SHUTDOWN:
157 case MOD_QUIESCE:
158 default:
159 return EOPNOTSUPP;
160 }
161
162 if (RT_SUCCESS(rc))
163 return 0;
164 return RTErrConvertToErrno(rc);
165}
166
167
168static int VBoxDrvFreeBSDLoad(void)
169{
170 g_cUsers = 0;
171
172 /*
173 * Initialize the runtime.
174 */
175 int rc = RTR0Init(0);
176 if (RT_SUCCESS(rc))
177 {
178 Log(("VBoxDrvFreeBSDLoad:\n"));
179
180 /*
181 * Initialize the device extension.
182 */
183 rc = supdrvInitDevExt(&g_VBoxDrvFreeBSDDevExt, sizeof(SUPDRVSESSION));
184 if (RT_SUCCESS(rc))
185 {
186 /*
187 * Configure character devices. Add symbolic links for compatibility.
188 */
189 g_pVBoxDrvFreeBSDChrDevSys = make_dev(&g_VBoxDrvFreeBSDChrDevSwSys, 0, UID_ROOT, GID_WHEEL, VBOXDRV_PERM, "vboxdrv");
190 g_pVBoxDrvFreeBSDChrDevUsr = make_dev(&g_VBoxDrvFreeBSDChrDevSwUsr, 1, UID_ROOT, GID_WHEEL, 0666, "vboxdrvu");
191 return VINF_SUCCESS;
192 }
193
194 printf("vboxdrv: supdrvInitDevExt failed, rc=%d\n", rc);
195 RTR0Term();
196 }
197 else
198 printf("vboxdrv: RTR0Init failed, rc=%d\n", rc);
199 return rc;
200}
201
202static int VBoxDrvFreeBSDUnload(void)
203{
204 Log(("VBoxDrvFreeBSDUnload:\n"));
205
206 if (g_cUsers > 0)
207 return VERR_RESOURCE_BUSY;
208
209 /*
210 * Reserve what we did in VBoxDrvFreeBSDInit.
211 */
212 destroy_dev(g_pVBoxDrvFreeBSDChrDevUsr);
213 destroy_dev(g_pVBoxDrvFreeBSDChrDevSys);
214
215 supdrvDeleteDevExt(&g_VBoxDrvFreeBSDDevExt);
216
217 RTR0TermForced();
218
219 memset(&g_VBoxDrvFreeBSDDevExt, 0, sizeof(g_VBoxDrvFreeBSDDevExt));
220 return VINF_SUCCESS;
221}
222
223
224/**
225 *
226 * @returns 0 on success, errno on failure.
227 * EBUSY if the device is used by someone else.
228 * @param pDev The device node.
229 * @param fOpen The open flags.
230 * @param iDevType Some device type thing we don't use.
231 * @param pTd The thread.
232 * @param fUnrestricted Set if opening /dev/vboxdrv, clear if /dev/vboxdrvu.
233 */
234static int vboxdrvFreeBSDOpenCommon(struct cdev *pDev, int fOpen, int iDevType, struct thread *pTd, bool fUnrestricted)
235{
236 PSUPDRVSESSION pSession;
237 int rc;
238
239 /*
240 * Let's be a bit picky about the flags...
241 */
242 if (fOpen != (FREAD | FWRITE /*=O_RDWR*/))
243 {
244 Log(("VBoxDrvFreeBSDOpen: fOpen=%#x expected %#x\n", fOpen, O_RDWR));
245 return EINVAL;
246 }
247
248 /*
249 * Create a new session.
250 */
251 rc = supdrvCreateSession(&g_VBoxDrvFreeBSDDevExt, true /* fUser */, fUnrestricted, &pSession);
252 if (RT_SUCCESS(rc))
253 {
254 /** @todo get (r)uid and (r)gid.
255 pSession->Uid = stuff;
256 pSession->Gid = stuff; */
257 rc = devfs_set_cdevpriv(pSession, vboxdrvFreeBSDDtr); Assert(rc == 0);
258 Log(("VBoxDrvFreeBSDOpen: pSession=%p\n", pSession));
259 ASMAtomicIncU32(&g_cUsers);
260 return 0;
261 }
262
263 return RTErrConvertToErrno(rc);
264}
265
266
267/** For vboxdrv. */
268static int VBoxDrvFreeBSDOpenSys(struct cdev *pDev, int fOpen, int iDevType, struct thread *pTd)
269{
270 return vboxdrvFreeBSDOpenCommon(pDev, fOpen, iDevType, pTd, true);
271}
272
273
274/** For vboxdrvu. */
275static int VBoxDrvFreeBSDOpenUsr(struct cdev *pDev, int fOpen, int iDevType, struct thread *pTd)
276{
277 return vboxdrvFreeBSDOpenCommon(pDev, fOpen, iDevType, pTd, false);
278}
279
280
281/**
282 * Close a file device previously opened by VBoxDrvFreeBSDOpen.
283 *
284 * @param pvData The session being closed.
285 */
286static void vboxdrvFreeBSDDtr(void *pvData)
287{
288 PSUPDRVSESSION pSession = pvData;
289 Log(("vboxdrvFreeBSDDtr: pSession=%p\n", pSession));
290
291 /*
292 * Close the session.
293 */
294 supdrvSessionRelease(pSession);
295 ASMAtomicDecU32(&g_cUsers);
296}
297
298
299/**
300 * I/O control request.
301 *
302 * @returns depends...
303 * @param pDev The device.
304 * @param ulCmd The command.
305 * @param pvData Pointer to the data.
306 * @param fFile The file descriptor flags.
307 * @param pTd The calling thread.
308 */
309static int VBoxDrvFreeBSDIOCtl(struct cdev *pDev, u_long ulCmd, caddr_t pvData, int fFile, struct thread *pTd)
310{
311 PSUPDRVSESSION pSession;
312 devfs_get_cdevpriv((void **)&pSession);
313
314 /*
315 * Deal with the fast ioctl path first.
316 */
317 AssertCompile((SUP_IOCTL_FAST_DO_FIRST & 0xff) == (SUP_IOCTL_FLAG | 64));
318 if ( (uintptr_t)(ulCmd - SUP_IOCTL_FAST_DO_FIRST) < (uintptr_t)32
319 && pSession->fUnrestricted)
320 return supdrvIOCtlFast(ulCmd - SUP_IOCTL_FAST_DO_FIRST, *(uint32_t *)pvData, &g_VBoxDrvFreeBSDDevExt, pSession);
321
322 return VBoxDrvFreeBSDIOCtlSlow(pSession, ulCmd, pvData, pTd);
323}
324
325
326/**
327 * Deal with the 'slow' I/O control requests.
328 *
329 * @returns 0 on success, appropriate errno on failure.
330 * @param pSession The session.
331 * @param ulCmd The command.
332 * @param pvData The request data.
333 * @param pTd The calling thread.
334 */
335static int VBoxDrvFreeBSDIOCtlSlow(PSUPDRVSESSION pSession, u_long ulCmd, caddr_t pvData, struct thread *pTd)
336{
337 PSUPREQHDR pHdr;
338 uint32_t cbReq = IOCPARM_LEN(ulCmd);
339 void *pvUser = NULL;
340
341 /*
342 * Buffered request?
343 */
344 if ((IOC_DIRMASK & ulCmd) == IOC_INOUT)
345 {
346 pHdr = (PSUPREQHDR)pvData;
347 if (RT_UNLIKELY(cbReq < sizeof(*pHdr)))
348 {
349 OSDBGPRINT(("VBoxDrvFreeBSDIOCtlSlow: cbReq=%#x < %#x; ulCmd=%#lx\n", cbReq, (int)sizeof(*pHdr), ulCmd));
350 return EINVAL;
351 }
352 if (RT_UNLIKELY((pHdr->fFlags & SUPREQHDR_FLAGS_MAGIC_MASK) != SUPREQHDR_FLAGS_MAGIC))
353 {
354 OSDBGPRINT(("VBoxDrvFreeBSDIOCtlSlow: bad magic fFlags=%#x; ulCmd=%#lx\n", pHdr->fFlags, ulCmd));
355 return EINVAL;
356 }
357 if (RT_UNLIKELY( RT_MAX(pHdr->cbIn, pHdr->cbOut) != cbReq
358 || pHdr->cbIn < sizeof(*pHdr)
359 || pHdr->cbOut < sizeof(*pHdr)))
360 {
361 OSDBGPRINT(("VBoxDrvFreeBSDIOCtlSlow: max(%#x,%#x) != %#x; ulCmd=%#lx\n", pHdr->cbIn, pHdr->cbOut, cbReq, ulCmd));
362 return EINVAL;
363 }
364 }
365 /*
366 * Big unbuffered request?
367 */
368 else if ((IOC_DIRMASK & ulCmd) == IOC_VOID && !cbReq)
369 {
370 /*
371 * Read the header, validate it and figure out how much that needs to be buffered.
372 */
373 SUPREQHDR Hdr;
374 pvUser = *(void **)pvData;
375 int rc = copyin(pvUser, &Hdr, sizeof(Hdr));
376 if (RT_UNLIKELY(rc))
377 {
378 OSDBGPRINT(("VBoxDrvFreeBSDIOCtlSlow: copyin(%p,Hdr,) -> %#x; ulCmd=%#lx\n", pvUser, rc, ulCmd));
379 return rc;
380 }
381 if (RT_UNLIKELY((Hdr.fFlags & SUPREQHDR_FLAGS_MAGIC_MASK) != SUPREQHDR_FLAGS_MAGIC))
382 {
383 OSDBGPRINT(("VBoxDrvFreeBSDIOCtlSlow: bad magic fFlags=%#x; ulCmd=%#lx\n", Hdr.fFlags, ulCmd));
384 return EINVAL;
385 }
386 cbReq = RT_MAX(Hdr.cbIn, Hdr.cbOut);
387 if (RT_UNLIKELY( Hdr.cbIn < sizeof(Hdr)
388 || Hdr.cbOut < sizeof(Hdr)
389 || cbReq > _1M*16))
390 {
391 OSDBGPRINT(("VBoxDrvFreeBSDIOCtlSlow: max(%#x,%#x); ulCmd=%#lx\n", Hdr.cbIn, Hdr.cbOut, ulCmd));
392 return EINVAL;
393 }
394
395 /*
396 * Allocate buffer and copy in the data.
397 */
398 pHdr = (PSUPREQHDR)RTMemTmpAlloc(cbReq);
399 if (RT_UNLIKELY(!pHdr))
400 {
401 OSDBGPRINT(("VBoxDrvFreeBSDIOCtlSlow: failed to allocate buffer of %d bytes; ulCmd=%#lx\n", cbReq, ulCmd));
402 return ENOMEM;
403 }
404 rc = copyin(pvUser, pHdr, Hdr.cbIn);
405 if (RT_UNLIKELY(rc))
406 {
407 OSDBGPRINT(("VBoxDrvFreeBSDIOCtlSlow: copyin(%p,%p,%#x) -> %#x; ulCmd=%#lx\n",
408 pvUser, pHdr, Hdr.cbIn, rc, ulCmd));
409 RTMemTmpFree(pHdr);
410 return rc;
411 }
412 if (Hdr.cbIn < cbReq)
413 RT_BZERO((uint8_t *)pHdr + Hdr.cbIn, cbReq - Hdr.cbIn);
414 }
415 else
416 {
417 Log(("VBoxDrvFreeBSDIOCtlSlow: huh? cbReq=%#x ulCmd=%#lx\n", cbReq, ulCmd));
418 return EINVAL;
419 }
420
421 /*
422 * Process the IOCtl.
423 */
424 int rc = supdrvIOCtl(ulCmd, &g_VBoxDrvFreeBSDDevExt, pSession, pHdr, cbReq);
425 if (RT_LIKELY(!rc))
426 {
427 /*
428 * If unbuffered, copy back the result before returning.
429 */
430 if (pvUser)
431 {
432 uint32_t cbOut = pHdr->cbOut;
433 if (cbOut > cbReq)
434 {
435 OSDBGPRINT(("VBoxDrvFreeBSDIOCtlSlow: too much output! %#x > %#x; uCmd=%#lx!\n", cbOut, cbReq, ulCmd));
436 cbOut = cbReq;
437 }
438 rc = copyout(pHdr, pvUser, cbOut);
439 if (RT_UNLIKELY(rc))
440 OSDBGPRINT(("VBoxDrvFreeBSDIOCtlSlow: copyout(%p,%p,%#x) -> %d; uCmd=%#lx!\n", pHdr, pvUser, cbOut, rc, ulCmd));
441
442 Log(("VBoxDrvFreeBSDIOCtlSlow: returns %d / %d ulCmd=%lx\n", 0, pHdr->rc, ulCmd));
443
444 /* cleanup */
445 RTMemTmpFree(pHdr);
446 }
447 }
448 else
449 {
450 /*
451 * The request failed, just clean up.
452 */
453 if (pvUser)
454 RTMemTmpFree(pHdr);
455
456 Log(("VBoxDrvFreeBSDIOCtlSlow: ulCmd=%lx pData=%p failed, rc=%d\n", ulCmd, pvData, rc));
457 rc = EINVAL;
458 }
459
460 return rc;
461}
462
463
464/**
465 * The SUPDRV IDC entry point.
466 *
467 * @returns VBox status code, see supdrvIDC.
468 * @param uReq The request code.
469 * @param pReq The request.
470 */
471int VBOXCALL SUPDrvFreeBSDIDC(uint32_t uReq, PSUPDRVIDCREQHDR pReq)
472{
473 PSUPDRVSESSION pSession;
474
475 /*
476 * Some quick validations.
477 */
478 if (RT_UNLIKELY(!RT_VALID_PTR(pReq)))
479 return VERR_INVALID_POINTER;
480
481 pSession = pReq->pSession;
482 if (pSession)
483 {
484 if (RT_UNLIKELY(!RT_VALID_PTR(pReq->pSession)))
485 return VERR_INVALID_PARAMETER;
486 if (RT_UNLIKELY(pSession->pDevExt != &g_VBoxDrvFreeBSDDevExt))
487 return VERR_INVALID_PARAMETER;
488 }
489 else if (RT_UNLIKELY(uReq != SUPDRV_IDC_REQ_CONNECT))
490 return VERR_INVALID_PARAMETER;
491
492 /*
493 * Do the job.
494 */
495 return supdrvIDC(uReq, &g_VBoxDrvFreeBSDDevExt, pSession, pReq);
496}
497
498
499void VBOXCALL supdrvOSCleanupSession(PSUPDRVDEVEXT pDevExt, PSUPDRVSESSION pSession)
500{
501 NOREF(pDevExt);
502 NOREF(pSession);
503}
504
505
506void VBOXCALL supdrvOSSessionHashTabInserted(PSUPDRVDEVEXT pDevExt, PSUPDRVSESSION pSession, void *pvUser)
507{
508 NOREF(pDevExt); NOREF(pSession); NOREF(pvUser);
509}
510
511
512void VBOXCALL supdrvOSSessionHashTabRemoved(PSUPDRVDEVEXT pDevExt, PSUPDRVSESSION pSession, void *pvUser)
513{
514 NOREF(pDevExt); NOREF(pSession); NOREF(pvUser);
515}
516
517
518void VBOXCALL supdrvOSObjInitCreator(PSUPDRVOBJ pObj, PSUPDRVSESSION pSession)
519{
520 NOREF(pObj);
521 NOREF(pSession);
522}
523
524
525bool VBOXCALL supdrvOSObjCanAccess(PSUPDRVOBJ pObj, PSUPDRVSESSION pSession, const char *pszObjName, int *prc)
526{
527 NOREF(pObj);
528 NOREF(pSession);
529 NOREF(pszObjName);
530 NOREF(prc);
531 return false;
532}
533
534
535bool VBOXCALL supdrvOSGetForcedAsyncTscMode(PSUPDRVDEVEXT pDevExt)
536{
537 return false;
538}
539
540
541bool VBOXCALL supdrvOSAreCpusOfflinedOnSuspend(void)
542{
543 /** @todo verify this. */
544 return false;
545}
546
547
548bool VBOXCALL supdrvOSAreTscDeltasInSync(void)
549{
550 return false;
551}
552
553
554int VBOXCALL supdrvOSLdrOpen(PSUPDRVDEVEXT pDevExt, PSUPDRVLDRIMAGE pImage, const char *pszFilename)
555{
556 NOREF(pDevExt); NOREF(pImage); NOREF(pszFilename);
557 return VERR_NOT_SUPPORTED;
558}
559
560
561int VBOXCALL supdrvOSLdrValidatePointer(PSUPDRVDEVEXT pDevExt, PSUPDRVLDRIMAGE pImage, void *pv,
562 const uint8_t *pbImageBits, const char *pszSymbol)
563{
564 NOREF(pDevExt); NOREF(pImage); NOREF(pv); NOREF(pbImageBits); NOREF(pszSymbol);
565 return VERR_NOT_SUPPORTED;
566}
567
568
569int VBOXCALL supdrvOSLdrLoad(PSUPDRVDEVEXT pDevExt, PSUPDRVLDRIMAGE pImage, const uint8_t *pbImageBits, PSUPLDRLOAD pReq)
570{
571 NOREF(pDevExt); NOREF(pImage); NOREF(pbImageBits); NOREF(pReq);
572 return VERR_NOT_SUPPORTED;
573}
574
575
576void VBOXCALL supdrvOSLdrUnload(PSUPDRVDEVEXT pDevExt, PSUPDRVLDRIMAGE pImage)
577{
578 NOREF(pDevExt); NOREF(pImage);
579}
580
581
582void VBOXCALL supdrvOSLdrNotifyOpened(PSUPDRVDEVEXT pDevExt, PSUPDRVLDRIMAGE pImage, const char *pszFilename)
583{
584 NOREF(pDevExt); NOREF(pImage); NOREF(pszFilename);
585}
586
587
588void VBOXCALL supdrvOSLdrNotifyUnloaded(PSUPDRVDEVEXT pDevExt, PSUPDRVLDRIMAGE pImage)
589{
590 NOREF(pDevExt); NOREF(pImage);
591}
592
593
594int VBOXCALL supdrvOSLdrQuerySymbol(PSUPDRVDEVEXT pDevExt, PSUPDRVLDRIMAGE pImage,
595 const char *pszSymbol, size_t cchSymbol, void **ppvSymbol)
596{
597 RT_NOREF(pDevExt, pImage, pszSymbol, cchSymbol, ppvSymbol);
598 return VERR_WRONG_ORDER;
599}
600
601
602void VBOXCALL supdrvOSLdrRetainWrapperModule(PSUPDRVDEVEXT pDevExt, PSUPDRVLDRIMAGE pImage)
603{
604 RT_NOREF(pDevExt, pImage);
605 AssertFailed();
606}
607
608
609void VBOXCALL supdrvOSLdrReleaseWrapperModule(PSUPDRVDEVEXT pDevExt, PSUPDRVLDRIMAGE pImage)
610{
611 RT_NOREF(pDevExt, pImage);
612 AssertFailed();
613}
614
615#ifdef SUPDRV_WITH_MSR_PROBER
616
617int VBOXCALL supdrvOSMsrProberRead(uint32_t uMsr, RTCPUID idCpu, uint64_t *puValue)
618{
619 NOREF(uMsr); NOREF(idCpu); NOREF(puValue);
620 return VERR_NOT_SUPPORTED;
621}
622
623
624int VBOXCALL supdrvOSMsrProberWrite(uint32_t uMsr, RTCPUID idCpu, uint64_t uValue)
625{
626 NOREF(uMsr); NOREF(idCpu); NOREF(uValue);
627 return VERR_NOT_SUPPORTED;
628}
629
630
631int VBOXCALL supdrvOSMsrProberModify(RTCPUID idCpu, PSUPMSRPROBER pReq)
632{
633 NOREF(idCpu); NOREF(pReq);
634 return VERR_NOT_SUPPORTED;
635}
636
637#endif /* SUPDRV_WITH_MSR_PROBER */
638
639
640#if defined(RT_ARCH_AMD64) || defined(RT_ARCH_ARM64)
641SUPR0DECL(int) SUPR0HCPhysToVirt(RTHCPHYS HCPhys, void **ppv)
642{
643 AssertReturn(!(HCPhys & PAGE_OFFSET_MASK), VERR_INVALID_POINTER);
644 AssertReturn(HCPhys != NIL_RTHCPHYS, VERR_INVALID_POINTER);
645 *ppv = (void *)(uintptr_t)pmap_map(NULL, HCPhys, (HCPhys | PAGE_OFFSET_MASK) + 1, VM_PROT_WRITE | VM_PROT_READ);
646 return VINF_SUCCESS;
647}
648#endif
649
650
651SUPR0DECL(int) SUPR0PrintfV(const char *pszFormat, va_list va)
652{
653 char szMsg[256];
654 RTStrPrintfV(szMsg, sizeof(szMsg), pszFormat, va);
655 szMsg[sizeof(szMsg) - 1] = '\0';
656
657 printf("%s", szMsg);
658 return 0;
659}
660
661
662SUPR0DECL(uint32_t) SUPR0GetKernelFeatures(void)
663{
664 return 0;
665}
666
667
668SUPR0DECL(bool) SUPR0FpuBegin(bool fCtxHook)
669{
670 RT_NOREF(fCtxHook);
671 return false;
672}
673
674
675SUPR0DECL(void) SUPR0FpuEnd(bool fCtxHook)
676{
677 RT_NOREF(fCtxHook);
678}
679
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