VirtualBox

Changeset 90930 in vbox


Ignore:
Timestamp:
Aug 27, 2021 12:21:09 AM (3 years ago)
Author:
vboxsync
Message:

SUPDrv,Config.kmk: Make the module wrappering work for 5.13+. bugref:9937

Location:
trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/Config.kmk

    r90928 r90930  
    48144814TEMPLATE_VBoxR0_CXXFLAGS.amd64     += -mcmodel=kernel
    48154815 endif
    4816  ifdef VBOX_WITH_KMOD_WRAPPED_R0_MODS
     4816 ifdef VBOX_WITH_KMOD_WRAPPED_R0_MODS # For BTF/pahold issue we use -g1
    48174817TEMPLATE_VBoxR0_DEFS               += VBOX_WITH_KMOD_WRAPPED_R0_MODS
    48184818TEMPLATE_VBoxR0_LDFLAGS.linux      += $(PATH_ROOT)/src/VBox/HostDrivers/Support/linux/VBoxR0-wrapped.lds
    48194819TEMPLATE_VBoxR0_LNK_DEPS.linux     += $(PATH_ROOT)/src/VBox/HostDrivers/Support/linux/VBoxR0-wrapped.lds
     4820TEMPLATE_VBoxR0_CFLAGS.linux       += -g1
     4821TEMPLATE_VBoxR0_CXXFLAGS.linux     += -g1
    48204822 endif
    48214823 ifn1of ($(KBUILD_TARGET),solaris freebsd)
  • trunk/src/VBox/HostDrivers/Support/linux/SUPDrv-linux.c

    r90780 r90930  
    101101
    102102/*********************************************************************************************************************************
     103*   Structures and Typedefs                                                                                                      *
     104*********************************************************************************************************************************/
     105#if RTLNX_VER_MIN(5,0,0)
     106/** Wrapper module list entry. */
     107typedef struct SUPDRVLNXMODULE
     108{
     109    RTLISTNODE      ListEntry;
     110    struct module  *pModule;
     111} SUPDRVLNXMODULE;
     112/** Pointer to a wrapper module list entry. */
     113typedef SUPDRVLNXMODULE *PSUPDRVLNXMODULE;
     114#endif
     115
     116
     117/*********************************************************************************************************************************
    103118*   Internal Functions                                                                                                           *
    104119*********************************************************************************************************************************/
     
    126141static void VBoxDevRelease(struct device *pDev);
    127142#endif
     143static int  supdrvLinuxLdrModuleNotifyCallback(struct notifier_block *pBlock,
     144                                               unsigned long uModuleState, void *pvModule);
    128145
    129146
     
    225242
    226243#ifdef VBOX_WITH_SUSPEND_NOTIFICATION
     244
    227245# if RTLNX_VER_MIN(2,6,30)
    228246static struct dev_pm_ops gPlatformPMOps =
     
    260278    }
    261279};
     280
    262281#endif /* VBOX_WITH_SUSPEND_NOTIFICATION */
     282
     283#if RTLNX_VER_MIN(5,0,0)
     284/** Module load/unload notification registration record. */
     285static struct notifier_block    g_supdrvLinuxModuleNotifierBlock =
     286{
     287    .notifier_call = supdrvLinuxLdrModuleNotifyCallback,
     288    .priority      = 0
     289};
     290/** Spinlock protecting g_supdrvLinuxWrapperModuleList. */
     291static spinlock_t               g_supdrvLinuxWrapperModuleSpinlock;
     292/** List of potential wrapper modules (PSUPDRVLNXMODULE). */
     293static RTLISTANCHOR             g_supdrvLinuxWrapperModuleList;
     294#endif
    263295
    264296
     
    310342{
    311343    int       rc;
     344
     345#if RTLNX_VER_MIN(5,0,0)
     346    spin_lock_init(&g_supdrvLinuxWrapperModuleSpinlock);
     347    RTListInit(&g_supdrvLinuxWrapperModuleList);
     348#endif
    312349
    313350    /*
     
    362399#endif
    363400                    {
     401#if RTLNX_VER_MIN(5,0,0)
     402                        /*
     403                         * Register the module notifier.
     404                         */
     405                        int rc2 = register_module_notifier(&g_supdrvLinuxModuleNotifierBlock);
     406                        if (rc2)
     407                            printk(KERN_WARNING "vboxdrv: failed to register module notifier! rc2=%d\n", rc2);
     408#endif
     409
     410
    364411                        printk(KERN_INFO "vboxdrv: TSC mode is %s, tentative frequency %llu Hz\n",
    365412                               SUPGetGIPModeName(g_DevExt.pGip), g_DevExt.pGip->u64CpuHz);
     
    405452    platform_device_unregister(&gPlatformDevice);
    406453    platform_driver_unregister(&gPlatformDriver);
     454#endif
     455
     456#if RTLNX_VER_MIN(5,0,0)
     457    /*
     458     * Kick the list of potential wrapper modules.
     459     */
     460    unregister_module_notifier(&g_supdrvLinuxModuleNotifierBlock);
     461
     462    spin_lock(&g_supdrvLinuxWrapperModuleSpinlock);
     463    while (!RTListIsEmpty(&g_supdrvLinuxWrapperModuleList))
     464    {
     465        PSUPDRVLNXMODULE pCur = RTListRemoveFirst(&g_supdrvLinuxWrapperModuleList, SUPDRVLNXMODULE, ListEntry);
     466        spin_unlock(&g_supdrvLinuxWrapperModuleSpinlock);
     467
     468        pCur->pModule = NULL;
     469        RTMemFree(pCur);
     470
     471        spin_lock(&g_supdrvLinuxWrapperModuleSpinlock);
     472    }
     473    spin_unlock(&g_supdrvLinuxWrapperModuleSpinlock);
    407474#endif
    408475
     
    761828
    762829
    763 # if RTLNX_VER_MAX(5,12,0)
     830#if RTLNX_VER_MIN(5,0,0)
     831
     832/**
     833 * Checks if the given module is one of our potential wrapper modules or not.
     834 */
     835static bool supdrvLinuxLdrIsPotentialWrapperModule(struct module const *pModule)
     836{
     837    if (   pModule
     838        && strncmp(pModule->name, RT_STR_TUPLE("vbox_")) == 0)
     839        return true;
     840    return false;
     841}
     842
     843/**
     844 * Called when a kernel module changes state.
     845 *
     846 * We use this to listen for wrapper modules being loaded, since some evil
     847 * bugger removed the find_module() export in 5.13.
     848 */
     849static int supdrvLinuxLdrModuleNotifyCallback(struct notifier_block *pBlock, unsigned long uModuleState, void *pvModule)
     850{
     851    struct module *pModule = (struct module *)pvModule;
     852    switch (uModuleState)
     853    {
     854        case MODULE_STATE_UNFORMED: /* Setting up the module... */
     855            break;
     856
     857        /*
     858         * The module is about to have its ctors & init functions called.
     859         *
     860         * Add anything that looks like a wrapper module to our tracker list.
     861         */
     862        case MODULE_STATE_COMING:
     863            if (supdrvLinuxLdrIsPotentialWrapperModule(pModule))
     864            {
     865                PSUPDRVLNXMODULE pTracker = (PSUPDRVLNXMODULE)RTMemAlloc(sizeof(*pTracker));
     866                if (pTracker)
     867                {
     868                    pTracker->pModule = pModule;
     869                    spin_lock(&g_supdrvLinuxWrapperModuleSpinlock);
     870                    RTListPrepend(&g_supdrvLinuxWrapperModuleList, &pTracker->ListEntry);
     871                    spin_unlock(&g_supdrvLinuxWrapperModuleSpinlock);
     872                }
     873            }
     874            break;
     875
     876        case MODULE_STATE_LIVE:
     877            break;
     878
     879        /*
     880         * The module has been uninited and is going away.
     881         *
     882         * Remove the tracker entry for the module, if we have one.
     883         */
     884        case MODULE_STATE_GOING:
     885        {
     886            PSUPDRVLNXMODULE pCur;
     887            spin_lock(&g_supdrvLinuxWrapperModuleSpinlock);
     888            RTListForEach(&g_supdrvLinuxWrapperModuleList, pCur, SUPDRVLNXMODULE, ListEntry)
     889            {
     890                if (pCur->pModule == pModule)
     891                {
     892                    RTListNodeRemove(&pCur->ListEntry);
     893                    spin_unlock(&g_supdrvLinuxWrapperModuleSpinlock);
     894
     895                    pCur->pModule = NULL;
     896                    RTMemFree(pCur);
     897
     898                    spin_lock(&g_supdrvLinuxWrapperModuleSpinlock); /* silly */
     899                    break;
     900                }
     901            }
     902            spin_unlock(&g_supdrvLinuxWrapperModuleSpinlock);
     903            break;
     904        }
     905    }
     906    RT_NOREF(pBlock);
     907    return NOTIFY_OK;
     908}
     909
     910/**
     911 * Replacement for find_module() that's no longer exported with 5.13.
     912 */
     913static struct module *supdrvLinuxLdrFindModule(const char *pszLnxModName)
     914{
     915    PSUPDRVLNXMODULE pCur;
     916
     917    spin_lock(&g_supdrvLinuxWrapperModuleSpinlock);
     918    RTListForEach(&g_supdrvLinuxWrapperModuleList, pCur, SUPDRVLNXMODULE, ListEntry)
     919    {
     920        struct module * const pModule = pCur->pModule;
     921        if (   pModule
     922            && strcmp(pszLnxModName, pModule->name) == 0)
     923        {
     924            spin_unlock(&g_supdrvLinuxWrapperModuleSpinlock);
     925            return pModule;
     926        }
     927    }
     928    spin_unlock(&g_supdrvLinuxWrapperModuleSpinlock);
     929    return NULL;
     930}
     931
     932#endif /* >= 5.0.0 */
     933
     934
    764935/**
    765936 * Used by native wrapper modules, forwarding to supdrvLdrRegisterWrappedModule
     
    769940                                                    const char *pszLnxModName, void **phMod)
    770941{
    771 # if RTLNX_VER_MIN(2,6,30)
     942    AssertPtrReturn(pszLnxModName, VERR_INVALID_POINTER);
     943    AssertReturn(*pszLnxModName, VERR_INVALID_NAME);
     944
    772945    /* Locate the module structure for the caller so can later reference
    773946       and dereference it to prevent unloading while it is being used.
     
    783956       SUPDrv so we can call find_module() here.
    784957
    785        Sigh^2. */
    786     AssertPtrReturn(pszLnxModName, VERR_INVALID_POINTER);
    787     AssertReturn(*pszLnxModName, VERR_INVALID_NAME);
     958       Sigh^2.
     959
     960       Update 5.13:
     961       The find_module() and module_mutex symbols are no longer exported,
     962       probably the doing of the same evil bugger mentioned above.  So, we now
     963       register a module notification callback and track the modules we're
     964       interested in that way. */
     965
     966#if RTLNX_VER_MIN(5,0,0)
     967    struct module *pLnxModule = supdrvLinuxLdrFindModule(pszLnxModName);
     968    if (pLnxModule)
     969        return supdrvLdrRegisterWrappedModule(&g_DevExt, pWrappedModInfo, pLnxModule, phMod);
     970    printk("vboxdrv: supdrvLinuxLdrFindModule(%s) failed in SUPDrvLinuxLdrRegisterWrappedModule!\n", pszLnxModName);
     971    return VERR_MODULE_NOT_FOUND;
     972
     973#elif RTLNX_VER_MIN(2,6,30)
    788974    if (mutex_lock_interruptible(&module_mutex) == 0)
    789975    {
     
    796982    }
    797983    return VERR_INTERRUPTED;
    798 # else
     984
     985#else
    799986    printk("vboxdrv: wrapper modules are not supported on 2.6.29 and earlier. sorry.\n");
    800987    return VERR_NOT_SUPPORTED;
    801 # endif
     988#endif
    802989}
    803990EXPORT_SYMBOL(SUPDrvLinuxLdrRegisterWrappedModule);
    804 #endif /* < 5.12.0 */
    805991
    806992
Note: See TracChangeset for help on using the changeset viewer.

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