Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 23 Jan 2011 16:33:07 +0200
From:      Mikolaj Golub <to.my.trociny@gmail.com>
To:        freebsd-virtualization@FreeBSD.org, freebsd-emulation@freebsd.org
Subject:   VirtualBox + VIMAGE
Message-ID:  <86oc77heqk.fsf@kopusha.home.net>

next in thread | raw e-mail | index | archive | help
--=-=-=

Hi,

Sorry for cross posting, but this question concerns both VirtualBox and VIMAGE :-).

I would like to be able to run VirtualBox on my desktop, with kernel compilled
with VIMAGE, so I would use light vnet jails for FreeBSD VMs and VirtualBox
for other OSes.

Currently the system will crash if you try to use VirtualBox bridged
networking under VIMAGE kernel.

The crash may look like below:

db> bt

Tracing pid 2349 tid 100239 td 0xc984b2d0
ifunit(c7e3b9ac,6f,c129e970,f8089984,c08d6dc0,...) at ifunit+0x33
vboxNetFltOsInitInstance(c7e3b810,0,8,7,c9aa6ae0,...) at vboxNetFltOsInitInstance+0x31
vboxNetFltFactoryCreateAndConnect(c9aa8cc8,c96636d4,c9664010,0,c966403c,...) at vboxNetFltFactory
CreateAndConnect+0x1f7
_end(c7b11810,c962c238,3,c962c2b8,0,...) at 0xc9c0114f
_end(c7b11810,c962c22c,f20,c0d31268,f8089a90,...) at 0xc9c01265
_end(c962c22c,0,0,c7b11810,c0cfe2fe,...) at 0xc9bbc775
_end(f808a000,fffffffd,28,c962c22c,0,...) at 0xc9bbd086
supdrvIOCtl(c10c5607,c12a0a40,c7b11810,c962c200,c0e81df8,...) at supdrvIOCtl+0x1af1
VBoxDrvFreeBSDIOCtl(c94efb00,c10c5607,c962c200,3,c984b2d0,...) at VBoxDrvFreeBSDIOCtl+0x1ea
devfs_ioctl_f(c8e70118,c10c5607,c962c200,c9a82900,c984b2d0,...) at devfs_ioctl_f+0x10b
kern_ioctl(c984b2d0,e,c10c5607,c962c200,1089cec,...) at kern_ioctl+0x1fd
ioctl(c984b2d0,f8089cec,2b077000,1,c94ed2a8,...) at ioctl+0x134
syscallenter(c984b2d0,f8089ce4,c0c20e2d,c0e83290,0,...) at syscallenter+0x2a6
syscall(f8089d28) at syscall+0x4f
Xint0x80_syscall() at Xint0x80_syscall+0x21
--- syscall (54, FreeBSD ELF32, ioctl), eip = 0x282ae093, esp = 0xbf8b980c, ebp = 0xbf8b9828 ---

So it crashes when a function (ifunit in this case) tries to access
virtualized variable (V_ifnet in this case). The macro uses td->td_vnet for
this, which should be set to current vnet, but for VBox driver threads it is
NULL.

As a quick fix I added in VBoxNetFlt-freebsd.c in all "problem" functions
CURVNET_SET_QUIET(vnet0) macro, which sets td->td_vnet to default vnet (see the
attached patch). This has fixed the issue for me and now I am happily running
both VNET jails and VirtualBox machines on my desktop.

But the way I fixed the issue looks hackish for me. Could someone suggest a
better solution?

In case someone is interested in trying this patch, below are the instructions
how to build "VIMAGE safe" vbox driver from ports:

cd /usr/ports/emulators/virtualbox-ose-kmod
make patch
cd work
patch -p0 < /path/to/VirtualBox-3.2.12.VIMAGE.patch
cd ..
VIMAGE=1 make

-- 
Mikolaj Golub


--=-=-=
Content-Type: text/x-patch
Content-Disposition: inline; filename=VirtualBox-3.2.12.VIMAGE.patch

