Changeset 41117 in vbox for trunk/include/VBox
- Timestamp:
- May 2, 2012 2:22:29 PM (13 years ago)
- svn:sync-xref-src-repo-rev:
- 77725
- Location:
- trunk/include/VBox
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/VBox/VBoxTpG.h
r40986 r41117 34 34 RT_C_DECLS_BEGIN 35 35 36 /** 37 * 32-bit probe location. 38 */ 39 typedef struct VTGPROBELOC32 40 { 41 uint32_t uLine : 31; 42 uint32_t fEnabled : 1; 43 uint32_t idProbe; 44 uint32_t pszFunction; 45 uint32_t pbProbe; 46 } VTGPROBELOC32; 47 AssertCompileSize(VTGPROBELOC32, 16); 48 /** Pointer to a 32-bit probe location. */ 49 typedef VTGPROBELOC32 *PVTGPROBELOC32; 50 /** Pointer to a const 32-bit probe location. */ 51 typedef VTGPROBELOC32 const *PCVTGPROBELOC32; 52 53 /** 54 * 64-bit probe location. 55 */ 56 typedef struct VTGPROBELOC64 57 { 58 uint32_t uLine : 31; 59 uint32_t fEnabled : 1; 60 uint32_t idProbe; 61 uint64_t pszFunction; 62 uint64_t pbProbe; 63 uint64_t uAlignment; 64 } VTGPROBELOC64; 65 AssertCompileSize(VTGPROBELOC64, 32); 66 /** Pointer to a 64-bit probe location. */ 67 typedef VTGPROBELOC64 *PVTGPROBELOC64; 68 /** Pointer to a const 64-bit probe location. */ 69 typedef VTGPROBELOC64 const *PCVTGPROBELOC64; 70 36 71 37 72 /** … … 52 87 /** Pointer to a probe location. */ 53 88 typedef VTGPROBELOC *PVTGPROBELOC; 89 /** Pointer to a const probe location. */ 90 typedef VTGPROBELOC const *PCVTGPROBELOC; 54 91 55 92 /** @def VTG_OBJ_SECT … … 154 191 /** Pointer to an argument descriptor. */ 155 192 typedef VTGDESCARG *PVTGDESCARG; 193 /** Pointer to a const argument descriptor. */ 194 typedef VTGDESCARG const *PCVTGDESCARG; 156 195 157 196 … … 168 207 /** Pointer to a VTG argument list descriptor. */ 169 208 typedef VTGDESCARGLIST *PVTGDESCARGLIST; 209 /** Pointer to a const VTG argument list descriptor. */ 210 typedef VTGDESCARGLIST const *PCVTGDESCARGLIST; 170 211 171 212 … … 181 222 /** The distance from this structure to the VTG object header. */ 182 223 int32_t offObjHdr; 183 uint32_t u32User;184 uint32_t u32User2;185 224 } VTGDESCPROBE; 186 AssertCompileSize(VTGDESCPROBE, 24);225 AssertCompileSize(VTGDESCPROBE, 16); 187 226 /** Pointer to a VTG probe descriptor. */ 188 227 typedef VTGDESCPROBE *PVTGDESCPROBE; 228 /** Pointer to a const VTG probe descriptor. */ 229 typedef VTGDESCPROBE const *PCVTGDESCPROBE; 189 230 190 231 … … 253 294 /** Pointer to a VTG provider descriptor. */ 254 295 typedef VTGDESCPROVIDER *PVTGDESCPROVIDER; 296 /** Pointer to a const VTG provider descriptor. */ 297 typedef VTGDESCPROVIDER const *PCVTGDESCPROVIDER; 255 298 256 299 … … 260 303 typedef struct VTGOBJHDR 261 304 { 305 /** Magic value (VTGOBJHDR_MAGIC). */ 262 306 char szMagic[24]; 307 /** The bitness of the structures. 308 * This only affects the probe location pointers and structures. */ 263 309 uint32_t cBits; 264 uint32_t u32Reserved0; 265 PVTGDESCPROVIDER paProviders; 266 uintptr_t cbProviders; 267 PVTGDESCPROBE paProbes; 268 uintptr_t cbProbes; 269 bool *pafProbeEnabled; 270 uintptr_t cbProbeEnabled; 271 char *pachStrTab; 272 uintptr_t cbStrTab; 273 PVTGDESCARGLIST paArgLists; 274 uintptr_t cbArgLists; 275 PVTGPROBELOC paProbLocs; 276 PVTGPROBELOC paProbLocsEnd; 277 uintptr_t auReserved1[4]; 310 /** The size of the VTG object. This excludes the probe locations. */ 311 uint32_t cbObj; 312 313 /** @name Area Descriptors 314 * @remarks The offsets are relative to the header. The members are 315 * ordered by ascending offset (maybe with the exception of the 316 * probe locations). No overlaps, though there might be zero 317 * filled gaps between them due to alignment. 318 * @{ */ 319 /* 32: */ 320 /** Offset of the string table (char) relative to this header. */ 321 uint32_t offStrTab; 322 /** The size of the string table, in bytes. */ 323 uint32_t cbStrTab; 324 /** Offset of the argument lists (VTGDESCARGLIST - variable size) relative 325 * to this header. */ 326 uint32_t offArgLists; 327 /** The size of the argument lists, in bytes. */ 328 uint32_t cbArgLists; 329 /* 48: */ 330 /** Offset of the probe array (VTGDESCPROBE) relative to this header. */ 331 uint32_t offProbes; 332 /** The size of the probe array, in bytes. */ 333 uint32_t cbProbes; 334 /** Offset of the provider array (VTGDESCPROVIDER) relative to this 335 * header. */ 336 uint32_t offProviders; 337 /** The size of the provider array, in bytes. */ 338 uint32_t cbProviders; 339 /* 64: */ 340 /** Offset of the probe-enabled array (uint32_t) relative to this 341 * header. */ 342 uint32_t offProbeEnabled; 343 /** The size of the probe-enabled array, in bytes. */ 344 uint32_t cbProbeEnabled; 345 /** Offset of the probe location array (VTGPROBELOC) relative to this 346 * header. 347 * @remarks This is filled in by the first VTG user using uProbeLocs. */ 348 int32_t offProbeLocs; 349 /** The size of the probe location array, in bytes. 350 * @remarks This is filled in by the first VTG user using uProbeLocs. */ 351 uint32_t cbProbeLocs; 352 /** @} */ 353 /* 80: */ 354 /** 355 * The probe location array is generated by C code and lives in a 356 * different section/subsection/segment than the rest of the data. 357 * 358 * The assembler cannot generate offsets across sections for most (if not 359 * all) object formats, so we have to store pointers here. The first user 360 * of the data will convert these two members into offset and size and fill 361 * in the offProbeLocs and cbProbeLocs members above. 362 * 363 * @remarks Converting these members to offset+size and reusing the members 364 * to store the converted values isn't possible because of 365 * raw-mode context modules having relocations associated with the 366 * fields. 367 */ 368 union 369 { 370 PVTGPROBELOC p; 371 uintptr_t uPtr; 372 uint32_t u32; 373 uint64_t u64; 374 } 375 /** Pointer to the probe location array. */ 376 uProbeLocs, 377 /** Pointer to the end of the probe location array. */ 378 uProbeLocsEnd; 379 /** UUID for making sharing ring-0 structures for the same ring-3 380 * modules easier. */ 381 RTUUID Uuid; 382 /** Reserved / alignment. */ 383 uint32_t au32Reserved1[4]; 278 384 } VTGOBJHDR; 385 AssertCompileSize(VTGOBJHDR, 128); 386 AssertCompileMemberAlignment(VTGOBJHDR, uProbeLocs, 8); 387 AssertCompileMemberAlignment(VTGOBJHDR, uProbeLocsEnd, 8); 279 388 /** Pointer to a VTG data object header. */ 280 389 typedef VTGOBJHDR *PVTGOBJHDR; 390 /** Pointer to a const VTG data object header. */ 391 typedef VTGOBJHDR const *PCVTGOBJHDR; 281 392 282 393 /** The current VTGOBJHDR::szMagic value. */ 283 #define VTGOBJHDR_MAGIC "VTG Object Header v1. 4\0"394 #define VTGOBJHDR_MAGIC "VTG Object Header v1.5\0" 284 395 285 396 /** The name of the VTG data object header symbol in the object file. */ -
trunk/include/VBox/err.h
r40878 r41117 1623 1623 /** Bad VTG bit count value. */ 1624 1624 #define VERR_SUPDRV_VTG_BITS (-3705) 1625 /** Bad VTG header. */ 1626 #define VERR_SUPDRV_VTG_BAD_HDR (-3706) 1627 /** Bad VTG header - pointer. */ 1628 #define VERR_SUPDRV_VTG_BAD_HDR_PTR (-3707) 1625 /** Bad VTG header - misc. */ 1626 #define VERR_SUPDRV_VTG_BAD_HDR_MISC (-3706) 1627 /** Bad VTG header - offset. */ 1628 #define VERR_SUPDRV_VTG_BAD_HDR_OFF (-3707) 1629 /** Bad VTG header - offset. */ 1630 #define VERR_SUPDRV_VTG_BAD_HDR_PTR (-3708) 1629 1631 /** Bad VTG header - to low value. */ 1630 #define VERR_SUPDRV_VTG_BAD_HDR_TOO_FEW (-370 8)1632 #define VERR_SUPDRV_VTG_BAD_HDR_TOO_FEW (-3709) 1631 1633 /** Bad VTG header - to high value. */ 1632 #define VERR_SUPDRV_VTG_BAD_HDR_TOO_MUCH (-37 09)1634 #define VERR_SUPDRV_VTG_BAD_HDR_TOO_MUCH (-3710) 1633 1635 /** Bad VTG header - size value is not a multiple of the structure size. */ 1634 #define VERR_SUPDRV_VTG_BAD_HDR_NOT_MULTIPLE (-371 0)1636 #define VERR_SUPDRV_VTG_BAD_HDR_NOT_MULTIPLE (-3711) 1635 1637 /** Bad VTG string table offset. */ 1636 #define VERR_SUPDRV_VTG_STRTAB_OFF (-371 1)1638 #define VERR_SUPDRV_VTG_STRTAB_OFF (-3712) 1637 1639 /** Bad VTG string. */ 1638 #define VERR_SUPDRV_VTG_BAD_STRING (-371 2)1640 #define VERR_SUPDRV_VTG_BAD_STRING (-3713) 1639 1641 /** VTG string is too long. */ 1640 #define VERR_SUPDRV_VTG_STRING_TOO_LONG (-371 3)1642 #define VERR_SUPDRV_VTG_STRING_TOO_LONG (-3714) 1641 1643 /** Bad VTG attribute value. */ 1642 #define VERR_SUPDRV_VTG_BAD_ATTR (-371 4)1644 #define VERR_SUPDRV_VTG_BAD_ATTR (-3715) 1643 1645 /** Bad VTG provider descriptor. */ 1644 #define VERR_SUPDRV_VTG_BAD_PROVIDER (-371 5)1646 #define VERR_SUPDRV_VTG_BAD_PROVIDER (-3716) 1645 1647 /** Bad VTG probe descriptor. */ 1646 #define VERR_SUPDRV_VTG_BAD_PROBE (-371 6)1648 #define VERR_SUPDRV_VTG_BAD_PROBE (-3717) 1647 1649 /** Bad VTG argument list descriptor. */ 1648 #define VERR_SUPDRV_VTG_BAD_ARGLIST (-371 7)1650 #define VERR_SUPDRV_VTG_BAD_ARGLIST (-3718) 1649 1651 /** Bad VTG probe enabled data. */ 1650 #define VERR_SUPDRV_VTG_BAD_PROBE_ENABLED (-371 8)1652 #define VERR_SUPDRV_VTG_BAD_PROBE_ENABLED (-3719) 1651 1653 /** Bad VTG probe location record. */ 1652 #define VERR_SUPDRV_VTG_BAD_PROBE_LOC (-37 19)1654 #define VERR_SUPDRV_VTG_BAD_PROBE_LOC (-3720) 1653 1655 /** The VTG object for the session or image has already been registered. */ 1654 #define VERR_SUPDRV_VTG_ALREADY_REGISTERED (-372 0)1656 #define VERR_SUPDRV_VTG_ALREADY_REGISTERED (-3721) 1655 1657 /** A driver may only register one VTG object per session. */ 1656 #define VERR_SUPDRV_VTG_ONLY_ONCE_PER_SESSION (-372 1)1658 #define VERR_SUPDRV_VTG_ONLY_ONCE_PER_SESSION (-3722) 1657 1659 /** A tracer has already been registered. */ 1658 #define VERR_SUPDRV_TRACER_ALREADY_REGISTERED (-372 2)1660 #define VERR_SUPDRV_TRACER_ALREADY_REGISTERED (-3723) 1659 1661 /** The session has no tracer associated with it. */ 1660 #define VERR_SUPDRV_TRACER_NOT_REGISTERED (-372 3)1662 #define VERR_SUPDRV_TRACER_NOT_REGISTERED (-3724) 1661 1663 /** The tracer has already been opened in this sesssion. */ 1662 #define VERR_SUPDRV_TRACER_ALREADY_OPENED (-372 4)1664 #define VERR_SUPDRV_TRACER_ALREADY_OPENED (-3725) 1663 1665 /** The tracer has not been opened. */ 1664 #define VERR_SUPDRV_TRACER_NOT_OPENED (-372 5)1666 #define VERR_SUPDRV_TRACER_NOT_OPENED (-3726) 1665 1667 /** There is no tracer present. */ 1666 #define VERR_SUPDRV_TRACER_NOT_PRESENT (-372 6)1668 #define VERR_SUPDRV_TRACER_NOT_PRESENT (-3727) 1667 1669 /** The tracer is unloading. */ 1668 #define VERR_SUPDRV_TRACER_UNLOADING (-372 7)1670 #define VERR_SUPDRV_TRACER_UNLOADING (-3728) 1669 1671 /** Another thread in the session is talking to the tracer. */ 1670 #define VERR_SUPDRV_TRACER_SESSION_BUSY (-372 8)1672 #define VERR_SUPDRV_TRACER_SESSION_BUSY (-3729) 1671 1673 /** The tracer cannot open it self in the same session. */ 1672 #define VERR_SUPDRV_TRACER_CANNOT_OPEN_SELF (-37 29)1674 #define VERR_SUPDRV_TRACER_CANNOT_OPEN_SELF (-3730) 1673 1675 /** Bad argument flags. */ 1674 #define VERR_SUPDRV_TRACER_BAD_ARG_FLAGS (-3730) 1676 #define VERR_SUPDRV_TRACER_BAD_ARG_FLAGS (-3731) 1677 /** The session has reached the max number of (user mode) providers. */ 1678 #define VERR_SUPDRV_TRACER_TOO_MANY_PROVIDERS (-3732) 1679 /** The tracepoint provider object is too large. */ 1680 #define VERR_SUPDRV_TRACER_TOO_LARGE (-3733) 1681 /** The probe location array isn't adjacent to the probe enable array. */ 1682 #define VERR_SUPDRV_TRACER_UMOD_NOT_ADJACENT (-3734) 1683 /** The user mode tracepoint provider has too many probe locations and 1684 * probes. */ 1685 #define VERR_SUPDRV_TRACER_UMOD_TOO_MANY_PROBES (-3735) 1686 /** The user mode tracepoint provider string table is too large. */ 1687 #define VERR_SUPDRV_TRACER_UMOD_STRTAB_TOO_BIG (-3736) 1688 /** The user mode tracepoint provider string table offset is bad. */ 1689 #define VERR_SUPDRV_TRACER_UMOD_STRTAB_OFF_BAD (-3737) 1675 1690 /** @} */ 1676 1691 -
trunk/include/VBox/sup.h
r40983 r41117 91 91 SUPPAGINGMODE_AMD64_GLOBAL_NX 92 92 } SUPPAGINGMODE; 93 94 95 /**96 * The CPU state.97 */98 typedef enum SUPGIPCPUSTATE99 {100 /** Invalid CPU state / unused CPU entry. */101 SUPGIPCPUSTATE_INVALID = 0,102 /** The CPU is not present. */103 SUPGIPCPUSTATE_ABSENT,104 /** The CPU is offline. */105 SUPGIPCPUSTATE_OFFLINE,106 /** The CPU is online. */107 SUPGIPCPUSTATE_ONLINE,108 /** Force 32-bit enum type. */109 SUPGIPCPUSTATE_32_BIT_HACK = 0x7fffffff110 } SUPGIPCPUSTATE;111 112 /**113 * Per CPU data.114 */115 typedef struct SUPGIPCPU116 {117 /** Update transaction number.118 * This number is incremented at the start and end of each update. It follows119 * thusly that odd numbers indicates update in progress, while even numbers120 * indicate stable data. Use this to make sure that the data items you fetch121 * are consistent. */122 volatile uint32_t u32TransactionId;123 /** The interval in TSC ticks between two NanoTS updates.124 * This is the average interval over the last 2, 4 or 8 updates + a little slack.125 * The slack makes the time go a tiny tiny bit slower and extends the interval enough126 * to avoid ending up with too many 1ns increments. */127 volatile uint32_t u32UpdateIntervalTSC;128 /** Current nanosecond timestamp. */129 volatile uint64_t u64NanoTS;130 /** The TSC at the time of u64NanoTS. */131 volatile uint64_t u64TSC;132 /** Current CPU Frequency. */133 volatile uint64_t u64CpuHz;134 /** Number of errors during updating.135 * Typical errors are under/overflows. */136 volatile uint32_t cErrors;137 /** Index of the head item in au32TSCHistory. */138 volatile uint32_t iTSCHistoryHead;139 /** Array of recent TSC interval deltas.140 * The most recent item is at index iTSCHistoryHead.141 * This history is used to calculate u32UpdateIntervalTSC.142 */143 volatile uint32_t au32TSCHistory[8];144 /** The interval between the last two NanoTS updates. (experiment for now) */145 volatile uint32_t u32PrevUpdateIntervalNS;146 147 /** Reserved for future per processor data. */148 volatile uint32_t au32Reserved[5+5];149 150 /** @todo Add topology/NUMA info. */151 /** The CPU state. */152 SUPGIPCPUSTATE volatile enmState;153 /** The host CPU ID of this CPU (the SUPGIPCPU is indexed by APIC ID). */154 RTCPUID idCpu;155 /** The CPU set index of this CPU. */156 int16_t iCpuSet;157 /** The APIC ID of this CPU. */158 uint16_t idApic;159 } SUPGIPCPU;160 AssertCompileSize(RTCPUID, 4);161 AssertCompileSize(SUPGIPCPU, 128);162 AssertCompileMemberAlignment(SUPGIPCPU, u64NanoTS, 8);163 AssertCompileMemberAlignment(SUPGIPCPU, u64TSC, 8);164 165 /** Pointer to per cpu data.166 * @remark there is no const version of this typedef, see g_pSUPGlobalInfoPage for details. */167 typedef SUPGIPCPU *PSUPGIPCPU;168 169 170 171 /**172 * Global Information Page.173 *174 * This page contains useful information and can be mapped into any175 * process or VM. It can be accessed thru the g_pSUPGlobalInfoPage176 * pointer when a session is open.177 */178 typedef struct SUPGLOBALINFOPAGE179 {180 /** Magic (SUPGLOBALINFOPAGE_MAGIC). */181 uint32_t u32Magic;182 /** The GIP version. */183 uint32_t u32Version;184 185 /** The GIP update mode, see SUPGIPMODE. */186 uint32_t u32Mode;187 /** The number of entries in the CPU table.188 * (This can work as RTMpGetArraySize().) */189 uint16_t cCpus;190 /** The size of the GIP in pages. */191 uint16_t cPages;192 /** The update frequency of the of the NanoTS. */193 volatile uint32_t u32UpdateHz;194 /** The update interval in nanoseconds. (10^9 / u32UpdateHz) */195 volatile uint32_t u32UpdateIntervalNS;196 /** The timestamp of the last time we update the update frequency. */197 volatile uint64_t u64NanoTSLastUpdateHz;198 /** The set of online CPUs. */199 RTCPUSET OnlineCpuSet;200 /** The set of present CPUs. */201 RTCPUSET PresentCpuSet;202 /** The set of possible CPUs. */203 RTCPUSET PossibleCpuSet;204 /** The number of CPUs that are online. */205 volatile uint16_t cOnlineCpus;206 /** The number of CPUs present in the system. */207 volatile uint16_t cPresentCpus;208 /** The highest number of CPUs possible. */209 uint16_t cPossibleCpus;210 /** The highest number of CPUs possible. */211 uint16_t u16Padding0;212 /** The max CPU ID (RTMpGetMaxCpuId). */213 RTCPUID idCpuMax;214 215 /** Padding / reserved space for future data. */216 uint32_t au32Padding1[29];217 218 /** Table indexed by the CPU APIC ID to get the CPU table index. */219 uint16_t aiCpuFromApicId[256];220 /** CPU set index to CPU table index. */221 uint16_t aiCpuFromCpuSetIdx[RTCPUSET_MAX_CPUS];222 223 /** Array of per-cpu data.224 * This is index by ApicId via the aiCpuFromApicId table.225 *226 * The clock and frequency information is updated for all CPUs if u32Mode227 * is SUPGIPMODE_ASYNC_TSC, otherwise (SUPGIPMODE_SYNC_TSC) only the first228 * entry is updated. */229 SUPGIPCPU aCPUs[1];230 } SUPGLOBALINFOPAGE;231 AssertCompileMemberAlignment(SUPGLOBALINFOPAGE, u64NanoTSLastUpdateHz, 8);232 #if defined(RT_ARCH_SPARC) || defined(RT_ARCH_SPARC64)233 AssertCompileMemberAlignment(SUPGLOBALINFOPAGE, aCPUs, 32);234 #else235 AssertCompileMemberAlignment(SUPGLOBALINFOPAGE, aCPUs, 256);236 #endif237 238 /** Pointer to the global info page.239 * @remark there is no const version of this typedef, see g_pSUPGlobalInfoPage for details. */240 typedef SUPGLOBALINFOPAGE *PSUPGLOBALINFOPAGE;241 242 243 /** The value of the SUPGLOBALINFOPAGE::u32Magic field. (Soryo Fuyumi) */244 #define SUPGLOBALINFOPAGE_MAGIC 0x19590106245 /** The GIP version.246 * Upper 16 bits is the major version. Major version is only changed with247 * incompatible changes in the GIP. */248 #define SUPGLOBALINFOPAGE_VERSION 0x00030000249 250 /**251 * SUPGLOBALINFOPAGE::u32Mode values.252 */253 typedef enum SUPGIPMODE254 {255 /** The usual invalid null entry. */256 SUPGIPMODE_INVALID = 0,257 /** The TSC of the cores and cpus in the system is in sync. */258 SUPGIPMODE_SYNC_TSC,259 /** Each core has it's own TSC. */260 SUPGIPMODE_ASYNC_TSC,261 /** The usual 32-bit hack. */262 SUPGIPMODE_32BIT_HACK = 0x7fffffff263 } SUPGIPMODE;264 265 /** Pointer to the Global Information Page.266 *267 * This pointer is valid as long as SUPLib has a open session. Anyone using268 * the page must treat this pointer as highly volatile and not trust it beyond269 * one transaction.270 *271 * @remark The GIP page is read-only to everyone but the support driver and272 * is actually mapped read only everywhere but in ring-0. However273 * it is not marked 'const' as this might confuse compilers into274 * thinking that values doesn't change even if members are marked275 * as volatile. Thus, there is no PCSUPGLOBALINFOPAGE type.276 */277 #if defined(IN_SUP_R0) || defined(IN_SUP_R3) || defined(IN_SUP_RC)278 extern DECLEXPORT(PSUPGLOBALINFOPAGE) g_pSUPGlobalInfoPage;279 280 #elif !defined(IN_RING0) || defined(RT_OS_WINDOWS) || defined(RT_OS_SOLARIS)281 extern DECLIMPORT(PSUPGLOBALINFOPAGE) g_pSUPGlobalInfoPage;282 283 #else /* IN_RING0 && !RT_OS_WINDOWS */284 # if !defined(__GNUC__) || defined(RT_OS_DARWIN) || !defined(RT_ARCH_AMD64)285 # define g_pSUPGlobalInfoPage (&g_SUPGlobalInfoPage)286 # else287 # define g_pSUPGlobalInfoPage (SUPGetGIPHlp())288 /** Workaround for ELF+GCC problem on 64-bit hosts.289 * (GCC emits a mov with a R_X86_64_32 reloc, we need R_X86_64_64.) */290 DECLINLINE(PSUPGLOBALINFOPAGE) SUPGetGIPHlp(void)291 {292 PSUPGLOBALINFOPAGE pGIP;293 __asm__ __volatile__ ("movabs $g_SUPGlobalInfoPage,%0\n\t"294 : "=a" (pGIP));295 return pGIP;296 }297 # endif298 /** The GIP.299 * We save a level of indirection by exporting the GIP instead of a variable300 * pointing to it. */301 extern DECLIMPORT(SUPGLOBALINFOPAGE) g_SUPGlobalInfoPage;302 #endif303 304 /**305 * Gets the GIP pointer.306 *307 * @returns Pointer to the GIP or NULL.308 */309 SUPDECL(PSUPGLOBALINFOPAGE) SUPGetGIP(void);310 311 #ifdef ___iprt_asm_amd64_x86_h312 /**313 * Gets the TSC frequency of the calling CPU.314 *315 * @returns TSC frequency, UINT64_MAX on failure.316 * @param pGip The GIP pointer.317 */318 DECLINLINE(uint64_t) SUPGetCpuHzFromGIP(PSUPGLOBALINFOPAGE pGip)319 {320 unsigned iCpu;321 322 if (RT_UNLIKELY(!pGip || pGip->u32Magic != SUPGLOBALINFOPAGE_MAGIC))323 return UINT64_MAX;324 325 if (pGip->u32Mode != SUPGIPMODE_ASYNC_TSC)326 iCpu = 0;327 else328 {329 iCpu = pGip->aiCpuFromApicId[ASMGetApicId()];330 if (iCpu >= pGip->cCpus)331 return UINT64_MAX;332 }333 334 return pGip->aCPUs[iCpu].u64CpuHz;335 }336 #endif337 338 /**339 * Request for generic VMMR0Entry calls.340 */341 typedef struct SUPVMMR0REQHDR342 {343 /** The magic. (SUPVMMR0REQHDR_MAGIC) */344 uint32_t u32Magic;345 /** The size of the request. */346 uint32_t cbReq;347 } SUPVMMR0REQHDR;348 /** Pointer to a ring-0 request header. */349 typedef SUPVMMR0REQHDR *PSUPVMMR0REQHDR;350 /** the SUPVMMR0REQHDR::u32Magic value (Ethan Iverson - The Bad Plus). */351 #define SUPVMMR0REQHDR_MAGIC UINT32_C(0x19730211)352 353 354 /** For the fast ioctl path.355 * @{356 */357 /** @see VMMR0_DO_RAW_RUN. */358 #define SUP_VMMR0_DO_RAW_RUN 0359 /** @see VMMR0_DO_HWACC_RUN. */360 #define SUP_VMMR0_DO_HWACC_RUN 1361 /** @see VMMR0_DO_NOP */362 #define SUP_VMMR0_DO_NOP 2363 /** @} */364 365 /** SUPR3QueryVTCaps capability flags366 * @{367 */368 #define SUPVTCAPS_AMD_V RT_BIT(0)369 #define SUPVTCAPS_VT_X RT_BIT(1)370 #define SUPVTCAPS_NESTED_PAGING RT_BIT(2)371 /** @} */372 373 /**374 * Request for generic FNSUPR0SERVICEREQHANDLER calls.375 */376 typedef struct SUPR0SERVICEREQHDR377 {378 /** The magic. (SUPR0SERVICEREQHDR_MAGIC) */379 uint32_t u32Magic;380 /** The size of the request. */381 uint32_t cbReq;382 } SUPR0SERVICEREQHDR;383 /** Pointer to a ring-0 service request header. */384 typedef SUPR0SERVICEREQHDR *PSUPR0SERVICEREQHDR;385 /** the SUPVMMR0REQHDR::u32Magic value (Esbjoern Svensson - E.S.P.). */386 #define SUPR0SERVICEREQHDR_MAGIC UINT32_C(0x19640416)387 388 389 /** Event semaphore handle. Ring-0 / ring-3. */390 typedef R0PTRTYPE(struct SUPSEMEVENTHANDLE *) SUPSEMEVENT;391 /** Pointer to an event semaphore handle. */392 typedef SUPSEMEVENT *PSUPSEMEVENT;393 /** Nil event semaphore handle. */394 #define NIL_SUPSEMEVENT ((SUPSEMEVENT)0)395 396 /**397 * Creates a single release event semaphore.398 *399 * @returns VBox status code.400 * @param pSession The session handle of the caller.401 * @param phEvent Where to return the handle to the event semaphore.402 */403 SUPDECL(int) SUPSemEventCreate(PSUPDRVSESSION pSession, PSUPSEMEVENT phEvent);404 405 /**406 * Closes a single release event semaphore handle.407 *408 * @returns VBox status code.409 * @retval VINF_OBJECT_DESTROYED if the semaphore was destroyed.410 * @retval VINF_SUCCESS if the handle was successfully closed but the semaphore411 * object remained alive because of other references.412 *413 * @param pSession The session handle of the caller.414 * @param hEvent The handle. Nil is quietly ignored.415 */416 SUPDECL(int) SUPSemEventClose(PSUPDRVSESSION pSession, SUPSEMEVENT hEvent);417 418 /**419 * Signals a single release event semaphore.420 *421 * @returns VBox status code.422 * @param pSession The session handle of the caller.423 * @param hEvent The semaphore handle.424 */425 SUPDECL(int) SUPSemEventSignal(PSUPDRVSESSION pSession, SUPSEMEVENT hEvent);426 427 #ifdef IN_RING0428 /**429 * Waits on a single release event semaphore, not interruptible.430 *431 * @returns VBox status code.432 * @param pSession The session handle of the caller.433 * @param hEvent The semaphore handle.434 * @param cMillies The number of milliseconds to wait.435 * @remarks Not available in ring-3.436 */437 SUPDECL(int) SUPSemEventWait(PSUPDRVSESSION pSession, SUPSEMEVENT hEvent, uint32_t cMillies);438 #endif439 440 /**441 * Waits on a single release event semaphore, interruptible.442 *443 * @returns VBox status code.444 * @param pSession The session handle of the caller.445 * @param hEvent The semaphore handle.446 * @param cMillies The number of milliseconds to wait.447 */448 SUPDECL(int) SUPSemEventWaitNoResume(PSUPDRVSESSION pSession, SUPSEMEVENT hEvent, uint32_t cMillies);449 450 /**451 * Waits on a single release event semaphore, interruptible.452 *453 * @returns VBox status code.454 * @param pSession The session handle of the caller.455 * @param hEvent The semaphore handle.456 * @param uNsTimeout The deadline given on the RTTimeNanoTS() clock.457 */458 SUPDECL(int) SUPSemEventWaitNsAbsIntr(PSUPDRVSESSION pSession, SUPSEMEVENT hEvent, uint64_t uNsTimeout);459 460 /**461 * Waits on a single release event semaphore, interruptible.462 *463 * @returns VBox status code.464 * @param pSession The session handle of the caller.465 * @param hEvent The semaphore handle.466 * @param cNsTimeout The number of nanoseconds to wait.467 */468 SUPDECL(int) SUPSemEventWaitNsRelIntr(PSUPDRVSESSION pSession, SUPSEMEVENT hEvent, uint64_t cNsTimeout);469 470 /**471 * Gets the best timeout resolution that SUPSemEventWaitNsAbsIntr and472 * SUPSemEventWaitNsAbsIntr can do.473 *474 * @returns The resolution in nanoseconds.475 * @param pSession The session handle of the caller.476 */477 SUPDECL(uint32_t) SUPSemEventGetResolution(PSUPDRVSESSION pSession);478 479 480 /** Multiple release event semaphore handle. Ring-0 / ring-3. */481 typedef R0PTRTYPE(struct SUPSEMEVENTMULTIHANDLE *) SUPSEMEVENTMULTI;482 /** Pointer to an multiple release event semaphore handle. */483 typedef SUPSEMEVENTMULTI *PSUPSEMEVENTMULTI;484 /** Nil multiple release event semaphore handle. */485 #define NIL_SUPSEMEVENTMULTI ((SUPSEMEVENTMULTI)0)486 487 /**488 * Creates a multiple release event semaphore.489 *490 * @returns VBox status code.491 * @param pSession The session handle of the caller.492 * @param phEventMulti Where to return the handle to the event semaphore.493 */494 SUPDECL(int) SUPSemEventMultiCreate(PSUPDRVSESSION pSession, PSUPSEMEVENTMULTI phEventMulti);495 496 /**497 * Closes a multiple release event semaphore handle.498 *499 * @returns VBox status code.500 * @retval VINF_OBJECT_DESTROYED if the semaphore was destroyed.501 * @retval VINF_SUCCESS if the handle was successfully closed but the semaphore502 * object remained alive because of other references.503 *504 * @param pSession The session handle of the caller.505 * @param hEventMulti The handle. Nil is quietly ignored.506 */507 SUPDECL(int) SUPSemEventMultiClose(PSUPDRVSESSION pSession, SUPSEMEVENTMULTI hEventMulti);508 509 /**510 * Signals a multiple release event semaphore.511 *512 * @returns VBox status code.513 * @param pSession The session handle of the caller.514 * @param hEventMulti The semaphore handle.515 */516 SUPDECL(int) SUPSemEventMultiSignal(PSUPDRVSESSION pSession, SUPSEMEVENTMULTI hEventMulti);517 518 /**519 * Resets a multiple release event semaphore.520 *521 * @returns VBox status code.522 * @param pSession The session handle of the caller.523 * @param hEventMulti The semaphore handle.524 */525 SUPDECL(int) SUPSemEventMultiReset(PSUPDRVSESSION pSession, SUPSEMEVENTMULTI hEventMulti);526 527 #ifdef IN_RING0528 /**529 * Waits on a multiple release event semaphore, not interruptible.530 *531 * @returns VBox status code.532 * @param pSession The session handle of the caller.533 * @param hEventMulti The semaphore handle.534 * @param cMillies The number of milliseconds to wait.535 * @remarks Not available in ring-3.536 */537 SUPDECL(int) SUPSemEventMultiWait(PSUPDRVSESSION pSession, SUPSEMEVENTMULTI hEventMulti, uint32_t cMillies);538 #endif539 540 /**541 * Waits on a multiple release event semaphore, interruptible.542 *543 * @returns VBox status code.544 * @param pSession The session handle of the caller.545 * @param hEventMulti The semaphore handle.546 * @param cMillies The number of milliseconds to wait.547 */548 SUPDECL(int) SUPSemEventMultiWaitNoResume(PSUPDRVSESSION pSession, SUPSEMEVENTMULTI hEventMulti, uint32_t cMillies);549 550 /**551 * Waits on a multiple release event semaphore, interruptible.552 *553 * @returns VBox status code.554 * @param pSession The session handle of the caller.555 * @param hEventMulti The semaphore handle.556 * @param uNsTimeout The deadline given on the RTTimeNanoTS() clock.557 */558 SUPDECL(int) SUPSemEventMultiWaitNsAbsIntr(PSUPDRVSESSION pSession, SUPSEMEVENTMULTI hEventMulti, uint64_t uNsTimeout);559 560 /**561 * Waits on a multiple release event semaphore, interruptible.562 *563 * @returns VBox status code.564 * @param pSession The session handle of the caller.565 * @param hEventMulti The semaphore handle.566 * @param cNsTimeout The number of nanoseconds to wait.567 */568 SUPDECL(int) SUPSemEventMultiWaitNsRelIntr(PSUPDRVSESSION pSession, SUPSEMEVENTMULTI hEventMulti, uint64_t cNsTimeout);569 570 /**571 * Gets the best timeout resolution that SUPSemEventMultiWaitNsAbsIntr and572 * SUPSemEventMultiWaitNsRelIntr can do.573 *574 * @returns The resolution in nanoseconds.575 * @param pSession The session handle of the caller.576 */577 SUPDECL(uint32_t) SUPSemEventMultiGetResolution(PSUPDRVSESSION pSession);578 579 580 #ifdef IN_RING3581 582 /** @defgroup grp_sup_r3 SUP Host Context Ring-3 API583 * @ingroup grp_sup584 * @{585 */586 587 /**588 * Installs the support library.589 *590 * @returns VBox status code.591 */592 SUPR3DECL(int) SUPR3Install(void);593 594 /**595 * Uninstalls the support library.596 *597 * @returns VBox status code.598 */599 SUPR3DECL(int) SUPR3Uninstall(void);600 601 /**602 * Trusted main entry point.603 *604 * This is exported as "TrustedMain" by the dynamic libraries which contains the605 * "real" application binary for which the hardened stub is built. The entry606 * point is invoked upon successful initialization of the support library and607 * runtime.608 *609 * @returns main kind of exit code.610 * @param argc The argument count.611 * @param argv The argument vector.612 * @param envp The environment vector.613 */614 typedef DECLCALLBACK(int) FNSUPTRUSTEDMAIN(int argc, char **argv, char **envp);615 /** Pointer to FNSUPTRUSTEDMAIN(). */616 typedef FNSUPTRUSTEDMAIN *PFNSUPTRUSTEDMAIN;617 618 /** Which operation failed. */619 typedef enum SUPINITOP620 {621 /** Invalid. */622 kSupInitOp_Invalid = 0,623 /** Installation integrity error. */624 kSupInitOp_Integrity,625 /** Setuid related. */626 kSupInitOp_RootCheck,627 /** Driver related. */628 kSupInitOp_Driver,629 /** IPRT init related. */630 kSupInitOp_IPRT,631 /** Place holder. */632 kSupInitOp_End633 } SUPINITOP;634 635 /**636 * Trusted error entry point, optional.637 *638 * This is exported as "TrustedError" by the dynamic libraries which contains639 * the "real" application binary for which the hardened stub is built.640 *641 * @param pszWhere Where the error occurred (function name).642 * @param enmWhat Which operation went wrong.643 * @param rc The status code.644 * @param pszMsgFmt Error message format string.645 * @param va The message format arguments.646 */647 typedef DECLCALLBACK(void) FNSUPTRUSTEDERROR(const char *pszWhere, SUPINITOP enmWhat, int rc, const char *pszMsgFmt, va_list va);648 /** Pointer to FNSUPTRUSTEDERROR. */649 typedef FNSUPTRUSTEDERROR *PFNSUPTRUSTEDERROR;650 651 /**652 * Secure main.653 *654 * This is used for the set-user-ID-on-execute binaries on unixy systems655 * and when using the open-vboxdrv-via-root-service setup on Windows.656 *657 * This function will perform the integrity checks of the VirtualBox658 * installation, open the support driver, open the root service (later),659 * and load the DLL corresponding to \a pszProgName and execute its main660 * function.661 *662 * @returns Return code appropriate for main().663 *664 * @param pszProgName The program name. This will be used to figure out which665 * DLL/SO/DYLIB to load and execute.666 * @param fFlags Flags.667 * @param argc The argument count.668 * @param argv The argument vector.669 * @param envp The environment vector.670 */671 DECLHIDDEN(int) SUPR3HardenedMain(const char *pszProgName, uint32_t fFlags, int argc, char **argv, char **envp);672 673 /** @name SUPR3SecureMain flags.674 * @{ */675 /** Don't open the device. (Intended for VirtualBox without -startvm.) */676 #define SUPSECMAIN_FLAGS_DONT_OPEN_DEV RT_BIT_32(0)677 /** @} */678 679 /**680 * Initializes the support library.681 * Each successful call to SUPR3Init() must be countered by a682 * call to SUPR3Term(false).683 *684 * @returns VBox status code.685 * @param ppSession Where to store the session handle. Defaults to NULL.686 */687 SUPR3DECL(int) SUPR3Init(PSUPDRVSESSION *ppSession);688 689 /**690 * Terminates the support library.691 *692 * @returns VBox status code.693 * @param fForced Forced termination. This means to ignore the694 * init call count and just terminated.695 */696 #ifdef __cplusplus697 SUPR3DECL(int) SUPR3Term(bool fForced = false);698 #else699 SUPR3DECL(int) SUPR3Term(int fForced);700 #endif701 702 /**703 * Sets the ring-0 VM handle for use with fast IOCtls.704 *705 * @returns VBox status code.706 * @param pVMR0 The ring-0 VM handle.707 * NIL_RTR0PTR can be used to unset the handle when the708 * VM is about to be destroyed.709 */710 SUPR3DECL(int) SUPR3SetVMForFastIOCtl(PVMR0 pVMR0);711 712 /**713 * Calls the HC R0 VMM entry point.714 * See VMMR0Entry() for more details.715 *716 * @returns error code specific to uFunction.717 * @param pVMR0 Pointer to the Ring-0 (Host Context) mapping of the VM structure.718 * @param idCpu The virtual CPU ID.719 * @param uOperation Operation to execute.720 * @param pvArg Argument.721 */722 SUPR3DECL(int) SUPR3CallVMMR0(PVMR0 pVMR0, VMCPUID idCpu, unsigned uOperation, void *pvArg);723 724 /**725 * Variant of SUPR3CallVMMR0, except that this takes the fast ioclt path726 * regardsless of compile-time defaults.727 *728 * @returns VBox status code.729 * @param pVMR0 The ring-0 VM handle.730 * @param uOperation The operation; only the SUP_VMMR0_DO_* ones are valid.731 * @param idCpu The virtual CPU ID.732 */733 SUPR3DECL(int) SUPR3CallVMMR0Fast(PVMR0 pVMR0, unsigned uOperation, VMCPUID idCpu);734 735 /**736 * Calls the HC R0 VMM entry point, in a safer but slower manner than737 * SUPR3CallVMMR0. When entering using this call the R0 components can call738 * into the host kernel (i.e. use the SUPR0 and RT APIs).739 *740 * See VMMR0Entry() for more details.741 *742 * @returns error code specific to uFunction.743 * @param pVMR0 Pointer to the Ring-0 (Host Context) mapping of the VM structure.744 * @param idCpu The virtual CPU ID.745 * @param uOperation Operation to execute.746 * @param u64Arg Constant argument.747 * @param pReqHdr Pointer to a request header. Optional.748 * This will be copied in and out of kernel space. There currently is a size749 * limit on this, just below 4KB.750 */751 SUPR3DECL(int) SUPR3CallVMMR0Ex(PVMR0 pVMR0, VMCPUID idCpu, unsigned uOperation, uint64_t u64Arg, PSUPVMMR0REQHDR pReqHdr);752 753 /**754 * Calls a ring-0 service.755 *756 * The operation and the request packet is specific to the service.757 *758 * @returns error code specific to uFunction.759 * @param pszService The service name.760 * @param cchService The length of the service name.761 * @param uReq The request number.762 * @param u64Arg Constant argument.763 * @param pReqHdr Pointer to a request header. Optional.764 * This will be copied in and out of kernel space. There currently is a size765 * limit on this, just below 4KB.766 */767 SUPR3DECL(int) SUPR3CallR0Service(const char *pszService, size_t cchService, uint32_t uOperation, uint64_t u64Arg, PSUPR0SERVICEREQHDR pReqHdr);768 769 /** Which logger. */770 typedef enum SUPLOGGER771 {772 SUPLOGGER_DEBUG = 1,773 SUPLOGGER_RELEASE774 } SUPLOGGER;775 776 /**777 * Changes the settings of the specified ring-0 logger.778 *779 * @returns VBox status code.780 * @param enmWhich Which logger.781 * @param pszFlags The flags settings.782 * @param pszGroups The groups settings.783 * @param pszDest The destination specificier.784 */785 SUPR3DECL(int) SUPR3LoggerSettings(SUPLOGGER enmWhich, const char *pszFlags, const char *pszGroups, const char *pszDest);786 787 /**788 * Creates a ring-0 logger instance.789 *790 * @returns VBox status code.791 * @param enmWhich Which logger to create.792 * @param pszFlags The flags settings.793 * @param pszGroups The groups settings.794 * @param pszDest The destination specificier.795 */796 SUPR3DECL(int) SUPR3LoggerCreate(SUPLOGGER enmWhich, const char *pszFlags, const char *pszGroups, const char *pszDest);797 798 /**799 * Destroys a ring-0 logger instance.800 *801 * @returns VBox status code.802 * @param enmWhich Which logger.803 */804 SUPR3DECL(int) SUPR3LoggerDestroy(SUPLOGGER enmWhich);805 806 /**807 * Queries the paging mode of the host OS.808 *809 * @returns The paging mode.810 */811 SUPR3DECL(SUPPAGINGMODE) SUPR3GetPagingMode(void);812 813 /**814 * Allocate zero-filled pages.815 *816 * Use this to allocate a number of pages suitable for seeding / locking.817 * Call SUPR3PageFree() to free the pages once done with them.818 *819 * @returns VBox status.820 * @param cPages Number of pages to allocate.821 * @param ppvPages Where to store the base pointer to the allocated pages.822 */823 SUPR3DECL(int) SUPR3PageAlloc(size_t cPages, void **ppvPages);824 825 /**826 * Frees pages allocated with SUPR3PageAlloc().827 *828 * @returns VBox status.829 * @param pvPages Pointer returned by SUPR3PageAlloc().830 * @param cPages Number of pages that was allocated.831 */832 SUPR3DECL(int) SUPR3PageFree(void *pvPages, size_t cPages);833 834 /**835 * Allocate non-zeroed, locked, pages with user and, optionally, kernel836 * mappings.837 *838 * Use SUPR3PageFreeEx() to free memory allocated with this function.839 *840 * @returns VBox status code.841 * @param cPages The number of pages to allocate.842 * @param fFlags Flags, reserved. Must be zero.843 * @param ppvPages Where to store the address of the user mapping.844 * @param pR0Ptr Where to store the address of the kernel mapping.845 * NULL if no kernel mapping is desired.846 * @param paPages Where to store the physical addresses of each page.847 * Optional.848 */849 SUPR3DECL(int) SUPR3PageAllocEx(size_t cPages, uint32_t fFlags, void **ppvPages, PRTR0PTR pR0Ptr, PSUPPAGE paPages);850 851 /**852 * Maps a portion of a ring-3 only allocation into kernel space.853 *854 * @returns VBox status code.855 *856 * @param pvR3 The address SUPR3PageAllocEx return.857 * @param off Offset to start mapping at. Must be page aligned.858 * @param cb Number of bytes to map. Must be page aligned.859 * @param fFlags Flags, must be zero.860 * @param pR0Ptr Where to store the address on success.861 *862 */863 SUPR3DECL(int) SUPR3PageMapKernel(void *pvR3, uint32_t off, uint32_t cb, uint32_t fFlags, PRTR0PTR pR0Ptr);864 865 /**866 * Changes the protection of867 *868 * @returns VBox status code.869 * @retval VERR_NOT_SUPPORTED if the OS doesn't allow us to change page level870 * protection. See also RTR0MemObjProtect.871 *872 * @param pvR3 The ring-3 address SUPR3PageAllocEx returned.873 * @param R0Ptr The ring-0 address SUPR3PageAllocEx returned if it874 * is desired that the corresponding ring-0 page875 * mappings should change protection as well. Pass876 * NIL_RTR0PTR if the ring-0 pages should remain877 * unaffected.878 * @param off Offset to start at which to start chagning the page879 * level protection. Must be page aligned.880 * @param cb Number of bytes to change. Must be page aligned.881 * @param fProt The new page level protection, either a combination882 * of RTMEM_PROT_READ, RTMEM_PROT_WRITE and883 * RTMEM_PROT_EXEC, or just RTMEM_PROT_NONE.884 */885 SUPR3DECL(int) SUPR3PageProtect(void *pvR3, RTR0PTR R0Ptr, uint32_t off, uint32_t cb, uint32_t fProt);886 887 /**888 * Free pages allocated by SUPR3PageAllocEx.889 *890 * @returns VBox status code.891 * @param pvPages The address of the user mapping.892 * @param cPages The number of pages.893 */894 SUPR3DECL(int) SUPR3PageFreeEx(void *pvPages, size_t cPages);895 896 /**897 * Allocated memory with page aligned memory with a contiguous and locked physical898 * memory backing below 4GB.899 *900 * @returns Pointer to the allocated memory (virtual address).901 * *pHCPhys is set to the physical address of the memory.902 * If ppvR0 isn't NULL, *ppvR0 is set to the ring-0 mapping.903 * The returned memory must be freed using SUPR3ContFree().904 * @returns NULL on failure.905 * @param cPages Number of pages to allocate.906 * @param pR0Ptr Where to store the ring-0 mapping of the allocation. (optional)907 * @param pHCPhys Where to store the physical address of the memory block.908 *909 * @remark This 2nd version of this API exists because we're not able to map the910 * ring-3 mapping executable on WIN64. This is a serious problem in regard to911 * the world switchers.912 */913 SUPR3DECL(void *) SUPR3ContAlloc(size_t cPages, PRTR0PTR pR0Ptr, PRTHCPHYS pHCPhys);914 915 /**916 * Frees memory allocated with SUPR3ContAlloc().917 *918 * @returns VBox status code.919 * @param pv Pointer to the memory block which should be freed.920 * @param cPages Number of pages to be freed.921 */922 SUPR3DECL(int) SUPR3ContFree(void *pv, size_t cPages);923 924 /**925 * Allocated non contiguous physical memory below 4GB.926 *927 * The memory isn't zeroed.928 *929 * @returns VBox status code.930 * @returns NULL on failure.931 * @param cPages Number of pages to allocate.932 * @param ppvPages Where to store the pointer to the allocated memory.933 * The pointer stored here on success must be passed to934 * SUPR3LowFree when the memory should be released.935 * @param ppvPagesR0 Where to store the ring-0 pointer to the allocated memory. optional.936 * @param paPages Where to store the physical addresses of the individual pages.937 */938 SUPR3DECL(int) SUPR3LowAlloc(size_t cPages, void **ppvPages, PRTR0PTR ppvPagesR0, PSUPPAGE paPages);939 940 /**941 * Frees memory allocated with SUPR3LowAlloc().942 *943 * @returns VBox status code.944 * @param pv Pointer to the memory block which should be freed.945 * @param cPages Number of pages that was allocated.946 */947 SUPR3DECL(int) SUPR3LowFree(void *pv, size_t cPages);948 949 /**950 * Load a module into R0 HC.951 *952 * This will verify the file integrity in a similar manner as953 * SUPR3HardenedVerifyFile before loading it.954 *955 * @returns VBox status code.956 * @param pszFilename The path to the image file.957 * @param pszModule The module name. Max 32 bytes.958 * @param ppvImageBase Where to store the image address.959 * @param pErrInfo Where to return extended error information.960 * Optional.961 */962 SUPR3DECL(int) SUPR3LoadModule(const char *pszFilename, const char *pszModule, void **ppvImageBase, PRTERRINFO pErrInfo);963 964 /**965 * Load a module into R0 HC.966 *967 * This will verify the file integrity in a similar manner as968 * SUPR3HardenedVerifyFile before loading it.969 *970 * @returns VBox status code.971 * @param pszFilename The path to the image file.972 * @param pszModule The module name. Max 32 bytes.973 * @param pszSrvReqHandler The name of the service request handler entry974 * point. See FNSUPR0SERVICEREQHANDLER.975 * @param ppvImageBase Where to store the image address.976 */977 SUPR3DECL(int) SUPR3LoadServiceModule(const char *pszFilename, const char *pszModule,978 const char *pszSrvReqHandler, void **ppvImageBase);979 980 /**981 * Frees a R0 HC module.982 *983 * @returns VBox status code.984 * @param pszModule The module to free.985 * @remark This will not actually 'free' the module, there are of course usage counting.986 */987 SUPR3DECL(int) SUPR3FreeModule(void *pvImageBase);988 989 /**990 * Get the address of a symbol in a ring-0 module.991 *992 * @returns VBox status code.993 * @param pszModule The module name.994 * @param pszSymbol Symbol name. If it's value is less than 64k it's treated like a995 * ordinal value rather than a string pointer.996 * @param ppvValue Where to store the symbol value.997 */998 SUPR3DECL(int) SUPR3GetSymbolR0(void *pvImageBase, const char *pszSymbol, void **ppvValue);999 1000 /**1001 * Load R0 HC VMM code.1002 *1003 * @returns VBox status code.1004 * @deprecated Use SUPR3LoadModule(pszFilename, "VMMR0.r0", &pvImageBase)1005 */1006 SUPR3DECL(int) SUPR3LoadVMM(const char *pszFilename);1007 1008 /**1009 * Unloads R0 HC VMM code.1010 *1011 * @returns VBox status code.1012 * @deprecated Use SUPR3FreeModule().1013 */1014 SUPR3DECL(int) SUPR3UnloadVMM(void);1015 1016 /**1017 * Get the physical address of the GIP.1018 *1019 * @returns VBox status code.1020 * @param pHCPhys Where to store the physical address of the GIP.1021 */1022 SUPR3DECL(int) SUPR3GipGetPhys(PRTHCPHYS pHCPhys);1023 1024 /**1025 * Verifies the integrity of a file, and optionally opens it.1026 *1027 * The integrity check is for whether the file is suitable for loading into1028 * the hypervisor or VM process. The integrity check may include verifying1029 * the authenticode/elfsign/whatever signature of the file, which can take1030 * a little while.1031 *1032 * @returns VBox status code. On failure it will have printed a LogRel message.1033 *1034 * @param pszFilename The file.1035 * @param pszWhat For the LogRel on failure.1036 * @param phFile Where to store the handle to the opened file. This is optional, pass NULL1037 * if the file should not be opened.1038 * @deprecated Write a new one.1039 */1040 SUPR3DECL(int) SUPR3HardenedVerifyFile(const char *pszFilename, const char *pszWhat, PRTFILE phFile);1041 1042 /**1043 * Verifies the integrity of a the current process, including the image1044 * location and that the invocation was absolute.1045 *1046 * This must currently be called after initializing the runtime. The intended1047 * audience is set-uid-to-root applications, root services and similar.1048 *1049 * @returns VBox status code. On failure1050 * message.1051 * @param pszArgv0 The first argument to main().1052 * @param fInternal Set this to @c true if this is an internal1053 * VirtualBox application. Otherwise pass @c false.1054 * @param pErrInfo Where to return extended error information.1055 */1056 SUPR3DECL(int) SUPR3HardenedVerifySelf(const char *pszArgv0, bool fInternal, PRTERRINFO pErrInfo);1057 1058 /**1059 * Verifies the integrity of an installation directory.1060 *1061 * The integrity check verifies that the directory cannot be tampered with by1062 * normal users on the system. On Unix this translates to root ownership and1063 * no symbolic linking.1064 *1065 * @returns VBox status code. On failure a message will be stored in @a pszErr.1066 *1067 * @param pszDirPath The directory path.1068 * @param fRecursive Whether the check should be recursive or1069 * not. When set, all sub-directores will be checked,1070 * including files (@a fCheckFiles is ignored).1071 * @param fCheckFiles Whether to apply the same basic integrity check to1072 * the files in the directory as the directory itself.1073 * @param pErrInfo Where to return extended error information.1074 * Optional.1075 */1076 SUPR3DECL(int) SUPR3HardenedVerifyDir(const char *pszDirPath, bool fRecursive, bool fCheckFiles, PRTERRINFO pErrInfo);1077 1078 /**1079 * Verifies the integrity of a plug-in module.1080 *1081 * This is similar to SUPR3HardenedLdrLoad, except it does not load the module1082 * and that the module does not have to be shipped with VirtualBox.1083 *1084 * @returns VBox status code. On failure a message will be stored in @a pszErr.1085 *1086 * @param pszFilename The filename of the plug-in module (nothing can be1087 * omitted here).1088 * @param pErrInfo Where to return extended error information.1089 * Optional.1090 */1091 SUPR3DECL(int) SUPR3HardenedVerifyPlugIn(const char *pszFilename, PRTERRINFO pErrInfo);1092 1093 /**1094 * Same as RTLdrLoad() but will verify the files it loads (hardened builds).1095 *1096 * Will add dll suffix if missing and try load the file.1097 *1098 * @returns iprt status code.1099 * @param pszFilename Image filename. This must have a path.1100 * @param phLdrMod Where to store the handle to the loaded module.1101 * @param fFlags See RTLDRLOAD_FLAGS_XXX.1102 * @param pErrInfo Where to return extended error information.1103 * Optional.1104 */1105 SUPR3DECL(int) SUPR3HardenedLdrLoad(const char *pszFilename, PRTLDRMOD phLdrMod, uint32_t fFlags, PRTERRINFO pErrInfo);1106 1107 /**1108 * Same as RTLdrLoadAppPriv() but it will verify the files it loads (hardened1109 * builds).1110 *1111 * Will add dll suffix to the file if missing, then look for it in the1112 * architecture dependent application directory.1113 *1114 * @returns iprt status code.1115 * @param pszFilename Image filename.1116 * @param phLdrMod Where to store the handle to the loaded module.1117 * @param fFlags See RTLDRLOAD_FLAGS_XXX.1118 * @param pErrInfo Where to return extended error information.1119 * Optional.1120 */1121 SUPR3DECL(int) SUPR3HardenedLdrLoadAppPriv(const char *pszFilename, PRTLDRMOD phLdrMod, uint32_t fFlags, PRTERRINFO pErrInfo);1122 1123 /**1124 * Same as RTLdrLoad() but will verify the files it loads (hardened builds).1125 *1126 * This differs from SUPR3HardenedLdrLoad() in that it can load modules from1127 * extension packs and anything else safely installed on the system, provided1128 * they pass the hardening tests.1129 *1130 * @returns iprt status code.1131 * @param pszFilename The full path to the module, with extension.1132 * @param phLdrMod Where to store the handle to the loaded module.1133 * @param pErrInfo Where to return extended error information.1134 * Optional.1135 */1136 SUPR3DECL(int) SUPR3HardenedLdrLoadPlugIn(const char *pszFilename, PRTLDRMOD phLdrMod, PRTERRINFO pErrInfo);1137 1138 /**1139 * Check if the host kernel can run in VMX root mode.1140 *1141 * @returns VINF_SUCCESS if supported, error code indicating why if not.1142 */1143 SUPR3DECL(int) SUPR3QueryVTxSupported(void);1144 1145 /**1146 * Return VT-x/AMD-V capabilities.1147 *1148 * @returns VINF_SUCCESS if supported, error code indicating why if not.1149 * @param pfCaps Pointer to capability dword (out).1150 * @todo Intended for main, which means we need to relax the privilege requires1151 * when accessing certain vboxdrv functions.1152 */1153 SUPR3DECL(int) SUPR3QueryVTCaps(uint32_t *pfCaps);1154 1155 /**1156 * Open the tracer.1157 *1158 * @returns VBox status code.1159 * @param uCookie Cookie identifying the tracer we expect to talk to.1160 * @param uArg Tracer specific open argument.1161 */1162 SUPR3DECL(int) SUPR3TracerOpen(uint32_t uCookie, uintptr_t uArg);1163 1164 /**1165 * Closes the tracer.1166 *1167 * @returns VBox status code.1168 */1169 SUPR3DECL(int) SUPR3TracerClose(void);1170 1171 /**1172 * Perform an I/O request on the tracer.1173 *1174 * @returns VBox status.1175 * @param uCmd The tracer command.1176 * @param uArg The argument.1177 * @param piRetVal Where to store the tracer return value.1178 */1179 SUPR3DECL(int) SUPR3TracerIoCtl(uintptr_t uCmd, uintptr_t uArg, int32_t *piRetVal);1180 1181 /**1182 * Registers the user module with the tracer.1183 *1184 * @returns VBox status code.1185 * @param hModNative Native module handle. Pass ~(uintptr_t)0 if not1186 * at hand.1187 * @param pszModule The module name.1188 * @param pVtgHdr The VTG header.1189 * @param fFlags See SUP_TRACER_UMOD_FLAGS_XXX1190 */1191 SUPR3DECL(int) SUPR3TracerRegisterModule(uintptr_t hModNative, const char *pszModule, struct VTGOBJHDR *pVtgHdr, uint32_t fFlags);1192 1193 /**1194 * Deregisters the user module.1195 *1196 * @returns VBox status code.1197 * @param pVtgHdr The VTG header.1198 */1199 SUPR3DECL(int) SUPR3TracerDeregisterModule(struct VTGOBJHDR *pVtgHdr);1200 1201 /**1202 * Fire the probe.1203 *1204 * @param pVtgProbeLoc The probe location record.1205 * @param uArg0 Raw probe argument 0.1206 * @param uArg1 Raw probe argument 1.1207 * @param uArg2 Raw probe argument 2.1208 * @param uArg3 Raw probe argument 3.1209 * @param uArg4 Raw probe argument 4.1210 */1211 SUPDECL(void) SUPTracerFireProbe(struct VTGPROBELOC *pVtgProbeLoc, uintptr_t uArg0, uintptr_t uArg1, uintptr_t uArg2,1212 uintptr_t uArg3, uintptr_t uArg4);1213 /** @} */1214 #endif /* IN_RING3 */1215 1216 /** @name User mode module flags (SUPR3TracerRegisterModule & SUP_IOCTL_TRACER_UMOD_REG).1217 * @{ */1218 /** Executable image. */1219 #define SUP_TRACER_UMOD_FLAGS_EXE UINT32_C(1)1220 /** Shared library (DLL, DYLIB, SO, etc). */1221 #define SUP_TRACER_UMOD_FLAGS_SHARED UINT32_C(2)1222 /** Image type mask. */1223 #define SUP_TRACER_UMOD_FLAGS_TYPE_MASK UINT32_C(3)1224 /** @} */1225 1226 1227 #ifdef IN_RING01228 /** @defgroup grp_sup_r0 SUP Host Context Ring-0 API1229 * @ingroup grp_sup1230 * @{1231 */1232 1233 /**1234 * Security objectype.1235 */1236 typedef enum SUPDRVOBJTYPE1237 {1238 /** The usual invalid object. */1239 SUPDRVOBJTYPE_INVALID = 0,1240 /** A Virtual Machine instance. */1241 SUPDRVOBJTYPE_VM,1242 /** Internal network. */1243 SUPDRVOBJTYPE_INTERNAL_NETWORK,1244 /** Internal network interface. */1245 SUPDRVOBJTYPE_INTERNAL_NETWORK_INTERFACE,1246 /** Single release event semaphore. */1247 SUPDRVOBJTYPE_SEM_EVENT,1248 /** Multiple release event semaphore. */1249 SUPDRVOBJTYPE_SEM_EVENT_MULTI,1250 /** Raw PCI device. */1251 SUPDRVOBJTYPE_RAW_PCI_DEVICE,1252 /** The first invalid object type in this end. */1253 SUPDRVOBJTYPE_END,1254 /** The usual 32-bit type size hack. */1255 SUPDRVOBJTYPE_32_BIT_HACK = 0x7ffffff1256 } SUPDRVOBJTYPE;1257 1258 /**1259 * Object destructor callback.1260 * This is called for reference counted objectes when the count reaches 0.1261 *1262 * @param pvObj The object pointer.1263 * @param pvUser1 The first user argument.1264 * @param pvUser2 The second user argument.1265 */1266 typedef DECLCALLBACK(void) FNSUPDRVDESTRUCTOR(void *pvObj, void *pvUser1, void *pvUser2);1267 /** Pointer to a FNSUPDRVDESTRUCTOR(). */1268 typedef FNSUPDRVDESTRUCTOR *PFNSUPDRVDESTRUCTOR;1269 1270 SUPR0DECL(void *) SUPR0ObjRegister(PSUPDRVSESSION pSession, SUPDRVOBJTYPE enmType, PFNSUPDRVDESTRUCTOR pfnDestructor, void *pvUser1, void *pvUser2);1271 SUPR0DECL(int) SUPR0ObjAddRef(void *pvObj, PSUPDRVSESSION pSession);1272 SUPR0DECL(int) SUPR0ObjAddRefEx(void *pvObj, PSUPDRVSESSION pSession, bool fNoBlocking);1273 SUPR0DECL(int) SUPR0ObjRelease(void *pvObj, PSUPDRVSESSION pSession);1274 SUPR0DECL(int) SUPR0ObjVerifyAccess(void *pvObj, PSUPDRVSESSION pSession, const char *pszObjName);1275 1276 SUPR0DECL(int) SUPR0LockMem(PSUPDRVSESSION pSession, RTR3PTR pvR3, uint32_t cPages, PRTHCPHYS paPages);1277 SUPR0DECL(int) SUPR0UnlockMem(PSUPDRVSESSION pSession, RTR3PTR pvR3);1278 SUPR0DECL(int) SUPR0ContAlloc(PSUPDRVSESSION pSession, uint32_t cPages, PRTR0PTR ppvR0, PRTR3PTR ppvR3, PRTHCPHYS pHCPhys);1279 SUPR0DECL(int) SUPR0ContFree(PSUPDRVSESSION pSession, RTHCUINTPTR uPtr);1280 SUPR0DECL(int) SUPR0LowAlloc(PSUPDRVSESSION pSession, uint32_t cPages, PRTR0PTR ppvR0, PRTR3PTR ppvR3, PRTHCPHYS paPages);1281 SUPR0DECL(int) SUPR0LowFree(PSUPDRVSESSION pSession, RTHCUINTPTR uPtr);1282 SUPR0DECL(int) SUPR0MemAlloc(PSUPDRVSESSION pSession, uint32_t cb, PRTR0PTR ppvR0, PRTR3PTR ppvR3);1283 SUPR0DECL(int) SUPR0MemGetPhys(PSUPDRVSESSION pSession, RTHCUINTPTR uPtr, PSUPPAGE paPages);1284 SUPR0DECL(int) SUPR0MemFree(PSUPDRVSESSION pSession, RTHCUINTPTR uPtr);1285 SUPR0DECL(int) SUPR0PageAllocEx(PSUPDRVSESSION pSession, uint32_t cPages, uint32_t fFlags, PRTR3PTR ppvR3, PRTR0PTR ppvR0, PRTHCPHYS paPages);1286 SUPR0DECL(int) SUPR0PageMapKernel(PSUPDRVSESSION pSession, RTR3PTR pvR3, uint32_t offSub, uint32_t cbSub, uint32_t fFlags, PRTR0PTR ppvR0);1287 SUPR0DECL(int) SUPR0PageProtect(PSUPDRVSESSION pSession, RTR3PTR pvR3, RTR0PTR pvR0, uint32_t offSub, uint32_t cbSub, uint32_t fProt);1288 SUPR0DECL(int) SUPR0PageFree(PSUPDRVSESSION pSession, RTR3PTR pvR3);1289 SUPR0DECL(int) SUPR0GipMap(PSUPDRVSESSION pSession, PRTR3PTR ppGipR3, PRTHCPHYS pHCPhysGip);1290 SUPR0DECL(int) SUPR0QueryVTCaps(PSUPDRVSESSION pSession, uint32_t *pfCaps);1291 SUPR0DECL(int) SUPR0GipUnmap(PSUPDRVSESSION pSession);1292 SUPR0DECL(int) SUPR0Printf(const char *pszFormat, ...);1293 SUPR0DECL(SUPPAGINGMODE) SUPR0GetPagingMode(void);1294 SUPR0DECL(int) SUPR0EnableVTx(bool fEnable);1295 1296 /** @name Absolute symbols1297 * Take the address of these, don't try call them.1298 * @{ */1299 SUPR0DECL(void) SUPR0AbsIs64bit(void);1300 SUPR0DECL(void) SUPR0Abs64bitKernelCS(void);1301 SUPR0DECL(void) SUPR0Abs64bitKernelSS(void);1302 SUPR0DECL(void) SUPR0Abs64bitKernelDS(void);1303 SUPR0DECL(void) SUPR0AbsKernelCS(void);1304 SUPR0DECL(void) SUPR0AbsKernelSS(void);1305 SUPR0DECL(void) SUPR0AbsKernelDS(void);1306 SUPR0DECL(void) SUPR0AbsKernelES(void);1307 SUPR0DECL(void) SUPR0AbsKernelFS(void);1308 SUPR0DECL(void) SUPR0AbsKernelGS(void);1309 /** @} */1310 1311 /**1312 * Support driver component factory.1313 *1314 * Component factories are registered by drivers that provides services1315 * such as the host network interface filtering and access to the host1316 * TCP/IP stack.1317 *1318 * @remark Module dependencies and making sure that a component doesn't1319 * get unloaded while in use, is the sole responsibility of the1320 * driver/kext/whatever implementing the component.1321 */1322 typedef struct SUPDRVFACTORY1323 {1324 /** The (unique) name of the component factory. */1325 char szName[56];1326 /**1327 * Queries a factory interface.1328 *1329 * The factory interface is specific to each component and will be be1330 * found in the header(s) for the component alongside its UUID.1331 *1332 * @returns Pointer to the factory interfaces on success, NULL on failure.1333 *1334 * @param pSupDrvFactory Pointer to this structure.1335 * @param pSession The SUPDRV session making the query.1336 * @param pszInterfaceUuid The UUID of the factory interface.1337 */1338 DECLR0CALLBACKMEMBER(void *, pfnQueryFactoryInterface,(struct SUPDRVFACTORY const *pSupDrvFactory, PSUPDRVSESSION pSession, const char *pszInterfaceUuid));1339 } SUPDRVFACTORY;1340 /** Pointer to a support driver factory. */1341 typedef SUPDRVFACTORY *PSUPDRVFACTORY;1342 /** Pointer to a const support driver factory. */1343 typedef SUPDRVFACTORY const *PCSUPDRVFACTORY;1344 1345 SUPR0DECL(int) SUPR0ComponentRegisterFactory(PSUPDRVSESSION pSession, PCSUPDRVFACTORY pFactory);1346 SUPR0DECL(int) SUPR0ComponentDeregisterFactory(PSUPDRVSESSION pSession, PCSUPDRVFACTORY pFactory);1347 SUPR0DECL(int) SUPR0ComponentQueryFactory(PSUPDRVSESSION pSession, const char *pszName, const char *pszInterfaceUuid, void **ppvFactoryIf);1348 1349 1350 /** @name Tracing1351 * @{ */1352 1353 /**1354 * Tracer data associated with a provider.1355 */1356 typedef union SUPDRVTRACERDATA1357 {1358 /** Generic */1359 uint64_t au64[2];1360 1361 /** DTrace data. */1362 struct1363 {1364 /** Provider ID. */1365 uintptr_t idProvider;1366 /** The number of trace points provided. */1367 uint32_t volatile cProvidedProbes;1368 /** Whether we've invalidated this bugger. */1369 bool fZombie;1370 } DTrace;1371 } SUPDRVTRACERDATA;1372 /** Pointer to the tracer data associated with a provider. */1373 typedef SUPDRVTRACERDATA *PSUPDRVTRACERDATA;1374 1375 /**1376 * Support driver tracepoint provider core.1377 */1378 typedef struct SUPDRVVDTPROVIDERCORE1379 {1380 /** The tracer data member. */1381 SUPDRVTRACERDATA TracerData;1382 /** The provider descriptor. */1383 struct VTGDESCPROVIDER *pDesc;1384 /** The VTG header. */1385 struct VTGOBJHDR *pHdr;1386 /** Pointer to the provider name (a copy that's always available). */1387 const char *pszName;1388 /** Pointer to the module name. */1389 const char *pszModName;1390 } SUPDRVVDTPROVIDERCORE;1391 /** Pointer to a tracepoint provider core structure. */1392 typedef SUPDRVVDTPROVIDERCORE *PSUPDRVVDTPROVIDERCORE;1393 1394 93 1395 94 /** … … 1452 151 uint64_t r13; 1453 152 uint64_t r14; 153 uint64_t r15; 1454 154 } Amd64; 1455 155 } u; 1456 156 } SUPDRVTRACERUSRCTX; 1457 157 /** Pointer to the usermode probe context information. */ 158 typedef SUPDRVTRACERUSRCTX *PSUPDRVTRACERUSRCTX; 159 /** Pointer to the const usermode probe context information. */ 1458 160 typedef SUPDRVTRACERUSRCTX const *PCSUPDRVTRACERUSRCTX; 1459 161 162 /** 163 * The CPU state. 164 */ 165 typedef enum SUPGIPCPUSTATE 166 { 167 /** Invalid CPU state / unused CPU entry. */ 168 SUPGIPCPUSTATE_INVALID = 0, 169 /** The CPU is not present. */ 170 SUPGIPCPUSTATE_ABSENT, 171 /** The CPU is offline. */ 172 SUPGIPCPUSTATE_OFFLINE, 173 /** The CPU is online. */ 174 SUPGIPCPUSTATE_ONLINE, 175 /** Force 32-bit enum type. */ 176 SUPGIPCPUSTATE_32_BIT_HACK = 0x7fffffff 177 } SUPGIPCPUSTATE; 178 179 /** 180 * Per CPU data. 181 */ 182 typedef struct SUPGIPCPU 183 { 184 /** Update transaction number. 185 * This number is incremented at the start and end of each update. It follows 186 * thusly that odd numbers indicates update in progress, while even numbers 187 * indicate stable data. Use this to make sure that the data items you fetch 188 * are consistent. */ 189 volatile uint32_t u32TransactionId; 190 /** The interval in TSC ticks between two NanoTS updates. 191 * This is the average interval over the last 2, 4 or 8 updates + a little slack. 192 * The slack makes the time go a tiny tiny bit slower and extends the interval enough 193 * to avoid ending up with too many 1ns increments. */ 194 volatile uint32_t u32UpdateIntervalTSC; 195 /** Current nanosecond timestamp. */ 196 volatile uint64_t u64NanoTS; 197 /** The TSC at the time of u64NanoTS. */ 198 volatile uint64_t u64TSC; 199 /** Current CPU Frequency. */ 200 volatile uint64_t u64CpuHz; 201 /** Number of errors during updating. 202 * Typical errors are under/overflows. */ 203 volatile uint32_t cErrors; 204 /** Index of the head item in au32TSCHistory. */ 205 volatile uint32_t iTSCHistoryHead; 206 /** Array of recent TSC interval deltas. 207 * The most recent item is at index iTSCHistoryHead. 208 * This history is used to calculate u32UpdateIntervalTSC. 209 */ 210 volatile uint32_t au32TSCHistory[8]; 211 /** The interval between the last two NanoTS updates. (experiment for now) */ 212 volatile uint32_t u32PrevUpdateIntervalNS; 213 214 /** Reserved for future per processor data. */ 215 volatile uint32_t au32Reserved[5+5]; 216 217 /** @todo Add topology/NUMA info. */ 218 /** The CPU state. */ 219 SUPGIPCPUSTATE volatile enmState; 220 /** The host CPU ID of this CPU (the SUPGIPCPU is indexed by APIC ID). */ 221 RTCPUID idCpu; 222 /** The CPU set index of this CPU. */ 223 int16_t iCpuSet; 224 /** The APIC ID of this CPU. */ 225 uint16_t idApic; 226 } SUPGIPCPU; 227 AssertCompileSize(RTCPUID, 4); 228 AssertCompileSize(SUPGIPCPU, 128); 229 AssertCompileMemberAlignment(SUPGIPCPU, u64NanoTS, 8); 230 AssertCompileMemberAlignment(SUPGIPCPU, u64TSC, 8); 231 232 /** Pointer to per cpu data. 233 * @remark there is no const version of this typedef, see g_pSUPGlobalInfoPage for details. */ 234 typedef SUPGIPCPU *PSUPGIPCPU; 235 236 237 238 /** 239 * Global Information Page. 240 * 241 * This page contains useful information and can be mapped into any 242 * process or VM. It can be accessed thru the g_pSUPGlobalInfoPage 243 * pointer when a session is open. 244 */ 245 typedef struct SUPGLOBALINFOPAGE 246 { 247 /** Magic (SUPGLOBALINFOPAGE_MAGIC). */ 248 uint32_t u32Magic; 249 /** The GIP version. */ 250 uint32_t u32Version; 251 252 /** The GIP update mode, see SUPGIPMODE. */ 253 uint32_t u32Mode; 254 /** The number of entries in the CPU table. 255 * (This can work as RTMpGetArraySize().) */ 256 uint16_t cCpus; 257 /** The size of the GIP in pages. */ 258 uint16_t cPages; 259 /** The update frequency of the of the NanoTS. */ 260 volatile uint32_t u32UpdateHz; 261 /** The update interval in nanoseconds. (10^9 / u32UpdateHz) */ 262 volatile uint32_t u32UpdateIntervalNS; 263 /** The timestamp of the last time we update the update frequency. */ 264 volatile uint64_t u64NanoTSLastUpdateHz; 265 /** The set of online CPUs. */ 266 RTCPUSET OnlineCpuSet; 267 /** The set of present CPUs. */ 268 RTCPUSET PresentCpuSet; 269 /** The set of possible CPUs. */ 270 RTCPUSET PossibleCpuSet; 271 /** The number of CPUs that are online. */ 272 volatile uint16_t cOnlineCpus; 273 /** The number of CPUs present in the system. */ 274 volatile uint16_t cPresentCpus; 275 /** The highest number of CPUs possible. */ 276 uint16_t cPossibleCpus; 277 /** The highest number of CPUs possible. */ 278 uint16_t u16Padding0; 279 /** The max CPU ID (RTMpGetMaxCpuId). */ 280 RTCPUID idCpuMax; 281 282 /** Padding / reserved space for future data. */ 283 uint32_t au32Padding1[29]; 284 285 /** Table indexed by the CPU APIC ID to get the CPU table index. */ 286 uint16_t aiCpuFromApicId[256]; 287 /** CPU set index to CPU table index. */ 288 uint16_t aiCpuFromCpuSetIdx[RTCPUSET_MAX_CPUS]; 289 290 /** Array of per-cpu data. 291 * This is index by ApicId via the aiCpuFromApicId table. 292 * 293 * The clock and frequency information is updated for all CPUs if u32Mode 294 * is SUPGIPMODE_ASYNC_TSC, otherwise (SUPGIPMODE_SYNC_TSC) only the first 295 * entry is updated. */ 296 SUPGIPCPU aCPUs[1]; 297 } SUPGLOBALINFOPAGE; 298 AssertCompileMemberAlignment(SUPGLOBALINFOPAGE, u64NanoTSLastUpdateHz, 8); 299 #if defined(RT_ARCH_SPARC) || defined(RT_ARCH_SPARC64) 300 AssertCompileMemberAlignment(SUPGLOBALINFOPAGE, aCPUs, 32); 301 #else 302 AssertCompileMemberAlignment(SUPGLOBALINFOPAGE, aCPUs, 256); 303 #endif 304 305 /** Pointer to the global info page. 306 * @remark there is no const version of this typedef, see g_pSUPGlobalInfoPage for details. */ 307 typedef SUPGLOBALINFOPAGE *PSUPGLOBALINFOPAGE; 308 309 310 /** The value of the SUPGLOBALINFOPAGE::u32Magic field. (Soryo Fuyumi) */ 311 #define SUPGLOBALINFOPAGE_MAGIC 0x19590106 312 /** The GIP version. 313 * Upper 16 bits is the major version. Major version is only changed with 314 * incompatible changes in the GIP. */ 315 #define SUPGLOBALINFOPAGE_VERSION 0x00030000 316 317 /** 318 * SUPGLOBALINFOPAGE::u32Mode values. 319 */ 320 typedef enum SUPGIPMODE 321 { 322 /** The usual invalid null entry. */ 323 SUPGIPMODE_INVALID = 0, 324 /** The TSC of the cores and cpus in the system is in sync. */ 325 SUPGIPMODE_SYNC_TSC, 326 /** Each core has it's own TSC. */ 327 SUPGIPMODE_ASYNC_TSC, 328 /** The usual 32-bit hack. */ 329 SUPGIPMODE_32BIT_HACK = 0x7fffffff 330 } SUPGIPMODE; 331 332 /** Pointer to the Global Information Page. 333 * 334 * This pointer is valid as long as SUPLib has a open session. Anyone using 335 * the page must treat this pointer as highly volatile and not trust it beyond 336 * one transaction. 337 * 338 * @remark The GIP page is read-only to everyone but the support driver and 339 * is actually mapped read only everywhere but in ring-0. However 340 * it is not marked 'const' as this might confuse compilers into 341 * thinking that values doesn't change even if members are marked 342 * as volatile. Thus, there is no PCSUPGLOBALINFOPAGE type. 343 */ 344 #if defined(IN_SUP_R0) || defined(IN_SUP_R3) || defined(IN_SUP_RC) 345 extern DECLEXPORT(PSUPGLOBALINFOPAGE) g_pSUPGlobalInfoPage; 346 347 #elif !defined(IN_RING0) || defined(RT_OS_WINDOWS) || defined(RT_OS_SOLARIS) 348 extern DECLIMPORT(PSUPGLOBALINFOPAGE) g_pSUPGlobalInfoPage; 349 350 #else /* IN_RING0 && !RT_OS_WINDOWS */ 351 # if !defined(__GNUC__) || defined(RT_OS_DARWIN) || !defined(RT_ARCH_AMD64) 352 # define g_pSUPGlobalInfoPage (&g_SUPGlobalInfoPage) 353 # else 354 # define g_pSUPGlobalInfoPage (SUPGetGIPHlp()) 355 /** Workaround for ELF+GCC problem on 64-bit hosts. 356 * (GCC emits a mov with a R_X86_64_32 reloc, we need R_X86_64_64.) */ 357 DECLINLINE(PSUPGLOBALINFOPAGE) SUPGetGIPHlp(void) 358 { 359 PSUPGLOBALINFOPAGE pGIP; 360 __asm__ __volatile__ ("movabs $g_SUPGlobalInfoPage,%0\n\t" 361 : "=a" (pGIP)); 362 return pGIP; 363 } 364 # endif 365 /** The GIP. 366 * We save a level of indirection by exporting the GIP instead of a variable 367 * pointing to it. */ 368 extern DECLIMPORT(SUPGLOBALINFOPAGE) g_SUPGlobalInfoPage; 369 #endif 370 371 /** 372 * Gets the GIP pointer. 373 * 374 * @returns Pointer to the GIP or NULL. 375 */ 376 SUPDECL(PSUPGLOBALINFOPAGE) SUPGetGIP(void); 377 378 #ifdef ___iprt_asm_amd64_x86_h 379 /** 380 * Gets the TSC frequency of the calling CPU. 381 * 382 * @returns TSC frequency, UINT64_MAX on failure. 383 * @param pGip The GIP pointer. 384 */ 385 DECLINLINE(uint64_t) SUPGetCpuHzFromGIP(PSUPGLOBALINFOPAGE pGip) 386 { 387 unsigned iCpu; 388 389 if (RT_UNLIKELY(!pGip || pGip->u32Magic != SUPGLOBALINFOPAGE_MAGIC)) 390 return UINT64_MAX; 391 392 if (pGip->u32Mode != SUPGIPMODE_ASYNC_TSC) 393 iCpu = 0; 394 else 395 { 396 iCpu = pGip->aiCpuFromApicId[ASMGetApicId()]; 397 if (iCpu >= pGip->cCpus) 398 return UINT64_MAX; 399 } 400 401 return pGip->aCPUs[iCpu].u64CpuHz; 402 } 403 #endif 404 405 /** 406 * Request for generic VMMR0Entry calls. 407 */ 408 typedef struct SUPVMMR0REQHDR 409 { 410 /** The magic. (SUPVMMR0REQHDR_MAGIC) */ 411 uint32_t u32Magic; 412 /** The size of the request. */ 413 uint32_t cbReq; 414 } SUPVMMR0REQHDR; 415 /** Pointer to a ring-0 request header. */ 416 typedef SUPVMMR0REQHDR *PSUPVMMR0REQHDR; 417 /** the SUPVMMR0REQHDR::u32Magic value (Ethan Iverson - The Bad Plus). */ 418 #define SUPVMMR0REQHDR_MAGIC UINT32_C(0x19730211) 419 420 421 /** For the fast ioctl path. 422 * @{ 423 */ 424 /** @see VMMR0_DO_RAW_RUN. */ 425 #define SUP_VMMR0_DO_RAW_RUN 0 426 /** @see VMMR0_DO_HWACC_RUN. */ 427 #define SUP_VMMR0_DO_HWACC_RUN 1 428 /** @see VMMR0_DO_NOP */ 429 #define SUP_VMMR0_DO_NOP 2 430 /** @} */ 431 432 /** SUPR3QueryVTCaps capability flags 433 * @{ 434 */ 435 #define SUPVTCAPS_AMD_V RT_BIT(0) 436 #define SUPVTCAPS_VT_X RT_BIT(1) 437 #define SUPVTCAPS_NESTED_PAGING RT_BIT(2) 438 /** @} */ 439 440 /** 441 * Request for generic FNSUPR0SERVICEREQHANDLER calls. 442 */ 443 typedef struct SUPR0SERVICEREQHDR 444 { 445 /** The magic. (SUPR0SERVICEREQHDR_MAGIC) */ 446 uint32_t u32Magic; 447 /** The size of the request. */ 448 uint32_t cbReq; 449 } SUPR0SERVICEREQHDR; 450 /** Pointer to a ring-0 service request header. */ 451 typedef SUPR0SERVICEREQHDR *PSUPR0SERVICEREQHDR; 452 /** the SUPVMMR0REQHDR::u32Magic value (Esbjoern Svensson - E.S.P.). */ 453 #define SUPR0SERVICEREQHDR_MAGIC UINT32_C(0x19640416) 454 455 456 /** Event semaphore handle. Ring-0 / ring-3. */ 457 typedef R0PTRTYPE(struct SUPSEMEVENTHANDLE *) SUPSEMEVENT; 458 /** Pointer to an event semaphore handle. */ 459 typedef SUPSEMEVENT *PSUPSEMEVENT; 460 /** Nil event semaphore handle. */ 461 #define NIL_SUPSEMEVENT ((SUPSEMEVENT)0) 462 463 /** 464 * Creates a single release event semaphore. 465 * 466 * @returns VBox status code. 467 * @param pSession The session handle of the caller. 468 * @param phEvent Where to return the handle to the event semaphore. 469 */ 470 SUPDECL(int) SUPSemEventCreate(PSUPDRVSESSION pSession, PSUPSEMEVENT phEvent); 471 472 /** 473 * Closes a single release event semaphore handle. 474 * 475 * @returns VBox status code. 476 * @retval VINF_OBJECT_DESTROYED if the semaphore was destroyed. 477 * @retval VINF_SUCCESS if the handle was successfully closed but the semaphore 478 * object remained alive because of other references. 479 * 480 * @param pSession The session handle of the caller. 481 * @param hEvent The handle. Nil is quietly ignored. 482 */ 483 SUPDECL(int) SUPSemEventClose(PSUPDRVSESSION pSession, SUPSEMEVENT hEvent); 484 485 /** 486 * Signals a single release event semaphore. 487 * 488 * @returns VBox status code. 489 * @param pSession The session handle of the caller. 490 * @param hEvent The semaphore handle. 491 */ 492 SUPDECL(int) SUPSemEventSignal(PSUPDRVSESSION pSession, SUPSEMEVENT hEvent); 493 494 #ifdef IN_RING0 495 /** 496 * Waits on a single release event semaphore, not interruptible. 497 * 498 * @returns VBox status code. 499 * @param pSession The session handle of the caller. 500 * @param hEvent The semaphore handle. 501 * @param cMillies The number of milliseconds to wait. 502 * @remarks Not available in ring-3. 503 */ 504 SUPDECL(int) SUPSemEventWait(PSUPDRVSESSION pSession, SUPSEMEVENT hEvent, uint32_t cMillies); 505 #endif 506 507 /** 508 * Waits on a single release event semaphore, interruptible. 509 * 510 * @returns VBox status code. 511 * @param pSession The session handle of the caller. 512 * @param hEvent The semaphore handle. 513 * @param cMillies The number of milliseconds to wait. 514 */ 515 SUPDECL(int) SUPSemEventWaitNoResume(PSUPDRVSESSION pSession, SUPSEMEVENT hEvent, uint32_t cMillies); 516 517 /** 518 * Waits on a single release event semaphore, interruptible. 519 * 520 * @returns VBox status code. 521 * @param pSession The session handle of the caller. 522 * @param hEvent The semaphore handle. 523 * @param uNsTimeout The deadline given on the RTTimeNanoTS() clock. 524 */ 525 SUPDECL(int) SUPSemEventWaitNsAbsIntr(PSUPDRVSESSION pSession, SUPSEMEVENT hEvent, uint64_t uNsTimeout); 526 527 /** 528 * Waits on a single release event semaphore, interruptible. 529 * 530 * @returns VBox status code. 531 * @param pSession The session handle of the caller. 532 * @param hEvent The semaphore handle. 533 * @param cNsTimeout The number of nanoseconds to wait. 534 */ 535 SUPDECL(int) SUPSemEventWaitNsRelIntr(PSUPDRVSESSION pSession, SUPSEMEVENT hEvent, uint64_t cNsTimeout); 536 537 /** 538 * Gets the best timeout resolution that SUPSemEventWaitNsAbsIntr and 539 * SUPSemEventWaitNsAbsIntr can do. 540 * 541 * @returns The resolution in nanoseconds. 542 * @param pSession The session handle of the caller. 543 */ 544 SUPDECL(uint32_t) SUPSemEventGetResolution(PSUPDRVSESSION pSession); 545 546 547 /** Multiple release event semaphore handle. Ring-0 / ring-3. */ 548 typedef R0PTRTYPE(struct SUPSEMEVENTMULTIHANDLE *) SUPSEMEVENTMULTI; 549 /** Pointer to an multiple release event semaphore handle. */ 550 typedef SUPSEMEVENTMULTI *PSUPSEMEVENTMULTI; 551 /** Nil multiple release event semaphore handle. */ 552 #define NIL_SUPSEMEVENTMULTI ((SUPSEMEVENTMULTI)0) 553 554 /** 555 * Creates a multiple release event semaphore. 556 * 557 * @returns VBox status code. 558 * @param pSession The session handle of the caller. 559 * @param phEventMulti Where to return the handle to the event semaphore. 560 */ 561 SUPDECL(int) SUPSemEventMultiCreate(PSUPDRVSESSION pSession, PSUPSEMEVENTMULTI phEventMulti); 562 563 /** 564 * Closes a multiple release event semaphore handle. 565 * 566 * @returns VBox status code. 567 * @retval VINF_OBJECT_DESTROYED if the semaphore was destroyed. 568 * @retval VINF_SUCCESS if the handle was successfully closed but the semaphore 569 * object remained alive because of other references. 570 * 571 * @param pSession The session handle of the caller. 572 * @param hEventMulti The handle. Nil is quietly ignored. 573 */ 574 SUPDECL(int) SUPSemEventMultiClose(PSUPDRVSESSION pSession, SUPSEMEVENTMULTI hEventMulti); 575 576 /** 577 * Signals a multiple release event semaphore. 578 * 579 * @returns VBox status code. 580 * @param pSession The session handle of the caller. 581 * @param hEventMulti The semaphore handle. 582 */ 583 SUPDECL(int) SUPSemEventMultiSignal(PSUPDRVSESSION pSession, SUPSEMEVENTMULTI hEventMulti); 584 585 /** 586 * Resets a multiple release event semaphore. 587 * 588 * @returns VBox status code. 589 * @param pSession The session handle of the caller. 590 * @param hEventMulti The semaphore handle. 591 */ 592 SUPDECL(int) SUPSemEventMultiReset(PSUPDRVSESSION pSession, SUPSEMEVENTMULTI hEventMulti); 593 594 #ifdef IN_RING0 595 /** 596 * Waits on a multiple release event semaphore, not interruptible. 597 * 598 * @returns VBox status code. 599 * @param pSession The session handle of the caller. 600 * @param hEventMulti The semaphore handle. 601 * @param cMillies The number of milliseconds to wait. 602 * @remarks Not available in ring-3. 603 */ 604 SUPDECL(int) SUPSemEventMultiWait(PSUPDRVSESSION pSession, SUPSEMEVENTMULTI hEventMulti, uint32_t cMillies); 605 #endif 606 607 /** 608 * Waits on a multiple release event semaphore, interruptible. 609 * 610 * @returns VBox status code. 611 * @param pSession The session handle of the caller. 612 * @param hEventMulti The semaphore handle. 613 * @param cMillies The number of milliseconds to wait. 614 */ 615 SUPDECL(int) SUPSemEventMultiWaitNoResume(PSUPDRVSESSION pSession, SUPSEMEVENTMULTI hEventMulti, uint32_t cMillies); 616 617 /** 618 * Waits on a multiple release event semaphore, interruptible. 619 * 620 * @returns VBox status code. 621 * @param pSession The session handle of the caller. 622 * @param hEventMulti The semaphore handle. 623 * @param uNsTimeout The deadline given on the RTTimeNanoTS() clock. 624 */ 625 SUPDECL(int) SUPSemEventMultiWaitNsAbsIntr(PSUPDRVSESSION pSession, SUPSEMEVENTMULTI hEventMulti, uint64_t uNsTimeout); 626 627 /** 628 * Waits on a multiple release event semaphore, interruptible. 629 * 630 * @returns VBox status code. 631 * @param pSession The session handle of the caller. 632 * @param hEventMulti The semaphore handle. 633 * @param cNsTimeout The number of nanoseconds to wait. 634 */ 635 SUPDECL(int) SUPSemEventMultiWaitNsRelIntr(PSUPDRVSESSION pSession, SUPSEMEVENTMULTI hEventMulti, uint64_t cNsTimeout); 636 637 /** 638 * Gets the best timeout resolution that SUPSemEventMultiWaitNsAbsIntr and 639 * SUPSemEventMultiWaitNsRelIntr can do. 640 * 641 * @returns The resolution in nanoseconds. 642 * @param pSession The session handle of the caller. 643 */ 644 SUPDECL(uint32_t) SUPSemEventMultiGetResolution(PSUPDRVSESSION pSession); 645 646 647 #ifdef IN_RING3 648 649 /** @defgroup grp_sup_r3 SUP Host Context Ring-3 API 650 * @ingroup grp_sup 651 * @{ 652 */ 653 654 /** 655 * Installs the support library. 656 * 657 * @returns VBox status code. 658 */ 659 SUPR3DECL(int) SUPR3Install(void); 660 661 /** 662 * Uninstalls the support library. 663 * 664 * @returns VBox status code. 665 */ 666 SUPR3DECL(int) SUPR3Uninstall(void); 667 668 /** 669 * Trusted main entry point. 670 * 671 * This is exported as "TrustedMain" by the dynamic libraries which contains the 672 * "real" application binary for which the hardened stub is built. The entry 673 * point is invoked upon successful initialization of the support library and 674 * runtime. 675 * 676 * @returns main kind of exit code. 677 * @param argc The argument count. 678 * @param argv The argument vector. 679 * @param envp The environment vector. 680 */ 681 typedef DECLCALLBACK(int) FNSUPTRUSTEDMAIN(int argc, char **argv, char **envp); 682 /** Pointer to FNSUPTRUSTEDMAIN(). */ 683 typedef FNSUPTRUSTEDMAIN *PFNSUPTRUSTEDMAIN; 684 685 /** Which operation failed. */ 686 typedef enum SUPINITOP 687 { 688 /** Invalid. */ 689 kSupInitOp_Invalid = 0, 690 /** Installation integrity error. */ 691 kSupInitOp_Integrity, 692 /** Setuid related. */ 693 kSupInitOp_RootCheck, 694 /** Driver related. */ 695 kSupInitOp_Driver, 696 /** IPRT init related. */ 697 kSupInitOp_IPRT, 698 /** Place holder. */ 699 kSupInitOp_End 700 } SUPINITOP; 701 702 /** 703 * Trusted error entry point, optional. 704 * 705 * This is exported as "TrustedError" by the dynamic libraries which contains 706 * the "real" application binary for which the hardened stub is built. 707 * 708 * @param pszWhere Where the error occurred (function name). 709 * @param enmWhat Which operation went wrong. 710 * @param rc The status code. 711 * @param pszMsgFmt Error message format string. 712 * @param va The message format arguments. 713 */ 714 typedef DECLCALLBACK(void) FNSUPTRUSTEDERROR(const char *pszWhere, SUPINITOP enmWhat, int rc, const char *pszMsgFmt, va_list va); 715 /** Pointer to FNSUPTRUSTEDERROR. */ 716 typedef FNSUPTRUSTEDERROR *PFNSUPTRUSTEDERROR; 717 718 /** 719 * Secure main. 720 * 721 * This is used for the set-user-ID-on-execute binaries on unixy systems 722 * and when using the open-vboxdrv-via-root-service setup on Windows. 723 * 724 * This function will perform the integrity checks of the VirtualBox 725 * installation, open the support driver, open the root service (later), 726 * and load the DLL corresponding to \a pszProgName and execute its main 727 * function. 728 * 729 * @returns Return code appropriate for main(). 730 * 731 * @param pszProgName The program name. This will be used to figure out which 732 * DLL/SO/DYLIB to load and execute. 733 * @param fFlags Flags. 734 * @param argc The argument count. 735 * @param argv The argument vector. 736 * @param envp The environment vector. 737 */ 738 DECLHIDDEN(int) SUPR3HardenedMain(const char *pszProgName, uint32_t fFlags, int argc, char **argv, char **envp); 739 740 /** @name SUPR3SecureMain flags. 741 * @{ */ 742 /** Don't open the device. (Intended for VirtualBox without -startvm.) */ 743 #define SUPSECMAIN_FLAGS_DONT_OPEN_DEV RT_BIT_32(0) 744 /** @} */ 745 746 /** 747 * Initializes the support library. 748 * Each successful call to SUPR3Init() must be countered by a 749 * call to SUPR3Term(false). 750 * 751 * @returns VBox status code. 752 * @param ppSession Where to store the session handle. Defaults to NULL. 753 */ 754 SUPR3DECL(int) SUPR3Init(PSUPDRVSESSION *ppSession); 755 756 /** 757 * Terminates the support library. 758 * 759 * @returns VBox status code. 760 * @param fForced Forced termination. This means to ignore the 761 * init call count and just terminated. 762 */ 763 #ifdef __cplusplus 764 SUPR3DECL(int) SUPR3Term(bool fForced = false); 765 #else 766 SUPR3DECL(int) SUPR3Term(int fForced); 767 #endif 768 769 /** 770 * Sets the ring-0 VM handle for use with fast IOCtls. 771 * 772 * @returns VBox status code. 773 * @param pVMR0 The ring-0 VM handle. 774 * NIL_RTR0PTR can be used to unset the handle when the 775 * VM is about to be destroyed. 776 */ 777 SUPR3DECL(int) SUPR3SetVMForFastIOCtl(PVMR0 pVMR0); 778 779 /** 780 * Calls the HC R0 VMM entry point. 781 * See VMMR0Entry() for more details. 782 * 783 * @returns error code specific to uFunction. 784 * @param pVMR0 Pointer to the Ring-0 (Host Context) mapping of the VM structure. 785 * @param idCpu The virtual CPU ID. 786 * @param uOperation Operation to execute. 787 * @param pvArg Argument. 788 */ 789 SUPR3DECL(int) SUPR3CallVMMR0(PVMR0 pVMR0, VMCPUID idCpu, unsigned uOperation, void *pvArg); 790 791 /** 792 * Variant of SUPR3CallVMMR0, except that this takes the fast ioclt path 793 * regardsless of compile-time defaults. 794 * 795 * @returns VBox status code. 796 * @param pVMR0 The ring-0 VM handle. 797 * @param uOperation The operation; only the SUP_VMMR0_DO_* ones are valid. 798 * @param idCpu The virtual CPU ID. 799 */ 800 SUPR3DECL(int) SUPR3CallVMMR0Fast(PVMR0 pVMR0, unsigned uOperation, VMCPUID idCpu); 801 802 /** 803 * Calls the HC R0 VMM entry point, in a safer but slower manner than 804 * SUPR3CallVMMR0. When entering using this call the R0 components can call 805 * into the host kernel (i.e. use the SUPR0 and RT APIs). 806 * 807 * See VMMR0Entry() for more details. 808 * 809 * @returns error code specific to uFunction. 810 * @param pVMR0 Pointer to the Ring-0 (Host Context) mapping of the VM structure. 811 * @param idCpu The virtual CPU ID. 812 * @param uOperation Operation to execute. 813 * @param u64Arg Constant argument. 814 * @param pReqHdr Pointer to a request header. Optional. 815 * This will be copied in and out of kernel space. There currently is a size 816 * limit on this, just below 4KB. 817 */ 818 SUPR3DECL(int) SUPR3CallVMMR0Ex(PVMR0 pVMR0, VMCPUID idCpu, unsigned uOperation, uint64_t u64Arg, PSUPVMMR0REQHDR pReqHdr); 819 820 /** 821 * Calls a ring-0 service. 822 * 823 * The operation and the request packet is specific to the service. 824 * 825 * @returns error code specific to uFunction. 826 * @param pszService The service name. 827 * @param cchService The length of the service name. 828 * @param uReq The request number. 829 * @param u64Arg Constant argument. 830 * @param pReqHdr Pointer to a request header. Optional. 831 * This will be copied in and out of kernel space. There currently is a size 832 * limit on this, just below 4KB. 833 */ 834 SUPR3DECL(int) SUPR3CallR0Service(const char *pszService, size_t cchService, uint32_t uOperation, uint64_t u64Arg, PSUPR0SERVICEREQHDR pReqHdr); 835 836 /** Which logger. */ 837 typedef enum SUPLOGGER 838 { 839 SUPLOGGER_DEBUG = 1, 840 SUPLOGGER_RELEASE 841 } SUPLOGGER; 842 843 /** 844 * Changes the settings of the specified ring-0 logger. 845 * 846 * @returns VBox status code. 847 * @param enmWhich Which logger. 848 * @param pszFlags The flags settings. 849 * @param pszGroups The groups settings. 850 * @param pszDest The destination specificier. 851 */ 852 SUPR3DECL(int) SUPR3LoggerSettings(SUPLOGGER enmWhich, const char *pszFlags, const char *pszGroups, const char *pszDest); 853 854 /** 855 * Creates a ring-0 logger instance. 856 * 857 * @returns VBox status code. 858 * @param enmWhich Which logger to create. 859 * @param pszFlags The flags settings. 860 * @param pszGroups The groups settings. 861 * @param pszDest The destination specificier. 862 */ 863 SUPR3DECL(int) SUPR3LoggerCreate(SUPLOGGER enmWhich, const char *pszFlags, const char *pszGroups, const char *pszDest); 864 865 /** 866 * Destroys a ring-0 logger instance. 867 * 868 * @returns VBox status code. 869 * @param enmWhich Which logger. 870 */ 871 SUPR3DECL(int) SUPR3LoggerDestroy(SUPLOGGER enmWhich); 872 873 /** 874 * Queries the paging mode of the host OS. 875 * 876 * @returns The paging mode. 877 */ 878 SUPR3DECL(SUPPAGINGMODE) SUPR3GetPagingMode(void); 879 880 /** 881 * Allocate zero-filled pages. 882 * 883 * Use this to allocate a number of pages suitable for seeding / locking. 884 * Call SUPR3PageFree() to free the pages once done with them. 885 * 886 * @returns VBox status. 887 * @param cPages Number of pages to allocate. 888 * @param ppvPages Where to store the base pointer to the allocated pages. 889 */ 890 SUPR3DECL(int) SUPR3PageAlloc(size_t cPages, void **ppvPages); 891 892 /** 893 * Frees pages allocated with SUPR3PageAlloc(). 894 * 895 * @returns VBox status. 896 * @param pvPages Pointer returned by SUPR3PageAlloc(). 897 * @param cPages Number of pages that was allocated. 898 */ 899 SUPR3DECL(int) SUPR3PageFree(void *pvPages, size_t cPages); 900 901 /** 902 * Allocate non-zeroed, locked, pages with user and, optionally, kernel 903 * mappings. 904 * 905 * Use SUPR3PageFreeEx() to free memory allocated with this function. 906 * 907 * @returns VBox status code. 908 * @param cPages The number of pages to allocate. 909 * @param fFlags Flags, reserved. Must be zero. 910 * @param ppvPages Where to store the address of the user mapping. 911 * @param pR0Ptr Where to store the address of the kernel mapping. 912 * NULL if no kernel mapping is desired. 913 * @param paPages Where to store the physical addresses of each page. 914 * Optional. 915 */ 916 SUPR3DECL(int) SUPR3PageAllocEx(size_t cPages, uint32_t fFlags, void **ppvPages, PRTR0PTR pR0Ptr, PSUPPAGE paPages); 917 918 /** 919 * Maps a portion of a ring-3 only allocation into kernel space. 920 * 921 * @returns VBox status code. 922 * 923 * @param pvR3 The address SUPR3PageAllocEx return. 924 * @param off Offset to start mapping at. Must be page aligned. 925 * @param cb Number of bytes to map. Must be page aligned. 926 * @param fFlags Flags, must be zero. 927 * @param pR0Ptr Where to store the address on success. 928 * 929 */ 930 SUPR3DECL(int) SUPR3PageMapKernel(void *pvR3, uint32_t off, uint32_t cb, uint32_t fFlags, PRTR0PTR pR0Ptr); 931 932 /** 933 * Changes the protection of 934 * 935 * @returns VBox status code. 936 * @retval VERR_NOT_SUPPORTED if the OS doesn't allow us to change page level 937 * protection. See also RTR0MemObjProtect. 938 * 939 * @param pvR3 The ring-3 address SUPR3PageAllocEx returned. 940 * @param R0Ptr The ring-0 address SUPR3PageAllocEx returned if it 941 * is desired that the corresponding ring-0 page 942 * mappings should change protection as well. Pass 943 * NIL_RTR0PTR if the ring-0 pages should remain 944 * unaffected. 945 * @param off Offset to start at which to start chagning the page 946 * level protection. Must be page aligned. 947 * @param cb Number of bytes to change. Must be page aligned. 948 * @param fProt The new page level protection, either a combination 949 * of RTMEM_PROT_READ, RTMEM_PROT_WRITE and 950 * RTMEM_PROT_EXEC, or just RTMEM_PROT_NONE. 951 */ 952 SUPR3DECL(int) SUPR3PageProtect(void *pvR3, RTR0PTR R0Ptr, uint32_t off, uint32_t cb, uint32_t fProt); 953 954 /** 955 * Free pages allocated by SUPR3PageAllocEx. 956 * 957 * @returns VBox status code. 958 * @param pvPages The address of the user mapping. 959 * @param cPages The number of pages. 960 */ 961 SUPR3DECL(int) SUPR3PageFreeEx(void *pvPages, size_t cPages); 962 963 /** 964 * Allocated memory with page aligned memory with a contiguous and locked physical 965 * memory backing below 4GB. 966 * 967 * @returns Pointer to the allocated memory (virtual address). 968 * *pHCPhys is set to the physical address of the memory. 969 * If ppvR0 isn't NULL, *ppvR0 is set to the ring-0 mapping. 970 * The returned memory must be freed using SUPR3ContFree(). 971 * @returns NULL on failure. 972 * @param cPages Number of pages to allocate. 973 * @param pR0Ptr Where to store the ring-0 mapping of the allocation. (optional) 974 * @param pHCPhys Where to store the physical address of the memory block. 975 * 976 * @remark This 2nd version of this API exists because we're not able to map the 977 * ring-3 mapping executable on WIN64. This is a serious problem in regard to 978 * the world switchers. 979 */ 980 SUPR3DECL(void *) SUPR3ContAlloc(size_t cPages, PRTR0PTR pR0Ptr, PRTHCPHYS pHCPhys); 981 982 /** 983 * Frees memory allocated with SUPR3ContAlloc(). 984 * 985 * @returns VBox status code. 986 * @param pv Pointer to the memory block which should be freed. 987 * @param cPages Number of pages to be freed. 988 */ 989 SUPR3DECL(int) SUPR3ContFree(void *pv, size_t cPages); 990 991 /** 992 * Allocated non contiguous physical memory below 4GB. 993 * 994 * The memory isn't zeroed. 995 * 996 * @returns VBox status code. 997 * @returns NULL on failure. 998 * @param cPages Number of pages to allocate. 999 * @param ppvPages Where to store the pointer to the allocated memory. 1000 * The pointer stored here on success must be passed to 1001 * SUPR3LowFree when the memory should be released. 1002 * @param ppvPagesR0 Where to store the ring-0 pointer to the allocated memory. optional. 1003 * @param paPages Where to store the physical addresses of the individual pages. 1004 */ 1005 SUPR3DECL(int) SUPR3LowAlloc(size_t cPages, void **ppvPages, PRTR0PTR ppvPagesR0, PSUPPAGE paPages); 1006 1007 /** 1008 * Frees memory allocated with SUPR3LowAlloc(). 1009 * 1010 * @returns VBox status code. 1011 * @param pv Pointer to the memory block which should be freed. 1012 * @param cPages Number of pages that was allocated. 1013 */ 1014 SUPR3DECL(int) SUPR3LowFree(void *pv, size_t cPages); 1015 1016 /** 1017 * Load a module into R0 HC. 1018 * 1019 * This will verify the file integrity in a similar manner as 1020 * SUPR3HardenedVerifyFile before loading it. 1021 * 1022 * @returns VBox status code. 1023 * @param pszFilename The path to the image file. 1024 * @param pszModule The module name. Max 32 bytes. 1025 * @param ppvImageBase Where to store the image address. 1026 * @param pErrInfo Where to return extended error information. 1027 * Optional. 1028 */ 1029 SUPR3DECL(int) SUPR3LoadModule(const char *pszFilename, const char *pszModule, void **ppvImageBase, PRTERRINFO pErrInfo); 1030 1031 /** 1032 * Load a module into R0 HC. 1033 * 1034 * This will verify the file integrity in a similar manner as 1035 * SUPR3HardenedVerifyFile before loading it. 1036 * 1037 * @returns VBox status code. 1038 * @param pszFilename The path to the image file. 1039 * @param pszModule The module name. Max 32 bytes. 1040 * @param pszSrvReqHandler The name of the service request handler entry 1041 * point. See FNSUPR0SERVICEREQHANDLER. 1042 * @param ppvImageBase Where to store the image address. 1043 */ 1044 SUPR3DECL(int) SUPR3LoadServiceModule(const char *pszFilename, const char *pszModule, 1045 const char *pszSrvReqHandler, void **ppvImageBase); 1046 1047 /** 1048 * Frees a R0 HC module. 1049 * 1050 * @returns VBox status code. 1051 * @param pszModule The module to free. 1052 * @remark This will not actually 'free' the module, there are of course usage counting. 1053 */ 1054 SUPR3DECL(int) SUPR3FreeModule(void *pvImageBase); 1055 1056 /** 1057 * Get the address of a symbol in a ring-0 module. 1058 * 1059 * @returns VBox status code. 1060 * @param pszModule The module name. 1061 * @param pszSymbol Symbol name. If it's value is less than 64k it's treated like a 1062 * ordinal value rather than a string pointer. 1063 * @param ppvValue Where to store the symbol value. 1064 */ 1065 SUPR3DECL(int) SUPR3GetSymbolR0(void *pvImageBase, const char *pszSymbol, void **ppvValue); 1066 1067 /** 1068 * Load R0 HC VMM code. 1069 * 1070 * @returns VBox status code. 1071 * @deprecated Use SUPR3LoadModule(pszFilename, "VMMR0.r0", &pvImageBase) 1072 */ 1073 SUPR3DECL(int) SUPR3LoadVMM(const char *pszFilename); 1074 1075 /** 1076 * Unloads R0 HC VMM code. 1077 * 1078 * @returns VBox status code. 1079 * @deprecated Use SUPR3FreeModule(). 1080 */ 1081 SUPR3DECL(int) SUPR3UnloadVMM(void); 1082 1083 /** 1084 * Get the physical address of the GIP. 1085 * 1086 * @returns VBox status code. 1087 * @param pHCPhys Where to store the physical address of the GIP. 1088 */ 1089 SUPR3DECL(int) SUPR3GipGetPhys(PRTHCPHYS pHCPhys); 1090 1091 /** 1092 * Verifies the integrity of a file, and optionally opens it. 1093 * 1094 * The integrity check is for whether the file is suitable for loading into 1095 * the hypervisor or VM process. The integrity check may include verifying 1096 * the authenticode/elfsign/whatever signature of the file, which can take 1097 * a little while. 1098 * 1099 * @returns VBox status code. On failure it will have printed a LogRel message. 1100 * 1101 * @param pszFilename The file. 1102 * @param pszWhat For the LogRel on failure. 1103 * @param phFile Where to store the handle to the opened file. This is optional, pass NULL 1104 * if the file should not be opened. 1105 * @deprecated Write a new one. 1106 */ 1107 SUPR3DECL(int) SUPR3HardenedVerifyFile(const char *pszFilename, const char *pszWhat, PRTFILE phFile); 1108 1109 /** 1110 * Verifies the integrity of a the current process, including the image 1111 * location and that the invocation was absolute. 1112 * 1113 * This must currently be called after initializing the runtime. The intended 1114 * audience is set-uid-to-root applications, root services and similar. 1115 * 1116 * @returns VBox status code. On failure 1117 * message. 1118 * @param pszArgv0 The first argument to main(). 1119 * @param fInternal Set this to @c true if this is an internal 1120 * VirtualBox application. Otherwise pass @c false. 1121 * @param pErrInfo Where to return extended error information. 1122 */ 1123 SUPR3DECL(int) SUPR3HardenedVerifySelf(const char *pszArgv0, bool fInternal, PRTERRINFO pErrInfo); 1124 1125 /** 1126 * Verifies the integrity of an installation directory. 1127 * 1128 * The integrity check verifies that the directory cannot be tampered with by 1129 * normal users on the system. On Unix this translates to root ownership and 1130 * no symbolic linking. 1131 * 1132 * @returns VBox status code. On failure a message will be stored in @a pszErr. 1133 * 1134 * @param pszDirPath The directory path. 1135 * @param fRecursive Whether the check should be recursive or 1136 * not. When set, all sub-directores will be checked, 1137 * including files (@a fCheckFiles is ignored). 1138 * @param fCheckFiles Whether to apply the same basic integrity check to 1139 * the files in the directory as the directory itself. 1140 * @param pErrInfo Where to return extended error information. 1141 * Optional. 1142 */ 1143 SUPR3DECL(int) SUPR3HardenedVerifyDir(const char *pszDirPath, bool fRecursive, bool fCheckFiles, PRTERRINFO pErrInfo); 1144 1145 /** 1146 * Verifies the integrity of a plug-in module. 1147 * 1148 * This is similar to SUPR3HardenedLdrLoad, except it does not load the module 1149 * and that the module does not have to be shipped with VirtualBox. 1150 * 1151 * @returns VBox status code. On failure a message will be stored in @a pszErr. 1152 * 1153 * @param pszFilename The filename of the plug-in module (nothing can be 1154 * omitted here). 1155 * @param pErrInfo Where to return extended error information. 1156 * Optional. 1157 */ 1158 SUPR3DECL(int) SUPR3HardenedVerifyPlugIn(const char *pszFilename, PRTERRINFO pErrInfo); 1159 1160 /** 1161 * Same as RTLdrLoad() but will verify the files it loads (hardened builds). 1162 * 1163 * Will add dll suffix if missing and try load the file. 1164 * 1165 * @returns iprt status code. 1166 * @param pszFilename Image filename. This must have a path. 1167 * @param phLdrMod Where to store the handle to the loaded module. 1168 * @param fFlags See RTLDRLOAD_FLAGS_XXX. 1169 * @param pErrInfo Where to return extended error information. 1170 * Optional. 1171 */ 1172 SUPR3DECL(int) SUPR3HardenedLdrLoad(const char *pszFilename, PRTLDRMOD phLdrMod, uint32_t fFlags, PRTERRINFO pErrInfo); 1173 1174 /** 1175 * Same as RTLdrLoadAppPriv() but it will verify the files it loads (hardened 1176 * builds). 1177 * 1178 * Will add dll suffix to the file if missing, then look for it in the 1179 * architecture dependent application directory. 1180 * 1181 * @returns iprt status code. 1182 * @param pszFilename Image filename. 1183 * @param phLdrMod Where to store the handle to the loaded module. 1184 * @param fFlags See RTLDRLOAD_FLAGS_XXX. 1185 * @param pErrInfo Where to return extended error information. 1186 * Optional. 1187 */ 1188 SUPR3DECL(int) SUPR3HardenedLdrLoadAppPriv(const char *pszFilename, PRTLDRMOD phLdrMod, uint32_t fFlags, PRTERRINFO pErrInfo); 1189 1190 /** 1191 * Same as RTLdrLoad() but will verify the files it loads (hardened builds). 1192 * 1193 * This differs from SUPR3HardenedLdrLoad() in that it can load modules from 1194 * extension packs and anything else safely installed on the system, provided 1195 * they pass the hardening tests. 1196 * 1197 * @returns iprt status code. 1198 * @param pszFilename The full path to the module, with extension. 1199 * @param phLdrMod Where to store the handle to the loaded module. 1200 * @param pErrInfo Where to return extended error information. 1201 * Optional. 1202 */ 1203 SUPR3DECL(int) SUPR3HardenedLdrLoadPlugIn(const char *pszFilename, PRTLDRMOD phLdrMod, PRTERRINFO pErrInfo); 1204 1205 /** 1206 * Check if the host kernel can run in VMX root mode. 1207 * 1208 * @returns VINF_SUCCESS if supported, error code indicating why if not. 1209 */ 1210 SUPR3DECL(int) SUPR3QueryVTxSupported(void); 1211 1212 /** 1213 * Return VT-x/AMD-V capabilities. 1214 * 1215 * @returns VINF_SUCCESS if supported, error code indicating why if not. 1216 * @param pfCaps Pointer to capability dword (out). 1217 * @todo Intended for main, which means we need to relax the privilege requires 1218 * when accessing certain vboxdrv functions. 1219 */ 1220 SUPR3DECL(int) SUPR3QueryVTCaps(uint32_t *pfCaps); 1221 1222 /** 1223 * Open the tracer. 1224 * 1225 * @returns VBox status code. 1226 * @param uCookie Cookie identifying the tracer we expect to talk to. 1227 * @param uArg Tracer specific open argument. 1228 */ 1229 SUPR3DECL(int) SUPR3TracerOpen(uint32_t uCookie, uintptr_t uArg); 1230 1231 /** 1232 * Closes the tracer. 1233 * 1234 * @returns VBox status code. 1235 */ 1236 SUPR3DECL(int) SUPR3TracerClose(void); 1237 1238 /** 1239 * Perform an I/O request on the tracer. 1240 * 1241 * @returns VBox status. 1242 * @param uCmd The tracer command. 1243 * @param uArg The argument. 1244 * @param piRetVal Where to store the tracer return value. 1245 */ 1246 SUPR3DECL(int) SUPR3TracerIoCtl(uintptr_t uCmd, uintptr_t uArg, int32_t *piRetVal); 1247 1248 /** 1249 * Registers the user module with the tracer. 1250 * 1251 * @returns VBox status code. 1252 * @param hModNative Native module handle. Pass ~(uintptr_t)0 if not 1253 * at hand. 1254 * @param pszModule The module name. 1255 * @param pVtgHdr The VTG header. 1256 * @param uVtgHdrAddr The address to which the VTG header is loaded 1257 * in the relevant execution context. 1258 * @param fFlags See SUP_TRACER_UMOD_FLAGS_XXX 1259 */ 1260 SUPR3DECL(int) SUPR3TracerRegisterModule(uintptr_t hModNative, const char *pszModule, struct VTGOBJHDR *pVtgHdr, 1261 RTUINTPTR uVtgHdrAddr, uint32_t fFlags); 1262 1263 /** 1264 * Deregisters the user module. 1265 * 1266 * @returns VBox status code. 1267 * @param pVtgHdr The VTG header. 1268 */ 1269 SUPR3DECL(int) SUPR3TracerDeregisterModule(struct VTGOBJHDR *pVtgHdr); 1270 1271 /** 1272 * Fire the probe. 1273 * 1274 * @param pVtgProbeLoc The probe location record. 1275 * @param uArg0 Raw probe argument 0. 1276 * @param uArg1 Raw probe argument 1. 1277 * @param uArg2 Raw probe argument 2. 1278 * @param uArg3 Raw probe argument 3. 1279 * @param uArg4 Raw probe argument 4. 1280 */ 1281 SUPDECL(void) SUPTracerFireProbe(struct VTGPROBELOC *pVtgProbeLoc, uintptr_t uArg0, uintptr_t uArg1, uintptr_t uArg2, 1282 uintptr_t uArg3, uintptr_t uArg4); 1283 /** @} */ 1284 #endif /* IN_RING3 */ 1285 1286 /** @name User mode module flags (SUPR3TracerRegisterModule & SUP_IOCTL_TRACER_UMOD_REG). 1287 * @{ */ 1288 /** Executable image. */ 1289 #define SUP_TRACER_UMOD_FLAGS_EXE UINT32_C(1) 1290 /** Shared library (DLL, DYLIB, SO, etc). */ 1291 #define SUP_TRACER_UMOD_FLAGS_SHARED UINT32_C(2) 1292 /** Image type mask. */ 1293 #define SUP_TRACER_UMOD_FLAGS_TYPE_MASK UINT32_C(3) 1294 /** @} */ 1295 1296 1297 #ifdef IN_RING0 1298 /** @defgroup grp_sup_r0 SUP Host Context Ring-0 API 1299 * @ingroup grp_sup 1300 * @{ 1301 */ 1302 1303 /** 1304 * Security objectype. 1305 */ 1306 typedef enum SUPDRVOBJTYPE 1307 { 1308 /** The usual invalid object. */ 1309 SUPDRVOBJTYPE_INVALID = 0, 1310 /** A Virtual Machine instance. */ 1311 SUPDRVOBJTYPE_VM, 1312 /** Internal network. */ 1313 SUPDRVOBJTYPE_INTERNAL_NETWORK, 1314 /** Internal network interface. */ 1315 SUPDRVOBJTYPE_INTERNAL_NETWORK_INTERFACE, 1316 /** Single release event semaphore. */ 1317 SUPDRVOBJTYPE_SEM_EVENT, 1318 /** Multiple release event semaphore. */ 1319 SUPDRVOBJTYPE_SEM_EVENT_MULTI, 1320 /** Raw PCI device. */ 1321 SUPDRVOBJTYPE_RAW_PCI_DEVICE, 1322 /** The first invalid object type in this end. */ 1323 SUPDRVOBJTYPE_END, 1324 /** The usual 32-bit type size hack. */ 1325 SUPDRVOBJTYPE_32_BIT_HACK = 0x7ffffff 1326 } SUPDRVOBJTYPE; 1327 1328 /** 1329 * Object destructor callback. 1330 * This is called for reference counted objectes when the count reaches 0. 1331 * 1332 * @param pvObj The object pointer. 1333 * @param pvUser1 The first user argument. 1334 * @param pvUser2 The second user argument. 1335 */ 1336 typedef DECLCALLBACK(void) FNSUPDRVDESTRUCTOR(void *pvObj, void *pvUser1, void *pvUser2); 1337 /** Pointer to a FNSUPDRVDESTRUCTOR(). */ 1338 typedef FNSUPDRVDESTRUCTOR *PFNSUPDRVDESTRUCTOR; 1339 1340 SUPR0DECL(void *) SUPR0ObjRegister(PSUPDRVSESSION pSession, SUPDRVOBJTYPE enmType, PFNSUPDRVDESTRUCTOR pfnDestructor, void *pvUser1, void *pvUser2); 1341 SUPR0DECL(int) SUPR0ObjAddRef(void *pvObj, PSUPDRVSESSION pSession); 1342 SUPR0DECL(int) SUPR0ObjAddRefEx(void *pvObj, PSUPDRVSESSION pSession, bool fNoBlocking); 1343 SUPR0DECL(int) SUPR0ObjRelease(void *pvObj, PSUPDRVSESSION pSession); 1344 SUPR0DECL(int) SUPR0ObjVerifyAccess(void *pvObj, PSUPDRVSESSION pSession, const char *pszObjName); 1345 1346 SUPR0DECL(int) SUPR0LockMem(PSUPDRVSESSION pSession, RTR3PTR pvR3, uint32_t cPages, PRTHCPHYS paPages); 1347 SUPR0DECL(int) SUPR0UnlockMem(PSUPDRVSESSION pSession, RTR3PTR pvR3); 1348 SUPR0DECL(int) SUPR0ContAlloc(PSUPDRVSESSION pSession, uint32_t cPages, PRTR0PTR ppvR0, PRTR3PTR ppvR3, PRTHCPHYS pHCPhys); 1349 SUPR0DECL(int) SUPR0ContFree(PSUPDRVSESSION pSession, RTHCUINTPTR uPtr); 1350 SUPR0DECL(int) SUPR0LowAlloc(PSUPDRVSESSION pSession, uint32_t cPages, PRTR0PTR ppvR0, PRTR3PTR ppvR3, PRTHCPHYS paPages); 1351 SUPR0DECL(int) SUPR0LowFree(PSUPDRVSESSION pSession, RTHCUINTPTR uPtr); 1352 SUPR0DECL(int) SUPR0MemAlloc(PSUPDRVSESSION pSession, uint32_t cb, PRTR0PTR ppvR0, PRTR3PTR ppvR3); 1353 SUPR0DECL(int) SUPR0MemGetPhys(PSUPDRVSESSION pSession, RTHCUINTPTR uPtr, PSUPPAGE paPages); 1354 SUPR0DECL(int) SUPR0MemFree(PSUPDRVSESSION pSession, RTHCUINTPTR uPtr); 1355 SUPR0DECL(int) SUPR0PageAllocEx(PSUPDRVSESSION pSession, uint32_t cPages, uint32_t fFlags, PRTR3PTR ppvR3, PRTR0PTR ppvR0, PRTHCPHYS paPages); 1356 SUPR0DECL(int) SUPR0PageMapKernel(PSUPDRVSESSION pSession, RTR3PTR pvR3, uint32_t offSub, uint32_t cbSub, uint32_t fFlags, PRTR0PTR ppvR0); 1357 SUPR0DECL(int) SUPR0PageProtect(PSUPDRVSESSION pSession, RTR3PTR pvR3, RTR0PTR pvR0, uint32_t offSub, uint32_t cbSub, uint32_t fProt); 1358 SUPR0DECL(int) SUPR0PageFree(PSUPDRVSESSION pSession, RTR3PTR pvR3); 1359 SUPR0DECL(int) SUPR0GipMap(PSUPDRVSESSION pSession, PRTR3PTR ppGipR3, PRTHCPHYS pHCPhysGip); 1360 SUPR0DECL(int) SUPR0QueryVTCaps(PSUPDRVSESSION pSession, uint32_t *pfCaps); 1361 SUPR0DECL(int) SUPR0GipUnmap(PSUPDRVSESSION pSession); 1362 SUPR0DECL(int) SUPR0Printf(const char *pszFormat, ...); 1363 SUPR0DECL(SUPPAGINGMODE) SUPR0GetPagingMode(void); 1364 SUPR0DECL(int) SUPR0EnableVTx(bool fEnable); 1365 1366 /** @name Absolute symbols 1367 * Take the address of these, don't try call them. 1368 * @{ */ 1369 SUPR0DECL(void) SUPR0AbsIs64bit(void); 1370 SUPR0DECL(void) SUPR0Abs64bitKernelCS(void); 1371 SUPR0DECL(void) SUPR0Abs64bitKernelSS(void); 1372 SUPR0DECL(void) SUPR0Abs64bitKernelDS(void); 1373 SUPR0DECL(void) SUPR0AbsKernelCS(void); 1374 SUPR0DECL(void) SUPR0AbsKernelSS(void); 1375 SUPR0DECL(void) SUPR0AbsKernelDS(void); 1376 SUPR0DECL(void) SUPR0AbsKernelES(void); 1377 SUPR0DECL(void) SUPR0AbsKernelFS(void); 1378 SUPR0DECL(void) SUPR0AbsKernelGS(void); 1379 /** @} */ 1380 1381 /** 1382 * Support driver component factory. 1383 * 1384 * Component factories are registered by drivers that provides services 1385 * such as the host network interface filtering and access to the host 1386 * TCP/IP stack. 1387 * 1388 * @remark Module dependencies and making sure that a component doesn't 1389 * get unloaded while in use, is the sole responsibility of the 1390 * driver/kext/whatever implementing the component. 1391 */ 1392 typedef struct SUPDRVFACTORY 1393 { 1394 /** The (unique) name of the component factory. */ 1395 char szName[56]; 1396 /** 1397 * Queries a factory interface. 1398 * 1399 * The factory interface is specific to each component and will be be 1400 * found in the header(s) for the component alongside its UUID. 1401 * 1402 * @returns Pointer to the factory interfaces on success, NULL on failure. 1403 * 1404 * @param pSupDrvFactory Pointer to this structure. 1405 * @param pSession The SUPDRV session making the query. 1406 * @param pszInterfaceUuid The UUID of the factory interface. 1407 */ 1408 DECLR0CALLBACKMEMBER(void *, pfnQueryFactoryInterface,(struct SUPDRVFACTORY const *pSupDrvFactory, PSUPDRVSESSION pSession, const char *pszInterfaceUuid)); 1409 } SUPDRVFACTORY; 1410 /** Pointer to a support driver factory. */ 1411 typedef SUPDRVFACTORY *PSUPDRVFACTORY; 1412 /** Pointer to a const support driver factory. */ 1413 typedef SUPDRVFACTORY const *PCSUPDRVFACTORY; 1414 1415 SUPR0DECL(int) SUPR0ComponentRegisterFactory(PSUPDRVSESSION pSession, PCSUPDRVFACTORY pFactory); 1416 SUPR0DECL(int) SUPR0ComponentDeregisterFactory(PSUPDRVSESSION pSession, PCSUPDRVFACTORY pFactory); 1417 SUPR0DECL(int) SUPR0ComponentQueryFactory(PSUPDRVSESSION pSession, const char *pszName, const char *pszInterfaceUuid, void **ppvFactoryIf); 1418 1419 1420 /** @name Tracing 1421 * @{ */ 1422 1423 /** 1424 * Tracer data associated with a provider. 1425 */ 1426 typedef union SUPDRVTRACERDATA 1427 { 1428 /** Generic */ 1429 uint64_t au64[2]; 1430 1431 /** DTrace data. */ 1432 struct 1433 { 1434 /** Provider ID. */ 1435 uintptr_t idProvider; 1436 /** The number of trace points provided. */ 1437 uint32_t volatile cProvidedProbes; 1438 /** Whether we've invalidated this bugger. */ 1439 bool fZombie; 1440 } DTrace; 1441 } SUPDRVTRACERDATA; 1442 /** Pointer to the tracer data associated with a provider. */ 1443 typedef SUPDRVTRACERDATA *PSUPDRVTRACERDATA; 1444 1445 /** 1446 * Probe location info for ring-0. 1447 * 1448 * Since we cannot trust user tracepoint modules, we need to duplicate the probe 1449 * ID and enabled flag in ring-0. 1450 */ 1451 typedef struct SUPDRVPROBELOC 1452 { 1453 /** The probe ID. */ 1454 uint32_t idProbe; 1455 /** Whether it's enabled or not. */ 1456 bool fEnabled; 1457 } SUPDRVPROBELOC; 1458 /** Pointer to a ring-0 probe location record. */ 1459 typedef SUPDRVPROBELOC *PSUPDRVPROBELOC; 1460 1461 /** 1462 * Probe info for ring-0. 1463 * 1464 * Since we cannot trust user tracepoint modules, we need to duplicate the 1465 * probe enable count. 1466 */ 1467 typedef struct SUPDRVPROBEINFO 1468 { 1469 /** The number of times this probe has been enabled. */ 1470 uint32_t volatile cEnabled; 1471 } SUPDRVPROBEINFO; 1472 /** Pointer to a ring-0 probe info record. */ 1473 typedef SUPDRVPROBEINFO *PSUPDRVPROBEINFO; 1474 1475 /** 1476 * Support driver tracepoint provider core. 1477 */ 1478 typedef struct SUPDRVVDTPROVIDERCORE 1479 { 1480 /** The tracer data member. */ 1481 SUPDRVTRACERDATA TracerData; 1482 /** Pointer to the provider name (a copy that's always available). */ 1483 const char *pszName; 1484 /** Pointer to the module name (a copy that's always available). */ 1485 const char *pszModName; 1486 1487 /** The provider descriptor. */ 1488 struct VTGDESCPROVIDER *pDesc; 1489 /** The VTG header. */ 1490 struct VTGOBJHDR *pHdr; 1491 1492 /** The size of the entries in the pvProbeLocsEn table. */ 1493 uint8_t cbProbeLocsEn; 1494 /** The actual module bit count (corresponds to cbProbeLocsEn). */ 1495 uint8_t cBits; 1496 /** Set if this is a Umod, otherwise clear.. */ 1497 bool fUmod; 1498 /** Explicit alignment padding (paranoia). */ 1499 uint8_t abAlignment[ARCH_BITS == 32 ? 1 : 5]; 1500 1501 /** The probe locations used for descriptive purposes. */ 1502 struct VTGPROBELOC const *paProbeLocsRO; 1503 /** Pointer to the probe location array where the enable flag needs 1504 * flipping. For kernel providers, this will always be SUPDRVPROBELOC, 1505 * while user providers can either be 32-bit or 64-bit. Use 1506 * cbProbeLocsEn to calculate the address of an entry. */ 1507 void *pvProbeLocsEn; 1508 /** Pointer to the probe array containing the enabled counts. */ 1509 uint32_t *pacProbeEnabled; 1510 1511 /** The ring-0 probe location info for user tracepoint modules. 1512 * This is NULL if fUmod is false. */ 1513 PSUPDRVPROBELOC paR0ProbeLocs; 1514 /** The ring-0 probe info for user tracepoint modules. 1515 * This is NULL if fUmod is false. */ 1516 PSUPDRVPROBEINFO paR0Probes; 1517 1518 } SUPDRVVDTPROVIDERCORE; 1519 /** Pointer to a tracepoint provider core structure. */ 1520 typedef SUPDRVVDTPROVIDERCORE *PSUPDRVVDTPROVIDERCORE; 1460 1521 1461 1522 /** Pointer to a tracer registration record. */
Note:
See TracChangeset
for help on using the changeset viewer.