VirtualBox

source: vbox/trunk/src/VBox/HostDrivers/Support/SUPDrvInternal.h@ 54321

Last change on this file since 54321 was 54315, checked in by vboxsync, 10 years ago

SUPDrv: Eliminated the need for the GIP master to have a zero TSC delta value. Fixed incorrect RTCPUSET indexing (don't use idCpu!). Documented the tsc delta thred states. Made it transition from terminating to destroyed. Renamed supdrvMeasureTscDeltas to supdrvMeasureInitialTscDeltas and dropped the unused pidxMaster parameter.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 37.4 KB
Line 
1/* $Id: SUPDrvInternal.h 54315 2015-02-19 21:33:21Z vboxsync $ */
2/** @file
3 * VirtualBox Support Driver - Internal header.
4 */
5
6/*
7 * Copyright (C) 2006-2014 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#ifndef ___SUPDrvInternal_h
28#define ___SUPDrvInternal_h
29
30
31/*******************************************************************************
32* Header Files *
33*******************************************************************************/
34#include <VBox/cdefs.h>
35#include <VBox/types.h>
36#include <VBox/sup.h>
37
38#include <iprt/assert.h>
39#include <iprt/list.h>
40#include <iprt/memobj.h>
41#include <iprt/time.h>
42#include <iprt/timer.h>
43#include <iprt/string.h>
44#include <iprt/err.h>
45
46#ifdef SUPDRV_AGNOSTIC
47/* do nothing */
48
49#elif defined(RT_OS_WINDOWS)
50 RT_C_DECLS_BEGIN
51# if (_MSC_VER >= 1400) && !defined(VBOX_WITH_PATCHED_DDK)
52# define _InterlockedExchange _InterlockedExchange_StupidDDKVsCompilerCrap
53# define _InterlockedExchangeAdd _InterlockedExchangeAdd_StupidDDKVsCompilerCrap
54# define _InterlockedCompareExchange _InterlockedCompareExchange_StupidDDKVsCompilerCrap
55# define _InterlockedAddLargeStatistic _InterlockedAddLargeStatistic_StupidDDKVsCompilerCrap
56# define _interlockedbittestandset _interlockedbittestandset_StupidDDKVsCompilerCrap
57# define _interlockedbittestandreset _interlockedbittestandreset_StupidDDKVsCompilerCrap
58# define _interlockedbittestandset64 _interlockedbittestandset64_StupidDDKVsCompilerCrap
59# define _interlockedbittestandreset64 _interlockedbittestandreset64_StupidDDKVsCompilerCrap
60# pragma warning(disable : 4163)
61# include <iprt/nt/nt.h>
62# pragma warning(default : 4163)
63# undef _InterlockedExchange
64# undef _InterlockedExchangeAdd
65# undef _InterlockedCompareExchange
66# undef _InterlockedAddLargeStatistic
67# undef _interlockedbittestandset
68# undef _interlockedbittestandreset
69# undef _interlockedbittestandset64
70# undef _interlockedbittestandreset64
71# else
72# include <iprt/nt/nt.h>
73# endif
74# include <memory.h>
75 RT_C_DECLS_END
76
77#elif defined(RT_OS_LINUX)
78# include <linux/version.h>
79# if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 33)
80# include <generated/autoconf.h>
81# else
82# ifndef AUTOCONF_INCLUDED
83# include <linux/autoconf.h>
84# endif
85# endif
86# if defined(CONFIG_MODVERSIONS) && !defined(MODVERSIONS)
87# define MODVERSIONS
88# if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 71)
89# include <linux/modversions.h>
90# endif
91# endif
92# if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 0)
93# undef ALIGN
94# endif
95# ifndef KBUILD_STR
96# if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 16)
97# define KBUILD_STR(s) s
98# else
99# define KBUILD_STR(s) #s
100# endif
101# endif
102# include <linux/string.h>
103# include <linux/spinlock.h>
104# include <linux/slab.h>
105# if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)
106# include <linux/semaphore.h>
107# else /* older kernels */
108# include <asm/semaphore.h>
109# endif /* older kernels */
110# include <linux/timer.h>
111
112#elif defined(RT_OS_DARWIN)
113# include <libkern/libkern.h>
114# include <iprt/string.h>
115
116#elif defined(RT_OS_OS2)
117
118#elif defined(RT_OS_FREEBSD)
119# define memset libkern_memset /** @todo these are just hacks to get it compiling, check out later. */
120# define memcmp libkern_memcmp
121# define strchr libkern_strchr
122# define strrchr libkern_strrchr
123# define ffsl libkern_ffsl
124# define fls libkern_fls
125# define flsl libkern_flsl
126# include <sys/libkern.h>
127# undef memset
128# undef memcmp
129# undef strchr
130# undef strrchr
131# undef ffs
132# undef ffsl
133# undef fls
134# undef flsl
135# include <iprt/string.h>
136
137#elif defined(RT_OS_SOLARIS)
138# include <sys/cmn_err.h>
139# include <iprt/string.h>
140
141#else
142# error "unsupported OS."
143#endif
144
145#include "SUPDrvIOC.h"
146#include "SUPDrvIDC.h"
147
148
149
150/*******************************************************************************
151* Defined Constants And Macros *
152*******************************************************************************/
153/*
154 * Hardcoded cookies.
155 */
156#define BIRD 0x64726962 /* 'bird' */
157#define BIRD_INV 0x62697264 /* 'drib' */
158
159
160#ifdef RT_OS_WINDOWS
161/** Use a normal mutex for the loader so we remain at the same IRQL after
162 * taking it.
163 * @todo fix the mutex implementation on linux and make this the default. */
164# define SUPDRV_USE_MUTEX_FOR_LDR
165
166/** Use a normal mutex for the GIP so we remain at the same IRQL after
167 * taking it.
168 * @todo fix the mutex implementation on linux and make this the default. */
169# define SUPDRV_USE_MUTEX_FOR_GIP
170#endif
171
172
173/**
174 * OS debug print macro.
175 */
176#define OSDBGPRINT(a) SUPR0Printf a
177
178/** Debug printf macro shared with the ring-3 part. */
179#ifdef DEBUG_bird
180# define SUP_DPRINTF(a) SUPR0Printf a
181#else
182# define SUP_DPRINTF(a) do { } while (0)
183#endif
184
185
186/** @name Context values for the per-session handle tables.
187 * The context value is used to distinguish between the different kinds of
188 * handles, making the handle table API do all the work.
189 * @{ */
190/** Handle context value for single release event handles. */
191#define SUPDRV_HANDLE_CTX_EVENT ((void *)(uintptr_t)(SUPDRVOBJTYPE_SEM_EVENT))
192/** Handle context value for multiple release event handles. */
193#define SUPDRV_HANDLE_CTX_EVENT_MULTI ((void *)(uintptr_t)(SUPDRVOBJTYPE_SEM_EVENT_MULTI))
194/** @} */
195
196
197/**
198 * Validates a session pointer.
199 *
200 * @returns true/false accordingly.
201 * @param pSession The session.
202 */
203#define SUP_IS_SESSION_VALID(pSession) \
204 ( VALID_PTR(pSession) \
205 && pSession->u32Cookie == BIRD_INV)
206
207/**
208 * Validates a device extension pointer.
209 *
210 * @returns true/false accordingly.
211 * @param pDevExt The device extension.
212 */
213#define SUP_IS_DEVEXT_VALID(pDevExt) \
214 ( VALID_PTR(pDevExt)\
215 && pDevExt->u32Cookie == BIRD)
216
217
218/** @def SUPDRV_WITH_MSR_PROBER
219 * Enables the SUP_IOCTL_MSR_PROBER function.
220 * By default, only enabled in DEBUG builds as it's a sensitive feature.
221 */
222#if defined(DEBUG) && !defined(SUPDRV_WITH_MSR_PROBER) && !defined(SUPDRV_WITHOUT_MSR_PROBER)
223# define SUPDRV_WITH_MSR_PROBER
224#endif
225
226/** @def SUPDRV_WITHOUT_MSR_PROBER
227 * Executive overide for disabling the SUP_IOCTL_MSR_PROBER function.
228 */
229#ifdef SUPDRV_WITHOUT_MSR_PROBER
230# undef SUPDRV_WITH_MSR_PROBER
231#endif
232
233#if 1
234/** Use a dedicated kernel thread to service TSC-delta measurement requests.
235 * @todo Test on servers with many CPUs and sockets. */
236#define SUPDRV_USE_TSC_DELTA_THREAD
237#endif
238
239/*******************************************************************************
240* Structures and Typedefs *
241*******************************************************************************/
242/** Pointer to the device extension. */
243typedef struct SUPDRVDEVEXT *PSUPDRVDEVEXT;
244
245#ifdef SUPDRV_USE_TSC_DELTA_THREAD
246/**
247 * TSC-delta measurement thread state machine.
248 */
249typedef enum SUPDRVTSCDELTATHREADSTATE
250{
251 /** Uninitialized/invalid value. */
252 kTscDeltaThreadState_Invalid = 0,
253 /** The thread is being created.
254 * Next state: Listening, Butchered, Terminating */
255 kTscDeltaThreadState_Creating,
256 /** The thread is listening for events.
257 * Previous state: Creating, Measuring
258 * Next state: WaitAndMeasure, Butchered, Terminated */
259 kTscDeltaThreadState_Listening,
260 /** The thread is sleeping before starting a measurement.
261 * Previous state: Listening, Measuring
262 * Next state: Measuring, Butchered, Terminating
263 * @remarks The thread won't enter this state on its own, it is put into this
264 * state by the GIP timer, the CPU online callback and by the
265 * SUP_IOCTL_TSC_DELTA_MEASURE code. */
266 kTscDeltaThreadState_WaitAndMeasure,
267 /** The thread is currently servicing a measurement request.
268 * Previous state: WaitAndMeasure
269 * Next state: Listening, WaitAndMeasure, Terminate */
270 kTscDeltaThreadState_Measuring,
271 /** The thread is terminating.
272 * @remarks The thread won't enter this state on its own, is put into this state
273 * by supdrvTscDeltaTerm. */
274 kTscDeltaThreadState_Terminating,
275 /** The thread is butchered due to an unexpected error.
276 * Previous State: Creating, Listening, WaitAndMeasure */
277 kTscDeltaThreadState_Butchered,
278 /** The thread is destroyed (final).
279 * Previous state: Terminating */
280 kTscDeltaThreadState_Destroyed,
281 /** The usual 32-bit blowup hack. */
282 kTscDeltaThreadState_32BitHack = 0x7fffffff
283} SUPDRVTSCDELTATHREADSTATE;
284#endif /* SUPDRV_USE_TSC_DELTA_THREAD */
285
286/**
287 * Memory reference types.
288 */
289typedef enum
290{
291 /** Unused entry */
292 MEMREF_TYPE_UNUSED = 0,
293 /** Locked memory (r3 mapping only). */
294 MEMREF_TYPE_LOCKED,
295 /** Continuous memory block (r3 and r0 mapping). */
296 MEMREF_TYPE_CONT,
297 /** Low memory block (r3 and r0 mapping). */
298 MEMREF_TYPE_LOW,
299 /** Memory block (r3 and r0 mapping). */
300 MEMREF_TYPE_MEM,
301 /** Locked memory (r3 mapping only) allocated by the support driver. */
302 MEMREF_TYPE_PAGE,
303 /** Blow the type up to 32-bit and mark the end. */
304 MEMREF_TYPE_32BIT_HACK = 0x7fffffff
305} SUPDRVMEMREFTYPE, *PSUPDRVMEMREFTYPE;
306
307
308/**
309 * Structure used for tracking memory a session
310 * references in one way or another.
311 */
312typedef struct SUPDRVMEMREF
313{
314 /** The memory object handle. */
315 RTR0MEMOBJ MemObj;
316 /** The ring-3 mapping memory object handle. */
317 RTR0MEMOBJ MapObjR3;
318 /** Type of memory. */
319 SUPDRVMEMREFTYPE eType;
320} SUPDRVMEMREF, *PSUPDRVMEMREF;
321
322
323/**
324 * Bundle of locked memory ranges.
325 */
326typedef struct SUPDRVBUNDLE
327{
328 /** Pointer to the next bundle. */
329 struct SUPDRVBUNDLE * volatile pNext;
330 /** Referenced memory. */
331 SUPDRVMEMREF aMem[64];
332 /** Number of entries used. */
333 uint32_t volatile cUsed;
334} SUPDRVBUNDLE, *PSUPDRVBUNDLE;
335
336
337/**
338 * Loaded image.
339 */
340typedef struct SUPDRVLDRIMAGE
341{
342 /** Next in chain. */
343 struct SUPDRVLDRIMAGE * volatile pNext;
344 /** Pointer to the image. */
345 void *pvImage;
346 /** Pointer to the allocated image buffer.
347 * pvImage is 32-byte aligned or it may governed by the native loader (this
348 * member is NULL then). */
349 void *pvImageAlloc;
350 /** Size of the image including the tables. This is mainly for verification
351 * of the load request. */
352 uint32_t cbImageWithTabs;
353 /** Size of the image. */
354 uint32_t cbImageBits;
355 /** The number of entries in the symbol table. */
356 uint32_t cSymbols;
357 /** Pointer to the symbol table. */
358 PSUPLDRSYM paSymbols;
359 /** The offset of the string table. */
360 char *pachStrTab;
361 /** Size of the string table. */
362 uint32_t cbStrTab;
363 /** Pointer to the optional module initialization callback. */
364 PFNR0MODULEINIT pfnModuleInit;
365 /** Pointer to the optional module termination callback. */
366 PFNR0MODULETERM pfnModuleTerm;
367 /** Service request handler. This is NULL for non-service modules. */
368 PFNSUPR0SERVICEREQHANDLER pfnServiceReqHandler;
369 /** The ldr image state. (IOCtl code of last operation.) */
370 uint32_t uState;
371 /** Usage count. */
372 uint32_t volatile cUsage;
373 /** Pointer to the device extension. */
374 struct SUPDRVDEVEXT *pDevExt;
375#ifdef RT_OS_WINDOWS
376 /** The section object for the loaded image (fNative=true). */
377 void *pvNtSectionObj;
378 /** Lock object. */
379 RTR0MEMOBJ hMemLock;
380#endif
381#if defined(RT_OS_SOLARIS) && defined(VBOX_WITH_NATIVE_SOLARIS_LOADING)
382 /** The Solaris module ID. */
383 int idSolMod;
384 /** Pointer to the module control structure. */
385 struct modctl *pSolModCtl;
386#endif
387 /** Whether it's loaded by the native loader or not. */
388 bool fNative;
389 /** Image name. */
390 char szName[32];
391} SUPDRVLDRIMAGE, *PSUPDRVLDRIMAGE;
392
393
394/** Image usage record. */
395typedef struct SUPDRVLDRUSAGE
396{
397 /** Next in chain. */
398 struct SUPDRVLDRUSAGE * volatile pNext;
399 /** The image. */
400 PSUPDRVLDRIMAGE pImage;
401 /** Load count. */
402 uint32_t volatile cUsage;
403} SUPDRVLDRUSAGE, *PSUPDRVLDRUSAGE;
404
405
406/**
407 * Component factory registration record.
408 */
409typedef struct SUPDRVFACTORYREG
410{
411 /** Pointer to the next registration. */
412 struct SUPDRVFACTORYREG *pNext;
413 /** Pointer to the registered factory. */
414 PCSUPDRVFACTORY pFactory;
415 /** The session owning the factory.
416 * Used for deregistration and session cleanup. */
417 PSUPDRVSESSION pSession;
418 /** Length of the name. */
419 size_t cchName;
420} SUPDRVFACTORYREG;
421/** Pointer to a component factory registration record. */
422typedef SUPDRVFACTORYREG *PSUPDRVFACTORYREG;
423/** Pointer to a const component factory registration record. */
424typedef SUPDRVFACTORYREG const *PCSUPDRVFACTORYREG;
425
426
427/**
428 * Registered object.
429 * This takes care of reference counting and tracking data for access checks.
430 */
431typedef struct SUPDRVOBJ
432{
433 /** Magic value (SUPDRVOBJ_MAGIC). */
434 uint32_t u32Magic;
435 /** The object type. */
436 SUPDRVOBJTYPE enmType;
437 /** Pointer to the next in the global list. */
438 struct SUPDRVOBJ * volatile pNext;
439 /** Pointer to the object destructor.
440 * This may be set to NULL if the image containing the destructor get unloaded. */
441 PFNSUPDRVDESTRUCTOR pfnDestructor;
442 /** User argument 1. */
443 void *pvUser1;
444 /** User argument 2. */
445 void *pvUser2;
446 /** The total sum of all per-session usage. */
447 uint32_t volatile cUsage;
448 /** The creator user id. */
449 RTUID CreatorUid;
450 /** The creator group id. */
451 RTGID CreatorGid;
452 /** The creator process id. */
453 RTPROCESS CreatorProcess;
454} SUPDRVOBJ, *PSUPDRVOBJ;
455
456/** Magic number for SUPDRVOBJ::u32Magic. (Dame Agatha Mary Clarissa Christie). */
457#define SUPDRVOBJ_MAGIC UINT32_C(0x18900915)
458/** Dead number magic for SUPDRVOBJ::u32Magic. */
459#define SUPDRVOBJ_MAGIC_DEAD UINT32_C(0x19760112)
460
461/**
462 * The per-session object usage record.
463 */
464typedef struct SUPDRVUSAGE
465{
466 /** Pointer to the next in the list. */
467 struct SUPDRVUSAGE * volatile pNext;
468 /** Pointer to the object we're recording usage for. */
469 PSUPDRVOBJ pObj;
470 /** The usage count. */
471 uint32_t volatile cUsage;
472} SUPDRVUSAGE, *PSUPDRVUSAGE;
473
474
475/**
476 * Per session data.
477 * This is mainly for memory tracking.
478 */
479typedef struct SUPDRVSESSION
480{
481 /** Pointer to the device extension. */
482 PSUPDRVDEVEXT pDevExt;
483 /** Session Cookie. */
484 uint32_t u32Cookie;
485 /** Set if is an unrestricted session, clear if restricted. */
486 bool fUnrestricted;
487
488 /** Set if we're in the hash table, clear if not. Protected by the hash
489 * table spinlock. */
490 bool fInHashTable;
491 /** Reference counter. */
492 uint32_t volatile cRefs;
493 /** Pointer to the next session with the same hash (common hash table).
494 * Protected by the hash table spinlock. */
495 PSUPDRVSESSION pCommonNextHash;
496 /** Pointer to the OS specific session pointer, if available and in use.
497 * This is atomically set and cleared as the session is inserted and removed
498 * from the hash table (protected by the session hash table spinlock). */
499 PSUPDRVSESSION *ppOsSessionPtr;
500 /** The process (id) of the session. */
501 RTPROCESS Process;
502 /** Which process this session is associated with.
503 * This is NIL_RTR0PROCESS for kernel sessions and valid for user ones. */
504 RTR0PROCESS R0Process;
505
506 /** The VM associated with the session. */
507 PVM pVM;
508 /** Handle table for IPRT semaphore wrapper APIs.
509 * This takes care of its own locking in an IRQ safe manner. */
510 RTHANDLETABLE hHandleTable;
511 /** Load usage records. (protected by SUPDRVDEVEXT::mtxLdr) */
512 PSUPDRVLDRUSAGE volatile pLdrUsage;
513
514 /** Spinlock protecting the bundles, the GIP members and the
515 * fProcessCleanupDone flag. It continues to be valid until the last
516 * reference to the session is released. */
517 RTSPINLOCK Spinlock;
518 /** The ring-3 mapping of the GIP (readonly). */
519 RTR0MEMOBJ GipMapObjR3;
520 /** Set if the session is using the GIP. */
521 uint32_t fGipReferenced;
522 /** Bundle of locked memory objects. */
523 SUPDRVBUNDLE Bundle;
524 /** List of generic usage records. (protected by SUPDRVDEVEXT::SpinLock) */
525 PSUPDRVUSAGE volatile pUsage;
526
527 /** The user id of the session. (Set by the OS part.) */
528 RTUID Uid;
529 /** The group id of the session. (Set by the OS part.) */
530 RTGID Gid;
531 /** Per session tracer specfic data. */
532 uintptr_t uTracerData;
533 /** The thread currently actively talking to the tracer. (One at the time!) */
534 RTNATIVETHREAD hTracerCaller;
535 /** List of tracepoint providers associated with the session
536 * (SUPDRVTPPROVIDER). */
537 RTLISTANCHOR TpProviders;
538 /** The number of providers in TpProviders. */
539 uint32_t cTpProviders;
540 /** The number of threads active in supdrvIOCtl_TracerUmodProbeFire or
541 * SUPR0TracerUmodProbeFire. */
542 uint32_t volatile cTpProbesFiring;
543 /** User tracepoint modules (PSUPDRVTRACKERUMOD). */
544 RTLISTANCHOR TpUmods;
545 /** The user tracepoint module lookup table. */
546 struct SUPDRVTRACERUMOD *apTpLookupTable[32];
547#ifndef SUPDRV_AGNOSTIC
548# if defined(RT_OS_DARWIN)
549 /** Pointer to the associated org_virtualbox_SupDrvClient object. */
550 void *pvSupDrvClient;
551 /** Whether this session has been opened or not. */
552 bool fOpened;
553# endif
554# if defined(RT_OS_OS2)
555 /** The system file number of this session. */
556 uint16_t sfn;
557 uint16_t Alignment; /**< Alignment */
558# endif
559# if defined(RT_OS_DARWIN) || defined(RT_OS_OS2) || defined(RT_OS_SOLARIS)
560 /** Pointer to the next session with the same hash. */
561 PSUPDRVSESSION pNextHash;
562# endif
563# if defined(RT_OS_WINDOWS) && defined(VBOX_WITH_HARDENING)
564 /** Pointer to the process protection structure for this session. */
565 struct SUPDRVNTPROTECT *pNtProtect;
566# endif
567#endif /* !SUPDRV_AGNOSTIC */
568} SUPDRVSESSION;
569
570
571/**
572 * The TSC delta synchronization struct. rounded to cache line size.
573 */
574typedef union SUPTSCDELTASYNC
575{
576 /** The synchronization variable, holds values GIP_TSC_DELTA_SYNC_*. */
577 volatile uint32_t u;
578 /** Padding to cache line size. */
579 uint8_t u8Padding[64];
580} SUPTSCDELTASYNC;
581AssertCompileSize(SUPTSCDELTASYNC, 64);
582typedef SUPTSCDELTASYNC *PSUPTSCDELTASYNC;
583
584
585/**
586 * Device extension.
587 */
588typedef struct SUPDRVDEVEXT
589{
590 /** Global cookie. */
591 uint32_t u32Cookie;
592 /** The actual size of SUPDRVSESSION. (SUPDRV_AGNOSTIC) */
593 uint32_t cbSession;
594
595 /** Spinlock to serialize the initialization, usage counting and objects.
596 * This is IRQ safe because we want to be able signal semaphores from the
597 * special HM context (and later maybe interrupt handlers), so we must be able
598 * to reference and dereference handles when IRQs are disabled. */
599 RTSPINLOCK Spinlock;
600
601 /** List of registered objects. Protected by the spinlock. */
602 PSUPDRVOBJ volatile pObjs;
603 /** List of free object usage records. */
604 PSUPDRVUSAGE volatile pUsageFree;
605
606 /** Loader mutex.
607 * This protects pvVMMR0, pvVMMR0Entry, pImages and SUPDRVSESSION::pLdrUsage. */
608#ifdef SUPDRV_USE_MUTEX_FOR_LDR
609 RTSEMMUTEX mtxLdr;
610#else
611 RTSEMFASTMUTEX mtxLdr;
612#endif
613
614 /** VMM Module 'handle'.
615 * 0 if the code VMM isn't loaded and Idt are nops. */
616 void * volatile pvVMMR0;
617 /** VMMR0EntryInt() pointer. */
618 DECLR0CALLBACKMEMBER(int, pfnVMMR0EntryInt, (PVM pVM, unsigned uOperation, void *pvArg));
619 /** VMMR0EntryFast() pointer. */
620 DECLR0CALLBACKMEMBER(void, pfnVMMR0EntryFast, (PVM pVM, VMCPUID idCpu, unsigned uOperation));
621 /** VMMR0EntryEx() pointer. */
622 DECLR0CALLBACKMEMBER(int, pfnVMMR0EntryEx, (PVM pVM, VMCPUID idCpu, unsigned uOperation, PSUPVMMR0REQHDR pReq, uint64_t u64Arg, PSUPDRVSESSION pSession));
623
624 /** Linked list of loaded code. */
625 PSUPDRVLDRIMAGE volatile pLdrImages;
626 /** Set if the image loading interface got disabled after loading all needed images */
627 bool fLdrLockedDown;
628
629 /** @name These members for detecting whether an API caller is in ModuleInit.
630 * Certain APIs are only permitted from ModuleInit, like for instance tracepoint
631 * registration.
632 * @{ */
633 /** The image currently executing its ModuleInit. */
634 PSUPDRVLDRIMAGE volatile pLdrInitImage;
635 /** The thread currently executing a ModuleInit function. */
636 RTNATIVETHREAD volatile hLdrInitThread;
637 /** @} */
638
639
640 /** GIP mutex.
641 * Any changes to any of the GIP members requires ownership of this mutex,
642 * except on driver init and termination. */
643#ifdef SUPDRV_USE_MUTEX_FOR_GIP
644 RTSEMMUTEX mtxGip;
645#else
646 RTSEMFASTMUTEX mtxGip;
647#endif
648 /** GIP spinlock protecting GIP members during Mp events.
649 * This is IRQ safe since be may get MP callbacks in contexts where IRQs are
650 * disabled (on some platforms). */
651 RTSPINLOCK hGipSpinlock;
652 /** Pointer to the Global Info Page (GIP). */
653 PSUPGLOBALINFOPAGE pGip;
654 /** The physical address of the GIP. */
655 RTHCPHYS HCPhysGip;
656 /** Number of processes using the GIP.
657 * (The updates are suspend while cGipUsers is 0.)*/
658 uint32_t volatile cGipUsers;
659 /** The ring-0 memory object handle for the GIP page. */
660 RTR0MEMOBJ GipMemObj;
661 /** The GIP timer handle. */
662 PRTTIMER pGipTimer;
663 /** If non-zero we've successfully called RTTimerRequestSystemGranularity(). */
664 uint32_t u32SystemTimerGranularityGrant;
665 /** The CPU id of the GIP master.
666 * This CPU is responsible for the updating the common GIP data and it is
667 * the one used to calculate TSC deltas relative to.
668 * (The initial master will have a 0 zero value, but it it goes offline the
669 * new master may have a non-zero value.) */
670 RTCPUID volatile idGipMaster;
671
672 /** Component factory mutex.
673 * This protects pComponentFactoryHead and component factory querying. */
674 RTSEMFASTMUTEX mtxComponentFactory;
675 /** The head of the list of registered component factories. */
676 PSUPDRVFACTORYREG pComponentFactoryHead;
677
678 /** Lock protecting The tracer members. */
679 RTSEMFASTMUTEX mtxTracer;
680 /** List of tracer providers (SUPDRVTPPROVIDER). */
681 RTLISTANCHOR TracerProviderList;
682 /** List of zombie tracer providers (SUPDRVTPPROVIDER). */
683 RTLISTANCHOR TracerProviderZombieList;
684 /** Pointer to the tracer registration record. */
685 PCSUPDRVTRACERREG pTracerOps;
686 /** The ring-0 session of a native tracer provider. */
687 PSUPDRVSESSION pTracerSession;
688 /** The image containing the tracer. */
689 PSUPDRVLDRIMAGE pTracerImage;
690 /** The tracer helpers. */
691 SUPDRVTRACERHLP TracerHlp;
692 /** The number of session having opened the tracer currently. */
693 uint32_t cTracerOpens;
694 /** The number of threads currently calling into the tracer. */
695 uint32_t volatile cTracerCallers;
696 /** Set if the tracer is being unloaded. */
697 bool fTracerUnloading;
698 /** Hash table for user tracer modules (SUPDRVVTGCOPY). */
699 RTLISTANCHOR aTrackerUmodHash[128];
700
701 /** @name Session Handle Table.
702 * @{ */
703 /** Spinlock protecting apSessionHashTab, cSessions,
704 * SUPDRVSESSION::ppOsSessionPtr, SUPDRVSESSION::pCommonNextHash, and possibly
705 * others depending on the OS. */
706 RTSPINLOCK hSessionHashTabSpinlock;
707 /** Session hash table hash table. The size of this table must make sense in
708 * comparison to GVMM_MAX_HANDLES. */
709 PSUPDRVSESSION apSessionHashTab[HC_ARCH_BITS == 64 ? 8191 : 127];
710 /** The number of open sessions. */
711 int32_t cSessions;
712 /** @} */
713
714 /** @name TSC-delta measurement.
715 * @{ */
716 /** TSC reading during start of TSC frequency refinement phase. */
717 uint64_t u64TscAnchor;
718 /** Timestamp (in nanosec) during start of TSC frequency refinement phase. */
719 uint64_t u64NanoTSAnchor;
720 /** Pointer to the timer used to refine the TSC frequency. */
721 PRTTIMER pTscRefineTimer;
722 /** Pointer to the TSC delta sync. struct. */
723 void *pvTscDeltaSync;
724 /** The TSC delta measurement initiator Cpu Id. */
725 RTCPUID volatile idTscDeltaInitiator;
726 /** Number of online/offline events, incremented each time a CPU goes online
727 * or offline. */
728 uint32_t volatile cMpOnOffEvents;
729 /** Aligned pointer to the TSC delta sync. struct. */
730 PSUPTSCDELTASYNC pTscDeltaSync;
731 /** The set of CPUs we need to take measurements for. */
732 RTCPUSET TscDeltaCpuSet;
733 /** The set of CPUs we have completed taken measurements for. */
734 RTCPUSET TscDeltaObtainedCpuSet;
735 /** @} */
736
737#ifdef SUPDRV_USE_TSC_DELTA_THREAD
738 /** @name TSC-delta measurement thread.
739 * @{ */
740 /** Spinlock protecting enmTscDeltaThreadState. */
741 RTSPINLOCK hTscDeltaSpinlock;
742 /** TSC-delta measurement thread. */
743 RTTHREAD hTscDeltaThread;
744 /** The event signalled during state changes to the TSC-delta thread. */
745 RTSEMEVENT hTscDeltaEvent;
746 /** The state of the TSC-delta measurement thread. */
747 SUPDRVTSCDELTATHREADSTATE enmTscDeltaThreadState;
748 /** Thread timeout time before rechecking state in ms. */
749 RTMSINTERVAL cMsTscDeltaTimeout;
750 /** Whether the TSC-delta measurement was successful. */
751 int32_t volatile rcTscDelta;
752 /** @} */
753#endif
754
755 /*
756 * Note! The non-agnostic bits must be at the very end of the structure!
757 */
758#ifndef SUPDRV_AGNOSTIC
759# ifdef RT_OS_WINDOWS
760 /** Callback object returned by ExCreateCallback. */
761 PCALLBACK_OBJECT pObjPowerCallback;
762 /** Callback handle returned by ExRegisterCallback. */
763 PVOID hPowerCallback;
764# endif
765#endif
766} SUPDRVDEVEXT;
767
768/** Calculates the index into g_apSessionHashTab.*/
769#define SUPDRV_SESSION_HASH(a_pid) ( (a_pid) % RT_ELEMENTS(((SUPDRVDEVEXT *)NULL)->apSessionHashTab) )
770
771
772RT_C_DECLS_BEGIN
773
774/*******************************************************************************
775* OS Specific Functions *
776*******************************************************************************/
777/**
778 * Called to clean up the session structure before it's freed.
779 *
780 * @param pDevExt The device globals.
781 * @param pSession The session that's being cleaned up.
782 */
783void VBOXCALL supdrvOSCleanupSession(PSUPDRVDEVEXT pDevExt, PSUPDRVSESSION pSession);
784
785/**
786 * Called to let the OS specfic code perform additional insertion work while
787 * still under the protection of the hash table spinlock.
788 *
789 * @param pDevExt The device globals.
790 * @param pSession The session that was inserted.
791 * @param pvUser User context specified to the insert call.
792 */
793void VBOXCALL supdrvOSSessionHashTabInserted(PSUPDRVDEVEXT pDevExt, PSUPDRVSESSION pSession, void *pvUser);
794
795/**
796 * Called to let the OS specfic code perform additional removal work while still
797 * under the protection of the hash table spinlock.
798 *
799 * @param pDevExt The device globals.
800 * @param pSession The session that was removed.
801 * @param pvUser User context specified to the remove call.
802 */
803void VBOXCALL supdrvOSSessionHashTabRemoved(PSUPDRVDEVEXT pDevExt, PSUPDRVSESSION pSession, void *pvUser);
804
805void VBOXCALL supdrvOSObjInitCreator(PSUPDRVOBJ pObj, PSUPDRVSESSION pSession);
806bool VBOXCALL supdrvOSObjCanAccess(PSUPDRVOBJ pObj, PSUPDRVSESSION pSession, const char *pszObjName, int *prc);
807bool VBOXCALL supdrvOSGetForcedAsyncTscMode(PSUPDRVDEVEXT pDevExt);
808bool VBOXCALL supdrvOSAreTscDeltasInSync(void);
809int VBOXCALL supdrvOSEnableVTx(bool fEnabled);
810bool VBOXCALL supdrvOSSuspendVTxOnCpu(void);
811void VBOXCALL supdrvOSResumeVTxOnCpu(bool fSuspended);
812
813/**
814 * Try open the image using the native loader.
815 *
816 * @returns IPRT status code.
817 * @retval VERR_NOT_SUPPORTED if native loading isn't supported.
818 *
819 * @param pDevExt The device globals.
820 * @param pImage The image handle. pvImage should be set on
821 * success, pvImageAlloc can also be set if
822 * appropriate.
823 * @param pszFilename The file name - UTF-8, may containing UNIX
824 * slashes on non-UNIX systems.
825 */
826int VBOXCALL supdrvOSLdrOpen(PSUPDRVDEVEXT pDevExt, PSUPDRVLDRIMAGE pImage, const char *pszFilename);
827
828/**
829 * Notification call indicating that a image is being opened for the first time.
830 *
831 * Can be used to log the load address of the image.
832 *
833 * @param pDevExt The device globals.
834 * @param pImage The image handle.
835 */
836void VBOXCALL supdrvOSLdrNotifyOpened(PSUPDRVDEVEXT pDevExt, PSUPDRVLDRIMAGE pImage);
837
838/**
839 * Validates an entry point address.
840 *
841 * Called before supdrvOSLdrLoad.
842 *
843 * @returns IPRT status code.
844 * @param pDevExt The device globals.
845 * @param pImage The image data (still in the open state).
846 * @param pv The address within the image.
847 * @param pbImageBits The image bits as loaded by ring-3.
848 */
849int VBOXCALL supdrvOSLdrValidatePointer(PSUPDRVDEVEXT pDevExt, PSUPDRVLDRIMAGE pImage,
850 void *pv, const uint8_t *pbImageBits);
851
852/**
853 * Load the image.
854 *
855 * @returns IPRT status code.
856 * @param pDevExt The device globals.
857 * @param pImage The image data (up to date). Adjust entrypoints
858 * and exports if necessary.
859 * @param pbImageBits The image bits as loaded by ring-3.
860 * @param pReq Pointer to the request packet so that the VMMR0
861 * entry points can be adjusted.
862 */
863int VBOXCALL supdrvOSLdrLoad(PSUPDRVDEVEXT pDevExt, PSUPDRVLDRIMAGE pImage, const uint8_t *pbImageBits, PSUPLDRLOAD pReq);
864
865
866/**
867 * Unload the image.
868 *
869 * @param pDevExt The device globals.
870 * @param pImage The image data (mostly still valid).
871 */
872void VBOXCALL supdrvOSLdrUnload(PSUPDRVDEVEXT pDevExt, PSUPDRVLDRIMAGE pImage);
873
874
875#ifdef SUPDRV_WITH_MSR_PROBER
876
877/**
878 * Tries to read an MSR.
879 *
880 * @returns One of the listed VBox status codes.
881 * @retval VINF_SUCCESS if read successfully, value in *puValue.
882 * @retval VERR_ACCESS_DENIED if we couldn't read it (GP).
883 * @retval VERR_NOT_SUPPORTED if not supported.
884 *
885 * @param uMsr The MSR to read from.
886 * @param idCpu The CPU to read the MSR on. NIL_RTCPUID
887 * indicates any suitable CPU.
888 * @param puValue Where to return the value.
889 */
890int VBOXCALL supdrvOSMsrProberRead(uint32_t uMsr, RTCPUID idCpu, uint64_t *puValue);
891
892/**
893 * Tries to write an MSR.
894 *
895 * @returns One of the listed VBox status codes.
896 * @retval VINF_SUCCESS if written successfully.
897 * @retval VERR_ACCESS_DENIED if we couldn't write the value to it (GP).
898 * @retval VERR_NOT_SUPPORTED if not supported.
899 *
900 * @param uMsr The MSR to write to.
901 * @param idCpu The CPU to write the MSR on. NIL_RTCPUID
902 * indicates any suitable CPU.
903 * @param uValue The value to write.
904 */
905int VBOXCALL supdrvOSMsrProberWrite(uint32_t uMsr, RTCPUID idCpu, uint64_t uValue);
906
907/**
908 * Tries to modify an MSR value.
909 *
910 * @returns One of the listed VBox status codes.
911 * @retval VINF_SUCCESS if succeeded.
912 * @retval VERR_NOT_SUPPORTED if not supported.
913 *
914 * @param idCpu The CPU to modify the MSR on. NIL_RTCPUID
915 * indicates any suitable CPU.
916 * @param pReq The request packet with input arguments and
917 * where to store the results.
918 */
919int VBOXCALL supdrvOSMsrProberModify(RTCPUID idCpu, PSUPMSRPROBER pReq);
920
921#endif /* SUPDRV_WITH_MSR_PROBER */
922
923#if defined(RT_OS_DARWIN)
924int VBOXCALL supdrvDarwinResumeSuspendedKbds(void);
925#endif
926
927/*******************************************************************************
928* Shared Functions *
929*******************************************************************************/
930/* SUPDrv.c */
931int VBOXCALL supdrvIOCtl(uintptr_t uIOCtl, PSUPDRVDEVEXT pDevExt, PSUPDRVSESSION pSession, PSUPREQHDR pReqHdr, size_t cbReq);
932int VBOXCALL supdrvIOCtlFast(uintptr_t uIOCtl, VMCPUID idCpu, PSUPDRVDEVEXT pDevExt, PSUPDRVSESSION pSession);
933int VBOXCALL supdrvIDC(uintptr_t uIOCtl, PSUPDRVDEVEXT pDevExt, PSUPDRVSESSION pSession, PSUPDRVIDCREQHDR pReqHdr);
934int VBOXCALL supdrvInitDevExt(PSUPDRVDEVEXT pDevExt, size_t cbSession);
935void VBOXCALL supdrvDeleteDevExt(PSUPDRVDEVEXT pDevExt);
936int VBOXCALL supdrvCreateSession(PSUPDRVDEVEXT pDevExt, bool fUser, bool fUnrestricted, PSUPDRVSESSION *ppSession);
937int VBOXCALL supdrvSessionHashTabInsert(PSUPDRVDEVEXT pDevExt, PSUPDRVSESSION pSession, PSUPDRVSESSION *ppOsSessionPtr, void *pvUser);
938int VBOXCALL supdrvSessionHashTabRemove(PSUPDRVDEVEXT pDevExt, PSUPDRVSESSION pSession, void *pvUser);
939PSUPDRVSESSION VBOXCALL supdrvSessionHashTabLookup(PSUPDRVDEVEXT pDevExt, RTPROCESS Process, RTR0PROCESS R0Process,
940 PSUPDRVSESSION *ppOsSessionPtr);
941uint32_t VBOXCALL supdrvSessionRetain(PSUPDRVSESSION pSession);
942uint32_t VBOXCALL supdrvSessionRelease(PSUPDRVSESSION pSession);
943
944int VBOXCALL supdrvTracerInit(PSUPDRVDEVEXT pDevExt);
945void VBOXCALL supdrvTracerTerm(PSUPDRVDEVEXT pDevExt);
946void VBOXCALL supdrvTracerModuleUnloading(PSUPDRVDEVEXT pDevExt, PSUPDRVLDRIMAGE pImage);
947void VBOXCALL supdrvTracerCleanupSession(PSUPDRVDEVEXT pDevExt, PSUPDRVSESSION pSession);
948int VBOXCALL supdrvIOCtl_TracerUmodRegister(PSUPDRVDEVEXT pDevExt, PSUPDRVSESSION pSession,
949 RTR3PTR R3PtrVtgHdr, RTUINTPTR uVtgHdrAddr,
950 RTR3PTR R3PtrStrTab, uint32_t cbStrTab,
951 const char *pszModName, uint32_t fFlags);
952int VBOXCALL supdrvIOCtl_TracerUmodDeregister(PSUPDRVDEVEXT pDevExt, PSUPDRVSESSION pSession, RTR3PTR R3PtrVtgHdr);
953void VBOXCALL supdrvIOCtl_TracerUmodProbeFire(PSUPDRVDEVEXT pDevExt, PSUPDRVSESSION pSession, PSUPDRVTRACERUSRCTX pCtx);
954int VBOXCALL supdrvIOCtl_TracerOpen(PSUPDRVDEVEXT pDevExt, PSUPDRVSESSION pSession, uint32_t uCookie, uintptr_t uArg);
955int VBOXCALL supdrvIOCtl_TracerClose(PSUPDRVDEVEXT pDevExt, PSUPDRVSESSION pSession);
956int VBOXCALL supdrvIOCtl_TracerIOCtl(PSUPDRVDEVEXT pDevExt, PSUPDRVSESSION pSession, uintptr_t uCmd, uintptr_t uArg, int32_t *piRetVal);
957extern PFNRT g_pfnSupdrvProbeFireKernel;
958DECLASM(void) supdrvTracerProbeFireStub(void);
959
960#ifdef VBOX_WITH_NATIVE_DTRACE
961const SUPDRVTRACERREG * VBOXCALL supdrvDTraceInit(void);
962#endif
963
964RT_C_DECLS_END
965
966#endif
967
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