diff -rpu VirtualBox-3.2.12_OSE.orig/src/VBox/HostDrivers/VBoxNetFlt/freebsd/Makefile VirtualBox-3.2.12_OSE/src/VBox/HostDrivers/VBoxNetFlt/freebsd/Makefile
--- VirtualBox-3.2.12_OSE.orig/src/VBox/HostDrivers/VBoxNetFlt/freebsd/Makefile	2010-12-01 19:09:33.000000000 +0200
+++ VirtualBox-3.2.12_OSE/src/VBox/HostDrivers/VBoxNetFlt/freebsd/Makefile	2011-01-23 12:44:24.000000000 +0200
@@ -26,6 +26,10 @@ CFLAGS += -DRT_OS_FREEBSD -DIN_RING0 -DI
  CFLAGS += -DRT_ARCH_AMD64
 .endif
 
+.if defined(VIMAGE)
+ CFLAGS += -DVIMAGE
+.endif
+
 SRCS = \
 	VBoxNetFlt-freebsd.c \
 	VBoxNetFlt.c \
diff -rpu VirtualBox-3.2.12_OSE.orig/src/VBox/HostDrivers/VBoxNetFlt/freebsd/VBoxNetFlt-freebsd.c VirtualBox-3.2.12_OSE/src/VBox/HostDrivers/VBoxNetFlt/freebsd/VBoxNetFlt-freebsd.c
--- VirtualBox-3.2.12_OSE.orig/src/VBox/HostDrivers/VBoxNetFlt/freebsd/VBoxNetFlt-freebsd.c	2010-12-01 19:09:33.000000000 +0200
+++ VirtualBox-3.2.12_OSE/src/VBox/HostDrivers/VBoxNetFlt/freebsd/VBoxNetFlt-freebsd.c	2011-01-23 12:14:19.000000000 +0200
@@ -51,6 +51,7 @@
 #include <net/if_dl.h>
 #include <net/if_types.h>
 #include <net/ethernet.h>
+#include <net/vnet.h>
 
 #include <netgraph/ng_message.h>
 #include <netgraph/netgraph.h>
