[Pkg-virtualbox-commits] [virtualbox] 01/03: Imported Upstream version 4.3.34-dfsg

Gianfranco Costamagna locutusofborg-guest at moszumanska.debian.org
Wed Nov 18 08:28:28 UTC 2015


This is an automated email from the git hooks/post-receive script.

locutusofborg-guest pushed a commit to branch jessie
in repository virtualbox.

commit 2044fac0361813d4ca650d6124a18c8db25eb50c
Author: Gianfranco Costamagna <costamagnagianfranco at yahoo.it>
Date:   Tue Nov 17 14:35:36 2015 +0100

    Imported Upstream version 4.3.34-dfsg
---
 Config.kmk                                         |    4 +-
 doc/manual/user_ChangeLogImpl.xml                  |   43 +
 include/VBox/err.h                                 |    6 +-
 include/iprt/string.h                              |    2 +
 .../Graphics/BIOS/VBoxVgaBiosAlternative.asm       |    6 +-
 .../Graphics/BIOS/VBoxVgaBiosAlternative.md5sum    |    2 +-
 src/VBox/Devices/Graphics/DevVGA-SVGA3d.cpp        |    2 +-
 src/VBox/Devices/Graphics/DevVGA.h                 |   13 +-
 src/VBox/Devices/Graphics/DevVGA_VBVA.cpp          |    6 +-
 src/VBox/Devices/Network/slirp/tcp_subr.c          |   16 +
 src/VBox/Devices/PC/BIOS/VBoxBiosAlternative.asm   |    4 +-
 .../Devices/PC/BIOS/VBoxBiosAlternative.md5sum     |    2 +-
 .../Devices/USB/linux/USBProxyDevice-linux.cpp     |    1 -
 src/VBox/Devices/testcase/tstDeviceStructSize.cpp  |    3 +
 src/VBox/HostDrivers/VBoxNetAdp/VBoxNetAdp.c       | 1010 --------------------
 src/VBox/Installer/linux/rpm/VirtualBox.tmpl.spec  |    2 +-
 src/VBox/Main/src-server/MachineImpl.cpp           |    6 +-
 src/VBox/NetworkServices/NAT/pxtcp.c               |   14 +-
 src/VBox/Runtime/generic/http-curl.cpp             |    4 +-
 .../r0drv/darwin/dbgkrnlinfo-r0drv-darwin.cpp      |   72 +-
 src/VBox/Runtime/r3/nt/pathint-nt.cpp              |   20 +-
 src/VBox/VMM/VMMR0/HMSVMR0.cpp                     |   71 +-
 src/VBox/VMM/VMMR0/HMVMXR0.cpp                     |  132 ++-
 src/VBox/VMM/VMMR3/VMMGuruMeditation.cpp           |    1 +
 src/VBox/VMM/include/EMHandleRCTmpl.h              |    1 +
 src/libs/xpcom18a4/nsprpub/lib/ds/plarena.c        |   10 +
 src/libs/xpcom18a4/nsprpub/lib/ds/plarena.h        |   36 +-
 27 files changed, 348 insertions(+), 1141 deletions(-)

diff --git a/Config.kmk b/Config.kmk
index f41c2c0..f421d92 100644
--- a/Config.kmk
+++ b/Config.kmk
@@ -208,7 +208,7 @@ VBOX_VERSION_MINOR = 3
 # This is the current build number. It should be increased every time we publish a
 # new build. The define is available in every source file. Only even build numbers
 # will be published, odd numbers are set during development.
-VBOX_VERSION_BUILD = 32
+VBOX_VERSION_BUILD = 34
 # The raw version string. This *must not* contain any other information/fields than
 # major, minor and build revision (as it is now) -- also will be used for host/guest version
 # comparison.
@@ -5734,7 +5734,7 @@ endif
 SVN                    ?= svn$(HOSTSUFF_EXE)
 VBOX_SVN_REV_KMK        = $(PATH_OUT)/revision.kmk
 ifndef VBOX_SVN_REV
- VBOX_SVN_REV_FALLBACK := $(patsubst %:,,  $Rev: 103443 $  )
+ VBOX_SVN_REV_FALLBACK := $(patsubst %:,,  $Rev: 104062 $  )
  VBOX_SVN_DEP          := $(firstword $(wildcard $(PATH_ROOT)/.svn/wc.db $(abspath $(PATH_ROOT)/../.svn/wc.db) $(abspath $(PATH_ROOT)/../../.svn/wc.db) $(PATH_ROOT)/.svn/entries))
  ifeq ($(which $(SVN)),)
   VBOX_SVN_DEP         :=
diff --git a/doc/manual/user_ChangeLogImpl.xml b/doc/manual/user_ChangeLogImpl.xml
index eb4b325..c7839b5 100644
--- a/doc/manual/user_ChangeLogImpl.xml
+++ b/doc/manual/user_ChangeLogImpl.xml
@@ -1,6 +1,49 @@
 <?xml version="1.0" encoding="UTF-8"?>
 
   <sect1>
