SUPDrvTracer.cpp revision 6947da10583ff63a965e6c07156ce7126a7bad22
adf2bcd2e5d07d5a11553b88e147c1f4b2249bffvboxsync * VBoxDrv - The VirtualBox Support Driver - Tracer Interface.
c58f1213e628a545081c70e26c6b67a841cff880vboxsync * Copyright (C) 2012 Oracle Corporation
71c8a528203c289a8585ce10ac6bafc4274058c6vboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
71c8a528203c289a8585ce10ac6bafc4274058c6vboxsync * available from http://www.virtualbox.org. This file is free software;
71c8a528203c289a8585ce10ac6bafc4274058c6vboxsync * you can redistribute it and/or modify it under the terms of the GNU
71c8a528203c289a8585ce10ac6bafc4274058c6vboxsync * General Public License (GPL) as published by the Free Software
71c8a528203c289a8585ce10ac6bafc4274058c6vboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
71c8a528203c289a8585ce10ac6bafc4274058c6vboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
71c8a528203c289a8585ce10ac6bafc4274058c6vboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
71c8a528203c289a8585ce10ac6bafc4274058c6vboxsync * The contents of this file may alternatively be used under the terms
71c8a528203c289a8585ce10ac6bafc4274058c6vboxsync * of the Common Development and Distribution License Version 1.0
71c8a528203c289a8585ce10ac6bafc4274058c6vboxsync * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
71c8a528203c289a8585ce10ac6bafc4274058c6vboxsync * VirtualBox OSE distribution, in which case the provisions of the
71c8a528203c289a8585ce10ac6bafc4274058c6vboxsync * CDDL are applicable instead of those of the GPL.
70bb61ea2f96e80150e807529ce5df435607706bvboxsync * You may elect to license modified versions of this file under the
71c8a528203c289a8585ce10ac6bafc4274058c6vboxsync * terms and conditions of either the GPL or the CDDL or both.
71c8a528203c289a8585ce10ac6bafc4274058c6vboxsync/*******************************************************************************
71c8a528203c289a8585ce10ac6bafc4274058c6vboxsync* Header Files *
edefdc20eedaf9ef5b1293e56ba9b8cca7b5c740vboxsync*******************************************************************************/
9e4ea89b1085fdaa5861e45a729d9c978db1a8f1vboxsync/*******************************************************************************
147e101bcd061b5e085e4a2c0cc9fc35546ff1aavboxsync* Structures and Typedefs *
9e4ea89b1085fdaa5861e45a729d9c978db1a8f1vboxsync*******************************************************************************/
e59069cf1c98c1c2e90a18ec76fbc2e9907fb917vboxsync * Data for a tracepoint provider.
9e4ea89b1085fdaa5861e45a729d9c978db1a8f1vboxsync /** The entry in the provider list for this image. */
9e4ea89b1085fdaa5861e45a729d9c978db1a8f1vboxsync /** The core structure. */
9e4ea89b1085fdaa5861e45a729d9c978db1a8f1vboxsync /** Pointer to the image this provider resides in. NULL if it's a
9e4ea89b1085fdaa5861e45a729d9c978db1a8f1vboxsync * driver. */
9e4ea89b1085fdaa5861e45a729d9c978db1a8f1vboxsync /** The session this provider is associated with if registered via
c33fc49611f2444dade533488bf431e29eb88bcdvboxsync * SUPR0VtgRegisterDrv. NULL if pImage is set. */
9e4ea89b1085fdaa5861e45a729d9c978db1a8f1vboxsync /** Used to indicate that we've called pfnProviderDeregistered already and it
6e12ccc60ac657fb87e27b7a2b26e0a63bebe024vboxsync * failed because the provider was busy. Next time we must try
6e12ccc60ac657fb87e27b7a2b26e0a63bebe024vboxsync * pfnProviderDeregisterZombie.
db0ecde8f28fdb4525bc6d94056166c70b02ebb8vboxsync * @remarks This does not necessiarly mean the provider is in the zombie
db0ecde8f28fdb4525bc6d94056166c70b02ebb8vboxsync * list. See supdrvTracerCommonDeregisterImpl. */
8b36957d815c23b479eb35d93ac76c66392e9402vboxsync /** Set if the provider has been successfully registered with the
9e4ea89b1085fdaa5861e45a729d9c978db1a8f1vboxsync * tracer. */
9353e321b583ed6f2b42414257a5212885575b5cvboxsync /** The provider name (for logging purposes). */
9e4ea89b1085fdaa5861e45a729d9c978db1a8f1vboxsync/** Pointer to the data for a tracepoint provider. */
9e4ea89b1085fdaa5861e45a729d9c978db1a8f1vboxsync/*******************************************************************************
9e4ea89b1085fdaa5861e45a729d9c978db1a8f1vboxsync* Defined Constants And Macros *
9e4ea89b1085fdaa5861e45a729d9c978db1a8f1vboxsync*******************************************************************************/
9e4ea89b1085fdaa5861e45a729d9c978db1a8f1vboxsync/** Simple SUPR0Printf-style logging. */
2a5e5a032e6f23f8937718e4ee4d6979188bdd19vboxsync/*******************************************************************************
2a5e5a032e6f23f8937718e4ee4d6979188bdd19vboxsync* Global Variables *
2a5e5a032e6f23f8937718e4ee4d6979188bdd19vboxsync*******************************************************************************/
2a5e5a032e6f23f8937718e4ee4d6979188bdd19vboxsync/** The address of the current probe fire routine for kernel mode. */
2a5e5a032e6f23f8937718e4ee4d6979188bdd19vboxsyncPFNRT g_pfnSupdrvProbeFireKernel = supdrvTracerProbeFireStub;
9e4ea89b1085fdaa5861e45a729d9c978db1a8f1vboxsync * Validates a VTG string against length and characterset limitations.
f62342e2cc901a67e27fa69c0e712ee35e9c4c68vboxsync * @returns VINF_SUCCESS, VERR_SUPDRV_VTG_BAD_STRING or
b604fbf16eda38d14b4999c245f032bfaa5aa85avboxsync * VERR_SUPDRV_VTG_STRING_TOO_LONG.
13d1fd6f43e9a245a4f2b4fc6845bdaa5d0f4134vboxsync * @param psz The string.
9e4ea89b1085fdaa5861e45a729d9c978db1a8f1vboxsync /*RTAssertMsg2("off=%u '%s'\n", off, psz);*/
9e4ea89b1085fdaa5861e45a729d9c978db1a8f1vboxsync * Validates the VTG data.
3933885bc0c2c93436d858a14564c6179ec72872vboxsync * @returns VBox status code.
3933885bc0c2c93436d858a14564c6179ec72872vboxsync * @param pVtgHdr The VTG object header of the data to validate.
3933885bc0c2c93436d858a14564c6179ec72872vboxsync * @param cbVtgObj The size of the VTG object.
3933885bc0c2c93436d858a14564c6179ec72872vboxsync * @param pbImage The image base. For validating the probe
3933885bc0c2c93436d858a14564c6179ec72872vboxsync * locations.
3933885bc0c2c93436d858a14564c6179ec72872vboxsync * @param cbImage The image size to go with @a pbImage.
3933885bc0c2c93436d858a14564c6179ec72872vboxsyncstatic int supdrvVtgValidate(PVTGOBJHDR pVtgHdr, size_t cbVtgObj, const uint8_t *pbImage, size_t cbImage)
9e4ea89b1085fdaa5861e45a729d9c978db1a8f1vboxsync#define MY_VALIDATE_PTR(p, cb, cMin, cMax, cbUnit, rcBase) \
9e4ea89b1085fdaa5861e45a729d9c978db1a8f1vboxsync || (uintptr_t)(p) - (uintptr_t)pVtgHdr > cbVtgObj - (cb) ) \
ad9e5a61fea617d40d07390ff1737277d6aef869vboxsync SUPR0Printf("supdrvVtgValidate: " #rcBase "_TOO_PTR - p=%p cb=%#zx pVtgHdr=%p cbVtgHdr=%#zu line=%u %s\n", \
23d9dbdaf1b83107abf9882246a4a46933f733efvboxsync p, (size_t)(cb), pVtgHdr, cbVtgObj, __LINE__, #p); \
4090390866c02d5d0ad061151cdb298b9a173e86vboxsync SUPR0Printf("supdrvVtgValidate: " #rcBase "_TOO_FEW - cb=%#zx cMin=%#zx cbUnit=%#zx line=%u %s\n", \
4090390866c02d5d0ad061151cdb298b9a173e86vboxsync (size_t)(cb), (size_t)(cMin), (size_t)cbUnit, __LINE__, #p); \
40dce69ff1c2949a489337922f30f1021d62d864vboxsync SUPR0Printf("supdrvVtgValidate: " #rcBase "_TOO_MUCH - cb=%#zx cMax=%#zx cbUnit=%#zx line=%u %s\n", \
657b2c9f6d33f08001e5fa6f6e0572dcf0391013vboxsync (size_t)(cb), (size_t)(cMax), (size_t)cbUnit, __LINE__, #p); \
a1b4fb3917412d2632d358ff8989f1ec971f2d5bvboxsync SUPR0Printf("supdrvVtgValidate: " #rcBase "_NOT_MULTIPLE - cb=%#zx cbUnit=%#zx line=%u %s\n", \
5a41049c24bcf93e3dc63c76bee23db645867e0cvboxsync } while (0)
a1b4fb3917412d2632d358ff8989f1ec971f2d5bvboxsync if ((uintptr_t)(p) - (uintptr_t)pbImage > cbImage) \
3f00104a87d8a725dfa0348b69cbdac901062a4avboxsync SUPR0Printf("supdrvVtgValidate: " #rc " - p=%p pbImage=%p cbImage=%#zxline=%u %s\n", \
3f00104a87d8a725dfa0348b69cbdac901062a4avboxsync return (rc); \
5d57bcb78f1f3f918bd3daf709b551b8c2d30485vboxsync else if (!RT_VALID_PTR(p)) \
cccc6ee5f7156cfcdf13acca545cf65124d9ed44vboxsync return (rc); \
3f00104a87d8a725dfa0348b69cbdac901062a4avboxsync } while (0)
147e101bcd061b5e085e4a2c0cc9fc35546ff1aavboxsync rc = supdrvVtgValidateString(pVtgHdr->pachStrTab + (offStrTab)); \
1147e980f6ab0b7ff1d08c13ad1c03eea30d102dvboxsync } while (0)
9e4ea89b1085fdaa5861e45a729d9c978db1a8f1vboxsync if ((Attr).u8Code <= (uint8_t)kVTGStability_Invalid || (Attr).u8Code >= (uint8_t)kVTGStability_End) \
9e4ea89b1085fdaa5861e45a729d9c978db1a8f1vboxsync if ((Attr).u8Data <= (uint8_t)kVTGStability_Invalid || (Attr).u8Data >= (uint8_t)kVTGStability_End) \
261b44f7fa60a1d4bb4102142d3aa44188908484vboxsync if ((Attr).u8DataDep <= (uint8_t)kVTGClass_Invalid || (Attr).u8DataDep >= (uint8_t)kVTGClass_End) \
261b44f7fa60a1d4bb4102142d3aa44188908484vboxsync } while (0)
261b44f7fa60a1d4bb4102142d3aa44188908484vboxsync * The header.
261b44f7fa60a1d4bb4102142d3aa44188908484vboxsync if (memcmp(pVtgHdr->szMagic, VTGOBJHDR_MAGIC, sizeof(pVtgHdr->szMagic)))
9e4ea89b1085fdaa5861e45a729d9c978db1a8f1vboxsync MY_VALIDATE_PTR(pVtgHdr->paProviders, pVtgHdr->cbProviders, 1, 16, sizeof(VTGDESCPROVIDER), VERR_SUPDRV_VTG_BAD_HDR);
6e12ccc60ac657fb87e27b7a2b26e0a63bebe024vboxsync MY_VALIDATE_PTR(pVtgHdr->paProbes, pVtgHdr->cbProbes, 1, _32K, sizeof(VTGDESCPROBE), VERR_SUPDRV_VTG_BAD_HDR);
6e12ccc60ac657fb87e27b7a2b26e0a63bebe024vboxsync MY_VALIDATE_PTR(pVtgHdr->pafProbeEnabled, pVtgHdr->cbProbeEnabled, 1, _32K, sizeof(bool), VERR_SUPDRV_VTG_BAD_HDR);
6e12ccc60ac657fb87e27b7a2b26e0a63bebe024vboxsync MY_VALIDATE_PTR(pVtgHdr->pachStrTab, pVtgHdr->cbStrTab, 4, _1M, sizeof(char), VERR_SUPDRV_VTG_BAD_HDR);
657b2c9f6d33f08001e5fa6f6e0572dcf0391013vboxsync MY_VALIDATE_PTR(pVtgHdr->paArgLists, pVtgHdr->cbArgLists, 1, _32K, sizeof(uint32_t), VERR_SUPDRV_VTG_BAD_HDR);
8b36957d815c23b479eb35d93ac76c66392e9402vboxsync MY_WITHIN_IMAGE(pVtgHdr->paProbLocs, VERR_SUPDRV_VTG_BAD_HDR_PTR);
9e4ea89b1085fdaa5861e45a729d9c978db1a8f1vboxsync MY_WITHIN_IMAGE(pVtgHdr->paProbLocsEnd, VERR_SUPDRV_VTG_BAD_HDR_PTR);
261b44f7fa60a1d4bb4102142d3aa44188908484vboxsync if ((uintptr_t)pVtgHdr->paProbLocs > (uintptr_t)pVtgHdr->paProbLocsEnd)
261b44f7fa60a1d4bb4102142d3aa44188908484vboxsync SUPR0Printf("supdrvVtgValidate: VERR_SUPDRV_VTG_BAD_HDR_PTR - paProbeLocs=%p > paProbLocsEnd=%p\n",
fc5f879e9508f333e20b37c63db9189a33059308vboxsync cbTmp = (uintptr_t)pVtgHdr->paProbLocsEnd - (uintptr_t)pVtgHdr->paProbLocs;
1c6ec9a3a329da6f61978a372e509cd233f0d9f9vboxsync SUPR0Printf("supdrvVtgValidate: VERR_SUPDRV_VTG_BAD_HDR_TOO_FEW - cbTmp=%#zx paProbeLocs=%p paProbLocsEnd=%p\n",
261b44f7fa60a1d4bb4102142d3aa44188908484vboxsync cbTmp, pVtgHdr->paProbLocs, pVtgHdr->paProbLocsEnd);
9e4ea89b1085fdaa5861e45a729d9c978db1a8f1vboxsync SUPR0Printf("supdrvVtgValidate: VERR_SUPDRV_VTG_BAD_HDR_TOO_MUCH - cbTmp=%#zx paProbeLocs=%p paProbLocsEnd=%p\n",
9e4ea89b1085fdaa5861e45a729d9c978db1a8f1vboxsync cbTmp, pVtgHdr->paProbLocs, pVtgHdr->paProbLocsEnd);
9e4ea89b1085fdaa5861e45a729d9c978db1a8f1vboxsync if (cbTmp / sizeof(VTGPROBELOC) * sizeof(VTGPROBELOC) != cbTmp)
9e4ea89b1085fdaa5861e45a729d9c978db1a8f1vboxsync SUPR0Printf("supdrvVtgValidate: VERR_SUPDRV_VTG_BAD_HDR_NOT_MULTIPLE - cbTmp=%#zx cbUnit=%#zx paProbeLocs=%p paProbLocsEnd=%p\n",
9e4ea89b1085fdaa5861e45a729d9c978db1a8f1vboxsync cbTmp, sizeof(VTGPROBELOC), pVtgHdr->paProbLocs, pVtgHdr->paProbLocsEnd);
261b44f7fa60a1d4bb4102142d3aa44188908484vboxsync if (pVtgHdr->cbProbes / sizeof(VTGDESCPROBE) != pVtgHdr->cbProbeEnabled)
9e4ea89b1085fdaa5861e45a729d9c978db1a8f1vboxsync SUPR0Printf("supdrvVtgValidate: VERR_SUPDRV_VTG_BAD_HDR - cbProbeEnabled=%#zx cbProbes=%#zx\n",
261b44f7fa60a1d4bb4102142d3aa44188908484vboxsync * Validate the providers.
9e4ea89b1085fdaa5861e45a729d9c978db1a8f1vboxsync cProviders = i = pVtgHdr->cbProviders / sizeof(VTGDESCPROVIDER);
9e4ea89b1085fdaa5861e45a729d9c978db1a8f1vboxsync while (i-- > 0)
cebc93936b5bb4d867e1c086dd1b206db33c31dcvboxsync if (pVtgHdr->paProviders[i].iFirstProbe >= pVtgHdr->cbProbeEnabled)
cebc93936b5bb4d867e1c086dd1b206db33c31dcvboxsync if (pVtgHdr->paProviders[i].iFirstProbe + pVtgHdr->paProviders[i].cProbes > pVtgHdr->cbProbeEnabled)
cebc93936b5bb4d867e1c086dd1b206db33c31dcvboxsync MY_VALIDATE_ATTR(pVtgHdr->paProviders[i].AttrSelf);
cebc93936b5bb4d867e1c086dd1b206db33c31dcvboxsync MY_VALIDATE_ATTR(pVtgHdr->paProviders[i].AttrModules);
cebc93936b5bb4d867e1c086dd1b206db33c31dcvboxsync MY_VALIDATE_ATTR(pVtgHdr->paProviders[i].AttrFunctions);
cebc93936b5bb4d867e1c086dd1b206db33c31dcvboxsync MY_VALIDATE_ATTR(pVtgHdr->paProviders[i].AttrNames);
cebc93936b5bb4d867e1c086dd1b206db33c31dcvboxsync MY_VALIDATE_ATTR(pVtgHdr->paProviders[i].AttrArguments);
9e4ea89b1085fdaa5861e45a729d9c978db1a8f1vboxsync * Validate probes.
67ee25dd0b63a61dc35a35d0aade75ca6cd06350vboxsync while (i-- > 0)
3933885bc0c2c93436d858a14564c6179ec72872vboxsync if (pVtgHdr->paProbes[i].offArgList >= pVtgHdr->cbArgLists)
3933885bc0c2c93436d858a14564c6179ec72872vboxsync if (pVtgHdr->paProbes[i].idxEnabled != i) /* The lists are parallel. */
060f7ec6ae5c99df18341ef2e1f3e91f4b0c89f1vboxsync if (pVtgHdr->paProbes[i].idxProvider >= cProviders)
cc74f15083bf80fbc96723a89faa06c15d0dead8vboxsync if ( i - pVtgHdr->paProviders[pVtgHdr->paProbes[i].idxProvider].iFirstProbe
a72b5355eb89aafe6bfcc8912cf02645d7cccceavboxsync >= pVtgHdr->paProviders[pVtgHdr->paProbes[i].idxProvider].cProbes)
3933885bc0c2c93436d858a14564c6179ec72872vboxsync /* The referenced argument list. */
3933885bc0c2c93436d858a14564c6179ec72872vboxsync pArgList = (PVTGDESCARGLIST)((uintptr_t)pVtgHdr->paArgLists + pVtgHdr->paProbes[i].offArgList);
9e4ea89b1085fdaa5861e45a729d9c978db1a8f1vboxsync while (iArg-- > 0)
a9315925c69e4c3bb342bb317ca5b6d29e1ee467vboxsync switch (pArgList->aArgs[iArg].fType & VTG_TYPE_SIZE_MASK)
dbabc9de5bf52ce5eb77cf82b038e9a6166c5a04vboxsync if (pArgList->aArgs[iArg].fType & VTG_TYPE_FIXED_SIZED)
f57758f0bcf995d350d64a7c059ac93573144c05vboxsync SUPR0Printf("supdrvVtgValidate: VERR_SUPDRV_TRACER_BAD_ARG_FLAGS - fType=%#x iArg=%u iProbe=%u\n",
3f00104a87d8a725dfa0348b69cbdac901062a4avboxsync if (VTG_TYPE_IS_LARGE(pArgList->aArgs[iArg].fType) && iArg >= 5)
3f00104a87d8a725dfa0348b69cbdac901062a4avboxsync if ((uint8_t)fHaveLargeArgs != pArgList->fHaveLargeArgs)
45a01ef53b009e9f56ce427bd8688da02ad32389vboxsync SUPR0Printf("supdrvVtgValidate: VERR_SUPDRV_TRACER_BAD_ARG_FLAGS - fType=%#x iProbe=%u fHaveLargeArgs=%d expected %d\n",
45a01ef53b009e9f56ce427bd8688da02ad32389vboxsync pArgList->aArgs[iArg].fType, i, pArgList->fHaveLargeArgs, fHaveLargeArgs);
62ab017295981c81484e5a5f93ff8b5f85f7defbvboxsync * Check that pafProbeEnabled is all zero.
7708252d252a55417a6a817041e4356797e34255vboxsync while (i-- > 0)
3933885bc0c2c93436d858a14564c6179ec72872vboxsync * Probe locations.
3933885bc0c2c93436d858a14564c6179ec72872vboxsync while (i-- > 0)
aa0553becec2abc2e781f839ba1d399c31c2c07fvboxsync MY_WITHIN_IMAGE(pVtgHdr->paProbLocs[i].pszFunction, VERR_SUPDRV_VTG_BAD_PROBE_LOC);
a1b4fb3917412d2632d358ff8989f1ec971f2d5bvboxsync offTmp = (uintptr_t)pVtgHdr->paProbLocs[i].pbProbe - (uintptr_t)pVtgHdr->paProbes;
aa0553becec2abc2e781f839ba1d399c31c2c07fvboxsync if (offTmp / sizeof(VTGDESCPROBE) * sizeof(VTGDESCPROBE) != offTmp)
1147e980f6ab0b7ff1d08c13ad1c03eea30d102dvboxsync * Gets a string from the string table.
1147e980f6ab0b7ff1d08c13ad1c03eea30d102dvboxsync * @returns Pointer to the string.
1147e980f6ab0b7ff1d08c13ad1c03eea30d102dvboxsync * @param pVtgHdr The VTG object header.
1147e980f6ab0b7ff1d08c13ad1c03eea30d102dvboxsync * @param offStrTab The string table offset.
1147e980f6ab0b7ff1d08c13ad1c03eea30d102dvboxsyncstatic const char *supdrvVtgGetString(PVTGOBJHDR pVtgHdr, uint32_t offStrTab)
1147e980f6ab0b7ff1d08c13ad1c03eea30d102dvboxsync * Frees the provider structure and associated resources.
1147e980f6ab0b7ff1d08c13ad1c03eea30d102dvboxsync * @param pProv The provider to free.
48890ac9b4b339e0341e826b5c26ce6408729987vboxsyncstatic void supdrvTracerFreeProvider(PSUPDRVTPPROVIDER pProv)
48890ac9b4b339e0341e826b5c26ce6408729987vboxsync LOG_TRACER(("Freeing tracepoint provider '%s' / %p\n", pProv->szName, pProv->Core.TracerData.DTrace.idProvider));
48890ac9b4b339e0341e826b5c26ce6408729987vboxsync * Deregisters a provider.
48890ac9b4b339e0341e826b5c26ce6408729987vboxsync * If the provider is still busy, it will be put in the zombie list.
48890ac9b4b339e0341e826b5c26ce6408729987vboxsync * @param pDevExt The device extension.
48890ac9b4b339e0341e826b5c26ce6408729987vboxsync * @param pProv The provider.
48890ac9b4b339e0341e826b5c26ce6408729987vboxsync * @remarks The caller owns mtxTracer.
48890ac9b4b339e0341e826b5c26ce6408729987vboxsyncstatic void supdrvTracerDeregisterVtgObj(PSUPDRVDEVEXT pDevExt, PSUPDRVTPPROVIDER pProv)
71c8a528203c289a8585ce10ac6bafc4274058c6vboxsync rc = pDevExt->pTracerOps->pfnProviderDeregister(pDevExt->pTracerOps, &pProv->Core);
71c8a528203c289a8585ce10ac6bafc4274058c6vboxsync RTListAppend(&pDevExt->TracerProviderZombieList, &pProv->ListEntry);
71c8a528203c289a8585ce10ac6bafc4274058c6vboxsync LOG_TRACER(("Invalidated provider '%s' / %p and put it on the zombie list (rc=%Rrc)\n",
71c8a528203c289a8585ce10ac6bafc4274058c6vboxsync pProv->szName, pProv->Core.TracerData.DTrace.idProvider, rc));
89aedeb1d8af54aba6ae46dbbd256281315c1be6vboxsync * Processes the zombie list.
89aedeb1d8af54aba6ae46dbbd256281315c1be6vboxsync * @param pDevExt The device extension.
71c8a528203c289a8585ce10ac6bafc4274058c6vboxsyncstatic void supdrvTracerProcessZombies(PSUPDRVDEVEXT pDevExt)
147e101bcd061b5e085e4a2c0cc9fc35546ff1aavboxsync RTListForEachSafe(&pDevExt->TracerProviderZombieList, pProv, pProvNext, SUPDRVTPPROVIDER, ListEntry)
1dc37bff2fb26897f5892d8330fe2bc0c9859aecvboxsync int rc = pDevExt->pTracerOps->pfnProviderDeregisterZombie(pDevExt->pTracerOps, &pProv->Core);
71c8a528203c289a8585ce10ac6bafc4274058c6vboxsync * Unregisters all providers, including zombies, waiting for busy providers to
1147e980f6ab0b7ff1d08c13ad1c03eea30d102dvboxsync * go idle and unregister smoothly.
1147e980f6ab0b7ff1d08c13ad1c03eea30d102dvboxsync * This may block.
1147e980f6ab0b7ff1d08c13ad1c03eea30d102dvboxsync * @param pDevExt The device extension.
1147e980f6ab0b7ff1d08c13ad1c03eea30d102dvboxsyncstatic void supdrvTracerRemoveAllProviders(PSUPDRVDEVEXT pDevExt)
71c8a528203c289a8585ce10ac6bafc4274058c6vboxsync * Unregister all probes (there should only be one).
1207f59aa62006952dbb0bf7700decf34d8caeb2vboxsync RTListForEachSafe(&pDevExt->TracerProviderList, pProv, pProvNext, SUPDRVTPPROVIDER, ListEntry)
d29ab0cfbeef254251f0a2458163034999abb8a0vboxsync * Try unregister zombies now, sleep on busy ones and tracer opens.
147e101bcd061b5e085e4a2c0cc9fc35546ff1aavboxsync for (i = 0; ; i++)
71c8a528203c289a8585ce10ac6bafc4274058c6vboxsync /* Zombies */
71c8a528203c289a8585ce10ac6bafc4274058c6vboxsync RTListForEachSafe(&pDevExt->TracerProviderZombieList, pProv, pProvNext, SUPDRVTPPROVIDER, ListEntry)
b304856b23107864c9c594a80cebca6006623f31vboxsync LOG_TRACER(("supdrvTracerRemoveAllProviders: Attemting to unregister '%s' / %p...\n",
b304856b23107864c9c594a80cebca6006623f31vboxsync pProv->szName, pProv->Core.TracerData.DTrace.idProvider));
b304856b23107864c9c594a80cebca6006623f31vboxsync rc = pDevExt->pTracerOps->pfnProviderDeregisterZombie(pDevExt->pTracerOps, &pProv->Core);
71c8a528203c289a8585ce10ac6bafc4274058c6vboxsync else if (!(i & 0xf))
8b36957d815c23b479eb35d93ac76c66392e9402vboxsync SUPR0Printf("supdrvTracerRemoveAllProviders: Waiting on busy provider '%s' / %p (rc=%d)\n",
147e101bcd061b5e085e4a2c0cc9fc35546ff1aavboxsync pProv->szName, pProv->Core.TracerData.DTrace.idProvider, rc);
d29ab0cfbeef254251f0a2458163034999abb8a0vboxsync LOG_TRACER(("supdrvTracerRemoveAllProviders: Failed to unregister provider '%s' / %p - rc=%d\n",
8b36957d815c23b479eb35d93ac76c66392e9402vboxsync pProv->szName, pProv->Core.TracerData.DTrace.idProvider, rc));
3a0bc95d0adf57baefd303e94b8f1b7b31a8f080vboxsync fEmpty = RTListIsEmpty(&pDevExt->TracerProviderZombieList);
21ddd8aa21b8d7ad25b18ab341ede34c1cb4a125vboxsync /* Tracer opens. */
21ddd8aa21b8d7ad25b18ab341ede34c1cb4a125vboxsync if (!(i & 0xf))
21ddd8aa21b8d7ad25b18ab341ede34c1cb4a125vboxsync SUPR0Printf("supdrvTracerRemoveAllProviders: Waiting on %u opens\n", pDevExt->cTracerOpens);
d29ab0cfbeef254251f0a2458163034999abb8a0vboxsync LOG_TRACER(("supdrvTracerRemoveAllProviders: Waiting on %u opens\n", pDevExt->cTracerOpens));
147e101bcd061b5e085e4a2c0cc9fc35546ff1aavboxsync /* Delay...*/
71c8a528203c289a8585ce10ac6bafc4274058c6vboxsync * Registers the VTG tracepoint providers of a driver.
9e4ea89b1085fdaa5861e45a729d9c978db1a8f1vboxsync * @returns VBox status code.
71c8a528203c289a8585ce10ac6bafc4274058c6vboxsync * @param pszName The driver name.
261b44f7fa60a1d4bb4102142d3aa44188908484vboxsync * @param pVtgHdr The VTG object header.
147e101bcd061b5e085e4a2c0cc9fc35546ff1aavboxsync * @param pVtgObj The size of the VTG object.
71c8a528203c289a8585ce10ac6bafc4274058c6vboxsync * @param pImage The image if applicable.
147e101bcd061b5e085e4a2c0cc9fc35546ff1aavboxsync * @param pSession The session if applicable.
9e4ea89b1085fdaa5861e45a729d9c978db1a8f1vboxsync * @param pszModName The module name.
f31ac84c1c57e23801423b5bd184fadabe6456f3vboxsyncstatic int supdrvTracerRegisterVtgObj(PSUPDRVDEVEXT pDevExt, PVTGOBJHDR pVtgHdr, size_t cbVtgObj, PSUPDRVLDRIMAGE pImage,
8fdb854581fe3cb394d84835dc09b02e6e18d4edvboxsync * Validate input.
36929067a9d3cba77fd78f1e8fa042ed3a8ae2d6vboxsync AssertPtrNullReturn(pSession, VERR_INVALID_POINTER);
71c8a528203c289a8585ce10ac6bafc4274058c6vboxsync rc = supdrvVtgValidate(pVtgHdr, cbVtgObj, (const uint8_t *)pImage->pvImage, pImage->cbImageBits);
ab2292e9c32bd271ec91123ef38699a0284b72cbvboxsync rc = supdrvVtgValidate(pVtgHdr, cbVtgObj, NULL, 0);
71c8a528203c289a8585ce10ac6bafc4274058c6vboxsync RTListForEach(&pDevExt->TracerProviderList, pProv, SUPDRVTPPROVIDER, ListEntry)
121568d0a1e932e6f6acd49376827a0e593815favboxsync * Register the providers.
db0ecde8f28fdb4525bc6d94056166c70b02ebb8vboxsync i = pVtgHdr->cbProviders / sizeof(VTGDESCPROVIDER);
f31ac84c1c57e23801423b5bd184fadabe6456f3vboxsync while (i-- > 0)
db0ecde8f28fdb4525bc6d94056166c70b02ebb8vboxsync const char *pszName = supdrvVtgGetString(pVtgHdr, pDesc->offName);
db0ecde8f28fdb4525bc6d94056166c70b02ebb8vboxsync pProv = (PSUPDRVTPPROVIDER)RTMemAllocZ(RT_OFFSETOF(SUPDRVTPPROVIDER, szName[cchName + 1]));
71c8a528203c289a8585ce10ac6bafc4274058c6vboxsync rc = pDevExt->pTracerOps->pfnProviderRegister(pDevExt->pTracerOps, &pProv->Core);
1bf151411167b02ebdc6d6a18de8b97030341e1fvboxsync RTListAppend(&pDevExt->TracerProviderList, &pProv->ListEntry);
8fdb854581fe3cb394d84835dc09b02e6e18d4edvboxsync LOG_TRACER(("Registered tracepoint provider '%s' in '%s' -> %p\n",
9e4ea89b1085fdaa5861e45a729d9c978db1a8f1vboxsync pProv->szName, pszModName, pProv->Core.TracerData.DTrace.idProvider));
147e101bcd061b5e085e4a2c0cc9fc35546ff1aavboxsync LOG_TRACER(("Failed to register tracepoint provider '%s' in '%s' -> %Rrc\n",
6e12ccc60ac657fb87e27b7a2b26e0a63bebe024vboxsync RTListForEachReverseSafe(&pDevExt->TracerProviderList, pProv, pProvNext, SUPDRVTPPROVIDER, ListEntry)
8b36957d815c23b479eb35d93ac76c66392e9402vboxsync * Registers the VTG tracepoint providers of a driver.
8b36957d815c23b479eb35d93ac76c66392e9402vboxsync * @returns VBox status code.
8b36957d815c23b479eb35d93ac76c66392e9402vboxsync * @param pSession The support driver session handle.
8b36957d815c23b479eb35d93ac76c66392e9402vboxsync * @param pVtgHdr The VTG header.
8b36957d815c23b479eb35d93ac76c66392e9402vboxsync * @param pszName The driver name.
8b36957d815c23b479eb35d93ac76c66392e9402vboxsyncSUPR0DECL(int) SUPR0TracerRegisterDrv(PSUPDRVSESSION pSession, PVTGOBJHDR pVtgHdr, const char *pszName)
8b36957d815c23b479eb35d93ac76c66392e9402vboxsync AssertReturn(SUP_IS_SESSION_VALID(pSession), VERR_INVALID_PARAMETER);
8b36957d815c23b479eb35d93ac76c66392e9402vboxsync AssertReturn(pSession->R0Process == NIL_RTR0PROCESS, VERR_INVALID_PARAMETER);
8b36957d815c23b479eb35d93ac76c66392e9402vboxsync LOG_TRACER(("SUPR0TracerRegisterDrv: pSession=%p pVtgHdr=%p pszName=%s\n", pSession, pVtgHdr, pszName));
49e54e2ffe0c10864d06e9d1ebe24a8eb1327a6bvboxsync rc = supdrvTracerRegisterVtgObj(pSession->pDevExt, pVtgHdr, _1M, NULL /*pImage*/, pSession, pszName);
49e54e2ffe0c10864d06e9d1ebe24a8eb1327a6bvboxsync * Try unregister zombies while we have a chance.
9e4ea89b1085fdaa5861e45a729d9c978db1a8f1vboxsync * Deregister the VTG tracepoint providers of a driver.
261b44f7fa60a1d4bb4102142d3aa44188908484vboxsync * @param pSession The support driver session handle.
49e54e2ffe0c10864d06e9d1ebe24a8eb1327a6bvboxsync * @param pVtgHdr The VTG header.
d29ab0cfbeef254251f0a2458163034999abb8a0vboxsyncSUPR0DECL(void) SUPR0TracerDeregisterDrv(PSUPDRVSESSION pSession)
147e101bcd061b5e085e4a2c0cc9fc35546ff1aavboxsync AssertReturnVoid(pSession->R0Process == NIL_RTR0PROCESS);
91f8453d16b48876deddaba298c211071d0ca3a5vboxsync LOG_TRACER(("SUPR0TracerDeregisterDrv: pSession=%p\n", pSession));
147e101bcd061b5e085e4a2c0cc9fc35546ff1aavboxsync * Search for providers belonging to this driver session.
9e4ea89b1085fdaa5861e45a729d9c978db1a8f1vboxsync RTListForEachSafe(&pDevExt->TracerProviderList, pProv, pProvNext, SUPDRVTPPROVIDER, ListEntry)
147e101bcd061b5e085e4a2c0cc9fc35546ff1aavboxsync * Try unregister zombies while we have a chance.
8b36957d815c23b479eb35d93ac76c66392e9402vboxsync * Registers the VTG tracepoint providers of a module loaded by
d29ab0cfbeef254251f0a2458163034999abb8a0vboxsync * the support driver.
d29ab0cfbeef254251f0a2458163034999abb8a0vboxsync * This should be called from the ModuleInit code.
d29ab0cfbeef254251f0a2458163034999abb8a0vboxsync * @returns VBox status code.
d29ab0cfbeef254251f0a2458163034999abb8a0vboxsync * @param hMod The module handle.
d29ab0cfbeef254251f0a2458163034999abb8a0vboxsync * @param pVtgHdr The VTG header.
d29ab0cfbeef254251f0a2458163034999abb8a0vboxsyncSUPR0DECL(int) SUPR0TracerRegisterModule(void *hMod, PVTGOBJHDR pVtgHdr)
9e4ea89b1085fdaa5861e45a729d9c978db1a8f1vboxsync LOG_TRACER(("SUPR0TracerRegisterModule: %p\n", pVtgHdr));
71c8a528203c289a8585ce10ac6bafc4274058c6vboxsync * Validate input and context.
147e101bcd061b5e085e4a2c0cc9fc35546ff1aavboxsync AssertReturn(pDevExt->pLdrInitImage == pImage, VERR_WRONG_ORDER);
9e4ea89b1085fdaa5861e45a729d9c978db1a8f1vboxsync AssertReturn(pDevExt->hLdrInitThread == RTThreadNativeSelf(), VERR_WRONG_ORDER);
147e101bcd061b5e085e4a2c0cc9fc35546ff1aavboxsync * Calculate the max VTG object size and hand it over to the common code.
147e101bcd061b5e085e4a2c0cc9fc35546ff1aavboxsync cbVtgObj = (uintptr_t)pVtgHdr - (uintptr_t)pImage->pvImage;
8b36957d815c23b479eb35d93ac76c66392e9402vboxsync AssertMsgReturn(cbVtgObj /*off*/ < pImage->cbImageBits,
147e101bcd061b5e085e4a2c0cc9fc35546ff1aavboxsync ("pVtgHdr=%p offVtgObj=%p cbImageBits=%p\n", pVtgHdr, cbVtgObj, pImage->cbImageBits),
147e101bcd061b5e085e4a2c0cc9fc35546ff1aavboxsync rc = supdrvTracerRegisterVtgObj(pDevExt, pVtgHdr, cbVtgObj, pImage, NULL, pImage->szName);
1dc37bff2fb26897f5892d8330fe2bc0c9859aecvboxsync LOG_TRACER(("SUPR0TracerRegisterModule: rc=%d\n", rc));
147e101bcd061b5e085e4a2c0cc9fc35546ff1aavboxsync * Try unregister zombies while we have a chance.
147e101bcd061b5e085e4a2c0cc9fc35546ff1aavboxsync * Registers the tracer implementation.
147e101bcd061b5e085e4a2c0cc9fc35546ff1aavboxsync * This should be called from the ModuleInit code or from a ring-0 session.
2a5e5a032e6f23f8937718e4ee4d6979188bdd19vboxsync * @returns VBox status code.
4a0e2f51aaf27c0bca61ff0f1adb91106264f0dbvboxsync * @param hMod The module handle.
4a0e2f51aaf27c0bca61ff0f1adb91106264f0dbvboxsync * @param pSession Ring-0 session handle.
147e101bcd061b5e085e4a2c0cc9fc35546ff1aavboxsync * @param pReg Pointer to the tracer registration structure.
7922c4cd397713a387c9e854e74c31a0d5065365vboxsync * @param ppHlp Where to return the tracer helper method table.
4a0e2f51aaf27c0bca61ff0f1adb91106264f0dbvboxsyncSUPR0DECL(int) SUPR0TracerRegisterImpl(void *hMod, PSUPDRVSESSION pSession, PCSUPDRVTRACERREG pReg, PCSUPDRVTRACERHLP *ppHlp)
4a0e2f51aaf27c0bca61ff0f1adb91106264f0dbvboxsync * Validate input and context.
4a0e2f51aaf27c0bca61ff0f1adb91106264f0dbvboxsync AssertReturn(pSession == NULL, VERR_INVALID_PARAMETER);
4a0e2f51aaf27c0bca61ff0f1adb91106264f0dbvboxsync AssertReturn(pDevExt->pLdrInitImage == pImage, VERR_WRONG_ORDER);
147e101bcd061b5e085e4a2c0cc9fc35546ff1aavboxsync AssertReturn(pDevExt->hLdrInitThread == RTThreadNativeSelf(), VERR_WRONG_ORDER);
1207f59aa62006952dbb0bf7700decf34d8caeb2vboxsync AssertReturn(SUP_IS_SESSION_VALID(pSession), VERR_INVALID_PARAMETER);
147e101bcd061b5e085e4a2c0cc9fc35546ff1aavboxsync AssertReturn(pSession->R0Process == NIL_RTR0PROCESS, VERR_INVALID_PARAMETER);
a9f530691071e3496b072915b0c5ceabd4e05ea5vboxsync AssertReturn(pReg->u32Magic == SUPDRVTRACERREG_MAGIC, VERR_INVALID_MAGIC);
a9f530691071e3496b072915b0c5ceabd4e05ea5vboxsync AssertReturn(pReg->u32Version == SUPDRVTRACERREG_VERSION, VERR_VERSION_MISMATCH);
a9f530691071e3496b072915b0c5ceabd4e05ea5vboxsync AssertReturn(pReg->uEndMagic == SUPDRVTRACERREG_MAGIC, VERR_VERSION_MISMATCH);
67e7d53d62514401efcd0e7a34f5faf772a3fe04vboxsync AssertPtrReturn(pReg->pfnProbeFireKernel, VERR_INVALID_POINTER);
b7a8ce033b32a429def2feb142bc1bdd1b5dffa2vboxsync AssertPtrReturn(pReg->pfnProbeFireUser, VERR_INVALID_POINTER);
147e101bcd061b5e085e4a2c0cc9fc35546ff1aavboxsync AssertPtrReturn(pReg->pfnTracerOpen, VERR_INVALID_POINTER);
147e101bcd061b5e085e4a2c0cc9fc35546ff1aavboxsync AssertPtrReturn(pReg->pfnTracerIoCtl, VERR_INVALID_POINTER);
1207f59aa62006952dbb0bf7700decf34d8caeb2vboxsync AssertPtrReturn(pReg->pfnTracerClose, VERR_INVALID_POINTER);
1207f59aa62006952dbb0bf7700decf34d8caeb2vboxsync AssertPtrReturn(pReg->pfnProviderRegister, VERR_INVALID_POINTER);
1207f59aa62006952dbb0bf7700decf34d8caeb2vboxsync AssertPtrReturn(pReg->pfnProviderDeregister, VERR_INVALID_POINTER);
1207f59aa62006952dbb0bf7700decf34d8caeb2vboxsync AssertPtrReturn(pReg->pfnProviderDeregisterZombie, VERR_INVALID_POINTER);
147e101bcd061b5e085e4a2c0cc9fc35546ff1aavboxsync * Do the job.
147e101bcd061b5e085e4a2c0cc9fc35546ff1aavboxsync LOG_TRACER(("SUPR0TracerRegisterImpl: pReg=%p\n", pReg));
147e101bcd061b5e085e4a2c0cc9fc35546ff1aavboxsync g_pfnSupdrvProbeFireKernel = (PFNRT)pDevExt->pTracerOps->pfnProbeFireKernel;
147e101bcd061b5e085e4a2c0cc9fc35546ff1aavboxsync * Iterate the already loaded modules and register their providers.
147e101bcd061b5e085e4a2c0cc9fc35546ff1aavboxsync RTListForEach(&pDevExt->TracerProviderList, pProv, SUPDRVTPPROVIDER, ListEntry)
147e101bcd061b5e085e4a2c0cc9fc35546ff1aavboxsync int rc2 = pDevExt->pTracerOps->pfnProviderRegister(pDevExt->pTracerOps, &pProv->Core);
147e101bcd061b5e085e4a2c0cc9fc35546ff1aavboxsync SUPR0Printf("SUPR0TracerRegisterImpl: Failed to register provider %s::%s - rc=%d\n",
8b36957d815c23b479eb35d93ac76c66392e9402vboxsync * Common tracer implementation deregistration code.
147e101bcd061b5e085e4a2c0cc9fc35546ff1aavboxsync * The caller sets fTracerUnloading prior to calling this function.
1207f59aa62006952dbb0bf7700decf34d8caeb2vboxsync * @param pDevExt The device extension structure.
1dc37bff2fb26897f5892d8330fe2bc0c9859aecvboxsyncstatic void supdrvTracerCommonDeregisterImpl(PSUPDRVDEVEXT pDevExt)
2a5e5a032e6f23f8937718e4ee4d6979188bdd19vboxsync * Reinstall the stub probe-fire function.
8b36957d815c23b479eb35d93ac76c66392e9402vboxsync g_pfnSupdrvProbeFireKernel = supdrvTracerProbeFireStub;
1207f59aa62006952dbb0bf7700decf34d8caeb2vboxsync * Disassociate the tracer implementation from all providers.
71c8a528203c289a8585ce10ac6bafc4274058c6vboxsync * We will have to wait on busy providers.
1207f59aa62006952dbb0bf7700decf34d8caeb2vboxsync for (i = 0; ; i++)
147e101bcd061b5e085e4a2c0cc9fc35546ff1aavboxsync /* Live providers. */
a9f530691071e3496b072915b0c5ceabd4e05ea5vboxsync RTListForEachSafe(&pDevExt->TracerProviderList, pProv, pProvNext, SUPDRVTPPROVIDER, ListEntry)
a9f530691071e3496b072915b0c5ceabd4e05ea5vboxsync LOG_TRACER(("supdrvTracerCommonDeregisterImpl: Attemting to unregister '%s' / %p...\n",
67e7d53d62514401efcd0e7a34f5faf772a3fe04vboxsync pProv->szName, pProv->Core.TracerData.DTrace.idProvider));
1207f59aa62006952dbb0bf7700decf34d8caeb2vboxsync rc = pDevExt->pTracerOps->pfnProviderDeregister(pDevExt->pTracerOps, &pProv->Core);
1207f59aa62006952dbb0bf7700decf34d8caeb2vboxsync rc = pDevExt->pTracerOps->pfnProviderDeregisterZombie(pDevExt->pTracerOps, &pProv->Core);
71c8a528203c289a8585ce10ac6bafc4274058c6vboxsync if (!(i & 0xf))
147e101bcd061b5e085e4a2c0cc9fc35546ff1aavboxsync SUPR0Printf("supdrvTracerCommonDeregisterImpl: Waiting on busy provider '%s' / %p (rc=%d)\n",
71c8a528203c289a8585ce10ac6bafc4274058c6vboxsync pProv->szName, pProv->Core.TracerData.DTrace.idProvider, rc);
2a5e5a032e6f23f8937718e4ee4d6979188bdd19vboxsync LOG_TRACER(("supdrvTracerCommonDeregisterImpl: Failed to unregister provider '%s' / %p - rc=%d\n",
71c8a528203c289a8585ce10ac6bafc4274058c6vboxsync pProv->szName, pProv->Core.TracerData.DTrace.idProvider, rc));
71c8a528203c289a8585ce10ac6bafc4274058c6vboxsync /* Zombies providers. */
1207f59aa62006952dbb0bf7700decf34d8caeb2vboxsync RTListForEachSafe(&pDevExt->TracerProviderZombieList, pProv, pProvNext, SUPDRVTPPROVIDER, ListEntry)
147e101bcd061b5e085e4a2c0cc9fc35546ff1aavboxsync LOG_TRACER(("supdrvTracerCommonDeregisterImpl: Attemting to unregister '%s' / %p (zombie)...\n",
1dc37bff2fb26897f5892d8330fe2bc0c9859aecvboxsync pProv->szName, pProv->Core.TracerData.DTrace.idProvider));
147e101bcd061b5e085e4a2c0cc9fc35546ff1aavboxsync rc = pDevExt->pTracerOps->pfnProviderDeregisterZombie(pDevExt->pTracerOps, &pProv->Core);
147e101bcd061b5e085e4a2c0cc9fc35546ff1aavboxsync if (!(i & 0xf))
1207f59aa62006952dbb0bf7700decf34d8caeb2vboxsync SUPR0Printf("supdrvTracerCommonDeregisterImpl: Waiting on busy provider '%s' / %p (rc=%d)\n",
71c8a528203c289a8585ce10ac6bafc4274058c6vboxsync pProv->szName, pProv->Core.TracerData.DTrace.idProvider, rc);
1207f59aa62006952dbb0bf7700decf34d8caeb2vboxsync LOG_TRACER(("supdrvTracerCommonDeregisterImpl: Failed to unregister provider '%s' / %p - rc=%d\n",
147e101bcd061b5e085e4a2c0cc9fc35546ff1aavboxsync pProv->szName, pProv->Core.TracerData.DTrace.idProvider, rc));
1dc37bff2fb26897f5892d8330fe2bc0c9859aecvboxsync /* Tracer opens. */
147e101bcd061b5e085e4a2c0cc9fc35546ff1aavboxsync if (!(i & 0xf))
71c8a528203c289a8585ce10ac6bafc4274058c6vboxsync SUPR0Printf("supdrvTracerCommonDeregisterImpl: Waiting on %u opens\n", pDevExt->cTracerOpens);
2a5e5a032e6f23f8937718e4ee4d6979188bdd19vboxsync LOG_TRACER(("supdrvTracerCommonDeregisterImpl: Waiting on %u opens\n", pDevExt->cTracerOpens));
147e101bcd061b5e085e4a2c0cc9fc35546ff1aavboxsync /* Done? */
1207f59aa62006952dbb0bf7700decf34d8caeb2vboxsync /* Delay...*/
1207f59aa62006952dbb0bf7700decf34d8caeb2vboxsync * Deregister the tracer implementation.
147e101bcd061b5e085e4a2c0cc9fc35546ff1aavboxsync * Deregister a tracer implementation.
147e101bcd061b5e085e4a2c0cc9fc35546ff1aavboxsync * This should be called from the ModuleTerm code or from a ring-0 session.
71c8a528203c289a8585ce10ac6bafc4274058c6vboxsync * @returns VBox status code.
147e101bcd061b5e085e4a2c0cc9fc35546ff1aavboxsync * @param hMod The module handle.
71c8a528203c289a8585ce10ac6bafc4274058c6vboxsync * @param pSession Ring-0 session handle.
8b36957d815c23b479eb35d93ac76c66392e9402vboxsyncSUPR0DECL(int) SUPR0TracerDeregisterImpl(void *hMod, PSUPDRVSESSION pSession)
71c8a528203c289a8585ce10ac6bafc4274058c6vboxsync * Validate input and context.
71c8a528203c289a8585ce10ac6bafc4274058c6vboxsync AssertReturn(pSession == NULL, VERR_INVALID_PARAMETER);
2823fbb1428e982169f04923472d7c94e7ed8385vboxsync AssertReturn(SUP_IS_SESSION_VALID(pSession), VERR_INVALID_PARAMETER);
147e101bcd061b5e085e4a2c0cc9fc35546ff1aavboxsync AssertReturn(pSession->R0Process == NIL_RTR0PROCESS, VERR_INVALID_PARAMETER);
147e101bcd061b5e085e4a2c0cc9fc35546ff1aavboxsync * Do the job.
a9f530691071e3496b072915b0c5ceabd4e05ea5vboxsync LOG_TRACER(("SUPR0TracerDeregisterImpl: Unloading ...\n"));
b7a8ce033b32a429def2feb142bc1bdd1b5dffa2vboxsync LOG_TRACER(("SUPR0TracerDeregisterImpl: ... done.\n"));
71c8a528203c289a8585ce10ac6bafc4274058c6vboxsync * The probe function is a bit more fun since we need tail jump optimizating.
2a5e5a032e6f23f8937718e4ee4d6979188bdd19vboxsync * Since we cannot ship yasm sources for linux and freebsd, owing to the cursed
71c8a528203c289a8585ce10ac6bafc4274058c6vboxsync * rebuilding of the kernel module from scratch at install time, we have to
147e101bcd061b5e085e4a2c0cc9fc35546ff1aavboxsync * deploy some ugly gcc inline assembly here.
1207f59aa62006952dbb0bf7700decf34d8caeb2vboxsync#if defined(__GNUC__) && (defined(RT_OS_FREEBSD) || defined(RT_OS_LINUX))
147e101bcd061b5e085e4a2c0cc9fc35546ff1aavboxsync .section .text \n\
8b36957d815c23b479eb35d93ac76c66392e9402vboxsync .p2align 2,,3 \n\
147e101bcd061b5e085e4a2c0cc9fc35546ff1aavboxsync .global SUPR0TracerFireProbe \n\
147e101bcd061b5e085e4a2c0cc9fc35546ff1aavboxsyncSUPR0TracerFireProbe: \n\
147e101bcd061b5e085e4a2c0cc9fc35546ff1aavboxsync movq g_pfnSupdrvProbeFireKernel(%rip), %rax \n\
147e101bcd061b5e085e4a2c0cc9fc35546ff1aavboxsync jmp *%rax \n\
1871985cb4854e5bfb2ead8174ee28dbfce74df5vboxsync movl g_pfnSupdrvProbeFireKernel, %eax \n\
1871985cb4854e5bfb2ead8174ee28dbfce74df5vboxsync jmp *%eax \n\
147e101bcd061b5e085e4a2c0cc9fc35546ff1aavboxsync .type supdrvTracerProbeFireStub,@function \n\
147e101bcd061b5e085e4a2c0cc9fc35546ff1aavboxsync .global supdrvTracerProbeFireStub \n\
147e101bcd061b5e085e4a2c0cc9fc35546ff1aavboxsyncsupdrvTracerProbeFireStub: \n\
147e101bcd061b5e085e4a2c0cc9fc35546ff1aavboxsync .previous \n\
1207f59aa62006952dbb0bf7700decf34d8caeb2vboxsync# if 0 /* Slickedit on windows highlighting fix */
147e101bcd061b5e085e4a2c0cc9fc35546ff1aavboxsync * Module unloading hook, called after execution in the module have ceased.
147e101bcd061b5e085e4a2c0cc9fc35546ff1aavboxsync * @param pDevExt The device extension structure.
147e101bcd061b5e085e4a2c0cc9fc35546ff1aavboxsync * @param pImage The image being unloaded.
a9f530691071e3496b072915b0c5ceabd4e05ea5vboxsyncvoid VBOXCALL supdrvTracerModuleUnloading(PSUPDRVDEVEXT pDevExt, PSUPDRVLDRIMAGE pImage)
147e101bcd061b5e085e4a2c0cc9fc35546ff1aavboxsync * If it is the tracer image, we have to unload all the providers.
d107911787df36a78788a841b73d24da896d02f6vboxsync LOG_TRACER(("supdrvTracerModuleUnloading: Unloading tracer ...\n"));
147e101bcd061b5e085e4a2c0cc9fc35546ff1aavboxsync LOG_TRACER(("supdrvTracerModuleUnloading: ... done.\n"));
147e101bcd061b5e085e4a2c0cc9fc35546ff1aavboxsync * Unregister all providers belonging to this image.
1dc37bff2fb26897f5892d8330fe2bc0c9859aecvboxsync RTListForEachSafe(&pDevExt->TracerProviderList, pProv, pProvNext, SUPDRVTPPROVIDER, ListEntry)
147e101bcd061b5e085e4a2c0cc9fc35546ff1aavboxsync * Try unregister zombies while we have a chance.
aa0553becec2abc2e781f839ba1d399c31c2c07fvboxsync * Called when a session is being cleaned up.
aa0553becec2abc2e781f839ba1d399c31c2c07fvboxsync * @param pDevExt The device extension structure.
aa0553becec2abc2e781f839ba1d399c31c2c07fvboxsync * @param pSession The session that is being torn down.
aa0553becec2abc2e781f839ba1d399c31c2c07fvboxsyncvoid VBOXCALL supdrvTracerCleanupSession(PSUPDRVDEVEXT pDevExt, PSUPDRVSESSION pSession)
aa0553becec2abc2e781f839ba1d399c31c2c07fvboxsync * If ring-0 session, make sure it has deregistered VTG objects and the tracer.
aa0553becec2abc2e781f839ba1d399c31c2c07fvboxsync RTListForEachSafe(&pDevExt->TracerProviderList, pProv, pProvNext, SUPDRVTPPROVIDER, ListEntry)
aa0553becec2abc2e781f839ba1d399c31c2c07fvboxsync * Clean up instance data the trace may have associated with the session.
147e101bcd061b5e085e4a2c0cc9fc35546ff1aavboxsync * Open the tracer.
147e101bcd061b5e085e4a2c0cc9fc35546ff1aavboxsync * @returns VBox status code
147e101bcd061b5e085e4a2c0cc9fc35546ff1aavboxsync * @param pDevExt The device extension structure.
8b36957d815c23b479eb35d93ac76c66392e9402vboxsync * @param pSession The current session.
71c8a528203c289a8585ce10ac6bafc4274058c6vboxsync * @param uCookie The tracer cookie.
1dc37bff2fb26897f5892d8330fe2bc0c9859aecvboxsync * @param uArg The tracer open argument.
8b36957d815c23b479eb35d93ac76c66392e9402vboxsyncint VBOXCALL supdrvIOCtl_TracerOpen(PSUPDRVDEVEXT pDevExt, PSUPDRVSESSION pSession, uint32_t uCookie, uintptr_t uArg)
71c8a528203c289a8585ce10ac6bafc4274058c6vboxsync rc = pDevExt->pTracerOps->pfnTracerOpen(pDevExt->pTracerOps, pSession, uCookie, uArg, &pSession->uTracerData);
f62342e2cc901a67e27fa69c0e712ee35e9c4c68vboxsync * Closes the tracer.
f62342e2cc901a67e27fa69c0e712ee35e9c4c68vboxsync * @returns VBox status code.
f62342e2cc901a67e27fa69c0e712ee35e9c4c68vboxsync * @param pDevExt The device extension structure.
f62342e2cc901a67e27fa69c0e712ee35e9c4c68vboxsync * @param pSession The current session.
f62342e2cc901a67e27fa69c0e712ee35e9c4c68vboxsyncint VBOXCALL supdrvIOCtl_TracerClose(PSUPDRVDEVEXT pDevExt, PSUPDRVSESSION pSession)
b604fbf16eda38d14b4999c245f032bfaa5aa85avboxsync pDevExt->pTracerOps->pfnTracerClose(pDevExt->pTracerOps, pSession, uTracerData);
13d1fd6f43e9a245a4f2b4fc6845bdaa5d0f4134vboxsync * Performs a tracer I/O control request.
13d1fd6f43e9a245a4f2b4fc6845bdaa5d0f4134vboxsync * @returns VBox status code.
13d1fd6f43e9a245a4f2b4fc6845bdaa5d0f4134vboxsync * @param pDevExt The device extension structure.
13d1fd6f43e9a245a4f2b4fc6845bdaa5d0f4134vboxsync * @param pSession The current session.
13d1fd6f43e9a245a4f2b4fc6845bdaa5d0f4134vboxsync * @param uCmd The tracer command.
13d1fd6f43e9a245a4f2b4fc6845bdaa5d0f4134vboxsync * @param uArg The tracer argument.
13d1fd6f43e9a245a4f2b4fc6845bdaa5d0f4134vboxsync * @param piRetVal Where to store the tracer specific return value.
13d1fd6f43e9a245a4f2b4fc6845bdaa5d0f4134vboxsyncint VBOXCALL supdrvIOCtl_TracerIOCtl(PSUPDRVDEVEXT pDevExt, PSUPDRVSESSION pSession, uintptr_t uCmd, uintptr_t uArg, int32_t *piRetVal)
71c8a528203c289a8585ce10ac6bafc4274058c6vboxsync rc = pDevExt->pTracerOps->pfnTracerIoCtl(pDevExt->pTracerOps, pSession, uTracerData, uCmd, uArg, piRetVal);
aa0553becec2abc2e781f839ba1d399c31c2c07fvboxsync * Early module initialization hook.
71c8a528203c289a8585ce10ac6bafc4274058c6vboxsync * @returns VBox status code.
71c8a528203c289a8585ce10ac6bafc4274058c6vboxsync * @param pDevExt The device extension structure.
71c8a528203c289a8585ce10ac6bafc4274058c6vboxsyncint VBOXCALL supdrvTracerInit(PSUPDRVDEVEXT pDevExt)
71c8a528203c289a8585ce10ac6bafc4274058c6vboxsync * Initialize the tracer.
9e4ea89b1085fdaa5861e45a729d9c978db1a8f1vboxsync int rc = RTSemFastMutexCreate(&pDevExt->mtxTracer);
147e101bcd061b5e085e4a2c0cc9fc35546ff1aavboxsync pDevExt->TracerHlp.uVersion = SUPDRVTRACERHLP_VERSION;
1dc37bff2fb26897f5892d8330fe2bc0c9859aecvboxsync /** @todo */
147e101bcd061b5e085e4a2c0cc9fc35546ff1aavboxsync pDevExt->TracerHlp.uEndVersion = SUPDRVTRACERHLP_VERSION;
147e101bcd061b5e085e4a2c0cc9fc35546ff1aavboxsync g_pfnSupdrvProbeFireKernel = (PFNRT)pDevExt->pTracerOps->pfnProbeFireKernel;
147e101bcd061b5e085e4a2c0cc9fc35546ff1aavboxsync * Register the provider for this module, if compiled in.
8b36957d815c23b479eb35d93ac76c66392e9402vboxsync rc = supdrvTracerRegisterVtgObj(pDevExt, &g_VTGObjHeader, _1M, NULL /*pImage*/, NULL /*pSession*/, "vboxdrv");
9bb98d54790a98dad0ad6d9bdc5d319b6fdf0bffvboxsync SUPR0Printf("supdrvTracerInit: supdrvTracerRegisterVtgObj failed with rc=%d\n", rc);
147e101bcd061b5e085e4a2c0cc9fc35546ff1aavboxsync * Late module termination hook.
147e101bcd061b5e085e4a2c0cc9fc35546ff1aavboxsync * @returns VBox status code.
8b36957d815c23b479eb35d93ac76c66392e9402vboxsync * @param pDevExt The device extension structure.