diff --git a/emulators/virtualbox-ose-kmod/Makefile b/emulators/virtualbox-ose-kmod/Makefile index b06147d885d1..252ba10585de 100644 --- a/emulators/virtualbox-ose-kmod/Makefile +++ b/emulators/virtualbox-ose-kmod/Makefile @@ -1,109 +1,110 @@ PORTNAME= virtualbox-ose DISTVERSION= 6.1.50 +PORTREVISION= 1 CATEGORIES= emulators MASTER_SITES= https://download.virtualbox.org/virtualbox/${DISTVERSION}/ PKGNAMESUFFIX= -kmod DISTNAME= VirtualBox-${DISTVERSION} MAINTAINER= vbox@FreeBSD.org COMMENT= VirtualBox kernel module for FreeBSD WWW= https://www.virtualbox.org/ LICENSE= GPLv2 LICENSE_FILE= ${WRKSRC}/COPYING ONLY_FOR_ARCHS= amd64 BUILD_DEPENDS= kmk:devel/kBuild USES= cpe compiler:c++14-lang kmod tar:bzip2 CPE_VENDOR= oracle CPE_PRODUCT= vm_virtualbox USE_RC_SUBR= vboxnet HAS_CONFIGURE= yes CONFIGURE_ARGS+= --build-headless CONFIGURE_ARGS+= --disable-alsa \ --disable-dbus \ --disable-docs \ --disable-libvpx \ --disable-pulse \ --disable-python \ --disable-sdl-ttf \ --disable-xpcom CONFIGURE_ARGS+= --nofatal --with-gcc="${CC}" --with-g++="${CXX}" CONFLICTS_INSTALL= virtualbox-ose-kmod-legacy PATCHDIR= ${.CURDIR}/../${PORTNAME}/files SUB_FILES= pkg-message SUB_LIST= OPSYS=${OPSYS} OSREL=${OSREL} WRKSRC= ${WRKDIR}/VirtualBox-${DISTVERSION} OPTIONS_DEFINE= DEBUG VIMAGE OPTIONS_DEFAULT= VIMAGE OPTIONS_SUB= yes DEBUG_DESC= Debug symbols, additional logs and assertions VIMAGE_DESC= VIMAGE virtual networking support .include VBOX_BIN= ${WRKSRC}/out/${KMK_ARCH}/${KMK_BUILDTYPE}/bin/src VBOX_KMODS= vboxdrv \ vboxnetadp \ vboxnetflt BUILD_WRKSRC= ${VBOX_BIN} KMK_BUILDTYPE= release KMK_CONFIG= VBOX_LIBPATH_X11=${LOCALBASE} VBOX_FREEBSD_SRC=${SRC_BASE}/sys KMK_FLAGS= HostDrivers-scripts vboxdrv-src VBoxNetFlt-src VBoxNetAdp-src .if ${PORT_OPTIONS:MDEBUG} KMK_FLAGS+= BUILD_TYPE=debug KMK_BUILDTYPE= debug EXTRA_PATCHES+= ${PATCHDIR}/extrapatch-Config.kmk \ ${PATCHDIR}/extrapatch-src-VBox-HostDrivers-Support-freebsd-Makefile MAKE_ARGS+= DEBUG_FLAGS="-O1 -g" .endif .if ${ARCH} == i386 KMK_ARCH= freebsd.x86 .else KMK_ARCH= freebsd.${ARCH} .endif .include SYMBOLSUFFIX= debug PLIST_SUB+= SYMBOLSUFFIX=${SYMBOLSUFFIX} post-patch: @${ECHO_CMD} 'VBOX_WITH_VBOXDRV = 1' > ${WRKSRC}/LocalConfig.kmk @${ECHO_CMD} 'VBOX_WITH_NETFLT = 1' >> ${WRKSRC}/LocalConfig.kmk @${ECHO_CMD} 'VBOX_WITH_NETADP = 1' >> ${WRKSRC}/LocalConfig.kmk @${ECHO_CMD} 'VBOX_WITH_ADDITIONS =' >> ${WRKSRC}/LocalConfig.kmk .if ${PORT_OPTIONS:MVIMAGE} @${ECHO_CMD} 'VBOX_WITH_NETFLT_VIMAGE = 1' >> ${WRKSRC}/LocalConfig.kmk .endif @${REINPLACE_CMD} -e 's|/usr/local|${LOCALBASE}|g' \ ${WRKSRC}/Config.kmk ${WRKSRC}/configure @${REINPLACE_CMD} \ -e 's|\$$KBUILDDIR_BIN/kmk_sed|${LOCALBASE}/bin/kmk_sed|g' \ ${WRKSRC}/configure pre-build: cd ${WRKSRC}/src/VBox/HostDrivers && ${SH} -c \ '. ${WRKSRC}/env.sh && ${KMK_CONFIG} ${LOCALBASE}/bin/kmk ${KMK_FLAGS}' do-install: ${MKDIR} ${STAGEDIR}${KMODDIR} .for i in ${VBOX_KMODS} ${INSTALL_KLD} ${VBOX_BIN}/${i}/${i}.ko ${STAGEDIR}${KMODDIR} .if ${PORT_OPTIONS:MDEBUG} ${INSTALL_KLD} ${VBOX_BIN}/${i}/${i}.ko.${SYMBOLSUFFIX} ${STAGEDIR}${KMODDIR} .endif .endfor .include diff --git a/emulators/virtualbox-ose/files/patch-src_VBox_HostDrivers_Support_freebsd_SUPDrv-freebsd.c b/emulators/virtualbox-ose/files/patch-src_VBox_HostDrivers_Support_freebsd_SUPDrv-freebsd.c index ea9d35bc1c65..7dd580efb0a0 100644 --- a/emulators/virtualbox-ose/files/patch-src_VBox_HostDrivers_Support_freebsd_SUPDrv-freebsd.c +++ b/emulators/virtualbox-ose/files/patch-src_VBox_HostDrivers_Support_freebsd_SUPDrv-freebsd.c @@ -1,209 +1,224 @@ --- src/VBox/HostDrivers/Support/freebsd/SUPDrv-freebsd.c.orig 2022-07-19 20:58:42 UTC +++ src/VBox/HostDrivers/Support/freebsd/SUPDrv-freebsd.c -@@ -44,8 +44,10 @@ +@@ -44,8 +44,11 @@ #include #include #include +#include ++#include /* mp_maxcpus */ #include "../SUPDrvInternal.h" +#include "freebsd/the-freebsd-kernel.h" #include #include #include -@@ -57,7 +59,14 @@ +@@ -57,7 +60,14 @@ #include #include #include +#include +#ifdef VBOX_WITH_EFLAGS_AC_SET_IN_VBOXDRV +# include +# include +# include +#endif + #ifdef VBOX_WITH_HARDENING # define VBOXDRV_PERM 0600 #else -@@ -76,7 +85,9 @@ static d_ioctl_t VBoxDrvFreeBSDIOCtl; +@@ -76,7 +86,9 @@ static d_ioctl_t VBoxDrvFreeBSDIOCtl; static d_open_t VBoxDrvFreeBSDOpenSys; static void vboxdrvFreeBSDDtr(void *pvData); static d_ioctl_t VBoxDrvFreeBSDIOCtl; +static d_ioctl_t VBoxDrvFreeBSDIOCtlSMAP; static int VBoxDrvFreeBSDIOCtlSlow(PSUPDRVSESSION pSession, u_long ulCmd, caddr_t pvData, struct thread *pTd); +static bool VBoxDrvFreeBSDCpuHasSMAP(void); /********************************************************************************************************************************* -@@ -93,7 +104,8 @@ static moduledata_t g_VBoxDrvFreeBSDModule = +@@ -93,7 +105,8 @@ static moduledata_t g_VBoxDrvFreeBSDModule = }; /** Declare the module as a pseudo device. */ -DECLARE_MODULE(vboxdrv, g_VBoxDrvFreeBSDModule, SI_SUB_PSEUDO, SI_ORDER_ANY); +#define KERNEL_RELBRANCHEND (roundup(__FreeBSD_version, 500) - 1) +DECLARE_MODULE_WITH_MAXVER(vboxdrv, g_VBoxDrvFreeBSDModule, SI_SUB_PSEUDO, SI_ORDER_ANY, KERNEL_RELBRANCHEND); MODULE_VERSION(vboxdrv, 1); /** -@@ -182,6 +194,13 @@ static int VBoxDrvFreeBSDLoad(void) +@@ -140,6 +153,13 @@ static int VBoxDrvFreeBSDModuleEvent(struct module *pM + static int VBoxDrvFreeBSDModuleEvent(struct module *pMod, int enmEventType, void *pvArg) + { + int rc; ++ ++ /* Refuse to load if mp_maxcpus is wrong */ ++ if (MAXCPU != mp_maxcpus) { ++ printf("vboxdrv: MAXCPU != mp_maxcpus (%d != %d)\n", MAXCPU, mp_maxcpus); ++ return EINVAL; ++ } ++ + switch (enmEventType) + { + case MOD_LOAD: +@@ -182,6 +202,13 @@ static int VBoxDrvFreeBSDLoad(void) rc = supdrvInitDevExt(&g_VBoxDrvFreeBSDDevExt, sizeof(SUPDRVSESSION)); if (RT_SUCCESS(rc)) { + if (VBoxDrvFreeBSDCpuHasSMAP()) + { + LogRel(("disabling SMAP for VBoxDrvFreeBSDIOCtl\n")); + g_VBoxDrvFreeBSDChrDevSwSys.d_ioctl = VBoxDrvFreeBSDIOCtlSMAP; + g_VBoxDrvFreeBSDChrDevSwUsr.d_ioctl = VBoxDrvFreeBSDIOCtlSMAP; + } + /* * Configure character devices. Add symbolic links for compatibility. */ -@@ -324,6 +343,45 @@ static int VBoxDrvFreeBSDIOCtl(struct cdev *pDev, u_lo +@@ -324,6 +351,45 @@ static int VBoxDrvFreeBSDIOCtl(struct cdev *pDev, u_lo /** + * Alternative Device I/O Control entry point on hosts with SMAP support. + * + * @returns depends... + * @param pDev The device. + * @param ulCmd The command. + * @param pvData Pointer to the data. + * @param fFile The file descriptor flags. + * @param pTd The calling thread. + */ +static int VBoxDrvFreeBSDIOCtlSMAP(struct cdev *pDev, u_long ulCmd, caddr_t pvData, int fFile, struct thread *pTd) +{ + /* + * Allow VBox R0 code to touch R3 memory. Setting the AC bit disables the + * SMAP check. + */ + RTCCUINTREG fSavedEfl = ASMAddFlags(X86_EFL_AC); + + int rc = VBoxDrvFreeBSDIOCtl(pDev, ulCmd, pvData, fFile, pTd); + +#ifdef VBOX_WITH_EFLAGS_AC_SET_IN_VBOXDRV + /* + * Before we restore AC and the rest of EFLAGS, check if the IOCtl handler code + * accidentially modified it or some other important flag. + */ + if (RT_UNLIKELY( (ASMGetFlags() & (X86_EFL_AC | X86_EFL_IF | X86_EFL_DF | X86_EFL_IOPL)) + != ((fSavedEfl & (X86_EFL_AC | X86_EFL_IF | X86_EFL_DF | X86_EFL_IOPL)) | X86_EFL_AC) )) + { + char szTmp[48]; + RTStrPrintf(szTmp, sizeof(szTmp), "ulCmd=%#x: %#x->%#x!", ulCmd, (uint32_t)fSavedEfl, (uint32_t)ASMGetFlags()); + supdrvBadContext(&g_VBoxDrvFreeBSDDevExt, "SUPDrv-freebsd.c", __LINE__, szTmp); + } +#endif + + ASMSetFlags(fSavedEfl); + return rc; +} + + +/** * Deal with the 'slow' I/O control requests. * * @returns 0 on success, appropriate errno on failure. -@@ -372,11 +430,10 @@ static int VBoxDrvFreeBSDIOCtlSlow(PSUPDRVSESSION pSes +@@ -372,11 +438,10 @@ static int VBoxDrvFreeBSDIOCtlSlow(PSUPDRVSESSION pSes */ SUPREQHDR Hdr; pvUser = *(void **)pvData; - int rc = copyin(pvUser, &Hdr, sizeof(Hdr)); - if (RT_UNLIKELY(rc)) + if (RT_FAILURE(RTR0MemUserCopyFrom(&Hdr, (uintptr_t)pvUser, sizeof(Hdr)))) { - OSDBGPRINT(("VBoxDrvFreeBSDIOCtlSlow: copyin(%p,Hdr,) -> %#x; ulCmd=%#lx\n", pvUser, rc, ulCmd)); - return rc; + OSDBGPRINT(("VBoxDrvFreeBSDIOCtlSlow: copyin(%p,Hdr,); ulCmd=%#lx\n", pvUser, ulCmd)); + return EFAULT; } if (RT_UNLIKELY((Hdr.fFlags & SUPREQHDR_FLAGS_MAGIC_MASK) != SUPREQHDR_FLAGS_MAGIC)) { -@@ -401,13 +458,12 @@ static int VBoxDrvFreeBSDIOCtlSlow(PSUPDRVSESSION pSes +@@ -401,13 +466,12 @@ static int VBoxDrvFreeBSDIOCtlSlow(PSUPDRVSESSION pSes OSDBGPRINT(("VBoxDrvFreeBSDIOCtlSlow: failed to allocate buffer of %d bytes; ulCmd=%#lx\n", cbReq, ulCmd)); return ENOMEM; } - rc = copyin(pvUser, pHdr, Hdr.cbIn); - if (RT_UNLIKELY(rc)) + if (RT_FAILURE(RTR0MemUserCopyFrom(pHdr, (uintptr_t)pvUser, Hdr.cbIn))) { - OSDBGPRINT(("VBoxDrvFreeBSDIOCtlSlow: copyin(%p,%p,%#x) -> %#x; ulCmd=%#lx\n", - pvUser, pHdr, Hdr.cbIn, rc, ulCmd)); + OSDBGPRINT(("VBoxDrvFreeBSDIOCtlSlow: copyin(%p,%p,%#x); ulCmd=%#lx\n", + pvUser, pHdr, Hdr.cbIn, ulCmd)); RTMemTmpFree(pHdr); - return rc; + return EFAULT; } if (Hdr.cbIn < cbReq) RT_BZERO((uint8_t *)pHdr + Hdr.cbIn, cbReq - Hdr.cbIn); -@@ -435,9 +491,8 @@ static int VBoxDrvFreeBSDIOCtlSlow(PSUPDRVSESSION pSes +@@ -435,9 +499,8 @@ static int VBoxDrvFreeBSDIOCtlSlow(PSUPDRVSESSION pSes OSDBGPRINT(("VBoxDrvFreeBSDIOCtlSlow: too much output! %#x > %#x; uCmd=%#lx!\n", cbOut, cbReq, ulCmd)); cbOut = cbReq; } - rc = copyout(pHdr, pvUser, cbOut); - if (RT_UNLIKELY(rc)) - OSDBGPRINT(("VBoxDrvFreeBSDIOCtlSlow: copyout(%p,%p,%#x) -> %d; uCmd=%#lx!\n", pHdr, pvUser, cbOut, rc, ulCmd)); + if (RT_FAILURE(RTR0MemUserCopyTo((uintptr_t)pvUser, pHdr, cbOut))) + OSDBGPRINT(("VBoxDrvFreeBSDIOCtlSlow: copyout(%p,%p,%#x); uCmd=%#lx!\n", pHdr, pvUser, cbOut, ulCmd)); Log(("VBoxDrvFreeBSDIOCtlSlow: returns %d / %d ulCmd=%lx\n", 0, pHdr->rc, ulCmd)); -@@ -540,8 +595,7 @@ bool VBOXCALL supdrvOSAreCpusOfflinedOnSuspend(void) +@@ -540,8 +603,7 @@ bool VBOXCALL supdrvOSAreCpusOfflinedOnSuspend(void) bool VBOXCALL supdrvOSAreCpusOfflinedOnSuspend(void) { - /** @todo verify this. */ - return false; + return true; } -@@ -624,20 +678,44 @@ int VBOXCALL supdrvOSMsrProberModify(RTCPUID idCpu, +@@ -624,20 +686,44 @@ int VBOXCALL supdrvOSMsrProberModify(RTCPUID idCpu, #endif /* SUPDRV_WITH_MSR_PROBER */ +/** + * Check if the CPU has SMAP support. + */ +static bool VBoxDrvFreeBSDCpuHasSMAP(void) +{ +#ifdef VBOX_WITH_EFLAGS_AC_SET_IN_VBOXDRV + if ((cpu_stdext_feature & CPUID_STDEXT_SMAP) != 0) + return true; +#endif + return false; +} + + SUPR0DECL(int) SUPR0PrintfV(const char *pszFormat, va_list va) { char szMsg[256]; + IPRT_FREEBSD_SAVE_EFL_AC(); + RTStrPrintfV(szMsg, sizeof(szMsg), pszFormat, va); szMsg[sizeof(szMsg) - 1] = '\0'; printf("%s", szMsg); + + IPRT_FREEBSD_RESTORE_EFL_AC(); return 0; } SUPR0DECL(uint32_t) SUPR0GetKernelFeatures(void) { - return 0; + uint32_t fFlags = 0; +#ifdef VBOX_WITH_EFLAGS_AC_SET_IN_VBOXDRV + if (g_VBoxDrvFreeBSDChrDevSwSys.d_ioctl == VBoxDrvFreeBSDIOCtlSMAP) + fFlags |= SUPKERNELFEATURES_SMAP; + else + Assert(!(ASMGetCR4() & X86_CR4_SMAP)); +#endif + return fFlags; }