+    <title>Version 4.3.34 (2015-11-10)</title>
+
+    <para>This is a maintenance release. The following items were fixed and/or
+      added:</para>
+
+    <itemizedlist>
+
+      <listitem>
+        <para>NAT: support TCP in DNS proxy (bug #14736)</para>
+      </listitem>
+
+      <listitem>
+        <para>NAT Network: fixed sporadic crashes on Windows hosts (bug #13899)</para>
+      </listitem>
+      
+      <listitem>
+        <para>USB: fixed a crash under certain conditions on hosts with Linux
+          kernels older than version 3.3</para>
+      </listitem>
+
+      <listitem>
+        <para>OVF: fixed duplicate USB controller entries in exported OVA/OVF
+          (bug #14749)</para>
+      </listitem>
+
+      <listitem>
+        <para>Webcam: passthrough fix for certain devices (Windows hosts only)</para>
+      </listitem>
+
+      <listitem>
+        <para>Mac OS X hosts: use the correct kernel on certain hosts</para>
+      </listitem>
+
+      <listitem>
+        <para>Windows hosts: fixes for a shared folder path with extended-length
+          path prefix (bug #14651)</para>
+      </listitem>
+
+    </itemizedlist>
+
+  </sect1>
+
+  <sect1>
     <title>Version 4.3.32 (2015-10-20)</title>
 
     <para>This is a maintenance release. The following items were fixed and/or
diff --git a/include/VBox/err.h b/include/VBox/err.h
index 089d48a..71cba57 100644
--- a/include/VBox/err.h
+++ b/include/VBox/err.h
@@ -246,6 +246,8 @@
 /** The specified execution engine cannot execute guest code in the current
  *  state. */
 #define VERR_EM_CANNOT_EXEC_GUEST           (-1156)
+/** Guest tried to trigger a CPU hang.  The guest is probably up to no good. */
+#define VERR_EM_GUEST_CPU_HANG              (-1157)
 /** @} */
 
 
@@ -1777,9 +1779,9 @@
 /** Type error opening the ApiPort LPC object. */
 #define VERR_SUPDRV_APIPORT_OPEN_ERROR_TYPE         (-3742)
 /** The process trying to open VBoxDrv is not a budding VM process (1). */
-#define VERR_SUPDRV_NOT_BUDDING_VM_PROCESS_1          (-3748)
+#define VERR_SUPDRV_NOT_BUDDING_VM_PROCESS_1        (-3748)
 /** The process trying to open VBoxDrv is not a budding VM process (2). */
-#define VERR_SUPDRV_NOT_BUDDING_VM_PROCESS_2          (-3748)
+#define VERR_SUPDRV_NOT_BUDDING_VM_PROCESS_2        (-3749)
 /** @} */
 
 
diff --git a/include/iprt/string.h b/include/iprt/string.h
index daf88d0..ad05749 100644
--- a/include/iprt/string.h
+++ b/include/iprt/string.h
@@ -33,7 +33,9 @@
 #include <iprt/err.h> /* for VINF_SUCCESS */
 #if defined(RT_OS_LINUX) && defined(__KERNEL__)
   RT_C_DECLS_BEGIN
+# define new newhack /* string.h: strreplace */
 # include <linux/string.h>
+# undef new
   RT_C_DECLS_END
 
 #elif defined(IN_XF86_MODULE) && !defined(NO_ANSIC)
diff --git a/src/VBox/Devices/Graphics/BIOS/VBoxVgaBiosAlternative.asm b/src/VBox/Devices/Graphics/BIOS/VBoxVgaBiosAlternative.asm
index fea6b58..39101db 100644
--- a/src/VBox/Devices/Graphics/BIOS/VBoxVgaBiosAlternative.asm
+++ b/src/VBox/Devices/Graphics/BIOS/VBoxVgaBiosAlternative.asm
@@ -6779,7 +6779,7 @@ vesa_pm_end:                                 ; 0xc4714 LB 0x1
 
 section _DATA progbits vstart=0x4800 align=1 ; size=0x36e1 class=DATA group=DGROUP
 _msg_vga_init:                               ; 0xc4800 LB 0x2f
-    db  'Oracle VM VirtualBox Version 4.3.32 VGA BIOS', 00dh, 00ah, 000h
+    db  'Oracle VM VirtualBox Version 4.3.34 VGA BIOS', 00dh, 00ah, 000h
 _vga_modes:                                  ; 0xc482f LB 0x80
     db  000h, 000h, 000h, 004h, 000h, 0b8h, 0ffh, 002h, 001h, 000h, 000h, 004h, 000h, 0b8h, 0ffh, 002h
     db  002h, 000h, 000h, 004h, 000h, 0b8h, 0ffh, 002h, 003h, 000h, 000h, 004h, 000h, 0b8h, 0ffh, 002h
@@ -7667,7 +7667,7 @@ _vbebios_vendor_name:                        ; 0xc7e35 LB 0x13
 _vbebios_product_name:                       ; 0xc7e48 LB 0x21
     db  'Oracle VM VirtualBox VBE Adapter', 000h
 _vbebios_product_revision:                   ; 0xc7e69 LB 0x24
-    db  'Oracle VM VirtualBox Version 4.3.32', 000h
+    db  'Oracle VM VirtualBox Version 4.3.34', 000h
 _vbebios_info_string:                        ; 0xc7e8d LB 0x2b
     db  'VirtualBox VBE Display Adapter enabled', 00dh, 00ah, 00dh, 00ah, 000h
 _no_vbebios_info_string:                     ; 0xc7eb8 LB 0x29
@@ -7698,4 +7698,4 @@ section CONST2 progbits vstart=0x7ee2 align=1 ; size=0x0 class=DATA group=DGROUP
     db  000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
     db  000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
     db  000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
-    db  000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 05ch
+    db  000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 058h
diff --git a/src/VBox/Devices/Graphics/BIOS/VBoxVgaBiosAlternative.md5sum b/src/VBox/Devices/Graphics/BIOS/VBoxVgaBiosAlternative.md5sum
index b5abc0d..6f14759 100644
--- a/src/VBox/Devices/Graphics/BIOS/VBoxVgaBiosAlternative.md5sum
+++ b/src/VBox/Devices/Graphics/BIOS/VBoxVgaBiosAlternative.md5sum
@@ -1 +1 @@
-c7a975f86cc75eff05957f7d423d50ee *VBoxVgaBios.rom
+138999b9d7e5869585864ee28a6acf44 *VBoxVgaBios.rom
diff --git a/src/VBox/Devices/Graphics/DevVGA-SVGA3d.cpp b/src/VBox/Devices/Graphics/DevVGA-SVGA3d.cpp
index b53119c..d3e01da 100644
--- a/src/VBox/Devices/Graphics/DevVGA-SVGA3d.cpp
+++ b/src/VBox/Devices/Graphics/DevVGA-SVGA3d.cpp
@@ -401,7 +401,7 @@ int vmsvga3dSurfaceStretchBlt(PVGASTATE pThis, SVGA3dSurfaceImageId const *pDstS
         AssertRCReturn(rc, rc);
     }
 
-    if (VMSVGA3DSURFACE_HAS_HW_SURFACE(pDstSurface))
+    if (!VMSVGA3DSURFACE_HAS_HW_SURFACE(pDstSurface))
     {
         /* Unknown surface type; turn it into a texture, which can be used for other purposes too. */
         Log(("vmsvga3dSurfaceStretchBlt: unknown dest surface id=%x type=%d format=%d -> create texture\n", sidDst, pDstSurface->flags, pDstSurface->format));
diff --git a/src/VBox/Devices/Graphics/DevVGA.h b/src/VBox/Devices/Graphics/DevVGA.h
index 292ed63..8f79fb5 100644
--- a/src/VBox/Devices/Graphics/DevVGA.h
+++ b/src/VBox/Devices/Graphics/DevVGA.h
@@ -411,7 +411,7 @@ typedef struct VGAState {
     PPDMDEVINSRC                pDevInsRC;
     /** Pointer to the GC vram mapping. */
     RCPTRTYPE(uint8_t *)        vram_ptrRC;
-    uint32_t                    PaddingMinus1;
+    uint32_t                    Padding1;
 
     /** Pointer to the device instance - R3 Ptr. */
     PPDMDEVINSR3                pDevInsR3;
@@ -445,12 +445,13 @@ typedef struct VGAState {
     /** The R0 vram pointer... */
     R0PTRTYPE(uint8_t *)        vram_ptrR0;
 
-#ifdef VBOX_WITH_VMSVGA
 # if HC_ARCH_BITS == 32
     uint32_t                    Padding3;
 # endif
+
+# ifdef VBOX_WITH_VMSVGA
     VMSVGAState                 svga;
-#endif
+# endif
 
     /** The number of monitors. */
     uint32_t                    cMonitors;
@@ -471,12 +472,12 @@ typedef struct VGAState {
     bool                        fRemappedVGA;
     /** Whether to render the guest VRAM to the framebuffer memory. False only for some LFB modes. */
     bool                        fRenderVRAM;
-#ifdef VBOX_WITH_VMSVGA
+# ifdef VBOX_WITH_VMSVGA
     /* Whether the SVGA emulation is enabled or not. */
     bool                        fVMSVGAEnabled;
-    bool                        Padding1[1];
+    bool                        Padding4[1];
 #else
-    bool                        Padding1[2];
+    bool                        Padding4[2];
 #endif
 
     /** The physical address the VRAM was assigned. */
diff --git a/src/VBox/Devices/Graphics/DevVGA_VBVA.cpp b/src/VBox/Devices/Graphics/DevVGA_VBVA.cpp
index 094d83e..0d5f1aa 100644
--- a/src/VBox/Devices/Graphics/DevVGA_VBVA.cpp
+++ b/src/VBox/Devices/Graphics/DevVGA_VBVA.cpp
@@ -265,8 +265,7 @@ static bool vbvaFetchCmd (VBVAPARTIALRECORD *pPartialRecord, VBVABUFFER *pVBVA,
             /* The command does not cross buffer boundary. Return address in the buffer. */
             *ppHdr = (VBVACMDHDR *)src;
 
-            /* Advance data offset. */
-            pVBVA->off32Data = (pVBVA->off32Data + cbRecord) % pVBVA->cbData;
+            /* Data offset will be updated in vbvaReleaseCmd. */
         }
         else
         {
@@ -309,7 +308,8 @@ static void vbvaReleaseCmd (VBVAPARTIALRECORD *pPartialRecord, VBVABUFFER *pVBVA
         /* The pointer is inside ring buffer. Must be continuous chunk. */
         Assert (pVBVA->cbData - ((uint8_t *)pHdr - au8RingBuffer) >= cbCmd);
 
-        /* Do nothing. */
+        /* Advance data offset. */
+        pVBVA->off32Data = (pVBVA->off32Data + cbCmd) % pVBVA->cbData;
 
         Assert (!pPartialRecord->pu8 && pPartialRecord->cb == 0);
     }
diff --git a/src/VBox/Devices/Network/slirp/tcp_subr.c b/src/VBox/Devices/Network/slirp/tcp_subr.c
index 0769a5f..8f052a2 100644
--- a/src/VBox/Devices/Network/slirp/tcp_subr.c
+++ b/src/VBox/Devices/Network/slirp/tcp_subr.c
@@ -425,6 +425,22 @@ int tcp_fconnect(PNATState pData, struct socket *so)
             switch(RT_N2H_U32(so->so_faddr.s_addr) & ~pData->netmask)
             {
                 case CTL_DNS:
+                    /*
+                     * TCP DNS proxy.  We only support "forwarding" to
+                     * single server.  We don't have infrastructure in
+                     * place to re-try connections to other servers.
+                     */
+                    if (   pData->fUseDnsProxy
+                        && so->so_fport == RT_H2N_U16_C(53))
+                    {
+                        struct dns_entry *ns = TAILQ_LAST(&pData->pDnsList, dns_list_head);
+                        if (ns != NULL)
+                        {
+                            addr.sin_addr = ns->de_addr;
+                            break;
+                        }
+                    }
+                    /* FALLTHROUGH */
                 case CTL_ALIAS:
                 default:
                     addr.sin_addr = loopback_addr;
diff --git a/src/VBox/Devices/PC/BIOS/VBoxBiosAlternative.asm b/src/VBox/Devices/PC/BIOS/VBoxBiosAlternative.asm
index 41a6ff4..4322ef9 100644
--- a/src/VBox/Devices/PC/BIOS/VBoxBiosAlternative.asm
+++ b/src/VBox/Devices/PC/BIOS/VBoxBiosAlternative.asm
@@ -965,7 +965,7 @@ section CONST progbits vstart=0xb0 align=1 ; size=0xcf8 class=DATA group=DGROUP
 
 section CONST2 progbits vstart=0xda8 align=1 ; size=0x3fa class=DATA group=DGROUP
 _bios_cvs_version_string:                    ; 0xf0da8 LB 0x12
-    db  'VirtualBox 4.3.32', 000h
+    db  'VirtualBox 4.3.34', 000h
 _bios_prefix_string:                         ; 0xf0dba LB 0x8
     db  'BIOS: ', 000h, 000h
 _isotag:                                     ; 0xf0dc2 LB 0x6
@@ -16070,4 +16070,4 @@ dummy_iret:                                  ; 0xfff53 LB 0x9d
     db  'XM'
 cpu_reset:                                   ; 0xffff0 LB 0x10
     jmp far 0f000h:0e05bh                     ; ea 5b e0 00 f0
-    db  030h, 036h, 02fh, 032h, 033h, 02fh, 039h, 039h, 000h, 0fch, 000h
+    db  030h, 036h, 02fh, 032h, 033h, 02fh, 039h, 039h, 000h, 0fch, 0feh
diff --git a/src/VBox/Devices/PC/BIOS/VBoxBiosAlternative.md5sum b/src/VBox/Devices/PC/BIOS/VBoxBiosAlternative.md5sum
index 98b4438..7975320 100644
--- a/src/VBox/Devices/PC/BIOS/VBoxBiosAlternative.md5sum
+++ b/src/VBox/Devices/PC/BIOS/VBoxBiosAlternative.md5sum
@@ -1 +1 @@
-0c85b0e4727cac0e1be95cd8f912fb59 *VBoxPcBios.rom
+a98983b2e1367f7a32369c8a8c3b3ef9 *VBoxPcBios.rom
diff --git a/src/VBox/Devices/USB/linux/USBProxyDevice-linux.cpp b/src/VBox/Devices/USB/linux/USBProxyDevice-linux.cpp
index df05840..d2ad58e 100644
--- a/src/VBox/Devices/USB/linux/USBProxyDevice-linux.cpp
+++ b/src/VBox/Devices/USB/linux/USBProxyDevice-linux.cpp
@@ -1425,7 +1425,6 @@ static int usbProxyLinuxUrbQueueSplit(PUSBPROXYDEV pProxyDev, PUSBPROXYURBLNX pU
             rc = usbProxyLinuxSubmitURB(pProxyDev, pCur, pUrb, &fUnplugged);
             if (RT_FAILURE(rc))
                 break;
-            usbProxyLinuxUrbLinkInFlight(USBPROXYDEV_2_DATA(pProxyDev, PUSBPROXYDEVLNX), pCur);
         }
     }
 
diff --git a/src/VBox/Devices/testcase/tstDeviceStructSize.cpp b/src/VBox/Devices/testcase/tstDeviceStructSize.cpp
index 06bdfa4..75c5f51 100644
--- a/src/VBox/Devices/testcase/tstDeviceStructSize.cpp
+++ b/src/VBox/Devices/testcase/tstDeviceStructSize.cpp
@@ -325,8 +325,11 @@ int main()
     CHECK_MEMBER_ALIGNMENT(PITSTATE, StatPITIrq, 8);
     CHECK_MEMBER_ALIGNMENT(SerialState, CritSect, 8);
 #ifdef VBOX_WITH_VMSVGA
+    CHECK_SIZE(VMSVGAState, RT_ALIGN_Z(sizeof(VMSVGAState), 8));
+    CHECK_MEMBER_ALIGNMENT(VGASTATE, svga, 8);
     CHECK_MEMBER_ALIGNMENT(VGASTATE, svga.u64HostWindowId, 8);
 #endif
+    CHECK_MEMBER_ALIGNMENT(VGASTATE, cMonitors, 8);
     CHECK_MEMBER_ALIGNMENT(VGASTATE, GCPhysVRAM, 8);
     CHECK_MEMBER_ALIGNMENT(VGASTATE, Dev, 8);
     CHECK_MEMBER_ALIGNMENT(VGASTATE, CritSect, 8);
diff --git a/src/VBox/HostDrivers/VBoxNetAdp/VBoxNetAdp.c b/src/VBox/HostDrivers/VBoxNetAdp/VBoxNetAdp.c
index f3c0aaf..5bc1de4 100644
--- a/src/VBox/HostDrivers/VBoxNetAdp/VBoxNetAdp.c
+++ b/src/VBox/HostDrivers/VBoxNetAdp/VBoxNetAdp.c
@@ -35,1015 +35,6 @@
 #include <VBox/err.h>
 #include <iprt/string.h>
 
-#ifdef VBOXANETADP_DO_NOT_USE_NETFLT
-#error "this code is broken"
-
-#include <VBox/sup.h>
-#include <iprt/assert.h>
-#include <iprt/spinlock.h>
-#include <iprt/uuid.h>
-#include <VBox/version.h>
-
-/** r=bird: why is this here in the agnostic code? */
-#ifdef RT_OS_DARWIN
-# include <net/ethernet.h>
-# include <net/if_ether.h>
-# include <net/if_types.h>
-# include <sys/socket.h>
-# include <net/if.h>
-# include <net/if_dl.h>
-# include <sys/errno.h>
-# include <sys/param.h>
-#endif
-
-
-/*******************************************************************************
-*   Defined Constants And Macros                                               *
-*******************************************************************************/
-#define IFPORT_2_VBOXNETADP(pIfPort) \
-    ( (PVBOXNETADP)((uint8_t *)pIfPort - RT_OFFSETOF(VBOXNETADP, MyPort)) )
-
-
-AssertCompileMemberSize(VBOXNETADP, enmState, sizeof(uint32_t));
-
-/**
- * Gets the enmState member atomically.
- *
- * Used for all reads.
- *
- * @returns The enmState value.
- * @param   pThis           The instance.
- */
-DECLINLINE(VBOXNETADPSTATE) vboxNetAdpGetState(PVBOXNETADP pThis)
-{
-    return (VBOXNETADPSTATE)ASMAtomicUoReadU32((uint32_t volatile *)&pThis->enmState);
-}
-
-
-/**
- * Sets the enmState member atomically.
- *
- * Used for all updates.
- *
- * @param   pThis           The instance.
- * @param   enmNewState     The new value.
- */
-DECLINLINE(void) vboxNetAdpSetState(PVBOXNETADP pThis, VBOXNETADPSTATE enmNewState)
-{
-    Log(("vboxNetAdpSetState: pThis=%p, state change: %d -> %d.\n", pThis, vboxNetAdpGetState(pThis), enmNewState));
-    ASMAtomicWriteU32((uint32_t volatile *)&pThis->enmState, enmNewState);
-}
-
-
-/**
- * Sets the enmState member atomically after first acquiring the spinlock.
- *
- * Used for all updates.
- *
- * @param   pThis           The instance.
- * @param   enmNewState     The new value.
- */
-DECLINLINE(void) vboxNetAdpSetStateWithLock(PVBOXNETADP pThis, VBOXNETADPSTATE enmNewState)
-{
-    Log(("vboxNetAdpSetStateWithLock: pThis=%p, state=%d.\n", pThis, enmNewState));
-    RTSpinlockAcquire(pThis->hSpinlock);
-    vboxNetAdpSetState(pThis, enmNewState);
-    RTSpinlockReleaseNoInts(pThis->hSpinlock);
-}
-
-
-/**
- * Gets the enmState member with locking.
- *
- * Used for all reads.
- *
- * @returns The enmState value.
- * @param   pThis           The instance.
- */
-DECLINLINE(VBOXNETADPSTATE) vboxNetAdpGetStateWithLock(PVBOXNETADP pThis)
-{
-    VBOXNETADPSTATE enmState;
-    RTSpinlockAcquire(pThis->hSpinlock);
-    enmState = vboxNetAdpGetState(pThis);
-    RTSpinlockReleaseNoInts(pThis->hSpinlock);
-    Log(("vboxNetAdpGetStateWithLock: pThis=%p, state=%d.\n", pThis, enmState));
-    return enmState;
-}
-
-
-/**
- * Checks and sets the enmState member atomically.
- *
- * Used for all updates.
- *
- * @returns true if the state has been changed.
- * @param   pThis           The instance.
- * @param   enmNewState     The new value.
- */
-DECLINLINE(bool) vboxNetAdpCheckAndSetState(PVBOXNETADP pThis, VBOXNETADPSTATE enmOldState, VBOXNETADPSTATE enmNewState)
-{
-    VBOXNETADPSTATE enmActualState;
-    bool fRc = true; /* be optimistic */
-
-    RTSpinlockAcquire(pThis->hSpinlock);
-    enmActualState = vboxNetAdpGetState(pThis); /** @todo r=bird: ASMAtomicCmpXchgU32()*/
-    if (enmActualState == enmOldState)
-        vboxNetAdpSetState(pThis, enmNewState);
-    else
-        fRc = false;
-    RTSpinlockReleaseNoInts(pThis->hSpinlock);
-
-    if (fRc)
-        Log(("vboxNetAdpCheckAndSetState: pThis=%p, state changed: %d -> %d.\n", pThis, enmOldState, enmNewState));
-    else
-        Log(("vboxNetAdpCheckAndSetState: pThis=%p, no state change: %d != %d (expected).\n", pThis, enmActualState, enmOldState));
-    return fRc;
-}
-
-
-/**
- * Finds a instance by its name, the caller does the locking.
- *
- * @returns Pointer to the instance by the given name. NULL if not found.
- * @param   pGlobals        The globals.
- * @param   pszName         The name of the instance.
- */
-static PVBOXNETADP vboxNetAdpFind(PVBOXNETADPGLOBALS pGlobals, const char *pszName)
-{
-    unsigned i;
-
-    for (i = 0; i < RT_ELEMENTS(pGlobals->aAdapters); i++)
-    {
-        PVBOXNETADP pThis = &pGlobals->aAdapters[i];
-        RTSpinlockAcquire(pThis->hSpinlock);
-        if (    vboxNetAdpGetState(pThis)
-            &&  !strcmp(pThis->szName, pszName))
-        {
-            RTSpinlockReleaseNoInts(pThis->hSpinlock);
-            return pThis;
-        }
-        RTSpinlockReleaseNoInts(pThis->hSpinlock);
-    }
-    return NULL;
-}
-
-
-/**
- * Releases a reference to the specified instance.
- *
- * @param   pThis           The instance.
- * @param   fBusy           Whether the busy counter should be decremented too.
- */
-DECLHIDDEN(void) vboxNetAdpRelease(PVBOXNETADP pThis)
-{
-    uint32_t cRefs;
-
-    /*
-     * Paranoid Android.
-     */
-    AssertPtr(pThis);
-    Assert(pThis->MyPort.u32Version == INTNETTRUNKIFPORT_VERSION);
-    Assert(pThis->MyPort.u32VersionEnd == INTNETTRUNKIFPORT_VERSION);
-    Assert(vboxNetAdpGetState(pThis) > kVBoxNetAdpState_Invalid);
-    AssertPtr(pThis->pGlobals);
-    Assert(pThis->hEventIdle != NIL_RTSEMEVENT);
-    Assert(pThis->hSpinlock != NIL_RTSPINLOCK);
-    Assert(pThis->szName[0]);
-
-    /*
-     * The object reference counting.
-     */
-    cRefs = ASMAtomicDecU32(&pThis->cRefs);
-    Assert(cRefs < UINT32_MAX / 2);
-}
-
-
-/**
- * Decrements the busy counter and does idle wakeup.
- *
- * @param   pThis           The instance.
- */
-DECLHIDDEN(void) vboxNetAdpIdle(PVBOXNETADP pThis)
-{
-    uint32_t cBusy;
-
-    /*
-     * Paranoid Android.
-     */
-    AssertPtr(pThis);
-    Assert(pThis->MyPort.u32Version == INTNETTRUNKIFPORT_VERSION);
-    Assert(pThis->MyPort.u32VersionEnd == INTNETTRUNKIFPORT_VERSION);
-    Assert(vboxNetAdpGetState(pThis) >= kVBoxNetAdpState_Connected);
-    AssertPtr(pThis->pGlobals);
-    Assert(pThis->hEventIdle != NIL_RTSEMEVENT);
-
-    cBusy = ASMAtomicDecU32(&pThis->cBusy);
-    if (!cBusy)
-    {
-        int rc = RTSemEventSignal(pThis->hEventIdle);
-        AssertRC(rc);
-    }
-    else
-        Assert(cBusy < UINT32_MAX / 2);
-}
-
-
-/**
- * Retains a reference to the specified instance.
- *
- * @param   pThis           The instance.
- */
-DECLHIDDEN(void) vboxNetAdpRetain(PVBOXNETADP pThis)
-{
-    uint32_t cRefs;
-
-    /*
-     * Paranoid Android.
-     */
-    AssertPtr(pThis);
-    Assert(pThis->MyPort.u32Version == INTNETTRUNKIFPORT_VERSION);
-    Assert(pThis->MyPort.u32VersionEnd == INTNETTRUNKIFPORT_VERSION);
-    Assert(vboxNetAdpGetState(pThis) > kVBoxNetAdpState_Invalid);
-    AssertPtr(pThis->pGlobals);
-    Assert(pThis->hEventIdle != NIL_RTSEMEVENT);
-    Assert(pThis->hSpinlock != NIL_RTSPINLOCK);
-    Assert(pThis->szName[0]);
-
-    /*
-     * Retain the object.
-     */
-    cRefs = ASMAtomicIncU32(&pThis->cRefs);
-    Assert(cRefs > 1 && cRefs < UINT32_MAX / 2);
-
-    NOREF(cRefs);
-}
-
-
-/**
- * Increments busy counter.
- *
- * @param   pThis           The instance.
- */
-DECLHIDDEN(void) vboxNetAdpBusy(PVBOXNETADP pThis)
-{
-    uint32_t cBusy;
-
-    /*
-     * Are we vigilant enough?
-     */
-    AssertPtr(pThis);
-    Assert(pThis->MyPort.u32Version == INTNETTRUNKIFPORT_VERSION);
-    Assert(pThis->MyPort.u32VersionEnd == INTNETTRUNKIFPORT_VERSION);
-    Assert(vboxNetAdpGetState(pThis) >= kVBoxNetAdpState_Connected);
-    AssertPtr(pThis->pGlobals);
-    Assert(pThis->hEventIdle != NIL_RTSEMEVENT);
-    cBusy = ASMAtomicIncU32(&pThis->cBusy);
-    Assert(cBusy > 0 && cBusy < UINT32_MAX / 2);
-
-    NOREF(cBusy);
-}
-
-
-/**
- * Generate a suitable MAC address.
- *
- * @param   pThis       The instance.
- * @param   pMac        Where to return the MAC address.
- */
-DECLHIDDEN(void) vboxNetAdpComposeMACAddress(PVBOXNETADP pThis, PRTMAC pMac)
-{
-#if 0 /* Use a locally administered version of the OUI we use for the guest NICs. */
-    pMac->au8[0] = 0x08 | 2;
-    pMac->au8[1] = 0x00;
-    pMac->au8[2] = 0x27;
-#else /* this is what \0vb comes down to. It seems to be unassigned atm. */
-    pMac->au8[0] = 0;
-    pMac->au8[1] = 0x76;
-    pMac->au8[2] = 0x62;
-#endif
-
-    pMac->au8[3] = 0; /* pThis->uUnit >> 16; */
-    pMac->au8[4] = 0; /* pThis->uUnit >> 8; */
-    pMac->au8[5] = pThis->uUnit;
-}
-
-
-/**
- * Checks if receive is possible and increases busy and ref counters if so.
- *
- * @param   pThis           The instance.
- */
-DECLHIDDEN(bool) vboxNetAdpPrepareToReceive(PVBOXNETADP pThis)
-{
-    bool fCanReceive  = false;
-    /*
-     * Input validation.
-     */
-    AssertPtr(pThis);
-    Assert(pThis->MyPort.u32Version == INTNETTRUNKIFPORT_VERSION);
-    RTSpinlockAcquire(pThis->hSpinlock);
-    if (vboxNetAdpGetState(pThis) == kVBoxNetAdpState_Active)
-    {
-        fCanReceive = true;
-        vboxNetAdpRetain(pThis);
-        vboxNetAdpBusy(pThis);
-    }
-    RTSpinlockReleaseNoInts(pThis->hSpinlock);
-    Log(("vboxNetAdpPrepareToReceive: fCanReceive=%d.\n", fCanReceive));
-
-    return fCanReceive;
-}
-
-
-/**
- * Forwards scatter/gather list to internal network and decreases busy and ref counters.
- *
- * @param   pThis           The instance.
- */
-DECLHIDDEN(void) vboxNetAdpReceive(PVBOXNETADP pThis, PINTNETSG pSG)
-{
-    /*
-     * Input validation.
-     */
-    AssertPtr(pThis);
-    AssertPtr(pSG);
-    AssertPtr(pThis->pSwitchPort);
-    Assert(pThis->MyPort.u32Version == INTNETTRUNKIFPORT_VERSION);
-    Log(("vboxNetAdpReceive: forwarding packet to internal net...\n"));
-    pThis->pSwitchPort->pfnRecv(pThis->pSwitchPort, pSG, INTNETTRUNKDIR_HOST);
-    vboxNetAdpIdle(pThis);
-    vboxNetAdpRelease(pThis);
-}
-
-
-/**
- * Decreases busy and ref counters.
- *
- * @param   pThis           The instance.
- */
-DECLHIDDEN(void) vboxNetAdpCancelReceive(PVBOXNETADP pThis)
-{
-    Log(("vboxNetAdpCancelReceive: cancelled.\n"));
-    vboxNetAdpIdle(pThis);
-    vboxNetAdpRelease(pThis);
-}
-
-
-/**
- * @copydoc INTNETTRUNKIFPORT::pfnXmit
- */
-static DECLCALLBACK(int) vboxNetAdpPortXmit(PINTNETTRUNKIFPORT pIfPort, PINTNETSG pSG, uint32_t fDst)
-{
-    PVBOXNETADP pThis = IFPORT_2_VBOXNETADP(pIfPort);
-    int rc = VINF_SUCCESS;
-
-    /*
-     * Input validation.
-     */
-    AssertPtr(pThis);
-    AssertPtr(pSG);
-    Assert(pThis->MyPort.u32Version == INTNETTRUNKIFPORT_VERSION);
-
-    Log(("vboxNetAdpPortXmit: outgoing packet (len=%d)\n", pSG->cbTotal));
-
-    /*
-     * Do a retain/busy, invoke the OS specific code.
-     */
-    RTSpinlockAcquire(pThis->hSpinlock);
-    if (vboxNetAdpGetState(pThis) != kVBoxNetAdpState_Active)
-    {
-        RTSpinlockReleaseNoInts(pThis->hSpinlock);
-        Log(("vboxNetAdpReceive: Dropping incoming packet for inactive interface %s.\n",
-             pThis->szName));
-        return VERR_INVALID_STATE;
-    }
-    vboxNetAdpRetain(pThis);
-    vboxNetAdpBusy(pThis);
-    RTSpinlockReleaseNoInts(pThis->hSpinlock);
-
-    rc = vboxNetAdpPortOsXmit(pThis, pSG, fDst);
-    vboxNetAdpIdle(pThis);
-    vboxNetAdpRelease(pThis);
-
-    return rc;
-}
-
-
-/**
- * @copydoc INTNETTRUNKIFPORT::pfnGetMacAddress
- */
-static DECLCALLBACK(void) vboxNetAdpPortGetMacAddress(PINTNETTRUNKIFPORT pIfPort, PRTMAC pMac)
-{
-    PVBOXNETADP pThis = IFPORT_2_VBOXNETADP(pIfPort);
-
-    /*
-     * Input validation.
-     */
-    AssertPtr(pThis);
-    Assert(pThis->MyPort.u32Version == INTNETTRUNKIFPORT_VERSION);
-    Assert(vboxNetAdpGetStateWithLock(pThis) == kVBoxNetAdpState_Active);
-
-    /*
-     * Forward the question to the OS specific code.
-     */
-    vboxNetAdpPortOsGetMacAddress(pThis, pMac);
-}
-
-
-/**
- * @copydoc INTNETTRUNKIFPORT::pfnWaitForIdle
- */
-static DECLCALLBACK(int) vboxNetAdpPortWaitForIdle(PINTNETTRUNKIFPORT pIfPort, uint32_t cMillies)
-{
-    int rc;
-    PVBOXNETADP pThis = IFPORT_2_VBOXNETADP(pIfPort);
-
-    /*
-     * Input validation.
-     */
-    AssertPtr(pThis);
-    Assert(pThis->MyPort.u32Version == INTNETTRUNKIFPORT_VERSION);
-    AssertReturn(vboxNetAdpGetStateWithLock(pThis) >= kVBoxNetAdpState_Connected, VERR_INVALID_STATE);
-
-    /*
-     * Go to sleep on the semaphore after checking the busy count.
-     */
-    vboxNetAdpRetain(pThis);
-
-    rc = VINF_SUCCESS;
-    while (pThis->cBusy && RT_SUCCESS(rc))
-        rc = RTSemEventWait(pThis->hEventIdle, cMillies); /** @todo make interruptible? */
-
-    vboxNetAdpRelease(pThis);
-
-    return rc;
-}
-
-
-/**
- * @copydoc INTNETTRUNKIFPORT::pfnSetActive
- */
-static DECLCALLBACK(bool) vboxNetAdpPortSetActive(PINTNETTRUNKIFPORT pIfPort, bool fActive)
-{
-    bool fPreviouslyActive;
-    PVBOXNETADP pThis = IFPORT_2_VBOXNETADP(pIfPort);
-
-    /*
-     * Input validation.
-     */
-    AssertPtr(pThis);
-    AssertPtr(pThis->pGlobals);
-    Assert(pThis->MyPort.u32Version == INTNETTRUNKIFPORT_VERSION);
-
-    Log(("vboxNetAdpPortSetActive: pThis=%p, fActive=%d, state before: %d.\n", pThis, fActive, vboxNetAdpGetState(pThis)));
-    RTSpinlockAcquire(pThis->hSpinlock);
-
-    fPreviouslyActive = vboxNetAdpGetState(pThis) == kVBoxNetAdpState_Active;
-    if (fPreviouslyActive != fActive)
-    {
-        switch (vboxNetAdpGetState(pThis))
-        {
-            case kVBoxNetAdpState_Connected:
-                vboxNetAdpSetState(pThis, kVBoxNetAdpState_Active);
-                break;
-            case kVBoxNetAdpState_Active:
-                vboxNetAdpSetState(pThis, kVBoxNetAdpState_Connected);
-                break;
-            default:
-                break;
-        }
-    }
-
-    RTSpinlockReleaseNoInts(pThis->hSpinlock);
-    Log(("vboxNetAdpPortSetActive: state after: %RTbool.\n", vboxNetAdpGetState(pThis)));
-    return fPreviouslyActive;
-}
-
-
-/**
- * @copydoc INTNETTRUNKIFPORT::pfnDisconnectAndRelease
- */
-static DECLCALLBACK(void) vboxNetAdpPortDisconnectAndRelease(PINTNETTRUNKIFPORT pIfPort)
-{
-    PVBOXNETADP pThis = IFPORT_2_VBOXNETADP(pIfPort);
-
-    /*
-     * Serious paranoia.
-     */
-    AssertPtr(pThis);
-    Assert(pThis->MyPort.u32Version == INTNETTRUNKIFPORT_VERSION);
-    Assert(pThis->MyPort.u32VersionEnd == INTNETTRUNKIFPORT_VERSION);
-    AssertPtr(pThis->pGlobals);
-    Assert(pThis->hEventIdle != NIL_RTSEMEVENT);
-    Assert(pThis->hSpinlock != NIL_RTSPINLOCK);
-
-
-    /*
-     * Disconnect and release it.
-     */
-    RTSpinlockAcquire(pThis->hSpinlock);
-    //Assert(vboxNetAdpGetState(pThis) == kVBoxNetAdpState_Connected);
-    Assert(!pThis->cBusy);
-    vboxNetAdpSetState(pThis, kVBoxNetAdpState_Transitional);
-    RTSpinlockReleaseNoInts(pThis->hSpinlock);
-
-    vboxNetAdpOsDisconnectIt(pThis);
-    pThis->pSwitchPort = NULL;
-
-    RTSpinlockAcquire(pThis->hSpinlock);
-    vboxNetAdpSetState(pThis, kVBoxNetAdpState_Available);
-    RTSpinlockReleaseNoInts(pThis->hSpinlock);
-
-    vboxNetAdpRelease(pThis);
-}
-
-
-/**
- * @copydoc INTNETTRUNKIFPORT::pfnRelease
- */
-static DECLCALLBACK(void) vboxNetAdpPortRelease(PINTNETTRUNKIFPORT pIfPort)
-{
-    PVBOXNETADP pThis = IFPORT_2_VBOXNETADP(pIfPort);
-    vboxNetAdpRelease(pThis);
-}
-
-
-/**
- * @copydoc INTNETTRUNKIFPORT::pfnRetain
- */
-static DECLCALLBACK(void) vboxNetAdpPortRetain(PINTNETTRUNKIFPORT pIfPort)
-{
-    PVBOXNETADP pThis = IFPORT_2_VBOXNETADP(pIfPort);
-    vboxNetAdpRetain(pThis);
-}
-
-
-int vboxNetAdpCreate(PINTNETTRUNKFACTORY pIfFactory, PVBOXNETADP *ppNew)
-{
-    PVBOXNETADPGLOBALS pGlobals = (PVBOXNETADPGLOBALS)((uint8_t *)pIfFactory - RT_OFFSETOF(VBOXNETADPGLOBALS, TrunkFactory));
-    unsigned i;
-    int rc;
-
-    for (i = 0; i < RT_ELEMENTS(pGlobals->aAdapters); i++)
-    {
-        PVBOXNETADP pThis = &pGlobals->aAdapters[i];
-
-        if (vboxNetAdpCheckAndSetState(pThis, kVBoxNetAdpState_Invalid, kVBoxNetAdpState_Transitional))
-        {
-            /* Found an empty slot -- use it. */
-            uint32_t cRefs = ASMAtomicIncU32(&pThis->cRefs);
-            Assert(cRefs == 1);
-            RTMAC Mac;
-            vboxNetAdpComposeMACAddress(pThis, &Mac);
-            rc = vboxNetAdpOsCreate(pThis, &Mac);
-            *ppNew = pThis;
-
-            RTSpinlockAcquire(pThis->hSpinlock);
-            vboxNetAdpSetState(pThis, kVBoxNetAdpState_Available);
-            RTSpinlockReleaseNoInts(pThis->hSpinlock);
-            return rc;
-        }
-    }
-
-    /* All slots in adapter array are busy. */
-    return VERR_OUT_OF_RESOURCES;
-}
-
-int vboxNetAdpDestroy(PVBOXNETADP pThis)
-{
-    int rc = VINF_SUCCESS;
-
-    RTSpinlockAcquire(pThis->hSpinlock);
-    if (vboxNetAdpGetState(pThis) != kVBoxNetAdpState_Available || pThis->cBusy)
-    {
-        RTSpinlockReleaseNoInts(pThis->hSpinlock);
-        return VERR_INTNET_FLT_IF_BUSY;
-    }
-    vboxNetAdpSetState(pThis, kVBoxNetAdpState_Transitional);
-    RTSpinlockReleaseNoInts(pThis->hSpinlock);
-    vboxNetAdpRelease(pThis);
-
-    vboxNetAdpOsDestroy(pThis);
-
-    RTSpinlockAcquire(pThis->hSpinlock);
-    vboxNetAdpSetState(pThis, kVBoxNetAdpState_Invalid);
-    RTSpinlockReleaseNoInts(pThis->hSpinlock);
-
-    return rc;
-}
-
-/**
- * Connects the instance to the specified switch port.
- *
- * Called while owning the lock. We're ASSUMING that the internal
- * networking code is already owning an recursive mutex, so, there
- * will be no deadlocks when vboxNetAdpOsConnectIt calls back into
- * it for setting preferences.
- *
- * @returns VBox status code.
- * @param   pThis               The instance.
- * @param   pSwitchPort         The port on the internal network 'switch'.
- * @param   ppIfPort            Where to return our port interface.
- */
-static int vboxNetAdpConnectIt(PVBOXNETADP pThis, PINTNETTRUNKSWPORT pSwitchPort, PINTNETTRUNKIFPORT *ppIfPort)
-{
-    int rc;
-
-    /*
-     * Validate state.
-     */
-    Assert(!pThis->cBusy);
-    Assert(vboxNetAdpGetStateWithLock(pThis) == kVBoxNetAdpState_Transitional);
-
-    /*
-     * Do the job.
-     * Note that we're calling the os stuff while owning the semaphore here.
-     */
-    pThis->pSwitchPort = pSwitchPort;
-    rc = vboxNetAdpOsConnectIt(pThis);
-    if (RT_SUCCESS(rc))
-    {
-        *ppIfPort = &pThis->MyPort;
-    }
-    else
-        pThis->pSwitchPort = NULL;
-
-    return rc;
-}
-
-
-/**
- * @copydoc INTNETTRUNKFACTORY::pfnCreateAndConnect
- */
-static DECLCALLBACK(int) vboxNetAdpFactoryCreateAndConnect(PINTNETTRUNKFACTORY pIfFactory, const char *pszName,
-                                                           PINTNETTRUNKSWPORT pSwitchPort, uint32_t fFlags,
-                                                           PINTNETTRUNKIFPORT *ppIfPort)
-{
-    PVBOXNETADPGLOBALS pGlobals = (PVBOXNETADPGLOBALS)((uint8_t *)pIfFactory - RT_OFFSETOF(VBOXNETADPGLOBALS, TrunkFactory));
-    PVBOXNETADP pThis;
-    int rc;
-
-    LogFlow(("vboxNetAdpFactoryCreateAndConnect: pszName=%p:{%s} fFlags=%#x\n", pszName, pszName, fFlags));
-    Assert(pGlobals->cFactoryRefs > 0);
-    AssertMsgReturn(!fFlags,
-                    ("%#x\n", fFlags), VERR_INVALID_PARAMETER);
-
-    /*
-     * Find instance, check if busy, connect if not.
-     */
-    pThis = vboxNetAdpFind(pGlobals, pszName);
-    if (pThis)
-    {
-        if (vboxNetAdpCheckAndSetState(pThis, kVBoxNetAdpState_Available, kVBoxNetAdpState_Transitional))
-        {
-            vboxNetAdpRetain(pThis);
-            rc = vboxNetAdpConnectIt(pThis, pSwitchPort, ppIfPort);
-            vboxNetAdpSetStateWithLock(pThis, RT_SUCCESS(rc) ? kVBoxNetAdpState_Connected : kVBoxNetAdpState_Available);
-        }
-        else
-            rc = VERR_INTNET_FLT_IF_BUSY;
-    }
-    else
-        rc = VERR_INTNET_FLT_IF_NOT_FOUND;
-
-    return rc;
-}
-
-
-/**
- * @copydoc INTNETTRUNKFACTORY::pfnRelease
- */
-static DECLCALLBACK(void) vboxNetAdpFactoryRelease(PINTNETTRUNKFACTORY pIfFactory)
-{
-    PVBOXNETADPGLOBALS pGlobals = (PVBOXNETADPGLOBALS)((uint8_t *)pIfFactory - RT_OFFSETOF(VBOXNETADPGLOBALS, TrunkFactory));
-
-    int32_t cRefs = ASMAtomicDecS32(&pGlobals->cFactoryRefs);
-    Assert(cRefs >= 0); NOREF(cRefs);
-    LogFlow(("vboxNetAdpFactoryRelease: cRefs=%d (new)\n", cRefs));
-}
-
-
-/**
- * Implements the SUPDRV component factor interface query method.
- *
- * @returns Pointer to an interface. NULL if not supported.
- *
- * @param   pSupDrvFactory      Pointer to the component factory registration structure.
- * @param   pSession            The session - unused.
- * @param   pszInterfaceUuid    The factory interface id.
- */
-static DECLCALLBACK(void *) vboxNetAdpQueryFactoryInterface(PCSUPDRVFACTORY pSupDrvFactory, PSUPDRVSESSION pSession, const char *pszInterfaceUuid)
-{
-    PVBOXNETADPGLOBALS pGlobals = (PVBOXNETADPGLOBALS)((uint8_t *)pSupDrvFactory - RT_OFFSETOF(VBOXNETADPGLOBALS, SupDrvFactory));
-
-    /*
-     * Convert the UUID strings and compare them.
-     */
-    RTUUID UuidReq;
-    int rc = RTUuidFromStr(&UuidReq, pszInterfaceUuid);
-    if (RT_SUCCESS(rc))
-    {
-        if (!RTUuidCompareStr(&UuidReq, INTNETTRUNKFACTORY_UUID_STR))
-        {
-            ASMAtomicIncS32(&pGlobals->cFactoryRefs);
-            return &pGlobals->TrunkFactory;
-        }
-#ifdef LOG_ENABLED
-        else
-            Log(("VBoxNetAdp: unknown factory interface query (%s)\n", pszInterfaceUuid));
-#endif
-    }
-    else
-        Log(("VBoxNetAdp: rc=%Rrc, uuid=%s\n", rc, pszInterfaceUuid));
-
-    return NULL;
-}
-
-
-/**
- * Checks whether the VBoxNetAdp wossname can be unloaded.
- *
- * This will return false if someone is currently using the module.
- *
- * @returns true if it's relatively safe to unload it, otherwise false.
- * @param   pGlobals        Pointer to the globals.
- */
-DECLHIDDEN(bool) vboxNetAdpCanUnload(PVBOXNETADPGLOBALS pGlobals)
-{
-    bool fRc = true; /* Assume it can be unloaded. */
-    unsigned i;
-
-    for (i = 0; i < RT_ELEMENTS(pGlobals->aAdapters); i++)
-    {
-        PVBOXNETADP pThis = &pGlobals->aAdapters[i];
-        if (vboxNetAdpGetStateWithLock(&pGlobals->aAdapters[i]) >= kVBoxNetAdpState_Connected)
-        {
-            fRc = false;
-            break; /* We already know the answer. */
-        }
-    }
-    return fRc && ASMAtomicUoReadS32((int32_t volatile *)&pGlobals->cFactoryRefs) <= 0;
-}
-
-/**
- * tries to deinitialize Idc
- * we separate the globals settings "base" which is actually
- * "general" globals settings except for Idc, and idc.
- * This is needed for windows filter driver, which gets loaded prior to VBoxDrv,
- * thus it's not possible to make idc initialization from the driver startup routine for it,
- * though the "base is still needed for the driver to functions".
- * @param pGlobals
- * @return VINF_SUCCESS on success, VERR_WRONG_ORDER if we're busy.
- */
-DECLHIDDEN(int) vboxNetAdpTryDeleteIdc(PVBOXNETADPGLOBALS pGlobals)
-{
-    int rc;
-
-    Assert(pGlobals->hFastMtx != NIL_RTSEMFASTMUTEX);
-
-    /*
-     * Check before trying to deregister the factory.
-     */
-    if (!vboxNetAdpCanUnload(pGlobals))
-        return VERR_WRONG_ORDER;
-
-    /*
-     * Disconnect from SUPDRV and check that nobody raced us,
-     * reconnect if that should happen.
-     */
-    rc = SUPR0IdcComponentDeregisterFactory(&pGlobals->SupDrvIDC, &pGlobals->SupDrvFactory);
-    AssertRC(rc);
-    if (!vboxNetAdpCanUnload(pGlobals))
-    {
-        rc = SUPR0IdcComponentRegisterFactory(&pGlobals->SupDrvIDC, &pGlobals->SupDrvFactory);
-        AssertRC(rc);
-        return VERR_WRONG_ORDER;
-    }
-
-    SUPR0IdcClose(&pGlobals->SupDrvIDC);
-
-    return rc;
-}
-
-static int vboxNetAdpSlotCreate(PVBOXNETADPGLOBALS pGlobals, unsigned uUnit, PVBOXNETADP pNew)
-{
-    int rc;
-
-    pNew->MyPort.u32Version             = INTNETTRUNKIFPORT_VERSION;
-    pNew->MyPort.pfnRetain              = vboxNetAdpPortRetain;
-    pNew->MyPort.pfnRelease             = vboxNetAdpPortRelease;
-    pNew->MyPort.pfnDisconnectAndRelease= vboxNetAdpPortDisconnectAndRelease;
-    pNew->MyPort.pfnSetState            = vboxNetAdpPortSetState;
-    pNew->MyPort.pfnWaitForIdle         = vboxNetAdpPortWaitForIdle;
-    pNew->MyPort.pfnXmit                = vboxNetAdpPortXmit;
-    pNew->MyPort.u32VersionEnd          = INTNETTRUNKIFPORT_VERSION;
-    pNew->pSwitchPort                   = NULL;
-    pNew->pGlobals                      = pGlobals;
-    pNew->hSpinlock                     = NIL_RTSPINLOCK;
-    pNew->enmState                      = kVBoxNetAdpState_Invalid;
-    pNew->cRefs                         = 0;
-    pNew->cBusy                         = 0;
-    pNew->hEventIdle                    = NIL_RTSEMEVENT;
-
-    rc = RTSpinlockCreate(&pNew->hSpinlock, RTSPINLOCK_FLAGS_INTERRUPT_SAFE, "VBoxNetAdptSlotCreate");
-    if (RT_SUCCESS(rc))
-    {
-        rc = RTSemEventCreate(&pNew->hEventIdle);
-        if (RT_SUCCESS(rc))
-        {
-            rc = vboxNetAdpOsInit(pNew);
-            if (RT_SUCCESS(rc))
-            {
-                return rc;
-            }
-            RTSemEventDestroy(pNew->hEventIdle);
-            pNew->hEventIdle = NIL_RTSEMEVENT;
-        }
-        RTSpinlockDestroy(pNew->hSpinlock);
-        pNew->hSpinlock = NIL_RTSPINLOCK;
-    }
-    return rc;
-}
-
-static void vboxNetAdpSlotDestroy(PVBOXNETADP pThis)
-{
-    Assert(pThis->cRefs == 0);
-    Assert(pThis->cBusy == 0);
-    Assert(vboxNetAdpGetState(pThis) == kVBoxNetAdpState_Invalid);
-    if (pThis->hEventIdle != NIL_RTSEMEVENT)
-    {
-        RTSemEventDestroy(pThis->hEventIdle);
-        pThis->hEventIdle = NIL_RTSEMEVENT;
-    }
-    if (pThis->hSpinlock != NIL_RTSPINLOCK)
-    {
-        RTSpinlockDestroy(pThis->hSpinlock);
-        pThis->hSpinlock = NIL_RTSPINLOCK;
-    }
-}
-
-/**
- * performs "base" globals deinitialization
- * we separate the globals settings "base" which is actually
- * "general" globals settings except for Idc, and idc.
- * This is needed for windows filter driver, which gets loaded prior to VBoxDrv,
- * thus it's not possible to make idc initialization from the driver startup routine for it,
- * though the "base is still needed for the driver to functions".
- * @param pGlobals
- * @return none
- */
-DECLHIDDEN(void) vboxNetAdpDeleteGlobalsBase(PVBOXNETADPGLOBALS pGlobals)
-{
-    int i;
-    /*
-     * Release resources.
-     */
-    for (i = 0; i < (int)RT_ELEMENTS(pGlobals->aAdapters); i++)
-        if (RT_SUCCESS(vboxNetAdpDestroy(&pGlobals->aAdapters[i])))
-            vboxNetAdpSlotDestroy(&pGlobals->aAdapters[i]);
-
-    RTSemFastMutexDestroy(pGlobals->hFastMtx);
-    pGlobals->hFastMtx = NIL_RTSEMFASTMUTEX;
-
-#ifdef VBOXNETADP_STATIC_CONFIG
-    RTSemEventDestroy(pGlobals->hTimerEvent);
-    pGlobals->hTimerEvent = NIL_RTSEMEVENT;
-#endif
-
-}
-
-
-/**
- * Called by the native part when the OS wants the driver to unload.
- *
- * @returns VINF_SUCCESS on success, VERR_WRONG_ORDER if we're busy.
- *
- * @param   pGlobals        Pointer to the globals.
- */
-DECLHIDDEN(int) vboxNetAdpTryDeleteGlobals(PVBOXNETADPGLOBALS pGlobals)
-{
-    int rc = vboxNetAdpTryDeleteIdc(pGlobals);
-    if (RT_SUCCESS(rc))
-    {
-        vboxNetAdpDeleteGlobalsBase(pGlobals);
-    }
-    return rc;
-}
-
-
-/**
- * performs the "base" globals initialization
- * we separate the globals initialization to globals "base" initialization which is actually
- * "general" globals initialization except for Idc not being initialized, and idc initialization.
- * This is needed for windows filter driver, which gets loaded prior to VBoxDrv,
- * thus it's not possible to make idc initialization from the driver startup routine for it.
- *
- * @returns VBox status code.
- * @param   pGlobals    Pointer to the globals. */
-DECLHIDDEN(int) vboxNetAdpInitGlobalsBase(PVBOXNETADPGLOBALS pGlobals)
-{
-    /*
-     * Initialize the common portions of the structure.
-     */
-    int i;
-    int rc = RTSemFastMutexCreate(&pGlobals->hFastMtx);
-    if (RT_SUCCESS(rc))
-    {
-        memset(pGlobals->aAdapters, 0, sizeof(pGlobals->aAdapters));
-        for (i = 0; i < (int)RT_ELEMENTS(pGlobals->aAdapters); i++)
-        {
-            rc = vboxNetAdpSlotCreate(pGlobals, i, &pGlobals->aAdapters[i]);
-            if (RT_FAILURE(rc))
-            {
-                /* Clean up. */
-                while (--i >= 0)
-                    vboxNetAdpSlotDestroy(&pGlobals->aAdapters[i]);
-                Log(("vboxNetAdpInitGlobalsBase: Failed to create fast mutex (rc=%Rrc).\n", rc));
-                RTSemFastMutexDestroy(pGlobals->hFastMtx);
-                return rc;
-            }
-        }
-        pGlobals->TrunkFactory.pfnRelease = vboxNetAdpFactoryRelease;
-        pGlobals->TrunkFactory.pfnCreateAndConnect = vboxNetAdpFactoryCreateAndConnect;
-
-        strcpy(pGlobals->SupDrvFactory.szName, "VBoxNetAdp");
-        pGlobals->SupDrvFactory.pfnQueryFactoryInterface = vboxNetAdpQueryFactoryInterface;
-    }
-
-    return rc;
-}
-
-/**
- * performs the Idc initialization
- * we separate the globals initialization to globals "base" initialization which is actually
- * "general" globals initialization except for Idc not being initialized, and idc initialization.
- * This is needed for windows filter driver, which gets loaded prior to VBoxDrv,
- * thus it's not possible to make idc initialization from the driver startup routine for it.
- *
- * @returns VBox status code.
- * @param   pGlobals    Pointer to the globals. */
-DECLHIDDEN(int) vboxNetAdpInitIdc(PVBOXNETADPGLOBALS pGlobals)
-{
-    int rc;
-    /*
-     * Establish a connection to SUPDRV and register our component factory.
-     */
-    rc = SUPR0IdcOpen(&pGlobals->SupDrvIDC, 0 /* iReqVersion = default */, 0 /* iMinVersion = default */, NULL, NULL, NULL);
-    if (RT_SUCCESS(rc))
-    {
-        rc = SUPR0IdcComponentRegisterFactory(&pGlobals->SupDrvIDC, &pGlobals->SupDrvFactory);
-        if (RT_SUCCESS(rc))
-        {
-#if 1 /** @todo REMOVE ME! */
-            PVBOXNETADP pTmp;
-            rc = vboxNetAdpCreate(&pGlobals->TrunkFactory, &pTmp);
-            if (RT_FAILURE(rc))
-                Log(("Failed to create vboxnet0, rc=%Rrc.\n", rc));
-#endif
-            Log(("VBoxNetAdp: pSession=%p\n", SUPR0IdcGetSession(&pGlobals->SupDrvIDC)));
-            return rc;
-        }
-
-        /* bail out. */
-        LogRel(("VBoxNetAdp: Failed to register component factory, rc=%Rrc\n", rc));
-        SUPR0IdcClose(&pGlobals->SupDrvIDC);
-    }
-
-    return rc;
-}
-
-/**
- * Called by the native driver/kext module initialization routine.
- *
- * It will initialize the common parts of the globals, assuming the caller
- * has already taken care of the OS specific bits.
- *
- * @returns VBox status code.
- * @param   pGlobals    Pointer to the globals.
- */
-DECLHIDDEN(int) vboxNetAdpInitGlobals(PVBOXNETADPGLOBALS pGlobals)
-{
-    /*
-     * Initialize the common portions of the structure.
-     */
-    int rc = vboxNetAdpInitGlobalsBase(pGlobals);
-    if (RT_SUCCESS(rc))
-    {
-        rc = vboxNetAdpInitIdc(pGlobals);
-        if (RT_SUCCESS(rc))
-        {
-            return rc;
-        }
-
-        /* bail out. */
-        vboxNetAdpDeleteGlobalsBase(pGlobals);
-    }
-
-    return rc;
-}
-
-#else /* !VBOXANETADP_DO_NOT_USE_NETFLT */
-
 
 VBOXNETADP g_aAdapters[VBOXNETADP_MAX_INSTANCES];
 static uint8_t g_aUnits[VBOXNETADP_MAX_UNITS/8];
@@ -1226,4 +217,3 @@ void vboxNetAdpShutdown(void)
     for (i = 0; i < RT_ELEMENTS(g_aAdapters); i++)
         vboxNetAdpDestroy(&g_aAdapters[i]);
 }
-#endif /* !VBOXANETADP_DO_NOT_USE_NETFLT */
diff --git a/src/VBox/Installer/linux/rpm/VirtualBox.tmpl.spec b/src/VBox/Installer/linux/rpm/VirtualBox.tmpl.spec
index da0f3e2..ba12829 100644
--- a/src/VBox/Installer/linux/rpm/VirtualBox.tmpl.spec
+++ b/src/VBox/Installer/linux/rpm/VirtualBox.tmpl.spec
@@ -28,7 +28,7 @@ License:   GPLv2
 Group:     Applications/System
 Vendor:    Oracle Corporation
 BuildRoot: %BUILDROOT%
-Requires:  %INITSCRIPTS% %LIBASOUND%
+Requires:  %INITSCRIPTS% %LIBASOUND% net-tools
 
 %if %{?rpm_suse:1}%{!?rpm_suse:0}
 %debug_package
diff --git a/src/VBox/Main/src-server/MachineImpl.cpp b/src/VBox/Main/src-server/MachineImpl.cpp
index 73a984f..18ce8dc 100644
--- a/src/VBox/Main/src-server/MachineImpl.cpp
+++ b/src/VBox/Main/src-server/MachineImpl.cpp
@@ -10754,9 +10754,8 @@ HRESULT Machine::saveHardware(settings::Hardware &data, settings::Debugging *pDb
         if (FAILED(rc)) throw rc;
 
         /* USB Controller (required) */
-        for (USBControllerList::const_iterator it = mUSBControllers->begin();
-             it != mUSBControllers->end();
-             ++it)
+        data.usbSettings.llUSBControllers.clear();
+        for (USBControllerList::const_iterator it = mUSBControllers->begin(); it != mUSBControllers->end(); ++it)
         {
             ComObjPtr<USBController> ctrl = *it;
             settings::USBController settingsCtrl;
@@ -10859,6 +10858,7 @@ HRESULT Machine::saveHardware(settings::Hardware &data, settings::Debugging *pDb
         if (FAILED(rc)) throw rc;
 
         /* Host PCI devices */
+        data.pciAttachments.clear();
         for (HWData::PCIDeviceAssignmentList::const_iterator it = mHWData->mPCIDeviceAssignments.begin();
              it != mHWData->mPCIDeviceAssignments.end();
              ++it)
diff --git a/src/VBox/NetworkServices/NAT/pxtcp.c b/src/VBox/NetworkServices/NAT/pxtcp.c
index 6486eaa..1b83e2c 100644
--- a/src/VBox/NetworkServices/NAT/pxtcp.c
+++ b/src/VBox/NetworkServices/NAT/pxtcp.c
@@ -1271,7 +1271,7 @@ pxtcp_pcb_connect(struct pxtcp *pxtcp, const struct fwspec *fwspec)
         goto reset;
     }
 
-    /* nit: comapres PF and AF, but they are the same everywhere */
+    /* nit: compares PF and AF, but they are the same everywhere */
     LWIP_ASSERT1(ss.ss_family == fwspec->sdom);
 
     status = fwany_ipX_addr_set_src(&src_addr, (const struct sockaddr *)&ss);
@@ -2290,12 +2290,20 @@ pxtcp_pcb_sent(void *arg, struct tcp_pcb *pcb, u16_t len)
                 DPRINTF0(("%s: sock %d: %R[sockerr]\n",
                           __func__, pxtcp->sock, sockerr));
 
+#if HAVE_TCP_POLLHUP == POLLIN /* see counterpart in pxtcp_pmgr_pump() */
                 /*
-                 * Since we are pulling, pxtcp is no longer registered
-                 * with poll manager so we can kill it directly.
+                 * It may still be registered with poll manager for POLLOUT.
+                 */
+                pxtcp_chan_send_weak(POLLMGR_CHAN_PXTCP_RESET, pxtcp);
+                return ERR_OK;
+#else
+                /*
+                 * It is no longer registered with poll manager so we
+                 * can kill it directly.
                  */
                 pxtcp_pcb_reset_pxtcp(pxtcp);
                 return ERR_ABRT;
+#endif
             }
         }
     }
diff --git a/src/VBox/Runtime/generic/http-curl.cpp b/src/VBox/Runtime/generic/http-curl.cpp
index 8fd23d9..770c0f7 100644
--- a/src/VBox/Runtime/generic/http-curl.cpp
+++ b/src/VBox/Runtime/generic/http-curl.cpp
@@ -712,7 +712,9 @@ static int rtHttpConfigureProxyForUrlFromEnv(PRTHTTPINTERNAL pThis, const char *
         rc = RTEnvGetEx(RTENV_DEFAULT, pszNoProxyVar, pszNoProxy, cchActual + _1K, NULL);
     }
     AssertMsg(rc == VINF_SUCCESS || rc == VERR_ENV_VAR_NOT_FOUND, ("rc=%Rrc\n", rc));
-    bool fNoProxy = rtHttpUrlInNoProxyList(pszUrl, RTStrStrip(pszNoProxy));
+    bool fNoProxy = false;
+    if (RT_SUCCESS(rc))
+        fNoProxy = rtHttpUrlInNoProxyList(pszUrl, RTStrStrip(pszNoProxy));
     RTMemTmpFree(pszNoProxyFree);
     if (!fNoProxy)
     {
diff --git a/src/VBox/Runtime/r0drv/darwin/dbgkrnlinfo-r0drv-darwin.cpp b/src/VBox/Runtime/r0drv/darwin/dbgkrnlinfo-r0drv-darwin.cpp
index 5e7105f..c961202 100644
--- a/src/VBox/Runtime/r0drv/darwin/dbgkrnlinfo-r0drv-darwin.cpp
+++ b/src/VBox/Runtime/r0drv/darwin/dbgkrnlinfo-r0drv-darwin.cpp
@@ -44,6 +44,8 @@ RT_C_DECLS_END
 # include <sys/systm.h>
 # include <vfs/vfs_support.h>
 /*# include <miscfs/specfs/specdev.h>*/
+#else
+# include <stdio.h> /* for printf */
 #endif
 
 #include "internal/iprt.h"
@@ -1031,20 +1033,14 @@ static void rtR0DbgKrnlDarwinDtor(RTDBGKRNLINFOINT *pThis)
 }
 
 
-RTR0DECL(int) RTR0DbgKrnlInfoOpen(PRTDBGKRNLINFO phKrnlInfo, uint32_t fFlags)
+static int rtR0DbgKrnlDarwinOpen(PRTDBGKRNLINFO phKrnlInfo, const char *pszKernelFile)
 {
-    AssertPtrReturn(phKrnlInfo, VERR_INVALID_POINTER);
-    *phKrnlInfo = NIL_RTDBGKRNLINFO;
-    AssertReturn(!fFlags, VERR_INVALID_PARAMETER);
-
     RTDBGKRNLINFOINT *pThis = (RTDBGKRNLINFOINT *)RTMemAllocZ(sizeof(*pThis));
     if (!pThis)
         return VERR_NO_MEMORY;
     pThis->hFile = NIL_RTFILE;
 
-    int rc = RTFileOpen(&pThis->hFile, "/mach_kernel", RTFILE_O_READ | RTFILE_O_OPEN | RTFILE_O_DENY_WRITE);
-    if (rc == VERR_FILE_NOT_FOUND)
-        rc = RTFileOpen(&pThis->hFile, "/System/Library/Kernels/kernel", RTFILE_O_READ | RTFILE_O_OPEN | RTFILE_O_DENY_WRITE);
+    int rc = RTFileOpen(&pThis->hFile, pszKernelFile, RTFILE_O_READ | RTFILE_O_OPEN | RTFILE_O_DENY_WRITE);
     if (RT_SUCCESS(rc))
         rc = rtR0DbgKrnlDarwinLoadFileHeaders(pThis);
     if (RT_SUCCESS(rc))
@@ -1077,6 +1073,66 @@ RTR0DECL(int) RTR0DbgKrnlInfoOpen(PRTDBGKRNLINFO phKrnlInfo, uint32_t fFlags)
 }
 
 
+RTR0DECL(int) RTR0DbgKrnlInfoOpen(PRTDBGKRNLINFO phKrnlInfo, uint32_t fFlags)
+{
+    AssertPtrReturn(phKrnlInfo, VERR_INVALID_POINTER);
+    *phKrnlInfo = NIL_RTDBGKRNLINFO;
+    AssertReturn(!fFlags, VERR_INVALID_PARAMETER);
+
+    /*
+     * Go thru likely kernel locations
+     *
+     * Note! Check the OS X version and reorder the list?
+     * Note! We should try fish kcsuffix out of bootargs or somewhere one day.
+     */
+    static bool s_fFirstCall = true;
+    struct
+    {
+        const char *pszLocation;
+        int         rc;
+    } aKernels[] =
+    {
+        { "/System/Library/Kernels/kernel", VERR_WRONG_ORDER },
+        { "/System/Library/Kernels/kernel.development", VERR_WRONG_ORDER },
+        { "/System/Library/Kernels/kernel.debug", VERR_WRONG_ORDER },
+        { "/mach_kernel", VERR_WRONG_ORDER },
+    };
+    int rc;
+    for (uint32_t i = 0; i < RT_ELEMENTS(aKernels); i++)
+    {
+        aKernels[i].rc = rc = rtR0DbgKrnlDarwinOpen(phKrnlInfo, aKernels[i].pszLocation);
+        if (RT_SUCCESS(rc))
+        {
+            if (s_fFirstCall)
+            {
+                printf("RTR0DbgKrnlInfoOpen: Using kernel file '%s'\n", aKernels[i].pszLocation);
+                s_fFirstCall = false;
+            }
+            return rc;
+        }
+    }
+
+    /*
+     * Failed.
+     */
+    /* Pick the best error code. */
+    for (uint32_t i = 0; rc == VERR_FILE_NOT_FOUND && i < RT_ELEMENTS(aKernels); i++)
+        if (aKernels[i].rc != VERR_FILE_NOT_FOUND)
+            rc = aKernels[i].rc;
+
+    /* Bitch about it. */
+    printf("RTR0DbgKrnlInfoOpen: failed to find matching kernel file! rc=%d\n", rc);
+    if (s_fFirstCall)
+    {
+        for (uint32_t i = 0; i < RT_ELEMENTS(aKernels); i++)
+            printf("RTR0DbgKrnlInfoOpen: '%s' -> %d\n", aKernels[i].pszLocation, aKernels[i].rc);
+        s_fFirstCall = false;
+    }
+
+    return rc;
+}
+
+
 RTR0DECL(uint32_t) RTR0DbgKrnlInfoRetain(RTDBGKRNLINFO hKrnlInfo)
 {
     RTDBGKRNLINFOINT *pThis = hKrnlInfo;
diff --git a/src/VBox/Runtime/r3/nt/pathint-nt.cpp b/src/VBox/Runtime/r3/nt/pathint-nt.cpp
index aedbc0d..a32f637 100644
--- a/src/VBox/Runtime/r3/nt/pathint-nt.cpp
+++ b/src/VBox/Runtime/r3/nt/pathint-nt.cpp
@@ -46,6 +46,7 @@ static char const g_szPrefix[]    = "\\??\\";
 
 /**
  * Handles the pass thru case for UTF-8 input.
+ * Win32 path uses "\\?\" prefix which is converted to "\??\" NT prefix.
  *
  * @returns IPRT status code.
  * @param   pNtName             Where to return the NT name.
@@ -56,14 +57,15 @@ static int rtNtPathFromWinUtf8PassThru(struct _UNICODE_STRING *pNtName, PHANDLE
 {
     PRTUTF16 pwszPath = NULL;
     size_t   cwcLen;
-    int rc = RTStrToUtf16Ex(pszPath + 1, RTSTR_MAX, &pwszPath, 0, &cwcLen);
+    int rc = RTStrToUtf16Ex(pszPath, RTSTR_MAX, &pwszPath, 0, &cwcLen);
     if (RT_SUCCESS(rc))
     {
         if (cwcLen < _32K - 1)
         {
             pwszPath[0] = '\\';
-            pwszPath[1] = '.';
-            pwszPath[2] = '\\';
+            pwszPath[1] = '?';
+            pwszPath[2] = '?';
+            pwszPath[3] = '\\';
 
             pNtName->Buffer = pwszPath;
             pNtName->Length = (uint16_t)(cwcLen * sizeof(RTUTF16));
@@ -81,6 +83,7 @@ static int rtNtPathFromWinUtf8PassThru(struct _UNICODE_STRING *pNtName, PHANDLE
 
 /**
  * Handles the pass thru case for UTF-16 input.
+ * Win32 path uses "\\?\" prefix which is converted to "\??\" NT prefix.
  *
  * @returns IPRT status code.
  * @param   pNtName             Where to return the NT name.
@@ -91,10 +94,6 @@ static int rtNtPathFromWinUtf8PassThru(struct _UNICODE_STRING *pNtName, PHANDLE
 static int rtNtPathFromWinUtf16PassThru(struct _UNICODE_STRING *pNtName, PHANDLE phRootDir,
                                         PCRTUTF16 pwszWinPath, size_t cwcWinPath)
 {
-    /* Drop a character because: \\?\ -> \.\ */
-    pwszWinPath++;
-    cwcWinPath--;
-
     /* Check length and allocate memory for it. */
     int rc;
     if (cwcWinPath < _32K - 1)
@@ -104,9 +103,10 @@ static int rtNtPathFromWinUtf16PassThru(struct _UNICODE_STRING *pNtName, PHANDLE
         {
             /* Intialize the path. */
             pwszNtPath[0] = '\\';
-            pwszNtPath[1] = '.';
-            pwszNtPath[2] = '\\';
-            memcpy(pwszNtPath + 3, pwszWinPath + 3, (cwcWinPath - 3) * sizeof(RTUTF16));
+            pwszNtPath[1] = '?';
+            pwszNtPath[2] = '?';
+            pwszNtPath[3] = '\\';
+            memcpy(pwszNtPath + 4, pwszWinPath + 4, (cwcWinPath - 4) * sizeof(RTUTF16));
             pwszNtPath[cwcWinPath] = '\0';
 
             /* Initialize the return values. */
diff --git a/src/VBox/VMM/VMMR0/HMSVMR0.cpp b/src/VBox/VMM/VMMR0/HMSVMR0.cpp
index bde9f92..8123cbe 100644
--- a/src/VBox/VMM/VMMR0/HMSVMR0.cpp
+++ b/src/VBox/VMM/VMMR0/HMSVMR0.cpp
@@ -102,9 +102,10 @@
     do \
     { \
         int rc = hmR0SvmCheckExitDueToEventDelivery(pVCpu, pCtx, pSvmTransient); \
-        if (RT_UNLIKELY(rc == VINF_HM_DOUBLE_FAULT)) \
+        if (RT_LIKELY(rc == VINF_SUCCESS)) { /* likely */ } \
+        else if (rc == VINF_HM_DOUBLE_FAULT) \
             return VINF_SUCCESS; \
-        else if (RT_UNLIKELY(rc == VINF_EM_RESET)) \
+        else \
             return rc; \
     } while (0)
 
@@ -291,6 +292,7 @@ static FNSVMEXITHANDLER hmR0SvmExitXcptPF;
 static FNSVMEXITHANDLER hmR0SvmExitXcptNM;
 static FNSVMEXITHANDLER hmR0SvmExitXcptMF;
 static FNSVMEXITHANDLER hmR0SvmExitXcptDB;
+static FNSVMEXITHANDLER hmR0SvmExitXcptAC;
 /** @} */
 
 DECLINLINE(int) hmR0SvmHandleExit(PVMCPU pVCpu, PCPUMCTX pMixedCtx, PSVMTRANSIENT pSvmTransient);
@@ -668,6 +670,12 @@ VMMR0DECL(int) SVMR0SetupVM(PVM pVM)
 
         AssertMsgReturn(pVmcb, ("Invalid pVmcb for vcpu[%u]\n", i), VERR_SVM_INVALID_PVMCB);
 
+        /* Always trap #AC for reasons of security. */
+        pVmcb->ctrl.u32InterceptException |= RT_BIT_32(X86_XCPT_AC);
+
+        /* Always trap #DB for reasons of security. */
+        pVmcb->ctrl.u32InterceptException |= RT_BIT_32(X86_XCPT_DB);
+
         /* Trap exceptions unconditionally (debug purposes). */
 #ifdef HMSVM_ALWAYS_TRAP_PF
         pVmcb->ctrl.u32InterceptException |=   RT_BIT(X86_XCPT_PF);
@@ -1089,6 +1097,8 @@ DECLINLINE(void) hmR0SvmAddXcptIntercept(PSVMVMCB pVmcb, uint32_t u32Xcpt)
  */
 DECLINLINE(void) hmR0SvmRemoveXcptIntercept(PSVMVMCB pVmcb, uint32_t u32Xcpt)
 {
+    Assert(u32Xcpt != X86_XCPT_DB);
+    Assert(u32Xcpt != X86_XCPT_AC);
 #ifndef HMSVM_ALWAYS_TRAP_ALL_XCPTS
     if (pVmcb->ctrl.u32InterceptException & RT_BIT(u32Xcpt))
     {
@@ -1409,7 +1419,6 @@ static void hmR0SvmLoadSharedDebugState(PVMCPU pVCpu, PSVMVMCB pVmcb, PCPUMCTX p
     Assert((pCtx->dr[6] & X86_DR6_RA1_MASK) == X86_DR6_RA1_MASK); Assert((pCtx->dr[6] & X86_DR6_RAZ_MASK) == 0);
     Assert((pCtx->dr[7] & X86_DR7_RA1_MASK) == X86_DR7_RA1_MASK); Assert((pCtx->dr[7] & X86_DR7_RAZ_MASK) == 0);
 
-    bool fInterceptDB     = false;
     bool fInterceptMovDRx = false;
 
     /*
@@ -1422,7 +1431,6 @@ static void hmR0SvmLoadSharedDebugState(PVMCPU pVCpu, PSVMVMCB pVmcb, PCPUMCTX p
     {
         pVCpu->hm.s.fClearTrapFlag = true;
         pVmcb->guest.u64RFlags |= X86_EFL_TF;
-        fInterceptDB = true;
         fInterceptMovDRx = true; /* Need clean DR6, no guest mess. */
     }
 
@@ -1465,7 +1473,6 @@ static void hmR0SvmLoadSharedDebugState(PVMCPU pVCpu, PSVMVMCB pVmcb, PCPUMCTX p
 
         /** @todo If we cared, we could optimize to allow the guest to read registers
          *        with the same values. */
-        fInterceptDB = true;
         fInterceptMovDRx = true;
         Log5(("hmR0SvmLoadSharedDebugState: Loaded hyper DRx\n"));
     }
@@ -1512,6 +1519,10 @@ static void hmR0SvmLoadSharedDebugState(PVMCPU pVCpu, PSVMVMCB pVmcb, PCPUMCTX p
         /*
          * If no debugging enabled, we'll lazy load DR0-3. We don't need to
          * intercept #DB as DR6 is updated in the VMCB.
+         *
+         * Note! If we cared and dared, we could skip intercepting \#DB here.
+         *       However, \#DB shouldn't be performance critical, so we'll play safe
+         *       and keep the code similar to the VT-x code and always intercept it.
          */
 #if HC_ARCH_BITS == 32 && defined(VBOX_WITH_64_BITS_GUESTS) && !defined(VBOX_WITH_HYBRID_32BIT_KERNEL)
         else if (   !CPUMIsGuestDebugStateActivePending(pVCpu)
@@ -1524,14 +1535,7 @@ static void hmR0SvmLoadSharedDebugState(PVMCPU pVCpu, PSVMVMCB pVmcb, PCPUMCTX p
         }
     }
 
-    /*
-     * Set up the intercepts.
-     */
-    if (fInterceptDB)
-        hmR0SvmAddXcptIntercept(pVmcb, X86_XCPT_DB);
-    else
-        hmR0SvmRemoveXcptIntercept(pVmcb, X86_XCPT_DB);
-
+    Assert(pVmcb->ctrl.u32InterceptException & RT_BIT_32(X86_XCPT_DB));
     if (fInterceptMovDRx)
     {
         if (   pVmcb->ctrl.u16InterceptRdDRx != 0xffff
@@ -3259,6 +3263,9 @@ DECLINLINE(int) hmR0SvmHandleExit(PVMCPU pVCpu, PCPUMCTX pCtx, PSVMTRANSIENT pSv
         case SVM_EXIT_EXCEPTION_1:   /* X86_XCPT_DB */
             return hmR0SvmExitXcptDB(pVCpu, pCtx, pSvmTransient);
 
+        case SVM_EXIT_EXCEPTION_11:  /* X86_XCPT_AC */
+            return hmR0SvmExitXcptAC(pVCpu, pCtx, pSvmTransient);
+
         case SVM_EXIT_MONITOR:
             return hmR0SvmExitMonitor(pVCpu, pCtx, pSvmTransient);
 
@@ -3366,7 +3373,7 @@ DECLINLINE(int) hmR0SvmHandleExit(PVMCPU pVCpu, PCPUMCTX pCtx, PSVMTRANSIENT pSv
                 case SVM_EXIT_EXCEPTION_D:             /* X86_XCPT_GP */
                 /*   SVM_EXIT_EXCEPTION_E: */          /* X86_XCPT_PF - Handled above. */
                 /*   SVM_EXIT_EXCEPTION_10: */         /* X86_XCPT_MF - Handled above. */
-                case SVM_EXIT_EXCEPTION_11:            /* X86_XCPT_AC */
+                /*   SVM_EXIT_EXCEPTION_11: */         /* X86_XCPT_AC - Handled above. */
                 case SVM_EXIT_EXCEPTION_12:            /* X86_XCPT_MC */
                 case SVM_EXIT_EXCEPTION_13:            /* X86_XCPT_XF */
                 case SVM_EXIT_EXCEPTION_F:             /* Reserved */
@@ -3762,6 +3769,7 @@ DECLINLINE(bool) hmR0SvmIsContributoryXcpt(const uint32_t uVector)
  * @retval VINF_HM_DOUBLE_FAULT if a #DF condition was detected and we ought to
  *         continue execution of the guest which will delivery the #DF.
  * @retval VINF_EM_RESET if we detected a triple-fault condition.
+ * @retval VERR_EM_GUEST_CPU_HANG if we detected a guest CPU hang.
  *
  * @param   pVCpu           Pointer to the VMCPU.
  * @param   pCtx            Pointer to the guest-CPU context.
@@ -3785,6 +3793,7 @@ static int hmR0SvmCheckExitDueToEventDelivery(PVMCPU pVCpu, PCPUMCTX pCtx, PSVMT
             SVMREFLECTXCPT_XCPT,    /* Reflect the exception to the guest or for further evaluation by VMM. */
             SVMREFLECTXCPT_DF,      /* Reflect the exception as a double-fault to the guest. */
             SVMREFLECTXCPT_TF,      /* Indicate a triple faulted state to the VMM. */
+            SVMREFLECTXCPT_HANG,    /* Indicate bad VM trying to deadlock the CPU. */
             SVMREFLECTXCPT_NONE     /* Nothing to reflect. */
         } SVMREFLECTXCPT;
 
@@ -3808,6 +3817,12 @@ static int hmR0SvmCheckExitDueToEventDelivery(PVMCPU pVCpu, PCPUMCTX pCtx, PSVMT
                     pSvmTransient->fVectoringPF = true;
                     Log4(("IDT: Vectoring #PF uCR2=%#RX64\n", pCtx->cr2));
                 }
+                else if (   uExitVector == X86_XCPT_AC
+                         && uIdtVector == X86_XCPT_AC)
+                {
+                    Log4(("IDT: Nested #AC - Bad guest\n"));
+                    enmReflect = SVMREFLECTXCPT_HANG;
+                }
                 else if (   (pVmcb->ctrl.u32InterceptException & HMSVM_CONTRIBUTORY_XCPT_MASK)
                          && hmR0SvmIsContributoryXcpt(uExitVector)
                          && (   hmR0SvmIsContributoryXcpt(uIdtVector)
@@ -3867,12 +3882,18 @@ static int hmR0SvmCheckExitDueToEventDelivery(PVMCPU pVCpu, PCPUMCTX pCtx, PSVMT
                 break;
             }
 
+            case SVMREFLECTXCPT_HANG:
+            {
+                rc = VERR_EM_GUEST_CPU_HANG;
+                break;
+            }
+
             default:
                 Assert(rc == VINF_SUCCESS);
                 break;
         }
     }
-    Assert(rc == VINF_SUCCESS || rc == VINF_HM_DOUBLE_FAULT || rc == VINF_EM_RESET);
+    Assert(rc == VINF_SUCCESS || rc == VINF_HM_DOUBLE_FAULT || rc == VINF_EM_RESET || rc == VERR_EM_GUEST_CPU_HANG);
     return rc;
 }
 
@@ -4994,5 +5015,25 @@ HMSVM_EXIT_DECL hmR0SvmExitXcptDB(PVMCPU pVCpu, PCPUMCTX pCtx, PSVMTRANSIENT pSv
     return rc;
 }
 
+
+/**
+ * \#VMEXIT handler for alignment check exceptions (SVM_EXIT_EXCEPTION_11).
+ * Conditional \#VMEXIT.
+ */
+HMSVM_EXIT_DECL hmR0SvmExitXcptAC(PVMCPU pVCpu, PCPUMCTX pCtx, PSVMTRANSIENT pSvmTransient)
+{
+    HMSVM_VALIDATE_EXIT_HANDLER_PARAMS();
+
+    HMSVM_CHECK_EXIT_DUE_TO_EVENT_DELIVERY();
+
+    SVMEVENT Event;
+    Event.u          = 0;
+    Event.n.u1Valid  = 1;
+    Event.n.u3Type   = SVM_EVENT_EXCEPTION;
+    Event.n.u8Vector = X86_XCPT_AC;
+    hmR0SvmSetPendingEvent(pVCpu, &Event, 0 /* GCPtrFaultAddress */);
+    return VINF_SUCCESS;
+}
+
 /** @} */
 
diff --git a/src/VBox/VMM/VMMR0/HMVMXR0.cpp b/src/VBox/VMM/VMMR0/HMVMXR0.cpp
index e8bcdc5..64dedcd 100644
--- a/src/VBox/VMM/VMMR0/HMVMXR0.cpp
+++ b/src/VBox/VMM/VMMR0/HMVMXR0.cpp
@@ -150,12 +150,12 @@ typedef RTHCUINTREG                   HMVMXHCUINTREG;
  * - #PF need not be intercepted even in real-mode if we have Nested Paging
  * support.
  */
-#define HMVMX_REAL_MODE_XCPT_MASK    (  RT_BIT(X86_XCPT_DE)            /* RT_BIT(X86_XCPT_DB) */ | RT_BIT(X86_XCPT_NMI)   \
+#define HMVMX_REAL_MODE_XCPT_MASK    (  RT_BIT(X86_XCPT_DE)  /* always: | RT_BIT(X86_XCPT_DB) */ | RT_BIT(X86_XCPT_NMI)   \
                                       | RT_BIT(X86_XCPT_BP)             | RT_BIT(X86_XCPT_OF)    | RT_BIT(X86_XCPT_BR)    \
                                       | RT_BIT(X86_XCPT_UD)            /* RT_BIT(X86_XCPT_NM) */ | RT_BIT(X86_XCPT_DF)    \
                                       | RT_BIT(X86_XCPT_CO_SEG_OVERRUN) | RT_BIT(X86_XCPT_TS)    | RT_BIT(X86_XCPT_NP)    \
                                       | RT_BIT(X86_XCPT_SS)             | RT_BIT(X86_XCPT_GP)   /* RT_BIT(X86_XCPT_PF) */ \
-                                     /* RT_BIT(X86_XCPT_MF) */          | RT_BIT(X86_XCPT_AC)    | RT_BIT(X86_XCPT_MC)    \
+                                     /* RT_BIT(X86_XCPT_MF)     always: | RT_BIT(X86_XCPT_AC) */ | RT_BIT(X86_XCPT_MC)    \
                                       | RT_BIT(X86_XCPT_XF))
 
 /**
@@ -403,6 +403,7 @@ static FNVMXEXITHANDLER hmR0VmxExitInvpcid;
 static int          hmR0VmxExitXcptNM(PVMCPU pVCpu, PCPUMCTX pMixedCtx, PVMXTRANSIENT pVmxTransient);
 static int          hmR0VmxExitXcptPF(PVMCPU pVCpu, PCPUMCTX pMixedCtx, PVMXTRANSIENT pVmxTransient);
 static int          hmR0VmxExitXcptMF(PVMCPU pVCpu, PCPUMCTX pMixedCtx, PVMXTRANSIENT pVmxTransient);
+static int          hmR0VmxExitXcptAC(PVMCPU pVCpu, PCPUMCTX pMixedCtx, PVMXTRANSIENT pVmxTransient);
 static int          hmR0VmxExitXcptDB(PVMCPU pVCpu, PCPUMCTX pMixedCtx, PVMXTRANSIENT pVmxTransient);
 static int          hmR0VmxExitXcptBP(PVMCPU pVCpu, PCPUMCTX pMixedCtx, PVMXTRANSIENT pVmxTransient);
 static int          hmR0VmxExitXcptGP(PVMCPU pVCpu, PCPUMCTX pMixedCtx, PVMXTRANSIENT pVmxTransient);
@@ -2125,7 +2126,15 @@ static int hmR0VmxInitXcptBitmap(PVM pVM, PVMCPU pVCpu)
 
     LogFlowFunc(("pVM=%p pVCpu=%p\n", pVM, pVCpu));
 
-    uint32_t u32XcptBitmap = 0;
+    /*
+     * #AC: We always intercept it to prevent the guest from hanging the CPU.
+     *
+     * #DB: Because we need to maintain the DR6 state even when intercepting DRx reads
+     *      and writes, and because recursive #DBs can cause the CPU hang, we must always
+     *      intercept it.
+     */
+    uint32_t u32XcptBitmap =   RT_BIT(X86_XCPT_AC)
+                             | RT_BIT(X86_XCPT_DB);
 
     /* Without Nested Paging, #PF must cause a VM-exit so we can sync our shadow page tables. */
     if (!pVM->hm.s.fNestedPaging)
@@ -3370,7 +3379,6 @@ static int hmR0VmxLoadSharedCR0(PVMCPU pVCpu, PCPUMCTX pMixedCtx)
 #ifdef HMVMX_ALWAYS_TRAP_ALL_XCPTS
         pVCpu->hm.s.vmx.u32XcptBitmap |= 0
                                          | RT_BIT(X86_XCPT_BP)
-                                         | RT_BIT(X86_XCPT_DB)
                                          | RT_BIT(X86_XCPT_DE)
                                          | RT_BIT(X86_XCPT_NM)
                                          | RT_BIT(X86_XCPT_UD)
@@ -3401,6 +3409,8 @@ static int hmR0VmxLoadSharedCR0(PVMCPU pVCpu, PCPUMCTX pMixedCtx)
         /* Write VT-x's view of the guest CR0 into the VMCS and update the exception bitmap. */
         rc = VMXWriteVmcs32(VMX_VMCS_GUEST_CR0, u32GuestCR0);
         AssertRCReturn(rc, rc);
+        Assert(pVCpu->hm.s.vmx.u32XcptBitmap & RT_BIT_32(X86_XCPT_AC));
+        Assert(pVCpu->hm.s.vmx.u32XcptBitmap & RT_BIT_32(X86_XCPT_DB));
         rc = VMXWriteVmcs32(VMX_VMCS32_CTRL_EXCEPTION_BITMAP, pVCpu->hm.s.vmx.u32XcptBitmap);
         AssertRCReturn(rc, rc);
         Log4(("Load: VMX_VMCS_GUEST_CR0=%#RX32 (uSetCR0=%#RX32 uZapCR0=%#RX32)\n", u32GuestCR0, uSetCR0, uZapCR0));
@@ -3681,7 +3691,7 @@ static int hmR0VmxLoadSharedDebugState(PVMCPU pVCpu, PCPUMCTX pMixedCtx)
 
     int  rc;
     PVM  pVM              = pVCpu->CTX_SUFF(pVM);
-    bool fInterceptDB     = false;
+    bool fSteppingDB      = false;
     bool fInterceptMovDRx = false;
     if (   pVCpu->hm.s.fSingleInstruction
         || DBGFIsStepping(pVCpu))
@@ -3692,18 +3702,18 @@ static int hmR0VmxLoadSharedDebugState(PVMCPU pVCpu, PCPUMCTX pMixedCtx)
             pVCpu->hm.s.vmx.u32ProcCtls |= VMX_VMCS_CTRL_PROC_EXEC_MONITOR_TRAP_FLAG;
             rc = VMXWriteVmcs32(VMX_VMCS32_CTRL_PROC_EXEC, pVCpu->hm.s.vmx.u32ProcCtls);
             AssertRCReturn(rc, rc);
-            Assert(fInterceptDB == false);
+            Assert(fSteppingDB == false);
         }
         else
         {
             pMixedCtx->eflags.u32 |= X86_EFL_TF;
             pVCpu->hm.s.fClearTrapFlag = true;
             HMCPU_CF_SET(pVCpu, HM_CHANGED_GUEST_RFLAGS);
-            fInterceptDB = true;
+            fSteppingDB = true;
         }
     }
 
-    if (   fInterceptDB
+    if (   fSteppingDB
         || (CPUMGetHyperDR7(pVCpu) & X86_DR7_ENABLED_MASK))
     {
         /*
@@ -3735,7 +3745,6 @@ static int hmR0VmxLoadSharedDebugState(PVMCPU pVCpu, PCPUMCTX pMixedCtx)
         AssertRCReturn(rc, rc);
 
         pVCpu->hm.s.fUsingHyperDR7 = true;
-        fInterceptDB = true;
         fInterceptMovDRx = true;
     }
     else
@@ -3764,12 +3773,13 @@ static int hmR0VmxLoadSharedDebugState(PVMCPU pVCpu, PCPUMCTX pMixedCtx)
                 Assert(!CPUMIsHyperDebugStateActive(pVCpu));
                 STAM_COUNTER_INC(&pVCpu->hm.s.StatDRxArmed);
             }
-            Assert(!fInterceptDB);
             Assert(!fInterceptMovDRx);
         }
         /*
          * If no debugging enabled, we'll lazy load DR0-3.  Unlike on AMD-V, we
-         * must intercept #DB in order to maintain a correct DR6 guest value.
+         * must intercept #DB in order to maintain a correct DR6 guest value, and
+         * because we need to intercept it to prevent nested #DBs from hanging the
+         * CPU, we end up always having to intercept it.  See hmR0VmxInitXcptBitmap.
          */
 #if HC_ARCH_BITS == 32 && defined(VBOX_WITH_64_BITS_GUESTS) && !defined(VBOX_WITH_HYBRID_32BIT_KERNEL)
         else if (   !CPUMIsGuestDebugStateActivePending(pVCpu)
@@ -3779,7 +3789,6 @@ static int hmR0VmxLoadSharedDebugState(PVMCPU pVCpu, PCPUMCTX pMixedCtx)
 #endif
         {
             fInterceptMovDRx = true;
-            fInterceptDB = true;
         }
 
         /* Update guest DR7. */
@@ -3790,21 +3799,6 @@ static int hmR0VmxLoadSharedDebugState(PVMCPU pVCpu, PCPUMCTX pMixedCtx)
     }
 
     /*
-     * Update the exception bitmap regarding intercepting #DB generated by the guest.
-     */
-    if (   fInterceptDB
-        || pVCpu->hm.s.vmx.RealMode.fRealOnV86Active)
-        pVCpu->hm.s.vmx.u32XcptBitmap |= RT_BIT(X86_XCPT_DB);
-    else
-    {
-#ifndef HMVMX_ALWAYS_TRAP_ALL_XCPTS
-        pVCpu->hm.s.vmx.u32XcptBitmap &= ~RT_BIT(X86_XCPT_DB);
-#endif
-    }
-    rc = VMXWriteVmcs32(VMX_VMCS32_CTRL_EXCEPTION_BITMAP, pVCpu->hm.s.vmx.u32XcptBitmap);
-    AssertRCReturn(rc, rc);
-
-    /*
      * Update the processor-based VM-execution controls regarding intercepting MOV DRx instructions.
      */
     if (fInterceptMovDRx)
@@ -5375,6 +5369,7 @@ DECLINLINE(void) hmR0VmxSetPendingXcptDF(PVMCPU pVCpu, PCPUMCTX pMixedCtx)
  * @retval VINF_HM_DOUBLE_FAULT if a #DF condition was detected and we ought to
  *         continue execution of the guest which will delivery the #DF.
  * @retval VINF_EM_RESET if we detected a triple-fault condition.
+ * @retval VERR_EM_GUEST_CPU_HANG if we detected a guest CPU hang.
  *
  * @param   pVCpu           Pointer to the VMCPU.
  * @param   pMixedCtx       Pointer to the guest-CPU context. The data may be
@@ -5402,6 +5397,7 @@ static int hmR0VmxCheckExitDueToEventDelivery(PVMCPU pVCpu, PCPUMCTX pMixedCtx,
             VMXREFLECTXCPT_XCPT,    /* Reflect the exception to the guest or for further evaluation by VMM. */
             VMXREFLECTXCPT_DF,      /* Reflect the exception as a double-fault to the guest. */
             VMXREFLECTXCPT_TF,      /* Indicate a triple faulted state to the VMM. */
+            VMXREFLECTXCPT_HANG,    /* Indicate bad VM trying to deadlock the CPU. */
             VMXREFLECTXCPT_NONE     /* Nothing to reflect. */
         } VMXREFLECTXCPT;
 
@@ -5425,6 +5421,12 @@ static int hmR0VmxCheckExitDueToEventDelivery(PVMCPU pVCpu, PCPUMCTX pMixedCtx,
                     pVmxTransient->fVectoringPF = true;
                     Log4(("IDT: vcpu[%RU32] Vectoring #PF uCR2=%#RX64\n", pVCpu->idCpu, pMixedCtx->cr2));
                 }
+                else if (   uExitVector == X86_XCPT_AC
+                         && uIdtVector == X86_XCPT_AC)
+                {
+                    Log4(("IDT: Nested #AC - Bad guest\n"));
+                    enmReflect = VMXREFLECTXCPT_HANG;
+                }
                 else if (   (pVCpu->hm.s.vmx.u32XcptBitmap & HMVMX_CONTRIBUTORY_XCPT_MASK)
                          && hmR0VmxIsContributoryXcpt(uExitVector)
                          && (   hmR0VmxIsContributoryXcpt(uIdtVector)
@@ -5505,12 +5507,18 @@ static int hmR0VmxCheckExitDueToEventDelivery(PVMCPU pVCpu, PCPUMCTX pMixedCtx,
                 break;
             }
 
+            case VMXREFLECTXCPT_HANG:
+            {
+                rc = VERR_EM_GUEST_CPU_HANG;
+                break;
+            }
+
             default:
                 Assert(rc == VINF_SUCCESS);
                 break;
         }
     }
-    Assert(rc == VINF_SUCCESS || rc == VINF_HM_DOUBLE_FAULT || rc == VINF_EM_RESET);
+    Assert(rc == VINF_SUCCESS || rc == VINF_HM_DOUBLE_FAULT || rc == VINF_EM_RESET || rc == VERR_EM_GUEST_CPU_HANG);
     return rc;
 }
 
@@ -9218,13 +9226,10 @@ HMVMX_EXIT_DECL hmR0VmxExitXcptOrNmi(PVMCPU pVCpu, PCPUMCTX pMixedCtx, PVMXTRANS
 
     /* If this VM-exit occurred while delivering an event through the guest IDT, handle it accordingly. */
     rc = hmR0VmxCheckExitDueToEventDelivery(pVCpu, pMixedCtx, pVmxTransient);
-    if (RT_UNLIKELY(rc == VINF_HM_DOUBLE_FAULT))
-    {
-        STAM_PROFILE_ADV_STOP(&pVCpu->hm.s.StatExitXcptNmi, y3);
-        return VINF_SUCCESS;
-    }
-    else if (RT_UNLIKELY(rc == VINF_EM_RESET))
+    if (RT_UNLIKELY(rc != VINF_SUCCESS))
     {
+        if (rc == VINF_HM_DOUBLE_FAULT)
+            rc = VINF_SUCCESS;
         STAM_PROFILE_ADV_STOP(&pVCpu->hm.s.StatExitXcptNmi, y3);
         return rc;
     }
@@ -9249,6 +9254,7 @@ HMVMX_EXIT_DECL hmR0VmxExitXcptOrNmi(PVMCPU pVCpu, PCPUMCTX pMixedCtx, PVMXTRANS
                 case X86_XCPT_MF: rc = hmR0VmxExitXcptMF(pVCpu, pMixedCtx, pVmxTransient);      break;
                 case X86_XCPT_DB: rc = hmR0VmxExitXcptDB(pVCpu, pMixedCtx, pVmxTransient);      break;
                 case X86_XCPT_BP: rc = hmR0VmxExitXcptBP(pVCpu, pMixedCtx, pVmxTransient);      break;
+                case X86_XCPT_AC: rc = hmR0VmxExitXcptAC(pVCpu, pMixedCtx, pVmxTransient);      break;
 #ifdef HMVMX_ALWAYS_TRAP_ALL_XCPTS
                 case X86_XCPT_XF: STAM_COUNTER_INC(&pVCpu->hm.s.StatExitGuestXF);
                                   rc = hmR0VmxExitXcptGeneric(pVCpu, pMixedCtx, pVmxTransient); break;
@@ -10486,10 +10492,12 @@ HMVMX_EXIT_DECL hmR0VmxExitApicAccess(PVMCPU pVCpu, PCPUMCTX pMixedCtx, PVMXTRAN
 
     /* If this VM-exit occurred while delivering an event through the guest IDT, handle it accordingly. */
     int rc = hmR0VmxCheckExitDueToEventDelivery(pVCpu, pMixedCtx, pVmxTransient);
-    if (RT_UNLIKELY(rc == VINF_HM_DOUBLE_FAULT))
-        return VINF_SUCCESS;
-    else if (RT_UNLIKELY(rc == VINF_EM_RESET))
+    if (RT_UNLIKELY(rc != VINF_SUCCESS))
+    {
+        if (rc == VINF_HM_DOUBLE_FAULT)
+            rc = VINF_SUCCESS;
         return rc;
+    }
 
 #if 0
     /** @todo Investigate if IOMMMIOPhysHandler() requires a lot of state, for now
@@ -10573,20 +10581,13 @@ HMVMX_EXIT_DECL hmR0VmxExitMovDRx(PVMCPU pVCpu, PCPUMCTX pMixedCtx, PVMXTRANSIEN
         && !pVCpu->hm.s.fSingleInstruction
         && !pVmxTransient->fWasHyperDebugStateActive)
     {
-        /* Don't intercept MOV DRx and #DB any more. */
+        Assert(pVCpu->hm.s.vmx.u32XcptBitmap & RT_BIT_32(X86_XCPT_DB));
+
+        /* Don't intercept MOV DRx any more. */
         pVCpu->hm.s.vmx.u32ProcCtls &= ~VMX_VMCS_CTRL_PROC_EXEC_MOV_DR_EXIT;
         rc = VMXWriteVmcs32(VMX_VMCS32_CTRL_PROC_EXEC, pVCpu->hm.s.vmx.u32ProcCtls);
         AssertRCReturn(rc, rc);
 
-        if (!pVCpu->hm.s.vmx.RealMode.fRealOnV86Active)
-        {
-#ifndef HMVMX_ALWAYS_TRAP_ALL_XCPTS
-            pVCpu->hm.s.vmx.u32XcptBitmap &= ~RT_BIT(X86_XCPT_DB);
-            rc = VMXWriteVmcs32(VMX_VMCS32_CTRL_EXCEPTION_BITMAP, pVCpu->hm.s.vmx.u32XcptBitmap);
-            AssertRCReturn(rc, rc);
-#endif
-        }
-
         /* We're playing with the host CPU state here, make sure we can't preempt or longjmp. */
         VMMRZCallRing3Disable(pVCpu);
         HM_DISABLE_PREEMPT_IF_NEEDED();
@@ -10660,10 +10661,12 @@ HMVMX_EXIT_DECL hmR0VmxExitEptMisconfig(PVMCPU pVCpu, PCPUMCTX pMixedCtx, PVMXTR
 
     /* If this VM-exit occurred while delivering an event through the guest IDT, handle it accordingly. */
     int rc = hmR0VmxCheckExitDueToEventDelivery(pVCpu, pMixedCtx, pVmxTransient);
-    if (RT_UNLIKELY(rc == VINF_HM_DOUBLE_FAULT))
-        return VINF_SUCCESS;
-    else if (RT_UNLIKELY(rc == VINF_EM_RESET))
+    if (RT_UNLIKELY(rc != VINF_SUCCESS))
+    {
+        if (rc == VINF_HM_DOUBLE_FAULT)
+            rc = VINF_SUCCESS;
         return rc;
+    }
 
     RTGCPHYS GCPhys = 0;
     rc = VMXReadVmcs64(VMX_VMCS64_EXIT_GUEST_PHYS_ADDR_FULL, &GCPhys);
@@ -10715,10 +10718,12 @@ HMVMX_EXIT_DECL hmR0VmxExitEptViolation(PVMCPU pVCpu, PCPUMCTX pMixedCtx, PVMXTR
 
     /* If this VM-exit occurred while delivering an event through the guest IDT, handle it accordingly. */
     int rc = hmR0VmxCheckExitDueToEventDelivery(pVCpu, pMixedCtx, pVmxTransient);
-    if (RT_UNLIKELY(rc == VINF_HM_DOUBLE_FAULT))
-        return VINF_SUCCESS;
-    else if (RT_UNLIKELY(rc == VINF_EM_RESET))
+    if (RT_UNLIKELY(rc != VINF_SUCCESS))
+    {
+        if (rc == VINF_HM_DOUBLE_FAULT)
+            rc = VINF_SUCCESS;
         return rc;
+    }
 
     RTGCPHYS GCPhys = 0;
     rc  = VMXReadVmcs64(VMX_VMCS64_EXIT_GUEST_PHYS_ADDR_FULL, &GCPhys);
@@ -10839,6 +10844,27 @@ static int hmR0VmxExitXcptBP(PVMCPU pVCpu, PCPUMCTX pMixedCtx, PVMXTRANSIENT pVm
 
 
 /**
+ * VM-exit exception handler for \#AC (alignment check exception).
+ */
+static int hmR0VmxExitXcptAC(PVMCPU pVCpu, PCPUMCTX pMixedCtx, PVMXTRANSIENT pVmxTransient)
+{
+    HMVMX_VALIDATE_EXIT_XCPT_HANDLER_PARAMS();
+
+    /*
+     * Re-inject it. We'll detect any nesting before getting here.
+     */
+    int rc = hmR0VmxReadExitIntErrorCodeVmcs(pVCpu, pVmxTransient);
+    rc    |= hmR0VmxReadExitInstrLenVmcs(pVCpu, pVmxTransient);
+    AssertRCReturn(rc, rc);
+    Assert(pVmxTransient->fVmcsFieldsRead & HMVMX_UPDATED_TRANSIENT_EXIT_INTERRUPTION_INFO);
+
+    hmR0VmxSetPendingEvent(pVCpu, VMX_VMCS_CTRL_ENTRY_IRQ_INFO_FROM_EXIT_INT_INFO(pVmxTransient->uExitIntInfo),
+                           pVmxTransient->cbInstr, pVmxTransient->uExitIntErrorCode, 0 /* GCPtrFaultAddress */);
+    return VINF_SUCCESS;
+}
+
+
+/**
  * VM-exit exception handler for #DB (Debug exception).
  */
 static int hmR0VmxExitXcptDB(PVMCPU pVCpu, PCPUMCTX pMixedCtx, PVMXTRANSIENT pVmxTransient)
diff --git a/src/VBox/VMM/VMMR3/VMMGuruMeditation.cpp b/src/VBox/VMM/VMMR3/VMMGuruMeditation.cpp
index 56dc1d5..c6a3077 100644
--- a/src/VBox/VMM/VMMR3/VMMGuruMeditation.cpp
+++ b/src/VBox/VMM/VMMR3/VMMGuruMeditation.cpp
@@ -600,6 +600,7 @@ VMMR3DECL(void) VMMR3FatalDump(PVM pVM, PVMCPU pVCpu, int rcErr)
 
         case VERR_IEM_INSTR_NOT_IMPLEMENTED:
         case VERR_IEM_ASPECT_NOT_IMPLEMENTED:
+        case VERR_EM_GUEST_CPU_HANG:
         {
             DBGFR3Info(pVM->pUVM, "cpumguest", NULL, pHlp);
             DBGFR3Info(pVM->pUVM, "cpumguestinstr", NULL, pHlp);
diff --git a/src/VBox/VMM/include/EMHandleRCTmpl.h b/src/VBox/VMM/include/EMHandleRCTmpl.h
index ef54f34..2c05895 100644
--- a/src/VBox/VMM/include/EMHandleRCTmpl.h
+++ b/src/VBox/VMM/include/EMHandleRCTmpl.h
@@ -337,6 +337,7 @@ int emR3HmHandleRC(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx, int rc)
         case VERR_VMM_RING3_CALL_DISABLED:
         case VERR_IEM_INSTR_NOT_IMPLEMENTED:
         case VERR_IEM_ASPECT_NOT_IMPLEMENTED:
+        case VERR_EM_GUEST_CPU_HANG:
             break;
 
 #ifdef EMHANDLERC_WITH_HM
diff --git a/src/libs/xpcom18a4/nsprpub/lib/ds/plarena.c b/src/libs/xpcom18a4/nsprpub/lib/ds/plarena.c
index 34d675f..e61efbe 100644
--- a/src/libs/xpcom18a4/nsprpub/lib/ds/plarena.c
+++ b/src/libs/xpcom18a4/nsprpub/lib/ds/plarena.c
@@ -115,6 +115,9 @@ PR_IMPLEMENT(void) PL_InitArenaPool(
         align = PL_ARENA_DEFAULT_ALIGN;
     pool->mask = PR_BITMASK(PR_CeilingLog2(align));
     pool->first.next = NULL;
+    /* Set all three addresses in pool->first to the same dummy value.
+     * These addresses are only compared with each other, but never
+     * dereferenced. */
     pool->first.base = pool->first.avail = pool->first.limit =
         (PRUword)PL_ARENA_ALIGN(pool, &pool->first + 1);
     pool->current = &pool->first;
@@ -158,10 +161,14 @@ PR_IMPLEMENT(void *) PL_ArenaAllocate(PLArenaPool *pool, PRUint32 nb)
 {
     PLArena *a;   
     char *rp;     /* returned pointer */
+    PRUint32 nbOld;
 
     PR_ASSERT((nb & pool->mask) == 0);
     
+    nbOld = nb;
     nb = (PRUword)PL_ARENA_ALIGN(pool, nb); /* force alignment */
+    if (nb < nbOld)
+        return NULL;
 
     /* attempt to allocate from arenas at pool->current */
     {
@@ -217,6 +224,7 @@ PR_IMPLEMENT(void *) PL_ArenaAllocate(PLArenaPool *pool, PRUint32 nb)
             a->base = a->avail = (PRUword)PL_ARENA_ALIGN(pool, a + 1);
             rp = (char *)a->avail;
             a->avail += nb;
+            PR_ASSERT(a->avail <= a->limit);
             /* the newly allocated arena is linked after pool->current 
             *  and becomes pool->current */
             a->next = pool->current->next;
@@ -239,6 +247,8 @@ PR_IMPLEMENT(void *) PL_ArenaGrow(
 {
     void *newp;
 
+    if (PR_UINT32_MAX - size < incr)
+        return NULL;
     PL_ARENA_ALLOCATE(newp, pool, size + incr);
     if (newp)
         memcpy(newp, p, size);
diff --git a/src/libs/xpcom18a4/nsprpub/lib/ds/plarena.h b/src/libs/xpcom18a4/nsprpub/lib/ds/plarena.h
index 38f3e39..174bd97 100644
--- a/src/libs/xpcom18a4/nsprpub/lib/ds/plarena.h
+++ b/src/libs/xpcom18a4/nsprpub/lib/ds/plarena.h
@@ -108,31 +108,37 @@ struct PLArenaPool {
 #define PL_ARENA_ALLOCATE(p, pool, nb) \
     PR_BEGIN_MACRO \
         PLArena *_a = (pool)->current; \
-        PRUint32 _nb = PL_ARENA_ALIGN(pool, nb); \
+        PRUint32 _nb = PL_ARENA_ALIGN(pool, (PRUint32)nb); \
         PRUword _p = _a->avail; \
-        PRUword _q = _p + _nb; \
-        if (_q > _a->limit) \
+        if (_nb < (PRUint32)nb) { \
+            _p = 0; \
+        } else if (_nb > (_a->limit - _a->avail)) { \
             _p = (PRUword)PL_ArenaAllocate(pool, _nb); \
-        else \
-            _a->avail = _q; \
+        } else { \
+            _a->avail += _nb; \
+        } \
         p = (void *)_p; \
-        PL_ArenaCountAllocation(pool, nb); \
+        if (p) { \
+            PL_ArenaCountAllocation(pool, nb); \
+        } \
     PR_END_MACRO
 
 #define PL_ARENA_GROW(p, pool, size, incr) \
     PR_BEGIN_MACRO \
         PLArena *_a = (pool)->current; \
-        PRUint32 _incr = PL_ARENA_ALIGN(pool, incr); \
-        PRUword _p = _a->avail; \
-        PRUword _q = _p + _incr; \
-        if (_p == (PRUword)(p) + PL_ARENA_ALIGN(pool, size) && \
-            _q <= _a->limit) { \
-            _a->avail = _q; \
-            PL_ArenaCountInplaceGrowth(pool, size, incr); \
+        PRUint32 _incr = PL_ARENA_ALIGN(pool, (PRUint32)incr); \
+        if (_incr < (PRUint32)incr) { \
+            p = NULL; \
+        } else if (_a->avail == (PRUword)(p) + PL_ARENA_ALIGN(pool, size) && \
+            _incr <= (_a->limit - _a->avail)) { \
+            _a->avail = _incr; \
+            PL_ArenaCountInplaceGrowth(pool, size, (RTUint32)incr); \
         } else { \
-            p = PL_ArenaGrow(pool, p, size, incr); \
+            p = PL_ArenaGrow(pool, p, size, (PRUint32)incr); \
+        } \
+        if (p) { \
+            PL_ArenaCountGrowth(pool, size, (PRUint32)incr); \
         } \
-        PL_ArenaCountGrowth(pool, size, incr); \
     PR_END_MACRO
 
 #define PL_ARENA_MARK(pool) ((void *) (pool)->current->avail)

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-virtualbox/virtualbox.git



More information about the Pkg-virtualbox-commits mailing list