SUPLib.cpp revision 5ee6ca3260f3d19e6975f6b7d8b9434bb6092f55
c58c758d3642ac45d3f12356c406c631fcd8f538vboxsync/* $Id$ */
c58c758d3642ac45d3f12356c406c631fcd8f538vboxsync/** @file
c58c758d3642ac45d3f12356c406c631fcd8f538vboxsync * VirtualBox Support Library - Common code.
c58c758d3642ac45d3f12356c406c631fcd8f538vboxsync */
c58c758d3642ac45d3f12356c406c631fcd8f538vboxsync
c58c758d3642ac45d3f12356c406c631fcd8f538vboxsync/*
967f50840df88ba3efcb33939c933400a70fe9b5vboxsync * Copyright (C) 2006-2007 Sun Microsystems, Inc.
c58c758d3642ac45d3f12356c406c631fcd8f538vboxsync *
c58c758d3642ac45d3f12356c406c631fcd8f538vboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
c58c758d3642ac45d3f12356c406c631fcd8f538vboxsync * available from http://www.virtualbox.org. This file is free software;
c58c758d3642ac45d3f12356c406c631fcd8f538vboxsync * you can redistribute it and/or modify it under the terms of the GNU
c58c758d3642ac45d3f12356c406c631fcd8f538vboxsync * General Public License (GPL) as published by the Free Software
c58c758d3642ac45d3f12356c406c631fcd8f538vboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
c58c758d3642ac45d3f12356c406c631fcd8f538vboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
c58c758d3642ac45d3f12356c406c631fcd8f538vboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
c58c758d3642ac45d3f12356c406c631fcd8f538vboxsync *
c58c758d3642ac45d3f12356c406c631fcd8f538vboxsync * The contents of this file may alternatively be used under the terms
c58c758d3642ac45d3f12356c406c631fcd8f538vboxsync * of the Common Development and Distribution License Version 1.0
c58c758d3642ac45d3f12356c406c631fcd8f538vboxsync * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
c58c758d3642ac45d3f12356c406c631fcd8f538vboxsync * VirtualBox OSE distribution, in which case the provisions of the
c58c758d3642ac45d3f12356c406c631fcd8f538vboxsync * CDDL are applicable instead of those of the GPL.
c58c758d3642ac45d3f12356c406c631fcd8f538vboxsync *
c58c758d3642ac45d3f12356c406c631fcd8f538vboxsync * You may elect to license modified versions of this file under the
c58c758d3642ac45d3f12356c406c631fcd8f538vboxsync * terms and conditions of either the GPL or the CDDL or both.
c58c758d3642ac45d3f12356c406c631fcd8f538vboxsync *
c58c758d3642ac45d3f12356c406c631fcd8f538vboxsync * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
c58c758d3642ac45d3f12356c406c631fcd8f538vboxsync * Clara, CA 95054 USA or visit http://www.sun.com if you need
c58c758d3642ac45d3f12356c406c631fcd8f538vboxsync * additional information or have any questions.
c58c758d3642ac45d3f12356c406c631fcd8f538vboxsync */
c58c758d3642ac45d3f12356c406c631fcd8f538vboxsync
5a5b5956f8b592c807c94785d58c25e717d430c4vboxsync/** @page pg_sup SUP - The Support Library
c58c758d3642ac45d3f12356c406c631fcd8f538vboxsync *
c58c758d3642ac45d3f12356c406c631fcd8f538vboxsync * The support library is responsible for providing facilities to load
c58c758d3642ac45d3f12356c406c631fcd8f538vboxsync * VMM Host Ring-0 code, to call Host VMM Ring-0 code from Ring-3 Host
b26e5b503baa3dffc58048982eaf17ad1b53f207vboxsync * code, to pin down physical memory, and more.
c58c758d3642ac45d3f12356c406c631fcd8f538vboxsync *
5a5b5956f8b592c807c94785d58c25e717d430c4vboxsync * The VMM Host Ring-0 code can be combined in the support driver if
e4bf6817370e1a71833a02285515694afcda7599vboxsync * permitted by kernel module license policies. If it is not combined
5a5b5956f8b592c807c94785d58c25e717d430c4vboxsync * it will be externalized in a .r0 module that will be loaded using
c58c758d3642ac45d3f12356c406c631fcd8f538vboxsync * the IPRT loader.
7c4a90169768dcfac3c355a4c1f98b3ef0193641vboxsync *
7c4a90169768dcfac3c355a4c1f98b3ef0193641vboxsync * The Ring-0 calling is done thru a generic SUP interface which will
7c4a90169768dcfac3c355a4c1f98b3ef0193641vboxsync * tranfer an argument set and call a predefined entry point in the Host
7c4a90169768dcfac3c355a4c1f98b3ef0193641vboxsync * VMM Ring-0 code.
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync *
c58c758d3642ac45d3f12356c406c631fcd8f538vboxsync * See @ref grp_sup "SUP - Support APIs" for API details.
d1e9999d55e7ac80a28692c161710be98071fc00vboxsync */
c58c758d3642ac45d3f12356c406c631fcd8f538vboxsync
c58c758d3642ac45d3f12356c406c631fcd8f538vboxsync/*******************************************************************************
c58c758d3642ac45d3f12356c406c631fcd8f538vboxsync* Header Files *
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync*******************************************************************************/
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync#define LOG_GROUP LOG_GROUP_SUP
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync#include <VBox/sup.h>
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync#include <VBox/err.h>
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync#include <VBox/param.h>
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsync#include <VBox/vmm.h>
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsync#include <VBox/log.h>
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsync#include <VBox/x86.h>
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsync
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsync#include <iprt/assert.h>
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsync#include <iprt/alloc.h>
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsync#include <iprt/alloca.h>
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsync#include <iprt/ldr.h>
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsync#include <iprt/asm.h>
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsync#include <iprt/mp.h>
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsync#include <iprt/cpuset.h>
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsync#include <iprt/thread.h>
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsync#include <iprt/process.h>
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsync#include <iprt/path.h>
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync#include <iprt/string.h>
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync#include <iprt/env.h>
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync#include <iprt/rand.h>
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync#include "SUPLibInternal.h"
c553cea6bfe2ce63ff5517ca4ec288502a890e99vboxsync#include "SUPDrvIOC.h"
c553cea6bfe2ce63ff5517ca4ec288502a890e99vboxsync
c553cea6bfe2ce63ff5517ca4ec288502a890e99vboxsync
c553cea6bfe2ce63ff5517ca4ec288502a890e99vboxsync/*******************************************************************************
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync* Defined Constants And Macros *
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync*******************************************************************************/
c553cea6bfe2ce63ff5517ca4ec288502a890e99vboxsync/** R0 VMM module name. */
c553cea6bfe2ce63ff5517ca4ec288502a890e99vboxsync#define VMMR0_NAME "VMMR0"
c553cea6bfe2ce63ff5517ca4ec288502a890e99vboxsync
c553cea6bfe2ce63ff5517ca4ec288502a890e99vboxsync
c553cea6bfe2ce63ff5517ca4ec288502a890e99vboxsync/*******************************************************************************
c553cea6bfe2ce63ff5517ca4ec288502a890e99vboxsync* Structures and Typedefs *
c553cea6bfe2ce63ff5517ca4ec288502a890e99vboxsync*******************************************************************************/
c553cea6bfe2ce63ff5517ca4ec288502a890e99vboxsynctypedef DECLCALLBACK(int) FNCALLVMMR0(PVMR0 pVMR0, unsigned uOperation, void *pvArg);
c553cea6bfe2ce63ff5517ca4ec288502a890e99vboxsynctypedef FNCALLVMMR0 *PFNCALLVMMR0;
c553cea6bfe2ce63ff5517ca4ec288502a890e99vboxsync
c553cea6bfe2ce63ff5517ca4ec288502a890e99vboxsync
c553cea6bfe2ce63ff5517ca4ec288502a890e99vboxsync/*******************************************************************************
c553cea6bfe2ce63ff5517ca4ec288502a890e99vboxsync* Global Variables *
c553cea6bfe2ce63ff5517ca4ec288502a890e99vboxsync*******************************************************************************/
c553cea6bfe2ce63ff5517ca4ec288502a890e99vboxsync/** Init counter. */
c553cea6bfe2ce63ff5517ca4ec288502a890e99vboxsyncstatic uint32_t g_cInits = 0;
c553cea6bfe2ce63ff5517ca4ec288502a890e99vboxsync/** Whether we've been preinitied. */
c553cea6bfe2ce63ff5517ca4ec288502a890e99vboxsyncstatic bool g_fPreInited = false;
c553cea6bfe2ce63ff5517ca4ec288502a890e99vboxsync/** The SUPLib instance data.
c553cea6bfe2ce63ff5517ca4ec288502a890e99vboxsync * Well, at least parts of it, specificly the parts that are being handed over
c553cea6bfe2ce63ff5517ca4ec288502a890e99vboxsync * via the pre-init mechanism from the hardened executable stub. */
c553cea6bfe2ce63ff5517ca4ec288502a890e99vboxsyncstatic SUPLIBDATA g_supLibData =
c553cea6bfe2ce63ff5517ca4ec288502a890e99vboxsync{
c553cea6bfe2ce63ff5517ca4ec288502a890e99vboxsync NIL_RTFILE
c553cea6bfe2ce63ff5517ca4ec288502a890e99vboxsync#if defined(RT_OS_DARWIN)
c553cea6bfe2ce63ff5517ca4ec288502a890e99vboxsync , NULL
c553cea6bfe2ce63ff5517ca4ec288502a890e99vboxsync#elif defined(RT_OS_LINUX)
c553cea6bfe2ce63ff5517ca4ec288502a890e99vboxsync , false
c553cea6bfe2ce63ff5517ca4ec288502a890e99vboxsync#endif
c553cea6bfe2ce63ff5517ca4ec288502a890e99vboxsync};
c553cea6bfe2ce63ff5517ca4ec288502a890e99vboxsync
c553cea6bfe2ce63ff5517ca4ec288502a890e99vboxsync/** Pointer to the Global Information Page.
c553cea6bfe2ce63ff5517ca4ec288502a890e99vboxsync *
c553cea6bfe2ce63ff5517ca4ec288502a890e99vboxsync * This pointer is valid as long as SUPLib has a open session. Anyone using
c553cea6bfe2ce63ff5517ca4ec288502a890e99vboxsync * the page must treat this pointer as higly volatile and not trust it beyond
c553cea6bfe2ce63ff5517ca4ec288502a890e99vboxsync * one transaction.
c553cea6bfe2ce63ff5517ca4ec288502a890e99vboxsync *
c553cea6bfe2ce63ff5517ca4ec288502a890e99vboxsync * @todo This will probably deserve it's own session or some other good solution...
c553cea6bfe2ce63ff5517ca4ec288502a890e99vboxsync */
c553cea6bfe2ce63ff5517ca4ec288502a890e99vboxsyncDECLEXPORT(PSUPGLOBALINFOPAGE) g_pSUPGlobalInfoPage;
c553cea6bfe2ce63ff5517ca4ec288502a890e99vboxsync/** Address of the ring-0 mapping of the GIP. */
c553cea6bfe2ce63ff5517ca4ec288502a890e99vboxsyncstatic PSUPGLOBALINFOPAGE g_pSUPGlobalInfoPageR0;
c553cea6bfe2ce63ff5517ca4ec288502a890e99vboxsync/** The physical address of the GIP. */
c553cea6bfe2ce63ff5517ca4ec288502a890e99vboxsyncstatic RTHCPHYS g_HCPhysSUPGlobalInfoPage = NIL_RTHCPHYS;
c553cea6bfe2ce63ff5517ca4ec288502a890e99vboxsync
c553cea6bfe2ce63ff5517ca4ec288502a890e99vboxsync/** The negotiated cookie. */
c553cea6bfe2ce63ff5517ca4ec288502a890e99vboxsyncuint32_t g_u32Cookie = 0;
c553cea6bfe2ce63ff5517ca4ec288502a890e99vboxsync/** The negotiated session cookie. */
c553cea6bfe2ce63ff5517ca4ec288502a890e99vboxsyncuint32_t g_u32SessionCookie;
c553cea6bfe2ce63ff5517ca4ec288502a890e99vboxsync/** Session handle. */
c553cea6bfe2ce63ff5517ca4ec288502a890e99vboxsyncPSUPDRVSESSION g_pSession;
c553cea6bfe2ce63ff5517ca4ec288502a890e99vboxsync/** R0 SUP Functions used for resolving referenced to the SUPR0 module. */
c553cea6bfe2ce63ff5517ca4ec288502a890e99vboxsyncstatic PSUPQUERYFUNCS g_pFunctions;
c553cea6bfe2ce63ff5517ca4ec288502a890e99vboxsync
c553cea6bfe2ce63ff5517ca4ec288502a890e99vboxsync#ifdef VBOX_WITH_IDT_PATCHING
c553cea6bfe2ce63ff5517ca4ec288502a890e99vboxsync/** The negotiated interrupt number. */
c553cea6bfe2ce63ff5517ca4ec288502a890e99vboxsyncstatic uint8_t g_u8Interrupt = 3;
c553cea6bfe2ce63ff5517ca4ec288502a890e99vboxsync/** Pointer to the generated code fore calling VMMR0. */
c553cea6bfe2ce63ff5517ca4ec288502a890e99vboxsyncstatic PFNCALLVMMR0 g_pfnCallVMMR0;
c553cea6bfe2ce63ff5517ca4ec288502a890e99vboxsync#endif
c553cea6bfe2ce63ff5517ca4ec288502a890e99vboxsync/** VMMR0 Load Address. */
c553cea6bfe2ce63ff5517ca4ec288502a890e99vboxsyncstatic RTR0PTR g_pvVMMR0 = NIL_RTR0PTR;
c553cea6bfe2ce63ff5517ca4ec288502a890e99vboxsync/** PAGE_ALLOC support indicator. */
5902b558ec0657b3ee3cdba4deaa190f6fe182f1vboxsyncstatic bool g_fSupportsPageAllocLocked = true;
5902b558ec0657b3ee3cdba4deaa190f6fe182f1vboxsync/** Fake mode indicator. (~0 at first, 0 or 1 after first test) */
c553cea6bfe2ce63ff5517ca4ec288502a890e99vboxsyncstatic uint32_t g_u32FakeMode = ~0;
c553cea6bfe2ce63ff5517ca4ec288502a890e99vboxsync
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsync/*******************************************************************************
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsync* Internal Functions *
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsync*******************************************************************************/
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsyncstatic int supInitFake(PSUPDRVSESSION *ppSession);
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsyncstatic int supLoadModule(const char *pszFilename, const char *pszModule, void **ppvImageBase);
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsync#ifdef VBOX_WITH_IDT_PATCHING
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsyncstatic int supInstallIDTE(void);
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsync#endif
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsyncstatic DECLCALLBACK(int) supLoadModuleResolveImport(RTLDRMOD hLdrMod, const char *pszModule, const char *pszSymbol, unsigned uSymbol, RTUINTPTR *pValue, void *pvUser);
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsync
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsync
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsyncSUPR3DECL(int) SUPInstall(void)
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsync{
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsync return suplibOsInstall();
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsync}
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsync
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsync
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsyncSUPR3DECL(int) SUPUninstall(void)
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsync{
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsync return suplibOsUninstall();
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsync}
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsync
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsync
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsyncDECLEXPORT(int) supR3PreInit(PSUPPREINITDATA pPreInitData, uint32_t fFlags)
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsync{
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsync /*
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsync * The caller is kind of trustworthy, just perform some basic checks.
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsync *
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsync * Note! Do not do any fancy stuff here because IPRT has NOT been
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsync * initialized at this point.
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsync */
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsync if (!VALID_PTR(pPreInitData))
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsync return VERR_INVALID_POINTER;
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsync if (g_fPreInited || g_cInits > 0)
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsync return VERR_WRONG_ORDER;
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsync
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsync if ( pPreInitData->u32Magic != SUPPREINITDATA_MAGIC
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsync || pPreInitData->u32EndMagic != SUPPREINITDATA_MAGIC)
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsync return VERR_INVALID_MAGIC;
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsync if ( !(fFlags & SUPSECMAIN_FLAGS_DONT_OPEN_DEV)
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsync && pPreInitData->Data.hDevice == NIL_RTFILE)
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsync return VERR_INVALID_HANDLE;
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsync if ( (fFlags & SUPSECMAIN_FLAGS_DONT_OPEN_DEV)
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsync && pPreInitData->Data.hDevice != NIL_RTFILE)
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsync return VERR_INVALID_PARAMETER;
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsync
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsync /*
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsync * Hand out the data.
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsync */
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsync int rc = supR3HardenedRecvPreInitData(pPreInitData);
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsync if (RT_FAILURE(rc))
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsync return rc;
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsync
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsync /** @todo This may need some small restructuring later, it doesn't quite work with a root service flag... */
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsync if (!(fFlags & SUPSECMAIN_FLAGS_DONT_OPEN_DEV))
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsync {
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsync g_supLibData = pPreInitData->Data;
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsync g_fPreInited = true;
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsync }
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsync
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsync return VINF_SUCCESS;
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsync}
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsync
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsync
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsyncSUPR3DECL(int) SUPR3Init(PSUPDRVSESSION *ppSession)
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsync{
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsync /*
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsync * Perform some sanity checks.
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsync * (Got some trouble with compile time member alignment assertions.)
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsync */
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsync Assert(!(RT_OFFSETOF(SUPGLOBALINFOPAGE, u64NanoTSLastUpdateHz) & 0x7));
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsync Assert(!(RT_OFFSETOF(SUPGLOBALINFOPAGE, aCPUs) & 0x1f));
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsync Assert(!(RT_OFFSETOF(SUPGLOBALINFOPAGE, aCPUs[1]) & 0x1f));
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsync Assert(!(RT_OFFSETOF(SUPGLOBALINFOPAGE, aCPUs[0].u64NanoTS) & 0x7));
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsync Assert(!(RT_OFFSETOF(SUPGLOBALINFOPAGE, aCPUs[0].u64TSC) & 0x7));
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsync Assert(!(RT_OFFSETOF(SUPGLOBALINFOPAGE, aCPUs[0].u64CpuHz) & 0x7));
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsync
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsync /*
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsync * Check if already initialized.
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsync */
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsync if (ppSession)
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsync *ppSession = g_pSession;
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsync if (g_cInits++ > 0)
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsync return VINF_SUCCESS;
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsync
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsync /*
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsync * Check for fake mode.
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsync *
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsync * Fake mode is used when we're doing smoke testing and debugging.
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsync * It's also useful on platforms where we haven't root access or which
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsync * we haven't ported the support driver to.
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsync */
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsync if (g_u32FakeMode == ~0U)
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsync {
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsync const char *psz = RTEnvGet("VBOX_SUPLIB_FAKE");
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsync if (psz && !strcmp(psz, "fake"))
7468341cace5f5d2287abd9b8c3543033c7bf049vboxsync ASMAtomicCmpXchgU32(&g_u32FakeMode, 1, ~0U);
7468341cace5f5d2287abd9b8c3543033c7bf049vboxsync else
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsync ASMAtomicCmpXchgU32(&g_u32FakeMode, 0, ~0U);
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsync }
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsync if (RT_UNLIKELY(g_u32FakeMode))
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsync return supInitFake(ppSession);
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsync
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsync /*
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsync * Open the support driver.
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsync */
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsync int rc = suplibOsInit(&g_supLibData, g_fPreInited);
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsync if (RT_SUCCESS(rc))
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsync {
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsync /*
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsync * Negotiate the cookie.
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsync */
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsync SUPCOOKIE CookieReq;
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsync memset(&CookieReq, 0xff, sizeof(CookieReq));
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsync CookieReq.Hdr.u32Cookie = SUPCOOKIE_INITIAL_COOKIE;
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsync CookieReq.Hdr.u32SessionCookie = RTRandU32();
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsync CookieReq.Hdr.cbIn = SUP_IOCTL_COOKIE_SIZE_IN;
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsync CookieReq.Hdr.cbOut = SUP_IOCTL_COOKIE_SIZE_OUT;
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsync CookieReq.Hdr.fFlags = SUPREQHDR_FLAGS_DEFAULT;
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsync CookieReq.Hdr.rc = VERR_INTERNAL_ERROR;
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsync strcpy(CookieReq.u.In.szMagic, SUPCOOKIE_MAGIC);
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsync CookieReq.u.In.u32ReqVersion = SUPDRV_IOC_VERSION;
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsync const uint32_t MinVersion = (SUPDRV_IOC_VERSION & 0xffff0000) == 0x00090000
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsync ? 0x00090001
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsync : SUPDRV_IOC_VERSION & 0xffff0000;
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsync CookieReq.u.In.u32MinVersion = MinVersion;
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsync rc = suplibOsIOCtl(&g_supLibData, SUP_IOCTL_COOKIE, &CookieReq, SUP_IOCTL_COOKIE_SIZE);
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsync if ( RT_SUCCESS(rc)
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsync && RT_SUCCESS(CookieReq.Hdr.rc))
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsync {
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsync if ( (CookieReq.u.Out.u32SessionVersion & 0xffff0000) == (SUPDRV_IOC_VERSION & 0xffff0000)
e4bf6817370e1a71833a02285515694afcda7599vboxsync && CookieReq.u.Out.u32SessionVersion >= MinVersion)
e4bf6817370e1a71833a02285515694afcda7599vboxsync {
e4bf6817370e1a71833a02285515694afcda7599vboxsync /*
e4bf6817370e1a71833a02285515694afcda7599vboxsync * Query the functions.
e4bf6817370e1a71833a02285515694afcda7599vboxsync */
e4bf6817370e1a71833a02285515694afcda7599vboxsync PSUPQUERYFUNCS pFuncsReq = (PSUPQUERYFUNCS)RTMemAllocZ(SUP_IOCTL_QUERY_FUNCS_SIZE(CookieReq.u.Out.cFunctions));
e4bf6817370e1a71833a02285515694afcda7599vboxsync if (pFuncsReq)
e4bf6817370e1a71833a02285515694afcda7599vboxsync {
967f50840df88ba3efcb33939c933400a70fe9b5vboxsync pFuncsReq->Hdr.u32Cookie = CookieReq.u.Out.u32Cookie;
e4bf6817370e1a71833a02285515694afcda7599vboxsync pFuncsReq->Hdr.u32SessionCookie = CookieReq.u.Out.u32SessionCookie;
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsync pFuncsReq->Hdr.cbIn = SUP_IOCTL_QUERY_FUNCS_SIZE_IN;
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync pFuncsReq->Hdr.cbOut = SUP_IOCTL_QUERY_FUNCS_SIZE_OUT(CookieReq.u.Out.cFunctions);
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync pFuncsReq->Hdr.fFlags = SUPREQHDR_FLAGS_DEFAULT;
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync pFuncsReq->Hdr.rc = VERR_INTERNAL_ERROR;
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync rc = suplibOsIOCtl(&g_supLibData, SUP_IOCTL_QUERY_FUNCS(CookieReq.u.Out.cFunctions), pFuncsReq, SUP_IOCTL_QUERY_FUNCS_SIZE(CookieReq.u.Out.cFunctions));
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync if (RT_SUCCESS(rc))
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync rc = pFuncsReq->Hdr.rc;
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync if (RT_SUCCESS(rc))
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync {
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync g_u32Cookie = CookieReq.u.Out.u32Cookie;
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync g_u32SessionCookie = CookieReq.u.Out.u32SessionCookie;
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync g_pSession = CookieReq.u.Out.pSession;
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync g_pFunctions = pFuncsReq;
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync if (ppSession)
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync *ppSession = CookieReq.u.Out.pSession;
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync /*
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync * Map the GIP into userspace.
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync * This is an optional feature, so we will ignore any failures here.
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync */
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync if (!g_pSUPGlobalInfoPage)
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync {
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync SUPGIPMAP GipMapReq;
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync GipMapReq.Hdr.u32Cookie = g_u32Cookie;
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync GipMapReq.Hdr.u32SessionCookie = g_u32SessionCookie;
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync GipMapReq.Hdr.cbIn = SUP_IOCTL_GIP_MAP_SIZE_IN;
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync GipMapReq.Hdr.cbOut = SUP_IOCTL_GIP_MAP_SIZE_OUT;
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync GipMapReq.Hdr.fFlags = SUPREQHDR_FLAGS_DEFAULT;
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync GipMapReq.Hdr.rc = VERR_INTERNAL_ERROR;
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync GipMapReq.u.Out.HCPhysGip = NIL_RTHCPHYS;
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync GipMapReq.u.Out.pGipR0 = NIL_RTR0PTR;
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync GipMapReq.u.Out.pGipR3 = NULL;
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync rc = suplibOsIOCtl(&g_supLibData, SUP_IOCTL_GIP_MAP, &GipMapReq, SUP_IOCTL_GIP_MAP_SIZE);
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync if (RT_SUCCESS(rc))
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync rc = GipMapReq.Hdr.rc;
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync if (RT_SUCCESS(rc))
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync {
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync AssertRelease(GipMapReq.u.Out.pGipR3->u32Magic == SUPGLOBALINFOPAGE_MAGIC);
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync AssertRelease(GipMapReq.u.Out.pGipR3->u32Version >= SUPGLOBALINFOPAGE_VERSION);
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync ASMAtomicXchgSize(&g_HCPhysSUPGlobalInfoPage, GipMapReq.u.Out.HCPhysGip);
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync ASMAtomicCmpXchgPtr((void * volatile *)&g_pSUPGlobalInfoPage, GipMapReq.u.Out.pGipR3, NULL);
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync ASMAtomicCmpXchgPtr((void * volatile *)&g_pSUPGlobalInfoPageR0, (void *)GipMapReq.u.Out.pGipR0, NULL);
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync }
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync }
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync return VINF_SUCCESS;
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync }
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync /* bailout */
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync RTMemFree(pFuncsReq);
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync }
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync else
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync rc = VERR_NO_MEMORY;
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync }
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync else
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync {
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync LogRel(("Support driver version mismatch: SessionVersion=%#x DriverVersion=%#x ClientVersion=%#x MinVersion=%#x\n",
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync CookieReq.u.Out.u32SessionVersion, CookieReq.u.Out.u32DriverVersion, SUPDRV_IOC_VERSION, MinVersion));
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync rc = VERR_VM_DRIVER_VERSION_MISMATCH;
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync }
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync }
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync else
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync {
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync if (RT_SUCCESS(rc))
c58c758d3642ac45d3f12356c406c631fcd8f538vboxsync {
c58c758d3642ac45d3f12356c406c631fcd8f538vboxsync rc = CookieReq.Hdr.rc;
c58c758d3642ac45d3f12356c406c631fcd8f538vboxsync LogRel(("Support driver version mismatch: DriverVersion=%#x ClientVersion=%#x rc=%Rrc\n",
e4bf6817370e1a71833a02285515694afcda7599vboxsync CookieReq.u.Out.u32DriverVersion, SUPDRV_IOC_VERSION, rc));
e4bf6817370e1a71833a02285515694afcda7599vboxsync if (rc != VERR_VM_DRIVER_VERSION_MISMATCH)
e4bf6817370e1a71833a02285515694afcda7599vboxsync rc = VERR_VM_DRIVER_VERSION_MISMATCH;
e4bf6817370e1a71833a02285515694afcda7599vboxsync }
e4bf6817370e1a71833a02285515694afcda7599vboxsync else
e4bf6817370e1a71833a02285515694afcda7599vboxsync {
e4bf6817370e1a71833a02285515694afcda7599vboxsync /* for pre 0x00060000 drivers */
e4bf6817370e1a71833a02285515694afcda7599vboxsync LogRel(("Support driver version mismatch: DriverVersion=too-old ClientVersion=%#x\n", SUPDRV_IOC_VERSION));
e4bf6817370e1a71833a02285515694afcda7599vboxsync rc = VERR_VM_DRIVER_VERSION_MISMATCH;
5b0a093ca572a855886faa6747ad46df859dd041vboxsync }
5b0a093ca572a855886faa6747ad46df859dd041vboxsync }
5b0a093ca572a855886faa6747ad46df859dd041vboxsync
5b0a093ca572a855886faa6747ad46df859dd041vboxsync suplibOsTerm(&g_supLibData);
5b0a093ca572a855886faa6747ad46df859dd041vboxsync }
5b0a093ca572a855886faa6747ad46df859dd041vboxsync AssertMsgFailed(("SUPR3Init() failed rc=%Rrc\n", rc));
5b0a093ca572a855886faa6747ad46df859dd041vboxsync g_cInits--;
5b0a093ca572a855886faa6747ad46df859dd041vboxsync
5b0a093ca572a855886faa6747ad46df859dd041vboxsync return rc;
5b0a093ca572a855886faa6747ad46df859dd041vboxsync}
5b0a093ca572a855886faa6747ad46df859dd041vboxsync
5b0a093ca572a855886faa6747ad46df859dd041vboxsync/**
5b0a093ca572a855886faa6747ad46df859dd041vboxsync * Fake mode init.
5b0a093ca572a855886faa6747ad46df859dd041vboxsync */
5b0a093ca572a855886faa6747ad46df859dd041vboxsyncstatic int supInitFake(PSUPDRVSESSION *ppSession)
5b0a093ca572a855886faa6747ad46df859dd041vboxsync{
5b0a093ca572a855886faa6747ad46df859dd041vboxsync Log(("SUP: Fake mode!\n"));
5b0a093ca572a855886faa6747ad46df859dd041vboxsync static const SUPFUNC s_aFakeFunctions[] =
5b0a093ca572a855886faa6747ad46df859dd041vboxsync {
5b0a093ca572a855886faa6747ad46df859dd041vboxsync /* name function */
5b0a093ca572a855886faa6747ad46df859dd041vboxsync { "SUPR0ComponentRegisterFactory", 0xefeefffd },
5b0a093ca572a855886faa6747ad46df859dd041vboxsync { "SUPR0ComponentDeregisterFactory", 0xefeefffe },
ad66a27959d7085aa31760f63ce082943be60e89vboxsync { "SUPR0ComponentQueryFactory", 0xefeeffff },
ad66a27959d7085aa31760f63ce082943be60e89vboxsync { "SUPR0ObjRegister", 0xefef0000 },
ad66a27959d7085aa31760f63ce082943be60e89vboxsync { "SUPR0ObjAddRef", 0xefef0001 },
c553cea6bfe2ce63ff5517ca4ec288502a890e99vboxsync { "SUPR0ObjRelease", 0xefef0002 },
ad66a27959d7085aa31760f63ce082943be60e89vboxsync { "SUPR0ObjVerifyAccess", 0xefef0003 },
ad66a27959d7085aa31760f63ce082943be60e89vboxsync { "SUPR0LockMem", 0xefef0004 },
ad66a27959d7085aa31760f63ce082943be60e89vboxsync { "SUPR0UnlockMem", 0xefef0005 },
967f50840df88ba3efcb33939c933400a70fe9b5vboxsync { "SUPR0ContAlloc", 0xefef0006 },
ad66a27959d7085aa31760f63ce082943be60e89vboxsync { "SUPR0ContFree", 0xefef0007 },
ad66a27959d7085aa31760f63ce082943be60e89vboxsync { "SUPR0MemAlloc", 0xefef0008 },
ad66a27959d7085aa31760f63ce082943be60e89vboxsync { "SUPR0MemGetPhys", 0xefef0009 },
6ade813a528d8d2de918522b445e04010f09f021vboxsync { "SUPR0MemFree", 0xefef000a },
6ade813a528d8d2de918522b445e04010f09f021vboxsync { "SUPR0Printf", 0xefef000b },
6ade813a528d8d2de918522b445e04010f09f021vboxsync { "SUPR0ExecuteCallback", 0xefef000c },
c553cea6bfe2ce63ff5517ca4ec288502a890e99vboxsync { "RTMemAlloc", 0xefef000d },
ad66a27959d7085aa31760f63ce082943be60e89vboxsync { "RTMemAllocZ", 0xefef000e },
c553cea6bfe2ce63ff5517ca4ec288502a890e99vboxsync { "RTMemFree", 0xefef000f },
ad66a27959d7085aa31760f63ce082943be60e89vboxsync { "RTR0MemObjAddress", 0xefef0010 },
c553cea6bfe2ce63ff5517ca4ec288502a890e99vboxsync { "RTR0MemObjAddressR3", 0xefef0011 },
ad66a27959d7085aa31760f63ce082943be60e89vboxsync { "RTR0MemObjAllocPage", 0xefef0012 },
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync { "RTR0MemObjAllocPhysNC", 0xefef0013 },
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync { "RTR0MemObjAllocLow", 0xefef0014 },
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync { "RTR0MemObjFree", 0xefef0015 },
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync { "RTR0MemObjGetPagePhysAddr", 0xefef0016 },
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync { "RTR0MemObjMapUser", 0xefef0017 },
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync { "RTProcSelf", 0xefef0038 },
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync { "RTR0ProcHandleSelf", 0xefef0039 },
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync { "RTSemEventCreate", 0xefef0018 },
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync { "RTSemEventSignal", 0xefef0019 },
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync { "RTSemEventWait", 0xefef001a },
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync { "RTSemEventWaitNoResume", 0xefef001b },
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync { "RTSemEventDestroy", 0xefef001c },
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync { "RTSemEventMultiCreate", 0xefef001d },
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync { "RTSemEventMultiSignal", 0xefef001e },
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync { "RTSemEventMultiReset", 0xefef001f },
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync { "RTSemEventMultiWait", 0xefef0020 },
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync { "RTSemEventMultiWaitNoResume", 0xefef0021 },
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync { "RTSemEventMultiDestroy", 0xefef0022 },
c58c758d3642ac45d3f12356c406c631fcd8f538vboxsync { "RTSemFastMutexCreate", 0xefef0023 },
c58c758d3642ac45d3f12356c406c631fcd8f538vboxsync { "RTSemFastMutexDestroy", 0xefef0024 },
c58c758d3642ac45d3f12356c406c631fcd8f538vboxsync { "RTSemFastMutexRequest", 0xefef0025 },
c58c758d3642ac45d3f12356c406c631fcd8f538vboxsync { "RTSemFastMutexRelease", 0xefef0026 },
c58c758d3642ac45d3f12356c406c631fcd8f538vboxsync { "RTSpinlockCreate", 0xefef0027 },
5b0a093ca572a855886faa6747ad46df859dd041vboxsync { "RTSpinlockDestroy", 0xefef0028 },
ad66a27959d7085aa31760f63ce082943be60e89vboxsync { "RTSpinlockAcquire", 0xefef0029 },
d1e9999d55e7ac80a28692c161710be98071fc00vboxsync { "RTSpinlockRelease", 0xefef002a },
d1e9999d55e7ac80a28692c161710be98071fc00vboxsync { "RTSpinlockAcquireNoInts", 0xefef002b },
d1e9999d55e7ac80a28692c161710be98071fc00vboxsync { "RTSpinlockReleaseNoInts", 0xefef002c },
d1e9999d55e7ac80a28692c161710be98071fc00vboxsync { "RTTimeNanoTS", 0xefef002d },
d1e9999d55e7ac80a28692c161710be98071fc00vboxsync { "RTTimeMillieTS", 0xefef002e },
d1e9999d55e7ac80a28692c161710be98071fc00vboxsync { "RTTimeSystemNanoTS", 0xefef002f },
c58c758d3642ac45d3f12356c406c631fcd8f538vboxsync { "RTTimeSystemMillieTS", 0xefef0030 },
5b0a093ca572a855886faa6747ad46df859dd041vboxsync { "RTThreadNativeSelf", 0xefef0031 },
5b0a093ca572a855886faa6747ad46df859dd041vboxsync { "RTThreadSleep", 0xefef0032 },
5b0a093ca572a855886faa6747ad46df859dd041vboxsync { "RTThreadYield", 0xefef0033 },
5b0a093ca572a855886faa6747ad46df859dd041vboxsync { "RTLogDefaultInstance", 0xefef0034 },
ad66a27959d7085aa31760f63ce082943be60e89vboxsync { "RTLogRelDefaultInstance", 0xefef0035 },
5b0a093ca572a855886faa6747ad46df859dd041vboxsync { "RTLogSetDefaultInstanceThread", 0xefef0036 },
ad66a27959d7085aa31760f63ce082943be60e89vboxsync { "RTLogLogger", 0xefef0037 },
5b0a093ca572a855886faa6747ad46df859dd041vboxsync { "RTLogLoggerEx", 0xefef0038 },
ad66a27959d7085aa31760f63ce082943be60e89vboxsync { "RTLogLoggerExV", 0xefef0039 },
5b0a093ca572a855886faa6747ad46df859dd041vboxsync { "AssertMsg1", 0xefef003a },
ad66a27959d7085aa31760f63ce082943be60e89vboxsync { "AssertMsg2", 0xefef003b },
3bb3e26b3306b9f62b18c17380bdf2ca3a98ca49vboxsync };
3bb3e26b3306b9f62b18c17380bdf2ca3a98ca49vboxsync
5b0a093ca572a855886faa6747ad46df859dd041vboxsync /* fake r0 functions. */
ad66a27959d7085aa31760f63ce082943be60e89vboxsync g_pFunctions = (PSUPQUERYFUNCS)RTMemAllocZ(SUP_IOCTL_QUERY_FUNCS_SIZE(RT_ELEMENTS(s_aFakeFunctions)));
ad66a27959d7085aa31760f63ce082943be60e89vboxsync if (g_pFunctions)
ad66a27959d7085aa31760f63ce082943be60e89vboxsync {
ad66a27959d7085aa31760f63ce082943be60e89vboxsync g_pFunctions->u.Out.cFunctions = RT_ELEMENTS(s_aFakeFunctions);
ad66a27959d7085aa31760f63ce082943be60e89vboxsync memcpy(&g_pFunctions->u.Out.aFunctions[0], &s_aFakeFunctions[0], sizeof(s_aFakeFunctions));
ad66a27959d7085aa31760f63ce082943be60e89vboxsync g_pSession = (PSUPDRVSESSION)(void *)g_pFunctions;
e4bf6817370e1a71833a02285515694afcda7599vboxsync if (ppSession)
ad66a27959d7085aa31760f63ce082943be60e89vboxsync *ppSession = g_pSession;
e4bf6817370e1a71833a02285515694afcda7599vboxsync#ifdef VBOX_WITH_IDT_PATCHING
e4bf6817370e1a71833a02285515694afcda7599vboxsync Assert(g_u8Interrupt == 3);
967f50840df88ba3efcb33939c933400a70fe9b5vboxsync#endif
e961f5bfe1727c6816d3dad3805ebe21b6ba1c64vboxsync
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync /* fake the GIP. */
da44a59925a62ca7330a244c71b93794016f29f0vboxsync g_pSUPGlobalInfoPage = (PSUPGLOBALINFOPAGE)RTMemPageAllocZ(PAGE_SIZE);
da44a59925a62ca7330a244c71b93794016f29f0vboxsync if (g_pSUPGlobalInfoPage)
da44a59925a62ca7330a244c71b93794016f29f0vboxsync {
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync g_pSUPGlobalInfoPageR0 = g_pSUPGlobalInfoPage;
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync g_HCPhysSUPGlobalInfoPage = NIL_RTHCPHYS & ~(RTHCPHYS)PAGE_OFFSET_MASK;
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync /* the page is supposed to be invalid, so don't set the magic. */
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync return VINF_SUCCESS;
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync }
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync RTMemFree(g_pFunctions);
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync g_pFunctions = NULL;
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync }
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync return VERR_NO_MEMORY;
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync}
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsyncSUPR3DECL(int) SUPTerm(bool fForced)
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync{
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync /*
7c4a90169768dcfac3c355a4c1f98b3ef0193641vboxsync * Verify state.
967f50840df88ba3efcb33939c933400a70fe9b5vboxsync */
7c4a90169768dcfac3c355a4c1f98b3ef0193641vboxsync AssertMsg(g_cInits > 0, ("SUPTerm() is called before SUPR3Init()!\n"));
7c4a90169768dcfac3c355a4c1f98b3ef0193641vboxsync if (g_cInits == 0)
7c4a90169768dcfac3c355a4c1f98b3ef0193641vboxsync return VERR_WRONG_ORDER;
7c4a90169768dcfac3c355a4c1f98b3ef0193641vboxsync if (g_cInits == 1 || fForced)
7c4a90169768dcfac3c355a4c1f98b3ef0193641vboxsync {
7c4a90169768dcfac3c355a4c1f98b3ef0193641vboxsync /*
c58c758d3642ac45d3f12356c406c631fcd8f538vboxsync * NULL the GIP pointer.
c58c758d3642ac45d3f12356c406c631fcd8f538vboxsync */
c58c758d3642ac45d3f12356c406c631fcd8f538vboxsync if (g_pSUPGlobalInfoPage)
c58c758d3642ac45d3f12356c406c631fcd8f538vboxsync {
b26e5b503baa3dffc58048982eaf17ad1b53f207vboxsync ASMAtomicXchgPtr((void * volatile *)&g_pSUPGlobalInfoPage, NULL);
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync ASMAtomicXchgPtr((void * volatile *)&g_pSUPGlobalInfoPageR0, NULL);
b26e5b503baa3dffc58048982eaf17ad1b53f207vboxsync ASMAtomicXchgSize(&g_HCPhysSUPGlobalInfoPage, NIL_RTHCPHYS);
e4bf6817370e1a71833a02285515694afcda7599vboxsync /* just a little safe guard against threads using the page. */
b26e5b503baa3dffc58048982eaf17ad1b53f207vboxsync RTThreadSleep(50);
b26e5b503baa3dffc58048982eaf17ad1b53f207vboxsync }
b26e5b503baa3dffc58048982eaf17ad1b53f207vboxsync
b26e5b503baa3dffc58048982eaf17ad1b53f207vboxsync /*
b26e5b503baa3dffc58048982eaf17ad1b53f207vboxsync * Close the support driver.
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync */
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync int rc = suplibOsTerm(&g_supLibData);
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync if (rc)
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync return rc;
b26e5b503baa3dffc58048982eaf17ad1b53f207vboxsync
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync g_u32Cookie = 0;
b26e5b503baa3dffc58048982eaf17ad1b53f207vboxsync g_u32SessionCookie = 0;
b26e5b503baa3dffc58048982eaf17ad1b53f207vboxsync#ifdef VBOX_WITH_IDT_PATCHING
b26e5b503baa3dffc58048982eaf17ad1b53f207vboxsync g_u8Interrupt = 3;
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync#endif
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync g_cInits = 0;
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync }
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync else
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync g_cInits--;
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync return 0;
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync}
ad66a27959d7085aa31760f63ce082943be60e89vboxsync
ad66a27959d7085aa31760f63ce082943be60e89vboxsync
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsyncSUPR3DECL(SUPPAGINGMODE) SUPGetPagingMode(void)
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync{
b26e5b503baa3dffc58048982eaf17ad1b53f207vboxsync /* fake */
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync if (RT_UNLIKELY(g_u32FakeMode))
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync#ifdef RT_ARCH_AMD64
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync return SUPPAGINGMODE_AMD64_GLOBAL_NX;
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync#else
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync return SUPPAGINGMODE_32_BIT_GLOBAL;
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync#endif
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync /*
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync * Issue IOCtl to the SUPDRV kernel module.
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync */
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync SUPGETPAGINGMODE Req;
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync Req.Hdr.u32Cookie = g_u32Cookie;
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync Req.Hdr.u32SessionCookie = g_u32SessionCookie;
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync Req.Hdr.cbIn = SUP_IOCTL_GET_PAGING_MODE_SIZE_IN;
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync Req.Hdr.cbOut = SUP_IOCTL_GET_PAGING_MODE_SIZE_OUT;
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync Req.Hdr.fFlags = SUPREQHDR_FLAGS_DEFAULT;
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync Req.Hdr.rc = VERR_INTERNAL_ERROR;
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync int rc = suplibOsIOCtl(&g_supLibData, SUP_IOCTL_GET_PAGING_MODE, &Req, SUP_IOCTL_GET_PAGING_MODE_SIZE);
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync if ( RT_FAILURE(rc)
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync || RT_FAILURE(Req.Hdr.rc))
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync {
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync LogRel(("SUPGetPagingMode: %Rrc %Rrc\n", rc, Req.Hdr.rc));
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync Req.u.Out.enmMode = SUPPAGINGMODE_INVALID;
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync }
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync return Req.u.Out.enmMode;
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync}
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync/**
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync * For later.
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync */
4bf996d915405be92dc4394b2db1395e00e14d58vboxsyncstatic int supCallVMMR0ExFake(PVMR0 pVMR0, unsigned uOperation, uint64_t u64Arg, PSUPVMMR0REQHDR pReqHdr)
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync{
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync AssertMsgFailed(("%d\n", uOperation));
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync return VERR_NOT_SUPPORTED;
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync}
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync
4bf996d915405be92dc4394b2db1395e00e14d58vboxsyncSUPR3DECL(int) SUPCallVMMR0Fast(PVMR0 pVMR0, unsigned uOperation, unsigned idCpu)
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync{
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync if (RT_LIKELY(uOperation == SUP_VMMR0_DO_RAW_RUN))
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync return suplibOsIOCtlFast(&g_supLibData, SUP_IOCTL_FAST_DO_RAW_RUN, idCpu);
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync if (RT_LIKELY(uOperation == SUP_VMMR0_DO_HWACC_RUN))
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync return suplibOsIOCtlFast(&g_supLibData, SUP_IOCTL_FAST_DO_HWACC_RUN, idCpu);
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync if (RT_LIKELY(uOperation == SUP_VMMR0_DO_NOP))
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync return suplibOsIOCtlFast(&g_supLibData, SUP_IOCTL_FAST_DO_NOP, idCpu);
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync AssertMsgFailed(("%#x\n", uOperation));
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync return VERR_INTERNAL_ERROR;
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync}
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync
4bf996d915405be92dc4394b2db1395e00e14d58vboxsyncSUPR3DECL(int) SUPCallVMMR0Ex(PVMR0 pVMR0, unsigned uOperation, uint64_t u64Arg, PSUPVMMR0REQHDR pReqHdr)
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync{
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync /*
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync * The following operations don't belong here.
e4bf6817370e1a71833a02285515694afcda7599vboxsync */
e4bf6817370e1a71833a02285515694afcda7599vboxsync AssertMsgReturn( uOperation != SUP_VMMR0_DO_RAW_RUN
e4bf6817370e1a71833a02285515694afcda7599vboxsync && uOperation != SUP_VMMR0_DO_HWACC_RUN
e4bf6817370e1a71833a02285515694afcda7599vboxsync && uOperation != SUP_VMMR0_DO_NOP,
e4bf6817370e1a71833a02285515694afcda7599vboxsync ("%#x\n", uOperation),
e4bf6817370e1a71833a02285515694afcda7599vboxsync VERR_INTERNAL_ERROR);
e4bf6817370e1a71833a02285515694afcda7599vboxsync
e4bf6817370e1a71833a02285515694afcda7599vboxsync /* fake */
e4bf6817370e1a71833a02285515694afcda7599vboxsync if (RT_UNLIKELY(g_u32FakeMode))
e4bf6817370e1a71833a02285515694afcda7599vboxsync return supCallVMMR0ExFake(pVMR0, uOperation, u64Arg, pReqHdr);
e4bf6817370e1a71833a02285515694afcda7599vboxsync
e4bf6817370e1a71833a02285515694afcda7599vboxsync int rc;
e4bf6817370e1a71833a02285515694afcda7599vboxsync if (!pReqHdr)
e4bf6817370e1a71833a02285515694afcda7599vboxsync {
e4bf6817370e1a71833a02285515694afcda7599vboxsync /* no data. */
e4bf6817370e1a71833a02285515694afcda7599vboxsync SUPCALLVMMR0 Req;
e4bf6817370e1a71833a02285515694afcda7599vboxsync Req.Hdr.u32Cookie = g_u32Cookie;
e4bf6817370e1a71833a02285515694afcda7599vboxsync Req.Hdr.u32SessionCookie = g_u32SessionCookie;
e4bf6817370e1a71833a02285515694afcda7599vboxsync Req.Hdr.cbIn = SUP_IOCTL_CALL_VMMR0_SIZE_IN(0);
e4bf6817370e1a71833a02285515694afcda7599vboxsync Req.Hdr.cbOut = SUP_IOCTL_CALL_VMMR0_SIZE_OUT(0);
e4bf6817370e1a71833a02285515694afcda7599vboxsync Req.Hdr.fFlags = SUPREQHDR_FLAGS_DEFAULT;
7468341cace5f5d2287abd9b8c3543033c7bf049vboxsync Req.Hdr.rc = VERR_INTERNAL_ERROR;
e4bf6817370e1a71833a02285515694afcda7599vboxsync Req.u.In.pVMR0 = pVMR0;
e4bf6817370e1a71833a02285515694afcda7599vboxsync Req.u.In.uOperation = uOperation;
7468341cace5f5d2287abd9b8c3543033c7bf049vboxsync Req.u.In.u64Arg = u64Arg;
7468341cace5f5d2287abd9b8c3543033c7bf049vboxsync rc = suplibOsIOCtl(&g_supLibData, SUP_IOCTL_CALL_VMMR0(0), &Req, SUP_IOCTL_CALL_VMMR0_SIZE(0));
7468341cace5f5d2287abd9b8c3543033c7bf049vboxsync if (RT_SUCCESS(rc))
e4bf6817370e1a71833a02285515694afcda7599vboxsync rc = Req.Hdr.rc;
e4bf6817370e1a71833a02285515694afcda7599vboxsync }
e4bf6817370e1a71833a02285515694afcda7599vboxsync else if (SUP_IOCTL_CALL_VMMR0_SIZE(pReqHdr->cbReq) < _4K) /* FreeBSD won't copy more than 4K. */
e4bf6817370e1a71833a02285515694afcda7599vboxsync {
e4bf6817370e1a71833a02285515694afcda7599vboxsync AssertPtrReturn(pReqHdr, VERR_INVALID_POINTER);
e4bf6817370e1a71833a02285515694afcda7599vboxsync AssertReturn(pReqHdr->u32Magic == SUPVMMR0REQHDR_MAGIC, VERR_INVALID_MAGIC);
e4bf6817370e1a71833a02285515694afcda7599vboxsync const size_t cbReq = pReqHdr->cbReq;
e4bf6817370e1a71833a02285515694afcda7599vboxsync
e4bf6817370e1a71833a02285515694afcda7599vboxsync PSUPCALLVMMR0 pReq = (PSUPCALLVMMR0)alloca(SUP_IOCTL_CALL_VMMR0_SIZE(cbReq));
7468341cace5f5d2287abd9b8c3543033c7bf049vboxsync pReq->Hdr.u32Cookie = g_u32Cookie;
7468341cace5f5d2287abd9b8c3543033c7bf049vboxsync pReq->Hdr.u32SessionCookie = g_u32SessionCookie;
e4bf6817370e1a71833a02285515694afcda7599vboxsync pReq->Hdr.cbIn = SUP_IOCTL_CALL_VMMR0_SIZE_IN(cbReq);
e4bf6817370e1a71833a02285515694afcda7599vboxsync pReq->Hdr.cbOut = SUP_IOCTL_CALL_VMMR0_SIZE_OUT(cbReq);
e4bf6817370e1a71833a02285515694afcda7599vboxsync pReq->Hdr.fFlags = SUPREQHDR_FLAGS_DEFAULT;
e4bf6817370e1a71833a02285515694afcda7599vboxsync pReq->Hdr.rc = VERR_INTERNAL_ERROR;
e4bf6817370e1a71833a02285515694afcda7599vboxsync pReq->u.In.pVMR0 = pVMR0;
e4bf6817370e1a71833a02285515694afcda7599vboxsync pReq->u.In.uOperation = uOperation;
725fba5c64717677ac66072bae37e5b3686f3e6dvboxsync pReq->u.In.u64Arg = u64Arg;
725fba5c64717677ac66072bae37e5b3686f3e6dvboxsync memcpy(&pReq->abReqPkt[0], pReqHdr, cbReq);
e4bf6817370e1a71833a02285515694afcda7599vboxsync rc = suplibOsIOCtl(&g_supLibData, SUP_IOCTL_CALL_VMMR0(cbReq), pReq, SUP_IOCTL_CALL_VMMR0_SIZE(cbReq));
e4bf6817370e1a71833a02285515694afcda7599vboxsync if (RT_SUCCESS(rc))
e4bf6817370e1a71833a02285515694afcda7599vboxsync rc = pReq->Hdr.rc;
e4bf6817370e1a71833a02285515694afcda7599vboxsync memcpy(pReqHdr, &pReq->abReqPkt[0], cbReq);
e4bf6817370e1a71833a02285515694afcda7599vboxsync }
e4bf6817370e1a71833a02285515694afcda7599vboxsync else /** @todo may have to remove the size limits one this request... */
e4bf6817370e1a71833a02285515694afcda7599vboxsync AssertMsgFailedReturn(("cbReq=%#x\n", pReqHdr->cbReq), VERR_INTERNAL_ERROR);
e4bf6817370e1a71833a02285515694afcda7599vboxsync return rc;
e4bf6817370e1a71833a02285515694afcda7599vboxsync}
e4bf6817370e1a71833a02285515694afcda7599vboxsync
725fba5c64717677ac66072bae37e5b3686f3e6dvboxsync
725fba5c64717677ac66072bae37e5b3686f3e6dvboxsyncSUPR3DECL(int) SUPCallVMMR0(PVMR0 pVMR0, unsigned uOperation, void *pvArg)
e4bf6817370e1a71833a02285515694afcda7599vboxsync{
e4bf6817370e1a71833a02285515694afcda7599vboxsync#if defined(VBOX_WITH_IDT_PATCHING)
967f50840df88ba3efcb33939c933400a70fe9b5vboxsync return g_pfnCallVMMR0(pVMR0, uOperation, pvArg);
e4bf6817370e1a71833a02285515694afcda7599vboxsync
e4bf6817370e1a71833a02285515694afcda7599vboxsync#else
e4bf6817370e1a71833a02285515694afcda7599vboxsync /*
967f50840df88ba3efcb33939c933400a70fe9b5vboxsync * The following operations don't belong here.
725fba5c64717677ac66072bae37e5b3686f3e6dvboxsync */
e4bf6817370e1a71833a02285515694afcda7599vboxsync AssertMsgReturn( uOperation != SUP_VMMR0_DO_RAW_RUN
e4bf6817370e1a71833a02285515694afcda7599vboxsync && uOperation != SUP_VMMR0_DO_HWACC_RUN
e4bf6817370e1a71833a02285515694afcda7599vboxsync && uOperation != SUP_VMMR0_DO_NOP,
e4bf6817370e1a71833a02285515694afcda7599vboxsync ("%#x\n", uOperation),
e4bf6817370e1a71833a02285515694afcda7599vboxsync VERR_INTERNAL_ERROR);
e4bf6817370e1a71833a02285515694afcda7599vboxsync return SUPCallVMMR0Ex(pVMR0, uOperation, (uintptr_t)pvArg, NULL);
e4bf6817370e1a71833a02285515694afcda7599vboxsync#endif
e4bf6817370e1a71833a02285515694afcda7599vboxsync}
e4bf6817370e1a71833a02285515694afcda7599vboxsync
e4bf6817370e1a71833a02285515694afcda7599vboxsync
e4bf6817370e1a71833a02285515694afcda7599vboxsyncSUPR3DECL(int) SUPSetVMForFastIOCtl(PVMR0 pVMR0)
e4bf6817370e1a71833a02285515694afcda7599vboxsync{
e4bf6817370e1a71833a02285515694afcda7599vboxsync if (RT_UNLIKELY(g_u32FakeMode))
e4bf6817370e1a71833a02285515694afcda7599vboxsync return VINF_SUCCESS;
e4bf6817370e1a71833a02285515694afcda7599vboxsync
e4bf6817370e1a71833a02285515694afcda7599vboxsync SUPSETVMFORFAST Req;
e4bf6817370e1a71833a02285515694afcda7599vboxsync Req.Hdr.u32Cookie = g_u32Cookie;
7c4a90169768dcfac3c355a4c1f98b3ef0193641vboxsync Req.Hdr.u32SessionCookie = g_u32SessionCookie;
7c4a90169768dcfac3c355a4c1f98b3ef0193641vboxsync Req.Hdr.cbIn = SUP_IOCTL_SET_VM_FOR_FAST_SIZE_IN;
7c4a90169768dcfac3c355a4c1f98b3ef0193641vboxsync Req.Hdr.cbOut = SUP_IOCTL_SET_VM_FOR_FAST_SIZE_OUT;
7c4a90169768dcfac3c355a4c1f98b3ef0193641vboxsync Req.Hdr.fFlags = SUPREQHDR_FLAGS_DEFAULT;
7c4a90169768dcfac3c355a4c1f98b3ef0193641vboxsync Req.Hdr.rc = VERR_INTERNAL_ERROR;
e4bf6817370e1a71833a02285515694afcda7599vboxsync Req.u.In.pVMR0 = pVMR0;
e4bf6817370e1a71833a02285515694afcda7599vboxsync int rc = suplibOsIOCtl(&g_supLibData, SUP_IOCTL_SET_VM_FOR_FAST, &Req, SUP_IOCTL_SET_VM_FOR_FAST_SIZE);
e4bf6817370e1a71833a02285515694afcda7599vboxsync if (RT_SUCCESS(rc))
e4bf6817370e1a71833a02285515694afcda7599vboxsync rc = Req.Hdr.rc;
e4bf6817370e1a71833a02285515694afcda7599vboxsync return rc;
e4bf6817370e1a71833a02285515694afcda7599vboxsync}
e4bf6817370e1a71833a02285515694afcda7599vboxsync
e4bf6817370e1a71833a02285515694afcda7599vboxsync
e4bf6817370e1a71833a02285515694afcda7599vboxsyncSUPR3DECL(int) SUPPageAlloc(size_t cPages, void **ppvPages)
e4bf6817370e1a71833a02285515694afcda7599vboxsync{
e4bf6817370e1a71833a02285515694afcda7599vboxsync /*
e4bf6817370e1a71833a02285515694afcda7599vboxsync * Validate.
e4bf6817370e1a71833a02285515694afcda7599vboxsync */
e4bf6817370e1a71833a02285515694afcda7599vboxsync AssertPtrReturn(ppvPages, VERR_INVALID_POINTER);
725fba5c64717677ac66072bae37e5b3686f3e6dvboxsync *ppvPages = NULL;
725fba5c64717677ac66072bae37e5b3686f3e6dvboxsync AssertReturn(cPages > 0, VERR_INVALID_PARAMETER);
e4bf6817370e1a71833a02285515694afcda7599vboxsync
e4bf6817370e1a71833a02285515694afcda7599vboxsync#ifdef RT_OS_WINDOWS
e4bf6817370e1a71833a02285515694afcda7599vboxsync /*
e4bf6817370e1a71833a02285515694afcda7599vboxsync * Temporary hack for windows until we've sorted out the
e4bf6817370e1a71833a02285515694afcda7599vboxsync * locked memory that doesn't need to be accessible from kernel space.
e4bf6817370e1a71833a02285515694afcda7599vboxsync */
e4bf6817370e1a71833a02285515694afcda7599vboxsync return SUPPageAllocLockedEx(cPages, ppvPages, NULL);
e4bf6817370e1a71833a02285515694afcda7599vboxsync#else
e4bf6817370e1a71833a02285515694afcda7599vboxsync /*
e4bf6817370e1a71833a02285515694afcda7599vboxsync * Call OS specific worker.
725fba5c64717677ac66072bae37e5b3686f3e6dvboxsync */
725fba5c64717677ac66072bae37e5b3686f3e6dvboxsync return suplibOsPageAlloc(&g_supLibData, cPages, ppvPages);
725fba5c64717677ac66072bae37e5b3686f3e6dvboxsync#endif
5902b558ec0657b3ee3cdba4deaa190f6fe182f1vboxsync}
725fba5c64717677ac66072bae37e5b3686f3e6dvboxsync
e4bf6817370e1a71833a02285515694afcda7599vboxsync
e4bf6817370e1a71833a02285515694afcda7599vboxsyncSUPR3DECL(int) SUPPageFree(void *pvPages, size_t cPages)
e4bf6817370e1a71833a02285515694afcda7599vboxsync{
e4bf6817370e1a71833a02285515694afcda7599vboxsync /*
e4bf6817370e1a71833a02285515694afcda7599vboxsync * Validate.
e4bf6817370e1a71833a02285515694afcda7599vboxsync */
e4bf6817370e1a71833a02285515694afcda7599vboxsync AssertPtrReturn(pvPages, VERR_INVALID_POINTER);
e4bf6817370e1a71833a02285515694afcda7599vboxsync AssertReturn(cPages > 0, VERR_INVALID_PARAMETER);
e4bf6817370e1a71833a02285515694afcda7599vboxsync
e4bf6817370e1a71833a02285515694afcda7599vboxsync#ifdef RT_OS_WINDOWS
e4bf6817370e1a71833a02285515694afcda7599vboxsync /*
e4bf6817370e1a71833a02285515694afcda7599vboxsync * Temporary hack for windows, see above.
e4bf6817370e1a71833a02285515694afcda7599vboxsync */
e4bf6817370e1a71833a02285515694afcda7599vboxsync return SUPPageFreeLocked(pvPages, cPages);
e4bf6817370e1a71833a02285515694afcda7599vboxsync#else
e4bf6817370e1a71833a02285515694afcda7599vboxsync /*
e4bf6817370e1a71833a02285515694afcda7599vboxsync * Call OS specific worker.
e4bf6817370e1a71833a02285515694afcda7599vboxsync */
e4bf6817370e1a71833a02285515694afcda7599vboxsync return suplibOsPageFree(&g_supLibData, pvPages, cPages);
e4bf6817370e1a71833a02285515694afcda7599vboxsync#endif
e4bf6817370e1a71833a02285515694afcda7599vboxsync}
e4bf6817370e1a71833a02285515694afcda7599vboxsync
e4bf6817370e1a71833a02285515694afcda7599vboxsync
e4bf6817370e1a71833a02285515694afcda7599vboxsyncSUPR3DECL(int) SUPPageLock(void *pvStart, size_t cPages, PSUPPAGE paPages)
e4bf6817370e1a71833a02285515694afcda7599vboxsync{
e4bf6817370e1a71833a02285515694afcda7599vboxsync /*
e4bf6817370e1a71833a02285515694afcda7599vboxsync * Validate.
e4bf6817370e1a71833a02285515694afcda7599vboxsync */
e4bf6817370e1a71833a02285515694afcda7599vboxsync AssertPtr(pvStart);
e4bf6817370e1a71833a02285515694afcda7599vboxsync AssertMsg(RT_ALIGN_P(pvStart, PAGE_SIZE) == pvStart, ("pvStart (%p) must be page aligned\n", pvStart));
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync AssertPtr(paPages);
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync /* fake */
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync if (RT_UNLIKELY(g_u32FakeMode))
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync {
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync RTHCPHYS Phys = (uintptr_t)pvStart + PAGE_SIZE * 1024;
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync size_t iPage = cPages;
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync while (iPage-- > 0)
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync paPages[iPage].Phys = Phys + (iPage << PAGE_SHIFT);
967f50840df88ba3efcb33939c933400a70fe9b5vboxsync return VINF_SUCCESS;
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync }
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync /*
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync * Issue IOCtl to the SUPDRV kernel module.
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync */
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync int rc;
e4bf6817370e1a71833a02285515694afcda7599vboxsync PSUPPAGELOCK pReq = (PSUPPAGELOCK)RTMemTmpAllocZ(SUP_IOCTL_PAGE_LOCK_SIZE(cPages));
e4bf6817370e1a71833a02285515694afcda7599vboxsync if (RT_LIKELY(pReq))
e4bf6817370e1a71833a02285515694afcda7599vboxsync {
e4bf6817370e1a71833a02285515694afcda7599vboxsync pReq->Hdr.u32Cookie = g_u32Cookie;
725fba5c64717677ac66072bae37e5b3686f3e6dvboxsync pReq->Hdr.u32SessionCookie = g_u32SessionCookie;
e4bf6817370e1a71833a02285515694afcda7599vboxsync pReq->Hdr.cbIn = SUP_IOCTL_PAGE_LOCK_SIZE_IN;
e4bf6817370e1a71833a02285515694afcda7599vboxsync pReq->Hdr.cbOut = SUP_IOCTL_PAGE_LOCK_SIZE_OUT(cPages);
e4bf6817370e1a71833a02285515694afcda7599vboxsync pReq->Hdr.fFlags = SUPREQHDR_FLAGS_MAGIC | SUPREQHDR_FLAGS_EXTRA_OUT;
e4bf6817370e1a71833a02285515694afcda7599vboxsync pReq->Hdr.rc = VERR_INTERNAL_ERROR;
e4bf6817370e1a71833a02285515694afcda7599vboxsync pReq->u.In.pvR3 = pvStart;
e4bf6817370e1a71833a02285515694afcda7599vboxsync pReq->u.In.cPages = (uint32_t)cPages; AssertRelease(pReq->u.In.cPages == cPages);
e4bf6817370e1a71833a02285515694afcda7599vboxsync rc = suplibOsIOCtl(&g_supLibData, SUP_IOCTL_PAGE_LOCK, pReq, SUP_IOCTL_PAGE_LOCK_SIZE(cPages));
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync if (RT_SUCCESS(rc))
e4bf6817370e1a71833a02285515694afcda7599vboxsync rc = pReq->Hdr.rc;
e4bf6817370e1a71833a02285515694afcda7599vboxsync if (RT_SUCCESS(rc))
e4bf6817370e1a71833a02285515694afcda7599vboxsync {
e4bf6817370e1a71833a02285515694afcda7599vboxsync for (uint32_t iPage = 0; iPage < cPages; iPage++)
e4bf6817370e1a71833a02285515694afcda7599vboxsync {
725fba5c64717677ac66072bae37e5b3686f3e6dvboxsync paPages[iPage].uReserved = 0;
725fba5c64717677ac66072bae37e5b3686f3e6dvboxsync paPages[iPage].Phys = pReq->u.Out.aPages[iPage];
725fba5c64717677ac66072bae37e5b3686f3e6dvboxsync Assert(!(paPages[iPage].Phys & ~X86_PTE_PAE_PG_MASK));
725fba5c64717677ac66072bae37e5b3686f3e6dvboxsync }
e4bf6817370e1a71833a02285515694afcda7599vboxsync }
e4bf6817370e1a71833a02285515694afcda7599vboxsync RTMemTmpFree(pReq);
e4bf6817370e1a71833a02285515694afcda7599vboxsync }
e4bf6817370e1a71833a02285515694afcda7599vboxsync else
e4bf6817370e1a71833a02285515694afcda7599vboxsync rc = VERR_NO_TMP_MEMORY;
e4bf6817370e1a71833a02285515694afcda7599vboxsync
e4bf6817370e1a71833a02285515694afcda7599vboxsync return rc;
e4bf6817370e1a71833a02285515694afcda7599vboxsync}
e4bf6817370e1a71833a02285515694afcda7599vboxsync
e4bf6817370e1a71833a02285515694afcda7599vboxsync
e4bf6817370e1a71833a02285515694afcda7599vboxsyncSUPR3DECL(int) SUPPageUnlock(void *pvStart)
e4bf6817370e1a71833a02285515694afcda7599vboxsync{
3bb3e26b3306b9f62b18c17380bdf2ca3a98ca49vboxsync /*
e4bf6817370e1a71833a02285515694afcda7599vboxsync * Validate.
e4bf6817370e1a71833a02285515694afcda7599vboxsync */
e4bf6817370e1a71833a02285515694afcda7599vboxsync AssertPtr(pvStart);
e4bf6817370e1a71833a02285515694afcda7599vboxsync AssertMsg(RT_ALIGN_P(pvStart, PAGE_SIZE) == pvStart, ("pvStart (%p) must be page aligned\n", pvStart));
e4bf6817370e1a71833a02285515694afcda7599vboxsync
e4bf6817370e1a71833a02285515694afcda7599vboxsync /* fake */
e4bf6817370e1a71833a02285515694afcda7599vboxsync if (RT_UNLIKELY(g_u32FakeMode))
e4bf6817370e1a71833a02285515694afcda7599vboxsync return VINF_SUCCESS;
e4bf6817370e1a71833a02285515694afcda7599vboxsync
e4bf6817370e1a71833a02285515694afcda7599vboxsync /*
e4bf6817370e1a71833a02285515694afcda7599vboxsync * Issue IOCtl to the SUPDRV kernel module.
e4bf6817370e1a71833a02285515694afcda7599vboxsync */
e4bf6817370e1a71833a02285515694afcda7599vboxsync SUPPAGEUNLOCK Req;
e4bf6817370e1a71833a02285515694afcda7599vboxsync Req.Hdr.u32Cookie = g_u32Cookie;
e4bf6817370e1a71833a02285515694afcda7599vboxsync Req.Hdr.u32SessionCookie = g_u32SessionCookie;
e4bf6817370e1a71833a02285515694afcda7599vboxsync Req.Hdr.cbIn = SUP_IOCTL_PAGE_UNLOCK_SIZE_IN;
e4bf6817370e1a71833a02285515694afcda7599vboxsync Req.Hdr.cbOut = SUP_IOCTL_PAGE_UNLOCK_SIZE_OUT;
e4bf6817370e1a71833a02285515694afcda7599vboxsync Req.Hdr.fFlags = SUPREQHDR_FLAGS_DEFAULT;
e4bf6817370e1a71833a02285515694afcda7599vboxsync Req.Hdr.rc = VERR_INTERNAL_ERROR;
e4bf6817370e1a71833a02285515694afcda7599vboxsync Req.u.In.pvR3 = pvStart;
e4bf6817370e1a71833a02285515694afcda7599vboxsync int rc = suplibOsIOCtl(&g_supLibData, SUP_IOCTL_PAGE_UNLOCK, &Req, SUP_IOCTL_PAGE_UNLOCK_SIZE);
e4bf6817370e1a71833a02285515694afcda7599vboxsync if (RT_SUCCESS(rc))
e4bf6817370e1a71833a02285515694afcda7599vboxsync rc = Req.Hdr.rc;
e4bf6817370e1a71833a02285515694afcda7599vboxsync return rc;
e4bf6817370e1a71833a02285515694afcda7599vboxsync}
e4bf6817370e1a71833a02285515694afcda7599vboxsync
e4bf6817370e1a71833a02285515694afcda7599vboxsync
e4bf6817370e1a71833a02285515694afcda7599vboxsyncSUPR3DECL(int) SUPPageAllocLocked(size_t cPages, void **ppvPages)
e4bf6817370e1a71833a02285515694afcda7599vboxsync{
e4bf6817370e1a71833a02285515694afcda7599vboxsync return SUPPageAllocLockedEx(cPages, ppvPages, NULL);
e4bf6817370e1a71833a02285515694afcda7599vboxsync}
e4bf6817370e1a71833a02285515694afcda7599vboxsync
e4bf6817370e1a71833a02285515694afcda7599vboxsync
e4bf6817370e1a71833a02285515694afcda7599vboxsync/**
e4bf6817370e1a71833a02285515694afcda7599vboxsync * Fallback for SUPPageAllocLockedEx on systems where RTR0MemObjPhysAllocNC isn't supported.
e4bf6817370e1a71833a02285515694afcda7599vboxsync */
e4bf6817370e1a71833a02285515694afcda7599vboxsyncstatic int supPageAllocLockedFallback(size_t cPages, void **ppvPages, PSUPPAGE paPages)
e4bf6817370e1a71833a02285515694afcda7599vboxsync{
e4bf6817370e1a71833a02285515694afcda7599vboxsync int rc = suplibOsPageAlloc(&g_supLibData, cPages, ppvPages);
725fba5c64717677ac66072bae37e5b3686f3e6dvboxsync if (RT_SUCCESS(rc))
e4bf6817370e1a71833a02285515694afcda7599vboxsync {
e4bf6817370e1a71833a02285515694afcda7599vboxsync if (!paPages)
e4bf6817370e1a71833a02285515694afcda7599vboxsync paPages = (PSUPPAGE)alloca(sizeof(paPages[0]) * cPages);
725fba5c64717677ac66072bae37e5b3686f3e6dvboxsync rc = SUPPageLock(*ppvPages, cPages, paPages);
725fba5c64717677ac66072bae37e5b3686f3e6dvboxsync if (RT_FAILURE(rc))
e4bf6817370e1a71833a02285515694afcda7599vboxsync suplibOsPageFree(&g_supLibData, *ppvPages, cPages);
e4bf6817370e1a71833a02285515694afcda7599vboxsync }
e4bf6817370e1a71833a02285515694afcda7599vboxsync return rc;
e4bf6817370e1a71833a02285515694afcda7599vboxsync}
e4bf6817370e1a71833a02285515694afcda7599vboxsync
e4bf6817370e1a71833a02285515694afcda7599vboxsync
e4bf6817370e1a71833a02285515694afcda7599vboxsyncSUPR3DECL(int) SUPPageAllocLockedEx(size_t cPages, void **ppvPages, PSUPPAGE paPages)
e4bf6817370e1a71833a02285515694afcda7599vboxsync{
e4bf6817370e1a71833a02285515694afcda7599vboxsync /*
725fba5c64717677ac66072bae37e5b3686f3e6dvboxsync * Validate.
e4bf6817370e1a71833a02285515694afcda7599vboxsync */
e4bf6817370e1a71833a02285515694afcda7599vboxsync AssertPtrReturn(ppvPages, VERR_INVALID_POINTER);
725fba5c64717677ac66072bae37e5b3686f3e6dvboxsync *ppvPages = NULL;
725fba5c64717677ac66072bae37e5b3686f3e6dvboxsync AssertReturn(cPages > 0, VERR_INVALID_PARAMETER);
725fba5c64717677ac66072bae37e5b3686f3e6dvboxsync
725fba5c64717677ac66072bae37e5b3686f3e6dvboxsync /* fake */
725fba5c64717677ac66072bae37e5b3686f3e6dvboxsync if (RT_UNLIKELY(g_u32FakeMode))
725fba5c64717677ac66072bae37e5b3686f3e6dvboxsync {
725fba5c64717677ac66072bae37e5b3686f3e6dvboxsync *ppvPages = RTMemPageAllocZ((size_t)cPages * PAGE_SIZE);
725fba5c64717677ac66072bae37e5b3686f3e6dvboxsync if (!*ppvPages)
725fba5c64717677ac66072bae37e5b3686f3e6dvboxsync return VERR_NO_MEMORY;
725fba5c64717677ac66072bae37e5b3686f3e6dvboxsync if (paPages)
725fba5c64717677ac66072bae37e5b3686f3e6dvboxsync for (size_t iPage = 0; iPage < cPages; iPage++)
725fba5c64717677ac66072bae37e5b3686f3e6dvboxsync {
725fba5c64717677ac66072bae37e5b3686f3e6dvboxsync paPages[iPage].uReserved = 0;
725fba5c64717677ac66072bae37e5b3686f3e6dvboxsync paPages[iPage].Phys = (iPage + 1234) << PAGE_SHIFT;
725fba5c64717677ac66072bae37e5b3686f3e6dvboxsync Assert(!(paPages[iPage].Phys & ~X86_PTE_PAE_PG_MASK));
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync }
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync return VINF_SUCCESS;
7468341cace5f5d2287abd9b8c3543033c7bf049vboxsync }
7468341cace5f5d2287abd9b8c3543033c7bf049vboxsync
725fba5c64717677ac66072bae37e5b3686f3e6dvboxsync /* use fallback? */
967f50840df88ba3efcb33939c933400a70fe9b5vboxsync if (!g_fSupportsPageAllocLocked)
725fba5c64717677ac66072bae37e5b3686f3e6dvboxsync return supPageAllocLockedFallback(cPages, ppvPages, paPages);
967f50840df88ba3efcb33939c933400a70fe9b5vboxsync
725fba5c64717677ac66072bae37e5b3686f3e6dvboxsync /*
725fba5c64717677ac66072bae37e5b3686f3e6dvboxsync * Issue IOCtl to the SUPDRV kernel module.
725fba5c64717677ac66072bae37e5b3686f3e6dvboxsync */
725fba5c64717677ac66072bae37e5b3686f3e6dvboxsync int rc;
725fba5c64717677ac66072bae37e5b3686f3e6dvboxsync PSUPPAGEALLOC pReq = (PSUPPAGEALLOC)RTMemTmpAllocZ(SUP_IOCTL_PAGE_ALLOC_SIZE(cPages));
725fba5c64717677ac66072bae37e5b3686f3e6dvboxsync if (pReq)
725fba5c64717677ac66072bae37e5b3686f3e6dvboxsync {
725fba5c64717677ac66072bae37e5b3686f3e6dvboxsync pReq->Hdr.u32Cookie = g_u32Cookie;
7468341cace5f5d2287abd9b8c3543033c7bf049vboxsync pReq->Hdr.u32SessionCookie = g_u32SessionCookie;
725fba5c64717677ac66072bae37e5b3686f3e6dvboxsync pReq->Hdr.cbIn = SUP_IOCTL_PAGE_ALLOC_SIZE_IN;
725fba5c64717677ac66072bae37e5b3686f3e6dvboxsync pReq->Hdr.cbOut = SUP_IOCTL_PAGE_ALLOC_SIZE_OUT(cPages);
725fba5c64717677ac66072bae37e5b3686f3e6dvboxsync pReq->Hdr.fFlags = SUPREQHDR_FLAGS_MAGIC | SUPREQHDR_FLAGS_EXTRA_OUT;
725fba5c64717677ac66072bae37e5b3686f3e6dvboxsync pReq->Hdr.rc = VERR_INTERNAL_ERROR;
7468341cace5f5d2287abd9b8c3543033c7bf049vboxsync pReq->u.In.cPages = (uint32_t)cPages; AssertRelease(pReq->u.In.cPages == cPages);
7468341cace5f5d2287abd9b8c3543033c7bf049vboxsync rc = suplibOsIOCtl(&g_supLibData, SUP_IOCTL_PAGE_ALLOC, pReq, SUP_IOCTL_PAGE_ALLOC_SIZE(cPages));
725fba5c64717677ac66072bae37e5b3686f3e6dvboxsync if (RT_SUCCESS(rc))
725fba5c64717677ac66072bae37e5b3686f3e6dvboxsync {
725fba5c64717677ac66072bae37e5b3686f3e6dvboxsync rc = pReq->Hdr.rc;
725fba5c64717677ac66072bae37e5b3686f3e6dvboxsync if (RT_SUCCESS(rc))
e4bf6817370e1a71833a02285515694afcda7599vboxsync {
e4bf6817370e1a71833a02285515694afcda7599vboxsync *ppvPages = pReq->u.Out.pvR3;
7468341cace5f5d2287abd9b8c3543033c7bf049vboxsync if (paPages)
7468341cace5f5d2287abd9b8c3543033c7bf049vboxsync for (size_t iPage = 0; iPage < cPages; iPage++)
7468341cace5f5d2287abd9b8c3543033c7bf049vboxsync {
7468341cace5f5d2287abd9b8c3543033c7bf049vboxsync paPages[iPage].uReserved = 0;
7468341cace5f5d2287abd9b8c3543033c7bf049vboxsync paPages[iPage].Phys = pReq->u.Out.aPages[iPage];
7468341cace5f5d2287abd9b8c3543033c7bf049vboxsync Assert(!(paPages[iPage].Phys & ~X86_PTE_PAE_PG_MASK));
7468341cace5f5d2287abd9b8c3543033c7bf049vboxsync }
7468341cace5f5d2287abd9b8c3543033c7bf049vboxsync }
7468341cace5f5d2287abd9b8c3543033c7bf049vboxsync else if (rc == VERR_NOT_SUPPORTED)
7468341cace5f5d2287abd9b8c3543033c7bf049vboxsync {
7468341cace5f5d2287abd9b8c3543033c7bf049vboxsync g_fSupportsPageAllocLocked = false;
7468341cace5f5d2287abd9b8c3543033c7bf049vboxsync rc = supPageAllocLockedFallback(cPages, ppvPages, paPages);
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync }
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync }
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync RTMemTmpFree(pReq);
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync }
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync else
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync rc = VERR_NO_TMP_MEMORY;
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync return rc;
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync}
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsyncSUPR3DECL(int) SUPPageFreeLocked(void *pvPages, size_t cPages)
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync{
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync /*
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync * Validate.
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync */
967f50840df88ba3efcb33939c933400a70fe9b5vboxsync AssertPtrReturn(pvPages, VERR_INVALID_POINTER);
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync AssertReturn(cPages > 0, VERR_INVALID_PARAMETER);
967f50840df88ba3efcb33939c933400a70fe9b5vboxsync
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync /* fake */
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync if (RT_UNLIKELY(g_u32FakeMode))
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync {
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync RTMemPageFree(pvPages);
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync return VINF_SUCCESS;
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync }
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync /*
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync * Issue IOCtl to the SUPDRV kernel module.
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync */
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync int rc;
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync if (g_fSupportsPageAllocLocked)
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync {
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync SUPPAGEFREE Req;
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync Req.Hdr.u32Cookie = g_u32Cookie;
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync Req.Hdr.u32SessionCookie = g_u32SessionCookie;
725fba5c64717677ac66072bae37e5b3686f3e6dvboxsync Req.Hdr.cbIn = SUP_IOCTL_PAGE_FREE_SIZE_IN;
725fba5c64717677ac66072bae37e5b3686f3e6dvboxsync Req.Hdr.cbOut = SUP_IOCTL_PAGE_FREE_SIZE_OUT;
725fba5c64717677ac66072bae37e5b3686f3e6dvboxsync Req.Hdr.fFlags = SUPREQHDR_FLAGS_DEFAULT;
725fba5c64717677ac66072bae37e5b3686f3e6dvboxsync Req.Hdr.rc = VERR_INTERNAL_ERROR;
725fba5c64717677ac66072bae37e5b3686f3e6dvboxsync Req.u.In.pvR3 = pvPages;
967f50840df88ba3efcb33939c933400a70fe9b5vboxsync rc = suplibOsIOCtl(&g_supLibData, SUP_IOCTL_PAGE_FREE, &Req, SUP_IOCTL_PAGE_FREE_SIZE);
725fba5c64717677ac66072bae37e5b3686f3e6dvboxsync if (RT_SUCCESS(rc))
725fba5c64717677ac66072bae37e5b3686f3e6dvboxsync rc = Req.Hdr.rc;
725fba5c64717677ac66072bae37e5b3686f3e6dvboxsync }
725fba5c64717677ac66072bae37e5b3686f3e6dvboxsync else
725fba5c64717677ac66072bae37e5b3686f3e6dvboxsync {
725fba5c64717677ac66072bae37e5b3686f3e6dvboxsync /* fallback */
725fba5c64717677ac66072bae37e5b3686f3e6dvboxsync rc = SUPPageUnlock(pvPages);
725fba5c64717677ac66072bae37e5b3686f3e6dvboxsync if (RT_SUCCESS(rc))
725fba5c64717677ac66072bae37e5b3686f3e6dvboxsync rc = suplibOsPageFree(&g_supLibData, pvPages, cPages);
725fba5c64717677ac66072bae37e5b3686f3e6dvboxsync }
725fba5c64717677ac66072bae37e5b3686f3e6dvboxsync return rc;
725fba5c64717677ac66072bae37e5b3686f3e6dvboxsync}
725fba5c64717677ac66072bae37e5b3686f3e6dvboxsync
725fba5c64717677ac66072bae37e5b3686f3e6dvboxsync
725fba5c64717677ac66072bae37e5b3686f3e6dvboxsyncSUPR3DECL(void *) SUPContAlloc(size_t cPages, PRTHCPHYS pHCPhys)
725fba5c64717677ac66072bae37e5b3686f3e6dvboxsync{
725fba5c64717677ac66072bae37e5b3686f3e6dvboxsync return SUPContAlloc2(cPages, NIL_RTR0PTR, pHCPhys);
725fba5c64717677ac66072bae37e5b3686f3e6dvboxsync}
725fba5c64717677ac66072bae37e5b3686f3e6dvboxsync
725fba5c64717677ac66072bae37e5b3686f3e6dvboxsync
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsyncSUPR3DECL(void *) SUPContAlloc2(size_t cPages, PRTR0PTR pR0Ptr, PRTHCPHYS pHCPhys)
725fba5c64717677ac66072bae37e5b3686f3e6dvboxsync{
725fba5c64717677ac66072bae37e5b3686f3e6dvboxsync /*
725fba5c64717677ac66072bae37e5b3686f3e6dvboxsync * Validate.
725fba5c64717677ac66072bae37e5b3686f3e6dvboxsync */
725fba5c64717677ac66072bae37e5b3686f3e6dvboxsync AssertPtrReturn(pHCPhys, NULL);
725fba5c64717677ac66072bae37e5b3686f3e6dvboxsync *pHCPhys = NIL_RTHCPHYS;
725fba5c64717677ac66072bae37e5b3686f3e6dvboxsync AssertPtrNullReturn(pR0Ptr, NULL);
725fba5c64717677ac66072bae37e5b3686f3e6dvboxsync if (pR0Ptr)
725fba5c64717677ac66072bae37e5b3686f3e6dvboxsync *pR0Ptr = NIL_RTR0PTR;
725fba5c64717677ac66072bae37e5b3686f3e6dvboxsync AssertPtrNullReturn(pHCPhys, NULL);
725fba5c64717677ac66072bae37e5b3686f3e6dvboxsync AssertMsgReturn(cPages > 0 && cPages < 256, ("cPages=%d must be > 0 and < 256\n", cPages), NULL);
725fba5c64717677ac66072bae37e5b3686f3e6dvboxsync
725fba5c64717677ac66072bae37e5b3686f3e6dvboxsync /* fake */
725fba5c64717677ac66072bae37e5b3686f3e6dvboxsync if (RT_UNLIKELY(g_u32FakeMode))
725fba5c64717677ac66072bae37e5b3686f3e6dvboxsync {
725fba5c64717677ac66072bae37e5b3686f3e6dvboxsync void *pv = RTMemPageAllocZ(cPages * PAGE_SIZE);
725fba5c64717677ac66072bae37e5b3686f3e6dvboxsync if (pR0Ptr)
725fba5c64717677ac66072bae37e5b3686f3e6dvboxsync *pR0Ptr = (RTR0PTR)pv;
725fba5c64717677ac66072bae37e5b3686f3e6dvboxsync if (pHCPhys)
725fba5c64717677ac66072bae37e5b3686f3e6dvboxsync *pHCPhys = (uintptr_t)pv + (PAGE_SHIFT * 1024);
725fba5c64717677ac66072bae37e5b3686f3e6dvboxsync return pv;
725fba5c64717677ac66072bae37e5b3686f3e6dvboxsync }
725fba5c64717677ac66072bae37e5b3686f3e6dvboxsync
725fba5c64717677ac66072bae37e5b3686f3e6dvboxsync /*
725fba5c64717677ac66072bae37e5b3686f3e6dvboxsync * Issue IOCtl to the SUPDRV kernel module.
725fba5c64717677ac66072bae37e5b3686f3e6dvboxsync */
725fba5c64717677ac66072bae37e5b3686f3e6dvboxsync SUPCONTALLOC Req;
725fba5c64717677ac66072bae37e5b3686f3e6dvboxsync Req.Hdr.u32Cookie = g_u32Cookie;
725fba5c64717677ac66072bae37e5b3686f3e6dvboxsync Req.Hdr.u32SessionCookie = g_u32SessionCookie;
725fba5c64717677ac66072bae37e5b3686f3e6dvboxsync Req.Hdr.cbIn = SUP_IOCTL_CONT_ALLOC_SIZE_IN;
725fba5c64717677ac66072bae37e5b3686f3e6dvboxsync Req.Hdr.cbOut = SUP_IOCTL_CONT_ALLOC_SIZE_OUT;
725fba5c64717677ac66072bae37e5b3686f3e6dvboxsync Req.Hdr.fFlags = SUPREQHDR_FLAGS_DEFAULT;
725fba5c64717677ac66072bae37e5b3686f3e6dvboxsync Req.Hdr.rc = VERR_INTERNAL_ERROR;
725fba5c64717677ac66072bae37e5b3686f3e6dvboxsync Req.u.In.cPages = (uint32_t)cPages;
725fba5c64717677ac66072bae37e5b3686f3e6dvboxsync int rc = suplibOsIOCtl(&g_supLibData, SUP_IOCTL_CONT_ALLOC, &Req, SUP_IOCTL_CONT_ALLOC_SIZE);
725fba5c64717677ac66072bae37e5b3686f3e6dvboxsync if ( RT_SUCCESS(rc)
725fba5c64717677ac66072bae37e5b3686f3e6dvboxsync && RT_SUCCESS(Req.Hdr.rc))
725fba5c64717677ac66072bae37e5b3686f3e6dvboxsync {
725fba5c64717677ac66072bae37e5b3686f3e6dvboxsync *pHCPhys = Req.u.Out.HCPhys;
725fba5c64717677ac66072bae37e5b3686f3e6dvboxsync if (pR0Ptr)
725fba5c64717677ac66072bae37e5b3686f3e6dvboxsync *pR0Ptr = Req.u.Out.pvR0;
725fba5c64717677ac66072bae37e5b3686f3e6dvboxsync return Req.u.Out.pvR3;
725fba5c64717677ac66072bae37e5b3686f3e6dvboxsync }
725fba5c64717677ac66072bae37e5b3686f3e6dvboxsync
725fba5c64717677ac66072bae37e5b3686f3e6dvboxsync return NULL;
725fba5c64717677ac66072bae37e5b3686f3e6dvboxsync}
725fba5c64717677ac66072bae37e5b3686f3e6dvboxsync
725fba5c64717677ac66072bae37e5b3686f3e6dvboxsync
725fba5c64717677ac66072bae37e5b3686f3e6dvboxsyncSUPR3DECL(int) SUPContFree(void *pv, size_t cPages)
725fba5c64717677ac66072bae37e5b3686f3e6dvboxsync{
725fba5c64717677ac66072bae37e5b3686f3e6dvboxsync /*
725fba5c64717677ac66072bae37e5b3686f3e6dvboxsync * Validate.
725fba5c64717677ac66072bae37e5b3686f3e6dvboxsync */
725fba5c64717677ac66072bae37e5b3686f3e6dvboxsync if (!pv)
725fba5c64717677ac66072bae37e5b3686f3e6dvboxsync return VINF_SUCCESS;
725fba5c64717677ac66072bae37e5b3686f3e6dvboxsync AssertPtrReturn(pv, VERR_INVALID_POINTER);
725fba5c64717677ac66072bae37e5b3686f3e6dvboxsync AssertReturn(cPages > 0, VERR_INVALID_PARAMETER);
725fba5c64717677ac66072bae37e5b3686f3e6dvboxsync
725fba5c64717677ac66072bae37e5b3686f3e6dvboxsync /* fake */
725fba5c64717677ac66072bae37e5b3686f3e6dvboxsync if (RT_UNLIKELY(g_u32FakeMode))
725fba5c64717677ac66072bae37e5b3686f3e6dvboxsync {
e4bf6817370e1a71833a02285515694afcda7599vboxsync RTMemPageFree(pv);
e4bf6817370e1a71833a02285515694afcda7599vboxsync return VINF_SUCCESS;
7468341cace5f5d2287abd9b8c3543033c7bf049vboxsync }
7468341cace5f5d2287abd9b8c3543033c7bf049vboxsync
7468341cace5f5d2287abd9b8c3543033c7bf049vboxsync /*
7468341cace5f5d2287abd9b8c3543033c7bf049vboxsync * Issue IOCtl to the SUPDRV kernel module.
7468341cace5f5d2287abd9b8c3543033c7bf049vboxsync */
7468341cace5f5d2287abd9b8c3543033c7bf049vboxsync SUPCONTFREE Req;
7468341cace5f5d2287abd9b8c3543033c7bf049vboxsync Req.Hdr.u32Cookie = g_u32Cookie;
7468341cace5f5d2287abd9b8c3543033c7bf049vboxsync Req.Hdr.u32SessionCookie = g_u32SessionCookie;
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync Req.Hdr.cbIn = SUP_IOCTL_CONT_FREE_SIZE_IN;
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync Req.Hdr.cbOut = SUP_IOCTL_CONT_FREE_SIZE_OUT;
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync Req.Hdr.fFlags = SUPREQHDR_FLAGS_DEFAULT;
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync Req.Hdr.rc = VERR_INTERNAL_ERROR;
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync Req.u.In.pvR3 = pv;
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync int rc = suplibOsIOCtl(&g_supLibData, SUP_IOCTL_CONT_FREE, &Req, SUP_IOCTL_CONT_FREE_SIZE);
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync if (RT_SUCCESS(rc))
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync rc = Req.Hdr.rc;
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync return rc;
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync}
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsyncSUPR3DECL(int) SUPLowAlloc(size_t cPages, void **ppvPages, PRTR0PTR ppvPagesR0, PSUPPAGE paPages)
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync{
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync /*
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync * Validate.
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync */
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync AssertPtrReturn(ppvPages, VERR_INVALID_POINTER);
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync *ppvPages = NULL;
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync AssertPtrReturn(paPages, VERR_INVALID_POINTER);
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync AssertMsgReturn(cPages > 0 && cPages < 256, ("cPages=%d must be > 0 and < 256\n", cPages), VERR_INVALID_PARAMETER);
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync /* fake */
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync if (RT_UNLIKELY(g_u32FakeMode))
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync {
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync *ppvPages = RTMemPageAllocZ((size_t)cPages * PAGE_SIZE);
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync if (!*ppvPages)
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync return VERR_NO_LOW_MEMORY;
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync /* fake physical addresses. */
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync RTHCPHYS Phys = (uintptr_t)*ppvPages + PAGE_SIZE * 1024;
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync size_t iPage = cPages;
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync while (iPage-- > 0)
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync paPages[iPage].Phys = Phys + (iPage << PAGE_SHIFT);
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync return VINF_SUCCESS;
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync }
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync /*
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync * Issue IOCtl to the SUPDRV kernel module.
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync */
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync int rc;
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync PSUPLOWALLOC pReq = (PSUPLOWALLOC)RTMemTmpAllocZ(SUP_IOCTL_LOW_ALLOC_SIZE(cPages));
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync if (pReq)
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync {
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync pReq->Hdr.u32Cookie = g_u32Cookie;
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync pReq->Hdr.u32SessionCookie = g_u32SessionCookie;
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync pReq->Hdr.cbIn = SUP_IOCTL_LOW_ALLOC_SIZE_IN;
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync pReq->Hdr.cbOut = SUP_IOCTL_LOW_ALLOC_SIZE_OUT(cPages);
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync pReq->Hdr.fFlags = SUPREQHDR_FLAGS_MAGIC | SUPREQHDR_FLAGS_EXTRA_OUT;
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync pReq->Hdr.rc = VERR_INTERNAL_ERROR;
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync pReq->u.In.cPages = (uint32_t)cPages; AssertRelease(pReq->u.In.cPages == cPages);
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync rc = suplibOsIOCtl(&g_supLibData, SUP_IOCTL_LOW_ALLOC, pReq, SUP_IOCTL_LOW_ALLOC_SIZE(cPages));
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync if (RT_SUCCESS(rc))
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync rc = pReq->Hdr.rc;
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync if (RT_SUCCESS(rc))
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync {
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync *ppvPages = pReq->u.Out.pvR3;
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync if (ppvPagesR0)
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync *ppvPagesR0 = pReq->u.Out.pvR0;
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync if (paPages)
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync for (size_t iPage = 0; iPage < cPages; iPage++)
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync {
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync paPages[iPage].uReserved = 0;
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync paPages[iPage].Phys = pReq->u.Out.aPages[iPage];
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync Assert(!(paPages[iPage].Phys & ~X86_PTE_PAE_PG_MASK));
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync Assert(paPages[iPage].Phys <= UINT32_C(0xfffff000));
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync }
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync }
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync RTMemTmpFree(pReq);
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync }
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync else
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync rc = VERR_NO_TMP_MEMORY;
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync return rc;
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync}
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsyncSUPR3DECL(int) SUPLowFree(void *pv, size_t cPages)
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync{
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync /*
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync * Validate.
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync */
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync if (!pv)
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync return VINF_SUCCESS;
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync AssertPtrReturn(pv, VERR_INVALID_POINTER);
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync AssertReturn(cPages > 0, VERR_INVALID_PARAMETER);
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync /* fake */
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync if (RT_UNLIKELY(g_u32FakeMode))
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync {
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync RTMemPageFree(pv);
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync return VINF_SUCCESS;
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync }
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync /*
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync * Issue IOCtl to the SUPDRV kernel module.
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync */
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync SUPCONTFREE Req;
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync Req.Hdr.u32Cookie = g_u32Cookie;
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync Req.Hdr.u32SessionCookie = g_u32SessionCookie;
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync Req.Hdr.cbIn = SUP_IOCTL_LOW_FREE_SIZE_IN;
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync Req.Hdr.cbOut = SUP_IOCTL_LOW_FREE_SIZE_OUT;
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync Req.Hdr.fFlags = SUPREQHDR_FLAGS_DEFAULT;
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync Req.Hdr.rc = VERR_INTERNAL_ERROR;
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync Req.u.In.pvR3 = pv;
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync int rc = suplibOsIOCtl(&g_supLibData, SUP_IOCTL_LOW_FREE, &Req, SUP_IOCTL_LOW_FREE_SIZE);
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync if (RT_SUCCESS(rc))
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync rc = Req.Hdr.rc;
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync return rc;
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync}
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsyncSUPR3DECL(int) SUPR3HardenedVerifyFile(const char *pszFilename, const char *pszMsg, PRTFILE phFile)
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync{
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync /*
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync * Quick input validation.
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync */
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync AssertPtr(pszFilename);
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync AssertPtr(pszMsg);
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync AssertReturn(!phFile, VERR_NOT_IMPLEMENTED); /** @todo Implement this. The deal is that we make sure the
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync file is the same we verified after opening it. */
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync /*
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync * Only do the actual check in hardened builds.
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync */
7468341cace5f5d2287abd9b8c3543033c7bf049vboxsync#ifdef VBOX_WITH_HARDENING
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync int rc = supR3HardenedVerifyFile(pszFilename, false /* fFatal */);
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync if (RT_FAILURE(rc))
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync LogRel(("SUPR3HardenedVerifyFile: %s: Verification of \"%s\" failed, rc=%Rrc\n", pszMsg, pszFilename, rc));
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync return rc;
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync#else
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync return VINF_SUCCESS;
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync#endif
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync}
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsyncSUPR3DECL(int) SUPLoadModule(const char *pszFilename, const char *pszModule, void **ppvImageBase)
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync{
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync int rc = VINF_SUCCESS;
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync#ifdef VBOX_WITH_HARDENING
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync /*
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync * Check that the module can be trusted.
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync */
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync rc = supR3HardenedVerifyFile(pszFilename, false /* fFatal */);
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync#endif
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync if (RT_SUCCESS(rc))
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync {
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync /*
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync * Load the module.
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync * If it's VMMR0.r0 we need to install the IDTE.
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync */
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync rc = supLoadModule(pszFilename, pszModule, ppvImageBase);
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync#ifdef VBOX_WITH_IDT_PATCHING
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync if ( RT_SUCCESS(rc)
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync && !strcmp(pszModule, "VMMR0.r0"))
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync {
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync rc = supInstallIDTE();
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync if (RT_FAILURE(rc))
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync SUPFreeModule(*ppvImageBase);
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync }
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync#endif /* VBOX_WITH_IDT_PATCHING */
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync }
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync else
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync LogRel(("SUPLoadModule: Verification of \"%s\" failed, rc=%Rrc\n", rc));
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync return rc;
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync}
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync#ifdef VBOX_WITH_IDT_PATCHING
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync/**
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync * Generates the code for calling the interrupt gate.
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync *
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync * @returns VBox status code.
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync * g_pfnCallVMMR0 is changed on success.
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync * @param u8Interrupt The interrupt number.
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync */
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsyncstatic int suplibGenerateCallVMMR0(uint8_t u8Interrupt)
5902b558ec0657b3ee3cdba4deaa190f6fe182f1vboxsync{
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync /*
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync * Allocate memory.
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync */
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync uint8_t *pb = (uint8_t *)RTMemExecAlloc(256);
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync AssertReturn(pb, VERR_NO_MEMORY);
e8859cfff41731e3688972d64cf6d5575addcd8fvboxsync memset(pb, 0xcc, 256);
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync Assert(!g_pfnCallVMMR0);
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync g_pfnCallVMMR0 = *(PFNCALLVMMR0*)&pb;
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync /*
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync * Generate the code.
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync */
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync#ifdef RT_ARCH_AMD64
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync /*
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync * reg params:
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync * <GCC> <MSC> <argument>
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync * rdi rcx pVMR0
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync * esi edx uOperation
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync * rdx r8 pvArg
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync *
7468341cace5f5d2287abd9b8c3543033c7bf049vboxsync * eax eax [g_u32Gookie]
7468341cace5f5d2287abd9b8c3543033c7bf049vboxsync */
4e47bb772df0d04d1ded3e06354de547d52e2d06vboxsync *pb++ = 0xb8; /* mov eax, <g_u32Cookie> */
e8859cfff41731e3688972d64cf6d5575addcd8fvboxsync *(uint32_t *)pb = g_u32Cookie;
e8859cfff41731e3688972d64cf6d5575addcd8fvboxsync pb += sizeof(uint32_t);
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync *pb++ = 0xcd; /* int <u8Interrupt> */
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync *pb++ = u8Interrupt;
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync
e8859cfff41731e3688972d64cf6d5575addcd8fvboxsync *pb++ = 0xc3; /* ret */
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync
3bb3e26b3306b9f62b18c17380bdf2ca3a98ca49vboxsync#else
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync /*
e8859cfff41731e3688972d64cf6d5575addcd8fvboxsync * x86 stack:
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync * 0 saved esi
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync * 0 4 ret
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync * 4 8 pVM
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync * 8 c uOperation
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync * c 10 pvArg
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync */
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync *pb++ = 0x56; /* push esi */
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync *pb++ = 0x8b; /* mov eax, [pVM] */
d1e9999d55e7ac80a28692c161710be98071fc00vboxsync *pb++ = 0x44;
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync *pb++ = 0x24;
d1e9999d55e7ac80a28692c161710be98071fc00vboxsync *pb++ = 0x08; /* esp+08h */
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync
d1e9999d55e7ac80a28692c161710be98071fc00vboxsync *pb++ = 0x8b; /* mov edx, [uOperation] */
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync *pb++ = 0x54;
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync *pb++ = 0x24;
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync *pb++ = 0x0c; /* esp+0ch */
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync *pb++ = 0x8b; /* mov ecx, [pvArg] */
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync *pb++ = 0x4c;
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync *pb++ = 0x24;
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync *pb++ = 0x10; /* esp+10h */
d1e9999d55e7ac80a28692c161710be98071fc00vboxsync
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync *pb++ = 0xbe; /* mov esi, <g_u32Cookie> */
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync *(uint32_t *)pb = g_u32Cookie;
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync pb += sizeof(uint32_t);
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync *pb++ = 0xcd; /* int <u8Interrupt> */
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync *pb++ = u8Interrupt;
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync *pb++ = 0x5e; /* pop esi */
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync *pb++ = 0xc3; /* ret */
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync#endif
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync return VINF_SUCCESS;
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync}
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync/**
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync * Installs the IDTE patch.
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync *
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync * @return VBox status code.
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync */
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsyncstatic int supInstallIDTE(void)
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync{
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync /* already installed? */
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync if (g_u8Interrupt != 3 || g_u32FakeMode)
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync return VINF_SUCCESS;
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync int rc = VINF_SUCCESS;
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync const RTCPUID cCpus = RTMpGetCount();
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync if (cCpus <= 1)
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync {
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync /* UNI */
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync SUPIDTINSTALL Req;
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync Req.Hdr.u32Cookie = g_u32Cookie;
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync Req.Hdr.u32SessionCookie = g_u32SessionCookie;
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync Req.Hdr.cbIn = SUP_IOCTL_IDT_INSTALL_SIZE_IN;
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync Req.Hdr.cbOut = SUP_IOCTL_IDT_INSTALL_SIZE_OUT;
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync Req.Hdr.fFlags = SUPREQHDR_FLAGS_DEFAULT;
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync Req.Hdr.rc = VERR_INTERNAL_ERROR;
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync rc = suplibOsIOCtl(&g_supLibData, SUP_IOCTL_IDT_INSTALL, &Req, SUP_IOCTL_IDT_INSTALL_SIZE);
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync if (RT_SUCCESS(rc))
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync rc = Req.Hdr.rc;
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync if (RT_SUCCESS(rc))
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync {
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync g_u8Interrupt = Req.u.Out.u8Idt;
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync rc = suplibGenerateCallVMMR0(Req.u.Out.u8Idt);
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync }
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync }
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync else
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync {
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync /* SMP */
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync uint64_t u64AffMaskSaved = RTThreadGetAffinity();
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync RTCPUSET OnlineSet;
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync uint64_t u64AffMaskPatched = RTCpuSetToU64(RTMpGetOnlineSet(&OnlineSet)) & u64AffMaskSaved;
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync unsigned cCpusPatched = 0;
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync AssertLogRelReturn(cCpus < 64, VERR_INTERNAL_ERROR);
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync for (int i = 0; i < 64; i++)
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync {
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync /* Skip absent and inactive processors. */
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync uint64_t u64Mask = 1ULL << i;
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync if (!(u64Mask & u64AffMaskPatched))
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync continue;
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync /* Change CPU */
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync int rc2 = RTThreadSetAffinity(u64Mask);
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync if (RT_FAILURE(rc2))
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync {
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync u64AffMaskPatched &= ~u64Mask;
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync LogRel(("SUPLoadVMM: Failed to set affinity to cpu no. %d, rc=%Rrc.\n", i, rc2));
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync continue;
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync }
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync /* Patch the CPU. */
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync SUPIDTINSTALL Req;
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync Req.Hdr.u32Cookie = g_u32Cookie;
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync Req.Hdr.u32SessionCookie = g_u32SessionCookie;
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync Req.Hdr.cbIn = SUP_IOCTL_IDT_INSTALL_SIZE_IN;
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync Req.Hdr.cbOut = SUP_IOCTL_IDT_INSTALL_SIZE_OUT;
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync Req.Hdr.fFlags = SUPREQHDR_FLAGS_DEFAULT;
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync Req.Hdr.rc = VERR_INTERNAL_ERROR;
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync rc2 = suplibOsIOCtl(&g_supLibData, SUP_IOCTL_IDT_INSTALL, &Req, SUP_IOCTL_IDT_INSTALL_SIZE);
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync if (RT_SUCCESS(rc2))
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync rc2 = Req.Hdr.rc;
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync if (RT_SUCCESS(rc2))
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync {
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync if (!cCpusPatched)
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync {
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync g_u8Interrupt = Req.u.Out.u8Idt;
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync rc2 = suplibGenerateCallVMMR0(Req.u.Out.u8Idt);
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync if (RT_FAILURE(rc2))
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync {
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync LogRel(("suplibGenerateCallVMMR0 failed with rc=%Rrc.\n", i, rc2));
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync rc = rc2;
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync }
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync }
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync else
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync Assert(g_u8Interrupt == Req.u.Out.u8Idt);
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync cCpusPatched++;
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync }
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync else
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync {
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync LogRel(("SUPLoadVMM: Failed to patch cpu no. %d, rc=%Rrc.\n", i, rc2));
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync if (RT_SUCCESS(rc))
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync rc = rc2;
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync }
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync }
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync /* Fail if no CPUs was patched! */
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync if (RT_SUCCESS(rc) && cCpusPatched <= 0)
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync rc = VERR_GENERAL_FAILURE;
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync /* Ignore failures if a CPU was patched. */
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync else if (RT_FAILURE(rc) && cCpusPatched > 0)
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync rc = VINF_SUCCESS;
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync /* Set/restore the thread affinity. */
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync if (RT_SUCCESS(rc))
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync {
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync rc = RTThreadSetAffinity(u64AffMaskPatched);
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync AssertRC(rc);
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync }
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync else
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync {
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync int rc2 = RTThreadSetAffinity(u64AffMaskSaved);
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync AssertRC(rc2);
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync }
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync }
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync return rc;
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync}
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync#endif /* VBOX_WITH_IDT_PATCHING */
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync/**
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync * Resolve an external symbol during RTLdrGetBits().
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync *
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync * @returns VBox status code.
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync * @param hLdrMod The loader module handle.
5b0a093ca572a855886faa6747ad46df859dd041vboxsync * @param pszModule Module name.
5b0a093ca572a855886faa6747ad46df859dd041vboxsync * @param pszSymbol Symbol name, NULL if uSymbol should be used.
5b0a093ca572a855886faa6747ad46df859dd041vboxsync * @param uSymbol Symbol ordinal, ~0 if pszSymbol should be used.
5b0a093ca572a855886faa6747ad46df859dd041vboxsync * @param pValue Where to store the symbol value (address).
5b0a093ca572a855886faa6747ad46df859dd041vboxsync * @param pvUser User argument.
5b0a093ca572a855886faa6747ad46df859dd041vboxsync */
5b0a093ca572a855886faa6747ad46df859dd041vboxsyncstatic DECLCALLBACK(int) supLoadModuleResolveImport(RTLDRMOD hLdrMod, const char *pszModule,
5b0a093ca572a855886faa6747ad46df859dd041vboxsync const char *pszSymbol, unsigned uSymbol, RTUINTPTR *pValue, void *pvUser)
5b0a093ca572a855886faa6747ad46df859dd041vboxsync{
5b0a093ca572a855886faa6747ad46df859dd041vboxsync AssertPtr(pValue);
5b0a093ca572a855886faa6747ad46df859dd041vboxsync AssertPtr(pvUser);
5b0a093ca572a855886faa6747ad46df859dd041vboxsync
5b0a093ca572a855886faa6747ad46df859dd041vboxsync /*
5b0a093ca572a855886faa6747ad46df859dd041vboxsync * Only SUPR0 and VMMR0.r0
5b0a093ca572a855886faa6747ad46df859dd041vboxsync */
5b0a093ca572a855886faa6747ad46df859dd041vboxsync if ( pszModule
5b0a093ca572a855886faa6747ad46df859dd041vboxsync && *pszModule
5b0a093ca572a855886faa6747ad46df859dd041vboxsync && strcmp(pszModule, "SUPR0.dll")
5b0a093ca572a855886faa6747ad46df859dd041vboxsync && strcmp(pszModule, "VMMR0.r0"))
5b0a093ca572a855886faa6747ad46df859dd041vboxsync {
5b0a093ca572a855886faa6747ad46df859dd041vboxsync AssertMsgFailed(("%s is importing from %s! (expected 'SUPR0.dll' or 'VMMR0.r0', case-sensitiv)\n", pvUser, pszModule));
5b0a093ca572a855886faa6747ad46df859dd041vboxsync return VERR_SYMBOL_NOT_FOUND;
5b0a093ca572a855886faa6747ad46df859dd041vboxsync }
5b0a093ca572a855886faa6747ad46df859dd041vboxsync
5b0a093ca572a855886faa6747ad46df859dd041vboxsync /*
5b0a093ca572a855886faa6747ad46df859dd041vboxsync * No ordinals.
5b0a093ca572a855886faa6747ad46df859dd041vboxsync */
5b0a093ca572a855886faa6747ad46df859dd041vboxsync if (pszSymbol < (const char*)0x10000)
5b0a093ca572a855886faa6747ad46df859dd041vboxsync {
5b0a093ca572a855886faa6747ad46df859dd041vboxsync AssertMsgFailed(("%s is importing by ordinal (ord=%d)\n", pvUser, (int)(uintptr_t)pszSymbol));
5b0a093ca572a855886faa6747ad46df859dd041vboxsync return VERR_SYMBOL_NOT_FOUND;
5b0a093ca572a855886faa6747ad46df859dd041vboxsync }
5b0a093ca572a855886faa6747ad46df859dd041vboxsync
5b0a093ca572a855886faa6747ad46df859dd041vboxsync /*
5b0a093ca572a855886faa6747ad46df859dd041vboxsync * Lookup symbol.
5b0a093ca572a855886faa6747ad46df859dd041vboxsync */
d1e9999d55e7ac80a28692c161710be98071fc00vboxsync /* skip the 64-bit ELF import prefix first. */
d1e9999d55e7ac80a28692c161710be98071fc00vboxsync if (!strncmp(pszSymbol, "SUPR0$", sizeof("SUPR0$") - 1))
d1e9999d55e7ac80a28692c161710be98071fc00vboxsync pszSymbol += sizeof("SUPR0$") - 1;
d1e9999d55e7ac80a28692c161710be98071fc00vboxsync
d1e9999d55e7ac80a28692c161710be98071fc00vboxsync /*
5b0a093ca572a855886faa6747ad46df859dd041vboxsync * Check the VMMR0.r0 module if loaded.
5b0a093ca572a855886faa6747ad46df859dd041vboxsync */
5b0a093ca572a855886faa6747ad46df859dd041vboxsync /** @todo call the SUPLoadModule caller.... */
70aa086e9e9d2f85d2e997d0e69169018a001e54vboxsync /** @todo proper reference counting and such. */
5b0a093ca572a855886faa6747ad46df859dd041vboxsync if (g_pvVMMR0 != NIL_RTR0PTR)
5b0a093ca572a855886faa6747ad46df859dd041vboxsync {
5b0a093ca572a855886faa6747ad46df859dd041vboxsync void *pvValue;
5b0a093ca572a855886faa6747ad46df859dd041vboxsync if (!SUPGetSymbolR0((void *)g_pvVMMR0, pszSymbol, &pvValue))
5b0a093ca572a855886faa6747ad46df859dd041vboxsync {
5b0a093ca572a855886faa6747ad46df859dd041vboxsync *pValue = (uintptr_t)pvValue;
5b0a093ca572a855886faa6747ad46df859dd041vboxsync return VINF_SUCCESS;
5b0a093ca572a855886faa6747ad46df859dd041vboxsync }
5b0a093ca572a855886faa6747ad46df859dd041vboxsync }
5b0a093ca572a855886faa6747ad46df859dd041vboxsync
5b0a093ca572a855886faa6747ad46df859dd041vboxsync /* iterate the function table. */
5b0a093ca572a855886faa6747ad46df859dd041vboxsync int c = g_pFunctions->u.Out.cFunctions;
d1e9999d55e7ac80a28692c161710be98071fc00vboxsync PSUPFUNC pFunc = &g_pFunctions->u.Out.aFunctions[0];
d3dea25ec07f6546715fe3af943ea863294b392evboxsync while (c-- > 0)
d3dea25ec07f6546715fe3af943ea863294b392evboxsync {
5b0a093ca572a855886faa6747ad46df859dd041vboxsync if (!strcmp(pFunc->szName, pszSymbol))
70aa086e9e9d2f85d2e997d0e69169018a001e54vboxsync {
5b0a093ca572a855886faa6747ad46df859dd041vboxsync *pValue = (uintptr_t)pFunc->pfn;
5b0a093ca572a855886faa6747ad46df859dd041vboxsync return VINF_SUCCESS;
b26e5b503baa3dffc58048982eaf17ad1b53f207vboxsync }
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync pFunc++;
b26e5b503baa3dffc58048982eaf17ad1b53f207vboxsync }
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync /*
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync * The GIP.
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync */
b26e5b503baa3dffc58048982eaf17ad1b53f207vboxsync /** @todo R0 mapping? */
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync if ( pszSymbol
b26e5b503baa3dffc58048982eaf17ad1b53f207vboxsync && g_pSUPGlobalInfoPage
4e47bb772df0d04d1ded3e06354de547d52e2d06vboxsync && g_pSUPGlobalInfoPageR0
4e47bb772df0d04d1ded3e06354de547d52e2d06vboxsync && !strcmp(pszSymbol, "g_SUPGlobalInfoPage"))
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync {
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync *pValue = (uintptr_t)g_pSUPGlobalInfoPageR0;
b26e5b503baa3dffc58048982eaf17ad1b53f207vboxsync return VINF_SUCCESS;
b26e5b503baa3dffc58048982eaf17ad1b53f207vboxsync }
b26e5b503baa3dffc58048982eaf17ad1b53f207vboxsync
b26e5b503baa3dffc58048982eaf17ad1b53f207vboxsync /*
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync * Despair.
b26e5b503baa3dffc58048982eaf17ad1b53f207vboxsync */
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync c = g_pFunctions->u.Out.cFunctions;
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync pFunc = &g_pFunctions->u.Out.aFunctions[0];
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync while (c-- > 0)
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync {
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync AssertMsg2("%d: %s\n", g_pFunctions->u.Out.cFunctions - c, pFunc->szName);
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync pFunc++;
b26e5b503baa3dffc58048982eaf17ad1b53f207vboxsync }
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync AssertMsg2("%s is importing %s which we couldn't find\n", pvUser, pszSymbol);
b26e5b503baa3dffc58048982eaf17ad1b53f207vboxsync AssertMsgFailed(("%s is importing %s which we couldn't find\n", pvUser, pszSymbol));
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync if (g_u32FakeMode)
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync {
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync *pValue = 0xdeadbeef;
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync return VINF_SUCCESS;
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync }
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync return VERR_SYMBOL_NOT_FOUND;
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync}
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsync/** Argument package for supLoadModuleCalcSizeCB. */
4b8c66482cbc69a01ac399b8588b8bc80b310523vboxsynctypedef struct SUPLDRCALCSIZEARGS
da44a59925a62ca7330a244c71b93794016f29f0vboxsync{
da44a59925a62ca7330a244c71b93794016f29f0vboxsync size_t cbStrings;
5902b558ec0657b3ee3cdba4deaa190f6fe182f1vboxsync uint32_t cSymbols;
b26e5b503baa3dffc58048982eaf17ad1b53f207vboxsync size_t cbImage;
b26e5b503baa3dffc58048982eaf17ad1b53f207vboxsync} SUPLDRCALCSIZEARGS, *PSUPLDRCALCSIZEARGS;
b26e5b503baa3dffc58048982eaf17ad1b53f207vboxsync
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync/**
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync * Callback used to calculate the image size.
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync * @return VINF_SUCCESS
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync */
4bf996d915405be92dc4394b2db1395e00e14d58vboxsyncstatic DECLCALLBACK(int) supLoadModuleCalcSizeCB(RTLDRMOD hLdrMod, const char *pszSymbol, unsigned uSymbol, RTUINTPTR Value, void *pvUser)
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync{
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync PSUPLDRCALCSIZEARGS pArgs = (PSUPLDRCALCSIZEARGS)pvUser;
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync if ( pszSymbol != NULL
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync && *pszSymbol
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync && Value <= pArgs->cbImage)
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync {
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync pArgs->cSymbols++;
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync pArgs->cbStrings += strlen(pszSymbol) + 1;
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync }
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync return VINF_SUCCESS;
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync}
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync
b26e5b503baa3dffc58048982eaf17ad1b53f207vboxsync/** Argument package for supLoadModuleCreateTabsCB. */
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsynctypedef struct SUPLDRCREATETABSARGS
b26e5b503baa3dffc58048982eaf17ad1b53f207vboxsync{
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync size_t cbImage;
b26e5b503baa3dffc58048982eaf17ad1b53f207vboxsync PSUPLDRSYM pSym;
b26e5b503baa3dffc58048982eaf17ad1b53f207vboxsync char *pszBase;
b26e5b503baa3dffc58048982eaf17ad1b53f207vboxsync char *psz;
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync} SUPLDRCREATETABSARGS, *PSUPLDRCREATETABSARGS;
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync/**
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync * Callback used to calculate the image size.
b26e5b503baa3dffc58048982eaf17ad1b53f207vboxsync * @return VINF_SUCCESS
b26e5b503baa3dffc58048982eaf17ad1b53f207vboxsync */
b26e5b503baa3dffc58048982eaf17ad1b53f207vboxsyncstatic DECLCALLBACK(int) supLoadModuleCreateTabsCB(RTLDRMOD hLdrMod, const char *pszSymbol, unsigned uSymbol, RTUINTPTR Value, void *pvUser)
b26e5b503baa3dffc58048982eaf17ad1b53f207vboxsync{
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync PSUPLDRCREATETABSARGS pArgs = (PSUPLDRCREATETABSARGS)pvUser;
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync if ( pszSymbol != NULL
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync && *pszSymbol
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync && Value <= pArgs->cbImage)
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync {
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync pArgs->pSym->offSymbol = (uint32_t)Value;
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync pArgs->pSym->offName = pArgs->psz - pArgs->pszBase;
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync pArgs->pSym++;
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync
b26e5b503baa3dffc58048982eaf17ad1b53f207vboxsync size_t cbCopy = strlen(pszSymbol) + 1;
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync memcpy(pArgs->psz, pszSymbol, cbCopy);
b26e5b503baa3dffc58048982eaf17ad1b53f207vboxsync pArgs->psz += cbCopy;
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync }
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync return VINF_SUCCESS;
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync}
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync
b26e5b503baa3dffc58048982eaf17ad1b53f207vboxsync
b26e5b503baa3dffc58048982eaf17ad1b53f207vboxsync/**
b26e5b503baa3dffc58048982eaf17ad1b53f207vboxsync * Worker for SUPLoadModule().
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync *
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync * @returns VBox status code.
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync * @param pszFilename Name of the VMMR0 image file
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync */
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsyncstatic int supLoadModule(const char *pszFilename, const char *pszModule, void **ppvImageBase)
b26e5b503baa3dffc58048982eaf17ad1b53f207vboxsync{
b26e5b503baa3dffc58048982eaf17ad1b53f207vboxsync /*
b26e5b503baa3dffc58048982eaf17ad1b53f207vboxsync * Validate input.
b26e5b503baa3dffc58048982eaf17ad1b53f207vboxsync */
b26e5b503baa3dffc58048982eaf17ad1b53f207vboxsync AssertPtrReturn(pszFilename, VERR_INVALID_PARAMETER);
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync AssertPtrReturn(pszModule, VERR_INVALID_PARAMETER);
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync AssertPtrReturn(ppvImageBase, VERR_INVALID_PARAMETER);
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync AssertReturn(strlen(pszModule) < RT_SIZEOFMEMB(SUPLDROPEN, u.In.szName), VERR_FILENAME_TOO_LONG);
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync const bool fIsVMMR0 = !strcmp(pszModule, "VMMR0.r0");
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync *ppvImageBase = NULL;
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync /*
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync * Open image file and figure its size.
b26e5b503baa3dffc58048982eaf17ad1b53f207vboxsync */
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync RTLDRMOD hLdrMod;
b26e5b503baa3dffc58048982eaf17ad1b53f207vboxsync int rc = RTLdrOpen(pszFilename, &hLdrMod);
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync if (!RT_SUCCESS(rc))
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync return rc;
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync SUPLDRCALCSIZEARGS CalcArgs;
b26e5b503baa3dffc58048982eaf17ad1b53f207vboxsync CalcArgs.cbStrings = 0;
b26e5b503baa3dffc58048982eaf17ad1b53f207vboxsync CalcArgs.cSymbols = 0;
b26e5b503baa3dffc58048982eaf17ad1b53f207vboxsync CalcArgs.cbImage = RTLdrSize(hLdrMod);
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync rc = RTLdrEnumSymbols(hLdrMod, 0, NULL, 0, supLoadModuleCalcSizeCB, &CalcArgs);
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync if (RT_SUCCESS(rc))
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync {
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync const uint32_t offSymTab = RT_ALIGN_32(CalcArgs.cbImage, 8);
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync const uint32_t offStrTab = offSymTab + CalcArgs.cSymbols * sizeof(SUPLDRSYM);
b26e5b503baa3dffc58048982eaf17ad1b53f207vboxsync const uint32_t cbImage = RT_ALIGN_32(offStrTab + CalcArgs.cbStrings, 8);
b26e5b503baa3dffc58048982eaf17ad1b53f207vboxsync
b26e5b503baa3dffc58048982eaf17ad1b53f207vboxsync /*
b26e5b503baa3dffc58048982eaf17ad1b53f207vboxsync * Open the R0 image.
b26e5b503baa3dffc58048982eaf17ad1b53f207vboxsync */
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync SUPLDROPEN OpenReq;
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync OpenReq.Hdr.u32Cookie = g_u32Cookie;
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync OpenReq.Hdr.u32SessionCookie = g_u32SessionCookie;
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync OpenReq.Hdr.cbIn = SUP_IOCTL_LDR_OPEN_SIZE_IN;
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync OpenReq.Hdr.cbOut = SUP_IOCTL_LDR_OPEN_SIZE_OUT;
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync OpenReq.Hdr.fFlags = SUPREQHDR_FLAGS_DEFAULT;
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync OpenReq.Hdr.rc = VERR_INTERNAL_ERROR;
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync OpenReq.u.In.cbImage = cbImage;
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync strcpy(OpenReq.u.In.szName, pszModule);
b26e5b503baa3dffc58048982eaf17ad1b53f207vboxsync if (!g_u32FakeMode)
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync {
b26e5b503baa3dffc58048982eaf17ad1b53f207vboxsync rc = suplibOsIOCtl(&g_supLibData, SUP_IOCTL_LDR_OPEN, &OpenReq, SUP_IOCTL_LDR_OPEN_SIZE);
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync if (RT_SUCCESS(rc))
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync rc = OpenReq.Hdr.rc;
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync }
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync else
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync {
b26e5b503baa3dffc58048982eaf17ad1b53f207vboxsync OpenReq.u.Out.fNeedsLoading = true;
b26e5b503baa3dffc58048982eaf17ad1b53f207vboxsync OpenReq.u.Out.pvImageBase = 0xef423420;
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync }
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync *ppvImageBase = (void *)OpenReq.u.Out.pvImageBase;
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync if ( RT_SUCCESS(rc)
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync && OpenReq.u.Out.fNeedsLoading)
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync {
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync /*
b26e5b503baa3dffc58048982eaf17ad1b53f207vboxsync * We need to load it.
b26e5b503baa3dffc58048982eaf17ad1b53f207vboxsync * Allocate memory for the image bits.
b26e5b503baa3dffc58048982eaf17ad1b53f207vboxsync */
b26e5b503baa3dffc58048982eaf17ad1b53f207vboxsync PSUPLDRLOAD pLoadReq = (PSUPLDRLOAD)RTMemTmpAlloc(SUP_IOCTL_LDR_LOAD_SIZE(cbImage));
b26e5b503baa3dffc58048982eaf17ad1b53f207vboxsync if (pLoadReq)
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync {
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync /*
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync * Get the image bits.
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync */
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync rc = RTLdrGetBits(hLdrMod, &pLoadReq->u.In.achImage[0], (uintptr_t)OpenReq.u.Out.pvImageBase,
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync supLoadModuleResolveImport, (void *)pszModule);
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync if (RT_SUCCESS(rc))
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync {
b26e5b503baa3dffc58048982eaf17ad1b53f207vboxsync /*
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync * Get the entry points.
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync */
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync RTUINTPTR VMMR0EntryInt = 0;
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync RTUINTPTR VMMR0EntryFast = 0;
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync RTUINTPTR VMMR0EntryEx = 0;
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync RTUINTPTR ModuleInit = 0;
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync RTUINTPTR ModuleTerm = 0;
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync if (fIsVMMR0)
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync {
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync rc = RTLdrGetSymbolEx(hLdrMod, &pLoadReq->u.In.achImage[0], (uintptr_t)OpenReq.u.Out.pvImageBase, "VMMR0EntryInt", &VMMR0EntryInt);
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync if (RT_SUCCESS(rc))
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync rc = RTLdrGetSymbolEx(hLdrMod, &pLoadReq->u.In.achImage[0], (uintptr_t)OpenReq.u.Out.pvImageBase, "VMMR0EntryFast", &VMMR0EntryFast);
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync if (RT_SUCCESS(rc))
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync rc = RTLdrGetSymbolEx(hLdrMod, &pLoadReq->u.In.achImage[0], (uintptr_t)OpenReq.u.Out.pvImageBase, "VMMR0EntryEx", &VMMR0EntryEx);
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync }
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync if (RT_SUCCESS(rc))
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync {
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync int rc2 = RTLdrGetSymbolEx(hLdrMod, &pLoadReq->u.In.achImage[0], (uintptr_t)OpenReq.u.Out.pvImageBase, "ModuleInit", &ModuleInit);
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync if (RT_FAILURE(rc2))
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync ModuleInit = 0;
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync rc2 = RTLdrGetSymbolEx(hLdrMod, &pLoadReq->u.In.achImage[0], (uintptr_t)OpenReq.u.Out.pvImageBase, "ModuleTerm", &ModuleTerm);
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync if (RT_FAILURE(rc2))
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync ModuleTerm = 0;
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync }
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync if (RT_SUCCESS(rc))
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync {
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync /*
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync * Create the symbol and string tables.
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync */
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync SUPLDRCREATETABSARGS CreateArgs;
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync CreateArgs.cbImage = CalcArgs.cbImage;
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync CreateArgs.pSym = (PSUPLDRSYM)&pLoadReq->u.In.achImage[offSymTab];
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync CreateArgs.pszBase = (char *)&pLoadReq->u.In.achImage[offStrTab];
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync CreateArgs.psz = CreateArgs.pszBase;
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync rc = RTLdrEnumSymbols(hLdrMod, 0, NULL, 0, supLoadModuleCreateTabsCB, &CreateArgs);
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync if (RT_SUCCESS(rc))
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync {
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync AssertRelease((size_t)(CreateArgs.psz - CreateArgs.pszBase) <= CalcArgs.cbStrings);
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync AssertRelease((size_t)(CreateArgs.pSym - (PSUPLDRSYM)&pLoadReq->u.In.achImage[offSymTab]) <= CalcArgs.cSymbols);
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync /*
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync * Upload the image.
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync */
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync pLoadReq->Hdr.u32Cookie = g_u32Cookie;
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync pLoadReq->Hdr.u32SessionCookie = g_u32SessionCookie;
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync pLoadReq->Hdr.cbIn = SUP_IOCTL_LDR_LOAD_SIZE_IN(cbImage);
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync pLoadReq->Hdr.cbOut = SUP_IOCTL_LDR_LOAD_SIZE_OUT;
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync pLoadReq->Hdr.fFlags = SUPREQHDR_FLAGS_MAGIC | SUPREQHDR_FLAGS_EXTRA_IN;
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync pLoadReq->Hdr.rc = VERR_INTERNAL_ERROR;
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync
b26e5b503baa3dffc58048982eaf17ad1b53f207vboxsync pLoadReq->u.In.pfnModuleInit = (RTR0PTR)ModuleInit;
b26e5b503baa3dffc58048982eaf17ad1b53f207vboxsync pLoadReq->u.In.pfnModuleTerm = (RTR0PTR)ModuleTerm;
b26e5b503baa3dffc58048982eaf17ad1b53f207vboxsync if (fIsVMMR0)
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync {
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync pLoadReq->u.In.eEPType = SUPLDRLOADEP_VMMR0;
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync pLoadReq->u.In.EP.VMMR0.pvVMMR0 = OpenReq.u.Out.pvImageBase;
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync pLoadReq->u.In.EP.VMMR0.pvVMMR0EntryInt = (RTR0PTR)VMMR0EntryInt;
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync pLoadReq->u.In.EP.VMMR0.pvVMMR0EntryFast= (RTR0PTR)VMMR0EntryFast;
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync pLoadReq->u.In.EP.VMMR0.pvVMMR0EntryEx = (RTR0PTR)VMMR0EntryEx;
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync }
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync else
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync pLoadReq->u.In.eEPType = SUPLDRLOADEP_NOTHING;
b26e5b503baa3dffc58048982eaf17ad1b53f207vboxsync pLoadReq->u.In.offStrTab = offStrTab;
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync pLoadReq->u.In.cbStrTab = (uint32_t)CalcArgs.cbStrings;
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync AssertRelease(pLoadReq->u.In.cbStrTab == CalcArgs.cbStrings);
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync pLoadReq->u.In.offSymbols = offSymTab;
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync pLoadReq->u.In.cSymbols = CalcArgs.cSymbols;
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync pLoadReq->u.In.cbImage = cbImage;
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync pLoadReq->u.In.pvImageBase = OpenReq.u.Out.pvImageBase;
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync if (!g_u32FakeMode)
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync {
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync rc = suplibOsIOCtl(&g_supLibData, SUP_IOCTL_LDR_LOAD, pLoadReq, SUP_IOCTL_LDR_LOAD_SIZE(cbImage));
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync if (RT_SUCCESS(rc))
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync rc = pLoadReq->Hdr.rc;
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync }
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync else
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync rc = VINF_SUCCESS;
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync if ( RT_SUCCESS(rc)
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync || rc == VERR_ALREADY_LOADED /* A competing process. */
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync )
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync {
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync LogRel(("SUP: Loaded %s (%s) at %#p - ModuleInit at %RTptr and ModuleTerm at %RTptr\n", pszModule, pszFilename,
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync OpenReq.u.Out.pvImageBase, ModuleInit, ModuleTerm));
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync if (fIsVMMR0)
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync {
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync g_pvVMMR0 = OpenReq.u.Out.pvImageBase;
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync LogRel(("SUP: VMMR0EntryEx located at %RTptr, VMMR0EntryFast at %RTptr and VMMR0EntryInt at %RTptr\n",
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync VMMR0EntryEx, VMMR0EntryFast, VMMR0EntryInt));
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync }
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync#ifdef RT_OS_WINDOWS
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync LogRel(("SUP: windbg> .reload /f %s=%#p\n", pszFilename, OpenReq.u.Out.pvImageBase));
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync#endif
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync RTMemTmpFree(pLoadReq);
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync RTLdrClose(hLdrMod);
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync return VINF_SUCCESS;
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync }
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync }
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync }
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync }
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync RTMemTmpFree(pLoadReq);
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync }
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync else
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync {
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync AssertMsgFailed(("failed to allocated %d bytes for SUPLDRLOAD_IN structure!\n", SUP_IOCTL_LDR_LOAD_SIZE(cbImage)));
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync rc = VERR_NO_TMP_MEMORY;
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync }
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync }
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync else if (RT_SUCCESS(rc))
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync {
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync if (fIsVMMR0)
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync g_pvVMMR0 = OpenReq.u.Out.pvImageBase;
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync LogRel(("SUP: Opened %s (%s) at %#p.\n", pszModule, pszFilename, OpenReq.u.Out.pvImageBase));
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync#ifdef RT_OS_WINDOWS
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync LogRel(("SUP: windbg> .reload /f %s=%#p\n", pszFilename, OpenReq.u.Out.pvImageBase));
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync#endif
5a5b5956f8b592c807c94785d58c25e717d430c4vboxsync }
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync }
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync RTLdrClose(hLdrMod);
b26e5b503baa3dffc58048982eaf17ad1b53f207vboxsync return rc;
b26e5b503baa3dffc58048982eaf17ad1b53f207vboxsync}
b26e5b503baa3dffc58048982eaf17ad1b53f207vboxsync
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync
4bf996d915405be92dc4394b2db1395e00e14d58vboxsyncSUPR3DECL(int) SUPFreeModule(void *pvImageBase)
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync{
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync /* fake */
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync if (RT_UNLIKELY(g_u32FakeMode))
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync {
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync#ifdef VBOX_WITH_IDT_PATCHING
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync g_u8Interrupt = 3;
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync RTMemExecFree(*(void **)&g_pfnCallVMMR0);
b26e5b503baa3dffc58048982eaf17ad1b53f207vboxsync g_pfnCallVMMR0 = NULL;
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync#endif
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync g_pvVMMR0 = NIL_RTR0PTR;
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync return VINF_SUCCESS;
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync }
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync#ifdef VBOX_WITH_IDT_PATCHING
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync /*
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync * There is one special module. When this is freed we'll
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync * free the IDT entry that goes with it.
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync *
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync * Note that we don't keep count of VMMR0.r0 loads here, so the
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync * first unload will free it.
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync */
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync if ( (RTR0PTR)pvImageBase == g_pvVMMR0
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync && g_u8Interrupt != 3)
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync {
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync SUPIDTREMOVE Req;
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync Req.Hdr.u32Cookie = g_u32Cookie;
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync Req.Hdr.u32SessionCookie = g_u32SessionCookie;
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync Req.Hdr.cbIn = SUP_IOCTL_IDT_REMOVE_SIZE_IN;
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync Req.Hdr.cbOut = SUP_IOCTL_IDT_REMOVE_SIZE_OUT;
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync Req.Hdr.fFlags = SUPREQHDR_FLAGS_DEFAULT;
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync Req.Hdr.rc = VERR_INTERNAL_ERROR;
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync int rc = suplibOsIOCtl(&g_supLibData, SUP_IOCTL_IDT_REMOVE, &Req, SUP_IOCTL_IDT_REMOVE_SIZE);
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync if (RT_SUCCESS(rc))
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync rc = Req.Hdr.rc;
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync AssertRC(rc);
b26e5b503baa3dffc58048982eaf17ad1b53f207vboxsync g_u8Interrupt = 3;
b26e5b503baa3dffc58048982eaf17ad1b53f207vboxsync RTMemExecFree(*(void **)&g_pfnCallVMMR0);
b26e5b503baa3dffc58048982eaf17ad1b53f207vboxsync g_pfnCallVMMR0 = NULL;
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync }
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync#endif /* VBOX_WITH_IDT_PATCHING */
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync /*
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync * Free the requested module.
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync */
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync SUPLDRFREE Req;
b26e5b503baa3dffc58048982eaf17ad1b53f207vboxsync Req.Hdr.u32Cookie = g_u32Cookie;
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsync Req.Hdr.u32SessionCookie = g_u32SessionCookie;
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsync Req.Hdr.cbIn = SUP_IOCTL_LDR_FREE_SIZE_IN;
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsync Req.Hdr.cbOut = SUP_IOCTL_LDR_FREE_SIZE_OUT;
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync Req.Hdr.fFlags = SUPREQHDR_FLAGS_DEFAULT;
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync Req.Hdr.rc = VERR_INTERNAL_ERROR;
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync Req.u.In.pvImageBase = (RTR0PTR)pvImageBase;
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync int rc = suplibOsIOCtl(&g_supLibData, SUP_IOCTL_LDR_FREE, &Req, SUP_IOCTL_LDR_FREE_SIZE);
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync if (RT_SUCCESS(rc))
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync rc = Req.Hdr.rc;
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync if ( RT_SUCCESS(rc)
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync && (RTR0PTR)pvImageBase == g_pvVMMR0)
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync g_pvVMMR0 = NIL_RTR0PTR;
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync return rc;
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync}
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsyncSUPR3DECL(int) SUPGetSymbolR0(void *pvImageBase, const char *pszSymbol, void **ppvValue)
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync{
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync *ppvValue = NULL;
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync /* fake */
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync if (RT_UNLIKELY(g_u32FakeMode))
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync {
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync *ppvValue = (void *)(uintptr_t)0xdeadf00d;
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsync return VINF_SUCCESS;
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsync }
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsync
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsync /*
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsync * Do ioctl.
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsync */
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsync SUPLDRGETSYMBOL Req;
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsync Req.Hdr.u32Cookie = g_u32Cookie;
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsync Req.Hdr.u32SessionCookie = g_u32SessionCookie;
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsync Req.Hdr.cbIn = SUP_IOCTL_LDR_GET_SYMBOL_SIZE_IN;
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsync Req.Hdr.cbOut = SUP_IOCTL_LDR_GET_SYMBOL_SIZE_OUT;
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsync Req.Hdr.fFlags = SUPREQHDR_FLAGS_DEFAULT;
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsync Req.Hdr.rc = VERR_INTERNAL_ERROR;
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsync Req.u.In.pvImageBase = (RTR0PTR)pvImageBase;
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsync size_t cchSymbol = strlen(pszSymbol);
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsync if (cchSymbol >= sizeof(Req.u.In.szSymbol))
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsync return VERR_SYMBOL_NOT_FOUND;
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsync memcpy(Req.u.In.szSymbol, pszSymbol, cchSymbol + 1);
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsync int rc = suplibOsIOCtl(&g_supLibData, SUP_IOCTL_LDR_GET_SYMBOL, &Req, SUP_IOCTL_LDR_GET_SYMBOL_SIZE);
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsync if (RT_SUCCESS(rc))
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsync rc = Req.Hdr.rc;
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsync if (RT_SUCCESS(rc))
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsync *ppvValue = (void *)Req.u.Out.pvSymbol;
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync return rc;
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync}
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsyncSUPR3DECL(int) SUPLoadVMM(const char *pszFilename)
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync{
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync void *pvImageBase;
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync return SUPLoadModule(pszFilename, "VMMR0.r0", &pvImageBase);
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync}
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsyncSUPR3DECL(int) SUPUnloadVMM(void)
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync{
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync return SUPFreeModule((void*)g_pvVMMR0);
5a5b5956f8b592c807c94785d58c25e717d430c4vboxsync}
5a5b5956f8b592c807c94785d58c25e717d430c4vboxsync
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync
5a5b5956f8b592c807c94785d58c25e717d430c4vboxsyncSUPR3DECL(int) SUPGipGetPhys(PRTHCPHYS pHCPhys)
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync{
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync if (g_pSUPGlobalInfoPage)
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync {
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync *pHCPhys = g_HCPhysSUPGlobalInfoPage;
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync return VINF_SUCCESS;
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync }
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync *pHCPhys = NIL_RTHCPHYS;
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync return VERR_WRONG_ORDER;
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync}
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsync
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsync
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsync/**
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsync * Worker for SUPR3HardenedLdrLoad and SUPR3HardenedLdrLoadAppPriv.
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsync *
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsync * @returns iprt status code.
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsync * @param pszFilename The full file name.
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsync * @param phLdrMod Where to store the handle to the loaded module.
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsync */
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsyncstatic int supR3HardenedLdrLoadIt(const char *pszFilename, PRTLDRMOD phLdrMod)
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsync{
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsync#ifdef VBOX_WITH_HARDENING
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsync /*
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsync * Verify the image file.
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsync */
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsync int rc = supR3HardenedVerifyFile(pszFilename, false /* fFatal */);
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsync if (RT_FAILURE(rc))
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsync {
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsync LogRel(("supR3HardenedLdrLoadIt: Verification of \"%s\" failed, rc=%Rrc\n", rc));
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsync return rc;
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsync }
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsync#endif
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsync
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsync /*
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsync * Try load it.
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsync */
1025ef7261a6961d07d390e85a095d806ccb88d9vboxsync return RTLdrLoad(pszFilename, phLdrMod);
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync}
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsyncSUPR3DECL(int) SUPR3HardenedLdrLoad(const char *pszFilename, PRTLDRMOD phLdrMod)
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync{
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync /*
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync * Validate input.
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync */
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync AssertPtrReturn(pszFilename, VERR_INVALID_PARAMETER);
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync AssertPtrReturn(phLdrMod, VERR_INVALID_PARAMETER);
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync *phLdrMod = NIL_RTLDRMOD;
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync AssertReturn(RTPathHavePath(pszFilename), VERR_INVALID_PARAMETER);
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync /*
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync * Add the default extension if it's missing.
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync */
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync if (!RTPathHaveExt(pszFilename))
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync {
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync const char *pszSuff = RTLdrGetSuff();
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync size_t cchSuff = strlen(pszSuff);
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync size_t cchFilename = strlen(pszFilename);
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync char *psz = (char *)alloca(cchFilename + cchSuff + 1);
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync AssertReturn(psz, VERR_NO_TMP_MEMORY);
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync memcpy(psz, pszFilename, cchFilename);
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync memcpy(psz + cchFilename, pszSuff, cchSuff + 1);
113a43aca041000560f93f9a8ee23dfcf01a9e7cvboxsync pszFilename = psz;
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync }
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync /*
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync * Pass it on to the common library loader.
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync */
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync return supR3HardenedLdrLoadIt(pszFilename, phLdrMod);
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync}
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsyncSUPR3DECL(int) SUPR3HardenedLdrLoadAppPriv(const char *pszFilename, PRTLDRMOD phLdrMod)
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync{
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync LogFlow(("SUPR3HardenedLdrLoadAppPriv: pszFilename=%p:{%s} phLdrMod=%p\n", pszFilename, pszFilename, phLdrMod));
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync /*
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync * Validate input.
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync */
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync AssertPtrReturn(phLdrMod, VERR_INVALID_PARAMETER);
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync *phLdrMod = NIL_RTLDRMOD;
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync AssertPtrReturn(pszFilename, VERR_INVALID_PARAMETER);
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync AssertMsgReturn(!RTPathHavePath(pszFilename), ("%s\n", pszFilename), VERR_INVALID_PARAMETER);
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync /*
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync * Check the filename.
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync */
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync size_t cchFilename = strlen(pszFilename);
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync AssertMsgReturn(cchFilename < (RTPATH_MAX / 4) * 3, ("%zu\n", cchFilename), VERR_INVALID_PARAMETER);
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync const char *pszExt = "";
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync size_t cchExt = 0;
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync if (!RTPathHaveExt(pszFilename))
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync {
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync pszExt = RTLdrGetSuff();
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync cchExt = strlen(pszExt);
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync }
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync /*
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync * Construct the private arch path and check if the file exists.
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync */
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync char szPath[RTPATH_MAX];
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync int rc = RTPathAppPrivateArch(szPath, sizeof(szPath) - 1 - cchExt - cchFilename);
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync AssertRCReturn(rc, rc);
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync char *psz = strchr(szPath, '\0');
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync *psz++ = RTPATH_SLASH;
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync memcpy(psz, pszFilename, cchFilename);
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync psz += cchFilename;
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync memcpy(psz, pszExt, cchExt + 1);
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync if (!RTPathExists(szPath))
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync {
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync LogRel(("SUPR3HardenedLdrLoadAppPriv: \"%s\" not found\n", szPath));
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync return VERR_FILE_NOT_FOUND;
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync }
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync /*
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync * Pass it on to SUPR3HardenedLdrLoad.
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync */
71e045383a3316b27563b2f44b0e0e1231968bdcvboxsync rc = SUPR3HardenedLdrLoad(szPath, phLdrMod);
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync LogFlow(("SUPR3HardenedLdrLoadAppPriv: returns %Rrc\n", rc));
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync return rc;
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync}
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync
4bf996d915405be92dc4394b2db1395e00e14d58vboxsync