@@ -322,6 +323,7 @@ static int ng_vboxnetflt_rcvdata(hook_p 
     struct m_tag *mtag;
     bool fActive;
 
+    CURVNET_SET_QUIET(vnet0);
     fActive = vboxNetFltTryRetainBusyActive(pThis);
 
     NGI_GET_M(item, m);
@@ -346,6 +348,7 @@ static int ng_vboxnetflt_rcvdata(hook_p 
             ether_demux(ifp, m);
             if (fActive)
                 vboxNetFltRelease(pThis, true /*fBusy*/);
+            CURVNET_RESTORE();
             return (0);
         }
         mtx_lock_spin(&pThis->u.s.inq.ifq_mtx);
@@ -363,6 +366,7 @@ static int ng_vboxnetflt_rcvdata(hook_p 
             int rc = ether_output_frame(ifp, m);
             if (fActive)
                 vboxNetFltRelease(pThis, true /*fBusy*/);
+            CURVNET_RESTORE();
             return rc;
         }
         mtx_lock_spin(&pThis->u.s.outq.ifq_mtx);
@@ -377,6 +381,7 @@ static int ng_vboxnetflt_rcvdata(hook_p 
 
     if (fActive)
         vboxNetFltRelease(pThis, true /*fBusy*/);
+    CURVNET_RESTORE();
     return (0);
 }
 
@@ -409,6 +414,7 @@ static void vboxNetFltFreeBSDinput(void 
     bool fDropIt = false, fActive;
     PINTNETSG pSG;
 
+    CURVNET_SET_QUIET(vnet0);
     vboxNetFltRetain(pThis, true /* fBusy */);
     for (;;)
     {
@@ -438,6 +444,7 @@ static void vboxNetFltFreeBSDinput(void 
             ether_demux(ifp, m);
     }
     vboxNetFltRelease(pThis, true /* fBusy */);
+    CURVNET_RESTORE();
 }
 
 /**
@@ -452,6 +459,7 @@ static void vboxNetFltFreeBSDoutput(void
     bool fDropIt = false, fActive;
     PINTNETSG pSG;
 
+    CURVNET_SET_QUIET(vnet0);
     vboxNetFltRetain(pThis, true /* fBusy */);
     for (;;)
     {
@@ -481,6 +489,7 @@ static void vboxNetFltFreeBSDoutput(void
             ether_output_frame(ifp, m);
     }
     vboxNetFltRelease(pThis, true /* fBusy */);
+    CURVNET_RESTORE();
 }
 
 /**
@@ -497,6 +506,7 @@ int vboxNetFltPortOsXmit(PVBOXNETFLTINS 
     bool fActive;
     int error;
 
+    CURVNET_SET_QUIET(vnet0);
     ifp = (void *)ASMAtomicUoReadPtr((void * volatile *)&pThis->u.s.ifp);
 
     if (fDst & INTNETTRUNKDIR_WIRE)
@@ -539,6 +549,7 @@ int vboxNetFltPortOsXmit(PVBOXNETFLTINS 
         m->m_pkthdr.rcvif = ifp;
         ifp->if_input(ifp, m);
     }
+    CURVNET_RESTORE();
     return VINF_SUCCESS;
 }
 
@@ -556,6 +567,7 @@ int vboxNetFltOsInitInstance(PVBOXNETFLT
     node_p node;
     RTSPINLOCKTMP Tmp = RTSPINLOCKTMP_INITIALIZER;
 
+    CURVNET_SET_QUIET(vnet0);
     NOREF(pvContext);
     ifp = ifunit(pThis->szName);
     if (ifp == NULL)
@@ -602,6 +614,7 @@ int vboxNetFltOsInitInstance(PVBOXNETFLT
         pThis->pSwitchPort->pfnReportNoPreemptDsts(pThis->pSwitchPort, 0 /* none */);
         vboxNetFltRelease(pThis, true /*fBusy*/);
     }
+    CURVNET_RESTORE();
 
     return VINF_SUCCESS;
 }
@@ -610,6 +623,7 @@ bool vboxNetFltOsMaybeRediscovered(PVBOX
 {
     struct ifnet *ifp, *ifp0;
 
+    CURVNET_SET_QUIET(vnet0);
     ifp = (struct ifnet *)ASMAtomicUoReadPtr((void * volatile *)&pThis->u.s.ifp);
     /*
      * Attempt to check if the interface is still there and re-initialize if
@@ -628,6 +642,7 @@ bool vboxNetFltOsMaybeRediscovered(PVBOX
         vboxNetFltOsDeleteInstance(pThis);
         vboxNetFltOsInitInstance(pThis, NULL);
     }
+    CURVNET_RESTORE()
 
     return !ASMAtomicUoReadBool(&pThis->fDisconnectedFromHost);
 }
@@ -667,6 +682,7 @@ void vboxNetFltPortOsSetActive(PVBOXNETF
     char path[NG_PATHSIZ];
 
     Log(("%s: fActive:%d\n", __func__, fActive));
+    CURVNET_SET_QUIET(vnet0);
 
     ifp = (struct ifnet *)ASMAtomicUoReadPtr((void * volatile *)&pThis->u.s.ifp);
     node = (node_p)ASMAtomicUoReadPtr((void * volatile *)&pThis->u.s.node);
@@ -742,6 +758,7 @@ void vboxNetFltPortOsSetActive(PVBOXNETF
         strlcpy(rm->ourhook, "output", NG_HOOKSIZ);
         NG_SEND_MSG_PATH(error, node, msg, path, 0);
     }
+    CURVNET_RESTORE();
 }
 
 int vboxNetFltOsDisconnectIt(PVBOXNETFLTINS pThis)

--=-=-=--



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?86oc77heqk.fsf>