Path: blob/main/emulators/virtualbox-ose/files/patch-src-VBox-Additions-common-VBoxGuest-VBoxGuest-freebsd.c
17391 views
--- src/VBox/Additions/common/VBoxGuest/VBoxGuest-freebsd.c.orig 2019-01-25 18:12:28 UTC1+++ src/VBox/Additions/common/VBoxGuest/VBoxGuest-freebsd.c2@@ -45,6 +45,7 @@3#include <sys/uio.h>4#include <sys/bus.h>5#include <sys/poll.h>6+#include <sys/proc.h>7#include <sys/selinfo.h>8#include <sys/queue.h>9#include <sys/lock.h>10@@ -61,6 +62,7 @@11#include <VBox/version.h>12#include <VBox/log.h>13#include <iprt/assert.h>14+#include <iprt/err.h>15#include <iprt/initterm.h>16#include <iprt/process.h>17#include <iprt/string.h>18@@ -102,8 +104,6 @@ struct VBoxGuestDeviceState19struct resource *pIrqRes;20/** Pointer to the IRQ handler. */21void *pfnIrqHandler;22- /** VMMDev version */23- uint32_t u32Version;24};252627@@ -113,8 +113,7 @@ struct VBoxGuestDeviceState28/*29* Character device file handlers.30*/31-static d_fdopen_t vgdrvFreeBSDOpen;32-static d_close_t vgdrvFreeBSDClose;33+static d_open_t vgdrvFreeBSDOpen;34static d_ioctl_t vgdrvFreeBSDIOCtl;35static int vgdrvFreeBSDIOCtlSlow(PVBOXGUESTSESSION pSession, u_long ulCmd, caddr_t pvData, struct thread *pTd);36static d_write_t vgdrvFreeBSDWrite;37@@ -145,8 +144,7 @@ static struct cdevsw g_vgdrvFreeBSDChrDevSW =38{39.d_version = D_VERSION,40.d_flags = D_TRACKCLOSE | D_NEEDMINOR,41- .d_fdopen = vgdrvFreeBSDOpen,42- .d_close = vgdrvFreeBSDClose,43+ .d_open = vgdrvFreeBSDOpen,44.d_ioctl = vgdrvFreeBSDIOCtl,45.d_read = vgdrvFreeBSDRead,46.d_write = vgdrvFreeBSDWrite,47@@ -154,81 +152,28 @@ static struct cdevsw g_vgdrvFreeBSDChrDevSW =48.d_name = "vboxguest"49};5051+/** Device structure. */52+static struct cdev *g_pDev;53+54/** Device extention & session data association structure. */55static VBOXGUESTDEVEXT g_DevExt;5657-/** List of cloned device. Managed by the kernel. */58-static struct clonedevs *g_pvgdrvFreeBSDClones;59-/** The dev_clone event handler tag. */60-static eventhandler_tag g_vgdrvFreeBSDEHTag;61/** Reference counter */62static volatile uint32_t cUsers;63/** selinfo structure used for polling. */64static struct selinfo g_SelInfo;6566-/**67- * DEVFS event handler.68- */69-static void vgdrvFreeBSDClone(void *pvArg, struct ucred *pCred, char *pszName, int cchName, struct cdev **ppDev)70+static void vgdrvFreeBSDDtr(void *pSession)71{72- int iUnit;73- int rc;74-75- Log(("vgdrvFreeBSDClone: pszName=%s ppDev=%p\n", pszName, ppDev));76-77- /*78- * One device node per user, si_drv1 points to the session.79- * /dev/vboxguest<N> where N = {0...255}.80- */81- if (!ppDev)82- return;83- if (strcmp(pszName, "vboxguest") == 0)84- iUnit = -1;85- else if (dev_stdclone(pszName, NULL, "vboxguest", &iUnit) != 1)86- return;87- if (iUnit >= 256)88- {89- Log(("vgdrvFreeBSDClone: iUnit=%d >= 256 - rejected\n", iUnit));90- return;91- }92-93- Log(("vgdrvFreeBSDClone: pszName=%s iUnit=%d\n", pszName, iUnit));94-95- rc = clone_create(&g_pvgdrvFreeBSDClones, &g_vgdrvFreeBSDChrDevSW, &iUnit, ppDev, 0);96- Log(("vgdrvFreeBSDClone: clone_create -> %d; iUnit=%d\n", rc, iUnit));97- if (rc)98- {99- *ppDev = make_dev(&g_vgdrvFreeBSDChrDevSW,100- iUnit,101- UID_ROOT,102- GID_WHEEL,103- 0664,104- "vboxguest%d", iUnit);105- if (*ppDev)106- {107- dev_ref(*ppDev);108- (*ppDev)->si_flags |= SI_CHEAPCLONE;109- Log(("vgdrvFreeBSDClone: Created *ppDev=%p iUnit=%d si_drv1=%p si_drv2=%p\n",110- *ppDev, iUnit, (*ppDev)->si_drv1, (*ppDev)->si_drv2));111- (*ppDev)->si_drv1 = (*ppDev)->si_drv2 = NULL;112- }113- else114- Log(("vgdrvFreeBSDClone: make_dev iUnit=%d failed\n", iUnit));115- }116- else117- Log(("vgdrvFreeBSDClone: Existing *ppDev=%p iUnit=%d si_drv1=%p si_drv2=%p\n",118- *ppDev, iUnit, (*ppDev)->si_drv1, (*ppDev)->si_drv2));119+ VGDrvCommonCloseSession(&g_DevExt, pSession);120+ ASMAtomicDecU32(&cUsers);121}122123/**124* File open handler125*126*/127-#if __FreeBSD_version >= 700000128-static int vgdrvFreeBSDOpen(struct cdev *pDev, int fOpen, struct thread *pTd, struct file *pFd)129-#else130-static int vgdrvFreeBSDOpen(struct cdev *pDev, int fOpen, struct thread *pTd)131-#endif132+static int vgdrvFreeBSDOpen(struct cdev *pDev, int fOpen, int DevType, struct thread *pTd)133{134int rc;135PVBOXGUESTSESSION pSession;136@@ -240,12 +185,6 @@ static int vgdrvFreeBSDOpen(struct cdev *pDev, int fOp137LogFlow(("vgdrvFreeBSDOpen:\n"));138139/*140- * Try grab it (we don't grab the giant, remember).141- */142- if (!ASMAtomicCmpXchgPtr(&pDev->si_drv1, (void *)0x42, NULL))143- return EBUSY;144-145- /*146* Create a new session.147*/148fRequestor = VMMDEV_REQUESTOR_USERMODE | VMMDEV_REQUESTOR_TRUST_NOT_GIVEN;149@@ -262,14 +201,13 @@ static int vgdrvFreeBSDOpen(struct cdev *pDev, int fOp150rc = VGDrvCommonCreateUserSession(&g_DevExt, fRequestor, &pSession);151if (RT_SUCCESS(rc))152{153- if (ASMAtomicCmpXchgPtr(&pDev->si_drv1, pSession, (void *)0x42))154- {155- Log(("vgdrvFreeBSDOpen: success - g_DevExt=%p pSession=%p rc=%d pid=%d\n", &g_DevExt, pSession, rc, (int)RTProcSelf()));156+ Log(("vgdrvFreeBSDOpen: success - g_DevExt=%p pSession=%p rc=%d pid=%d\n", &g_DevExt, pSession, rc, (int)RTProcSelf()));157+ rc = devfs_set_cdevpriv(pSession, vgdrvFreeBSDDtr);158+ if (rc)159+ VGDrvCommonCloseSession(&g_DevExt, pSession);160+ else161ASMAtomicIncU32(&cUsers);162- return 0;163- }164-165- VGDrvCommonCloseSession(&g_DevExt, pSession);166+ return rc;167}168169LogRel(("vgdrvFreeBSDOpen: failed. rc=%d\n", rc));170@@ -277,33 +215,6 @@ static int vgdrvFreeBSDOpen(struct cdev *pDev, int fOp171}172173/**174- * File close handler175- *176- */177-static int vgdrvFreeBSDClose(struct cdev *pDev, int fFile, int DevType, struct thread *pTd)178-{179- PVBOXGUESTSESSION pSession = (PVBOXGUESTSESSION)pDev->si_drv1;180- Log(("vgdrvFreeBSDClose: fFile=%#x pSession=%p\n", fFile, pSession));181-182- /*183- * Close the session if it's still hanging on to the device...184- */185- if (VALID_PTR(pSession))186- {187- VGDrvCommonCloseSession(&g_DevExt, pSession);188- if (!ASMAtomicCmpXchgPtr(&pDev->si_drv1, NULL, pSession))189- Log(("vgdrvFreeBSDClose: si_drv1=%p expected %p!\n", pDev->si_drv1, pSession));190- ASMAtomicDecU32(&cUsers);191- /* Don't use destroy_dev here because it may sleep resulting in a hanging user process. */192- destroy_dev_sched(pDev);193- }194- else195- Log(("vgdrvFreeBSDClose: si_drv1=%p!\n", pSession));196- return 0;197-}198-199-200-/**201* I/O control request.202*203* @returns depends...204@@ -316,8 +227,12 @@ static int vgdrvFreeBSDClose(struct cdev *pDev, int fF205static int vgdrvFreeBSDIOCtl(struct cdev *pDev, u_long ulCmd, caddr_t pvData, int fFile, struct thread *pTd)206{207PVBOXGUESTSESSION pSession;208- devfs_get_cdevpriv((void **)&pSession);209+ int rc;210211+ rc = devfs_get_cdevpriv((void **)&pSession);212+ if (rc)213+ return rc;214+215/*216* Deal with the fast ioctl path first.217*/218@@ -512,12 +427,14 @@ int VBOXCALL VBoxGuestIDC(void *pvSession, uintptr_t u219220static int vgdrvFreeBSDPoll(struct cdev *pDev, int fEvents, struct thread *td)221{222- int fEventsProcessed;223+ PVBOXGUESTSESSION pSession;224+ int fEventsProcessed, rc;225226LogFlow(("vgdrvFreeBSDPoll: fEvents=%d\n", fEvents));227228- PVBOXGUESTSESSION pSession = (PVBOXGUESTSESSION)pDev->si_drv1;229- if (RT_UNLIKELY(!VALID_PTR(pSession))) {230+ rc = devfs_get_cdevpriv((void **)&pSession);231+ if (rc)232+ {233Log(("vgdrvFreeBSDPoll: no state data for %s\n", devtoname(pDev)));234return (fEvents & (POLLHUP|POLLIN|POLLRDNORM|POLLOUT|POLLWRNORM));235}236@@ -558,11 +475,8 @@ static int vgdrvFreeBSDDetach(device_t pDevice)237/*238* Reverse what we did in vgdrvFreeBSDAttach.239*/240- if (g_vgdrvFreeBSDEHTag != NULL)241- EVENTHANDLER_DEREGISTER(dev_clone, g_vgdrvFreeBSDEHTag);242+ destroy_dev(g_pDev);243244- clone_cleanup(&g_pvgdrvFreeBSDClones);245-246vgdrvFreeBSDRemoveIRQ(pDevice, pState);247248if (pState->pVMMDevMemRes)249@@ -727,18 +641,21 @@ static int vgdrvFreeBSDAttach(device_t pDevice)250VGDrvCommonProcessOptionsFromHost(&g_DevExt);251252/*253- * Configure device cloning.254+ * Configure device.255*/256- clone_setup(&g_pvgdrvFreeBSDClones);257- g_vgdrvFreeBSDEHTag = EVENTHANDLER_REGISTER(dev_clone, vgdrvFreeBSDClone, 0, 1000);258- if (g_vgdrvFreeBSDEHTag)259+ g_pDev = make_dev(&g_vgdrvFreeBSDChrDevSW,260+ 0,261+ UID_ROOT,262+ GID_WHEEL,263+ 0664,264+ "vboxguest");265+ if (g_pDev)266{267printf(DEVICE_NAME ": loaded successfully\n");268return 0;269}270271- printf(DEVICE_NAME ": EVENTHANDLER_REGISTER(dev_clone,,,) failed\n");272- clone_cleanup(&g_pvgdrvFreeBSDClones);273+ printf(DEVICE_NAME ": make_dev failed\n");274vgdrvFreeBSDRemoveIRQ(pDevice, pState);275}276else277278279