commit b8c6c3683894072f4a8ff910c354c03b65a23464 Author: Knut St. Osmundsen Date: Fri May 29 20:46:11 2026 +0000 SUPDrv/linux: Kicked out the code for the old KVM init approach. bugref:11093 bugref:10963 svn:sync-xref-src-repo-rev: r174036 diff --git a/src/VBox/HostDrivers/Support/linux/SUPDrv-linux.c b/src/VBox/HostDrivers/Support/linux/SUPDrv-linux.c index 41f73f61d41..f01446e6909 100644 --- a/src/vboxhost/vboxdrv/linux/SUPDrv-linux.c +++ b/src/vboxhost/vboxdrv/linux/SUPDrv-linux.c @@ -1,4 +1,4 @@ -/* $Id: SUPDrv-linux.c 114188 2026-05-27 06:59:16Z knut.osmundsen@oracle.com $ */ +/* $Id: SUPDrv-linux.c 114219 2026-05-29 20:46:11Z knut.osmundsen@oracle.com $ */ /** @file * VBoxDrv - The VirtualBox Support Driver - Linux specifics. */ @@ -112,12 +112,6 @@ # include # include # include - -#elif RTLNX_VER_RANGE(6,16,0, 7,1,0) && defined(CONFIG_MODULES) && defined(CONFIG_KVM_GENERIC_HARDWARE_ENABLING) && defined(VBOX_WITH_HOST_VMX) -# if defined(RT_ARCH_AMD64) || defined(RT_ARCH_X86) -# include -# define SUPDRV_LINUX_HAS_KVM_HWVIRT_API -# endif #endif @@ -241,23 +235,7 @@ static struct file_system_type g_SupDrvLnxFsType = .kill_sb = kill_anon_super }; # endif /* SUPDRV_LINUX_WITH_DUMMY_KVM_VM_OPENED_VIA_INODE */ - -#elif defined(SUPDRV_LINUX_HAS_KVM_HWVIRT_API) -/** Whether we have called kvm_enable_virtualization(). */ -static bool g_fEnabledHwvirtUsingKvm; -/** Whether we think AMD-V is supported by the CPU. */ -static bool g_fCpuSupportsSvm; -/** Whether we think VT-x is supported by the CPU. */ -static bool g_fCpuSupportsVmx; -/** Whether we need to put the corresponding KVM function pointers. */ -static bool g_fPutKvmEnableVirtualization, g_fPutKvmDisableVirtualization; -/** Function pointer to kvm_enable_virtualization(). */ -static __typeof__(kvm_enable_virtualization) *g_pfnKvmEnableVirtualization; -/** Function pointer to kvm_disable_virtualization(). */ -static __typeof__(kvm_disable_virtualization) *g_pfnKvmDisableVirtualization; -/** Pointer to the KVM hardware specific module. */ -static struct module *g_pKvmHwvirtModule; -#endif +#endif /* SUPDRV_LINUX_WITH_DUMMY_KVM_VM */ #if RTLNX_VER_MIN(6,15,0) && (defined(RT_ARCH_AMD64) || defined(RT_ARCH_X86)) /** Pointer to the switch_fpu_return function. */ @@ -430,7 +408,7 @@ DECLINLINE(RTUID) vboxdrvLinuxEuid(void) #endif -#if (RTLNX_VER_MIN(6,15,0) || defined(SUPDRV_LINUX_HAS_KVM_HWVIRT_API)) && (defined(RT_ARCH_AMD64) || defined(RT_ARCH_X86)) +#if RTLNX_VER_MIN(6,15,0) && (defined(RT_ARCH_AMD64) || defined(RT_ARCH_X86)) /** * Dynamically resolves a function we need. * @@ -463,116 +441,6 @@ supdrvLinuxFunction(const char *pszModule, const char *pszFunctionNm, PFNRT *ppf } #endif -#ifdef SUPDRV_LINUX_HAS_KVM_HWVIRT_API - -/** - * This is a hack/workaround that attempts to detect whether - * kvm_enable_virtualization() is likely to have been called. See - * @bugref{10963#c14} for details. - */ -static bool supdrvLinuxIsKvmVirtEnabledLikelyCalled(void) -{ - /** @todo Try get address of kvm_usage_count and its mutex via kallsyms_lookup_name() - * which in turn should be looked up by a kprobe. */ - /* - * We don't disable preemption/interrupts here because we assume all CPUs will have - * the relevant bits identical in CR4 and EFER. - */ - uint64_t const fVmxeMask = RT_BIT_64(13); /* CR4.VMXE bit. */ - if ( g_fCpuSupportsVmx - && (ASMGetCR4() & fVmxeMask)) - return true; - - uint32_t const idEfer = 0xc0000080; /* EFER MSR. */ - uint64_t const fSvmeMask = RT_BIT_64(12); /* EFER.SVME bit. */ - if ( g_fCpuSupportsSvm - && (ASMRdMsr(idEfer) & fSvmeMask)) - return true; - - return false; -} - - -/** - * Initializes usage of KVM hardware-virtualization symbols. - */ -static int __init supdrvLinuxInitKvmSymbols(PRTDBGKRNLINFO phKrnlInfo) -{ - /* - * Figure out the module name first using SUPR0GetVTSupport - * and just stop early if we cannot figure out the module name. - */ - uint32_t fCaps = 0; - int rc = SUPR0GetVTSupport(&fCaps); - g_fCpuSupportsSvm = (fCaps & SUPVTCAPS_AMD_V) || rc == VERR_SVM_NO_SVM; - g_fCpuSupportsVmx = (fCaps & SUPVTCAPS_VT_X) || rc == VERR_VMX_NO_VMX; - const char * const pszModName = g_fCpuSupportsVmx ? "kvm_intel" - : g_fCpuSupportsSvm ? "kvm_amd" : NULL; - if (!pszModName) - { - printk(KERN_WARNING "vboxdrv: Cannot determine KVM module name for this CPU architecture! (%d)\n", rc); - return RT_FAILURE(rc) ? rc : VERR_NOT_FOUND; - } - - /* - * Get the enable & disable functions. - */ - g_fPutKvmEnableVirtualization = supdrvLinuxFunction("kvm", "kvm_enable_virtualization", - (PFNRT *)&g_pfnKvmEnableVirtualization, phKrnlInfo); - if (g_pfnKvmEnableVirtualization) - { - g_fPutKvmDisableVirtualization = supdrvLinuxFunction("kvm", "kvm_disable_virtualization", - (PFNRT *)&g_pfnKvmDisableVirtualization, phKrnlInfo); - if (g_pfnKvmDisableVirtualization) - { - /* - * Try to obtain a reference to kvm_intel/kvm_amd module in addition to the - * reference to the kvm module. If we fail, we will not try to use KVM for - * enabling/disable hardware-virtualization. This is due a a bug in the Linux - * kernel, see @bugref{10963}. - * - * Note! find_module isn't exported, so we have to temporarily disable the - * indirect branch track machinery in order to call it safely. - * (Setting the SUPPORESS bit to 1 probably won't help much here, as - * the call is done via __x86_indirect_thunk_xxx.) - */ - struct module * (*pfnFindModule)(const char *) = NULL; - bool fPutFindModule = supdrvLinuxFunction(NULL, "find_module", (PFNRT *)&pfnFindModule, phKrnlInfo); - if (pfnFindModule) - { - struct module *pModule; - RTLNX_CET_UNSAFE_CALL(pfnFindModule, pModule = pfnFindModule(pszModName)); - if (fPutFindModule) - symbol_put_addr(pfnFindModule); - - if (pModule) - { - if (try_module_get(pModule)) - { - g_pKvmHwvirtModule = pModule; - return VINF_SUCCESS; - } - printk(KERN_WARNING "vboxdrv: Failed to obtain reference for the KVM impl module (%s)\n", pszModName); - } - else - printk(KERN_WARNING "vboxdrv: Failed to find the KVM impl module (%s)\n", pszModName); - } - if (g_fPutKvmDisableVirtualization) - symbol_put_addr(g_pfnKvmDisableVirtualization); - } - if (g_fPutKvmEnableVirtualization) - symbol_put_addr(g_pfnKvmEnableVirtualization); - } - - g_pfnKvmDisableVirtualization = NULL; - g_pfnKvmEnableVirtualization = NULL; - g_pKvmHwvirtModule = NULL; - g_fPutKvmEnableVirtualization = false; - g_fPutKvmDisableVirtualization = false; - return VERR_NOT_FOUND; -} - -#endif /* SUPDRV_LINUX_HAS_KVM_HWVIRT_API */ /** * Initialize module. @@ -640,23 +508,14 @@ static int __init VBoxDrvLinuxInit(void) /* * Resolve symbols that was made difficult to access with 6.19. */ -#if (defined(SUPDRV_LINUX_HAS_KVM_HWVIRT_API) || RTLNX_VER_MIN(6,15,0)) && (defined(RT_ARCH_AMD64) || defined(RT_ARCH_X86)) +#if RTLNX_VER_MIN(6,15,0) && (defined(RT_ARCH_AMD64) || defined(RT_ARCH_X86)) RTDBGKRNLINFO hKrnlInfo = NIL_RTDBGKRNLINFO; -# if RTLNX_VER_MIN(6,15,0) /* Needed for FPU management. */ supdrvLinuxFunction(NULL, "switch_fpu_return", (PFNRT *)&g_pfnSwitchFpuReturn, &hKrnlInfo); -# endif # ifdef SUPDRV_LINUX_DYNAMIC_CR4_FUNCTIONS /* Shadow CR4 */ supdrvLinuxFunction(NULL, "cr4_update_irqsoff", (PFNRT *)&g_pfnCr4UpdateIrqsoff, &hKrnlInfo); supdrvLinuxFunction(NULL, "cr4_read_shadow", (PFNRT *)&g_pfnCr4ReadShadow, &hKrnlInfo); -# endif -# ifdef SUPDRV_LINUX_HAS_KVM_HWVIRT_API - int rc2 = supdrvLinuxInitKvmSymbols(&hKrnlInfo); - if (RT_SUCCESS(rc2)) - printk(KERN_INFO "vboxdrv: Found KVM hardware-virtualization symbols\n"); - else - printk(KERN_WARNING "vboxdrv: Failed to find KVM hardware-virtualization symbols\n"); # endif if (hKrnlInfo != NIL_RTDBGKRNLINFO) RTR0DbgKrnlInfoRelease(hKrnlInfo); @@ -726,22 +585,8 @@ static void __exit VBoxDrvLinuxUnload(void) #endif /* - * Release symbol and module references. + * Release symbol references. */ -#ifdef SUPDRV_LINUX_HAS_KVM_HWVIRT_API - /* Put the kvm symbols and module. */ - if (g_fPutKvmEnableVirtualization && g_pfnKvmEnableVirtualization) - symbol_put_addr(g_pfnKvmEnableVirtualization); - g_pfnKvmEnableVirtualization = NULL; - if (g_fPutKvmDisableVirtualization && g_pfnKvmDisableVirtualization) - symbol_put_addr(g_pfnKvmDisableVirtualization); - if (g_pKvmHwvirtModule) - { - module_put(g_pKvmHwvirtModule); - g_pKvmHwvirtModule = NULL; - } -#endif - #ifdef SUPDRV_LINUX_DYNAMIC_CR4_FUNCTIONS /* We don't need to put these, they should be in core_kernel_text(). */ g_pfnCr4UpdateIrqsoff = NULL; @@ -2221,39 +2066,10 @@ int VBOXCALL supdrvOSEnableHwvirt(bool fEnable) } return rc; -#elif defined(SUPDRV_LINUX_HAS_KVM_HWVIRT_API) - if ( g_pfnKvmEnableVirtualization - && g_pfnKvmDisableVirtualization - && supdrvLinuxIsKvmVirtEnabledLikelyCalled()) - { /* likely */ } - else - return VERR_NOT_AVAILABLE; - - if (fEnable) - { - /* kvm_enable_virtualization() is guarded by kvm_usage_count reference counter inside a mutex. */ - int rc; - RTLNX_CET_UNSAFE_CALL(g_pfnKvmEnableVirtualization, rc = g_pfnKvmEnableVirtualization()); - if (!rc) - { - g_fEnabledHwvirtUsingKvm = true; - printk(KERN_INFO "vboxdrv: Enabled hardware-virtualization using KVM\n"); - return VINF_SUCCESS; - } - printk(KERN_ERR "vboxdrv: Failed to enable hardware-virtualization using KVM. rc=%d\n", rc); - return VERR_NOT_AVAILABLE; - } - - if (g_fEnabledHwvirtUsingKvm) - { - RTLNX_CET_UNSAFE_CALL(g_pfnKvmDisableVirtualization, g_pfnKvmDisableVirtualization()); - g_fEnabledHwvirtUsingKvm = false; - } - return VINF_SUCCESS; -#else +#else /* !SUPDRV_LINUX_WITH_DUMMY_KVM_VM */ RT_NOREF(fEnable); return VERR_NOT_SUPPORTED; -#endif +#endif /* !SUPDRV_LINUX_WITH_DUMMY_KVM_VM */ } @@ -2627,7 +2443,7 @@ MODULE_LICENSE("GPL"); #ifdef MODULE_VERSION MODULE_VERSION(VBOX_VERSION_STRING " r" RT_XSTR(VBOX_SVN_REV) " (" RT_XSTR(SUPDRV_IOC_VERSION) ")"); #endif -#ifdef SUPDRV_LINUX_HAS_KVM_HWVIRT_API +#ifdef SUPDRV_LINUX_WITH_DUMMY_KVM_VM MODULE_SOFTDEP("pre: kvm_intel kvm_amd"); #endif