VirtualBox

Changeset 41117 in vbox for trunk/include/VBox


Ignore:
Timestamp:
May 2, 2012 2:22:29 PM (13 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
77725
Message:

SUP,VBoxTpG,++: Initial implementation of generic user module tracepoints. (disabled)

Location:
trunk/include/VBox
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/VBox/VBoxTpG.h

    r40986 r41117  
    3434RT_C_DECLS_BEGIN
    3535
     36/**
     37 * 32-bit probe location.
     38 */
     39typedef 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;
     47AssertCompileSize(VTGPROBELOC32, 16);
     48/** Pointer to a 32-bit probe location. */
     49typedef VTGPROBELOC32 *PVTGPROBELOC32;
     50/** Pointer to a const 32-bit probe location. */
     51typedef VTGPROBELOC32 const *PCVTGPROBELOC32;
     52
     53/**
     54 * 64-bit probe location.
     55 */
     56typedef 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;
     65AssertCompileSize(VTGPROBELOC64, 32);
     66/** Pointer to a 64-bit probe location. */
     67typedef VTGPROBELOC64 *PVTGPROBELOC64;
     68/** Pointer to a const 64-bit probe location. */
     69typedef VTGPROBELOC64 const *PCVTGPROBELOC64;
     70
    3671
    3772/**
     
    5287/** Pointer to a probe location. */
    5388typedef VTGPROBELOC *PVTGPROBELOC;
     89/** Pointer to a const probe location. */
     90typedef VTGPROBELOC const *PCVTGPROBELOC;
    5491
    5592/** @def VTG_OBJ_SECT
     
    154191/** Pointer to an argument descriptor. */
    155192typedef VTGDESCARG         *PVTGDESCARG;
     193/** Pointer to a const argument descriptor. */
     194typedef VTGDESCARG const *PCVTGDESCARG;
    156195
    157196
     
    168207/** Pointer to a VTG argument list descriptor. */
    169208typedef VTGDESCARGLIST     *PVTGDESCARGLIST;
     209/** Pointer to a const VTG argument list descriptor. */
     210typedef VTGDESCARGLIST const *PCVTGDESCARGLIST;
    170211
    171212
     
    181222    /** The distance from this structure to the VTG object header. */
    182223    int32_t         offObjHdr;
    183     uint32_t        u32User;
    184     uint32_t        u32User2;
    185224} VTGDESCPROBE;
    186 AssertCompileSize(VTGDESCPROBE, 24);
     225AssertCompileSize(VTGDESCPROBE, 16);
    187226/** Pointer to a VTG probe descriptor. */
    188227typedef VTGDESCPROBE       *PVTGDESCPROBE;
     228/** Pointer to a const VTG probe descriptor. */
     229typedef VTGDESCPROBE const *PCVTGDESCPROBE;
    189230
    190231
     
    253294/** Pointer to a VTG provider descriptor. */
    254295typedef VTGDESCPROVIDER    *PVTGDESCPROVIDER;
     296/** Pointer to a const VTG provider descriptor. */
     297typedef VTGDESCPROVIDER const *PCVTGDESCPROVIDER;
    255298
    256299
     
    260303typedef struct VTGOBJHDR
    261304{
     305    /** Magic value (VTGOBJHDR_MAGIC). */
    262306    char                szMagic[24];
     307    /** The bitness of the structures.
     308     * This only affects the probe location pointers and structures. */
    263309    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];
    278384} VTGOBJHDR;
     385AssertCompileSize(VTGOBJHDR, 128);
     386AssertCompileMemberAlignment(VTGOBJHDR, uProbeLocs, 8);
     387AssertCompileMemberAlignment(VTGOBJHDR, uProbeLocsEnd, 8);
    279388/** Pointer to a VTG data object header. */
    280389typedef VTGOBJHDR          *PVTGOBJHDR;
     390/** Pointer to a const VTG data object header. */
     391typedef VTGOBJHDR const    *PCVTGOBJHDR;
    281392
    282393/** 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"
    284395
    285396/** The name of the VTG data object header symbol in the object file. */
  • trunk/include/VBox/err.h

    r40878 r41117  
    16231623/** Bad VTG bit count value.  */
    16241624#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)
    16291631/** Bad VTG header - to low value.  */
    1630 #define VERR_SUPDRV_VTG_BAD_HDR_TOO_FEW             (-3708)
     1632#define VERR_SUPDRV_VTG_BAD_HDR_TOO_FEW             (-3709)
    16311633/** Bad VTG header - to high value.  */
    1632 #define VERR_SUPDRV_VTG_BAD_HDR_TOO_MUCH            (-3709)
     1634#define VERR_SUPDRV_VTG_BAD_HDR_TOO_MUCH            (-3710)
    16331635/** Bad VTG header - size value is not a multiple of the structure size. */
    1634 #define VERR_SUPDRV_VTG_BAD_HDR_NOT_MULTIPLE        (-3710)
     1636#define VERR_SUPDRV_VTG_BAD_HDR_NOT_MULTIPLE        (-3711)
    16351637/** Bad VTG string table offset. */
    1636 #define VERR_SUPDRV_VTG_STRTAB_OFF                  (-3711)
     1638#define VERR_SUPDRV_VTG_STRTAB_OFF                  (-3712)
    16371639/** Bad VTG string. */
    1638 #define VERR_SUPDRV_VTG_BAD_STRING                  (-3712)
     1640#define VERR_SUPDRV_VTG_BAD_STRING                  (-3713)
    16391641/** VTG string is too long. */
    1640 #define VERR_SUPDRV_VTG_STRING_TOO_LONG             (-3713)
     1642#define VERR_SUPDRV_VTG_STRING_TOO_LONG             (-3714)
    16411643/** Bad VTG attribute value. */
    1642 #define VERR_SUPDRV_VTG_BAD_ATTR                    (-3714)
     1644#define VERR_SUPDRV_VTG_BAD_ATTR                    (-3715)
    16431645/** Bad VTG provider descriptor. */
    1644 #define VERR_SUPDRV_VTG_BAD_PROVIDER                (-3715)
     1646#define VERR_SUPDRV_VTG_BAD_PROVIDER                (-3716)
    16451647/** Bad VTG probe descriptor. */
    1646 #define VERR_SUPDRV_VTG_BAD_PROBE                   (-3716)
     1648#define VERR_SUPDRV_VTG_BAD_PROBE                   (-3717)
    16471649/** Bad VTG argument list descriptor. */
    1648 #define VERR_SUPDRV_VTG_BAD_ARGLIST                 (-3717)
     1650#define VERR_SUPDRV_VTG_BAD_ARGLIST                 (-3718)
    16491651/** Bad VTG probe enabled data. */
    1650 #define VERR_SUPDRV_VTG_BAD_PROBE_ENABLED           (-3718)
     1652#define VERR_SUPDRV_VTG_BAD_PROBE_ENABLED           (-3719)
    16511653/** Bad VTG probe location record. */
    1652 #define VERR_SUPDRV_VTG_BAD_PROBE_LOC               (-3719)
     1654#define VERR_SUPDRV_VTG_BAD_PROBE_LOC               (-3720)
    16531655/** The VTG object for the session or image has already been registered. */
    1654 #define VERR_SUPDRV_VTG_ALREADY_REGISTERED          (-3720)
     1656#define VERR_SUPDRV_VTG_ALREADY_REGISTERED          (-3721)
    16551657/** A driver may only register one VTG object per session. */
    1656 #define VERR_SUPDRV_VTG_ONLY_ONCE_PER_SESSION       (-3721)
     1658#define VERR_SUPDRV_VTG_ONLY_ONCE_PER_SESSION       (-3722)
    16571659/** A tracer has already been registered. */
    1658 #define VERR_SUPDRV_TRACER_ALREADY_REGISTERED       (-3722)
     1660#define VERR_SUPDRV_TRACER_ALREADY_REGISTERED       (-3723)
    16591661/** The session has no tracer associated with it. */
    1660 #define VERR_SUPDRV_TRACER_NOT_REGISTERED           (-3723)
     1662#define VERR_SUPDRV_TRACER_NOT_REGISTERED           (-3724)
    16611663/** The tracer has already been opened in this sesssion. */
    1662 #define VERR_SUPDRV_TRACER_ALREADY_OPENED           (-3724)
     1664#define VERR_SUPDRV_TRACER_ALREADY_OPENED           (-3725)
    16631665/** The tracer has not been opened. */
    1664 #define VERR_SUPDRV_TRACER_NOT_OPENED               (-3725)
     1666#define VERR_SUPDRV_TRACER_NOT_OPENED               (-3726)
    16651667/** There is no tracer present. */
    1666 #define VERR_SUPDRV_TRACER_NOT_PRESENT              (-3726)
     1668#define VERR_SUPDRV_TRACER_NOT_PRESENT              (-3727)
    16671669/** The tracer is unloading. */
    1668 #define VERR_SUPDRV_TRACER_UNLOADING                (-3727)
     1670#define VERR_SUPDRV_TRACER_UNLOADING                (-3728)
    16691671/** Another thread in the session is talking to the tracer.  */
    1670 #define VERR_SUPDRV_TRACER_SESSION_BUSY             (-3728)
     1672#define VERR_SUPDRV_TRACER_SESSION_BUSY             (-3729)
    16711673/** The tracer cannot open it self in the same session. */
    1672 #define VERR_SUPDRV_TRACER_CANNOT_OPEN_SELF         (-3729)
     1674#define VERR_SUPDRV_TRACER_CANNOT_OPEN_SELF         (-3730)
    16731675/** 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)
    16751690/** @} */
    16761691
  • trunk/include/VBox/sup.h

    r40983 r41117  
    9191    SUPPAGINGMODE_AMD64_GLOBAL_NX
    9292} SUPPAGINGMODE;
    93 
    94 
    95 /**
    96  * The CPU state.
    97  */
    98 typedef enum SUPGIPCPUSTATE
    99 {
    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 = 0x7fffffff
    110 } SUPGIPCPUSTATE;
    111 
    112 /**
    113  * Per CPU data.
    114  */
    115 typedef struct SUPGIPCPU
    116 {
    117     /** Update transaction number.
    118      * This number is incremented at the start and end of each update. It follows
    119      * thusly that odd numbers indicates update in progress, while even numbers
    120      * indicate stable data. Use this to make sure that the data items you fetch
    121      * 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 enough
    126      * 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 any
    175  * process or VM. It can be accessed thru the g_pSUPGlobalInfoPage
    176  * pointer when a session is open.
    177  */
    178 typedef struct SUPGLOBALINFOPAGE
    179 {
    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 u32Mode
    227      * is SUPGIPMODE_ASYNC_TSC, otherwise (SUPGIPMODE_SYNC_TSC) only the first
    228      * 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 #else
    235 AssertCompileMemberAlignment(SUPGLOBALINFOPAGE, aCPUs, 256);
    236 #endif
    237 
    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     0x19590106
    245 /** The GIP version.
    246  * Upper 16 bits is the major version. Major version is only changed with
    247  * incompatible changes in the GIP. */
    248 #define SUPGLOBALINFOPAGE_VERSION   0x00030000
    249 
    250 /**
    251  * SUPGLOBALINFOPAGE::u32Mode values.
    252  */
    253 typedef enum SUPGIPMODE
    254 {
    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 = 0x7fffffff
    263 } SUPGIPMODE;
    264 
    265 /** Pointer to the Global Information Page.
    266  *
    267  * This pointer is valid as long as SUPLib has a open session. Anyone using
    268  * the page must treat this pointer as highly volatile and not trust it beyond
    269  * one transaction.
    270  *
    271  * @remark  The GIP page is read-only to everyone but the support driver and
    272  *          is actually mapped read only everywhere but in ring-0. However
    273  *          it is not marked 'const' as this might confuse compilers into
    274  *          thinking that values doesn't change even if members are marked
    275  *          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 # else
    287 #  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 # endif
    298 /** The GIP.
    299  * We save a level of indirection by exporting the GIP instead of a variable
    300  * pointing to it. */
    301 extern DECLIMPORT(SUPGLOBALINFOPAGE)    g_SUPGlobalInfoPage;
    302 #endif
    303 
    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_h
    312 /**
    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     else
    328     {
    329         iCpu = pGip->aiCpuFromApicId[ASMGetApicId()];
    330         if (iCpu >= pGip->cCpus)
    331             return UINT64_MAX;
    332     }
    333 
    334     return pGip->aCPUs[iCpu].u64CpuHz;
    335 }
    336 #endif
    337 
    338 /**
    339  * Request for generic VMMR0Entry calls.
    340  */
    341 typedef struct SUPVMMR0REQHDR
    342 {
    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    0
    359 /** @see VMMR0_DO_HWACC_RUN. */
    360 #define SUP_VMMR0_DO_HWACC_RUN  1
    361 /** @see VMMR0_DO_NOP */
    362 #define SUP_VMMR0_DO_NOP        2
    363 /** @} */
    364 
    365 /** SUPR3QueryVTCaps capability flags
    366  * @{
    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 SUPR0SERVICEREQHDR
    377 {
    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 semaphore
    411  *          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_RING0
    428 /**
    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 #endif
    439 
    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 and
    472  * 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 semaphore
    502  *          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_RING0
    528 /**
    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 #endif
    539 
    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 and
    572  * 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_RING3
    581 
    582 /** @defgroup   grp_sup_r3     SUP Host Context Ring-3 API
    583  * @ingroup grp_sup
    584  * @{
    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 the
    605  * "real" application binary for which the hardened stub is built.  The entry
    606  * point is invoked upon successful initialization of the support library and
    607  * 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 SUPINITOP
    620 {
    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_End
    633 } SUPINITOP;
    634 
    635 /**
    636  * Trusted error entry point, optional.
    637  *
    638  * This is exported as "TrustedError" by the dynamic libraries which contains
    639  * 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 systems
    655  * and when using the open-vboxdrv-via-root-service setup on Windows.
    656  *
    657  * This function will perform the integrity checks of the VirtualBox
    658  * installation, open the support driver, open the root service (later),
    659  * and load the DLL corresponding to \a pszProgName and execute its main
    660  * function.
    661  *
    662  * @returns Return code appropriate for main().
    663  *
    664  * @param   pszProgName     The program name. This will be used to figure out which
    665  *                          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 a
    682  * 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 the
    694  *                      init call count and just terminated.
    695  */
    696 #ifdef __cplusplus
    697 SUPR3DECL(int) SUPR3Term(bool fForced = false);
    698 #else
    699 SUPR3DECL(int) SUPR3Term(int fForced);
    700 #endif
    701 
    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 the
    708  *                      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 path
    726  * 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 than
    737  * SUPR3CallVMMR0. When entering using this call the R0 components can call
    738  * 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 size
    749  *                      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 size
    765  *                      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 SUPLOGGER
    771 {
    772     SUPLOGGER_DEBUG = 1,
    773     SUPLOGGER_RELEASE
    774 } 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, kernel
    836  * 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 of
    867  *
    868  * @returns VBox status code.
    869  * @retval  VERR_NOT_SUPPORTED if the OS doesn't allow us to change page level
    870  *          protection. See also RTR0MemObjProtect.
    871  *
    872  * @param   pvR3            The ring-3 address SUPR3PageAllocEx returned.
    873  * @param   R0Ptr           The ring-0 address SUPR3PageAllocEx returned if it
    874  *                          is desired that the corresponding ring-0 page
    875  *                          mappings should change protection as well. Pass
    876  *                          NIL_RTR0PTR if the ring-0 pages should remain
    877  *                          unaffected.
    878  * @param   off             Offset to start at which to start chagning the page
    879  *                          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 combination
    882  *                          of RTMEM_PROT_READ, RTMEM_PROT_WRITE and
    883  *                          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 physical
    898  * 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 the
    910  *          ring-3 mapping executable on WIN64. This is a serious problem in regard to
    911  *          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 to
    934  *                      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 as
    953  * 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 as
    968  * 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 entry
    974  *                              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 a
    995  *                          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 into
    1028  * the hypervisor or VM process. The integrity check may include verifying
    1029  * the authenticode/elfsign/whatever signature of the file, which can take
    1030  * 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 NULL
    1037  *                          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 image
    1044  * location and that the invocation was absolute.
    1045  *
    1046  * This must currently be called after initializing the runtime.  The intended
    1047  * audience is set-uid-to-root applications, root services and similar.
    1048  *
    1049  * @returns VBox status code.  On failure
    1050  *          message.
    1051  * @param   pszArgv0        The first argument to main().
    1052  * @param   fInternal       Set this to @c true if this is an internal
    1053  *                          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 by
    1062  * normal users on the system.  On Unix this translates to root ownership and
    1063  * 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 or
    1069  *                          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 to
    1072  *                          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 module
    1082  * 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 be
    1087  *                          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 (hardened
    1109  * builds).
    1110  *
    1111  * Will add dll suffix to the file if missing, then look for it in the
    1112  * 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 from
    1127  * extension packs and anything else safely installed on the system, provided
    1128  * 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 requires
    1151  *       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 not
    1186  *                              at hand.
    1187  * @param   pszModule           The module name.
    1188  * @param   pVtgHdr             The VTG header.
    1189  * @param   fFlags              See SUP_TRACER_UMOD_FLAGS_XXX
    1190  */
    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_RING0
    1228 /** @defgroup   grp_sup_r0     SUP Host Context Ring-0 API
    1229  * @ingroup grp_sup
    1230  * @{
    1231  */
    1232 
    1233 /**
    1234  * Security objectype.
    1235  */
    1236 typedef enum SUPDRVOBJTYPE
    1237 {
    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 = 0x7ffffff
    1256 } 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 symbols
    1297  * 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 services
    1315  * such as the host network interface filtering and access to the host
    1316  * TCP/IP stack.
    1317  *
    1318  * @remark Module dependencies and making sure that a component doesn't
    1319  *         get unloaded while in use, is the sole responsibility of the
    1320  *         driver/kext/whatever implementing the component.
    1321  */
    1322 typedef struct SUPDRVFACTORY
    1323 {
    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 be
    1330      * 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 Tracing
    1351  * @{ */
    1352 
    1353 /**
    1354  * Tracer data associated with a provider.
    1355  */
    1356 typedef union SUPDRVTRACERDATA
    1357 {
    1358     /** Generic */
    1359     uint64_t                    au64[2];
    1360 
    1361     /** DTrace data. */
    1362     struct
    1363     {
    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 SUPDRVVDTPROVIDERCORE
    1379 {
    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 
    139493
    139594/**
     
    1452151            uint64_t        r13;
    1453152            uint64_t        r14;
     153            uint64_t        r15;
    1454154        } Amd64;
    1455155    } u;
    1456156} SUPDRVTRACERUSRCTX;
    1457157/** Pointer to the usermode probe context information. */
     158typedef SUPDRVTRACERUSRCTX *PSUPDRVTRACERUSRCTX;
     159/** Pointer to the const usermode probe context information. */
    1458160typedef SUPDRVTRACERUSRCTX const *PCSUPDRVTRACERUSRCTX;
    1459161
     162/**
     163 * The CPU state.
     164 */
     165typedef 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 */
     182typedef 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;
     227AssertCompileSize(RTCPUID, 4);
     228AssertCompileSize(SUPGIPCPU, 128);
     229AssertCompileMemberAlignment(SUPGIPCPU, u64NanoTS, 8);
     230AssertCompileMemberAlignment(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. */
     234typedef 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 */
     245typedef 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;
     298AssertCompileMemberAlignment(SUPGLOBALINFOPAGE, u64NanoTSLastUpdateHz, 8);
     299#if defined(RT_ARCH_SPARC) || defined(RT_ARCH_SPARC64)
     300AssertCompileMemberAlignment(SUPGLOBALINFOPAGE, aCPUs, 32);
     301#else
     302AssertCompileMemberAlignment(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. */
     307typedef 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 */
     320typedef 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)
     345extern DECLEXPORT(PSUPGLOBALINFOPAGE)   g_pSUPGlobalInfoPage;
     346
     347#elif !defined(IN_RING0) || defined(RT_OS_WINDOWS) || defined(RT_OS_SOLARIS)
     348extern 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.) */
     357DECLINLINE(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. */
     368extern DECLIMPORT(SUPGLOBALINFOPAGE)    g_SUPGlobalInfoPage;
     369#endif
     370
     371/**
     372 * Gets the GIP pointer.
     373 *
     374 * @returns Pointer to the GIP or NULL.
     375 */
     376SUPDECL(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 */
     385DECLINLINE(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 */
     408typedef 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. */
     416typedef 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 */
     443typedef 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. */
     451typedef 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. */
     457typedef R0PTRTYPE(struct SUPSEMEVENTHANDLE *) SUPSEMEVENT;
     458/** Pointer to an event semaphore handle. */
     459typedef 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 */
     470SUPDECL(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 */
     483SUPDECL(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 */
     492SUPDECL(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 */
     504SUPDECL(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 */
     515SUPDECL(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 */
     525SUPDECL(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 */
     535SUPDECL(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 */
     544SUPDECL(uint32_t) SUPSemEventGetResolution(PSUPDRVSESSION pSession);
     545
     546
     547/** Multiple release event semaphore handle. Ring-0 / ring-3. */
     548typedef R0PTRTYPE(struct SUPSEMEVENTMULTIHANDLE *)  SUPSEMEVENTMULTI;
     549/** Pointer to an multiple release event semaphore handle. */
     550typedef 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 */
     561SUPDECL(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 */
     574SUPDECL(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 */
     583SUPDECL(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 */
     592SUPDECL(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 */
     604SUPDECL(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 */
     615SUPDECL(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 */
     625SUPDECL(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 */
     635SUPDECL(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 */
     644SUPDECL(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 */
     659SUPR3DECL(int) SUPR3Install(void);
     660
     661/**
     662 * Uninstalls the support library.
     663 *
     664 * @returns VBox status code.
     665 */
     666SUPR3DECL(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 */
     681typedef DECLCALLBACK(int) FNSUPTRUSTEDMAIN(int argc, char **argv, char **envp);
     682/** Pointer to FNSUPTRUSTEDMAIN(). */
     683typedef FNSUPTRUSTEDMAIN *PFNSUPTRUSTEDMAIN;
     684
     685/** Which operation failed. */
     686typedef 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 */
     714typedef DECLCALLBACK(void) FNSUPTRUSTEDERROR(const char *pszWhere, SUPINITOP enmWhat, int rc, const char *pszMsgFmt, va_list va);
     715/** Pointer to FNSUPTRUSTEDERROR. */
     716typedef 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 */
     738DECLHIDDEN(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 */
     754SUPR3DECL(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
     764SUPR3DECL(int) SUPR3Term(bool fForced = false);
     765#else
     766SUPR3DECL(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 */
     777SUPR3DECL(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 */
     789SUPR3DECL(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 */
     800SUPR3DECL(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 */
     818SUPR3DECL(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 */
     834SUPR3DECL(int) SUPR3CallR0Service(const char *pszService, size_t cchService, uint32_t uOperation, uint64_t u64Arg, PSUPR0SERVICEREQHDR pReqHdr);
     835
     836/** Which logger. */
     837typedef 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 */
     852SUPR3DECL(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 */
     863SUPR3DECL(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 */
     871SUPR3DECL(int) SUPR3LoggerDestroy(SUPLOGGER enmWhich);
     872
     873/**
     874 * Queries the paging mode of the host OS.
     875 *
     876 * @returns The paging mode.
     877 */
     878SUPR3DECL(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 */
     890SUPR3DECL(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 */
     899SUPR3DECL(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 */
     916SUPR3DECL(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 */
     930SUPR3DECL(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 */
     952SUPR3DECL(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 */
     961SUPR3DECL(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 */
     980SUPR3DECL(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 */
     989SUPR3DECL(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 */
     1005SUPR3DECL(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 */
     1014SUPR3DECL(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 */
     1029SUPR3DECL(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 */
     1044SUPR3DECL(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 */
     1054SUPR3DECL(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 */
     1065SUPR3DECL(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 */
     1073SUPR3DECL(int) SUPR3LoadVMM(const char *pszFilename);
     1074
     1075/**
     1076 * Unloads R0 HC VMM code.
     1077 *
     1078 * @returns VBox status code.
     1079 * @deprecated  Use SUPR3FreeModule().
     1080 */
     1081SUPR3DECL(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 */
     1089SUPR3DECL(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 */
     1107SUPR3DECL(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 */
     1123SUPR3DECL(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 */
     1143SUPR3DECL(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 */
     1158SUPR3DECL(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 */
     1172SUPR3DECL(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 */
     1188SUPR3DECL(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 */
     1203SUPR3DECL(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 */
     1210SUPR3DECL(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 */
     1220SUPR3DECL(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 */
     1229SUPR3DECL(int) SUPR3TracerOpen(uint32_t uCookie, uintptr_t uArg);
     1230
     1231/**
     1232 * Closes the tracer.
     1233 *
     1234 * @returns VBox status code.
     1235 */
     1236SUPR3DECL(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 */
     1246SUPR3DECL(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 */
     1260SUPR3DECL(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 */
     1269SUPR3DECL(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 */
     1281SUPDECL(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 */
     1306typedef 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 */
     1336typedef DECLCALLBACK(void) FNSUPDRVDESTRUCTOR(void *pvObj, void *pvUser1, void *pvUser2);
     1337/** Pointer to a FNSUPDRVDESTRUCTOR(). */
     1338typedef FNSUPDRVDESTRUCTOR *PFNSUPDRVDESTRUCTOR;
     1339
     1340SUPR0DECL(void *) SUPR0ObjRegister(PSUPDRVSESSION pSession, SUPDRVOBJTYPE enmType, PFNSUPDRVDESTRUCTOR pfnDestructor, void *pvUser1, void *pvUser2);
     1341SUPR0DECL(int) SUPR0ObjAddRef(void *pvObj, PSUPDRVSESSION pSession);
     1342SUPR0DECL(int) SUPR0ObjAddRefEx(void *pvObj, PSUPDRVSESSION pSession, bool fNoBlocking);
     1343SUPR0DECL(int) SUPR0ObjRelease(void *pvObj, PSUPDRVSESSION pSession);
     1344SUPR0DECL(int) SUPR0ObjVerifyAccess(void *pvObj, PSUPDRVSESSION pSession, const char *pszObjName);
     1345
     1346SUPR0DECL(int) SUPR0LockMem(PSUPDRVSESSION pSession, RTR3PTR pvR3, uint32_t cPages, PRTHCPHYS paPages);
     1347SUPR0DECL(int) SUPR0UnlockMem(PSUPDRVSESSION pSession, RTR3PTR pvR3);
     1348SUPR0DECL(int) SUPR0ContAlloc(PSUPDRVSESSION pSession, uint32_t cPages, PRTR0PTR ppvR0, PRTR3PTR ppvR3, PRTHCPHYS pHCPhys);
     1349SUPR0DECL(int) SUPR0ContFree(PSUPDRVSESSION pSession, RTHCUINTPTR uPtr);
     1350SUPR0DECL(int) SUPR0LowAlloc(PSUPDRVSESSION pSession, uint32_t cPages, PRTR0PTR ppvR0, PRTR3PTR ppvR3, PRTHCPHYS paPages);
     1351SUPR0DECL(int) SUPR0LowFree(PSUPDRVSESSION pSession, RTHCUINTPTR uPtr);
     1352SUPR0DECL(int) SUPR0MemAlloc(PSUPDRVSESSION pSession, uint32_t cb, PRTR0PTR ppvR0, PRTR3PTR ppvR3);
     1353SUPR0DECL(int) SUPR0MemGetPhys(PSUPDRVSESSION pSession, RTHCUINTPTR uPtr, PSUPPAGE paPages);
     1354SUPR0DECL(int) SUPR0MemFree(PSUPDRVSESSION pSession, RTHCUINTPTR uPtr);
     1355SUPR0DECL(int) SUPR0PageAllocEx(PSUPDRVSESSION pSession, uint32_t cPages, uint32_t fFlags, PRTR3PTR ppvR3, PRTR0PTR ppvR0, PRTHCPHYS paPages);
     1356SUPR0DECL(int) SUPR0PageMapKernel(PSUPDRVSESSION pSession, RTR3PTR pvR3, uint32_t offSub, uint32_t cbSub, uint32_t fFlags, PRTR0PTR ppvR0);
     1357SUPR0DECL(int) SUPR0PageProtect(PSUPDRVSESSION pSession, RTR3PTR pvR3, RTR0PTR pvR0, uint32_t offSub, uint32_t cbSub, uint32_t fProt);
     1358SUPR0DECL(int) SUPR0PageFree(PSUPDRVSESSION pSession, RTR3PTR pvR3);
     1359SUPR0DECL(int) SUPR0GipMap(PSUPDRVSESSION pSession, PRTR3PTR ppGipR3, PRTHCPHYS pHCPhysGip);
     1360SUPR0DECL(int) SUPR0QueryVTCaps(PSUPDRVSESSION pSession, uint32_t *pfCaps);
     1361SUPR0DECL(int) SUPR0GipUnmap(PSUPDRVSESSION pSession);
     1362SUPR0DECL(int) SUPR0Printf(const char *pszFormat, ...);
     1363SUPR0DECL(SUPPAGINGMODE) SUPR0GetPagingMode(void);
     1364SUPR0DECL(int) SUPR0EnableVTx(bool fEnable);
     1365
     1366/** @name Absolute symbols
     1367 * Take the address of these, don't try call them.
     1368 * @{ */
     1369SUPR0DECL(void) SUPR0AbsIs64bit(void);
     1370SUPR0DECL(void) SUPR0Abs64bitKernelCS(void);
     1371SUPR0DECL(void) SUPR0Abs64bitKernelSS(void);
     1372SUPR0DECL(void) SUPR0Abs64bitKernelDS(void);
     1373SUPR0DECL(void) SUPR0AbsKernelCS(void);
     1374SUPR0DECL(void) SUPR0AbsKernelSS(void);
     1375SUPR0DECL(void) SUPR0AbsKernelDS(void);
     1376SUPR0DECL(void) SUPR0AbsKernelES(void);
     1377SUPR0DECL(void) SUPR0AbsKernelFS(void);
     1378SUPR0DECL(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 */
     1392typedef 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. */
     1411typedef SUPDRVFACTORY *PSUPDRVFACTORY;
     1412/** Pointer to a const support driver factory. */
     1413typedef SUPDRVFACTORY const *PCSUPDRVFACTORY;
     1414
     1415SUPR0DECL(int) SUPR0ComponentRegisterFactory(PSUPDRVSESSION pSession, PCSUPDRVFACTORY pFactory);
     1416SUPR0DECL(int) SUPR0ComponentDeregisterFactory(PSUPDRVSESSION pSession, PCSUPDRVFACTORY pFactory);
     1417SUPR0DECL(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 */
     1426typedef 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. */
     1443typedef 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 */
     1451typedef 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. */
     1459typedef 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 */
     1467typedef 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. */
     1473typedef SUPDRVPROBEINFO *PSUPDRVPROBEINFO;
     1474
     1475/**
     1476 * Support driver tracepoint provider core.
     1477 */
     1478typedef 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. */
     1520typedef SUPDRVVDTPROVIDERCORE *PSUPDRVVDTPROVIDERCORE;
    14601521
    14611522/** Pointer to a tracer registration record. */
Note: See TracChangeset for help on using the changeset viewer.

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