diff --git a/emulators/virtualbox-ose-kmod-legacy/Makefile b/emulators/virtualbox-ose-kmod-legacy/Makefile index 06b78180fb46..dedde4502e84 100644 --- a/emulators/virtualbox-ose-kmod-legacy/Makefile +++ b/emulators/virtualbox-ose-kmod-legacy/Makefile @@ -1,108 +1,111 @@ # Created by: Bernhard Froehlich PORTNAME= virtualbox-ose PORTVERSION= 5.2.44 PORTREVISION= 6 CATEGORIES= emulators MASTER_SITES= https://download.oracle.com/virtualbox/${PORTVERSION}/ PKGNAMESUFFIX= -kmod-legacy DISTNAME= VirtualBox-${PORTVERSION} MAINTAINER= vbox@FreeBSD.org COMMENT= VirtualBox kernel module for FreeBSD LICENSE= GPLv2 LICENSE_FILE= ${WRKSRC}/COPYING BUILD_DEPENDS= kmk:devel/kBuild CPE_VENDOR= oracle CPE_PRODUCT= vm_virtualbox +SUB_FILES= pkg-message +SUB_LIST= OPSYS=${OPSYS} OSREL=${OSREL} + USES= cpe kmod tar:bzip2 PATCHDIR= ${.CURDIR}/../${PORTNAME}-legacy/files WRKSRC= ${WRKDIR}/VirtualBox-${PORTVERSION} USE_RC_SUBR= vboxnet ONLY_FOR_ARCHS= i386 amd64 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 PORTSCOUT= limit:^5\. 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-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-kmod-legacy/files/pkg-message.in b/emulators/virtualbox-ose-kmod-legacy/files/pkg-message.in new file mode 100644 index 000000000000..4e03cc0b5ec7 --- /dev/null +++ b/emulators/virtualbox-ose-kmod-legacy/files/pkg-message.in @@ -0,0 +1,10 @@ +[ +{ type: install + message: < PORTNAME= virtualbox-ose PORTVERSION= 6.1.34 +PORTREVISION= 1 CATEGORIES= emulators MASTER_SITES= https://download.virtualbox.org/virtualbox/${PORTVERSION}/ PKGNAMESUFFIX= -kmod DISTNAME= VirtualBox-${PORTVERSION} MAINTAINER= vbox@FreeBSD.org COMMENT= VirtualBox kernel module for FreeBSD LICENSE= GPLv2 LICENSE_FILE= ${WRKSRC}/COPYING BUILD_DEPENDS= kmk:devel/kBuild CPE_VENDOR= oracle CPE_PRODUCT= vm_virtualbox +SUB_FILES= pkg-message +SUB_LIST= OPSYS=${OPSYS} OSREL=${OSREL} + USES= cpe compiler:c++14-lang kmod tar:bzip2 PATCHDIR= ${.CURDIR}/../${PORTNAME}/files WRKSRC= ${WRKDIR}/VirtualBox-${PORTVERSION} USE_RC_SUBR= vboxnet ONLY_FOR_ARCHS= amd64 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 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-kmod/files/pkg-message.in b/emulators/virtualbox-ose-kmod/files/pkg-message.in new file mode 100644 index 000000000000..4e03cc0b5ec7 --- /dev/null +++ b/emulators/virtualbox-ose-kmod/files/pkg-message.in @@ -0,0 +1,10 @@ +[ +{ type: install + message: < #include "../SUPDrvInternal.h" +#include "freebsd/the-freebsd-kernel.h" #include #include #include @@ -57,7 +58,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 +84,9 @@ static d_open_t VBoxDrvFreeBSDOpenUsr; 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); /********************************************************************************************************************************* -@@ -182,6 +192,13 @@ static int VBoxDrvFreeBSDLoad(void) +@@ -93,7 +103,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 +193,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. */ -@@ -311,7 +328,21 @@ static int VBoxDrvFreeBSDIOCtl(struct cdev *pDev, u_lo +@@ -311,7 +329,21 @@ static int VBoxDrvFreeBSDIOCtl(struct cdev *pDev, u_lo PSUPDRVSESSION pSession; devfs_get_cdevpriv((void **)&pSession); +#ifdef VBOX_WITH_EFLAGS_AC_SET_IN_VBOXDRV /* + * Refuse all I/O control calls if we've ever detected EFLAGS.AC being cleared. + * + * This isn't a problem, as there is absolutely nothing in the kernel context that + * depend on user context triggering cleanups. That would be pretty wild, right? + */ + if (RT_UNLIKELY(g_VBoxDrvFreeBSDDevExt.cBadContextCalls > 0)) + { + SUPR0Printf("VBoxDrvFreBSDIOCtl: EFLAGS.AC=0 detected %u times, refusing all I/O controls!\n", g_VBoxDrvFreeBSDDevExt.cBadContextCalls); + return ESPIPE; + } +#endif + + /* * Deal with the fast ioctl path first. */ if ( ( ulCmd == SUP_IOCTL_FAST_DO_RAW_RUN -@@ -325,6 +356,45 @@ static int VBoxDrvFreeBSDIOCtl(struct cdev *pDev, u_lo +@@ -325,6 +357,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. -@@ -373,11 +443,10 @@ static int VBoxDrvFreeBSDIOCtlSlow(PSUPDRVSESSION pSes +@@ -373,11 +444,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, 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)) { -@@ -402,13 +471,12 @@ static int VBoxDrvFreeBSDIOCtlSlow(PSUPDRVSESSION pSes +@@ -402,13 +472,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, 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); -@@ -436,9 +504,8 @@ static int VBoxDrvFreeBSDIOCtlSlow(PSUPDRVSESSION pSes +@@ -436,9 +505,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(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)); -@@ -541,8 +608,7 @@ bool VBOXCALL supdrvOSGetForcedAsyncTscMode(PSUPDRVDE +@@ -541,8 +609,7 @@ bool VBOXCALL supdrvOSGetForcedAsyncTscMode(PSUPDRVDE bool VBOXCALL supdrvOSAreCpusOfflinedOnSuspend(void) { - /** @todo verify this. */ - return false; + return true; } -@@ -625,11 +691,25 @@ int VBOXCALL supdrvOSMsrProberModify(RTCPUID idCpu, +@@ -625,11 +692,25 @@ 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) SUPR0Printf(const char *pszFormat, ...) { va_list va; char szMsg[256]; int cch; + IPRT_FREEBSD_SAVE_EFL_AC(); va_start(va, pszFormat); cch = RTStrPrintfV(szMsg, sizeof(szMsg), pszFormat, va); -@@ -637,12 +717,19 @@ SUPR0DECL(int) SUPR0Printf(const char *pszFormat, ...) +@@ -637,12 +718,19 @@ SUPR0DECL(int) SUPR0Printf(const char *pszFormat, ...) printf("%s", szMsg); + IPRT_FREEBSD_RESTORE_EFL_AC(); return cch; } 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; } - 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 fb3a4470d560..2e2c292d7ee8 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,198 +1,208 @@ ---- src/VBox/HostDrivers/Support/freebsd/SUPDrv-freebsd.c.orig 2021-10-18 17:58:03 UTC -+++ src/VBox/HostDrivers/Support/freebsd/SUPDrv-freebsd.c +--- src/VBox/HostDrivers/Support/freebsd/SUPDrv-freebsd.c.orig 2021-10-18 10:58:03.000000000 -0700 ++++ src/VBox/HostDrivers/Support/freebsd/SUPDrv-freebsd.c 2021-11-19 15:31:33.152269000 -0800 @@ -44,8 +44,10 @@ #include #include #include +#include #include "../SUPDrvInternal.h" +#include "freebsd/the-freebsd-kernel.h" #include #include #include @@ -57,7 +59,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_open_t VBoxDrvFreeBSDOpenUsr; 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); /********************************************************************************************************************************* -@@ -182,6 +193,13 @@ static int VBoxDrvFreeBSDLoad(void) +@@ -93,7 +104,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) 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 +342,45 @@ static int VBoxDrvFreeBSDIOCtl(struct cdev *pDev, u_lo +@@ -324,6 +343,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 +429,10 @@ static int VBoxDrvFreeBSDIOCtlSlow(PSUPDRVSESSION pSes +@@ -372,11 +430,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, 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 +457,12 @@ static int VBoxDrvFreeBSDIOCtlSlow(PSUPDRVSESSION pSes +@@ -401,13 +458,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, 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 +490,8 @@ static int VBoxDrvFreeBSDIOCtlSlow(PSUPDRVSESSION pSes +@@ -435,9 +491,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(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 +594,7 @@ bool VBOXCALL supdrvOSGetForcedAsyncTscMode(PSUPDRVDE +@@ -540,8 +595,7 @@ bool VBOXCALL supdrvOSGetForcedAsyncTscMode(PSUPDRVDE bool VBOXCALL supdrvOSAreCpusOfflinedOnSuspend(void) { - /** @todo verify this. */ - return false; + return true; } -@@ -624,19 +677,43 @@ int VBOXCALL supdrvOSMsrProberModify(RTCPUID idCpu, +@@ -624,19 +678,43 @@ 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; }