[Pkg-virtualbox-commits] [virtualbox] 02/06: Imported Upstream version 4.3.10-dfsg

Felix Geyer fgeyer at moszumanska.debian.org
Sun Apr 6 15:56:05 UTC 2014


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

fgeyer pushed a commit to branch master
in repository virtualbox.

commit 1700c7d32f7d9d101cbba9f1fcb8bb57ed16a727
Author: Felix Geyer <fgeyer at debian.org>
Date:   Sat Apr 5 22:17:15 2014 +0200

    Imported Upstream version 4.3.10-dfsg
---
 Config.kmk                                         |    4 +-
 doc/manual/en_US/user_AdvancedTopics.xml           |  357 +++-
 doc/manual/en_US/user_VBoxManage.xml               |    2 +-
 doc/manual/fr_FR/user_AdvancedTopics.xml           |   94 +-
 doc/manual/user_ChangeLogImpl.xml                  |  386 +++-
 include/VBox/HostServices/VBoxCrOpenGLSvc.h        |    3 +-
 include/VBox/VBoxVideo.h                           |   70 +-
 include/VBox/VBoxVideo3D.h                         |   32 -
 include/VBox/VBoxVideoHost3D.h                     |  128 ++
 include/VBox/log.h                                 |   87 +
 include/VBox/vmm/cpum.h                            |   16 +-
 include/VBox/vmm/hm_vmx.h                          |   40 +
 include/VBox/vmm/pdmifs.h                          |   20 +-
 include/VBox/vmm/ssm.h                             |    1 +
 .../common/VBoxGuestLib/VBoxGuestR0LibCrOgl.cpp    |   15 +-
 src/VBox/Additions/common/crOpenGL/Makefile.kmk    |    5 -
 src/VBox/Additions/linux/installer/vboxadd-x11.sh  |   16 +-
 src/VBox/Additions/x11/VBoxClient/draganddrop.cpp  |   92 +-
 src/VBox/Additions/x11/vboxvideo/Makefile.kmk      |    2 +-
 src/VBox/Debugger/DBGPlugInLinux.cpp               |   23 +-
 src/VBox/Devices/EFI/DevEFI.cpp                    |    2 +-
 src/VBox/Devices/EFI/FirmwareBin/VBoxEFI32.fd      |  Bin 1048576 -> 1048576 bytes
 src/VBox/Devices/EFI/FirmwareBin/VBoxEFI64.fd      |  Bin 1048576 -> 1048576 bytes
 .../Graphics/BIOS/VBoxVgaBiosAlternative.asm       |  253 +--
 .../Graphics/BIOS/VBoxVgaBiosAlternative.md5sum    |    2 +-
 src/VBox/Devices/Graphics/DevVGA.cpp               |    6 +
 src/VBox/Devices/Graphics/DevVGA.h                 |   11 +-
 src/VBox/Devices/Graphics/DevVGA_VBVA.cpp          |   74 +-
 src/VBox/Devices/Graphics/DevVGA_VDMA.cpp          | 2098 ++++++++++++--------
 src/VBox/Devices/Makefile.kmk                      |    5 +-
 src/VBox/Devices/Network/lwip-new/CHANGELOG        |   44 +
 src/VBox/Devices/Network/lwip-new/Makefile.kmk     |   34 +-
 src/VBox/Devices/Network/lwip-new/src/api/tcpip.c  |    1 +
 .../Devices/Network/lwip-new/src/core/ipv4/icmp.c  |    4 +
 .../Devices/Network/lwip-new/src/core/ipv4/ip4.c   |    4 +-
 .../Network/lwip-new/src/core/ipv4/ip_frag.c       |   15 +-
 .../Devices/Network/lwip-new/src/core/ipv6/icmp6.c |   10 +-
 .../Devices/Network/lwip-new/src/core/ipv6/ip6.c   |   17 +-
 .../Devices/Network/lwip-new/src/core/ipv6/mld6.c  |    2 +
 .../Devices/Network/lwip-new/src/core/ipv6/nd6.c   |    6 +
 src/VBox/Devices/Network/lwip-new/src/core/memp.c  |   12 +-
 src/VBox/Devices/Network/lwip-new/src/core/netif.c |   66 +-
 .../Devices/Network/lwip-new/src/core/snmp/mib2.c  |   10 +-
 src/VBox/Devices/Network/lwip-new/src/core/stats.c |    4 +-
 src/VBox/Devices/Network/lwip-new/src/core/tcp.c   |    9 +-
 .../Devices/Network/lwip-new/src/core/tcp_out.c    |    7 +-
 .../Devices/Network/lwip-new/src/core/timers.c     |   22 +-
 .../lwip-new/src/include/ipv4/lwip/autoip.h        |    3 +
 .../Network/lwip-new/src/include/ipv4/lwip/inet.h  |   16 +-
 .../lwip-new/src/include/ipv4/lwip/ip4_addr.h      |    3 +
 .../Network/lwip-new/src/include/ipv6/lwip/inet6.h |    2 +-
 .../lwip-new/src/include/ipv6/lwip/ip6_addr.h      |    9 +-
 .../Network/lwip-new/src/include/lwip/debug.h      |    8 +-
 .../Network/lwip-new/src/include/lwip/memp_std.h   |    2 +-
 .../Network/lwip-new/src/include/lwip/netif.h      |    2 +-
 .../Network/lwip-new/src/include/lwip/netifapi.h   |    3 +
 .../Network/lwip-new/src/include/lwip/opt.h        |   28 +-
 .../Network/lwip-new/src/include/lwip/snmp.h       |    4 +-
 .../Network/lwip-new/src/include/lwip/sockets.h    |   51 +-
 .../Devices/Network/lwip-new/vbox/VBoxLwipCore.cpp |   10 +-
 .../Network/lwip-new/vbox/include/lwip-log.h       |   93 +
 .../Network/lwip-new/vbox/include/lwip-namespace.h |   26 +-
 .../Network/{lwip-new/vbox/include => }/lwipopts.h |   61 +-
 src/VBox/Devices/PC/BIOS/VBoxBiosAlternative.asm   |    4 +-
 .../Devices/PC/BIOS/VBoxBiosAlternative.md5sum     |    2 +-
 src/VBox/Devices/Storage/DrvHostBase.cpp           |    4 +-
 src/VBox/Devices/VMMDev/VMMDevHGCM.cpp             |   12 +
 .../src/globals/UIExtraDataEventHandler.cpp        |   20 +-
 .../src/globals/UIExtraDataEventHandler.h          |    1 +
 .../src/platform/darwin/UICocoaApplication.h       |   23 +
 .../src/platform/darwin/UICocoaApplication.mm      |   94 +-
 .../src/platform/darwin/VBoxUtils-darwin-cocoa.mm  |   43 +
 .../src/platform/darwin/VBoxUtils-darwin.cpp       |   20 +
 .../src/platform/darwin/VBoxUtils-darwin.h         |   10 +
 .../VirtualBox/src/runtime/UIFrameBuffer.cpp       |    8 +
 .../VirtualBox/src/runtime/UIKeyboardHandler.cpp   |   12 +-
 .../Frontends/VirtualBox/src/runtime/UIMachine.cpp |   53 +-
 .../VirtualBox/src/runtime/UIMachineLogic.cpp      |   77 +-
 .../VirtualBox/src/runtime/UIMachineLogic.h        |   15 +-
 .../VirtualBox/src/runtime/UIMachineView.cpp       |    2 +-
 .../VirtualBox/src/runtime/UIMachineWindow.cpp     |   36 +-
 .../VirtualBox/src/runtime/UIMachineWindow.h       |   18 +-
 .../VirtualBox/src/runtime/UIMouseHandler.cpp      |   51 +-
 .../VirtualBox/src/runtime/UIMouseHandler.h        |    7 +
 .../Frontends/VirtualBox/src/runtime/UISession.cpp |   48 +-
 .../Frontends/VirtualBox/src/runtime/UISession.h   |    9 -
 .../fullscreen/UIMachineLogicFullscreen.cpp        |  448 ++++-
 .../runtime/fullscreen/UIMachineLogicFullscreen.h  |   58 +-
 .../fullscreen/UIMachineWindowFullscreen.cpp       |  228 ++-
 .../runtime/fullscreen/UIMachineWindowFullscreen.h |   39 +-
 .../src/runtime/normal/UIMachineLogicNormal.cpp    |   12 +-
 .../src/runtime/normal/UIMachineWindowNormal.cpp   |   16 +-
 .../src/runtime/scale/UIMachineLogicScale.cpp      |   12 +-
 .../src/runtime/scale/UIMachineWindowScale.cpp     |   16 +-
 .../runtime/seamless/UIMachineLogicSeamless.cpp    |   40 +-
 .../src/runtime/seamless/UIMachineLogicSeamless.h  |    3 +
 .../runtime/seamless/UIMachineWindowSeamless.cpp   |   47 +-
 .../src/runtime/seamless/UIMachineWindowSeamless.h |    6 +-
 .../src/settings/global/UIGlobalSettingsInput.cpp  |   20 +-
 .../VirtualBox/src/widgets/UIMiniToolBar.cpp       |   28 +-
 .../VirtualBox/src/widgets/UIMiniToolBar.h         |   13 +
 .../src/wizards/newvm/UIWizardNewVMPageBasic1.cpp  |    4 +-
 src/VBox/GuestHost/OpenGL/include/cr_server.h      |   13 +-
 src/VBox/GuestHost/OpenGL/include/cr_vreg.h        |   18 +-
 src/VBox/GuestHost/OpenGL/packer/pack_pixels.c     |    3 +-
 src/VBox/GuestHost/OpenGL/util/blitter.cpp         |    2 +-
 src/VBox/GuestHost/OpenGL/util/htable.cpp          |    2 +-
 .../VBoxNetFlt/darwin/VBoxNetFlt-darwin.cpp        |   84 +-
 src/VBox/HostServices/SharedOpenGL/Makefile.kmk    |    6 +
 .../SharedOpenGL/crserver/crservice.cpp            |   73 +-
 .../HostServices/SharedOpenGL/crserverlib/server.h |    6 +-
 .../SharedOpenGL/crserverlib/server_main.c         |  290 ++-
 .../SharedOpenGL/crserverlib/server_muralfbo.cpp   |   18 +-
 .../SharedOpenGL/crserverlib/server_presenter.cpp  |  397 +++-
 .../SharedOpenGL/crserverlib/server_stream.c       |   22 +
 .../SharedOpenGL/crserverlib/server_window.c       |   44 +-
 .../SharedOpenGL/render/renderspu_wgl.c            |   41 +-
 .../darwin/VirtualBox_mpkg/Localizable.strings     |    4 +-
 .../darwin/VirtualBox_mpkg/distribution.dist       |   24 +-
 src/VBox/Installer/linux/run-inst.sh               |   25 +-
 src/VBox/Main/include/ApplianceImpl.h              |    1 +
 src/VBox/Main/include/ConsoleImpl.h                |   10 +-
 src/VBox/Main/include/DisplayImpl.h                |   12 +-
 src/VBox/Main/include/EventImpl.h                  |    2 +-
 src/VBox/Main/include/MachineImpl.h                |    2 +
 src/VBox/Main/src-all/EventImpl.cpp                |  420 ++--
 src/VBox/Main/src-client/ConsoleImpl.cpp           |  708 +++----
 src/VBox/Main/src-client/ConsoleImpl2.cpp          |    8 +-
 src/VBox/Main/src-client/DisplayImpl.cpp           |   77 +-
 src/VBox/Main/src-client/GuestFileImpl.cpp         |    2 +-
 src/VBox/Main/src-client/GuestImpl.cpp             |    2 +-
 src/VBox/Main/src-client/GuestProcessImpl.cpp      |    2 +-
 src/VBox/Main/src-client/GuestSessionImpl.cpp      |    2 +-
 src/VBox/Main/src-client/KeyboardImpl.cpp          |    2 +-
 src/VBox/Main/src-client/MouseImpl.cpp             |    2 +-
 src/VBox/Main/src-client/VirtualBoxClientImpl.cpp  |    2 +-
 src/VBox/Main/src-server/ApplianceImpl.cpp         |    2 +
 src/VBox/Main/src-server/ApplianceImplExport.cpp   |   17 +-
 src/VBox/Main/src-server/HostDnsService.cpp        |    4 +-
 src/VBox/Main/src-server/MachineImpl.cpp           |   90 +-
 src/VBox/Main/src-server/NATNetworkImpl.cpp        |    4 +-
 src/VBox/Main/src-server/VirtualBoxImpl.cpp        |    8 +-
 src/VBox/Main/src-server/darwin/iokit.cpp          |    4 +-
 src/VBox/NetworkServices/DHCP/VBoxNetDHCP.cpp      |    6 +-
 src/VBox/NetworkServices/NAT/Makefile.kmk          |    1 +
 src/VBox/NetworkServices/NAT/VBoxNetLwipNAT.cpp    |  421 ++--
 .../include => NetworkServices/NAT}/lwipopts.h     |   67 +-
 src/VBox/NetworkServices/NAT/portfwd.c             |   57 +-
 .../NetworkServices/NetLib/VBoxNetBaseService.cpp  |   14 +-
 .../NetLib/VBoxNetPortForwardString.cpp            |   27 +-
 .../NetworkServices/NetLib/VBoxPortForwardString.h |    2 -
 src/VBox/Runtime/VBox/log-vbox.cpp                 |    1 +
 .../Runtime/common/asm/ASMAtomicCmpXchgExU64.asm   |    8 +-
 .../Runtime/common/asm/ASMAtomicCmpXchgU64.asm     |    4 +-
 src/VBox/Runtime/common/asm/ASMCpuIdExSlow.asm     |    5 +-
 src/VBox/Runtime/common/asm/ASMCpuId_Idx_ECX.asm   |   10 +-
 src/VBox/Runtime/common/string/strformatrt.cpp     |  173 +-
 src/VBox/Runtime/generic/env-generic.cpp           |    5 +
 src/VBox/Runtime/r0drv/nt/ntBldSymDb.cpp           |   19 +-
 src/VBox/Runtime/r0drv/nt/symdbdata.h              |   96 +-
 src/VBox/Runtime/r3/linux/sysfs.cpp                |  164 +-
 .../Runtime/r3/win/RTSystemQueryDmiString-win.cpp  |    8 +-
 src/VBox/Runtime/testcase/tstHandleTable.cpp       |    8 +-
 src/VBox/Runtime/testcase/tstMemAutoPtr.cpp        |    6 +-
 src/VBox/Runtime/testcase/tstRTStrFormat.cpp       |  108 +-
 src/VBox/Storage/VD.cpp                            |    2 +-
 src/VBox/Storage/VHD.cpp                           |    2 +-
 src/VBox/VMM/VMMAll/CPUMAllMsrs.cpp                |  214 +-
 src/VBox/VMM/VMMAll/PGMAllPool.cpp                 |    7 +-
 src/VBox/VMM/VMMR0/HMR0.cpp                        |    2 +-
 src/VBox/VMM/VMMR0/HMVMXR0.cpp                     |  214 +-
 src/VBox/VMM/VMMR3/CPUM.cpp                        |    8 +
 src/VBox/VMM/VMMR3/CPUMR3CpuId.cpp                 |   65 +-
 src/VBox/VMM/VMMR3/CPUMR3Db.cpp                    |   11 +
 src/VBox/VMM/VMMR3/CSAM.cpp                        |   15 +-
 src/VBox/VMM/VMMR3/PATM.cpp                        |    5 +-
 src/VBox/VMM/VMMR3/PATMSSM.cpp                     |    9 -
 src/VBox/VMM/VMMR3/SSM.cpp                         |   31 +
 src/VBox/VMM/VMMR3/VM.cpp                          |    9 +
 src/VBox/VMM/VMMR3/cpus/AMD_Athlon_64_3200.h       |    1 +
 ...64_3200.h => AMD_Athlon_64_X2_Dual_Core_4200.h} |  187 +-
 src/VBox/VMM/VMMR3/cpus/AMD_FX_8150_Eight_Core.h   |    1 +
 src/VBox/VMM/VMMR3/cpus/AMD_Phenom_II_X6_1100T.h   |    1 +
 src/VBox/VMM/VMMR3/cpus/Intel_Core_i5_3570.h       |    9 +-
 ...Intel_Core_i5_3570.h => Intel_Core_i7_2635QM.h} |  358 ++--
 src/VBox/VMM/VMMR3/cpus/Intel_Core_i7_3820QM.h     |    5 +-
 src/VBox/VMM/VMMR3/cpus/Intel_Core_i7_3960X.h      |    9 +-
 src/VBox/VMM/VMMR3/cpus/Intel_Pentium_4_3_00GHz.h  |    3 +-
 .../VMMR3/cpus/Intel_Pentium_M_processor_2_00GHz.h |    5 +-
 src/VBox/VMM/VMMR3/cpus/Intel_Xeon_X5482_3_20GHz.h |    5 +-
 .../VMM/VMMR3/cpus/Quad_Core_AMD_Opteron_2384.h    |    1 +
 .../VMM/VMMR3/cpus/VIA_QuadCore_L4700_1_2_GHz.h    |    3 +-
 src/VBox/VMM/include/CPUMInternal.h                |   18 +-
 src/VBox/VMM/include/CPUMInternal.mac              |    2 +-
 src/VBox/VMM/include/HMInternal.h                  |    2 +-
 src/VBox/VMM/include/PATMInternal.h                |    1 -
 src/VBox/VMM/testcase/tstGlobalConfig.cpp          |    4 +-
 src/VBox/VMM/testcase/tstInstrEmul.cpp             |   10 +-
 src/VBox/VMM/testcase/tstVMMFork.cpp               |    4 +-
 src/VBox/VMM/tools/Makefile.kmk                    |    2 +-
 src/VBox/VMM/tools/VBoxCpuReport.cpp               |  168 +-
 src/libs/xpcom18a4/python/server/loader.py         |   14 +-
 src/libs/xpcom18a4/python/src/PyGBase.cpp          |    3 +-
 src/libs/xpcom18a4/python/src/PyIID.cpp            |    2 +-
 src/libs/xpcom18a4/python/src/PyISupports.cpp      |    4 +-
 205 files changed, 7492 insertions(+), 3580 deletions(-)

diff --git a/Config.kmk b/Config.kmk
index 44320d5..e2260a9 100644
--- a/Config.kmk
+++ b/Config.kmk
@@ -206,7 +206,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 = 8
+VBOX_VERSION_BUILD = 10
 # 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.
@@ -5528,7 +5528,7 @@ endif
 SVN                    ?= svn$(HOSTSUFF_EXE)
 VBOX_SVN_REV_KMK        = $(PATH_OUT)/revision.kmk
 ifndef VBOX_SVN_REV
- VBOX_SVN_REV_FALLBACK := $(patsubst %:,,  $Rev: 92456 $  )
+ VBOX_SVN_REV_FALLBACK := $(patsubst %:,,  $Rev: 93012 $  )
  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/en_US/user_AdvancedTopics.xml b/doc/manual/en_US/user_AdvancedTopics.xml
index acc5dbd..ed2a45e 100644
--- a/doc/manual/en_US/user_AdvancedTopics.xml
+++ b/doc/manual/en_US/user_AdvancedTopics.xml
@@ -2138,6 +2138,355 @@ VBoxManage setextradata "VM name" VBoxInternal2/CoreDumpLive 1</screen>At
       the default behavior, use</para>
       <screen>VBoxManage setextradata "VM name" GUI/RestrictedRuntimeMenus</screen>
 
+      <para>You can also disable (i.e. blacklist) certain menu actions of certain
+        menus. Use the following command to disable certain actions of the
+        <emphasis>Application</emphasis> menu (only available on Mac OS X hosts):</para>
+      <screen>VBoxManage setextradata "VM name" GUI/RestrictedRuntimeApplicationMenuActions OPTION[,OPTION...]</screen>
+
+      <para>where <computeroutput>OPTION</computeroutput> is one of the
+        following keywords:</para><glosslist>
+        <glossentry>
+          <glossterm><computeroutput>All</computeroutput></glossterm>
+          <glossdef>
+            <para>Don't show any menu item in this menu.</para>
+          </glossdef>
+        </glossentry>
+        <glossentry>
+          <glossterm><computeroutput>About</computeroutput></glossterm>
+          <glossdef>
+            <para>Don't show the <emphasis>About</emphasis> menu item in this menu.</para>
+          </glossdef>
+        </glossentry>
+      </glosslist>
+
+      <para>This is a per-VM setting. Any combination of the above is allowed. To restore
+      the default behavior, use</para>
+      <screen>VBoxManage setextradata "VM name" GUI/RestrictedRuntimeMenus</screen>
+
+      <para>Use the following command to disable certain actions of the <emphasis>Machine</emphasis>
+        menu:</para>
+
+      <screen>VBoxManage setextradata "VM name" GUI/RestrictedRuntimeApplicationMenuActions OPTION[,OPTION...]</screen>
+
+      <para>where <computeroutput>OPTION</computeroutput> is one of the
+        following keywords:</para><glosslist>
+        <glossentry>
+          <glossterm><computeroutput>All</computeroutput></glossterm>
+          <glossdef>
+            <para>Don't show any menu item in this menu.</para>
+          </glossdef>
+        </glossentry>
+        <glossentry>
+          <glossterm><computeroutput>SettingsDialog</computeroutput></glossterm>
+          <glossdef>
+            <para>Don't show the <emphasis>Settings</emphasis> menu item in this menu.</para>
+          </glossdef>
+        </glossentry>
+        <glossentry>
+          <glossterm><computeroutput>TakeSnapshot</computeroutput></glossterm>
+          <glossdef>
+            <para>Don't show the <emphasis>Take Snapshot</emphasis> menu item in this menu.</para>
+          </glossdef>
+        </glossentry>
+        <glossentry>
+          <glossterm><computeroutput>TakeScreenshot</computeroutput></glossterm>
+          <glossdef>
+            <para>Don't show the <emphasis>Take Screenshot</emphasis> menu item in this menu.</para>
+          </glossdef>
+        </glossentry>
+        <glossentry>
+          <glossterm><computeroutput>InformationDialog</computeroutput></glossterm>
+          <glossdef>
+            <para>Don't show the <emphasis>Session Information</emphasis> menu item in this menu.</para>
+          </glossdef>
+        </glossentry>
+        <glossentry>
+          <glossterm><computeroutput>MouseIntegration</computeroutput></glossterm>
+          <glossdef>
+            <para>Don't show the <emphasis>Disable Mouse Integration</emphasis> menu item in this menu.</para>
+          </glossdef>
+        </glossentry>
+        <glossentry>
+          <glossterm><computeroutput>TypeCAD</computeroutput></glossterm>
+          <glossdef>
+            <para>Don't show the <emphasis>Insert Ctrl+Alt+Del</emphasis> menu item in this menu.</para>
+          </glossdef>
+        </glossentry>
+        <glossentry>
+          <glossterm><computeroutput>TypeCABS</computeroutput></glossterm>
+          <glossdef>
+            <para>Don't show the <emphasis>Insert Ctrl+Alt+Backspace</emphasis> menu item in
+              this menu (available on X11 hosts only).</para>
+          </glossdef>
+        </glossentry>
+        <glossentry>
+          <glossterm><computeroutput>Pause</computeroutput></glossterm>
+          <glossdef>
+            <para>Don't show the <emphasis>Pause</emphasis> menu item in this menu.</para>
+          </glossdef>
+        </glossentry>
+        <glossentry>
+          <glossterm><computeroutput>Reset</computeroutput></glossterm>
+          <glossdef>
+            <para>Don't show the <emphasis>Reset</emphasis> menu item in this menu.</para>
+          </glossdef>
+        </glossentry>
+        <glossentry>
+          <glossterm><computeroutput>SaveState</computeroutput></glossterm>
+          <glossdef>
+            <para>Don't show the <emphasis>Save the machine state</emphasis> menu item in this menu.</para>
+          </glossdef>
+        </glossentry>
+        <glossentry>
+          <glossterm><computeroutput>Shutdown</computeroutput></glossterm>
+          <glossdef>
+            <para>Don't show the <emphasis>ACPI Shutdown</emphasis> menu item in this menu.</para>
+          </glossdef>
+        </glossentry>
+        <glossentry>
+          <glossterm><computeroutput>PowerOff</computeroutput></glossterm>
+          <glossdef>
+            <para>Don't show the <emphasis>Power Off the machine</emphasis> menu item in this menu.</para>
+          </glossdef>
+        </glossentry>
+      </glosslist>
+
+      <para>This is a per-VM setting. Any combination of the above is allowed. To restore
+      the default behavior, use</para>
+      <screen>VBoxManage setextradata "VM name" GUI/RestrictedRuntimeApplicationMenuActions</screen>
+
+      <para>Use the following command to disable certain actions of the <emphasis>View</emphasis>
+        menu:</para>
+
+      <screen>VBoxManage setextradata "VM name" GUI/RestrictedRuntimeViewMenuActions OPTION[,OPTION...]</screen>
+
+      <para>where <computeroutput>OPTION</computeroutput> is one of the
+        following keywords:</para><glosslist>
+        <glossentry>
+          <glossterm><computeroutput>All</computeroutput></glossterm>
+          <glossdef>
+            <para>Don't show any menu item in this menu.</para>
+          </glossdef>
+        </glossentry>
+        <glossentry>
+          <glossterm><computeroutput>Fullscreen</computeroutput></glossterm>
+          <glossdef>
+            <para>Don't show the <emphasis>Switch to Fullscreen</emphasis> menu item in this menu.</para>
+          </glossdef>
+        </glossentry>
+        <glossentry>
+          <glossterm><computeroutput>Seamless</computeroutput></glossterm>
+          <glossdef>
+            <para>Don't show the <emphasis>Switch to Seamless Mode</emphasis> menu item in this menu.</para>
+          </glossdef>
+        </glossentry>
+        <glossentry>
+          <glossterm><computeroutput>Scale</computeroutput></glossterm>
+          <glossdef>
+            <para>Don't show the <emphasis>Switch to Scaled Mode</emphasis> menu item in this menu.</para>
+          </glossdef>
+        </glossentry>
+        <glossentry>
+          <glossterm><computeroutput>GuestAutoresize</computeroutput></glossterm>
+          <glossdef>
+            <para>Don't show the <emphasis>Auto-resize Guest Display</emphasis> menu item in this menu.</para>
+          </glossdef>
+        </glossentry>
+        <glossentry>
+          <glossterm><computeroutput>AdjustWindow</computeroutput></glossterm>
+          <glossdef>
+            <para>Don't show the <emphasis>Adjust Window Size</emphasis> menu item in this menu.</para>
+          </glossdef>
+        </glossentry>
+        <glossentry>
+          <glossterm><computeroutput>Multiscreen</computeroutput></glossterm>
+          <glossdef>
+            <para>Don't show the <emphasis>Multiscreen</emphasis> menu item in this menu (only visible in full screen / seamless mode).</para>
+          </glossdef>
+        </glossentry>
+      </glosslist>
+
+      <para>This is a per-VM setting. Any combination of the above is allowed. To restore
+      the default behavior, use</para>
+      <screen>VBoxManage setextradata "VM name" GUI/RestrictedRuntimeViewMenuActions</screen>
+
+      <para>Use the following command to disable certain actions of the <emphasis>View</emphasis>
+        menu:</para>
+
+      <screen>VBoxManage setextradata "VM name" GUI/RestrictedRuntimeDevicesMenuActions OPTION[,OPTION...]</screen>
+
+      <para>where <computeroutput>OPTION</computeroutput> is one of the
+        following keywords to disable actions in the <emphasis>Devices</emphasis> menu:</para><glosslist>
+        <glossentry>
+          <glossterm><computeroutput>All</computeroutput></glossterm>
+          <glossdef>
+            <para>Don't show any menu item in this menu.</para>
+          </glossdef>
+        </glossentry>
+        <glossentry>
+          <glossterm><computeroutput>OpticalDevices</computeroutput></glossterm>
+          <glossdef>
+            <para>Don't show the <emphasis>CD/DVD Devices</emphasis> menu item in this menu.</para>
+          </glossdef>
+        </glossentry>
+        <glossentry>
+          <glossterm><computeroutput>FloppyDevices</computeroutput></glossterm>
+          <glossdef>
+            <para>Don't show the <emphasis>FLoppy Devices</emphasis> menu item in this menu.</para>
+          </glossdef>
+        </glossentry>
+        <glossentry>
+          <glossterm><computeroutput>USBDevices</computeroutput></glossterm>
+          <glossdef>
+            <para>Don't show the <emphasis>USB Devices</emphasis> menu item in this menu.</para>
+          </glossdef>
+        </glossentry>
+        <glossentry>
+          <glossterm><computeroutput>SharedClipboard</computeroutput></glossterm>
+          <glossdef>
+            <para>Don't show the <emphasis>Shared Clipboard</emphasis> menu item in this menu.</para>
+          </glossdef>
+        </glossentry>
+        <glossentry>
+          <glossterm><computeroutput>DragAndDrop</computeroutput></glossterm>
+          <glossdef>
+            <para>Don't show the <emphasis>Drag'n'Drop</emphasis> menu item in this menu.</para>
+          </glossdef>
+        </glossentry>
+        <glossentry>
+          <glossterm><computeroutput>NetworkSettings</computeroutput></glossterm>
+          <glossdef>
+            <para>Don't show the <emphasis>Network Settings...</emphasis> menu item in this menu.</para>
+          </glossdef>
+        </glossentry>
+        <glossentry>
+          <glossterm><computeroutput>SharedFoldersSettings</computeroutput></glossterm>
+          <glossdef>
+            <para>Don't show the <emphasis>Shared Folders Settings...</emphasis> menu item in this menu.</para>
+          </glossdef>
+        </glossentry>
+        <glossentry>
+          <glossterm><computeroutput>VRDEServer</computeroutput></glossterm>
+          <glossdef>
+            <para>Don't show the <emphasis>Remove Display</emphasis> menu item in this menu.</para>
+          </glossdef>
+        </glossentry>
+        <glossentry>
+          <glossterm><computeroutput>InstallGuestTools</computeroutput></glossterm>
+          <glossdef>
+            <para>Don't show the <emphasis>Insert Guest Additions CD imnage...</emphasis> menu item in this menu.</para>
+          </glossdef>
+        </glossentry>
+      </glosslist>
+
+      <para>This is a per-VM setting. Any combination of the above is allowed. To restore
+      the default behavior, use</para>
+      <screen>VBoxManage setextradata "VM name" GUI/RestrictedRuntimeDevicesMenuActions</screen>
+
+      <para>Use the following command to disable certain actions of the <emphasis>View</emphasis>
+        menu:</para>
+
+      <screen>VBoxManage setextradata "VM name" GUI/RestrictedRuntimeDebuggerMenuActions OPTION[,OPTION...]</screen>
+
+      <para>where <computeroutput>OPTION</computeroutput> is one of the
+        following keywords to disable actions in the <emphasis>Debug</emphasis> menu (normally completely disabled):</para><glosslist>
+        <glossentry>
+          <glossterm><computeroutput>All</computeroutput></glossterm>
+          <glossdef>
+            <para>Don't show any menu item in this menu.</para>
+          </glossdef>
+        </glossentry>
+        <glossentry>
+          <glossterm><computeroutput>Statistics</computeroutput></glossterm>
+          <glossdef>
+            <para>Don't show the <emphasis>Statistics...</emphasis> menu item in this menu.</para>
+          </glossdef>
+        </glossentry>
+        <glossentry>
+          <glossterm><computeroutput>CommandLine</computeroutput></glossterm>
+          <glossdef>
+            <para>Don't show the <emphasis>Command Line...</emphasis> menu item in this menu.</para>
+          </glossdef>
+        </glossentry>
+        <glossentry>
+          <glossterm><computeroutput>Logging</computeroutput></glossterm>
+          <glossdef>
+            <para>Don't show the <emphasis>Logging...</emphasis> menu item in this menu.</para>
+          </glossdef>
+        </glossentry>
+        <glossentry>
+          <glossterm><computeroutput>LogDialog</computeroutput></glossterm>
+          <glossdef>
+            <para>Don't show the <emphasis>Show Log...</emphasis> menu item in this menu.</para>
+          </glossdef>
+        </glossentry>
+      </glosslist>
+
+      <para>This is a per-VM setting. Any combination of the above is allowed. To restore
+      the default behavior, use</para>
+      <screen>VBoxManage setextradata "VM name" GUI/RestrictedRuntimeDebuggerMenuActions</screen>
+
+      <para>Use the following command to disable certain actions of the <emphasis>View</emphasis>
+        menu:</para>
+
+      <screen>VBoxManage setextradata "VM name" GUI/RestrictedRuntimeHelpMenuActions OPTION[,OPTION...]</screen>
+
+      <para>where <computeroutput>OPTION</computeroutput> is one of the
+        following keywords to disable actions in the <emphasis>Help</emphasis> menu (normally completely disabled):</para><glosslist>
+        <glossentry>
+          <glossterm><computeroutput>All</computeroutput></glossterm>
+          <glossdef>
+            <para>Don't show any menu item in this menu.</para>
+          </glossdef>
+        </glossentry>
+        <glossentry>
+          <glossterm><computeroutput>Contents</computeroutput></glossterm>
+          <glossdef>
+            <para>Don't show the <emphasis>Contents...</emphasis> menu item in this menu.</para>
+          </glossdef>
+        </glossentry>
+        <glossentry>
+          <glossterm><computeroutput>WebSite</computeroutput></glossterm>
+          <glossdef>
+            <para>Don't show the <emphasis>VirtualBox Web Site...</emphasis> menu item in this menu.</para>
+          </glossdef>
+        </glossentry>
+        <glossentry>
+          <glossterm><computeroutput>ResetWarnings</computeroutput></glossterm>
+          <glossdef>
+            <para>Don't show the <emphasis>Reset All Warnings</emphasis> menu item in this menu.</para>
+          </glossdef>
+        </glossentry>
+        <glossentry>
+          <glossterm><computeroutput>NetworkAccessManager</computeroutput></glossterm>
+          <glossdef>
+            <para>Don't show the <emphasis>Network Operations Manager</emphasis> menu item in this menu.</para>
+          </glossdef>
+        </glossentry>
+        <glossentry>
+          <glossterm><computeroutput>About</computeroutput></glossterm>
+          <glossdef>
+            <para>Don't show the <emphasis>About</emphasis> menu item in this menu (only on non Mac OS X hosts).</para>
+          </glossdef>
+        </glossentry>
+        <glossentry>
+          <glossterm><computeroutput>Contents</computeroutput></glossterm>
+          <glossdef>
+            <para>Don't show the <emphasis>Contents...</emphasis> menu item in this menu.</para>
+          </glossdef>
+        </glossentry>
+        <glossentry>
+          <glossterm><computeroutput>Contents</computeroutput></glossterm>
+          <glossdef>
+            <para>Don't show the <emphasis>Contents...</emphasis> menu item in this menu.</para>
+          </glossdef>
+        </glossentry>
+      </glosslist>
+
+      <para>This is a per-VM setting. Any combination of the above is allowed. To restore
+      the default behavior, use</para>
+      <screen>VBoxManage setextradata "VM name" GUI/RestrictedRuntimeHelpMenuActions</screen>
+
     </sect2>
 
     <sect2>
@@ -2248,7 +2597,7 @@ VBoxManage setextradata "VM name" VBoxInternal2/CoreDumpLive 1</screen>At
         <glossentry>
           <glossterm><computeroutput>Fullscreen</computeroutput></glossterm>
           <glossdef>
-            <para>Don't allow to switch the VM into fullscreen mode.</para>
+            <para>Don't allow to switch the VM into full screen mode.</para>
           </glossdef>
         </glossentry>
 
@@ -2358,7 +2707,7 @@ VBoxManage setextradata "VM name" VBoxInternal2/CoreDumpLive 1</screen>At
               <row>
                 <entry><computeroutput>FullscreenMode</computeroutput></entry>
                 <entry>F</entry>
-                <entry>switch the VM into fullscreen</entry>
+                <entry>switch the VM into full screen</entry>
               </row>
               <row>
                 <entry><computeroutput>SeamlessMode</computeroutput></entry>
@@ -2383,7 +2732,7 @@ VBoxManage setextradata "VM name" VBoxInternal2/CoreDumpLive 1</screen>At
               <row>
                 <entry><computeroutput>PopupMenu</computeroutput></entry>
                 <entry>Home</entry>
-                <entry>show popup menu in fullscreen / seaml. mode</entry>
+                <entry>show popup menu in full screen / seaml. mode</entry>
               </row>
               <row>
                 <entry><computeroutput>SettingsDialog</computeroutput></entry>
@@ -2414,7 +2763,7 @@ VBoxManage setextradata "VM name" VBoxInternal2/CoreDumpLive 1</screen>At
           </tgroup>
         </table>
 
-        <para>To disable the fullscreen mode as well as the seamless mode, use the following command:
+        <para>To disable the full screen mode as well as the seamless mode, use the following command:
           <screen>VBoxManage setextradata global GUI/Input/MachineShortcuts "FullscreenMode=None,SeamlessMode=None"</screen>
         </para>
 
diff --git a/doc/manual/en_US/user_VBoxManage.xml b/doc/manual/en_US/user_VBoxManage.xml
index 8cd65f0..95d6c25 100644
--- a/doc/manual/en_US/user_VBoxManage.xml
+++ b/doc/manual/en_US/user_VBoxManage.xml
@@ -915,7 +915,7 @@ Statistics update:  disabled</screen></para>
             </listitem>
 
             <listitem>
-              <para><computeroutput>--natnatsettings<1-N>
+              <para><computeroutput>--natsettings<1-N>
               [<mtu>],[<socksnd>],[<sockrcv>],[<tcpsnd>],
               [<tcprcv>]</computeroutput>: This option controls several
               NAT settings (please see <xref linkend="nat-adv-settings" /> for
diff --git a/doc/manual/fr_FR/user_AdvancedTopics.xml b/doc/manual/fr_FR/user_AdvancedTopics.xml
index b80a68b..9c00d87 100644
--- a/doc/manual/fr_FR/user_AdvancedTopics.xml
+++ b/doc/manual/fr_FR/user_AdvancedTopics.xml
@@ -3154,62 +3154,68 @@ alice = {
   </sect1>
 
   <sect1 id="hostpowertweaks">
-    <title>Handling of host power management events</title>
+    <title>Prise en charge des événements de gestion de l'énergie de l'hôte</title>
 
-    <para>Some host power management events are handled by VirtualBox. The
-    actual behavior depends on the platform:</para>
+    <para>Certains événements de la gestion d'énergie de l'hôte sont gérés par 
+    VirtualBox. Le comportement dépend en fait de la plateforme :</para>
 
     <para>
       <glosslist>
         <glossentry>
-          <glossterm>Host Suspends</glossterm>
+          <glossterm>Mise en veille prolongée de l'hôte</glossterm>
            <glossdef>
              <para>
-               This event is generated when the host is about to suspend, that is,
-               the host saves the state to some non-volatile storage and powers off.
+               Cet événement est généré quand l'hîte va se mettre en veille prolongée,
+               c'est-à-dire quand l'hôte sauvegarde son état sur un support
+               de stockage non volatile puis s'éteint.
              </para>
              <para>
-               This event is currently only handled on Windows hosts and Mac OS X hosts.
-               When this event is generated, VirtualBox will pause all running VMs.
+               Cet événement n'est actuellement géré que sur les hôtes Windows 
+               et Mac OS X. Quand il est généré, VirtualBox mettra en pause toutes
+               les VMs en fonction.
              </para>
            </glossdef>
          </glossentry>
          <glossentry>
-           <glossterm>Host Resumes</glossterm>
+           <glossterm>Réveil de l'hôte</glossterm>
            <glossdef>
              <para>
-               This event is generated when the host woke up from the suspended
-               state.
+               Cet événement est généré lorsque l'hôte sort d'une mise en veille
+               prolongée.
              </para>
              <para>
-               This event is currently only handled on Windows hosts and Mac OS X hosts.
-               When this event is generated, VirtualBox will resume all VMs which
-               are where paused before.
+               Cet événement n'est actuellement géré que sur les hôtes Windows 
+               et Mac OS X.
+               Quand cet événement est généré, VirtualBox réveillera les VMs qui
+               ont été mises en pause. 
              </para>
            </glossdef>
          </glossentry>
          <glossentry>
-           <glossterm>Battery Low</glossterm>
+           <glossterm>Batterie faible</glossterm>
            <glossdef>
              <para>
-               The battery level reached a critical level (usually less than 5
-               percent charged).
+               Le niveau de la batterie a atteint un seuil critique (en général
+               moins de 5 pour cent de sa charge).
              </para>
              <para>
-               This event is currently only handled on Windows hosts and Mac OS X hosts.
-               When this event is generated, VirtualBox will save the state and
-               terminate all VMs in preperation of a potential host powerdown.
-             </para>
-             <para>The behavior can be configured. By executing the following command,
-             no VM is saved:</para>
+               Cet événement n'est actuellement géré que sur les hôtes Windows 
+               et Mac OS X.
+               Quand cet événement est généré, VirtualBox sauvegardera l'état et
+               terminera toutes les VMs pour préparer une coupure potentielle de
+               l'hôte 
+         </para>
+             <para>Ce comportement est configurable. En utilisant la commande
+             suivante, aucune VM n'est sauvegardé :</para>
              <screen>VBoxManage setextradata global "VBoxInternal2/SavestateOnBatteryLow" 0</screen>
-             <para>This is a global setting as well as a per-VM setting. The per-VM
-               value has higher precedence than the global value. The following command
-               will save the state of all VMs but will not save the state of VM "foo":</para>
+             <para>Il s'agit d'un réglage global ou individuel aux VMs. La valeur
+               individuelle à une VM est prioritaire sur celle globale. La commande
+               suivante sauvegardera l'état de toutes les VMs, sauf celui de la VM
+               "foo" :</para>
              <screen>VBoxManage setextradata global "VBoxInternal2/SavestateOnBatteryLow" 1
 VBoxManage setextradata "foo" "VBoxInternal2/SavestateOnBatteryLow" 0</screen>
-             <para>The first line is actually not required as by default the savestate
-             action is performed.</para>
+             <para>La première ligne n'est pas vraiment obligatoire puisque par
+             défaut, c'est une sauvegarde qui est effectuée.</para>
            </glossdef>
          </glossentry>
        </glosslist>
@@ -3218,33 +3224,35 @@ VBoxManage setextradata "foo" "VBoxInternal2/SavestateOnBatteryLow" 0</screen>
    </sect1>
 
    <sect1 id="sse412passthrough">
-     <title>Experimental support for passing through SSE4.1 / SSE4.2 instructions</title>
+     <title>Support expérimental du passage par des instructions SSE4.1 / SSE4.2</title>
      <para>
-       To provide SSE 4.1 / SSE 4.2 support to guests, the host CPU has to
-       implement these instruction sets. Starting with VirtualBox 4.3.8 it is
-       possible to enable these instructions for certain guests using the
-       following commands:</para><screen>VBoxManage setextradata "VM name" VBoxInternal/CPUM/SSE4.1 1
-VBoxManage setextradata "VM name" VBoxInternal/CPUM/SSE4.2 1</screen>
+       Pour offrir le support des SSE 4.1 / SSE 4.2 aux invités, le processeur
+       de vhôte doit gérer ces jeux d'instructions. A partir de VirtualBox 4.3.8,
+       il est possible d'activer ces instructions pour les invités en utilisant
+       les commandes suivantes :</para><screen>VBoxManage setextradata "VM name" VBoxInternal/CPUM/SSE4.1 1
+VBoxManage setextradata "nom VM" VBoxInternal/CPUM/SSE4.2 1</screen>
      <para>
-       These are a per-VM settings and they are turned off by default.
+       Ces paramètres se règlent par VM et sont désactivés par défaut.
      </para>
    </sect1>
 
   <sect1 id="hidledssync">
-    <title>Support for keyboard indicators synchronization</title>
+    <title>Support de la synchronization des indicateurs du clavier</title>
 
     <para>
-      This feature makes the host keyboard lights match those of the virtual machine's virtual
-      keyboard when the machine window is selected. It is currently implemented for Mac OS X and
-      Windows hosts and available as of releases 4.2.24 and 4.3.8. The feature can be enabled using
-      the following command:
+      Cette fonction permet aux diodes du clavier de correspondre à celles du
+      clavier de la machine virtuelle quand la fenêtre de la machine est active.
+      Elle est supportée pour l'instant sur les hôtes Mac OS X et Windows et
+      elle est disponible à partir des versions 4.2.24 et 4.3.8. Vous pouvez
+      activer cette fonction en utilisant la commande suivante :
     </para>
 
-    <screen>VBoxManage setextradata "VM name" GUI/HidLedsSync "1"</screen>
+    <screen>VBoxManage setextradata "nom VM" GUI/HidLedsSync "1"</screen>
 
     <para>
-      In order to disable it, use the same command but change "1" to "0", or use the VBoxManage
-      command to remove the extra data. This is a per-VM setting and it is disabled by default.
+      Pour la désactiver, utilisez  la même commande mais passez "1" à "0", ou
+      utilisez la commande VBoxManage pour supprimer les données supplémentaires.
+      C'est un paramètre par VM et désactivé par défaut.
     </para>
 
   </sect1>
diff --git a/doc/manual/user_ChangeLogImpl.xml b/doc/manual/user_ChangeLogImpl.xml
index 33eacdc..8c93805 100644
--- a/doc/manual/user_ChangeLogImpl.xml
+++ b/doc/manual/user_ChangeLogImpl.xml
@@ -1,6 +1,118 @@
 <?xml version="1.0" encoding="UTF-8"?>
 
   <sect1>
+    <title>Version 4.3.10 (2014-03-26)</title>
+
+    <para>This is a maintenance release. The following items were fixed and/or
+      added:</para>
+
+    <itemizedlist>
+
+      <listitem>
+        <para>VMM: more work on improving the emulation of certain MSR registers
+          on certain host CPUs (e.g. bugs #12734, #12736, #12744, #12748, #12686,
+          #12770)</para>
+      </listitem>
+
+      <listitem>
+        <para>VMM: fixed single-stepping for real-mode guests (VT-x without
+          unrestricted guest execution) and some I/O instructions (bug #12636)</para>
+      </listitem>
+
+      <listitem>
+        <para>VMM: fixed a potential problem with COW pages if nested paging is
+          not available</para>
+      </listitem>
+
+      <listitem>
+        <para>GUI: Mac OS X: experimental native full screen support for
+          Mountain Lion and Mavericks (bug #12292)</para>
+      </listitem>
+
+      <listitem>
+        <para>GUI: Mac OS X: removed the mini-toolbar minimize button which
+          doesn't work under Mac OS X full screen mode anyway</para>
+      </listitem>
+
+      <listitem>
+        <para>GUI: experimental HID LEDs synchronization for Windows and Mac OS X hosts:
+          fixed keyboard re-synchronization if the feature is disabled (as done by default;
+          bug #12758)</para>
+      </listitem>
+
+      <listitem>
+        <para>GUI: fixed a potential crash when opening the preferences menu
+          (bug #12862)</para>
+      </listitem>
+
+      <listitem>
+        <para>OVF: fixed a crash of the VirtualBox Manager when re-starting guest
+          export (bug #12586)</para>
+      </listitem>
+
+      <listitem>
+        <para>3D support: several fixes</para>
+      </listitem>
+
+      <listitem>
+        <para>HGCM: fixed a problem with saved states which could cause several
+          guest misbehavior after a VM was started from a saved state</para>
+      </listitem>
+
+      <listitem>
+        <para>Storage: fixed a bug preventing to compact differential snapshots
+        under certain conditions</para>
+      </listitem>
+
+      <listitem>
+        <para>VBoxSVC: fixed a segmentation fault on Linux hosts if a very long path
+          exists under /dev (bug #12760)</para>
+      </listitem>
+
+      <listitem>
+        <para>API: fixed guest misbehavior under certain conditions if a storage
+          medium was attached or removed at VM runtime</para>
+      </listitem>
+
+      <listitem>
+        <para>Windows installer: make the <emphasis>--silent</emphasis>
+          parameter work again (bug #12764)</para>
+      </listitem>
+
+      <listitem>
+        <para>Mac OS X Networking: prevent local traffic (VM-to/from-host) from
+          leaking to wire (bug #12750)</para>
+      </listitem>
+
+      <listitem>
+        <para>Windows Additions: fixed the environment for guest processes
+          (4.3.8 regression; bug #12782)</para>
+      </listitem>
+
+      <listitem>
+        <para>Windows Additions/WDDM: fixed divide by zero exception with
+          multiple guest screens under certain conditions</para>
+      </listitem>
+
+      <listitem>
+        <para>Windows Additions/WDDM: fixed crashes with 2D video
+          acceleration enabled (4.3.8 regression; bug #12745)</para>
+      </listitem>
+
+      <listitem>
+        <para>Linux Additions: install correctly on Ubuntu guest systems
+           with a /usr/lib64 directory (bug #12513)</para>
+      </listitem>
+
+      <listitem>
+        <para>X11 Additions: fix for the VBoxClient process not exiting
+           correctly (bug #12348) and consuming too much processor time</para>
+      </listitem>
+
+    </itemizedlist>
+  </sect1>
+
+  <sect1>
     <title>Version 4.3.8 (2014-02-25)</title>
 
     <para>This is a maintenance release. The following items were fixed and/or
@@ -40,7 +152,7 @@
 
       <listitem>
         <para>GUI: make sure that a minimized guest (using mini toolbar in
-          fullscreen/seamless mode) keeps the minimized state (bug #12199)</para>
+          full screen / seamless mode) keeps the minimized state (bug #12199)</para>
       </listitem>
 
       <listitem>
@@ -137,15 +249,15 @@
       </listitem>
 
       <listitem>
-        <para>3D: several fixes, multiscreen fixes (e.g. bug #9124)</para>
+        <para>3D support: several fixes, multiscreen fixes (e.g. bug #9124)</para>
       </listitem>
 
       <listitem>
-        <para>3D: include 3D content in captured videos (bug #12666)</para>
+        <para>3D support: include 3D content in captured videos (bug #12666)</para>
       </listitem>
 
       <listitem>
-        <para>3D: include 3D content in captured screenshot (bug #11758)</para>
+        <para>3D support: include 3D content in captured screenshot (bug #11758)</para>
       </listitem>
 
       <listitem>
@@ -630,7 +742,7 @@
 
       <listitem>
         <para>GUI: fixed guest resize breakage on visual representation mode change
-          (when switching from normal to fullscreen etc)</para>
+          (when switching from normal to full screen etc)</para>
       </listitem>
 
       <listitem>
@@ -1039,6 +1151,260 @@
   </sect1>
 
   <sect1>
+    <title>Version 4.2.22 (2014-01-10)</title>
+
+    <para>This is a maintenance release. The following items were fixed and/or
+      added:</para>
+
+    <itemizedlist>
+
+      <listitem>
+        <para>GUI: Mac OS X host: introduced extradata option "GUI/HidLedsSync" aimed to enable
+          HID LEDs synchronization (feature disabled by default)</para>
+      </listitem>
+
+      <listitem>
+        <para>GUI: Mac OS X host: fixed issue on MacBook Air/Pro hosts when GUI
+          might freeze in attempt to synchronize HID LEDs</para>
+      </listitem>
+
+      <listitem>
+        <para>Main: always expose the DMI memory information to Windows 2012 guests
+          (bug #12017)</para>
+      </listitem>
+
+      <listitem>
+        <para>HGCM: fixed crashes under certain conditions</para>
+      </listitem>
+
+      <listitem>
+        <para>Storage: fix for <emphasis>BLKCACHE_IOERR</emphasis> runtime errors under
+          rare circumstances (bug #11030)</para>
+      </listitem>
+
+      <listitem>
+        <para>AHCI: fixed a bug which resulted in Windows XP guest hangs if a
+          SATA CDROM is attached (bug #12417)</para>
+      </listitem>
+
+      <listitem>
+        <para>AHCI: fixed a Guru Meditation under certain conditions</para>
+      </listitem>
+
+      <listitem>
+        <para>E1000: if the cable was disconnected before the guest initialized
+          the device, the link status was not properly set to 'down' after the
+          initialization completed despite the fact that there was no connection</para>
+      </listitem>
+
+      <listitem>
+        <para>3D support: fixed offset of guest 3D image elements (Mac OS X Retina
+          hosts only; bug #11021)</para>
+      </listitem>
+
+      <listitem>
+        <para>3D support: many fixes</para>
+      </listitem>
+
+      <listitem>
+        <para>Linux Additions: support Enterprise Linux 6.5 kernels
+           (bug #12505)</para>
+      </listitem>
+
+      <listitem>
+        <para>Linux Additions: fixed CPU hot-remove on newer Linux kernels</para>
+      </listitem>
+
+      <listitem>
+        <para>Windows Additions: fixed guest crashes in in Shared Folders
+          service under certain conditions</para>
+      </listitem>
+
+    </itemizedlist>
+
+  </sect1>
+
+  <sect1>
+    <title>Version 4.2.20 (2013-11-28)</title>
+
+    <para>This is a maintenance release. The following items were fixed and/or
+      added:</para>
+
+    <itemizedlist>
+
+      <listitem>
+        <para>GUI: always report recommended resolutions for all monitors
+          (not always done since 4.2.12)</para>
+      </listitem>
+
+      <listitem>
+        <para>GUI: make sure the assigned license and description are attached to
+          the exported appliance</para>
+      </listitem>
+
+      <listitem>
+        <para>GUI: the OS X hot corners were not accessible while a VirtualBox VM
+          is running (Mac OS X hosts only; bug #4139)</para>
+      </listitem>
+
+      <listitem>
+        <para>NAT: don't run into an infinite loop in case the host cannot
+          access any DNS server (4.3.0 regression; bug #12300)</para>
+      </listitem>
+
+      <listitem>
+        <para>NAT: don't re-connect the cable if the DNS information changes
+          and the cable was disconnected before (4.3.0 regression; bug #12225)</para>
+      </listitem>
+
+      <listitem>
+        <para>Main: properly save the <emphasis>passthrough</emphasis> flag for DVD
+          drives without an attached medium</para>
+      </listitem>
+
+      <listitem>
+        <para>Keyboard: fixed a VM crash if a VM was resumed from a saved state
+          where at least one key was pressed (bug #11289)</para>
+      </listitem>
+
+      <listitem>
+        <para>2D Video acceleration: fix crashes on presentation mode switches
+          (bug #9194)</para>
+      </listitem>
+
+      <listitem>
+        <para>Storage: fixed errors with snapshots when using QCOW or QED disk images
+          (bug #12144)</para>
+      </listitem>
+
+      <listitem>
+        <para>Storage: fix for newer Linux kernels not detecting a hard disk as SSD
+          when using the IDE or SATA controller (bug #12025)</para>
+      </listitem>
+
+      <listitem>
+        <para>Storage: fixed detection of CD/DVD media when switching from an empty
+          to a host drive with passthrough enabled</para>
+      </listitem>
+
+      <listitem>
+        <para>Snapshots: fixed a bug which could result in lost medium attachments
+          (4.2.18 regression, bug #11750)</para>
+      </listitem>
+
+      <listitem>
+        <para>Shared Clipboard: fixed potential SEGFAULT when
+          working with UTF8 and UTF16 content (Mac OS X hosts only)</para>
+      </listitem>
+
+      <listitem>
+        <para>OVF: fixed import logic for OVF appliances containing multiple
+          VMs</para>
+      </listitem>
+
+      <listitem>
+        <para>Extpack Installer: make it work if the file is located in a folder with
+          special characters</para>
+      </listitem>
+
+      <listitem>
+        <para>SDK: extended the functionality coverage for the C bindings</para>
+      </listitem>
+
+      <listitem>
+        <para>API: block the removal of the current snapshot if it has child
+           snapshots (only relevant for VMs without snapshottable hard disks,
+           their presence always prevented removal), which resulted in VM
+           config corruption</para>
+      </listitem>
+
+      <listitem>
+        <para>API: mark VM configs with snapshots but without current snapshot
+           as inaccessible, as this combination is nonsense</para>
+      </listitem>
+
+      <listitem>
+        <para>API: fixed information for some automatically generated events
+          (only with XPCOM, Windows host was not affected), which caused
+          errors when getting some of the attributes over the webservice
+          (bug #12379)</para>
+      </listitem>
+
+      <listitem>
+        <para>Mac OS X hosts: support for Mac OS X 10.9 (Mavericks)</para>
+      </listitem>
+
+      <listitem>
+        <para>Mac OS X hosts: properly sign the kernel extensions for
+          Mavericks hosts (bug #12256)</para>
+      </listitem>
+
+      <listitem>
+        <para>Mac OS X hosts: use a launchd script instead of the deprecated
+          StartupItem mechanism (bug #8940)</para>
+      </listitem>
+
+      <listitem>
+        <para>Mac OS X hosts: fixed a bug where the VirtualBox dock icon was
+          not properly removed from the dock after a VM terminated preventing
+          Mavericks hosts from shutting (bug #12241)</para>
+      </listitem>
+
+      <listitem>
+        <para>Linux Additions: Linux 3.13 compile fix (bug #12358)</para>
+      </listitem>
+
+      <listitem>
+        <para>Linux Additions: Linux 3.12 compile fix (bug #12083)</para>
+      </listitem>
+
+      <listitem>
+        <para>Linux Additions: Linux 3.11 fix for shared folders (bugs #11946, #12128)</para>
+      </listitem>
+
+      <listitem>
+        <para>Linux Additions: compile fix for SLES11 SP3</para>
+      </listitem>
+
+      <listitem>
+        <para>Linux Additions: correctly set umask before installing
+           (bug #12166)</para>
+      </listitem>
+
+      <listitem>
+        <para>Linux Additions: build the vboxvideo kernel module correctly on
+           OL/RHEL 6.1 guests (bug #11996)</para>
+      </listitem>
+
+      <listitem>
+        <para>Linux Additions: make 3D work on Slackware 14.1
+           (bug #12320 comments 3 and 4)</para>
+      </listitem>
+
+      <listitem>
+        <para>Windows Additions: fixed memory leak caused by
+          <emphasis>WTSQuerySessionInformation()</emphasis>
+          on Windows 2000 guests (bug #12072)</para>
+      </listitem>
+
+      <listitem>
+        <para>Windows Additions: multimonitor resize fixes</para>
+      </listitem>
+
+      <listitem>
+        <para>X11 Additions/3D: fix freezes starting 3D desktop (bug #11503,
+           thank you Sam Spilsbury)</para>
+      </listitem>
+
+      <listitem>
+        <para>Guest additions/3D: fix an occasional dead-lock (bug #12319)
+           </para>
+      </listitem>
+
+    </itemizedlist>
+  </sect1>
+
+  <sect1>
     <title>Version 4.2.18 (2013-09-06)</title>
 
     <para>This is a maintenance release. The following items were fixed and/or
@@ -1432,7 +1798,7 @@
 
       <listitem>
         <para>GUI: Multi-screen support: seamless mode: fixed a bug when empty seamless
-          screens were represented by fullscreen windows</para>
+          screens were represented by full screen windows</para>
       </listitem>
 
       <listitem>
@@ -1442,7 +1808,7 @@
 
       <listitem>
         <para>GUI: Multi-screen support: machine window View menu should
-          have correct content in seamless/fullscreen mode now (Mac OS X hosts)</para>
+          have correct content in seamless / full screen mode now (Mac OS X hosts)</para>
       </listitem>
 
       <listitem>
@@ -2084,7 +2450,7 @@
       </listitem>
 
       <listitem>
-        <para>GUI: make sure VM receives keyboard focus on entering fullscreen-mode
+        <para>GUI: make sure VM receives keyboard focus on entering full screen mode
           on Win host (bug #11051)</para>
       </listitem>
 
@@ -5455,7 +5821,7 @@
       </listitem>
 
       <listitem>
-        <para>VGA: serveral small fixes for legacy VGA graphics modes</para>
+        <para>VGA: several small fixes for legacy VGA graphics modes</para>
       </listitem>
 
       <listitem>
@@ -9663,7 +10029,7 @@
       </listitem>
 
       <listitem>
-        <para>VMM: fixed guru meditation when booting Novell Netware 4.11 (VT-x only; bug #2898) </para>
+        <para>VMM: fixed guru meditation when booting Novell NetWare 4.11 (VT-x only; bug #2898) </para>
       </listitem>
 
       <listitem>
diff --git a/include/VBox/HostServices/VBoxCrOpenGLSvc.h b/include/VBox/HostServices/VBoxCrOpenGLSvc.h
index 5fd9f2a..e09f9a2 100644
--- a/include/VBox/HostServices/VBoxCrOpenGLSvc.h
+++ b/include/VBox/HostServices/VBoxCrOpenGLSvc.h
@@ -32,6 +32,7 @@
 #include <VBox/VBoxGuest2.h>
 #include <VBox/hgcmsvc.h>
 #include <VBox/VBoxVideo.h>
+#include <VBox/VBoxVideoHost3D.h>
 
 /* crOpenGL host functions */
 #define SHCRGL_HOST_FN_SET_CONSOLE (1)
@@ -44,11 +45,11 @@
 #endif
 #define SHCRGL_HOST_FN_VIEWPORT_CHANGED (15)
 #define SHCRGL_HOST_FN_SET_OUTPUT_REDIRECT (20)
-#define SHCRGL_HOST_FN_CRCMD_NOTIFY_CMDS   (21)
 #define SHCRGL_HOST_FN_DEV_RESIZE          (22)
 #define SHCRGL_HOST_FN_VIEWPORT_CHANGED2 (23)
 #define SHCRGL_HOST_FN_TAKE_SCREENSHOT (24)
 #define SHCRGL_HOST_FN_WINDOWS_SHOW (25)
+#define SHCRGL_HOST_FN_CTL          (26)
 /* crOpenGL guest functions */
 #define SHCRGL_GUEST_FN_WRITE       (2)
 #define SHCRGL_GUEST_FN_READ        (3)
diff --git a/include/VBox/VBoxVideo.h b/include/VBox/VBoxVideo.h
index fcae7eb..9d499e5 100644
--- a/include/VBox/VBoxVideo.h
+++ b/include/VBox/VBoxVideo.h
@@ -852,9 +852,9 @@ typedef struct VBVABUFFER
 #define VBVA_INFO_CAPS   12 /* informs host about HGSMI caps. see VBVACAPS below */
 #define VBVA_SCANLINE_CFG    13 /* configures scanline, see VBVASCANLINECFG below */
 #define VBVA_SCANLINE_INFO   14 /* requests scanline info, see VBVASCANLINEINFO below */
-#define VBVA_CMDVBVA_ENABLE  15 /* enables command ring buffer VBVA */
 #define VBVA_CMDVBVA_SUBMIT  16 /* inform host about VBVA Command submission */
 #define VBVA_CMDVBVA_FLUSH   17 /* inform host about VBVA Command submission */
+#define VBVA_CMDVBVA_CTL     18 /* G->H DMA command             */
 
 /* host->guest commands */
 #define VBVAHG_EVENT              1
@@ -1414,8 +1414,7 @@ typedef struct VBOXVDMACMD_CHILD_STATUS_IRQ
 # pragma pack()
 #endif /* #ifdef VBOX_WITH_VDMA */
 
-#ifdef VBOX_WITH_CRHGSMI
-# pragma pack(1)
+#pragma pack(1)
 typedef struct VBOXVDMACMD_CHROMIUM_BUFFER
 {
     VBOXVIDEOOFFSET offBuffer;
@@ -1439,7 +1438,7 @@ typedef enum
     VBOXVDMACMD_CHROMIUM_CTL_TYPE_SAVESTATE_END,
     VBOXVDMACMD_CHROMIUM_CTL_TYPE_CRHGSMI_SETUP_MAINCB,
     VBOXVDMACMD_CHROMIUM_CTL_TYPE_CRCONNECT,
-    VBOXVDMACMD_CHROMIUM_CTL_TYPE_SIZEHACK = 0xfffffffe
+    VBOXVDMACMD_CHROMIUM_CTL_TYPE_SIZEHACK = 0x7fffffff
 } VBOXVDMACMD_CHROMIUM_CTL_TYPE;
 
 typedef struct VBOXVDMACMD_CHROMIUM_CTL
@@ -1448,24 +1447,12 @@ typedef struct VBOXVDMACMD_CHROMIUM_CTL
     uint32_t cbCmd;
 } VBOXVDMACMD_CHROMIUM_CTL, *PVBOXVDMACMD_CHROMIUM_CTL;
 
-typedef struct VBOXVDMACMD_CHROMIUM_CTL_CRHGSMI_SETUP
-{
-    VBOXVDMACMD_CHROMIUM_CTL Hdr;
-    union
-    {
-        void *pvVRamBase;
-        uint64_t uAlignment;
-    };
-    uint64_t cbVRam;
-    struct VBOXCRCMD_CLTINFO *pCrCmdClientInfo;
-} VBOXVDMACMD_CHROMIUM_CTL_CRHGSMI_SETUP, *PVBOXVDMACMD_CHROMIUM_CTL_CRHGSMI_SETUP;
-
 
 typedef struct PDMIDISPLAYVBVACALLBACKS *HCRHGSMICMDCOMPLETION;
 typedef DECLCALLBACK(int) FNCRHGSMICMDCOMPLETION(HCRHGSMICMDCOMPLETION hCompletion, PVBOXVDMACMD_CHROMIUM_CMD pCmd, int rc);
 typedef FNCRHGSMICMDCOMPLETION *PFNCRHGSMICMDCOMPLETION;
 
-typedef DECLCALLBACK(bool) FNCROGLHASDATA();
+typedef DECLCALLBACK(bool) FNCROGLHASDATA(void);
 typedef FNCROGLHASDATA *PFNCROGLHASDATA;
 
 /* callbacks chrogl gives to main */
@@ -1636,7 +1623,7 @@ typedef struct VBOXCMDVBVA_HDR
         /* result, 0 on success, otherwise contains the failure code TBD */
         int8_t i8Result;
         uint8_t u8PrimaryID;
-    };
+    } u;
     /* DXGK DDI fence ID */
     volatile uint32_t u32FenceID;
 } VBOXCMDVBVA_HDR;
@@ -1668,7 +1655,7 @@ typedef struct VBOXCMDVBVA_ALLOCINFO
     {
         VBOXCMDVBVAOFFSET offVRAM;
         uint32_t id;
-    };
+    } u;
 } VBOXCMDVBVA_ALLOCINFO;
 
 typedef struct VBOXCMDVBVA_RECT
@@ -1723,7 +1710,8 @@ typedef struct VBOXCMDVBVA_CLRFILL
 typedef struct VBOXCMDVBVA_SYSMEMEL
 {
     uint32_t cPagesAfterFirst  : 12;
-    VBOXCMDVBVAPHADDR iPage    : 52;
+    uint32_t iPage1            : 20;
+    uint32_t iPage2;
 } VBOXCMDVBVA_SYSMEMEL;
 
 typedef struct VBOXCMDVBVA_PAGING_TRANSFER
@@ -1745,9 +1733,47 @@ typedef struct VBOXCMDVBVA_PAGING_FILL
     VBOXCMDVBVAOFFSET offVRAM;
 } VBOXCMDVBVA_PAGING_FILL;
 
-# pragma pack()
+#define VBOXCMDVBVACTL_TYPE_ENABLE     1
+#define VBOXCMDVBVACTL_TYPE_3DCTL      2
+
+typedef struct VBOXCMDVBVA_CTL
+{
+    uint32_t u32Type;
+    int32_t i32Result;
+} VBOXCMDVBVA_CTL;
+
+typedef struct VBOXCMDVBVA_CTL_ENABLE
+{
+    VBOXCMDVBVA_CTL Hdr;
+    VBVAENABLE Enable;
+} VBOXCMDVBVA_CTL_ENABLE;
+
+#define VBOXCMDVBVA3DCTL_TYPE_CONNECT     1
+#define VBOXCMDVBVA3DCTL_TYPE_DISCONNECT  2
+#define VBOXCMDVBVA3DCTL_TYPE_CMD         3
+
+typedef struct VBOXCMDVBVA_3DCTL
+{
+    uint32_t u32Type;
+    uint32_t u32CmdClientId;
+} VBOXCMDVBVA_3DCTL;
+
+typedef struct VBOXCMDVBVA_3DCTL_CONNECT
+{
+    VBOXCMDVBVA_3DCTL Hdr;
+    uint32_t u32MajorVersion;
+    uint32_t u32MinorVersion;
+    uint64_t u64Pid;
+} VBOXCMDVBVA_3DCTL_CONNECT;
+
+typedef struct VBOXCMDVBVA_3DCTL_CMD
+{
+    VBOXCMDVBVA_3DCTL Hdr;
+    VBOXCMDVBVA_HDR Cmd;
+} VBOXCMDVBVA_3DCTL_CMD;
+
+#pragma pack()
 
-#endif
 
 #ifdef VBOXVDMA_WITH_VBVA
 # pragma pack(1)
diff --git a/include/VBox/VBoxVideo3D.h b/include/VBox/VBoxVideo3D.h
index 2a04b66..56196dc 100644
--- a/include/VBox/VBoxVideo3D.h
+++ b/include/VBox/VBoxVideo3D.h
@@ -141,36 +141,4 @@ struct VBOXTLSREFDATA_DUMMY
 #define VBOX3D_NOTIFY_EVENT_TYPE_TEST_FUNCTIONAL 3
 
 
-/* interface between the VGA device and 3D Server Backend
- * VGA device and 3D backend work together in processing the VBVA-based ring buffer commands comming from guest.
- * With this interaction VGA device acts like a client, while 3D backend acts as a server.
- * VGA device can process some commands itself, while some of them are delegated to the 3D backend.
- *
- * */
-/* client handle, passed to client callbacks (see below) */
-typedef struct VBOXVDMAHOST *HVBOXCRCMDCLT;
-
-
-typedef struct VBOXCMDVBVA_HDR *PVBOXCMDVBVA_HDR;
-
-/* server queries client for the next command,
- * the obtained command must be returned to the client right after it gets processed,
- * the next PFNVBOXCRCMD_CLT_CMDGET call completes the previously submitted command,
- * Must not be called from the EMT thread.*/
-typedef DECLCALLBACKPTR(int, PFNVBOXCRCMD_CLT_CMDGET)(HVBOXCRCMDCLT hClt, PVBOXCMDVBVA_HDR *ppNextCmd, uint32_t *pcbNextCmd);
-
-struct VBVAINFOSCREEN;
-/* server queries for display mode.*/
-typedef DECLCALLBACKPTR(int, PFNVBOXCRCMD_CLT_DMGET)(HVBOXCRCMDCLT hClt, uint32_t idScreen, struct VBVAINFOSCREEN *pScreen, void **ppvVram);
-
-/* Client callbacks (i.e. those client exposes to the server) */
-typedef struct VBOXCRCMD_CLTINFO
-{
-    HVBOXCRCMDCLT hClient;
-    PFNVBOXCRCMD_CLT_CMDGET pfnCmdGet;
-    PFNVBOXCRCMD_CLT_DMGET pfnDmGet;
-} VBOXCRCMD_CLTINFO;
-
-
-
 #endif /* #ifndef ___VBox_VBoxVideo3D_h */
diff --git a/include/VBox/VBoxVideoHost3D.h b/include/VBox/VBoxVideoHost3D.h
new file mode 100644
index 0000000..21c7da9
--- /dev/null
+++ b/include/VBox/VBoxVideoHost3D.h
@@ -0,0 +1,128 @@
+/** @file
+ *
+ * VirtualBox 3D host inter-components interfaces
+ */
+
+/*
+ * Copyright (C) 2011-2012 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+#ifndef ___VBox_VBoxVideoHost3D_h
+#define ___VBox_VBoxVideoHost3D_h
+#include <iprt/cdefs.h>
+#include <VBox/VBoxVideo.h>
+
+/* screen update instance */
+typedef struct PDMIDISPLAYCONNECTOR *HVBOXCRCMDCLTSCR;
+struct VBVACMDHDR;
+
+typedef struct VBOXCMDVBVA_HDR *PVBOXCMDVBVA_HDR;
+
+typedef DECLCALLBACKPTR(void, PFNVBOXCRCMD_CLTSCR_UPDATE_BEGIN)(HVBOXCRCMDCLTSCR hClt, unsigned u32Screen);
+typedef DECLCALLBACKPTR(void, PFNVBOXCRCMD_CLTSCR_UPDATE_END)(HVBOXCRCMDCLTSCR hClt, unsigned uScreenId, int32_t x, int32_t y, uint32_t cx, uint32_t cy);
+typedef DECLCALLBACKPTR(void, PFNVBOXCRCMD_CLTSCR_UPDATE_PROCESS)(HVBOXCRCMDCLTSCR hClt, unsigned u32Screen, struct VBVACMDHDR *pCmd, size_t cbCmd);
+
+/*client callbacks to be used by the server
+ * when working in the CrCmd mode */
+typedef struct VBOXCRCMD_SVRENABLE_INFO
+{
+    HVBOXCRCMDCLTSCR hCltScr;
+    PFNVBOXCRCMD_CLTSCR_UPDATE_BEGIN pfnCltScrUpdateBegin;
+    PFNVBOXCRCMD_CLTSCR_UPDATE_PROCESS pfnCltScrUpdateProcess;
+    PFNVBOXCRCMD_CLTSCR_UPDATE_END pfnCltScrUpdateEnd;
+} VBOXCRCMD_SVRENABLE_INFO;
+
+typedef void * HVBOXCRCMDSVR;
+
+/* enables the CrCmd interface, thus the hgcm interface gets disabled.
+ * all subsequent calls will be done in the thread Enable was done,
+ * until the Disable is called */
+typedef DECLCALLBACKPTR(int, PFNVBOXCRCMD_SVR_ENABLE)(HVBOXCRCMDSVR hSvr, VBOXCRCMD_SVRENABLE_INFO *pInfo);
+/* Opposite to Enable (see above) */
+typedef DECLCALLBACKPTR(int, PFNVBOXCRCMD_SVR_DISABLE)(HVBOXCRCMDSVR hSvr);
+/* process command */
+typedef DECLCALLBACKPTR(int, PFNVBOXCRCMD_SVR_CMD)(HVBOXCRCMDSVR hSvr, PVBOXCMDVBVA_HDR pCmd, uint32_t cbCmd);
+/* process host control */
+typedef DECLCALLBACKPTR(int, PFNVBOXCRCMD_SVR_HOSTCTL)(HVBOXCRCMDSVR hSvr, uint8_t* pCtl, uint32_t cbCmd);
+/* process guest control */
+typedef DECLCALLBACKPTR(int, PFNVBOXCRCMD_SVR_GUESTCTL)(HVBOXCRCMDSVR hSvr, uint8_t* pCtl, uint32_t cbCmd);
+/* process SaveState */
+typedef DECLCALLBACKPTR(int, PFNVBOXCRCMD_SVR_SAVESTATE)(HVBOXCRCMDSVR hSvr, PSSMHANDLE pSSM);
+/* process LoadState */
+typedef DECLCALLBACKPTR(int, PFNVBOXCRCMD_SVR_LOADSTATE)(HVBOXCRCMDSVR hSvr, PSSMHANDLE pSSM, uint32_t u32Version);
+
+
+typedef struct VBOXCRCMD_SVRINFO
+{
+    HVBOXCRCMDSVR hSvr;
+    PFNVBOXCRCMD_SVR_ENABLE pfnEnable;
+    PFNVBOXCRCMD_SVR_DISABLE pfnDisable;
+    PFNVBOXCRCMD_SVR_CMD pfnCmd;
+    PFNVBOXCRCMD_SVR_HOSTCTL pfnHostCtl;
+    PFNVBOXCRCMD_SVR_GUESTCTL pfnGuestCtl;
+    PFNVBOXCRCMD_SVR_SAVESTATE pfnSaveState;
+    PFNVBOXCRCMD_SVR_LOADSTATE pfnLoadState;
+} VBOXCRCMD_SVRINFO;
+
+
+typedef struct VBOXVDMACMD_CHROMIUM_CTL_CRHGSMI_SETUP
+{
+    VBOXVDMACMD_CHROMIUM_CTL Hdr;
+    union
+    {
+        void *pvVRamBase;
+        uint64_t uAlignment;
+    };
+    uint64_t cbVRam;
+    /* out */
+    struct VBOXCRCMD_SVRINFO CrCmdServerInfo;
+} VBOXVDMACMD_CHROMIUM_CTL_CRHGSMI_SETUP, *PVBOXVDMACMD_CHROMIUM_CTL_CRHGSMI_SETUP;
+
+typedef enum
+{
+    VBOXCRCMDCTL_TYPE_HGCM = 1,
+    VBOXCRCMDCTL_TYPE_DISABLE,
+    VBOXCRCMDCTL_TYPE_ENABLE,
+    VBOXCRCMDCTL_TYPE_32bit = 0x7fffffff
+} VBOXCRCMDCTL_TYPE;
+
+typedef struct VBOXCRCMDCTL
+{
+    VBOXCRCMDCTL_TYPE enmType;
+    uint32_t u32Function;
+    /* not to be used by clients */
+    union
+    {
+        void(*pfnInternal)();
+        void* pvInternal;
+    };
+} VBOXCRCMDCTL;
+
+typedef struct VBOXVDMAHOST * HVBOXCRCMDCTL_REMAINING_HOST_COMMAND;
+
+typedef DECLCALLBACKPTR(uint8_t*, PFNVBOXCRCMDCTL_REMAINING_HOST_COMMAND)(HVBOXCRCMDCTL_REMAINING_HOST_COMMAND hClient, uint32_t *pcbCtl, int prevCmdRc);
+
+typedef struct VBOXCRCMDCTL_ENABLE
+{
+    VBOXCRCMDCTL Hdr;
+    HVBOXCRCMDCTL_REMAINING_HOST_COMMAND hRHCmd;
+    PFNVBOXCRCMDCTL_REMAINING_HOST_COMMAND pfnRHCmd;
+} VBOXCRCMDCTL_ENABLE;
+
+#endif /*#ifndef ___VBox_VBoxVideoHost3D_h*/
diff --git a/include/VBox/log.h b/include/VBox/log.h
index cdf4e11..276caa5 100644
--- a/include/VBox/log.h
+++ b/include/VBox/log.h
@@ -239,6 +239,64 @@ typedef enum LOGGROUP
     LOG_GROUP_IOM,
     /** XPCOM IPC group. */
     LOG_GROUP_IPC,
+    /** lwIP group. */
+    LOG_GROUP_LWIP,
+    /** lwIP group, api_lib.c API_LIB_DEBUG */
+    LOG_GROUP_LWIP_API_LIB,
+    /** lwIP group, api_msg.c API_MSG_DEBUG */
+    LOG_GROUP_LWIP_API_MSG,
+    /** lwIP group, etharp.c ETHARP_DEBUG */
+    LOG_GROUP_LWIP_ETHARP,
+    /** lwIP group, icmp.c ICMP_DEBUG */
+    LOG_GROUP_LWIP_ICMP,
+    /** lwIP group, igmp.c IGMP_DEBUG */
+    LOG_GROUP_LWIP_IGMP,
+    /** lwIP group, inet.c INET_DEBUG */
+    LOG_GROUP_LWIP_INET,
+    /** lwIP group, IP_DEBUG (sic!) */
+    LOG_GROUP_LWIP_IP4,
+    /** lwIP group, ip_frag.c IP_REASS_DEBUG (sic!) */
+    LOG_GROUP_LWIP_IP4_REASS,
+    /** lwIP group, IP6_DEBUG */
+    LOG_GROUP_LWIP_IP6,
+    /** lwIP group, mem.c MEM_DEBUG */
+    LOG_GROUP_LWIP_MEM,
+    /** lwIP group, memp.c MEMP_DEBUG */
+    LOG_GROUP_LWIP_MEMP,
+    /** lwIP group, netif.c NETIF_DEBUG */
+    LOG_GROUP_LWIP_NETIF,
+    /** lwIP group, pbuf.c PBUF_DEBUG */
+    LOG_GROUP_LWIP_PBUF,
+    /** lwIP group, raw.c RAW_DEBUG */
+    LOG_GROUP_LWIP_RAW,
+    /** lwIP group, sockets.c SOCKETS_DEBUG */
+    LOG_GROUP_LWIP_SOCKETS,
+    /** lwIP group, SYS_DEBUG */
+    LOG_GROUP_LWIP_SYS,
+    /** lwIP group, TCP_DEBUG */
+    LOG_GROUP_LWIP_TCP,
+    /** lwIP group, tcpip.c TCPIP_DEBUG */
+    LOG_GROUP_LWIP_TCPIP,
+    /** lwIP group, TCP_CWND_DEBUG (congestion window) */
+    LOG_GROUP_LWIP_TCP_CWND,
+    /** lwIP group, tcp_in.c TCP_FR_DEBUG (fast retransmit) */
+    LOG_GROUP_LWIP_TCP_FR,
+    /** lwIP group, tcp_in.c TCP_INPUT_DEBUG */
+    LOG_GROUP_LWIP_TCP_INPUT,
+    /** lwIP group, tcp_out.c TCP_OUTPUT_DEBUG */
+    LOG_GROUP_LWIP_TCP_OUTPUT,
+    /** lwIP group, TCP_QLEN_DEBUG */
+    LOG_GROUP_LWIP_TCP_QLEN,
+    /** lwIP group, TCP_RST_DEBUG */
+    LOG_GROUP_LWIP_TCP_RST,
+    /** lwIP group, TCP_RTO_DEBUG (retransmit) */
+    LOG_GROUP_LWIP_TCP_RTO,
+    /** lwIP group, tcp_in.c TCP_WND_DEBUG (window updates) */
+    LOG_GROUP_LWIP_TCP_WND,
+    /** lwIP group, timers.c TIMERS_DEBUG */
+    LOG_GROUP_LWIP_TIMERS,
+    /** lwIP group, udp.c UDP_DEBUG */
+    LOG_GROUP_LWIP_UDP,
     /** Main group. */
     LOG_GROUP_MAIN,
     /** Main group, IAdditionsFacility. */
@@ -780,6 +838,35 @@ typedef enum LOGGROUP
     "IEM",          \
     "IOM",          \
     "IPC",          \
+    "LWIP",            \
+    "LWIP_API_LIB",    \
+    "LWIP_API_MSG",    \
+    "LWIP_ETHARP",     \
+    "LWIP_ICMP",       \
+    "LWIP_IGMP",       \
+    "LWIP_INET",       \
+    "LWIP_IP4",        \
+    "LWIP_IP4_REASS",  \
+    "LWIP_IP6",        \
+    "LWIP_MEM",        \
+    "LWIP_MEMP",       \
+    "LWIP_NETIF",      \
+    "LWIP_PBUF",       \
+    "LWIP_RAW",        \
+    "LWIP_SOCKETS",    \
+    "LWIP_SYS",        \
+    "LWIP_TCP",        \
+    "LWIP_TCPIP",      \
+    "LWIP_TCP_CWND",   \
+    "LWIP_TCP_FR",     \
+    "LWIP_TCP_INPUT",  \
+    "LWIP_TCP_OUTPUT", \
+    "LWIP_TCP_QLEN",   \
+    "LWIP_TCP_RST",    \
+    "LWIP_TCP_RTO",    \
+    "LWIP_TCP_WND",    \
+    "LWIP_TIMERS",     \
+    "LWIP_UDP",        \
     "MAIN",         \
     "MAIN_ADDITIONSFACILITY", \
     "MAIN_ADDITIONSSTATECHANGEDEVENT", \
diff --git a/include/VBox/vmm/cpum.h b/include/VBox/vmm/cpum.h
index 0ce5aba..d3ca4c0 100644
--- a/include/VBox/vmm/cpum.h
+++ b/include/VBox/vmm/cpum.h
@@ -676,7 +676,21 @@ VMMDECL(uint32_t)       CPUMGetGuestCPL(PVMCPU pVCpu);
 VMMDECL(CPUMMODE)       CPUMGetGuestMode(PVMCPU pVCpu);
 VMMDECL(uint32_t)       CPUMGetGuestCodeBits(PVMCPU pVCpu);
 VMMDECL(DISCPUMODE)     CPUMGetGuestDisMode(PVMCPU pVCpu);
-VMMDECL(uint64_t)       CPUMGetGuestBusFrequency(PVM pVM);
+VMMDECL(uint64_t)       CPUMGetGuestScalableBusFrequency(PVM pVM);
+
+/** @name Typical scalable bus frequency values.
+ * @{ */
+/** Special internal value indicating that we don't know the frequency.
+ *  @internal  */
+#define CPUM_SBUSFREQ_UNKNOWN       UINT64_C(1)
+#define CPUM_SBUSFREQ_100MHZ        UINT64_C(100000000)
+#define CPUM_SBUSFREQ_133MHZ        UINT64_C(133333333)
+#define CPUM_SBUSFREQ_167MHZ        UINT64_C(166666666)
+#define CPUM_SBUSFREQ_200MHZ        UINT64_C(200000000)
+#define CPUM_SBUSFREQ_267MHZ        UINT64_C(266666666)
+#define CPUM_SBUSFREQ_333MHZ        UINT64_C(333333333)
+#define CPUM_SBUSFREQ_400MHZ        UINT64_C(400000000)
+/** @} */
 
 
 #ifdef IN_RING3
diff --git a/include/VBox/vmm/hm_vmx.h b/include/VBox/vmm/hm_vmx.h
index b499fa3..a84b01c 100644
--- a/include/VBox/vmm/hm_vmx.h
+++ b/include/VBox/vmm/hm_vmx.h
@@ -53,6 +53,46 @@
  * @{
  */
 
+/** @def HMVMXCPU_GST_SET_UPDATED
+ * Sets a guest-state-updated flag.
+ *
+ * @param   pVCpu   Pointer to the VMCPU.
+ * @param   fFlag   The flag to set.
+ */
+#define HMVMXCPU_GST_SET_UPDATED(pVCpu, fFlag)        (ASMAtomicUoOrU32(&(pVCpu)->hm.s.vmx.fUpdatedGuestState, (fFlag)))
+
+/** @def HMVMXCPU_GST_IS_SET
+ * Checks if all the flags in the specified guest-state-updated set is pending.
+ *
+ * @param   pVCpu   Pointer to the VMCPU.
+ * @param   fFlag   The flag to check.
+ */
+#define HMVMXCPU_GST_IS_SET(pVCpu, fFlag)             ((ASMAtomicUoReadU32(&(pVCpu)->hm.s.vmx.fUpdatedGuestState) & (fFlag)) == (fFlag))
+
+/** @def HMVMXCPU_GST_IS_UPDATED
+ * Checks if one or more of the flags in the specified guest-state-updated set
+ * is updated.
+ *
+ * @param   pVCpu   Pointer to the VMCPU.
+ * @param   fFlags  The flags to check for.
+ */
+#define HMVMXCPU_GST_IS_UPDATED(pVCpu, fFlags)        RT_BOOL(ASMAtomicUoReadU32(&(pVCpu)->hm.s.vmx.fUpdatedGuestState) & (fFlags))
+
+/** @def HMVMXCPU_GST_RESET_TO
+ * Resets the guest-state-updated flags to the specified value.
+ *
+ * @param   pVCpu   Pointer to the VMCPU.
+ * @param   fFlags  The new value.
+ */
+#define HMVMXCPU_GST_RESET_TO(pVCpu, fFlags)          (ASMAtomicUoWriteU32(&(pVCpu)->hm.s.vmx.fUpdatedGuestState, (fFlags)))
+
+/** @def HMVMXCPU_GST_VALUE
+ * Returns the current guest-state-updated flags value.
+ *
+ * @param   pVCpu   Pointer to the VMCPU.
+ */
+#define HMVMXCPU_GST_VALUE(pVCpu)                     (ASMAtomicUoReadU32(&(pVCpu)->hm.s.vmx.fUpdatedGuestState))
+
 /** @name Host-state restoration flags.
  * @{
  */
diff --git a/include/VBox/vmm/pdmifs.h b/include/VBox/vmm/pdmifs.h
index 94805d8..913c0dc 100644
--- a/include/VBox/vmm/pdmifs.h
+++ b/include/VBox/vmm/pdmifs.h
@@ -632,6 +632,8 @@ typedef struct VBOXVDMACMD_CHROMIUM_CTL *PVBOXVDMACMD_CHROMIUM_CTL; /* <- chromi
 
 /** Pointer to a display connector interface. */
 typedef struct PDMIDISPLAYCONNECTOR *PPDMIDISPLAYCONNECTOR;
+struct VBOXCRCMDCTL;
+typedef DECLCALLBACKPTR(void, PFNCRCTLCOMPLETION)(struct VBOXCRCMDCTL* pCmd, uint32_t cbCmd, int rc, void *pvCompletion);
 /**
  * Display connector interface (up).
  * Pair with PDMIDISPLAYPORT.
@@ -749,16 +751,16 @@ typedef struct PDMIDISPLAYCONNECTOR
      * @param   pCmd                Video HW Acceleration Command to be processed.
      * @thread  The emulation thread.
      */
-    DECLR3CALLBACKMEMBER(int, pfnCrCmdNotifyCmds, (PPDMIDISPLAYCONNECTOR pInterface));
+    DECLR3CALLBACKMEMBER(void, pfnCrHgsmiCommandProcess, (PPDMIDISPLAYCONNECTOR pInterface, PVBOXVDMACMD_CHROMIUM_CMD pCmd, uint32_t cbCmd));
 
     /**
-     * Process the guest chromium command.
+     * Process the guest chromium control command.
      *
      * @param   pInterface          Pointer to this interface.
      * @param   pCmd                Video HW Acceleration Command to be processed.
      * @thread  The emulation thread.
      */
-    DECLR3CALLBACKMEMBER(void, pfnCrHgsmiCommandProcess, (PPDMIDISPLAYCONNECTOR pInterface, PVBOXVDMACMD_CHROMIUM_CMD pCmd, uint32_t cbCmd));
+    DECLR3CALLBACKMEMBER(void, pfnCrHgsmiControlProcess, (PPDMIDISPLAYCONNECTOR pInterface, PVBOXVDMACMD_CHROMIUM_CTL pCtl, uint32_t cbCtl));
 
     /**
      * Process the guest chromium control command.
@@ -767,7 +769,10 @@ typedef struct PDMIDISPLAYCONNECTOR
      * @param   pCmd                Video HW Acceleration Command to be processed.
      * @thread  The emulation thread.
      */
-    DECLR3CALLBACKMEMBER(void, pfnCrHgsmiControlProcess, (PPDMIDISPLAYCONNECTOR pInterface, PVBOXVDMACMD_CHROMIUM_CTL pCtl, uint32_t cbCtl));
+    DECLR3CALLBACKMEMBER(int, pfnCrHgcmCtlSubmit, (PPDMIDISPLAYCONNECTOR pInterface,
+                                            struct VBOXCRCMDCTL* pCmd, uint32_t cbCmd,
+                                            PFNCRCTLCOMPLETION pfnCompletion,
+                                            void *pvCompletion));
 
     /**
      * The specified screen enters VBVA mode.
@@ -878,7 +883,7 @@ typedef struct PDMIDISPLAYCONNECTOR
     /** @} */
 } PDMIDISPLAYCONNECTOR;
 /** PDMIDISPLAYCONNECTOR interface ID. */
-#define PDMIDISPLAYCONNECTOR_IID                "c7a1b36d-8dfc-421d-b71f-3a0eeaf733e6"
+#define PDMIDISPLAYCONNECTOR_IID                "05ba9649-302e-43dd-b9ff-60b6fb311d97"
 
 
 /** Pointer to a block port interface. */
@@ -3063,6 +3068,11 @@ typedef struct PDMIDISPLAYVBVACALLBACKS
 
     DECLR3CALLBACKMEMBER(int, pfnCrHgsmiControlCompleteAsync, (PPDMIDISPLAYVBVACALLBACKS pInterface,
                                                                PVBOXVDMACMD_CHROMIUM_CTL pCmd, int rc));
+
+    DECLR3CALLBACKMEMBER(int, pfnCrCtlSubmit, (PPDMIDISPLAYVBVACALLBACKS pInterface,
+                                                                   struct VBOXCRCMDCTL* pCmd, uint32_t cbCmd,
+                                                                   PFNCRCTLCOMPLETION pfnCompletion,
+                                                                   void *pvCompletion));
 } PDMIDISPLAYVBVACALLBACKS;
 /** PDMIDISPLAYVBVACALLBACKS  */
 #define PDMIDISPLAYVBVACALLBACKS_IID            "b78b81d2-c821-4e66-96ff-dbafa76343a5"
diff --git a/include/VBox/vmm/ssm.h b/include/VBox/vmm/ssm.h
index a5b47d5..8218930 100644
--- a/include/VBox/vmm/ssm.h
+++ b/include/VBox/vmm/ssm.h
@@ -1165,6 +1165,7 @@ SSMR3RegisterExternal(PUVM pUVM, const char *pszName, uint32_t uInstance, uint32
                       PFNSSMEXTLIVEPREP pfnLivePrep, PFNSSMEXTLIVEEXEC pfnLiveExec, PFNSSMEXTLIVEVOTE pfnLiveVote,
                       PFNSSMEXTSAVEPREP pfnSavePrep, PFNSSMEXTSAVEEXEC pfnSaveExec, PFNSSMEXTSAVEDONE pfnSaveDone,
                       PFNSSMEXTLOADPREP pfnLoadPrep, PFNSSMEXTLOADEXEC pfnLoadExec, PFNSSMEXTLOADDONE pfnLoadDone, void *pvUser);
+VMMR3DECL(int)          SSMR3RegisterStub(PVM pVM, const char *pszName, uint32_t uInstance);
 VMMR3_INT_DECL(int)     SSMR3DeregisterDevice(PVM pVM, PPDMDEVINS pDevIns, const char *pszName, uint32_t uInstance);
 VMMR3_INT_DECL(int)     SSMR3DeregisterDriver(PVM pVM, PPDMDRVINS pDrvIns, const char *pszName, uint32_t uInstance);
 VMMR3DECL(int)          SSMR3DeregisterInternal(PVM pVM, const char *pszName);
diff --git a/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR0LibCrOgl.cpp b/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR0LibCrOgl.cpp
index 3fa03d2..893b471 100644
--- a/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR0LibCrOgl.cpp
+++ b/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR0LibCrOgl.cpp
@@ -91,9 +91,18 @@ DECLVBGL(int) vboxCrCtlConConnect(HVBOXCRCTL hCtl, uint32_t *pu32ClientID)
     RTStrCopy(info.Loc.u.host.achName, sizeof (info.Loc.u.host.achName), "VBoxSharedCrOpenGL");
     rc = vbglDriverIOCtl (&hCtl->driver, VBOXGUEST_IOCTL_HGCM_CONNECT, &info, sizeof (info));
     if (RT_SUCCESS(rc))
-        *pu32ClientID = info.u32ClientID;
-    else
-        *pu32ClientID = 0;
+    {
+        rc = info.result;
+        if (RT_SUCCESS(rc))
+        {
+            Assert(info.u32ClientID);
+            *pu32ClientID = info.u32ClientID;
+            return rc;
+        }
+    }
+
+    Assert(RT_FAILURE(rc));
+    *pu32ClientID = 0;
     return rc;
 }
 
diff --git a/src/VBox/Additions/common/crOpenGL/Makefile.kmk b/src/VBox/Additions/common/crOpenGL/Makefile.kmk
index 42a04d7..9d21e1a 100644
--- a/src/VBox/Additions/common/crOpenGL/Makefile.kmk
+++ b/src/VBox/Additions/common/crOpenGL/Makefile.kmk
@@ -240,7 +240,6 @@ ifdef VBOX_WITH_WDDM
 #
 # VBoxOGL-x86 - x86 VBoxOGL version built for amd64 build
 #
-DLLS.win.amd64 += VBoxOGL-x86
 VBoxOGL-x86_EXTENDS = VBoxOGL
 VBoxOGL-x86_BLD_TRG_ARCH = x86
 VBoxOGL-x86_LIBS = $(VBOX_LIB_IPRT_GUEST_R3_SHARED_X86) \
@@ -468,7 +467,6 @@ ifdef VBOX_WITH_WDDM
 #
 # VBoxOGLarrayspu-x86 - x86 version of VBoxOGLarrayspu built for amd64 build
 #
-DLLS.win.amd64 += VBoxOGLarrayspu-x86
 VBoxOGLarrayspu-x86_EXTENDS = VBoxOGLarrayspu
 VBoxOGLarrayspu-x86_BLD_TRG_ARCH = x86
 VBoxOGLarrayspu-x86_LIBS = $(VBOX_LIB_OGL_CRUTIL_X86) \
@@ -512,7 +510,6 @@ ifdef VBOX_WITH_WDDM
 #
 # VBoxOGLpassthroughspu-x86 - x86 version of VBoxOGLpassthroughspu built for amd64 build
 #
-DLLS.win.amd64 += VBoxOGLpassthroughspu-x86
 VBoxOGLpassthroughspu-x86_EXTENDS = VBoxOGLpassthroughspu
 VBoxOGLpassthroughspu-x86_BLD_TRG_ARCH = x86
 VBoxOGLpassthroughspu-x86_LIBS = $(VBOX_LIB_OGL_CRUTIL_X86)
@@ -594,7 +591,6 @@ ifdef VBOX_WITH_WDDM
 #
 # VBoxOGLpackspu-x86 - x86 version of VBoxOGLpackspu built for amd64 build
 #
-DLLS.win.amd64 += VBoxOGLpackspu-x86
 VBoxOGLpackspu-x86_EXTENDS = VBoxOGLpackspu
 VBoxOGLpackspu-x86_BLD_TRG_ARCH = x86
 VBoxOGLpackspu-x86_LIBS = $(VBOX_LIB_OGL_CRUTIL_X86) \
@@ -671,7 +667,6 @@ ifdef VBOX_WITH_WDDM
 #
 # VBoxOGLfeedbackspu-x86 - x86 version of VBoxOGLfeedbackspu built for amd64 build
 #
-DLLS.win.amd64 += VBoxOGLfeedbackspu-x86
 VBoxOGLfeedbackspu-x86_EXTENDS = VBoxOGLfeedbackspu
 VBoxOGLfeedbackspu-x86_BLD_TRG_ARCH = x86
 VBoxOGLfeedbackspu-x86_LIBS = $(VBOX_LIB_OGL_CRUTIL_X86) \
diff --git a/src/VBox/Additions/linux/installer/vboxadd-x11.sh b/src/VBox/Additions/linux/installer/vboxadd-x11.sh
index 1d87127..7188e4f 100755
--- a/src/VBox/Additions/linux/installer/vboxadd-x11.sh
+++ b/src/VBox/Additions/linux/installer/vboxadd-x11.sh
@@ -1,6 +1,6 @@
 #! /bin/sh
 #
-# Linux Additions X11 setup init script ($Revision: 91688 $)
+# Linux Additions X11 setup init script ($Revision: 92745 $)
 #
 
 #
@@ -38,17 +38,19 @@ cpu=`uname -m`;
 case "$cpu" in
   i[3456789]86|x86)
     cpu="x86"
-    LIB="/usr/lib"
+    lib_candidates="/usr/lib/i386-linux-gnu /usr/lib /lib"
     ;;
   x86_64|amd64)
     cpu="amd64"
-    if test -d "/usr/lib64"; then
-      LIB="/usr/lib64"
-    else
-      LIB="/usr/lib"
-    fi
+    lib_candidates="/usr/lib/x86_64-linux-gnu /usr/lib64 /usr/lib /lib64 /lib"
     ;;
 esac
+for i in $lib_candidates; do
+  if test -d "$i/VBoxGuestAdditions"; then
+    LIB=$i
+    break
+  fi
+done
 
 # Find the version of X installed
 # The last of the three is for the X.org 6.7 included in Fedora Core 2
diff --git a/src/VBox/Additions/x11/VBoxClient/draganddrop.cpp b/src/VBox/Additions/x11/VBoxClient/draganddrop.cpp
index cc44fae..f38a89f 100644
--- a/src/VBox/Additions/x11/VBoxClient/draganddrop.cpp
+++ b/src/VBox/Additions/x11/VBoxClient/draganddrop.cpp
@@ -14,6 +14,9 @@
  * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
  */
 
+#include <errno.h>
+#include <poll.h>
+
 #include <X11/Xlib.h>
 #include <X11/Xatom.h>
 //#include <X11/extensions/XTest.h>
@@ -423,7 +426,6 @@ public:
       , m_hX11Thread(NIL_RTTHREAD)
       , m_hEventSem(NIL_RTSEMEVENT)
       , m_pCurDnD(0)
-      , m_fSrvStopping(false)
     {}
 
     virtual const char *getPidFilePath() { return ".vboxclient-draganddrop.pid"; }
@@ -434,14 +436,13 @@ public:
 
     virtual void cleanup()
     {
-        /* Cleanup */
-        x11DragAndDropTerm();
+        /* Nothing to do, everything should be cleaned up automatically when the
+         * user process/X11 client exits. */
         VbglR3DnDTerm();
     };
 
 private:
     int x11DragAndDropInit();
-    int x11DragAndDropTerm();
     static int hgcmEventThread(RTTHREAD hThread, void *pvUser);
     static int x11EventThread(RTTHREAD hThread, void *pvUser);
 
@@ -474,7 +475,6 @@ private:
     RTTHREAD             m_hX11Thread;
     RTSEMEVENT           m_hEventSem;
     DragInstance        *m_pCurDnD;
-    bool                 m_fSrvStopping;
 
     friend class DragInstance;
 };
@@ -1662,7 +1662,8 @@ int DragAndDropService::run(bool fDaemonised /* = false */)
                     }
                 }
             }
-        } while (!ASMAtomicReadBool(&m_fSrvStopping));
+            XFlush(m_pDisplay);
+        } while (1);
     } while (0);
 
     LogRelFlowFunc(("returning %Rrc\n", rc));
@@ -1698,51 +1699,12 @@ int DragAndDropService::x11DragAndDropInit()
                             "X11-NOTIFY");
     } while (0);
 
-    /* Cleanup on failure */
-    if (RT_FAILURE(rc))
-        x11DragAndDropTerm();
+    /* No clean-up code for now, as we have no good way of testing it and things
+     * should get cleaned up when the user process/X11 client exits. */
 
     return rc;
 }
 
-int DragAndDropService::x11DragAndDropTerm()
-{
-    /* Mark that we are stopping. */
-    ASMAtomicWriteBool(&m_fSrvStopping, true);
-    RTSemEventSignal(m_hEventSem);
-
-    if (m_pDisplay)
-    {
-        /* Send a x11 client messages to the x11 event loop. */
-        XClientMessageEvent m;
-        RT_ZERO(m);
-        m.type         = ClientMessage;
-        m.display      = m_pDisplay;
-        m.window       = None;
-        m.message_type = xAtom(XA_dndstop);
-        m.format       = 32;
-        int xrc = XSendEvent(m_pDisplay, None, True, NoEventMask, reinterpret_cast<XEvent*>(&m));
-        if (RT_UNLIKELY(xrc == 0))
-                DO(("DnD_TERM: error sending xevent\n"));
-    }
-
-    /* We cannot signal the m_hHGCMThread as it is most likely waiting in vbglR3DoIOCtl() */
-    /* Wait for our event threads to stop. */
-    if (m_hX11Thread)
-        RTThreadWait(m_hX11Thread, RT_INDEFINITE_WAIT, NULL);
-    /* Cleanup */
-    /* todo: This doesn't work. The semaphore was interrupted by the user
-     * signal. It is not possible to destroy a semaphore while it is in interrupted state.
-     * According to Frank, the cleanup stuff done here is done _wrong_. We just
-     * should signal the main loop to stop and do the cleanup there. Needs
-     * adoption in all VBoxClient::Service's. */
-//    if (m_hEventSem)
-//        RTSemEventDestroy(m_hEventSem);
-    if (m_pDisplay)
-        XCloseDisplay(m_pDisplay);
-    return VINF_SUCCESS;
-}
-
 /* static */
 int DragAndDropService::hgcmEventThread(RTTHREAD hThread, void *pvUser)
 {
@@ -1762,7 +1724,7 @@ int DragAndDropService::hgcmEventThread(RTTHREAD hThread, void *pvUser)
             if (RT_FAILURE(rc))
                 return rc;
         }
-    } while (!ASMAtomicReadBool(&pThis->m_fSrvStopping));
+    } while (1);
 
     return VINF_SUCCESS;
 }
@@ -1775,24 +1737,17 @@ int DragAndDropService::x11EventThread(RTTHREAD hThread, void *pvUser)
     DnDEvent e;
     do
     {
-        /* Wait for new events. We can't use XIfEvent here, cause this locks
+        /* Wait for new events. We can't use XIfEvent here, because this locks
          * the window connection with a mutex and if no X11 events occurs this
-         * blocks any other calls we made to X11. So instead check for new
-         * events and if there are not any new one, sleep for a certain amount
-         * of time. */
+         * blocks any other calls we made to X11. So instead poll for new events
+         * on the connection file descriptor. */
+        /** @todo Make sure the locking is right - Xlib displays should never be
+         * used from two threads at once. */
         if (XEventsQueued(pThis->m_pDisplay, QueuedAfterFlush) > 0)
         {
             RT_ZERO(e);
             e.type = DnDEvent::X11_Type;
             XNextEvent(pThis->m_pDisplay, &e.x11);
-#if 0
-            /* We never detect the stop event here for some reason */
-            /* Check for a stop message. */
-            if (   e.x11.type == ClientMessage
-                && e.x11.xclient.message_type == xAtom(XA_dndstop))
-                break;
-#endif
-//            if (isDnDRespondEvent(pThis->m_pDisplay, &e.x11, 0))
             {
                 /* Appending makes a copy of the event structure. */
                 pThis->m_eventQueue.append(e);
@@ -1802,8 +1757,21 @@ int DragAndDropService::x11EventThread(RTTHREAD hThread, void *pvUser)
             }
         }
         else
-            RTThreadSleep(25);
-    } while (!ASMAtomicReadBool(&pThis->m_fSrvStopping));
+        {
+            struct pollfd pollFD;
+
+            pollFD.fd = ConnectionNumber(pThis->m_pDisplay);
+            pollFD.events = POLLIN | POLLPRI;
+            if (   (poll(&pollFD, 1, -1) < 0 && errno != EINTR)
+                || pollFD.revents & POLLNVAL)
+            {
+                LogRel(("X11 event thread: poll failed, stopping.\n"));
+                /** @todo Just stop the whole service.  What use is it just
+                 *        to stop one thread? */
+                return RTErrConvertFromErrno(errno);
+            }
+        }
+    } while (1);
 
     return VINF_SUCCESS;
 }
diff --git a/src/VBox/Additions/x11/vboxvideo/Makefile.kmk b/src/VBox/Additions/x11/vboxvideo/Makefile.kmk
index 7dde54c..67c5348 100644
--- a/src/VBox/Additions/x11/vboxvideo/Makefile.kmk
+++ b/src/VBox/Additions/x11/vboxvideo/Makefile.kmk
@@ -376,7 +376,7 @@ ifdef VBOX_USE_SYSTEM_XORG_HEADERS
         /usr/include/libdrm \
         /usr/include/xorg \
         /usr/include/pixman-1
- vboxvideo_drv_system_SOURCES := $(vboxvideo_drv_15_SOURCES)
+ vboxvideo_drv_system_SOURCES := $(vboxvideo_drv_17_SOURCES)
 endif
 
 
diff --git a/src/VBox/Debugger/DBGPlugInLinux.cpp b/src/VBox/Debugger/DBGPlugInLinux.cpp
index 05c27f8..bbe5df3 100644
--- a/src/VBox/Debugger/DBGPlugInLinux.cpp
+++ b/src/VBox/Debugger/DBGPlugInLinux.cpp
@@ -197,13 +197,13 @@ static DECLCALLBACK(bool)  dbgDiggerLinuxProbe(PUVM pUVM, void *pvData)
         DBGFADDRESS KernelAddr;
         DBGFR3AddrFromFlat(pUVM, &KernelAddr, g_au64LnxKernelAddresses[i]);
         DBGFADDRESS HitAddr;
-        static const uint8_t s_abLinuxVersion[] = "Linux version 2.";
+        static const uint8_t s_abLinuxVersion2x[] = "Linux version 2.";
         int rc = DBGFR3MemScan(pUVM, 0, &KernelAddr, LNX_MAX_KERNEL_SIZE, 1,
-                               s_abLinuxVersion, sizeof(s_abLinuxVersion) - 1, &HitAddr);
+                               s_abLinuxVersion2x, sizeof(s_abLinuxVersion2x) - 1, &HitAddr);
         if (RT_SUCCESS(rc))
         {
             char szTmp[128];
-            char const *pszY = &szTmp[sizeof(s_abLinuxVersion) - 1];
+            char const *pszY = &szTmp[sizeof(s_abLinuxVersion2x) - 1];
             rc = DBGFR3MemReadString(pUVM, 0, &HitAddr, szTmp, sizeof(szTmp));
             if (    RT_SUCCESS(rc)
                 &&  *pszY >= '0'
@@ -214,6 +214,23 @@ static DECLCALLBACK(bool)  dbgDiggerLinuxProbe(PUVM pUVM, void *pvData)
                 return true;
             }
         }
+        static const uint8_t s_abLinuxVersion3x[] = "Linux version 3.";
+        rc = DBGFR3MemScan(pUVM, 0, &KernelAddr, LNX_MAX_KERNEL_SIZE, 1,
+                           s_abLinuxVersion3x, sizeof(s_abLinuxVersion3x) - 1, &HitAddr);
+        if (RT_SUCCESS(rc))
+        {
+            char szTmp[128];
+            char const *pszY = &szTmp[sizeof(s_abLinuxVersion3x) - 1];
+            rc = DBGFR3MemReadString(pUVM, 0, &HitAddr, szTmp, sizeof(szTmp));
+            if (    RT_SUCCESS(rc)
+                &&  *pszY >= '0'
+                &&  *pszY <= '9')
+            {
+                pThis->AddrKernelBase  = KernelAddr;
+                pThis->AddrLinuxBanner = HitAddr;
+                return true;
+            }
+        }
     }
     return false;
 }
diff --git a/src/VBox/Devices/EFI/DevEFI.cpp b/src/VBox/Devices/EFI/DevEFI.cpp
index 1400a63..34b4b24 100644
--- a/src/VBox/Devices/EFI/DevEFI.cpp
+++ b/src/VBox/Devices/EFI/DevEFI.cpp
@@ -2241,7 +2241,7 @@ static DECLCALLBACK(int)  efiConstruct(PPDMDEVINS pDevIns, int iInstance, PCFGMN
      */
     pThis->u64TscFrequency = TMCpuTicksPerSecond(PDMDevHlpGetVM(pDevIns));
     pThis->u64CpuFrequency = pThis->u64TscFrequency;
-    pThis->u64FsbFrequency = CPUMGetGuestBusFrequency(PDMDevHlpGetVM(pDevIns));
+    pThis->u64FsbFrequency = CPUMGetGuestScalableBusFrequency(PDMDevHlpGetVM(pDevIns));
 
     /*
      * GOP graphics.
diff --git a/src/VBox/Devices/EFI/FirmwareBin/VBoxEFI32.fd b/src/VBox/Devices/EFI/FirmwareBin/VBoxEFI32.fd
index 22c648a..dd8f846 100644
Binary files a/src/VBox/Devices/EFI/FirmwareBin/VBoxEFI32.fd and b/src/VBox/Devices/EFI/FirmwareBin/VBoxEFI32.fd differ
diff --git a/src/VBox/Devices/EFI/FirmwareBin/VBoxEFI64.fd b/src/VBox/Devices/EFI/FirmwareBin/VBoxEFI64.fd
index eab9b08..d64748c 100644
Binary files a/src/VBox/Devices/EFI/FirmwareBin/VBoxEFI64.fd and b/src/VBox/Devices/EFI/FirmwareBin/VBoxEFI64.fd differ
diff --git a/src/VBox/Devices/Graphics/BIOS/VBoxVgaBiosAlternative.asm b/src/VBox/Devices/Graphics/BIOS/VBoxVgaBiosAlternative.asm
index 850c34f..183842b 100644
--- a/src/VBox/Devices/Graphics/BIOS/VBoxVgaBiosAlternative.asm
+++ b/src/VBox/Devices/Graphics/BIOS/VBoxVgaBiosAlternative.asm
@@ -1642,7 +1642,7 @@ vga_read_char_attr_:                         ; 0xc0acb LB 0xa8
     call 02f93h                               ; e8 73 24
     movzx bx, ch                              ; 0f b6 dd
     sal bx, 003h                              ; c1 e3 03
-    cmp byte [bx+0482fh], 000h                ; 80 bf 2f 48 00
+    cmp byte [bx+04830h], 000h                ; 80 bf 30 48 00
     jne short 00b5ah                          ; 75 2d
     mov dx, ax                                ; 89 c2
     imul dx, di                               ; 0f af d7
@@ -1658,7 +1658,7 @@ vga_read_char_attr_:                         ; 0xc0acb LB 0xa8
     add ax, ax                                ; 01 c0
     mov dx, cx                                ; 89 ca
     add dx, ax                                ; 01 c2
-    mov ax, word [bx+04832h]                  ; 8b 87 32 48
+    mov ax, word [bx+04833h]                  ; 8b 87 33 48
     call 02f93h                               ; e8 3c 24
     mov word [ss:si], ax                      ; 36 89 04
     lea sp, [bp-008h]                         ; 8d 66 f8
@@ -1724,18 +1724,18 @@ vga_get_font_info_:                          ; 0xc0b73 LB 0x82
     retn 00002h                               ; c2 02 00
     mov dx, 0010ch                            ; ba 0c 01
     jmp short 00b91h                          ; eb bf
-    mov ax, 05daeh                            ; b8 ae 5d
+    mov ax, 05dafh                            ; b8 af 5d
     mov dx, 0c000h                            ; ba 00 c0
     jmp short 00b96h                          ; eb bc
-    mov ax, 055aeh                            ; b8 ae 55
+    mov ax, 055afh                            ; b8 af 55
     jmp short 00bd5h                          ; eb f6
-    mov ax, 059aeh                            ; b8 ae 59
+    mov ax, 059afh                            ; b8 af 59
     jmp short 00bd5h                          ; eb f1
-    mov ax, 07baeh                            ; b8 ae 7b
+    mov ax, 07bafh                            ; b8 af 7b
     jmp short 00bd5h                          ; eb ec
-    mov ax, 06baeh                            ; b8 ae 6b
+    mov ax, 06bafh                            ; b8 af 6b
     jmp short 00bd5h                          ; eb e7
-    mov ax, 07cdbh                            ; b8 db 7c
+    mov ax, 07cdch                            ; b8 dc 7c
     jmp short 00bd5h                          ; eb e2
     jmp short 00bc4h                          ; eb cf
 vga_read_pixel_:                             ; 0xc0bf5 LB 0x139
@@ -1757,9 +1757,9 @@ vga_read_pixel_:                             ; 0xc0bf5 LB 0x139
     je near 00d27h                            ; 0f 84 0d 01
     movzx bx, al                              ; 0f b6 d8
     sal bx, 003h                              ; c1 e3 03
-    cmp byte [bx+0482fh], 000h                ; 80 bf 2f 48 00
+    cmp byte [bx+04830h], 000h                ; 80 bf 30 48 00
     je near 00d27h                            ; 0f 84 fe 00
-    mov bl, byte [bx+04830h]                  ; 8a 9f 30 48
+    mov bl, byte [bx+04831h]                  ; 8a 9f 31 48
     cmp bl, 003h                              ; 80 fb 03
     jc short 00c43h                           ; 72 11
     jbe short 00c4bh                          ; 76 17
@@ -1818,7 +1818,7 @@ vga_read_pixel_:                             ; 0xc0bf5 LB 0x139
     call 02f77h                               ; e8 b4 22
     movzx bx, cl                              ; 0f b6 d9
     sal bx, 003h                              ; c1 e3 03
-    cmp byte [bx+04831h], 002h                ; 80 bf 31 48 02
+    cmp byte [bx+04832h], 002h                ; 80 bf 32 48 02
     jne short 00cebh                          ; 75 1b
     mov cx, si                                ; 89 f1
     xor ch, ch                                ; 30 ed
@@ -2119,7 +2119,7 @@ biosfn_set_active_page_:                     ; 0xc0f00 LB 0xdc
     movzx bx, ch                              ; 0f b6 dd
     mov si, bx                                ; 89 de
     sal si, 003h                              ; c1 e6 03
-    cmp byte [si+0482fh], 000h                ; 80 bc 2f 48 00
+    cmp byte [si+04830h], 000h                ; 80 bc 30 48 00
     jne short 00f83h                          ; 75 40
     mov dx, strict word 0004ah                ; ba 4a 00
     mov ax, strict word 00040h                ; b8 40 00
@@ -2146,10 +2146,10 @@ biosfn_set_active_page_:                     ; 0xc0f00 LB 0xdc
     lea bx, [si+001h]                         ; 8d 5c 01
     imul bx, di                               ; 0f af df
     jmp short 00f95h                          ; eb 12
-    movzx bx, byte [bx+048aeh]                ; 0f b6 9f ae 48
+    movzx bx, byte [bx+048afh]                ; 0f b6 9f af 48
     sal bx, 006h                              ; c1 e3 06
     movzx ax, cl                              ; 0f b6 c1
-    mov bx, word [bx+048c5h]                  ; 8b 9f c5 48
+    mov bx, word [bx+048c6h]                  ; 8b 9f c6 48
     imul bx, ax                               ; 0f af d8
     mov dx, strict word 00063h                ; ba 63 00
     mov ax, strict word 00040h                ; b8 40 00
@@ -2214,15 +2214,15 @@ biosfn_set_video_mode_:                      ; 0xc0fdc LB 0x387
     cmp AL, strict byte 0ffh                  ; 3c ff
     je near 01359h                            ; 0f 84 43 03
     movzx si, al                              ; 0f b6 f0
-    mov al, byte [si+048aeh]                  ; 8a 84 ae 48
+    mov al, byte [si+048afh]                  ; 8a 84 af 48
     mov byte [bp-00ch], al                    ; 88 46 f4
     movzx bx, al                              ; 0f b6 d8
     sal bx, 006h                              ; c1 e3 06
-    movzx ax, byte [bx+048c2h]                ; 0f b6 87 c2 48
-    mov word [bp-018h], ax                    ; 89 46 e8
     movzx ax, byte [bx+048c3h]                ; 0f b6 87 c3 48
-    mov word [bp-016h], ax                    ; 89 46 ea
+    mov word [bp-018h], ax                    ; 89 46 e8
     movzx ax, byte [bx+048c4h]                ; 0f b6 87 c4 48
+    mov word [bp-016h], ax                    ; 89 46 ea
+    movzx ax, byte [bx+048c5h]                ; 0f b6 87 c5 48
     mov word [bp-014h], ax                    ; 89 46 ec
     mov dx, 00087h                            ; ba 87 00
     mov ax, strict word 00040h                ; b8 40 00
@@ -2238,13 +2238,13 @@ biosfn_set_video_mode_:                      ; 0xc0fdc LB 0x387
     jne near 010ebh                           ; 0f 85 8a 00
     mov bx, si                                ; 89 f3
     sal bx, 003h                              ; c1 e3 03
-    mov al, byte [bx+04834h]                  ; 8a 87 34 48
+    mov al, byte [bx+04835h]                  ; 8a 87 35 48
     mov dx, 003c6h                            ; ba c6 03
     out DX, AL                                ; ee
     xor al, al                                ; 30 c0
     mov dx, 003c8h                            ; ba c8 03
     out DX, AL                                ; ee
-    mov bl, byte [bx+04835h]                  ; 8a 9f 35 48
+    mov bl, byte [bx+04836h]                  ; 8a 9f 36 48
     cmp bl, 001h                              ; 80 fb 01
     jc short 0108bh                           ; 72 0e
     jbe short 01094h                          ; 76 15
@@ -2255,13 +2255,13 @@ biosfn_set_video_mode_:                      ; 0xc0fdc LB 0x387
     jmp short 010a1h                          ; eb 16
     test bl, bl                               ; 84 db
     jne short 010a1h                          ; 75 12
-    mov di, 05042h                            ; bf 42 50
+    mov di, 05043h                            ; bf 43 50
     jmp short 010a1h                          ; eb 0d
-    mov di, 05102h                            ; bf 02 51
+    mov di, 05103h                            ; bf 03 51
     jmp short 010a1h                          ; eb 08
-    mov di, 051c2h                            ; bf c2 51
+    mov di, 051c3h                            ; bf c3 51
     jmp short 010a1h                          ; eb 03
-    mov di, 05282h                            ; bf 82 52
+    mov di, 05283h                            ; bf 83 52
     xor bx, bx                                ; 31 db
     jmp short 010b4h                          ; eb 0f
     xor al, al                                ; 30 c0
@@ -2274,8 +2274,8 @@ biosfn_set_video_mode_:                      ; 0xc0fdc LB 0x387
     jnc short 010deh                          ; 73 2a
     movzx si, byte [bp-012h]                  ; 0f b6 76 ee
     sal si, 003h                              ; c1 e6 03
-    movzx si, byte [si+04835h]                ; 0f b6 b4 35 48
-    movzx dx, byte [si+048beh]                ; 0f b6 94 be 48
+    movzx si, byte [si+04836h]                ; 0f b6 b4 36 48
+    movzx dx, byte [si+048bfh]                ; 0f b6 94 bf 48
     cmp bx, dx                                ; 39 d3
     jnbe short 010a5h                         ; 77 dc
     imul si, bx, strict byte 00003h           ; 6b f3 03
@@ -2307,7 +2307,7 @@ biosfn_set_video_mode_:                      ; 0xc0fdc LB 0x387
     movzx si, byte [bp-00ch]                  ; 0f b6 76 f4
     sal si, 006h                              ; c1 e6 06
     add si, bx                                ; 01 de
-    mov al, byte [si+048e5h]                  ; 8a 84 e5 48
+    mov al, byte [si+048e6h]                  ; 8a 84 e6 48
     out DX, AL                                ; ee
     inc bx                                    ; 43
     jmp short 010f5h                          ; eb e4
@@ -2331,7 +2331,7 @@ biosfn_set_video_mode_:                      ; 0xc0fdc LB 0x387
     movzx si, byte [bp-00ch]                  ; 0f b6 76 f4
     sal si, 006h                              ; c1 e6 06
     add si, bx                                ; 01 de
-    mov al, byte [si+048c6h]                  ; 8a 84 c6 48
+    mov al, byte [si+048c7h]                  ; 8a 84 c7 48
     mov dx, 003c5h                            ; ba c5 03
     out DX, AL                                ; ee
     inc bx                                    ; 43
@@ -2346,14 +2346,14 @@ biosfn_set_video_mode_:                      ; 0xc0fdc LB 0x387
     movzx si, byte [bp-00ch]                  ; 0f b6 76 f4
     sal si, 006h                              ; c1 e6 06
     add si, bx                                ; 01 de
-    mov al, byte [si+048f9h]                  ; 8a 84 f9 48
+    mov al, byte [si+048fah]                  ; 8a 84 fa 48
     mov dx, 003cfh                            ; ba cf 03
     out DX, AL                                ; ee
     inc bx                                    ; 43
     jmp short 0114ch                          ; eb e1
     movzx bx, byte [bp-012h]                  ; 0f b6 5e ee
     sal bx, 003h                              ; c1 e3 03
-    cmp byte [bx+04830h], 001h                ; 80 bf 30 48 01
+    cmp byte [bx+04831h], 001h                ; 80 bf 31 48 01
     jne short 0117eh                          ; 75 05
     mov dx, 003b4h                            ; ba b4 03
     jmp short 01181h                          ; eb 03
@@ -2373,12 +2373,12 @@ biosfn_set_video_mode_:                      ; 0xc0fdc LB 0x387
     mov di, cx                                ; 89 cf
     add di, bx                                ; 01 df
     lea dx, [si+001h]                         ; 8d 54 01
-    mov al, byte [di+048cch]                  ; 8a 85 cc 48
+    mov al, byte [di+048cdh]                  ; 8a 85 cd 48
     out DX, AL                                ; ee
     inc bx                                    ; 43
     jmp short 0118bh                          ; eb e0
     mov bx, cx                                ; 89 cb
-    mov al, byte [bx+048cbh]                  ; 8a 87 cb 48
+    mov al, byte [bx+048cch]                  ; 8a 87 cc 48
     mov dx, 003c2h                            ; ba c2 03
     out DX, AL                                ; ee
     mov AL, strict byte 020h                  ; b0 20
@@ -2392,9 +2392,9 @@ biosfn_set_video_mode_:                      ; 0xc0fdc LB 0x387
     jne short 01226h                          ; 75 5f
     movzx bx, byte [bp-012h]                  ; 0f b6 5e ee
     sal bx, 003h                              ; c1 e3 03
-    cmp byte [bx+0482fh], 000h                ; 80 bf 2f 48 00
+    cmp byte [bx+04830h], 000h                ; 80 bf 30 48 00
     jne short 011e8h                          ; 75 13
-    mov es, [bx+04832h]                       ; 8e 87 32 48
+    mov es, [bx+04833h]                       ; 8e 87 33 48
     mov cx, 04000h                            ; b9 00 40
     mov ax, 00720h                            ; b8 20 07
     xor di, di                                ; 31 ff
@@ -2404,7 +2404,7 @@ biosfn_set_video_mode_:                      ; 0xc0fdc LB 0x387
     jmp short 01226h                          ; eb 3e
     cmp byte [bp-00eh], 00dh                  ; 80 7e f2 0d
     jnc short 01200h                          ; 73 12
-    mov es, [bx+04832h]                       ; 8e 87 32 48
+    mov es, [bx+04833h]                       ; 8e 87 33 48
     mov cx, 04000h                            ; b9 00 40
     xor ax, ax                                ; 31 c0
     xor di, di                                ; 31 ff
@@ -2422,7 +2422,7 @@ biosfn_set_video_mode_:                      ; 0xc0fdc LB 0x387
     mov word [bp-01ah], ax                    ; 89 46 e6
     mov AL, strict byte 00fh                  ; b0 0f
     out DX, AL                                ; ee
-    mov es, [bx+04832h]                       ; 8e 87 32 48
+    mov es, [bx+04833h]                       ; 8e 87 33 48
     mov cx, 08000h                            ; b9 00 80
     xor ax, ax                                ; 31 c0
     xor di, di                                ; 31 ff
@@ -2441,7 +2441,7 @@ biosfn_set_video_mode_:                      ; 0xc0fdc LB 0x387
     call 02fa1h                               ; e8 62 1d
     movzx bx, byte [bp-00ch]                  ; 0f b6 5e f4
     sal bx, 006h                              ; c1 e3 06
-    mov bx, word [bx+048c5h]                  ; 8b 9f c5 48
+    mov bx, word [bx+048c6h]                  ; 8b 9f c6 48
     mov dx, strict word 0004ch                ; ba 4c 00
     mov ax, strict word 00040h                ; b8 40 00
     call 02fa1h                               ; e8 4e 1d
@@ -2480,7 +2480,7 @@ biosfn_set_video_mode_:                      ; 0xc0fdc LB 0x387
     mov ax, strict word 00040h                ; b8 40 00
     call 02f85h                               ; e8 ce 1c
     mov cx, ds                                ; 8c d9
-    mov bx, 05592h                            ; bb 92 55
+    mov bx, 05593h                            ; bb 93 55
     mov dx, 000a8h                            ; ba a8 00
     mov ax, strict word 00040h                ; b8 40 00
     call 02fc1h                               ; e8 fc 1c
@@ -2494,7 +2494,7 @@ biosfn_set_video_mode_:                      ; 0xc0fdc LB 0x387
     call 02f85h                               ; e8 aa 1c
     movzx bx, byte [bp-012h]                  ; 0f b6 5e ee
     sal bx, 003h                              ; c1 e3 03
-    cmp byte [bx+0482fh], 000h                ; 80 bf 2f 48 00
+    cmp byte [bx+04830h], 000h                ; 80 bf 30 48 00
     jne short 012f2h                          ; 75 09
     mov dx, strict word 00007h                ; ba 07 00
     mov ax, strict word 00006h                ; b8 06 00
@@ -2512,7 +2512,7 @@ biosfn_set_video_mode_:                      ; 0xc0fdc LB 0x387
     call 00f00h                               ; e8 f5 fb
     movzx bx, byte [bp-012h]                  ; 0f b6 5e ee
     sal bx, 003h                              ; c1 e3 03
-    cmp byte [bx+0482fh], 000h                ; 80 bf 2f 48 00
+    cmp byte [bx+04830h], 000h                ; 80 bf 30 48 00
     jne short 01329h                          ; 75 10
     xor bl, bl                                ; 30 db
     mov AL, strict byte 004h                  ; b0 04
@@ -2522,7 +2522,7 @@ biosfn_set_video_mode_:                      ; 0xc0fdc LB 0x387
     mov AL, strict byte 003h                  ; b0 03
     mov AH, strict byte 011h                  ; b4 11
     int 010h                                  ; cd 10
-    mov dx, 059aeh                            ; ba ae 59
+    mov dx, 059afh                            ; ba af 59
     mov ax, strict word 0001fh                ; b8 1f 00
     call 00a00h                               ; e8 ce f6
     mov ax, word [bp-014h]                    ; 8b 46 ec
@@ -2532,13 +2532,13 @@ biosfn_set_video_mode_:                      ; 0xc0fdc LB 0x387
     je short 0134fh                           ; 74 10
     cmp ax, strict word 00008h                ; 3d 08 00
     jne short 01359h                          ; 75 15
-    mov dx, 055aeh                            ; ba ae 55
+    mov dx, 055afh                            ; ba af 55
     mov ax, strict word 00043h                ; b8 43 00
     call 00a00h                               ; e8 b3 f6
     jmp short 01359h                          ; eb 0a
-    mov dx, 05daeh                            ; ba ae 5d
+    mov dx, 05dafh                            ; ba af 5d
     jmp short 01347h                          ; eb f3
-    mov dx, 06baeh                            ; ba ae 6b
+    mov dx, 06bafh                            ; ba af 6b
     jmp short 01347h                          ; eb ee
     lea sp, [bp-00ah]                         ; 8d 66 f6
     pop di                                    ; 5f
@@ -2848,7 +2848,7 @@ biosfn_scroll_:                              ; 0xc1568 LB 0x506
     mov word [bp-01ah], ax                    ; 89 46 e6
     mov ax, word [bp-016h]                    ; 8b 46 ea
     imul ax, cx                               ; 0f af c1
-    cmp byte [di+0482fh], 000h                ; 80 bd 2f 48 00
+    cmp byte [di+04830h], 000h                ; 80 bd 30 48 00
     jne near 017c7h                           ; 0f 85 9f 01
     mov dx, ax                                ; 89 c2
     add dx, ax                                ; 01 c2
@@ -2871,7 +2871,7 @@ biosfn_scroll_:                              ; 0xc1568 LB 0x506
     movzx dx, byte [bp-00ch]                  ; 0f b6 56 f4
     sal dx, 008h                              ; c1 e2 08
     add dx, strict byte 00020h                ; 83 c2 20
-    mov es, [di+04832h]                       ; 8e 85 32 48
+    mov es, [di+04833h]                       ; 8e 85 33 48
     mov cx, ax                                ; 89 c1
     mov ax, dx                                ; 89 d0
     mov di, bx                                ; 89 df
@@ -2905,7 +2905,7 @@ biosfn_scroll_:                              ; 0xc1568 LB 0x506
     add di, dx                                ; 01 d7
     movzx si, byte [bp-00eh]                  ; 0f b6 76 f2
     sal si, 003h                              ; c1 e6 03
-    mov es, [si+04832h]                       ; 8e 84 32 48
+    mov es, [si+04833h]                       ; 8e 84 33 48
     cld                                       ; fc
     jcxz 016d3h                               ; e3 02
     rep stosw                                 ; f3 ab
@@ -2919,7 +2919,7 @@ biosfn_scroll_:                              ; 0xc1568 LB 0x506
     add dx, dx                                ; 01 d2
     movzx si, byte [bp-00eh]                  ; 0f b6 76 f2
     sal si, 003h                              ; c1 e6 03
-    mov ax, word [si+04832h]                  ; 8b 84 32 48
+    mov ax, word [si+04833h]                  ; 8b 84 33 48
     mov si, word [bp-014h]                    ; 8b 76 ec
     imul si, word [bp-016h]                   ; 0f af 76 ea
     add cx, si                                ; 01 f1
@@ -2963,7 +2963,7 @@ biosfn_scroll_:                              ; 0xc1568 LB 0x506
     add di, dx                                ; 01 d7
     movzx si, byte [bp-00eh]                  ; 0f b6 76 f2
     sal si, 003h                              ; c1 e6 03
-    mov es, [si+04832h]                       ; 8e 84 32 48
+    mov es, [si+04833h]                       ; 8e 84 33 48
     cld                                       ; fc
     jcxz 01774h                               ; e3 02
     rep stosw                                 ; f3 ab
@@ -2978,7 +2978,7 @@ biosfn_scroll_:                              ; 0xc1568 LB 0x506
     add dx, dx                                ; 01 d2
     movzx si, byte [bp-00eh]                  ; 0f b6 76 f2
     sal si, 003h                              ; c1 e6 03
-    mov ax, word [si+04832h]                  ; 8b 84 32 48
+    mov ax, word [si+04833h]                  ; 8b 84 33 48
     mov si, word [bp-014h]                    ; 8b 76 ec
     imul si, word [bp-016h]                   ; 0f af 76 ea
     add di, si                                ; 01 f7
@@ -2998,11 +2998,11 @@ biosfn_scroll_:                              ; 0xc1568 LB 0x506
     jc near 01a65h                            ; 0f 82 a4 02
     dec word [bp-014h]                        ; ff 4e ec
     jmp near 01723h                           ; e9 5c ff
-    movzx bx, byte [si+048aeh]                ; 0f b6 9c ae 48
+    movzx bx, byte [si+048afh]                ; 0f b6 9c af 48
     sal bx, 006h                              ; c1 e3 06
-    mov dl, byte [bx+048c4h]                  ; 8a 97 c4 48
+    mov dl, byte [bx+048c5h]                  ; 8a 97 c5 48
     mov byte [bp-00ah], dl                    ; 88 56 f6
-    mov bl, byte [di+04830h]                  ; 8a 9d 30 48
+    mov bl, byte [di+04831h]                  ; 8a 9d 31 48
     cmp bl, 004h                              ; 80 fb 04
     je short 017eeh                           ; 74 0f
     cmp bl, 003h                              ; 80 fb 03
@@ -3035,7 +3035,7 @@ biosfn_scroll_:                              ; 0xc1568 LB 0x506
     movzx ax, byte [bp-00ch]                  ; 0f b6 46 f4
     movzx bx, byte [bp-00eh]                  ; 0f b6 5e f2
     sal bx, 003h                              ; c1 e3 03
-    mov es, [bx+04832h]                       ; 8e 87 32 48
+    mov es, [bx+04833h]                       ; 8e 87 33 48
     xor di, di                                ; 31 ff
     cld                                       ; fc
     jcxz 0183fh                               ; e3 02
@@ -3117,7 +3117,7 @@ biosfn_scroll_:                              ; 0xc1568 LB 0x506
     jc near 01a65h                            ; 0f 82 3d 01
     dec word [bp-014h]                        ; ff 4e ec
     jmp short 018bch                          ; eb 8f
-    mov dl, byte [di+04831h]                  ; 8a 95 31 48
+    mov dl, byte [di+04832h]                  ; 8a 95 32 48
     cmp byte [bp-010h], 000h                  ; 80 7e f0 00
     jne short 01974h                          ; 75 3d
     cmp byte [bp-008h], 000h                  ; 80 7e f8 00
@@ -3135,7 +3135,7 @@ biosfn_scroll_:                              ; 0xc1568 LB 0x506
     movzx cx, dl                              ; 0f b6 ca
     imul cx, ax                               ; 0f af c8
     movzx ax, byte [bp-00ch]                  ; 0f b6 46 f4
-    mov es, [di+04832h]                       ; 8e 85 32 48
+    mov es, [di+04833h]                       ; 8e 85 33 48
     xor di, di                                ; 31 ff
     cld                                       ; fc
     jcxz 01971h                               ; e3 02
@@ -3237,11 +3237,11 @@ write_gfx_char_pl4_:                         ; 0xc1a6e LB 0xeb
     je short 01a8ch                           ; 74 0b
     cmp byte [bp+006h], 00eh                  ; 80 7e 06 0e
     jne short 01a91h                          ; 75 0a
-    mov di, 05daeh                            ; bf ae 5d
+    mov di, 05dafh                            ; bf af 5d
     jmp short 01a94h                          ; eb 08
-    mov di, 06baeh                            ; bf ae 6b
+    mov di, 06bafh                            ; bf af 6b
     jmp short 01a94h                          ; eb 03
-    mov di, 055aeh                            ; bf ae 55
+    mov di, 055afh                            ; bf af 55
     movzx si, cl                              ; 0f b6 f1
     movzx bx, byte [bp+006h]                  ; 0f b6 5e 06
     imul si, bx                               ; 0f af f3
@@ -3328,7 +3328,7 @@ write_gfx_char_cga_:                         ; 0xc1b59 LB 0x11e
     push di                                   ; 57
     sub sp, strict byte 00008h                ; 83 ec 08
     mov byte [bp-008h], dl                    ; 88 56 f8
-    mov si, 055aeh                            ; be ae 55
+    mov si, 055afh                            ; be af 55
     xor bh, bh                                ; 30 ff
     movzx di, byte [bp+006h]                  ; 0f b6 7e 06
     imul di, bx                               ; 0f af fb
@@ -3442,7 +3442,7 @@ write_gfx_char_lin_:                         ; 0xc1c77 LB 0x91
     push di                                   ; 57
     sub sp, strict byte 00008h                ; 83 ec 08
     mov byte [bp-006h], dl                    ; 88 56 fa
-    mov di, 055aeh                            ; bf ae 55
+    mov di, 055afh                            ; bf af 55
     movzx dx, cl                              ; 0f b6 d1
     movzx cx, byte [bp+004h]                  ; 0f b6 4e 04
     imul cx, dx                               ; 0f af ca
@@ -3537,7 +3537,7 @@ biosfn_write_char_attr_:                     ; 0xc1d08 LB 0x168
     movzx bx, cl                              ; 0f b6 d9
     mov di, bx                                ; 89 df
     sal di, 003h                              ; c1 e7 03
-    cmp byte [di+0482fh], 000h                ; 80 bd 2f 48 00
+    cmp byte [di+04830h], 000h                ; 80 bd 30 48 00
     jne short 01dc3h                          ; 75 47
     mov bx, word [bp-018h]                    ; 8b 5e e8
     imul bx, ax                               ; 0f af d8
@@ -3558,18 +3558,18 @@ biosfn_write_char_attr_:                     ; 0xc1d08 LB 0x168
     add ax, bx                                ; 01 d8
     mov word [bp-01ah], ax                    ; 89 46 e6
     mov ax, word [bp-01ah]                    ; 8b 46 e6
-    mov es, [di+04832h]                       ; 8e 85 32 48
+    mov es, [di+04833h]                       ; 8e 85 33 48
     mov cx, si                                ; 89 f1
     mov di, dx                                ; 89 d7
     cld                                       ; fc
     jcxz 01dc0h                               ; e3 02
     rep stosw                                 ; f3 ab
     jmp near 01e69h                           ; e9 a6 00
-    movzx bx, byte [bx+048aeh]                ; 0f b6 9f ae 48
+    movzx bx, byte [bx+048afh]                ; 0f b6 9f af 48
     sal bx, 006h                              ; c1 e3 06
-    mov al, byte [bx+048c4h]                  ; 8a 87 c4 48
+    mov al, byte [bx+048c5h]                  ; 8a 87 c5 48
     mov byte [bp-008h], al                    ; 88 46 f8
-    mov al, byte [di+04831h]                  ; 8a 85 31 48
+    mov al, byte [di+04832h]                  ; 8a 85 32 48
     mov byte [bp-014h], al                    ; 88 46 ec
     dec si                                    ; 4e
     cmp si, strict byte 0ffffh                ; 83 fe ff
@@ -3579,7 +3579,7 @@ biosfn_write_char_attr_:                     ; 0xc1d08 LB 0x168
     jnc near 01e69h                           ; 0f 83 7d 00
     movzx bx, byte [bp-006h]                  ; 0f b6 5e fa
     sal bx, 003h                              ; c1 e3 03
-    mov al, byte [bx+04830h]                  ; 8a 87 30 48
+    mov al, byte [bx+04831h]                  ; 8a 87 31 48
     cmp AL, strict byte 003h                  ; 3c 03
     jc short 01e07h                           ; 72 0c
     jbe short 01e0dh                          ; 76 10
@@ -3667,7 +3667,7 @@ biosfn_write_char_only_:                     ; 0xc1e70 LB 0x16f
     movzx di, cl                              ; 0f b6 f9
     mov bx, di                                ; 89 fb
     sal bx, 003h                              ; c1 e3 03
-    cmp byte [bx+0482fh], 000h                ; 80 bf 2f 48 00
+    cmp byte [bx+04830h], 000h                ; 80 bf 30 48 00
     jne short 01f2eh                          ; 75 4a
     mov dx, word [bp-018h]                    ; 8b 56 e8
     imul dx, ax                               ; 0f af d0
@@ -3689,7 +3689,7 @@ biosfn_write_char_only_:                     ; 0xc1e70 LB 0x16f
     movzx ax, byte [bp-012h]                  ; 0f b6 46 ee
     movzx bx, byte [bp-00eh]                  ; 0f b6 5e f2
     sal bx, 003h                              ; c1 e3 03
-    mov di, word [bx+04832h]                  ; 8b bf 32 48
+    mov di, word [bx+04833h]                  ; 8b bf 33 48
     mov bx, ax                                ; 89 c3
     mov dx, cx                                ; 89 ca
     mov ax, di                                ; 89 f8
@@ -3697,11 +3697,11 @@ biosfn_write_char_only_:                     ; 0xc1e70 LB 0x16f
     inc cx                                    ; 41
     inc cx                                    ; 41
     jmp short 01f0ah                          ; eb dc
-    movzx di, byte [di+048aeh]                ; 0f b6 bd ae 48
+    movzx di, byte [di+048afh]                ; 0f b6 bd af 48
     sal di, 006h                              ; c1 e7 06
-    mov al, byte [di+048c4h]                  ; 8a 85 c4 48
+    mov al, byte [di+048c5h]                  ; 8a 85 c5 48
     mov byte [bp-00ah], al                    ; 88 46 f6
-    mov al, byte [bx+04831h]                  ; 8a 87 31 48
+    mov al, byte [bx+04832h]                  ; 8a 87 32 48
     mov byte [bp-008h], al                    ; 88 46 f8
     dec si                                    ; 4e
     cmp si, strict byte 0ffffh                ; 83 fe ff
@@ -3711,7 +3711,7 @@ biosfn_write_char_only_:                     ; 0xc1e70 LB 0x16f
     jnc near 01fd8h                           ; 0f 83 81 00
     movzx bx, byte [bp-00eh]                  ; 0f b6 5e f2
     sal bx, 003h                              ; c1 e3 03
-    mov bl, byte [bx+04830h]                  ; 8a 9f 30 48
+    mov bl, byte [bx+04831h]                  ; 8a 9f 31 48
     cmp bl, 003h                              ; 80 fb 03
     jc short 01f75h                           ; 72 0e
     jbe short 01f7ch                          ; 76 13
@@ -3774,9 +3774,9 @@ biosfn_write_pixel_:                         ; 0xc1fdf LB 0x16a
     je near 02121h                            ; 0f 84 1e 01
     movzx bx, al                              ; 0f b6 d8
     sal bx, 003h                              ; c1 e3 03
-    cmp byte [bx+0482fh], 000h                ; 80 bf 2f 48 00
+    cmp byte [bx+04830h], 000h                ; 80 bf 30 48 00
     je near 02121h                            ; 0f 84 0f 01
-    mov al, byte [bx+04830h]                  ; 8a 87 30 48
+    mov al, byte [bx+04831h]                  ; 8a 87 31 48
     cmp AL, strict byte 003h                  ; 3c 03
     jc short 02029h                           ; 72 0f
     jbe short 02030h                          ; 76 14
@@ -3830,7 +3830,7 @@ biosfn_write_pixel_:                         ; 0xc1fdf LB 0x16a
     mov ax, cx                                ; 89 c8
     shr ax, 1                                 ; d1 e8
     imul ax, ax, strict byte 00050h           ; 6b c0 50
-    cmp byte [bx+04831h], 002h                ; 80 bf 31 48 02
+    cmp byte [bx+04832h], 002h                ; 80 bf 32 48 02
     jne short 020abh                          ; 75 08
     mov bx, word [bp-00ah]                    ; 8b 5e f6
     shr bx, 002h                              ; c1 eb 02
@@ -3848,7 +3848,7 @@ biosfn_write_pixel_:                         ; 0xc1fdf LB 0x16a
     mov bl, al                                ; 88 c3
     movzx si, byte [bp-004h]                  ; 0f b6 76 fc
     sal si, 003h                              ; c1 e6 03
-    cmp byte [si+04831h], 002h                ; 80 bc 31 48 02
+    cmp byte [si+04832h], 002h                ; 80 bc 32 48 02
     jne short 020f1h                          ; 75 19
     mov al, byte [bp-00ah]                    ; 8a 46 f6
     and AL, strict byte 003h                  ; 24 03
@@ -3988,7 +3988,7 @@ biosfn_write_teletype_:                      ; 0xc2149 LB 0x284
     movzx bx, byte [bp-00eh]                  ; 0f b6 5e f2
     mov si, bx                                ; 89 de
     sal si, 003h                              ; c1 e6 03
-    cmp byte [si+0482fh], 000h                ; 80 bc 2f 48 00
+    cmp byte [si+04830h], 000h                ; 80 bc 30 48 00
     jne short 02293h                          ; 75 4b
     mov ax, word [bp-012h]                    ; 8b 46 ee
     imul ax, word [bp-014h]                   ; 0f af 46 ec
@@ -4004,7 +4004,7 @@ biosfn_write_teletype_:                      ; 0xc2149 LB 0x284
     add cx, cx                                ; 01 c9
     add cx, dx                                ; 01 d1
     movzx bx, byte [bp-00ch]                  ; 0f b6 5e f4
-    mov ax, word [si+04832h]                  ; 8b 84 32 48
+    mov ax, word [si+04833h]                  ; 8b 84 33 48
     mov dx, cx                                ; 89 ca
     call 02f85h                               ; e8 0b 0d
     cmp byte [bp-010h], 003h                  ; 80 7e f0 03
@@ -4012,14 +4012,14 @@ biosfn_write_teletype_:                      ; 0xc2149 LB 0x284
     movzx bx, byte [bp-006h]                  ; 0f b6 5e fa
     mov dx, cx                                ; 89 ca
     inc dx                                    ; 42
-    mov ax, word [si+04832h]                  ; 8b 84 32 48
+    mov ax, word [si+04833h]                  ; 8b 84 33 48
     call 02f85h                               ; e8 f5 0c
     jmp near 02311h                           ; e9 7e 00
-    movzx bx, byte [bx+048aeh]                ; 0f b6 9f ae 48
+    movzx bx, byte [bx+048afh]                ; 0f b6 9f af 48
     sal bx, 006h                              ; c1 e3 06
-    mov ah, byte [bx+048c4h]                  ; 8a a7 c4 48
-    mov dl, byte [si+04831h]                  ; 8a 94 31 48
-    mov al, byte [si+04830h]                  ; 8a 84 30 48
+    mov ah, byte [bx+048c5h]                  ; 8a a7 c5 48
+    mov dl, byte [si+04832h]                  ; 8a 94 32 48
+    mov al, byte [si+04831h]                  ; 8a 84 31 48
     cmp AL, strict byte 003h                  ; 3c 03
     jc short 022b7h                           ; 72 0c
     jbe short 022bdh                          ; 76 10
@@ -4075,7 +4075,7 @@ biosfn_write_teletype_:                      ; 0xc2149 LB 0x284
     mov bh, byte [bp-012h]                    ; 8a 7e ee
     db  0feh, 0cfh
     ; dec bh                                    ; fe cf
-    cmp byte [si+0482fh], 000h                ; 80 bc 2f 48 00
+    cmp byte [si+04830h], 000h                ; 80 bc 30 48 00
     jne short 0238dh                          ; 75 46
     mov ax, word [bp-012h]                    ; 8b 46 ee
     imul ax, word [bp-014h]                   ; 0f af 46 ec
@@ -4092,7 +4092,7 @@ biosfn_write_teletype_:                      ; 0xc2149 LB 0x284
     add cx, cx                                ; 01 c9
     add dx, cx                                ; 01 ca
     inc dx                                    ; 42
-    mov ax, word [si+04832h]                  ; 8b 84 32 48
+    mov ax, word [si+04833h]                  ; 8b 84 33 48
     call 02f77h                               ; e8 02 0c
     push strict byte 00001h                   ; 6a 01
     movzx dx, byte [bp-004h]                  ; 0f b6 56 fc
@@ -4367,7 +4367,7 @@ biosfn_load_text_8_14_pat_:                  ; 0xc2571 LB 0x70
     mov di, bx                                ; 89 df
     sal di, 005h                              ; c1 e7 05
     add di, word [bp-00ch]                    ; 03 7e f4
-    add si, 05daeh                            ; 81 c6 ae 5d
+    add si, 05dafh                            ; 81 c6 af 5d
     mov cx, strict word 0000eh                ; b9 0e 00
     mov dx, 0c000h                            ; ba 00 c0
     mov ax, 0a000h                            ; b8 00 a0
@@ -4423,7 +4423,7 @@ biosfn_load_text_8_8_pat_:                   ; 0xc25e1 LB 0x72
     mov di, bx                                ; 89 df
     sal di, 005h                              ; c1 e7 05
     add di, word [bp-00ch]                    ; 03 7e f4
-    add si, 055aeh                            ; 81 c6 ae 55
+    add si, 055afh                            ; 81 c6 af 55
     mov cx, strict word 00008h                ; b9 08 00
     mov dx, 0c000h                            ; ba 00 c0
     mov ax, 0a000h                            ; b8 00 a0
@@ -4479,7 +4479,7 @@ biosfn_load_text_8_16_pat_:                  ; 0xc2653 LB 0x72
     mov di, bx                                ; 89 df
     sal di, 005h                              ; c1 e7 05
     add di, word [bp-00ch]                    ; 03 7e f4
-    add si, 06baeh                            ; 81 c6 ae 6b
+    add si, 06bafh                            ; 81 c6 af 6b
     mov cx, strict word 00010h                ; b9 10 00
     mov dx, 0c000h                            ; ba 00 c0
     mov ax, 0a000h                            ; b8 00 a0
@@ -4613,7 +4613,7 @@ biosfn_read_state_info_:                     ; 0xc278b LB 0x101
     push dx                                   ; 52
     push bx                                   ; 53
     mov cx, ds                                ; 8c d9
-    mov bx, 05582h                            ; bb 82 55
+    mov bx, 05583h                            ; bb 83 55
     mov dx, word [bp-00ah]                    ; 8b 56 f6
     mov ax, word [bp-008h]                    ; 8b 46 f8
     call 02fc1h                               ; e8 20 08
@@ -5513,7 +5513,7 @@ find_vga_entry_:                             ; 0xc2f50 LB 0x27
     jnbe short 02f71h                         ; 77 0e
     movzx bx, al                              ; 0f b6 d8
     sal bx, 003h                              ; c1 e3 03
-    cmp dl, byte [bx+0482eh]                  ; 3a 97 2e 48
+    cmp dl, byte [bx+0482fh]                  ; 3a 97 2f 48
     jne short 02f5dh                          ; 75 ee
     mov ah, al                                ; 88 c4
     mov al, ah                                ; 88 e0
@@ -6779,10 +6779,10 @@ vesa_pm_end:                                 ; 0xc4714 LB 0x1
   ; Padding 0xeb bytes at 0xc4715
   times 235 db 0
 
-section _DATA progbits vstart=0x4800 align=1 ; size=0x36e0 class=DATA group=DGROUP
-_msg_vga_init:                               ; 0xc4800 LB 0x2e
-    db  'Oracle VM VirtualBox Version 4.3.8 VGA BIOS', 00dh, 00ah, 000h
-_vga_modes:                                  ; 0xc482e LB 0x80
+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.10 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
     db  004h, 001h, 002h, 002h, 000h, 0b8h, 0ffh, 001h, 005h, 001h, 002h, 002h, 000h, 0b8h, 0ffh, 001h
@@ -6791,11 +6791,11 @@ _vga_modes:                                  ; 0xc482e LB 0x80
     db  00fh, 001h, 003h, 001h, 000h, 0a0h, 0ffh, 000h, 010h, 001h, 004h, 004h, 000h, 0a0h, 0ffh, 002h
     db  011h, 001h, 003h, 001h, 000h, 0a0h, 0ffh, 002h, 012h, 001h, 004h, 004h, 000h, 0a0h, 0ffh, 002h
     db  013h, 001h, 005h, 008h, 000h, 0a0h, 0ffh, 003h, 06ah, 001h, 004h, 004h, 000h, 0a0h, 0ffh, 002h
-_line_to_vpti:                               ; 0xc48ae LB 0x10
+_line_to_vpti:                               ; 0xc48af LB 0x10
     db  017h, 017h, 018h, 018h, 004h, 005h, 006h, 007h, 00dh, 00eh, 011h, 012h, 01ah, 01bh, 01ch, 01dh
-_dac_regs:                                   ; 0xc48be LB 0x4
+_dac_regs:                                   ; 0xc48bf LB 0x4
     dd  0ff3f3f3fh
-_video_param_table:                          ; 0xc48c2 LB 0x780
+_video_param_table:                          ; 0xc48c3 LB 0x780
     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
@@ -6916,7 +6916,7 @@ _video_param_table:                          ; 0xc48c2 LB 0x780
     db  072h, 0f0h, 000h, 060h, 000h, 000h, 000h, 000h, 000h, 000h, 059h, 08dh, 057h, 032h, 000h, 057h
     db  073h, 0e3h, 0ffh, 000h, 001h, 002h, 003h, 004h, 005h, 014h, 007h, 038h, 039h, 03ah, 03bh, 03ch
     db  03dh, 03eh, 03fh, 001h, 000h, 00fh, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 005h, 00fh, 0ffh
-_palette0:                                   ; 0xc5042 LB 0xc0
+_palette0:                                   ; 0xc5043 LB 0xc0
     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, 02ah, 02ah, 02ah, 02ah, 02ah, 02ah, 02ah, 02ah
     db  02ah, 02ah, 02ah, 02ah, 02ah, 02ah, 02ah, 02ah, 02ah, 02ah, 02ah, 02ah, 02ah, 02ah, 02ah, 02ah
@@ -6929,7 +6929,7 @@ _palette0:                                   ; 0xc5042 LB 0xc0
     db  02ah, 02ah, 02ah, 02ah, 02ah, 02ah, 02ah, 02ah, 02ah, 02ah, 02ah, 02ah, 02ah, 02ah, 02ah, 02ah
     db  02ah, 02ah, 02ah, 02ah, 02ah, 02ah, 02ah, 02ah, 03fh, 03fh, 03fh, 03fh, 03fh, 03fh, 03fh, 03fh
     db  03fh, 03fh, 03fh, 03fh, 03fh, 03fh, 03fh, 03fh, 03fh, 03fh, 03fh, 03fh, 03fh, 03fh, 03fh, 03fh
-_palette1:                                   ; 0xc5102 LB 0xc0
+_palette1:                                   ; 0xc5103 LB 0xc0
     db  000h, 000h, 000h, 000h, 000h, 02ah, 000h, 02ah, 000h, 000h, 02ah, 02ah, 02ah, 000h, 000h, 02ah
     db  000h, 02ah, 02ah, 015h, 000h, 02ah, 02ah, 02ah, 000h, 000h, 000h, 000h, 000h, 02ah, 000h, 02ah
     db  000h, 000h, 02ah, 02ah, 02ah, 000h, 000h, 02ah, 000h, 02ah, 02ah, 015h, 000h, 02ah, 02ah, 02ah
@@ -6942,7 +6942,7 @@ _palette1:                                   ; 0xc5102 LB 0xc0
     db  015h, 015h, 015h, 015h, 015h, 03fh, 015h, 03fh, 015h, 015h, 03fh, 03fh, 03fh, 015h, 015h, 03fh
     db  015h, 03fh, 03fh, 03fh, 015h, 03fh, 03fh, 03fh, 015h, 015h, 015h, 015h, 015h, 03fh, 015h, 03fh
     db  015h, 015h, 03fh, 03fh, 03fh, 015h, 015h, 03fh, 015h, 03fh, 03fh, 03fh, 015h, 03fh, 03fh, 03fh
-_palette2:                                   ; 0xc51c2 LB 0xc0
+_palette2:                                   ; 0xc51c3 LB 0xc0
     db  000h, 000h, 000h, 000h, 000h, 02ah, 000h, 02ah, 000h, 000h, 02ah, 02ah, 02ah, 000h, 000h, 02ah
     db  000h, 02ah, 02ah, 02ah, 000h, 02ah, 02ah, 02ah, 000h, 000h, 015h, 000h, 000h, 03fh, 000h, 02ah
     db  015h, 000h, 02ah, 03fh, 02ah, 000h, 015h, 02ah, 000h, 03fh, 02ah, 02ah, 015h, 02ah, 02ah, 03fh
@@ -6955,7 +6955,7 @@ _palette2:                                   ; 0xc51c2 LB 0xc0
     db  015h, 015h, 000h, 015h, 015h, 02ah, 015h, 03fh, 000h, 015h, 03fh, 02ah, 03fh, 015h, 000h, 03fh
     db  015h, 02ah, 03fh, 03fh, 000h, 03fh, 03fh, 02ah, 015h, 015h, 015h, 015h, 015h, 03fh, 015h, 03fh
     db  015h, 015h, 03fh, 03fh, 03fh, 015h, 015h, 03fh, 015h, 03fh, 03fh, 03fh, 015h, 03fh, 03fh, 03fh
-_palette3:                                   ; 0xc5282 LB 0x300
+_palette3:                                   ; 0xc5283 LB 0x300
     db  000h, 000h, 000h, 000h, 000h, 02ah, 000h, 02ah, 000h, 000h, 02ah, 02ah, 02ah, 000h, 000h, 02ah
     db  000h, 02ah, 02ah, 015h, 000h, 02ah, 02ah, 02ah, 015h, 015h, 015h, 015h, 015h, 03fh, 015h, 03fh
     db  015h, 015h, 03fh, 03fh, 03fh, 015h, 015h, 03fh, 015h, 03fh, 03fh, 03fh, 015h, 03fh, 03fh, 03fh
@@ -7004,12 +7004,12 @@ _palette3:                                   ; 0xc5282 LB 0x300
     db  00bh, 010h, 00bh, 00bh, 010h, 00ch, 00bh, 010h, 00dh, 00bh, 010h, 00fh, 00bh, 010h, 010h, 00bh
     db  00fh, 010h, 00bh, 00dh, 010h, 00bh, 00ch, 010h, 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
-_static_functionality:                       ; 0xc5582 LB 0x10
+_static_functionality:                       ; 0xc5583 LB 0x10
     db  0ffh, 0e0h, 00fh, 000h, 000h, 000h, 000h, 007h, 002h, 008h, 0e7h, 00ch, 000h, 000h, 000h, 000h
-_video_save_pointer_table:                   ; 0xc5592 LB 0x1c
-    db  0c2h, 048h, 000h, 0c0h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
+_video_save_pointer_table:                   ; 0xc5593 LB 0x1c
+    db  0c3h, 048h, 000h, 0c0h, 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
-_vgafont8:                                   ; 0xc55ae LB 0x800
+_vgafont8:                                   ; 0xc55af LB 0x800
     db  000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 07eh, 081h, 0a5h, 081h, 0bdh, 099h, 081h, 07eh
     db  07eh, 0ffh, 0dbh, 0ffh, 0c3h, 0e7h, 0ffh, 07eh, 06ch, 0feh, 0feh, 0feh, 07ch, 038h, 010h, 000h
     db  010h, 038h, 07ch, 0feh, 07ch, 038h, 010h, 000h, 038h, 07ch, 038h, 0feh, 0feh, 07ch, 038h, 07ch
@@ -7138,7 +7138,7 @@ _vgafont8:                                   ; 0xc55ae LB 0x800
     db  000h, 000h, 000h, 000h, 018h, 000h, 000h, 000h, 00fh, 00ch, 00ch, 00ch, 0ech, 06ch, 03ch, 01ch
     db  078h, 06ch, 06ch, 06ch, 06ch, 000h, 000h, 000h, 070h, 018h, 030h, 060h, 078h, 000h, 000h, 000h
     db  000h, 000h, 03ch, 03ch, 03ch, 03ch, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
-_vgafont14:                                  ; 0xc5dae LB 0xe00
+_vgafont14:                                  ; 0xc5daf LB 0xe00
     db  000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
     db  07eh, 081h, 0a5h, 081h, 081h, 0bdh, 099h, 081h, 07eh, 000h, 000h, 000h, 000h, 000h, 07eh, 0ffh
     db  0dbh, 0ffh, 0ffh, 0c3h, 0e7h, 0ffh, 07eh, 000h, 000h, 000h, 000h, 000h, 000h, 06ch, 0feh, 0feh
@@ -7363,7 +7363,7 @@ _vgafont14:                                  ; 0xc5dae LB 0xe00
     db  000h, 000h, 000h, 000h, 000h, 000h, 000h, 070h, 0d8h, 030h, 060h, 0c8h, 0f8h, 000h, 000h, 000h
     db  000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 07ch, 07ch, 07ch, 07ch, 07ch, 07ch, 000h, 000h
     db  000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
-_vgafont16:                                  ; 0xc6bae LB 0x1000
+_vgafont16:                                  ; 0xc6baf LB 0x1000
     db  000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
     db  000h, 000h, 07eh, 081h, 0a5h, 081h, 081h, 0bdh, 099h, 081h, 081h, 07eh, 000h, 000h, 000h, 000h
     db  000h, 000h, 07eh, 0ffh, 0dbh, 0ffh, 0ffh, 0c3h, 0e7h, 0ffh, 0ffh, 07eh, 000h, 000h, 000h, 000h
@@ -7620,7 +7620,7 @@ _vgafont16:                                  ; 0xc6bae LB 0x1000
     db  000h, 070h, 0d8h, 030h, 060h, 0c8h, 0f8h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
     db  000h, 000h, 000h, 000h, 07ch, 07ch, 07ch, 07ch, 07ch, 07ch, 07ch, 000h, 000h, 000h, 000h, 000h
     db  000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
-_vgafont14alt:                               ; 0xc7bae LB 0x12d
+_vgafont14alt:                               ; 0xc7baf LB 0x12d
     db  01dh, 000h, 000h, 000h, 000h, 024h, 066h, 0ffh, 066h, 024h, 000h, 000h, 000h, 000h, 000h, 022h
     db  000h, 063h, 063h, 063h, 022h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 02bh, 000h
     db  000h, 000h, 018h, 018h, 018h, 0ffh, 018h, 018h, 018h, 000h, 000h, 000h, 000h, 02dh, 000h, 000h
@@ -7640,7 +7640,7 @@ _vgafont14alt:                               ; 0xc7bae LB 0x12d
     db  000h, 0fch, 066h, 066h, 07ch, 062h, 066h, 06fh, 066h, 066h, 0f3h, 000h, 000h, 000h, 0f1h, 000h
     db  000h, 018h, 018h, 018h, 0ffh, 018h, 018h, 018h, 000h, 0ffh, 000h, 000h, 000h, 0f6h, 000h, 000h
     db  018h, 018h, 000h, 000h, 0ffh, 000h, 000h, 018h, 018h, 000h, 000h, 000h, 000h
-_vgafont16alt:                               ; 0xc7cdb LB 0x145
+_vgafont16alt:                               ; 0xc7cdc LB 0x144
     db  01dh, 000h, 000h, 000h, 000h, 000h, 024h, 066h, 0ffh, 066h, 024h, 000h, 000h, 000h, 000h, 000h
     db  000h, 030h, 000h, 000h, 03ch, 066h, 0c3h, 0c3h, 0dbh, 0dbh, 0c3h, 0c3h, 066h, 03ch, 000h, 000h
     db  000h, 000h, 04dh, 000h, 000h, 0c3h, 0e7h, 0ffh, 0ffh, 0dbh, 0c3h, 0c3h, 0c3h, 0c3h, 0c3h, 000h
@@ -7661,31 +7661,34 @@ _vgafont16alt:                               ; 0xc7cdb LB 0x145
     db  09eh, 000h, 0fch, 066h, 066h, 07ch, 062h, 066h, 06fh, 066h, 066h, 066h, 0f3h, 000h, 000h, 000h
     db  000h, 0abh, 000h, 0c0h, 0c0h, 0c2h, 0c6h, 0cch, 018h, 030h, 060h, 0ceh, 09bh, 006h, 00ch, 01fh
     db  000h, 000h, 0ach, 000h, 0c0h, 0c0h, 0c2h, 0c6h, 0cch, 018h, 030h, 066h, 0ceh, 096h, 03eh, 006h
-    db  006h, 000h, 000h, 000h, 000h
+    db  006h, 000h, 000h, 000h
 _vbebios_copyright:                          ; 0xc7e20 LB 0x15
     db  'VirtualBox VESA BIOS', 000h
 _vbebios_vendor_name:                        ; 0xc7e35 LB 0x13
     db  'Oracle Corporation', 000h
 _vbebios_product_name:                       ; 0xc7e48 LB 0x21
     db  'Oracle VM VirtualBox VBE Adapter', 000h
-_vbebios_product_revision:                   ; 0xc7e69 LB 0x23
-    db  'Oracle VM VirtualBox Version 4.3.8', 000h
-_vbebios_info_string:                        ; 0xc7e8c LB 0x2b
+_vbebios_product_revision:                   ; 0xc7e69 LB 0x24
+    db  'Oracle VM VirtualBox Version 4.3.10', 000h
+_vbebios_info_string:                        ; 0xc7e8d LB 0x2b
     db  'VirtualBox VBE Display Adapter enabled', 00dh, 00ah, 00dh, 00ah, 000h
-_no_vbebios_info_string:                     ; 0xc7eb7 LB 0x29
+_no_vbebios_info_string:                     ; 0xc7eb8 LB 0x29
     db  'No VirtualBox VBE support available!', 00dh, 00ah, 00dh, 00ah, 000h
 
-section CONST progbits vstart=0x7ee0 align=1 ; size=0x0 class=DATA group=DGROUP
+  ; Padding 0x1 bytes at 0xc7ee1
+    db  001h
+
+section CONST progbits vstart=0x7ee2 align=1 ; size=0x0 class=DATA group=DGROUP
 
-section CONST2 progbits vstart=0x7ee0 align=1 ; size=0x0 class=DATA group=DGROUP
+section CONST2 progbits vstart=0x7ee2 align=1 ; size=0x0 class=DATA group=DGROUP
 
-  ; Padding 0x120 bytes at 0xc7ee0
-    db  001h, 000h, 000h, 000h, 000h, 001h, 000h, 000h, 000h, 000h, 000h, 000h, 02fh, 068h, 06fh, 06dh
-    db  065h, 02fh, 066h, 06dh, 033h, 02fh, 073h, 072h, 063h, 02fh, 076h, 062h, 06fh, 078h, 02dh, 034h
-    db  02eh, 033h, 02fh, 06fh, 075h, 074h, 02fh, 06ch, 069h, 06eh, 075h, 078h, 02eh, 061h, 06dh, 064h
-    db  036h, 034h, 02fh, 072h, 065h, 06ch, 065h, 061h, 073h, 065h, 02fh, 06fh, 062h, 06ah, 02fh, 056h
-    db  042h, 06fh, 078h, 056h, 067h, 061h, 042h, 069h, 06fh, 073h, 02fh, 056h, 042h, 06fh, 078h, 056h
-    db  067h, 061h, 042h, 069h, 06fh, 073h, 02eh, 073h, 079h, 06dh, 000h, 000h, 000h, 000h, 000h, 000h
+  ; Padding 0x11e bytes at 0xc7ee2
+    db  000h, 000h, 000h, 000h, 001h, 000h, 000h, 000h, 000h, 000h, 000h, 02fh, 068h, 06fh, 06dh, 065h
+    db  02fh, 066h, 06dh, 033h, 02fh, 073h, 072h, 063h, 02fh, 076h, 062h, 06fh, 078h, 02dh, 034h, 02eh
+    db  033h, 02fh, 06fh, 075h, 074h, 02fh, 06ch, 069h, 06eh, 075h, 078h, 02eh, 061h, 06dh, 064h, 036h
+    db  034h, 02fh, 072h, 065h, 06ch, 065h, 061h, 073h, 065h, 02fh, 06fh, 062h, 06ah, 02fh, 056h, 042h
+    db  06fh, 078h, 056h, 067h, 061h, 042h, 069h, 06fh, 073h, 02fh, 056h, 042h, 06fh, 078h, 056h, 067h
+    db  061h, 042h, 069h, 06fh, 073h, 02eh, 073h, 079h, 06dh, 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, 000h, 000h, 000h
@@ -7697,4 +7700,4 @@ section CONST2 progbits vstart=0x7ee0 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, 000h, 000h, 016h
+    db  000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 068h
diff --git a/src/VBox/Devices/Graphics/BIOS/VBoxVgaBiosAlternative.md5sum b/src/VBox/Devices/Graphics/BIOS/VBoxVgaBiosAlternative.md5sum
index 4f54140..cb2d801 100644
--- a/src/VBox/Devices/Graphics/BIOS/VBoxVgaBiosAlternative.md5sum
+++ b/src/VBox/Devices/Graphics/BIOS/VBoxVgaBiosAlternative.md5sum
@@ -1 +1 @@
-86355c5abda5dd1b0bf3f2f65828c6a1 *VBoxVgaBios.rom
+25d0dc05c628f90ff6b5aa5e3987ba1f *VBoxVgaBios.rom
diff --git a/src/VBox/Devices/Graphics/DevVGA.cpp b/src/VBox/Devices/Graphics/DevVGA.cpp
index e55a4ed..da28d9b 100644
--- a/src/VBox/Devices/Graphics/DevVGA.cpp
+++ b/src/VBox/Devices/Graphics/DevVGA.cpp
@@ -5455,6 +5455,8 @@ static DECLCALLBACK(int) vgaR3LoadExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSM, uint
 static DECLCALLBACK(int) vgaR3LoadDone(PPDMDEVINS pDevIns, PSSMHANDLE pSSM)
 {
 #ifdef VBOX_WITH_HGSMI
+    PVGASTATE pThis = PDMINS_2_DATA(pDevIns, PVGASTATE);
+    VBVAPause(pThis, (pThis->vbe_regs[VBE_DISPI_INDEX_ENABLE] & VBE_DISPI_ENABLED) == 0);
     return vboxVBVALoadStateDone(pDevIns, pSSM);
 #else
     return VINF_SUCCESS;
@@ -5474,6 +5476,9 @@ static DECLCALLBACK(void)  vgaR3Reset(PPDMDEVINS pDevIns)
     char           *pchEnd;
     LogFlow(("vgaReset\n"));
 
+    if (pThis->pVdma)
+        vboxVDMAReset(pThis->pVdma);
+
 #ifdef VBOX_WITH_HGSMI
     VBVAReset(pThis);
 #endif /* VBOX_WITH_HGSMI */
@@ -5924,6 +5929,7 @@ static DECLCALLBACK(int)   vgaR3Construct(PPDMDEVINS pDevIns, int iInstance, PCF
     pThis->IVBVACallbacks.pfnCrHgsmiControlCompleteAsync = vboxVDMACrHgsmiControlCompleteAsync;
 # endif
 #endif
+    pThis->IVBVACallbacks.pfnCrCtlSubmit = vboxCmdVBVACmdHostCtl;
 
     /*
      * We use our own critical section to avoid unncessary pointer indirections
diff --git a/src/VBox/Devices/Graphics/DevVGA.h b/src/VBox/Devices/Graphics/DevVGA.h
index f3617bb..aad2b43 100644
--- a/src/VBox/Devices/Graphics/DevVGA.h
+++ b/src/VBox/Devices/Graphics/DevVGA.h
@@ -292,7 +292,8 @@ typedef struct VGAState {
 # if defined(VBOX_WITH_HGSMI) && (defined(VBOX_WITH_VIDEOHWACCEL) || defined(VBOX_WITH_CRHGSMI))
     /** LUN\#0: VBVA callbacks interface */
     PDMIDISPLAYVBVACALLBACKS    IVBVACallbacks;
-# elif HC_ARCH_BITS == 32
+# endif
+# if HC_ARCH_BITS == 32
     uint32_t                    Padding0;
 # endif
     /** Pointer to base interface of the driver. */
@@ -624,6 +625,10 @@ int vboxVBVASaveStateDone (PPDMDEVINS pDevIns, PSSMHANDLE pSSM);
 int vboxVDMACrHgsmiCommandCompleteAsync(PPDMIDISPLAYVBVACALLBACKS pInterface, PVBOXVDMACMD_CHROMIUM_CMD pCmd, int rc);
 int vboxVDMACrHgsmiControlCompleteAsync(PPDMIDISPLAYVBVACALLBACKS pInterface, PVBOXVDMACMD_CHROMIUM_CTL pCmd, int rc);
 # endif
+int vboxCmdVBVACmdHostCtl(PPDMIDISPLAYVBVACALLBACKS pInterface,
+                                                               struct VBOXCRCMDCTL* pCmd, uint32_t cbCmd,
+                                                               PFNCRCTLCOMPLETION pfnCompletion,
+                                                               void *pvCompletion);
 
 int vboxVBVASaveStateExec (PPDMDEVINS pDevIns, PSSMHANDLE pSSM);
 int vboxVBVALoadStateExec (PPDMDEVINS pDevIns, PSSMHANDLE pSSM, uint32_t u32Version);
@@ -633,17 +638,17 @@ int vboxVBVALoadStateDone (PPDMDEVINS pDevIns, PSSMHANDLE pSSM);
 typedef struct VBOXVDMAHOST *PVBOXVDMAHOST;
 int vboxVDMAConstruct(PVGASTATE pVGAState, uint32_t cPipeElements);
 int vboxVDMADestruct(PVBOXVDMAHOST pVdma);
+int vboxVDMAReset(PVBOXVDMAHOST pVdma);
 void vboxVDMAControl(PVBOXVDMAHOST pVdma, PVBOXVDMA_CTL pCmd, uint32_t cbCmd);
 void vboxVDMACommand(PVBOXVDMAHOST pVdma, PVBOXVDMACBUF_DR pCmd, uint32_t cbCmd);
 int vboxVDMASaveStateExecPrep(struct VBOXVDMAHOST *pVdma, PSSMHANDLE pSSM);
 int vboxVDMASaveStateExecDone(struct VBOXVDMAHOST *pVdma, PSSMHANDLE pSSM);
 # endif /* VBOX_WITH_VDMA */
 
-int vboxCmdVBVAEnable(PVGASTATE pVGAState, VBVABUFFER *pVBVA);
-int vboxCmdVBVADisable(PVGASTATE pVGAState);
 int vboxCmdVBVACmdSubmit(PVGASTATE pVGAState);
 int vboxCmdVBVACmdFlush(PVGASTATE pVGAState);
 void vboxCmdVBVACmdTimer(PVGASTATE pVGAState);
+int vboxCmdVBVACmdCtl(PVGASTATE pVGAState, VBOXCMDVBVA_CTL *pCtl, uint32_t cbCtl);
 
 #endif /* VBOX_WITH_HGSMI */
 
diff --git a/src/VBox/Devices/Graphics/DevVGA_VBVA.cpp b/src/VBox/Devices/Graphics/DevVGA_VBVA.cpp
index e7dccbb..ed727b1 100644
--- a/src/VBox/Devices/Graphics/DevVGA_VBVA.cpp
+++ b/src/VBox/Devices/Graphics/DevVGA_VBVA.cpp
@@ -1939,6 +1939,32 @@ static DECLCALLBACK(int) vbvaChannelHandler (void *pvHandler, uint16_t u16Channe
 
     switch (u16ChannelInfo)
     {
+        case VBVA_CMDVBVA_SUBMIT:
+        {
+            rc = vboxCmdVBVACmdSubmit(pVGAState);
+            break;
+        }
+        case VBVA_CMDVBVA_FLUSH:
+        {
+            rc =vboxCmdVBVACmdFlush(pVGAState);
+            break;
+        }
+        case VBVA_CMDVBVA_CTL:
+        {
+            if (cbBuffer < VBoxSHGSMIBufferHeaderSize() + sizeof (VBOXCMDVBVA_CTL))
+            {
+                Log(("buffer too small\n"));
+#ifdef DEBUG_misha
+                AssertMsgFailed(("buffer too small\n"));
+#endif
+                rc = VERR_INVALID_PARAMETER;
+                break;
+            }
+
+            VBOXCMDVBVA_CTL *pCtl = (VBOXCMDVBVA_CTL*)VBoxSHGSMIBufferData((PVBOXSHGSMIHEADER)pvBuffer);
+            rc = vboxCmdVBVACmdCtl(pVGAState, pCtl, cbBuffer - VBoxSHGSMIBufferHeaderSize());
+            break;
+        }
 #ifdef VBOX_WITH_VDMA
         case VBVA_VDMA_CMD:
         {
@@ -2252,54 +2278,6 @@ static DECLCALLBACK(int) vbvaChannelHandler (void *pvHandler, uint16_t u16Channe
             pCaps->rc = VINF_SUCCESS;
         } break;
 #endif
-
-        case VBVA_CMDVBVA_ENABLE:
-        {
-            if (cbBuffer < sizeof (VBVAENABLE))
-            {
-                rc = VERR_INVALID_PARAMETER;
-                break;
-            }
-
-            VBVAENABLE *pEnable = (VBVAENABLE *)pvBuffer;
-
-            if ((pEnable->u32Flags & (VBVA_F_ENABLE | VBVA_F_DISABLE)) == VBVA_F_ENABLE)
-            {
-                uint32_t u32Offset = pEnable->u32Offset;
-                VBVABUFFER *pVBVA = (VBVABUFFER *)HGSMIOffsetToPointerHost (pIns, u32Offset);
-
-                if (pVBVA)
-                    rc = vboxCmdVBVAEnable(pVGAState, pVBVA);
-                else
-                {
-                    LogRel(("Invalid VBVABUFFER offset 0x%x!!!\n",
-                         pEnable->u32Offset));
-                    rc = VERR_INVALID_PARAMETER;
-                }
-            }
-            else if ((pEnable->u32Flags & (VBVA_F_ENABLE | VBVA_F_DISABLE)) == VBVA_F_DISABLE)
-            {
-                rc = vboxCmdVBVADisable(pVGAState);
-            }
-            else
-            {
-                LogRel(("Invalid VBVA_ENABLE flags 0x%x!!!\n", pEnable->u32Flags));
-                rc = VERR_INVALID_PARAMETER;
-            }
-
-            pEnable->i32Result = rc;
-            break;
-        }
-        case VBVA_CMDVBVA_SUBMIT:
-        {
-            rc = vboxCmdVBVACmdSubmit(pVGAState);
-            break;
-        }
-        case VBVA_CMDVBVA_FLUSH:
-        {
-            rc =vboxCmdVBVACmdFlush(pVGAState);
-            break;
-        }
         case VBVA_SCANLINE_CFG:
         {
             if (cbBuffer < sizeof (VBVASCANLINECFG))
diff --git a/src/VBox/Devices/Graphics/DevVGA_VDMA.cpp b/src/VBox/Devices/Graphics/DevVGA_VDMA.cpp
index bdec54a..0e35fe5 100644
--- a/src/VBox/Devices/Graphics/DevVGA_VDMA.cpp
+++ b/src/VBox/Devices/Graphics/DevVGA_VDMA.cpp
@@ -20,12 +20,22 @@
 #include <iprt/thread.h>
 #include <iprt/mem.h>
 #include <iprt/asm.h>
+#include <iprt/list.h>
 
 #include "DevVGA.h"
 #include "HGSMI/SHGSMIHost.h"
 #include "HGSMI/HGSMIHostHlp.h"
 
 #include <VBox/VBoxVideo3D.h>
+#include <VBox/VBoxVideoHost3D.h>
+
+#ifdef DEBUG_misha
+# define VBOXVDBG_MEMCACHE_DISABLE
+#endif
+
+#ifndef VBOXVDBG_MEMCACHE_DISABLE
+# include <iprt/memcache.h>
+#endif
 
 #ifdef DEBUG_misha
 #define WARN_BP() do { AssertFailed(); } while (0)
@@ -37,127 +47,733 @@
         WARN_BP(); \
     } while (0)
 
-#ifdef VBOX_VDMA_WITH_WORKERTHREAD
-typedef enum
+#define VBOXVDMATHREAD_STATE_TERMINATED     0
+#define VBOXVDMATHREAD_STATE_CREATED        1
+#define VBOXVDMATHREAD_STATE_TERMINATING    2
+
+typedef struct VBOXVDMATHREAD
+{
+    RTTHREAD hWorkerThread;
+    RTSEMEVENT hEvent;
+    RTSEMEVENT hClientEvent;
+    volatile uint32_t u32State;
+} VBOXVDMATHREAD, *PVBOXVDMATHREAD;
+
+
+/* state transformations:
+ *
+ *   submitter   |    processor
+ *
+ *  LISTENING   --->  PROCESSING
+ *
+ *  */
+#define VBVAEXHOSTCONTEXT_STATE_LISTENING      0
+#define VBVAEXHOSTCONTEXT_STATE_PROCESSING     1
+
+#define VBVAEXHOSTCONTEXT_ESTATE_DISABLED     -1
+#define VBVAEXHOSTCONTEXT_ESTATE_PAUSED        0
+#define VBVAEXHOSTCONTEXT_ESTATE_ENABLED       1
+
+typedef struct VBVAEXHOSTCONTEXT
+{
+    VBVABUFFER *pVBVA;
+    volatile int32_t i32State;
+    volatile int32_t i32EnableState;
+    volatile uint32_t u32cCtls;
+    /* critical section for accessing ctl lists */
+    RTCRITSECT CltCritSect;
+    RTLISTANCHOR GuestCtlList;
+    RTLISTANCHOR HostCtlList;
+#ifndef VBOXVDBG_MEMCACHE_DISABLE
+    RTMEMCACHE CtlCache;
+#endif
+} VBVAEXHOSTCONTEXT;
+
+typedef enum
+{
+    VBVAEXHOSTCTL_TYPE_UNDEFINED = 0,
+    VBVAEXHOSTCTL_TYPE_HH_INTERNAL_PAUSE,
+    VBVAEXHOSTCTL_TYPE_HH_INTERNAL_RESUME,
+    VBVAEXHOSTCTL_TYPE_HH_ENABLE,
+    VBVAEXHOSTCTL_TYPE_HH_TERM,
+    VBVAEXHOSTCTL_TYPE_HH_RESET,
+    VBVAEXHOSTCTL_TYPE_HH_SAVESTATE,
+    VBVAEXHOSTCTL_TYPE_HH_LOADSTATE,
+    VBVAEXHOSTCTL_TYPE_HH_BE_OPAQUE,
+    VBVAEXHOSTCTL_TYPE_GHH_BE_OPAQUE,
+    VBVAEXHOSTCTL_TYPE_GH_ENABLE_DISABLE
+} VBVAEXHOSTCTL_TYPE;
+
+struct VBVAEXHOSTCTL;
+
+typedef DECLCALLBACKPTR(void, PFNVBVAEXHOSTCTL_COMPLETE)(VBVAEXHOSTCONTEXT *pVbva, struct VBVAEXHOSTCTL *pCtl, int rc, void *pvComplete);
+
+typedef struct VBVAEXHOSTCTL
+{
+    RTLISTNODE Node;
+    VBVAEXHOSTCTL_TYPE enmType;
+    union
+    {
+        struct
+        {
+            uint8_t * pu8Cmd;
+            uint32_t cbCmd;
+        } cmd;
+
+        struct
+        {
+            PSSMHANDLE pSSM;
+            uint32_t u32Version;
+        } state;
+    } u;
+    PFNVBVAEXHOSTCTL_COMPLETE pfnComplete;
+    void *pvComplete;
+} VBVAEXHOSTCTL;
+
+/* VBoxVBVAExHP**, i.e. processor functions, can NOT be called concurrently with each other,
+ * but can be called with other VBoxVBVAExS** (submitter) functions except Init/Start/Term aparently.
+ * Can only be called be the processor, i.e. the entity that acquired the processor state by direct or indirect call to the VBoxVBVAExHSCheckCommands
+ * see mor edetailed comments in headers for function definitions */
+typedef enum
+{
+    VBVAEXHOST_DATA_TYPE_NO_DATA = 0,
+    VBVAEXHOST_DATA_TYPE_CMD,
+    VBVAEXHOST_DATA_TYPE_HOSTCTL,
+    VBVAEXHOST_DATA_TYPE_GUESTCTL
+} VBVAEXHOST_DATA_TYPE;
+static VBVAEXHOST_DATA_TYPE VBoxVBVAExHPDataGet(struct VBVAEXHOSTCONTEXT *pCmdVbva, uint8_t **ppCmd, uint32_t *pcbCmd);
+
+static void VBoxVBVAExHPDataCompleteCmd(struct VBVAEXHOSTCONTEXT *pCmdVbva, uint32_t cbCmd);
+static void VBoxVBVAExHPDataCompleteCtl(struct VBVAEXHOSTCONTEXT *pCmdVbva, VBVAEXHOSTCTL *pCtl, int rc);
+
+/* VBoxVBVAExHP**, i.e. processor functions, can NOT be called concurrently with each other,
+ * can be called concurrently with istelf as well as with other VBoxVBVAEx** functions except Init/Start/Term aparently */
+static int VBoxVBVAExHSCheckCommands(struct VBVAEXHOSTCONTEXT *pCmdVbva);
+
+static int VBoxVBVAExHSInit(struct VBVAEXHOSTCONTEXT *pCmdVbva);
+static int VBoxVBVAExHSEnable(struct VBVAEXHOSTCONTEXT *pCmdVbva, VBVABUFFER *pVBVA);
+static int VBoxVBVAExHSDisable(struct VBVAEXHOSTCONTEXT *pCmdVbva);
+static void VBoxVBVAExHSTerm(struct VBVAEXHOSTCONTEXT *pCmdVbva);
+static int VBoxVBVAExHSSaveState(struct VBVAEXHOSTCONTEXT *pCmdVbva, uint8_t* pu8VramBase, PSSMHANDLE pSSM);
+static int VBoxVBVAExHSLoadState(struct VBVAEXHOSTCONTEXT *pCmdVbva, uint8_t* pu8VramBase, PSSMHANDLE pSSM, uint32_t u32Version);
+
+static VBVAEXHOSTCTL* VBoxVBVAExHCtlAlloc(VBVAEXHOSTCONTEXT *pCmdVbva)
+{
+#ifndef VBOXVDBG_MEMCACHE_DISABLE
+    return (VBVAEXHOSTCTL*)RTMemCacheAlloc(pCmdVbva->CtlCache);
+#else
+    return (VBVAEXHOSTCTL*)RTMemAlloc(sizeof (VBVAEXHOSTCTL));
+#endif
+}
+
+static void VBoxVBVAExHCtlFree(VBVAEXHOSTCONTEXT *pCmdVbva, VBVAEXHOSTCTL *pCtl)
+{
+#ifndef VBOXVDBG_MEMCACHE_DISABLE
+    RTMemCacheFree(pCmdVbva->CtlCache, pCtl);
+#else
+    RTMemFree(pCtl);
+#endif
+}
+
+static VBVAEXHOSTCTL* VBoxVBVAExHCtlCreate(VBVAEXHOSTCONTEXT *pCmdVbva, VBVAEXHOSTCTL_TYPE enmType)
+{
+    VBVAEXHOSTCTL* pCtl = VBoxVBVAExHCtlAlloc(pCmdVbva);
+    if (!pCtl)
+    {
+        WARN(("VBoxVBVAExHCtlAlloc failed\n"));
+        return NULL;
+    }
+
+    pCtl->enmType = enmType;
+    return pCtl;
+}
+
+static int vboxVBVAExHSProcessorAcquire(struct VBVAEXHOSTCONTEXT *pCmdVbva)
+{
+    Assert(pCmdVbva->i32State >= VBVAEXHOSTCONTEXT_STATE_LISTENING);
+
+    if (ASMAtomicCmpXchgS32(&pCmdVbva->i32State, VBVAEXHOSTCONTEXT_STATE_PROCESSING, VBVAEXHOSTCONTEXT_STATE_LISTENING))
+            return VINF_SUCCESS;
+    return VERR_SEM_BUSY;
+}
+
+static VBVAEXHOSTCTL* vboxVBVAExHPCheckCtl(struct VBVAEXHOSTCONTEXT *pCmdVbva, bool *pfHostCtl, bool fHostOnlyMode)
+{
+    Assert(pCmdVbva->i32State == VBVAEXHOSTCONTEXT_STATE_PROCESSING);
+
+    if(!fHostOnlyMode && !ASMAtomicUoReadU32(&pCmdVbva->u32cCtls))
+        return NULL;
+
+    int rc = RTCritSectEnter(&pCmdVbva->CltCritSect);
+    if (RT_SUCCESS(rc))
+    {
+        VBVAEXHOSTCTL* pCtl = RTListGetFirst(&pCmdVbva->HostCtlList, VBVAEXHOSTCTL, Node);
+        if (pCtl)
+            *pfHostCtl = true;
+        else if (!fHostOnlyMode)
+        {
+            if (ASMAtomicUoReadS32(&pCmdVbva->i32EnableState) > VBVAEXHOSTCONTEXT_ESTATE_PAUSED)
+            {
+                pCtl = RTListGetFirst(&pCmdVbva->GuestCtlList, VBVAEXHOSTCTL, Node);
+                /* pCtl can not be null here since pCmdVbva->u32cCtls is not null,
+                 * and there are no HostCtl commands*/
+                Assert(pCtl);
+                *pfHostCtl = false;
+            }
+        }
+
+        if (pCtl)
+        {
+            RTListNodeRemove(&pCtl->Node);
+            ASMAtomicDecU32(&pCmdVbva->u32cCtls);
+        }
+
+        RTCritSectLeave(&pCmdVbva->CltCritSect);
+
+        return pCtl;
+    }
+    else
+        WARN(("RTCritSectEnter failed %d\n", rc));
+
+    return NULL;
+}
+
+static VBVAEXHOSTCTL* VBoxVBVAExHPCheckHostCtlOnDisable(struct VBVAEXHOSTCONTEXT *pCmdVbva)
+{
+    bool fHostCtl;
+    return vboxVBVAExHPCheckCtl(pCmdVbva, &fHostCtl, true);
+}
+
+
+static bool vboxVBVAExHPCheckProcessCtlInternal(struct VBVAEXHOSTCONTEXT *pCmdVbva, VBVAEXHOSTCTL* pCtl)
+{
+    switch (pCtl->enmType)
+    {
+        case VBVAEXHOSTCTL_TYPE_HH_INTERNAL_PAUSE:
+            if (pCmdVbva->i32EnableState > VBVAEXHOSTCONTEXT_ESTATE_PAUSED)
+                ASMAtomicWriteS32(&pCmdVbva->i32EnableState, VBVAEXHOSTCONTEXT_ESTATE_PAUSED);
+            return true;
+        case VBVAEXHOSTCTL_TYPE_HH_INTERNAL_RESUME:
+            if (pCmdVbva->i32EnableState == VBVAEXHOSTCONTEXT_ESTATE_PAUSED)
+                ASMAtomicWriteS32(&pCmdVbva->i32EnableState, VBVAEXHOSTCONTEXT_ESTATE_ENABLED);
+            return true;
+        default:
+            return false;
+    }
+}
+
+static void vboxVBVAExHPProcessorRelease(struct VBVAEXHOSTCONTEXT *pCmdVbva)
+{
+    Assert(pCmdVbva->i32State == VBVAEXHOSTCONTEXT_STATE_PROCESSING);
+
+    ASMAtomicWriteS32(&pCmdVbva->i32State, VBVAEXHOSTCONTEXT_STATE_LISTENING);
+}
+
+static void vboxVBVAExHPHgEventSet(struct VBVAEXHOSTCONTEXT *pCmdVbva)
+{
+    Assert(pCmdVbva->i32State == VBVAEXHOSTCONTEXT_STATE_PROCESSING);
+    if (pCmdVbva->pVBVA)
+        ASMAtomicOrU32(&pCmdVbva->pVBVA->hostFlags.u32HostEvents, VBVA_F_STATE_PROCESSING);
+}
+
+static void vboxVBVAExHPHgEventClear(struct VBVAEXHOSTCONTEXT *pCmdVbva)
+{
+    Assert(pCmdVbva->i32State == VBVAEXHOSTCONTEXT_STATE_PROCESSING);
+    if (pCmdVbva->pVBVA)
+        ASMAtomicAndU32(&pCmdVbva->pVBVA->hostFlags.u32HostEvents, ~VBVA_F_STATE_PROCESSING);
+}
+
+static int vboxVBVAExHPCmdGet(struct VBVAEXHOSTCONTEXT *pCmdVbva, uint8_t **ppCmd, uint32_t *pcbCmd)
+{
+    Assert(pCmdVbva->i32State == VBVAEXHOSTCONTEXT_STATE_PROCESSING);
+    Assert(pCmdVbva->i32EnableState > VBVAEXHOSTCONTEXT_ESTATE_PAUSED);
+
+    VBVABUFFER *pVBVA = pCmdVbva->pVBVA;
+
+    uint32_t indexRecordFirst = pVBVA->indexRecordFirst;
+    uint32_t indexRecordFree = pVBVA->indexRecordFree;
+
+    Log(("first = %d, free = %d\n",
+                   indexRecordFirst, indexRecordFree));
+
+    if (indexRecordFirst == indexRecordFree)
+    {
+        /* No records to process. Return without assigning output variables. */
+        return VINF_EOF;
+    }
+
+    uint32_t cbRecordCurrent = ASMAtomicReadU32(&pVBVA->aRecords[indexRecordFirst].cbRecord);
+
+    /* A new record need to be processed. */
+    if (cbRecordCurrent & VBVA_F_RECORD_PARTIAL)
+    {
+        /* the record is being recorded, try again */
+        return VINF_TRY_AGAIN;
+    }
+
+    uint32_t cbRecord = cbRecordCurrent & ~VBVA_F_RECORD_PARTIAL;
+
+    if (!cbRecord)
+    {
+        /* the record is being recorded, try again */
+        return VINF_TRY_AGAIN;
+    }
+
+    /* we should not get partial commands here actually */
+    Assert(cbRecord);
+
+    /* The size of largest contiguous chunk in the ring biffer. */
+    uint32_t u32BytesTillBoundary = pVBVA->cbData - pVBVA->off32Data;
+
+    /* The pointer to data in the ring buffer. */
+    uint8_t *pSrc = &pVBVA->au8Data[pVBVA->off32Data];
+
+    /* Fetch or point the data. */
+    if (u32BytesTillBoundary >= cbRecord)
+    {
+        /* The command does not cross buffer boundary. Return address in the buffer. */
+        *ppCmd = pSrc;
+        *pcbCmd = cbRecord;
+        return VINF_SUCCESS;
+    }
+
+    LogRel(("CmdVbva: cross-bound writes unsupported\n"));
+    return VERR_INVALID_STATE;
+}
+
+static void VBoxVBVAExHPDataCompleteCmd(struct VBVAEXHOSTCONTEXT *pCmdVbva, uint32_t cbCmd)
+{
+    VBVABUFFER *pVBVA = pCmdVbva->pVBVA;
+    pVBVA->off32Data = (pVBVA->off32Data + cbCmd) % pVBVA->cbData;
+
+    pVBVA->indexRecordFirst = (pVBVA->indexRecordFirst + 1) % RT_ELEMENTS(pVBVA->aRecords);
+}
+
+static void VBoxVBVAExHPDataCompleteCtl(struct VBVAEXHOSTCONTEXT *pCmdVbva, VBVAEXHOSTCTL *pCtl, int rc)
+{
+    if (pCtl->pfnComplete)
+        pCtl->pfnComplete(pCmdVbva, pCtl, rc, pCtl->pvComplete);
+    else
+        VBoxVBVAExHCtlFree(pCmdVbva, pCtl);
+}
+
+static VBVAEXHOST_DATA_TYPE vboxVBVAExHPDataGet(struct VBVAEXHOSTCONTEXT *pCmdVbva, uint8_t **ppCmd, uint32_t *pcbCmd)
+{
+    Assert(pCmdVbva->i32State == VBVAEXHOSTCONTEXT_STATE_PROCESSING);
+    VBVAEXHOSTCTL*pCtl;
+    bool fHostClt;
+
+    for(;;)
+    {
+        pCtl = vboxVBVAExHPCheckCtl(pCmdVbva, &fHostClt, false);
+        if (pCtl)
+        {
+            if (fHostClt)
+            {
+                if (!vboxVBVAExHPCheckProcessCtlInternal(pCmdVbva, pCtl))
+                {
+                    *ppCmd = (uint8_t*)pCtl;
+                    *pcbCmd = sizeof (*pCtl);
+                    return VBVAEXHOST_DATA_TYPE_HOSTCTL;
+                }
+            }
+            else
+            {
+                *ppCmd = (uint8_t*)pCtl;
+                *pcbCmd = sizeof (*pCtl);
+                return VBVAEXHOST_DATA_TYPE_GUESTCTL;
+            }
+        }
+
+        if (ASMAtomicUoReadS32(&pCmdVbva->i32EnableState) <= VBVAEXHOSTCONTEXT_ESTATE_PAUSED)
+            return VBVAEXHOST_DATA_TYPE_NO_DATA;
+
+        int rc = vboxVBVAExHPCmdGet(pCmdVbva, ppCmd, pcbCmd);
+        switch (rc)
+        {
+            case VINF_SUCCESS:
+                return VBVAEXHOST_DATA_TYPE_CMD;
+            case VINF_EOF:
+                return VBVAEXHOST_DATA_TYPE_NO_DATA;
+            case VINF_TRY_AGAIN:
+                RTThreadSleep(1);
+                continue;
+            default:
+                /* this is something really unexpected, i.e. most likely guest has written something incorrect to the VBVA buffer */
+                WARN(("Warning: vboxVBVAExHCmdGet returned unexpected status %d\n", rc));
+                return VBVAEXHOST_DATA_TYPE_NO_DATA;
+        }
+    }
+
+    WARN(("Warning: VBoxVBVAExHCmdGet unexpected state\n"));
+    return VBVAEXHOST_DATA_TYPE_NO_DATA;
+}
+
+static VBVAEXHOST_DATA_TYPE VBoxVBVAExHPDataGet(struct VBVAEXHOSTCONTEXT *pCmdVbva, uint8_t **ppCmd, uint32_t *pcbCmd)
+{
+    VBVAEXHOST_DATA_TYPE enmType = vboxVBVAExHPDataGet(pCmdVbva, ppCmd, pcbCmd);
+    if (enmType == VBVAEXHOST_DATA_TYPE_NO_DATA)
+    {
+        vboxVBVAExHPHgEventClear(pCmdVbva);
+        vboxVBVAExHPProcessorRelease(pCmdVbva);
+        /* we need to prevent racing between us clearing the flag and command check/submission thread, i.e.
+         * 1. we check the queue -> and it is empty
+         * 2. submitter adds command to the queue
+         * 3. submitter checks the "processing" -> and it is true , thus it does not submit a notification
+         * 4. we clear the "processing" state
+         * 5. ->here we need to re-check the queue state to ensure we do not leak the notification of the above command
+         * 6. if the queue appears to be not-empty set the "processing" state back to "true"
+         **/
+        int rc = vboxVBVAExHSProcessorAcquire(pCmdVbva);
+        if (RT_SUCCESS(rc))
+        {
+            /* we are the processor now */
+            enmType = vboxVBVAExHPDataGet(pCmdVbva, ppCmd, pcbCmd);
+            if (enmType == VBVAEXHOST_DATA_TYPE_NO_DATA)
+            {
+                vboxVBVAExHPProcessorRelease(pCmdVbva);
+                return VBVAEXHOST_DATA_TYPE_NO_DATA;
+            }
+
+            vboxVBVAExHPHgEventSet(pCmdVbva);
+        }
+    }
+
+    return enmType;
+}
+
+DECLINLINE(bool) vboxVBVAExHSHasCommands(struct VBVAEXHOSTCONTEXT *pCmdVbva)
+{
+    VBVABUFFER *pVBVA = pCmdVbva->pVBVA;
+
+    if (pVBVA)
+    {
+        uint32_t indexRecordFirst = pVBVA->indexRecordFirst;
+        uint32_t indexRecordFree = pVBVA->indexRecordFree;
+
+        if (indexRecordFirst != indexRecordFree)
+            return true;
+    }
+
+    return !!ASMAtomicReadU32(&pCmdVbva->u32cCtls);
+}
+
+/* Checks whether the new commands are ready for processing
+ * @returns
+ *   VINF_SUCCESS - there are commands are in a queue, and the given thread is now the processor (i.e. typically it would delegate processing to a worker thread)
+ *   VINF_EOF - no commands in a queue
+ *   VINF_ALREADY_INITIALIZED - another thread already processing the commands
+ *   VERR_INVALID_STATE - the VBVA is paused or pausing */
+static int VBoxVBVAExHSCheckCommands(struct VBVAEXHOSTCONTEXT *pCmdVbva)
+{
+    int rc = vboxVBVAExHSProcessorAcquire(pCmdVbva);
+    if (RT_SUCCESS(rc))
+    {
+        /* we are the processor now */
+        if (vboxVBVAExHSHasCommands(pCmdVbva))
+        {
+            vboxVBVAExHPHgEventSet(pCmdVbva);
+            return VINF_SUCCESS;
+        }
+
+        vboxVBVAExHPProcessorRelease(pCmdVbva);
+        return VINF_EOF;
+    }
+    if (rc == VERR_SEM_BUSY)
+        return VINF_ALREADY_INITIALIZED;
+    return VERR_INVALID_STATE;
+}
+
+static int VBoxVBVAExHSInit(struct VBVAEXHOSTCONTEXT *pCmdVbva)
+{
+    memset(pCmdVbva, 0, sizeof (*pCmdVbva));
+    int rc = RTCritSectInit(&pCmdVbva->CltCritSect);
+    if (RT_SUCCESS(rc))
+    {
+#ifndef VBOXVDBG_MEMCACHE_DISABLE
+        rc = RTMemCacheCreate(&pCmdVbva->CtlCache, sizeof (VBVAEXHOSTCTL),
+                                0, /* size_t cbAlignment */
+                                UINT32_MAX, /* uint32_t cMaxObjects */
+                                NULL, /* PFNMEMCACHECTOR pfnCtor*/
+                                NULL, /* PFNMEMCACHEDTOR pfnDtor*/
+                                NULL, /* void *pvUser*/
+                                0 /* uint32_t fFlags*/
+                                );
+        if (RT_SUCCESS(rc))
+#endif
+        {
+            RTListInit(&pCmdVbva->GuestCtlList);
+            RTListInit(&pCmdVbva->HostCtlList);
+            pCmdVbva->i32State = VBVAEXHOSTCONTEXT_STATE_PROCESSING;
+            pCmdVbva->i32EnableState = VBVAEXHOSTCONTEXT_ESTATE_DISABLED;
+            return VINF_SUCCESS;
+        }
+#ifndef VBOXVDBG_MEMCACHE_DISABLE
+        else
+            WARN(("RTMemCacheCreate failed %d\n", rc));
+#endif
+    }
+    else
+        WARN(("RTCritSectInit failed %d\n", rc));
+
+    return rc;
+}
+
+DECLINLINE(bool) VBoxVBVAExHSIsEnabled(struct VBVAEXHOSTCONTEXT *pCmdVbva)
+{
+    return (ASMAtomicUoReadS32(&pCmdVbva->i32EnableState) >= VBVAEXHOSTCONTEXT_ESTATE_PAUSED);
+}
+
+static int VBoxVBVAExHSEnable(struct VBVAEXHOSTCONTEXT *pCmdVbva, VBVABUFFER *pVBVA)
+{
+    if (VBoxVBVAExHSIsEnabled(pCmdVbva))
+        return VINF_ALREADY_INITIALIZED;
+
+    pCmdVbva->pVBVA = pVBVA;
+    pCmdVbva->pVBVA->hostFlags.u32HostEvents = 0;
+    ASMAtomicWriteS32(&pCmdVbva->i32EnableState, VBVAEXHOSTCONTEXT_ESTATE_ENABLED);
+    return VINF_SUCCESS;
+}
+
+static int VBoxVBVAExHSDisable(struct VBVAEXHOSTCONTEXT *pCmdVbva)
+{
+    if (!VBoxVBVAExHSIsEnabled(pCmdVbva))
+        return VINF_SUCCESS;
+
+    ASMAtomicWriteS32(&pCmdVbva->i32EnableState, VBVAEXHOSTCONTEXT_ESTATE_DISABLED);
+    return VINF_SUCCESS;
+}
+
+static void VBoxVBVAExHSTerm(struct VBVAEXHOSTCONTEXT *pCmdVbva)
+{
+    /* ensure the processor is stopped */
+    Assert(pCmdVbva->i32State >= VBVAEXHOSTCONTEXT_STATE_LISTENING);
+
+    /* ensure no one tries to submit the command */
+    if (pCmdVbva->pVBVA)
+        pCmdVbva->pVBVA->hostFlags.u32HostEvents = 0;
+
+    Assert(RTListIsEmpty(&pCmdVbva->GuestCtlList));
+    Assert(RTListIsEmpty(&pCmdVbva->HostCtlList));
+
+    RTCritSectDelete(&pCmdVbva->CltCritSect);
+
+#ifndef VBOXVDBG_MEMCACHE_DISABLE
+    RTMemCacheDestroy(pCmdVbva->CtlCache);
+#endif
+
+    memset(pCmdVbva, 0, sizeof (*pCmdVbva));
+}
+
+/* Saves state
+ * @returns - same as VBoxVBVAExHSCheckCommands, or failure on load state fail
+ */
+static int VBoxVBVAExHSSaveState(struct VBVAEXHOSTCONTEXT *pCmdVbva, uint8_t* pu8VramBase, PSSMHANDLE pSSM)
+{
+    int rc;
+
+    int32_t i32EnableState = ASMAtomicUoReadS32(&pCmdVbva->i32EnableState);
+    if (i32EnableState >= VBVAEXHOSTCONTEXT_ESTATE_PAUSED)
+    {
+        if (i32EnableState != VBVAEXHOSTCONTEXT_ESTATE_PAUSED)
+        {
+            WARN(("vbva not paused\n"));
+            return VERR_INVALID_STATE;
+        }
+
+        rc = SSMR3PutU32(pSSM, (uint32_t)(((uint8_t*)pCmdVbva->pVBVA) - pu8VramBase));
+        AssertRCReturn(rc, rc);
+        return VINF_SUCCESS;
+    }
+
+    rc = SSMR3PutU32(pSSM, 0xffffffff);
+    AssertRCReturn(rc, rc);
+
+    return VINF_SUCCESS;
+}
+
+typedef enum
+{
+    VBVAEXHOSTCTL_SOURCE_GUEST = 0,
+    VBVAEXHOSTCTL_SOURCE_HOST_ANY,
+    VBVAEXHOSTCTL_SOURCE_HOST_ENABLED
+} VBVAEXHOSTCTL_SOURCE;
+
+
+static int VBoxVBVAExHCtlSubmit(VBVAEXHOSTCONTEXT *pCmdVbva, VBVAEXHOSTCTL* pCtl, VBVAEXHOSTCTL_SOURCE enmSource, PFNVBVAEXHOSTCTL_COMPLETE pfnComplete, void *pvComplete)
+{
+    if ((enmSource == VBVAEXHOSTCTL_SOURCE_HOST_ENABLED) && !VBoxVBVAExHSIsEnabled(pCmdVbva))
+    {
+        WARN(("cmd vbva not enabled\n"));
+        return VERR_INVALID_STATE;
+    }
+
+    pCtl->pfnComplete = pfnComplete;
+    pCtl->pvComplete = pvComplete;
+
+    int rc = RTCritSectEnter(&pCmdVbva->CltCritSect);
+    if (RT_SUCCESS(rc))
+    {
+        if (enmSource > VBVAEXHOSTCTL_SOURCE_GUEST)
+        {
+            if ((enmSource == VBVAEXHOSTCTL_SOURCE_HOST_ENABLED) && !VBoxVBVAExHSIsEnabled(pCmdVbva))
+            {
+                WARN(("cmd vbva not enabled\n"));
+                RTCritSectLeave(&pCmdVbva->CltCritSect);
+                return VERR_INVALID_STATE;
+            }
+            RTListAppend(&pCmdVbva->HostCtlList, &pCtl->Node);
+        }
+        else
+            RTListAppend(&pCmdVbva->GuestCtlList, &pCtl->Node);
+
+        ASMAtomicIncU32(&pCmdVbva->u32cCtls);
+
+        RTCritSectLeave(&pCmdVbva->CltCritSect);
+
+        rc = VBoxVBVAExHSCheckCommands(pCmdVbva);
+    }
+    else
+        WARN(("RTCritSectEnter failed %d\n", rc));
+
+    return rc;
+}
+
+
+/* Loads state
+ * @returns - same as VBoxVBVAExHSCheckCommands, or failure on load state fail
+ */
+static int VBoxVBVAExHSLoadState(struct VBVAEXHOSTCONTEXT *pCmdVbva, uint8_t* pu8VramBase, PSSMHANDLE pSSM, uint32_t u32Version)
+{
+    AssertMsgFailed(("implement!\n"));
+    uint32_t u32;
+    int rc = SSMR3GetU32(pSSM, &u32);
+    AssertRCReturn(rc, rc);
+    if (u32 != 0xffffffff)
+    {
+        VBVABUFFER *pVBVA = (VBVABUFFER*)pu8VramBase + u32;
+        rc = VBoxVBVAExHSEnable(pCmdVbva, pVBVA);
+        AssertRCReturn(rc, rc);
+        return VBoxVBVAExHSCheckCommands(pCmdVbva);
+    }
+
+    return VINF_SUCCESS;
+}
+
+typedef struct VBOXVDMAHOST
 {
-    VBOXVDMAPIPE_STATE_CLOSED    = 0,
-    VBOXVDMAPIPE_STATE_CREATED   = 1,
-    VBOXVDMAPIPE_STATE_OPENNED   = 2,
-    VBOXVDMAPIPE_STATE_CLOSING   = 3
-} VBOXVDMAPIPE_STATE;
+    PHGSMIINSTANCE pHgsmi;
+    PVGASTATE pVGAState;
+    VBVAEXHOSTCONTEXT CmdVbva;
+    VBOXVDMATHREAD Thread;
+    VBOXCRCMD_SVRINFO CrSrvInfo;
+    VBVAEXHOSTCTL* pCurRemainingHostCtl;
+#ifdef VBOX_VDMA_WITH_WATCHDOG
+    PTMTIMERR3 WatchDogTimer;
+#endif
+} VBOXVDMAHOST, *PVBOXVDMAHOST;
 
-typedef struct VBOXVDMAPIPE
+int VBoxVDMAThreadNotifyConstructSucceeded(PVBOXVDMATHREAD pThread)
 {
-    RTSEMEVENT hEvent;
-    /* critical section for accessing pipe properties */
-    RTCRITSECT hCritSect;
-    VBOXVDMAPIPE_STATE enmState;
-    /* true iff the other end needs Event notification */
-    bool bNeedNotify;
-} VBOXVDMAPIPE, *PVBOXVDMAPIPE;
+    Assert(pThread->u32State == VBOXVDMATHREAD_STATE_TERMINATED);
+    pThread->u32State = VBOXVDMATHREAD_STATE_CREATED;
+    int rc = RTSemEventSignal(pThread->hClientEvent);
+    AssertRC(rc);
+    return VINF_SUCCESS;
+}
 
-typedef enum
+int VBoxVDMAThreadNotifyConstructFailed(PVBOXVDMATHREAD pThread)
 {
-    VBOXVDMAPIPE_CMD_TYPE_UNDEFINED = 0,
-    VBOXVDMAPIPE_CMD_TYPE_DMACMD    = 1,
-    VBOXVDMAPIPE_CMD_TYPE_DMACTL    = 2
-} VBOXVDMAPIPE_CMD_TYPE;
+    Assert(pThread->u32State == VBOXVDMATHREAD_STATE_TERMINATED);
+    int rc = RTSemEventSignal(pThread->hClientEvent);
+    AssertRC(rc);
+    if (RT_SUCCESS(rc))
+        return VINF_SUCCESS;
+    return rc;
+}
 
-typedef struct VBOXVDMAPIPE_CMD_BODY
+DECLINLINE(bool) VBoxVDMAThreadIsTerminating(PVBOXVDMATHREAD pThread)
 {
-    VBOXVDMAPIPE_CMD_TYPE enmType;
-    union
-    {
-        PVBOXVDMACBUF_DR pDr;
-        PVBOXVDMA_CTL    pCtl;
-        void            *pvCmd;
-    } u;
-}VBOXVDMAPIPE_CMD_BODY, *PVBOXVDMAPIPE_CMD_BODY;
+    return ASMAtomicUoReadU32(&pThread->u32State) == VBOXVDMATHREAD_STATE_TERMINATING;
+}
 
-typedef struct VBOXVDMAPIPE_CMD
+int VBoxVDMAThreadCreate(PVBOXVDMATHREAD pThread, PFNRTTHREAD pfnThread, void *pvThread)
 {
-    HGSMILISTENTRY Entry;
-    VBOXVDMAPIPE_CMD_BODY Cmd;
-} VBOXVDMAPIPE_CMD, *PVBOXVDMAPIPE_CMD;
+    int rc = RTSemEventCreate(&pThread->hEvent);
+    if (RT_SUCCESS(rc))
+    {
+        rc = RTSemEventCreate(&pThread->hClientEvent);
+        if (RT_SUCCESS(rc))
+        {
+            pThread->u32State = VBOXVDMATHREAD_STATE_TERMINATED;
+            rc = RTThreadCreate(&pThread->hWorkerThread, pfnThread, pvThread, 0, RTTHREADTYPE_IO, RTTHREADFLAGS_WAITABLE, "VDMA");
+            if (RT_SUCCESS(rc))
+            {
+                rc = RTSemEventWait(pThread->hClientEvent, RT_INDEFINITE_WAIT);
+                if (RT_SUCCESS(rc))
+                {
+                    if (pThread->u32State == VBOXVDMATHREAD_STATE_CREATED)
+                        return VINF_SUCCESS;
+                    WARN(("thread routine failed the initialization\n"));
+                    rc = VERR_INVALID_STATE;
+                }
+                else
+                    WARN(("RTSemEventWait failed %d\n", rc));
 
-#define VBOXVDMAPIPE_CMD_FROM_ENTRY(_pE)  ( (PVBOXVDMAPIPE_CMD)((uint8_t *)(_pE) - RT_OFFSETOF(VBOXVDMAPIPE_CMD, Entry)) )
+                RTThreadWait(pThread->hWorkerThread, RT_INDEFINITE_WAIT, NULL);
+            }
+            else
+                WARN(("RTThreadCreate failed %d\n", rc));
 
-typedef struct VBOXVDMAPIPE_CMD_POOL
-{
-    HGSMILIST List;
-    uint32_t cCmds;
-    VBOXVDMAPIPE_CMD aCmds[1];
-} VBOXVDMAPIPE_CMD_POOL, *PVBOXVDMAPIPE_CMD_POOL;
-#endif
+            RTSemEventDestroy(pThread->hClientEvent);
+        }
+        else
+            WARN(("RTSemEventCreate failed %d\n", rc));
 
+        RTSemEventDestroy(pThread->hEvent);
+    }
+    else
+        WARN(("RTSemEventCreate failed %d\n", rc));
 
-/* state transformations:
- *
- *   submitter   |    processor
- *   STOPPED
- *      |
- *      |
- *      >
- *  LISTENING   --->  PROCESSING
- *      ^               _/
- *      |             _/
- *      |           _/
- *      |         _/
- *      |       _/
- *      |     _/
- *      |    /
- *      <   >
- *     PAUSED
- *
- *  */
-#define VBVAEXHOSTCONTEXT_STATE_STOPPED        0
-#define VBVAEXHOSTCONTEXT_STATE_LISTENING      1
-#define VBVAEXHOSTCONTEXT_STATE_PROCESSING     2
-#define VBVAEXHOSTCONTEXT_STATE_PAUSED         3
+    return rc;
+}
 
-typedef struct VBVAEXHOSTCONTEXT
+DECLINLINE(int) VBoxVDMAThreadEventNotify(PVBOXVDMATHREAD pThread)
 {
-    VBVABUFFER *pVBVA;
-    uint32_t cbCurData;
-    volatile uint32_t u32State;
-    volatile uint32_t u32Pause;
-    volatile uint32_t u32cOtherCommands;
-} VBVAEXHOSTCONTEXT;
-
-/* VBoxVBVAExHP**, i.e. processor functions, can NOT be called concurrently with each other,
- * but can be called with other VBoxVBVAExS** (submitter) functions except Init/Start/Term aparently.
- * Can only be called be the processor, i.e. the entity that acquired the processor state by direct or indirect call to the VBoxVBVAExHSCheckCommands
- * see mor edetailed comments in headers for function definitions */
-static bool VBoxVBVAExHPCmdCheckRelease(struct VBVAEXHOSTCONTEXT *pCmdVbva);
-static int VBoxVBVAExHPCmdGet(struct VBVAEXHOSTCONTEXT *pCmdVbva, uint8_t **ppCmd, uint32_t *pcbCmd);
+    int rc = RTSemEventSignal(pThread->hEvent);
+    AssertRC(rc);
+    return rc;
+}
 
-/* VBoxVBVAExHP**, i.e. processor functions, can NOT be called concurrently with each other,
- * can be called concurrently with istelf as well as with other VBoxVBVAEx** functions except Init/Start/Term aparently */
-static int VBoxVBVAExHSCheckCommands(struct VBVAEXHOSTCONTEXT *pCmdVbva);
+DECLINLINE(int) VBoxVDMAThreadEventWait(PVBOXVDMATHREAD pThread, RTMSINTERVAL cMillies)
+{
+    int rc = RTSemEventWait(pThread->hEvent, cMillies);
+    AssertRC(rc);
+    return rc;
+}
 
-static void VBoxVBVAExHSInit(struct VBVAEXHOSTCONTEXT *pCmdVbva);
-static int VBoxVBVAExHSEnable(struct VBVAEXHOSTCONTEXT *pCmdVbva, VBVABUFFER *pVBVA);
-static int VBoxVBVAExHSDisable(struct VBVAEXHOSTCONTEXT *pCmdVbva);
-static void VBoxVBVAExHSTerm(struct VBVAEXHOSTCONTEXT *pCmdVbva);
-static int VBoxVBVAExHSSaveState(struct VBVAEXHOSTCONTEXT *pCmdVbva, uint8_t* pu8VramBase, PSSMHANDLE pSSM);
-static int VBoxVBVAExHSLoadState(struct VBVAEXHOSTCONTEXT *pCmdVbva, uint8_t* pu8VramBase, PSSMHANDLE pSSM, uint32_t u32Version);
+void VBoxVDMAThreadMarkTerminating(PVBOXVDMATHREAD pThread)
+{
+    Assert(pThread->u32State == VBOXVDMATHREAD_STATE_CREATED);
+    ASMAtomicWriteU32(&pThread->u32State, VBOXVDMATHREAD_STATE_TERMINATING);
+}
 
-typedef struct VBOXVDMAHOST
+void VBoxVDMAThreadTerm(PVBOXVDMATHREAD pThread)
 {
-    PHGSMIINSTANCE pHgsmi;
-    PVGASTATE pVGAState;
-    VBVAEXHOSTCONTEXT CmdVbva;
-#ifdef VBOX_VDMA_WITH_WATCHDOG
-    PTMTIMERR3 WatchDogTimer;
-#endif
-#ifdef VBOX_VDMA_WITH_WORKERTHREAD
-    VBOXVDMAPIPE Pipe;
-    HGSMILIST PendingList;
-    RTTHREAD hWorkerThread;
-    VBOXVDMAPIPE_CMD_POOL CmdPool;
-#endif
-} VBOXVDMAHOST, *PVBOXVDMAHOST;
+    int rc;
+    if (ASMAtomicReadU32(&pThread->u32State) != VBOXVDMATHREAD_STATE_TERMINATING)
+    {
+        VBoxVDMAThreadMarkTerminating(pThread);
+        rc = VBoxVDMAThreadEventNotify(pThread);
+        AssertRC(rc);
+    }
+    rc = RTThreadWait(pThread->hWorkerThread, RT_INDEFINITE_WAIT, NULL);
+    AssertRC(rc);
+    RTSemEventDestroy(pThread->hClientEvent);
+    RTSemEventDestroy(pThread->hEvent);
+}
 
+static int vdmaVBVACtlSubmitSync(PVBOXVDMAHOST pVdma, VBVAEXHOSTCTL* pCtl, VBVAEXHOSTCTL_SOURCE enmSource);
 
 #ifdef VBOX_WITH_CRHGSMI
 
@@ -248,39 +864,301 @@ static int vboxVDMACrCtlPost(PVGASTATE pVGAState, PVBOXVDMACMD_CHROMIUM_CTL pCmd
     AssertRC(rc);
     if(RT_SUCCESS(rc))
     {
-        rc = vboxVDMACrCtlPostAsync (pVGAState, pCmd, cbCmd, vboxVDMACrCtlCbSetEvent, (void*)hComplEvent);
+        rc = vboxVDMACrCtlPostAsync(pVGAState, pCmd, cbCmd, vboxVDMACrCtlCbSetEvent, (void*)hComplEvent);
 #ifdef DEBUG_misha
         AssertRC(rc);
 #endif
         if (RT_SUCCESS(rc))
         {
-            rc = RTSemEventWaitNoResume(hComplEvent, RT_INDEFINITE_WAIT);
-            AssertRC(rc);
-            if(RT_SUCCESS(rc))
+            rc = RTSemEventWaitNoResume(hComplEvent, RT_INDEFINITE_WAIT);
+            AssertRC(rc);
+            if(RT_SUCCESS(rc))
+            {
+                RTSemEventDestroy(hComplEvent);
+            }
+        }
+        else
+        {
+            /* the command is completed */
+            RTSemEventDestroy(hComplEvent);
+        }
+    }
+    return rc;
+}
+
+typedef struct VDMA_VBVA_CTL_CYNC_COMPLETION
+{
+    int rc;
+    RTSEMEVENT hEvent;
+} VDMA_VBVA_CTL_CYNC_COMPLETION;
+
+static DECLCALLBACK(void) vboxVDMACrHgcmSubmitSyncCompletion(struct VBOXCRCMDCTL* pCmd, uint32_t cbCmd, int rc, void *pvCompletion)
+{
+    VDMA_VBVA_CTL_CYNC_COMPLETION *pData = (VDMA_VBVA_CTL_CYNC_COMPLETION*)pvCompletion;
+    pData->rc = rc;
+    rc = RTSemEventSignal(pData->hEvent);
+    if (!RT_SUCCESS(rc))
+        WARN(("RTSemEventSignal failed %d\n", rc));
+}
+
+static int vboxVDMACrHgcmSubmitSync(struct VBOXVDMAHOST *pVdma, VBOXCRCMDCTL* pCtl, uint32_t cbCtl)
+{
+    VDMA_VBVA_CTL_CYNC_COMPLETION Data;
+    Data.rc = VERR_NOT_IMPLEMENTED;
+    int rc = RTSemEventCreate(&Data.hEvent);
+    if (!RT_SUCCESS(rc))
+    {
+        WARN(("RTSemEventCreate failed %d\n", rc));
+        return rc;
+    }
+
+    PVGASTATE pVGAState = pVdma->pVGAState;
+    rc = pVGAState->pDrv->pfnCrHgcmCtlSubmit(pVGAState->pDrv, pCtl, cbCtl, vboxVDMACrHgcmSubmitSyncCompletion, &Data);
+    if (RT_SUCCESS(rc))
+    {
+        rc = RTSemEventWait(Data.hEvent, RT_INDEFINITE_WAIT);
+        if (RT_SUCCESS(rc))
+        {
+            rc = Data.rc;
+            if (!RT_SUCCESS(rc))
+            {
+                WARN(("pfnCrHgcmCtlSubmit command failed %d\n", rc));
+            }
+
+        }
+        else
+            WARN(("RTSemEventWait failed %d\n", rc));
+    }
+    else
+        WARN(("pfnCrHgcmCtlSubmit failed %d\n", rc));
+
+
+    RTSemEventDestroy(Data.hEvent);
+
+    return rc;
+}
+
+static DECLCALLBACK(uint8_t*) vboxVDMACrHgcmHandleEnableRemainingHostCommand(HVBOXCRCMDCTL_REMAINING_HOST_COMMAND hClient, uint32_t *pcbCtl, int prevCmdRc)
+{
+    struct VBOXVDMAHOST *pVdma = hClient;
+    if (!pVdma->pCurRemainingHostCtl)
+    {
+        /* disable VBVA, all subsequent host commands will go HGCM way */
+        VBoxVBVAExHSDisable(&pVdma->CmdVbva);
+    }
+    else
+    {
+        VBoxVBVAExHPDataCompleteCtl(&pVdma->CmdVbva, pVdma->pCurRemainingHostCtl, prevCmdRc);
+    }
+
+    pVdma->pCurRemainingHostCtl = VBoxVBVAExHPCheckHostCtlOnDisable(&pVdma->CmdVbva);
+    if (pVdma->pCurRemainingHostCtl)
+    {
+        *pcbCtl = pVdma->pCurRemainingHostCtl->u.cmd.cbCmd;
+        return pVdma->pCurRemainingHostCtl->u.cmd.pu8Cmd;
+    }
+
+    *pcbCtl = 0;
+    return NULL;
+}
+
+static int vboxVDMACrHgcmHandleEnable(struct VBOXVDMAHOST *pVdma)
+{
+    VBOXCRCMDCTL_ENABLE Enable;
+    Enable.Hdr.enmType = VBOXCRCMDCTL_TYPE_ENABLE;
+    Enable.hRHCmd = pVdma;
+    Enable.pfnRHCmd = vboxVDMACrHgcmHandleEnableRemainingHostCommand;
+
+    int rc = vboxVDMACrHgcmSubmitSync(pVdma, &Enable.Hdr, sizeof (Enable));
+    Assert(!pVdma->pCurRemainingHostCtl);
+    if (RT_SUCCESS(rc))
+    {
+        Assert(!VBoxVBVAExHSIsEnabled(&pVdma->CmdVbva));
+        return VINF_SUCCESS;
+    }
+
+    Assert(VBoxVBVAExHSIsEnabled(&pVdma->CmdVbva));
+    WARN(("vboxVDMACrHgcmSubmitSync failed %d\n", rc));
+
+    return rc;
+}
+
+static int vdmaVBVAEnableProcess(struct VBOXVDMAHOST *pVdma, uint32_t u32Offset)
+{
+    if (VBoxVBVAExHSIsEnabled(&pVdma->CmdVbva))
+    {
+        WARN(("vdma VBVA is already enabled\n"));
+        return VERR_INVALID_STATE;
+    }
+
+    VBVABUFFER *pVBVA = (VBVABUFFER *)HGSMIOffsetToPointerHost(pVdma->pHgsmi, u32Offset);
+    if (!pVBVA)
+    {
+        WARN(("invalid offset %d\n", u32Offset));
+        return VERR_INVALID_PARAMETER;
+    }
+
+    if (!pVdma->CrSrvInfo.pfnEnable)
+    {
+#ifdef DEBUG_misha
+        WARN(("pfnEnable is NULL\n"));
+        return VERR_NOT_SUPPORTED;
+#endif
+    }
+
+    int rc = VBoxVBVAExHSEnable(&pVdma->CmdVbva, pVBVA);
+    if (RT_SUCCESS(rc))
+    {
+        VBOXCRCMDCTL Ctl;
+        Ctl.enmType = VBOXCRCMDCTL_TYPE_DISABLE;
+        rc = vboxVDMACrHgcmSubmitSync(pVdma, &Ctl, sizeof (Ctl));
+        if (RT_SUCCESS(rc))
+        {
+            PVGASTATE pVGAState = pVdma->pVGAState;
+            VBOXCRCMD_SVRENABLE_INFO Info;
+            Info.hCltScr = pVGAState->pDrv;
+            Info.pfnCltScrUpdateBegin = pVGAState->pDrv->pfnVBVAUpdateBegin;
+            Info.pfnCltScrUpdateProcess = pVGAState->pDrv->pfnVBVAUpdateProcess;
+            Info.pfnCltScrUpdateEnd = pVGAState->pDrv->pfnVBVAUpdateEnd;
+            rc = pVdma->CrSrvInfo.pfnEnable(pVdma->CrSrvInfo.hSvr, &Info);
+            if (RT_SUCCESS(rc))
+                return VINF_SUCCESS;
+            else
+                WARN(("pfnEnable failed %d\n", rc));
+
+            vboxVDMACrHgcmHandleEnable(pVdma);
+        }
+        else
+            WARN(("vboxVDMACrHgcmSubmitSync failed %d\n", rc));
+
+        VBoxVBVAExHSDisable(&pVdma->CmdVbva);
+    }
+    else
+        WARN(("VBoxVBVAExHSEnable failed %d\n", rc));
+
+    return rc;
+}
+
+static int vdmaVBVADisableProcess(struct VBOXVDMAHOST *pVdma)
+{
+    if (!VBoxVBVAExHSIsEnabled(&pVdma->CmdVbva))
+    {
+        Log(("vdma VBVA is already disabled\n"));
+        return VINF_SUCCESS;
+    }
+
+    int rc = pVdma->CrSrvInfo.pfnDisable(pVdma->CrSrvInfo.hSvr);
+    if (RT_SUCCESS(rc))
+    {
+        /* disable is a bit tricky
+         * we need to ensure the host ctl commands do not come out of order
+         * and do not come over HGCM channel until after it is enabled */
+        rc = vboxVDMACrHgcmHandleEnable(pVdma);
+        if (RT_SUCCESS(rc))
+            return rc;
+
+        PVGASTATE pVGAState = pVdma->pVGAState;
+        VBOXCRCMD_SVRENABLE_INFO Info;
+        Info.hCltScr = pVGAState->pDrv;
+        Info.pfnCltScrUpdateBegin = pVGAState->pDrv->pfnVBVAUpdateBegin;
+        Info.pfnCltScrUpdateProcess = pVGAState->pDrv->pfnVBVAUpdateProcess;
+        Info.pfnCltScrUpdateEnd = pVGAState->pDrv->pfnVBVAUpdateEnd;
+        pVdma->CrSrvInfo.pfnEnable(pVdma->CrSrvInfo.hSvr, &Info);
+    }
+    else
+        WARN(("pfnDisable failed %d\n", rc));
+
+    return rc;
+}
+
+static int vboxVDMACrHostCtlProcess(struct VBOXVDMAHOST *pVdma, VBVAEXHOSTCTL *pCmd)
+{
+    switch (pCmd->enmType)
+    {
+        case VBVAEXHOSTCTL_TYPE_HH_SAVESTATE:
+            if (!VBoxVBVAExHSIsEnabled(&pVdma->CmdVbva))
+            {
+                WARN(("VBVAEXHOSTCTL_TYPE_HH_SAVESTATE for disabled vdma VBVA\n"));
+                return VERR_INVALID_STATE;
+            }
+            return pVdma->CrSrvInfo.pfnSaveState(pVdma->CrSrvInfo.hSvr, pCmd->u.state.pSSM);
+        case VBVAEXHOSTCTL_TYPE_HH_LOADSTATE:
+            if (!VBoxVBVAExHSIsEnabled(&pVdma->CmdVbva))
+            {
+                WARN(("VBVAEXHOSTCTL_TYPE_HH_LOADSTATE for disabled vdma VBVA\n"));
+                return VERR_INVALID_STATE;
+            }
+            return pVdma->CrSrvInfo.pfnLoadState(pVdma->CrSrvInfo.hSvr, pCmd->u.state.pSSM, pCmd->u.state.u32Version);
+        case VBVAEXHOSTCTL_TYPE_GHH_BE_OPAQUE:
+            if (!VBoxVBVAExHSIsEnabled(&pVdma->CmdVbva))
+            {
+                WARN(("VBVAEXHOSTCTL_TYPE_GHH_BE_OPAQUE for disabled vdma VBVA\n"));
+                return VERR_INVALID_STATE;
+            }
+            return pVdma->CrSrvInfo.pfnHostCtl(pVdma->CrSrvInfo.hSvr, pCmd->u.cmd.pu8Cmd, pCmd->u.cmd.cbCmd);
+        case VBVAEXHOSTCTL_TYPE_HH_TERM:
+        {
+            int rc = vdmaVBVADisableProcess(pVdma);
+            if (!RT_SUCCESS(rc))
+            {
+                WARN(("vdmaVBVADisableProcess failed %d\n", rc));
+                return rc;
+            }
+
+            VBoxVDMAThreadMarkTerminating(&pVdma->Thread);
+            return VINF_SUCCESS;
+        }
+        case VBVAEXHOSTCTL_TYPE_HH_RESET:
+        {
+            int rc = vdmaVBVADisableProcess(pVdma);
+            if (!RT_SUCCESS(rc))
+            {
+                WARN(("vdmaVBVADisableProcess failed %d\n", rc));
+                return rc;
+            }
+            return VINF_SUCCESS;
+        }
+        default:
+            WARN(("unexpected host ctl type %d\n", pCmd->enmType));
+            return VERR_INVALID_PARAMETER;
+    }
+}
+
+static int vboxVDMACrGuestCtlProcess(struct VBOXVDMAHOST *pVdma, VBVAEXHOSTCTL *pCmd)
+{
+    switch (pCmd->enmType)
+    {
+       case VBVAEXHOSTCTL_TYPE_GHH_BE_OPAQUE:
+           if (!VBoxVBVAExHSIsEnabled(&pVdma->CmdVbva))
+           {
+               WARN(("VBVAEXHOSTCTL_TYPE_GHH_BE_OPAQUE for disabled vdma VBVA\n"));
+               return VERR_INVALID_STATE;
+           }
+           return pVdma->CrSrvInfo.pfnGuestCtl(pVdma->CrSrvInfo.hSvr, pCmd->u.cmd.pu8Cmd, pCmd->u.cmd.cbCmd);
+        case VBVAEXHOSTCTL_TYPE_GH_ENABLE_DISABLE:
+        {
+            VBVAENABLE *pEnable = (VBVAENABLE *)pCmd->u.cmd.pu8Cmd;
+            Assert(pCmd->u.cmd.cbCmd == sizeof (VBVAENABLE));
+            if ((pEnable->u32Flags & (VBVA_F_ENABLE | VBVA_F_DISABLE)) == VBVA_F_ENABLE)
             {
-                RTSemEventDestroy(hComplEvent);
+                uint32_t u32Offset = pEnable->u32Offset;
+                return vdmaVBVAEnableProcess(pVdma, u32Offset);
             }
+
+            return vdmaVBVADisableProcess(pVdma);
         }
-        else
-        {
-            /* the command is completed */
-            RTSemEventDestroy(hComplEvent);
-        }
+        default:
+            WARN(("unexpected ctl type %d\n", pCmd->enmType));
+            return VERR_INVALID_PARAMETER;
     }
-    return rc;
 }
 
-static void vboxVDMACrCmdNotifyPerform(struct VBOXVDMAHOST *pVdma)
-{
-    PVGASTATE pVGAState = pVdma->pVGAState;
-    pVGAState->pDrv->pfnCrCmdNotifyCmds(pVGAState->pDrv);
-}
 
 /*
  * @returns
  *
  */
-static int vboxVDMACrCmdPreprocess(struct VBOXVDMAHOST *pVdma, uint8_t* pu8Cmd, uint32_t cbCmd)
+static int vboxVDMACrCmdProcess(struct VBOXVDMAHOST *pVdma, uint8_t* pu8Cmd, uint32_t cbCmd)
 {
     if (*pu8Cmd == VBOXCMDVBVA_OPTYPE_NOP)
         return VINF_EOF;
@@ -298,96 +1176,74 @@ static int vboxVDMACrCmdPreprocess(struct VBOXVDMAHOST *pVdma, uint8_t* pu8Cmd,
     switch (pCmd->u8OpCode)
     {
         case VBOXCMDVBVA_OPTYPE_NOPCMD:
-            pCmd->i8Result = 0;
+            pCmd->u.i8Result = 0;
             return VINF_EOF;
         default:
             return VINF_SUCCESS;
     }
 }
 
-static DECLCALLBACK(int) vboxVDMACrCmdCltCmdGet(HVBOXCRCMDCLT hClt, PVBOXCMDVBVA_HDR *ppNextCmd, uint32_t *pcbNextCmd)
+static DECLCALLBACK(int) vboxVDMACrCmdEnable(HVBOXCRCMDSVR hSvr, VBOXCRCMD_SVRENABLE_INFO *pInfo)
 {
-    struct VBOXVDMAHOST *pVdma = hClt;
+    return VINF_SUCCESS;
+}
 
-    VBoxVBVAExHPCmdCheckRelease(&pVdma->CmdVbva);
+static DECLCALLBACK(void) vboxVDMACrCmdDisable(HVBOXCRCMDSVR hSvr)
+{
+}
 
-    uint32_t cbCmd;
-    uint8_t *pu8Cmd;
+static DECLCALLBACK(int) vboxVDMACrCmdCtl(HVBOXCRCMDSVR hSvr, uint8_t* pCmd, uint32_t cbCmd)
+{
+    return VERR_NOT_SUPPORTED;
+}
 
-    for(;;)
+static DECLCALLBACK(int) vboxVDMACrCmdCmd(HVBOXCRCMDSVR hSvr, PVBOXCMDVBVA_HDR pCmd, uint32_t cbCmd)
+{
+    switch (pCmd->u8OpCode)
     {
-        int rc = VBoxVBVAExHPCmdGet(&pVdma->CmdVbva, &pu8Cmd, &cbCmd);
-        switch (rc)
+#if 0
+        case VBOXCMDVBVA_OPTYPE_BLT_OFFPRIMSZFMT_OR_ID:
         {
-            case VINF_SUCCESS:
-            {
-                rc = vboxVDMACrCmdPreprocess(pVdma, pu8Cmd, cbCmd);
-                switch (rc)
-                {
-                    case VINF_SUCCESS:
-                        *ppNextCmd = (PVBOXCMDVBVA_HDR)pu8Cmd;
-                        *pcbNextCmd = cbCmd;
-                        return VINF_SUCCESS;
-                    case VINF_EOF:
-                        continue;
-                    default:
-                        Assert(!RT_FAILURE(rc));
-                        return RT_FAILURE(rc) ? rc : VERR_INTERNAL_ERROR;
-                }
-                break;
-            }
-            case VINF_EOF:
-                return VINF_EOF;
-            case VINF_PERMISSION_DENIED:
-                /* processing was paused, processing state was released, only VBoxVBVAExHS*** calls are now allowed */
-                return VINF_EOF;
-            case VINF_INTERRUPTED:
-                /* command processing was interrupted, processor state remains set. client can process any commands */
-                vboxVDMACrCmdNotifyPerform(pVdma);
-                return VINF_EOF;
-            default:
-                Assert(!RT_FAILURE(rc));
-                return RT_FAILURE(rc) ? rc : VERR_INTERNAL_ERROR;
+            crVBoxServerCrCmdBltProcess(pCmd, cbCmd);
+            break;
         }
+#endif
+        default:
+            WARN(("unsupported command\n"));
+            pCmd->u.i8Result = -1;
     }
-
-    WARN(("Warning: vboxVDMACrCmdCltCmdGet unexpected state\n"));
-    return VERR_INTERNAL_ERROR;
-}
-
-static DECLCALLBACK(int) vboxVDMACrCmdCltDmGet(HVBOXCRCMDCLT hClt, uint32_t idScreen, struct VBVAINFOSCREEN *pScreen, void **ppvVram)
-{
-    struct VBOXVDMAHOST *pVdma = hClt;
-    PVGASTATE pVGAState = pVdma->pVGAState;
-
-    return VBVAGetScreenInfo(pVGAState, idScreen, pScreen, ppvVram);
+    return VINF_SUCCESS;
 }
 
 static int vboxVDMACrCtlHgsmiSetup(struct VBOXVDMAHOST *pVdma)
 {
-    PVBOXVDMACMD_CHROMIUM_CTL_CRHGSMI_SETUP pCmd;
-    pCmd = (PVBOXVDMACMD_CHROMIUM_CTL_CRHGSMI_SETUP) vboxVDMACrCtlCreate (VBOXVDMACMD_CHROMIUM_CTL_TYPE_CRHGSMI_SETUP,
-                                                                          sizeof (*pCmd));
+    PVBOXVDMACMD_CHROMIUM_CTL_CRHGSMI_SETUP pCmd = (PVBOXVDMACMD_CHROMIUM_CTL_CRHGSMI_SETUP)
+            vboxVDMACrCtlCreate (VBOXVDMACMD_CHROMIUM_CTL_TYPE_CRHGSMI_SETUP, sizeof (*pCmd));
+    int rc = VERR_NO_MEMORY;
     if (pCmd)
     {
-        VBOXCRCMD_CLTINFO CltInfo;
-        CltInfo.hClient = pVdma;
-        CltInfo.pfnCmdGet = vboxVDMACrCmdCltCmdGet;
-        CltInfo.pfnDmGet = vboxVDMACrCmdCltDmGet;
         PVGASTATE pVGAState = pVdma->pVGAState;
         pCmd->pvVRamBase = pVGAState->vram_ptrR3;
         pCmd->cbVRam = pVGAState->vram_size;
-        pCmd->pCrCmdClientInfo = &CltInfo;
-        int rc = vboxVDMACrCtlPost(pVGAState, &pCmd->Hdr, sizeof (*pCmd));
-        Assert(RT_SUCCESS(rc) || rc == VERR_NOT_SUPPORTED);
+        rc = vboxVDMACrCtlPost(pVGAState, &pCmd->Hdr, sizeof (*pCmd));
         if (RT_SUCCESS(rc))
         {
             rc = vboxVDMACrCtlGetRc(&pCmd->Hdr);
+            if (RT_SUCCESS(rc))
+                pVdma->CrSrvInfo = pCmd->CrCmdServerInfo;
+            else if (rc != VERR_NOT_SUPPORTED)
+                WARN(("vboxVDMACrCtlGetRc returned %d\n", rc));
         }
+        else
+            WARN(("vboxVDMACrCtlPost failed %d\n", rc));
+
         vboxVDMACrCtlRelease(&pCmd->Hdr);
-        return rc;
     }
-    return VERR_NO_MEMORY;
+
+    if (!RT_SUCCESS(rc))
+        memset(&pVdma->CrSrvInfo, 0, sizeof (pVdma->CrSrvInfo));
+
+    return rc;
 }
 
 static int vboxVDMACmdExecBpbTransfer(PVBOXVDMAHOST pVdma, const PVBOXVDMACMD_DMA_BPB_TRANSFER pTransfer, uint32_t cbBuffer);
@@ -883,236 +1739,52 @@ static int vboxVDMACmdExec(PVBOXVDMAHOST pVdma, const uint8_t *pvBuffer, uint32_
     return VERR_INVALID_STATE;
 }
 
-#ifdef VBOX_VDMA_WITH_WORKERTHREAD
-
-int vboxVDMAPipeConstruct(PVBOXVDMAPIPE pPipe)
+static DECLCALLBACK(int) vboxVDMAWorkerThread(RTTHREAD ThreadSelf, void *pvUser)
 {
-    int rc = RTSemEventCreate(&pPipe->hEvent);
-    AssertRC(rc);
-    if (RT_SUCCESS(rc))
-    {
-        rc = RTCritSectInit(&pPipe->hCritSect);
-        AssertRC(rc);
-        if (RT_SUCCESS(rc))
-        {
-            pPipe->enmState = VBOXVDMAPIPE_STATE_CREATED;
-            pPipe->bNeedNotify = true;
-            return VINF_SUCCESS;
-//            RTCritSectDelete(pPipe->hCritSect);
-        }
-        RTSemEventDestroy(pPipe->hEvent);
-    }
-    return rc;
-}
+    PVBOXVDMAHOST pVdma = (PVBOXVDMAHOST)pvUser;
+    PVGASTATE pVGAState = pVdma->pVGAState;
+    VBVAEXHOSTCONTEXT *pCmdVbva = &pVdma->CmdVbva;
+    PHGSMIINSTANCE pHgsmi = pVdma->pHgsmi;
+    uint8_t *pCmd;
+    uint32_t cbCmd;
 
-int vboxVDMAPipeOpenServer(PVBOXVDMAPIPE pPipe)
-{
-    int rc = RTCritSectEnter(&pPipe->hCritSect);
-    AssertRC(rc);
-    if (RT_SUCCESS(rc))
+    int rc = VBoxVDMAThreadNotifyConstructSucceeded(&pVdma->Thread);
+    if (!RT_SUCCESS(rc))
     {
-        Assert(pPipe->enmState == VBOXVDMAPIPE_STATE_CREATED);
-        switch (pPipe->enmState)
-        {
-            case VBOXVDMAPIPE_STATE_CREATED:
-                pPipe->enmState = VBOXVDMAPIPE_STATE_OPENNED;
-                pPipe->bNeedNotify = false;
-                rc = VINF_SUCCESS;
-                break;
-            case VBOXVDMAPIPE_STATE_OPENNED:
-                pPipe->bNeedNotify = false;
-                rc = VINF_ALREADY_INITIALIZED;
-                break;
-            default:
-                AssertBreakpoint();
-                rc = VERR_INVALID_STATE;
-                break;
-        }
-
-        RTCritSectLeave(&pPipe->hCritSect);
+        WARN(("VBoxVDMAThreadNotifyConstructSucceeded failed %d\n", rc));
+        return rc;
     }
-    return rc;
-}
 
-int vboxVDMAPipeCloseServer(PVBOXVDMAPIPE pPipe)
-{
-    int rc = RTCritSectEnter(&pPipe->hCritSect);
-    AssertRC(rc);
-    if (RT_SUCCESS(rc))
+    while (!VBoxVDMAThreadIsTerminating(&pVdma->Thread))
     {
-        Assert(pPipe->enmState == VBOXVDMAPIPE_STATE_CLOSED
-                || pPipe->enmState == VBOXVDMAPIPE_STATE_CLOSING);
-        switch (pPipe->enmState)
+        VBVAEXHOST_DATA_TYPE enmType = VBoxVBVAExHPDataGet(pCmdVbva, &pCmd, &cbCmd);
+        switch (enmType)
         {
-            case VBOXVDMAPIPE_STATE_CLOSING:
-                pPipe->enmState = VBOXVDMAPIPE_STATE_CLOSED;
-                rc = VINF_SUCCESS;
-                break;
-            case VBOXVDMAPIPE_STATE_CLOSED:
-                rc = VINF_ALREADY_INITIALIZED;
+            case VBVAEXHOST_DATA_TYPE_CMD:
+                vboxVDMACrCmdProcess(pVdma, pCmd, cbCmd);
+                VBoxVBVAExHPDataCompleteCmd(pCmdVbva, cbCmd);
+                VBVARaiseIrqNoWait(pVGAState, 0);
                 break;
-            default:
-                AssertBreakpoint();
-                rc = VERR_INVALID_STATE;
-                break;
-        }
-
-        RTCritSectLeave(&pPipe->hCritSect);
-    }
-    return rc;
-}
-
-int vboxVDMAPipeCloseClient(PVBOXVDMAPIPE pPipe)
-{
-    int rc = RTCritSectEnter(&pPipe->hCritSect);
-    AssertRC(rc);
-    if (RT_SUCCESS(rc))
-    {
-        bool bNeedNotify = false;
-        Assert(pPipe->enmState == VBOXVDMAPIPE_STATE_OPENNED
-                || pPipe->enmState == VBOXVDMAPIPE_STATE_CREATED
-                ||  pPipe->enmState == VBOXVDMAPIPE_STATE_CLOSED);
-        switch (pPipe->enmState)
-        {
-            case VBOXVDMAPIPE_STATE_OPENNED:
-                pPipe->enmState = VBOXVDMAPIPE_STATE_CLOSING;
-                bNeedNotify = pPipe->bNeedNotify;
-                pPipe->bNeedNotify = false;
+            case VBVAEXHOST_DATA_TYPE_HOSTCTL:
+                rc = vboxVDMACrHostCtlProcess(pVdma, (VBVAEXHOSTCTL*)pCmd);
+                VBoxVBVAExHPDataCompleteCtl(pCmdVbva, (VBVAEXHOSTCTL*)pCmd, rc);
                 break;
-            case VBOXVDMAPIPE_STATE_CREATED:
-                pPipe->enmState = VBOXVDMAPIPE_STATE_CLOSED;
-                pPipe->bNeedNotify = false;
+            case VBVAEXHOST_DATA_TYPE_GUESTCTL:
+                rc = vboxVDMACrGuestCtlProcess(pVdma, (VBVAEXHOSTCTL*)pCmd);
+                VBoxVBVAExHPDataCompleteCtl(pCmdVbva, (VBVAEXHOSTCTL*)pCmd, rc);
                 break;
-            case VBOXVDMAPIPE_STATE_CLOSED:
-                rc = VINF_ALREADY_INITIALIZED;
+            case VBVAEXHOST_DATA_TYPE_NO_DATA:
+                rc = VBoxVDMAThreadEventWait(&pVdma->Thread, RT_INDEFINITE_WAIT);
+                AssertRC(rc);
                 break;
             default:
-                AssertBreakpoint();
-                rc = VERR_INVALID_STATE;
-                break;
-        }
-
-        RTCritSectLeave(&pPipe->hCritSect);
-
-        if (bNeedNotify)
-        {
-            rc = RTSemEventSignal(pPipe->hEvent);
-            AssertRC(rc);
-        }
-    }
-    return rc;
-}
-
-
-typedef DECLCALLBACK(bool) FNHVBOXVDMARWCB(PVBOXVDMAPIPE pPipe, void *pvCallback);
-typedef FNHVBOXVDMARWCB *PFNHVBOXVDMARWCB;
-
-int vboxVDMAPipeModifyServer(PVBOXVDMAPIPE pPipe, PFNHVBOXVDMARWCB pfnCallback, void * pvCallback)
-{
-    int rc = RTCritSectEnter(&pPipe->hCritSect);
-    AssertRC(rc);
-    if (RT_SUCCESS(rc))
-    {
-        do
-        {
-            Assert(pPipe->enmState == VBOXVDMAPIPE_STATE_OPENNED
-                    || pPipe->enmState == VBOXVDMAPIPE_STATE_CLOSING);
-
-            if (pPipe->enmState >= VBOXVDMAPIPE_STATE_OPENNED)
-            {
-                bool bProcessing = pfnCallback(pPipe, pvCallback);
-                pPipe->bNeedNotify = !bProcessing;
-                if (bProcessing)
-                {
-                    RTCritSectLeave(&pPipe->hCritSect);
-                    rc = VINF_SUCCESS;
-                    break;
-                }
-                else if (pPipe->enmState == VBOXVDMAPIPE_STATE_CLOSING)
-                {
-                    pPipe->enmState = VBOXVDMAPIPE_STATE_CLOSED;
-                    RTCritSectLeave(&pPipe->hCritSect);
-                    rc = VINF_EOF;
-                    break;
-                }
-            }
-            else
-            {
-                AssertBreakpoint();
-                rc = VERR_INVALID_STATE;
-                RTCritSectLeave(&pPipe->hCritSect);
-                break;
-            }
-
-            RTCritSectLeave(&pPipe->hCritSect);
-
-            rc = RTSemEventWait(pPipe->hEvent, RT_INDEFINITE_WAIT);
-            AssertRC(rc);
-            if (!RT_SUCCESS(rc))
-                break;
-
-            rc = RTCritSectEnter(&pPipe->hCritSect);
-            AssertRC(rc);
-            if (!RT_SUCCESS(rc))
+                WARN(("unexpected type %d\n", enmType));
                 break;
-        } while (1);
-    }
-
-    return rc;
-}
-
-int vboxVDMAPipeModifyClient(PVBOXVDMAPIPE pPipe, PFNHVBOXVDMARWCB pfnCallback, void * pvCallback)
-{
-    int rc = RTCritSectEnter(&pPipe->hCritSect);
-    AssertRC(rc);
-    if (RT_SUCCESS(rc))
-    {
-        bool bNeedNotify = false;
-        Assert(pPipe->enmState == VBOXVDMAPIPE_STATE_OPENNED);
-        if (pPipe->enmState == VBOXVDMAPIPE_STATE_OPENNED)
-        {
-            bool bModified = pfnCallback(pPipe, pvCallback);
-            if (bModified)
-            {
-                bNeedNotify = pPipe->bNeedNotify;
-                pPipe->bNeedNotify = false;
-            }
-        }
-        else
-            rc = VERR_INVALID_STATE;
-
-        RTCritSectLeave(&pPipe->hCritSect);
-
-        if (bNeedNotify)
-        {
-            rc = RTSemEventSignal(pPipe->hEvent);
-            AssertRC(rc);
         }
     }
-    return rc;
-}
-
-int vboxVDMAPipeDestruct(PVBOXVDMAPIPE pPipe)
-{
-    Assert(pPipe->enmState == VBOXVDMAPIPE_STATE_CLOSED
-            || pPipe->enmState == VBOXVDMAPIPE_STATE_CREATED);
-    /* ensure the pipe is closed */
-    vboxVDMAPipeCloseClient(pPipe);
-
-    Assert(pPipe->enmState == VBOXVDMAPIPE_STATE_CLOSED);
-
-    if (pPipe->enmState != VBOXVDMAPIPE_STATE_CLOSED)
-        return VERR_INVALID_STATE;
-
-    int rc = RTCritSectDelete(&pPipe->hCritSect);
-    AssertRC(rc);
-
-    rc = RTSemEventDestroy(pPipe->hEvent);
-    AssertRC(rc);
 
     return VINF_SUCCESS;
 }
-#endif
 
 static void vboxVDMACommandProcess(PVBOXVDMAHOST pVdma, PVBOXVDMACBUF_DR pCmd, uint32_t cbCmd)
 {
@@ -1181,87 +1853,6 @@ static void vboxVDMAControlProcess(PVBOXVDMAHOST pVdma, PVBOXVDMA_CTL pCmd)
     AssertRC(rc);
 }
 
-#ifdef VBOX_VDMA_WITH_WORKERTHREAD
-typedef struct
-{
-    struct VBOXVDMAHOST *pVdma;
-    VBOXVDMAPIPE_CMD_BODY Cmd;
-    bool bHasCmd;
-} VBOXVDMACMD_PROCESS_CONTEXT, *PVBOXVDMACMD_PROCESS_CONTEXT;
-
-static DECLCALLBACK(bool) vboxVDMACommandProcessCb(PVBOXVDMAPIPE pPipe, void *pvCallback)
-{
-    PVBOXVDMACMD_PROCESS_CONTEXT pContext = (PVBOXVDMACMD_PROCESS_CONTEXT)pvCallback;
-    struct VBOXVDMAHOST *pVdma = pContext->pVdma;
-    HGSMILISTENTRY *pEntry = hgsmiListRemoveHead(&pVdma->PendingList);
-    if (pEntry)
-    {
-        PVBOXVDMAPIPE_CMD pPipeCmd = VBOXVDMAPIPE_CMD_FROM_ENTRY(pEntry);
-        Assert(pPipeCmd);
-        pContext->Cmd = pPipeCmd->Cmd;
-        hgsmiListPrepend(&pVdma->CmdPool.List, pEntry);
-        pContext->bHasCmd = true;
-        return true;
-    }
-
-    pContext->bHasCmd = false;
-    return false;
-}
-
-static DECLCALLBACK(int) vboxVDMAWorkerThread(RTTHREAD ThreadSelf, void *pvUser)
-{
-    PVBOXVDMAHOST pVdma = (PVBOXVDMAHOST)pvUser;
-    PHGSMIINSTANCE pHgsmi = pVdma->pHgsmi;
-    VBOXVDMACMD_PROCESS_CONTEXT Context;
-    Context.pVdma = pVdma;
-
-    int rc = vboxVDMAPipeOpenServer(&pVdma->Pipe);
-    AssertRC(rc);
-    if (RT_SUCCESS(rc))
-    {
-        do
-        {
-            rc = vboxVDMAPipeModifyServer(&pVdma->Pipe, vboxVDMACommandProcessCb, &Context);
-            AssertRC(rc);
-            if (RT_SUCCESS(rc))
-            {
-                switch (Context.Cmd.enmType)
-                {
-                    case VBOXVDMAPIPE_CMD_TYPE_DMACMD:
-                    {
-                        PVBOXVDMACBUF_DR pDr = Context.Cmd.u.pDr;
-                        vboxVDMACommandProcess(pVdma, pDr);
-                        break;
-                    }
-                    case VBOXVDMAPIPE_CMD_TYPE_DMACTL:
-                    {
-                        PVBOXVDMA_CTL pCtl = Context.Cmd.u.pCtl;
-                        vboxVDMAControlProcess(pVdma, pCtl);
-                        break;
-                    }
-                    default:
-                        AssertBreakpoint();
-                        break;
-                }
-
-                if (rc == VINF_EOF)
-                {
-                    rc = VINF_SUCCESS;
-                    break;
-                }
-            }
-            else
-                break;
-        } while (1);
-    }
-
-    /* always try to close the pipe to make sure the client side is notified */
-    int tmpRc = vboxVDMAPipeCloseServer(&pVdma->Pipe);
-    AssertRC(tmpRc);
-    return rc;
-}
-#endif
-
 #ifdef VBOX_VDMA_WITH_WATCHDOG
 static DECLCALLBACK(void) vboxVDMAWatchDogTimer(PPDMDEVINS pDevIns, PTMTIMER pTimer, void *pvUser)
 {
@@ -1301,41 +1892,27 @@ int vboxVDMAConstruct(PVGASTATE pVGAState, uint32_t cPipeElements)
                                     "VDMA WatchDog Timer", &pVdma->WatchDogTimer);
         AssertRC(rc);
 #endif
-#ifdef VBOX_VDMA_WITH_WORKERTHREAD
-        hgsmiListInit(&pVdma->PendingList);
-        rc = vboxVDMAPipeConstruct(&pVdma->Pipe);
-        AssertRC(rc);
+        rc = VBoxVBVAExHSInit(&pVdma->CmdVbva);
         if (RT_SUCCESS(rc))
         {
-            rc = RTThreadCreate(&pVdma->hWorkerThread, vboxVDMAWorkerThread, pVdma, 0, RTTHREADTYPE_IO, RTTHREADFLAGS_WAITABLE, "VDMA");
-            AssertRC(rc);
+            rc = VBoxVDMAThreadCreate(&pVdma->Thread, vboxVDMAWorkerThread, pVdma);
             if (RT_SUCCESS(rc))
             {
-                hgsmiListInit(&pVdma->CmdPool.List);
-                pVdma->CmdPool.cCmds = cPipeElements;
-                for (uint32_t i = 0; i < cPipeElements; ++i)
-                {
-                    hgsmiListAppend(&pVdma->CmdPool.List, &pVdma->CmdPool.aCmds[i].Entry);
-                }
-# if 0 //def VBOX_WITH_CRHGSMI
-                int tmpRc = vboxVDMACrCtlHgsmiSetup(pVdma);
-# endif
-#endif
                 pVGAState->pVdma = pVdma;
-                VBoxVBVAExHSInit(&pVdma->CmdVbva);
 #ifdef VBOX_WITH_CRHGSMI
                 int rcIgnored = vboxVDMACrCtlHgsmiSetup(pVdma); NOREF(rcIgnored); /** @todo is this ignoring intentional? */
 #endif
                 return VINF_SUCCESS;
-#ifdef VBOX_VDMA_WITH_WORKERTHREAD
             }
+            else
+                WARN(("VBoxVDMAThreadCreate faile %d\n", rc));
 
-            int tmpRc = vboxVDMAPipeDestruct(&pVdma->Pipe);
-            AssertRC(tmpRc);
+            VBoxVBVAExHSTerm(&pVdma->CmdVbva);
         }
+        else
+            WARN(("VBoxVBVAExHSInit faile %d\n", rc));
 
         RTMemFree(pVdma);
-#endif
     }
     else
         rc = VERR_OUT_OF_RESOURCES;
@@ -1343,46 +1920,34 @@ int vboxVDMAConstruct(PVGASTATE pVGAState, uint32_t cPipeElements)
     return rc;
 }
 
-int vboxVDMADestruct(struct VBOXVDMAHOST *pVdma)
+int vboxVDMAReset(struct VBOXVDMAHOST *pVdma)
 {
-#ifdef VBOX_VDMA_WITH_WORKERTHREAD
-    /* @todo: implement*/
-    AssertBreakpoint();
-#endif
-    VBoxVBVAExHSTerm(&pVdma->CmdVbva);
-    RTMemFree(pVdma);
+    VBVAEXHOSTCTL Ctl;
+    Ctl.enmType = VBVAEXHOSTCTL_TYPE_HH_RESET;
+    int rc = vdmaVBVACtlSubmitSync(pVdma, &Ctl, VBVAEXHOSTCTL_SOURCE_HOST_ANY);
+    if (!RT_SUCCESS(rc))
+    {
+        WARN(("vdmaVBVACtlSubmitSync failed %d\n", rc));
+        return rc;
+    }
     return VINF_SUCCESS;
 }
 
-#ifdef VBOX_VDMA_WITH_WORKERTHREAD
-typedef struct
-{
-    struct VBOXVDMAHOST *pVdma;
-    VBOXVDMAPIPE_CMD_BODY Cmd;
-    bool bQueued;
-} VBOXVDMACMD_SUBMIT_CONTEXT, *PVBOXVDMACMD_SUBMIT_CONTEXT;
-
-DECLCALLBACK(bool) vboxVDMACommandSubmitCb(PVBOXVDMAPIPE pPipe, void *pvCallback)
+int vboxVDMADestruct(struct VBOXVDMAHOST *pVdma)
 {
-    PVBOXVDMACMD_SUBMIT_CONTEXT pContext = (PVBOXVDMACMD_SUBMIT_CONTEXT)pvCallback;
-    struct VBOXVDMAHOST *pVdma = pContext->pVdma;
-    HGSMILISTENTRY *pEntry = hgsmiListRemoveHead(&pVdma->CmdPool.List);
-    Assert(pEntry);
-    if (pEntry)
+    VBVAEXHOSTCTL Ctl;
+    Ctl.enmType = VBVAEXHOSTCTL_TYPE_HH_TERM;
+    int rc = vdmaVBVACtlSubmitSync(pVdma, &Ctl, VBVAEXHOSTCTL_SOURCE_HOST_ANY);
+    if (!RT_SUCCESS(rc))
     {
-        PVBOXVDMAPIPE_CMD pPipeCmd = VBOXVDMAPIPE_CMD_FROM_ENTRY(pEntry);
-        pPipeCmd->Cmd = pContext->Cmd;
-        VBoxSHGSMICommandMarkAsynchCompletion(pContext->Cmd.u.pvCmd);
-        pContext->bQueued = true;
-        hgsmiListAppend(&pVdma->PendingList, pEntry);
-        return true;
+        WARN(("vdmaVBVACtlSubmitSync failed %d\n", rc));
+        return rc;
     }
-
-    /* @todo: should we try to flush some commands here? */
-    pContext->bQueued = false;
-    return false;
+    VBoxVDMAThreadTerm(&pVdma->Thread);
+    VBoxVBVAExHSTerm(&pVdma->CmdVbva);
+    RTMemFree(pVdma);
+    return VINF_SUCCESS;
 }
-#endif
 
 int vboxVDMASaveStateExecPrep(struct VBOXVDMAHOST *pVdma, PSSMHANDLE pSSM)
 {
@@ -1545,377 +2110,201 @@ void vboxVDMACommand(struct VBOXVDMAHOST *pVdma, PVBOXVDMACBUF_DR pCmd, uint32_t
 }
 
 /**/
-static int vboxVBVAExHSProcessorAcquire(struct VBVAEXHOSTCONTEXT *pCmdVbva)
-{
-    Assert(pCmdVbva->u32State != VBVAEXHOSTCONTEXT_STATE_STOPPED);
 
-    uint32_t oldState;
-    if (!ASMAtomicReadU32(&pCmdVbva->u32Pause))
+static int vdmaVBVACtlSubmit(PVBOXVDMAHOST pVdma, VBVAEXHOSTCTL* pCtl, VBVAEXHOSTCTL_SOURCE enmSource, PFNVBVAEXHOSTCTL_COMPLETE pfnComplete, void *pvComplete)
+{
+    int rc = VBoxVBVAExHCtlSubmit(&pVdma->CmdVbva, pCtl, enmSource, pfnComplete, pvComplete);
+    if (RT_SUCCESS(rc))
     {
-        if (ASMAtomicCmpXchgExU32(&pCmdVbva->u32State, VBVAEXHOSTCONTEXT_STATE_PROCESSING, VBVAEXHOSTCONTEXT_STATE_LISTENING, &oldState))
-            return VINF_SUCCESS;
-        return oldState == VBVAEXHOSTCONTEXT_STATE_PROCESSING ? VERR_SEM_BUSY : VERR_INVALID_STATE;
+        if (rc == VINF_SUCCESS)
+            return VBoxVDMAThreadEventNotify(&pVdma->Thread);
+        else
+            Assert(rc == VINF_ALREADY_INITIALIZED);
     }
-    return VERR_INVALID_STATE;
-}
-
-static bool vboxVBVAExHPCheckPause(struct VBVAEXHOSTCONTEXT *pCmdVbva)
-{
-    Assert(pCmdVbva->u32State == VBVAEXHOSTCONTEXT_STATE_PROCESSING);
-
-    if (!ASMAtomicReadU32(&pCmdVbva->u32Pause))
-        return false;
-
-    ASMAtomicWriteU32(&pCmdVbva->u32State, VBVAEXHOSTCONTEXT_STATE_PAUSED);
-    return true;
-}
-
-static bool vboxVBVAExHPCheckOtherCommands(struct VBVAEXHOSTCONTEXT *pCmdVbva)
-{
-    Assert(pCmdVbva->u32State == VBVAEXHOSTCONTEXT_STATE_PROCESSING);
-
-    return !!ASMAtomicUoReadU32(&pCmdVbva->u32cOtherCommands);
-}
-
-static void vboxVBVAExHPProcessorRelease(struct VBVAEXHOSTCONTEXT *pCmdVbva)
-{
-    Assert(pCmdVbva->u32State == VBVAEXHOSTCONTEXT_STATE_PROCESSING);
-
-    if (!vboxVBVAExHPCheckPause(pCmdVbva))
-        ASMAtomicWriteU32(&pCmdVbva->u32State, VBVAEXHOSTCONTEXT_STATE_LISTENING);
     else
-        ASMAtomicWriteU32(&pCmdVbva->u32State, VBVAEXHOSTCONTEXT_STATE_PAUSED);
-}
-
-static void vboxVBVAExHPHgEventSet(struct VBVAEXHOSTCONTEXT *pCmdVbva)
-{
-    Assert(pCmdVbva->u32State == VBVAEXHOSTCONTEXT_STATE_PROCESSING);
-
-    ASMAtomicOrU32(&pCmdVbva->pVBVA->hostFlags.u32HostEvents, VBVA_F_STATE_PROCESSING);
-}
-
-static void vboxVBVAExHPHgEventClear(struct VBVAEXHOSTCONTEXT *pCmdVbva)
-{
-    Assert(pCmdVbva->u32State == VBVAEXHOSTCONTEXT_STATE_PROCESSING);
+        WARN(("VBoxVBVAExHCtlSubmit failed %d\n", rc));
 
-    ASMAtomicAndU32(&pCmdVbva->pVBVA->hostFlags.u32HostEvents, ~VBVA_F_STATE_PROCESSING);
+    return rc;
 }
 
-static bool vboxVBVAExHPCmdCheckRelease(struct VBVAEXHOSTCONTEXT *pCmdVbva)
+static DECLCALLBACK(void) vboxCmdVBVACmdCtlGuestCompletion(VBVAEXHOSTCONTEXT *pVbva, struct VBVAEXHOSTCTL *pCtl, int rc, void *pvContext)
 {
-    if (!pCmdVbva->cbCurData)
-        return false;
-
-    VBVABUFFER *pVBVA = pCmdVbva->pVBVA;
-    pVBVA->off32Data = (pVBVA->off32Data + pCmdVbva->cbCurData) % pVBVA->cbData;
-
-    pVBVA->indexRecordFirst = (pVBVA->indexRecordFirst + 1) % RT_ELEMENTS(pVBVA->aRecords);
+    PVBOXVDMAHOST pVdma = (PVBOXVDMAHOST)pvContext;
+    VBOXCMDVBVA_CTL *pGCtl = (VBOXCMDVBVA_CTL*)(pCtl->u.cmd.pu8Cmd - sizeof (VBOXCMDVBVA_CTL));
+    AssertRC(rc);
+    pGCtl->i32Result = rc;
 
-    pCmdVbva->cbCurData = 0;
+    Assert(pVdma->pVGAState->fGuestCaps & VBVACAPS_COMPLETEGCMD_BY_IOREAD);
+    rc = VBoxSHGSMICommandComplete(pVdma->pHgsmi, pGCtl);
+    AssertRC(rc);
 
-    return true;
+    VBoxVBVAExHCtlFree(pVbva, pCtl);
 }
 
-static int vboxVBVAExHPCmdGet(struct VBVAEXHOSTCONTEXT *pCmdVbva, uint8_t **ppCmd, uint32_t *pcbCmd)
+static int vdmaVBVACtlOpaqueSubmit(PVBOXVDMAHOST pVdma, VBVAEXHOSTCTL_SOURCE enmSource, uint8_t* pu8Cmd, uint32_t cbCmd, PFNVBVAEXHOSTCTL_COMPLETE pfnComplete, void *pvComplete)
 {
-    Assert(pCmdVbva->u32State == VBVAEXHOSTCONTEXT_STATE_PROCESSING);
-
-    VBVABUFFER *pVBVA = pCmdVbva->pVBVA;
-
-    uint32_t indexRecordFirst = pVBVA->indexRecordFirst;
-    uint32_t indexRecordFree = pVBVA->indexRecordFree;
-
-    Log(("first = %d, free = %d\n",
-                   indexRecordFirst, indexRecordFree));
-
-    if (indexRecordFirst == indexRecordFree)
-    {
-        /* No records to process. Return without assigning output variables. */
-        return VINF_EOF;
-    }
-
-    uint32_t cbRecordCurrent = ASMAtomicReadU32(&pVBVA->aRecords[indexRecordFirst].cbRecord);
-
-    /* A new record need to be processed. */
-    if (cbRecordCurrent & VBVA_F_RECORD_PARTIAL)
-    {
-        /* the record is being recorded, try again */
-        return VINF_TRY_AGAIN;
-    }
-
-    uint32_t cbRecord = cbRecordCurrent & ~VBVA_F_RECORD_PARTIAL;
-
-    if (!cbRecord)
+    VBVAEXHOSTCTL* pHCtl = VBoxVBVAExHCtlCreate(&pVdma->CmdVbva, VBVAEXHOSTCTL_TYPE_GHH_BE_OPAQUE);
+    if (!pHCtl)
     {
-        /* the record is being recorded, try again */
-        return VINF_TRY_AGAIN;
+        WARN(("VBoxVBVAExHCtlCreate failed\n"));
+        return VERR_NO_MEMORY;
     }
 
-    /* we should not get partial commands here actually */
-    Assert(cbRecord);
-
-    /* The size of largest contiguous chunk in the ring biffer. */
-    uint32_t u32BytesTillBoundary = pVBVA->cbData - pVBVA->off32Data;
-
-    /* The pointer to data in the ring buffer. */
-    uint8_t *pSrc = &pVBVA->au8Data[pVBVA->off32Data];
-
-    /* Fetch or point the data. */
-    if (u32BytesTillBoundary >= cbRecord)
+    pHCtl->u.cmd.pu8Cmd = pu8Cmd;
+    pHCtl->u.cmd.cbCmd = cbCmd;
+    int rc = vdmaVBVACtlSubmit(pVdma, pHCtl, enmSource, pfnComplete, pvComplete);
+    if (!RT_SUCCESS(rc))
     {
-        /* The command does not cross buffer boundary. Return address in the buffer. */
-        *ppCmd = pSrc;
-        *pcbCmd = cbRecord;
-        pCmdVbva->cbCurData = cbRecord;
-        return VINF_SUCCESS;
+        WARN(("vdmaVBVACtlSubmit failed rc %d\n", rc));
+        return rc;;
     }
-
-    LogRel(("CmdVbva: cross-bound writes unsupported\n"));
-    return VERR_INVALID_STATE;
-}
-
-/* Resumes command processing
- * @returns - same as VBoxVBVAExHSCheckCommands
- */
-static int vboxVBVAExHSResume(struct VBVAEXHOSTCONTEXT *pCmdVbva)
-{
-    Assert(pCmdVbva->u32State != VBVAEXHOSTCONTEXT_STATE_STOPPED);
-
-    ASMAtomicWriteU32(&pCmdVbva->u32State, VBVAEXHOSTCONTEXT_STATE_LISTENING);
-
-    return VBoxVBVAExHSCheckCommands(pCmdVbva);
+    return VINF_SUCCESS;
 }
 
-/* pause the command processing. this will make the processor stop the command processing and release the processing state
- * to resume the command processing the vboxVBVAExHSResume must be called */
-static void vboxVBVAExHSPause(struct VBVAEXHOSTCONTEXT *pCmdVbva)
+static int vdmaVBVACtlOpaqueGuestSubmit(PVBOXVDMAHOST pVdma, VBOXCMDVBVA_CTL *pCtl, uint32_t cbCtl)
 {
-    Assert(pCmdVbva->u32State != VBVAEXHOSTCONTEXT_STATE_STOPPED);
-
-    Assert(!pCmdVbva->u32Pause);
-
-    ASMAtomicWriteU32(&pCmdVbva->u32Pause, 1);
-
-    for(;;)
-    {
-        if (ASMAtomicCmpXchgU32(&pCmdVbva->u32State, VBVAEXHOSTCONTEXT_STATE_PAUSED, VBVAEXHOSTCONTEXT_STATE_LISTENING))
-            break;
-
-        if (ASMAtomicReadU32(&pCmdVbva->u32State) == VBVAEXHOSTCONTEXT_STATE_PAUSED)
-            break;
-
-        RTThreadSleep(2);
-    }
+    Assert(cbCtl >= sizeof (VBOXCMDVBVA_CTL));
+    VBoxSHGSMICommandMarkAsynchCompletion(pCtl);
+    int rc = vdmaVBVACtlOpaqueSubmit(pVdma, VBVAEXHOSTCTL_SOURCE_GUEST, (uint8_t*)(pCtl+1), cbCtl - sizeof (VBOXCMDVBVA_CTL), vboxCmdVBVACmdCtlGuestCompletion, pVdma);
+    if (RT_SUCCESS(rc))
+        return VINF_SUCCESS;
 
-    pCmdVbva->u32Pause = 0;
+    WARN(("vdmaVBVACtlOpaqueSubmit failed %d\n", rc));
+    pCtl->i32Result = rc;
+    rc = VBoxSHGSMICommandComplete(pVdma->pHgsmi, pCtl);
+    AssertRC(rc);
+    return VINF_SUCCESS;
 }
 
-/* releases (completed) the command previously acquired by VBoxVBVAExHCmdGet
- * for convenience can be called if no command is currently acquired
- * in that case it will do nothing and return false.
- * if the completion notification is needed returns true. */
-static bool VBoxVBVAExHPCmdCheckRelease(struct VBVAEXHOSTCONTEXT *pCmdVbva)
+static DECLCALLBACK(void) vboxCmdVBVACmdCtlHostCompletion(VBVAEXHOSTCONTEXT *pVbva, struct VBVAEXHOSTCTL *pCtl, int rc, void *pvCompletion)
 {
-    Assert(pCmdVbva->u32State == VBVAEXHOSTCONTEXT_STATE_PROCESSING);
-
-    return vboxVBVAExHPCmdCheckRelease(pCmdVbva);
+    VBOXCRCMDCTL* pVboxCtl = (VBOXCRCMDCTL*)pCtl->u.cmd.pu8Cmd;
+    if (pVboxCtl->pfnInternal)
+        ((PFNCRCTLCOMPLETION)pVboxCtl->pfnInternal)(pVboxCtl, pCtl->u.cmd.cbCmd, rc, pvCompletion);
+    VBoxVBVAExHCtlFree(pVbva, pCtl);
 }
 
-/*
- * @returns
- *  VINF_SUCCESS - new command is obtained
- *  VINF_EOF - processor has completed all commands and release the processing state, only VBoxVBVAExHS*** calls are now allowed
- *  VINF_PERMISSION_DENIED - processing was paused, processing state was released, only VBoxVBVAExHS*** calls are now allowed
- *  VINF_INTERRUPTED - command processing was interrupted, processor state remains set. client can process any commands,
- *                     and call VBoxVBVAExHPCmdGet again for further processing
- *  VERR_** - error happened, most likely guest corrupted VBVA data
- *
- */
-static int VBoxVBVAExHPCmdGet(struct VBVAEXHOSTCONTEXT *pCmdVbva, uint8_t **ppCmd, uint32_t *pcbCmd)
+static int vdmaVBVACtlOpaqueHostSubmit(PVBOXVDMAHOST pVdma, struct VBOXCRCMDCTL* pCmd, uint32_t cbCmd,
+        PFNCRCTLCOMPLETION pfnCompletion,
+        void *pvCompletion)
 {
-    Assert(pCmdVbva->u32State == VBVAEXHOSTCONTEXT_STATE_PROCESSING);
-
-    for(;;)
+    pCmd->pfnInternal = (void(*)())pfnCompletion;
+    int rc = vdmaVBVACtlOpaqueSubmit(pVdma, VBVAEXHOSTCTL_SOURCE_HOST_ENABLED, (uint8_t*)pCmd, cbCmd, vboxCmdVBVACmdCtlHostCompletion, pvCompletion);
+    if (!RT_SUCCESS(rc))
     {
-        if (vboxVBVAExHPCheckPause(pCmdVbva))
-            return VINF_PERMISSION_DENIED;
-        if (vboxVBVAExHPCheckOtherCommands(pCmdVbva))
-            return VINF_INTERRUPTED;
-
-        int rc = vboxVBVAExHPCmdGet(pCmdVbva, ppCmd, pcbCmd);
-        switch (rc)
+        if (rc == VERR_INVALID_STATE)
         {
-            case VINF_SUCCESS:
-                return VINF_SUCCESS;
-            case VINF_EOF:
-                vboxVBVAExHPHgEventClear(pCmdVbva);
-                vboxVBVAExHPProcessorRelease(pCmdVbva);
-                /* we need to prevent racing between us clearing the flag and command check/submission thread, i.e.
-                 * 1. we check the queue -> and it is empty
-                 * 2. submitter adds command to the queue
-                 * 3. submitter checks the "processing" -> and it is true , thus it does not submit a notification
-                 * 4. we clear the "processing" state
-                 * 5. ->here we need to re-check the queue state to ensure we do not leak the notification of the above command
-                 * 6. if the queue appears to be not-empty set the "processing" state back to "true"
-                 **/
-                if (VBoxVBVAExHSCheckCommands(pCmdVbva) == VINF_SUCCESS)
-                    continue;
-                return VINF_EOF;
-            case VINF_TRY_AGAIN:
-                RTThreadSleep(1);
-                continue;
-            default:
-                /* this is something really unexpected, i.e. most likely guest has written something incorrect to the VBVA buffer */
-                if (RT_FAILURE(rc))
-                    return rc;
+            pCmd->pfnInternal = NULL;
+            PVGASTATE pVGAState = pVdma->pVGAState;
+            rc = pVGAState->pDrv->pfnCrHgcmCtlSubmit(pVGAState->pDrv, pCmd, cbCmd, pfnCompletion, pvCompletion);
+            if (!RT_SUCCESS(rc))
+                WARN(("pfnCrHgsmiControlProcess failed %d\n", rc));
 
-                WARN(("Warning: vboxVBVAExHCmdGet returned unexpected success status %d\n", rc));
-                return VERR_INTERNAL_ERROR;
+            return rc;
         }
+        WARN(("vdmaVBVACtlOpaqueSubmit failed %d\n", rc));
+        return rc;
     }
 
-    WARN(("Warning: VBoxVBVAExHCmdGet unexpected state\n"));
-    return VERR_INTERNAL_ERROR;
+    return VINF_SUCCESS;
 }
 
-/* Checks whether the new commands are ready for processing
- * @returns
- *   VINF_SUCCESS - there are commands are in a queue, and the given thread is now the processor (i.e. typically it would delegate processing to a worker thread)
- *   VINF_EOF - no commands in a queue
- *   VINF_ALREADY_INITIALIZED - another thread already processing the commands
- *   VERR_INVALID_STATE - the VBVA is paused or pausing */
-static int VBoxVBVAExHSCheckCommands(struct VBVAEXHOSTCONTEXT *pCmdVbva)
+static int vdmaVBVACtlEnableDisableSubmitInternal(PVBOXVDMAHOST pVdma, VBVAENABLE *pEnable, PFNVBVAEXHOSTCTL_COMPLETE pfnComplete, void *pvComplete)
 {
-    if (ASMAtomicUoReadU32(&pCmdVbva->u32State) == VBVAEXHOSTCONTEXT_STATE_STOPPED)
-        return VINF_EOF;
-
-    int rc = vboxVBVAExHSProcessorAcquire(pCmdVbva);
-    if (RT_SUCCESS(rc))
+    VBVAEXHOSTCTL* pHCtl = VBoxVBVAExHCtlCreate(&pVdma->CmdVbva, VBVAEXHOSTCTL_TYPE_GH_ENABLE_DISABLE);
+    if (!pHCtl)
     {
-        /* we are the processor now */
-        VBVABUFFER *pVBVA = pCmdVbva->pVBVA;
-
-        uint32_t indexRecordFirst = pVBVA->indexRecordFirst;
-        uint32_t indexRecordFree = pVBVA->indexRecordFree;
-
-        if (indexRecordFirst != indexRecordFree)
-        {
-            vboxVBVAExHPHgEventSet(pCmdVbva);
-            return VINF_SUCCESS;
-        }
-
-        vboxVBVAExHPProcessorRelease(pCmdVbva);
-        return VINF_EOF;
+        WARN(("VBoxVBVAExHCtlCreate failed\n"));
+        return VERR_NO_MEMORY;
     }
-    if (rc == VERR_SEM_BUSY)
-        return VINF_ALREADY_INITIALIZED;
-    Assert(rc == VERR_INVALID_STATE);
-    return VERR_INVALID_STATE;
-}
-
-static void VBoxVBVAExHSInit(struct VBVAEXHOSTCONTEXT *pCmdVbva)
-{
-    memset(pCmdVbva, 0, sizeof (*pCmdVbva));
-}
-
-static int VBoxVBVAExHSEnable(struct VBVAEXHOSTCONTEXT *pCmdVbva, VBVABUFFER *pVBVA)
-{
-    if (ASMAtomicUoReadU32(&pCmdVbva->u32State) != VBVAEXHOSTCONTEXT_STATE_STOPPED)
-        return VINF_ALREADY_INITIALIZED;
 
-    pCmdVbva->pVBVA = pVBVA;
-    pCmdVbva->pVBVA->hostFlags.u32HostEvents = 0;
-    ASMAtomicWriteU32(&pCmdVbva->u32State, VBVAEXHOSTCONTEXT_STATE_LISTENING);
+    pHCtl->u.cmd.pu8Cmd = (uint8_t*)pEnable;
+    pHCtl->u.cmd.cbCmd = sizeof (*pEnable);
+    int rc = vdmaVBVACtlSubmit(pVdma, pHCtl, VBVAEXHOSTCTL_SOURCE_GUEST, pfnComplete, pvComplete);
+    if (!RT_SUCCESS(rc))
+    {
+        WARN(("vdmaVBVACtlSubmit failed rc %d\n", rc));
+        return rc;;
+    }
     return VINF_SUCCESS;
 }
 
-static int VBoxVBVAExHSDisable(struct VBVAEXHOSTCONTEXT *pCmdVbva)
+static int vdmaVBVACtlEnableDisableSubmit(PVBOXVDMAHOST pVdma, VBOXCMDVBVA_CTL_ENABLE *pEnable)
 {
-    if (ASMAtomicUoReadU32(&pCmdVbva->u32State) == VBVAEXHOSTCONTEXT_STATE_STOPPED)
-        return VINF_SUCCESS;
-
-    /* ensure no commands pending and one tries to submit them */
-    int rc = vboxVBVAExHSProcessorAcquire(pCmdVbva);
+    VBoxSHGSMICommandMarkAsynchCompletion(&pEnable->Hdr);
+    int rc = vdmaVBVACtlEnableDisableSubmitInternal(pVdma, &pEnable->Enable, vboxCmdVBVACmdCtlGuestCompletion, pVdma);
     if (RT_SUCCESS(rc))
-    {
-        pCmdVbva->pVBVA->hostFlags.u32HostEvents = 0;
-        memset(pCmdVbva, 0, sizeof (*pCmdVbva));
         return VINF_SUCCESS;
-    }
-    return VERR_INVALID_STATE;
+
+    WARN(("vdmaVBVACtlEnableDisableSubmitInternal failed %d\n", rc));
+    pEnable->Hdr.i32Result = rc;
+    rc = VBoxSHGSMICommandComplete(pVdma->pHgsmi, &pEnable->Hdr);
+    AssertRC(rc);
+    return VINF_SUCCESS;
 }
 
-static void VBoxVBVAExHSTerm(struct VBVAEXHOSTCONTEXT *pCmdVbva)
+static DECLCALLBACK(void) vdmaVBVACtlSubmitSyncCompletion(VBVAEXHOSTCONTEXT *pVbva, struct VBVAEXHOSTCTL *pCtl, int rc, void *pvContext)
 {
-    /* ensure the processor is stopped */
-    if (ASMAtomicUoReadU32(&pCmdVbva->u32State) == VBVAEXHOSTCONTEXT_STATE_STOPPED)
-        return;
-
-    /* ensure no one tries to submit the command */
-    vboxVBVAExHSPause(pCmdVbva);
-    pCmdVbva->pVBVA->hostFlags.u32HostEvents = 0;
-    memset(pCmdVbva, 0, sizeof (*pCmdVbva));
+    VDMA_VBVA_CTL_CYNC_COMPLETION *pData = (VDMA_VBVA_CTL_CYNC_COMPLETION*)pvContext;
+    pData->rc = rc;
+    rc = RTSemEventSignal(pData->hEvent);
+    if (!RT_SUCCESS(rc))
+        WARN(("RTSemEventSignal failed %d\n", rc));
 }
 
-/* Saves state
- * @returns - same as VBoxVBVAExHSCheckCommands, or failure on load state fail
- */
-static int VBoxVBVAExHSSaveState(struct VBVAEXHOSTCONTEXT *pCmdVbva, uint8_t* pu8VramBase, PSSMHANDLE pSSM)
+static int vdmaVBVACtlSubmitSync(PVBOXVDMAHOST pVdma, VBVAEXHOSTCTL* pCtl, VBVAEXHOSTCTL_SOURCE enmSource)
 {
-    int rc;
-    if (ASMAtomicUoReadU32(&pCmdVbva->u32State) != VBVAEXHOSTCONTEXT_STATE_STOPPED)
+    VDMA_VBVA_CTL_CYNC_COMPLETION Data;
+    Data.rc = VERR_NOT_IMPLEMENTED;
+    int rc = RTSemEventCreate(&Data.hEvent);
+    if (!RT_SUCCESS(rc))
     {
-        vboxVBVAExHSPause(pCmdVbva);
-        rc = SSMR3PutU32(pSSM, (uint32_t)(((uint8_t*)pCmdVbva->pVBVA) - pu8VramBase));
-        AssertRCReturn(rc, rc);
-        return vboxVBVAExHSResume(pCmdVbva);
+        WARN(("RTSemEventCreate failed %d\n", rc));
+        return rc;
     }
 
-    rc = SSMR3PutU32(pSSM, 0xffffffff);
-    AssertRCReturn(rc, rc);
-
-    return VINF_EOF;
-}
-
-/* Loads state
- * @returns - same as VBoxVBVAExHSCheckCommands, or failure on load state fail
- */
-static int VBoxVBVAExHSLoadState(struct VBVAEXHOSTCONTEXT *pCmdVbva, uint8_t* pu8VramBase, PSSMHANDLE pSSM, uint32_t u32Version)
-{
-    uint32_t u32;
-    int rc = SSMR3GetU32(pSSM, &u32);
-    AssertRCReturn(rc, rc);
-    if (u32 != 0xffffffff)
+    rc = vdmaVBVACtlSubmit(pVdma, pCtl, enmSource, vdmaVBVACtlSubmitSyncCompletion, &Data);
+    if (RT_SUCCESS(rc))
     {
-        VBVABUFFER *pVBVA = (VBVABUFFER*)pu8VramBase + u32;
-        rc = VBoxVBVAExHSEnable(pCmdVbva, pVBVA);
-        AssertRCReturn(rc, rc);
-        return VBoxVBVAExHSCheckCommands(pCmdVbva);
+        rc = RTSemEventWait(Data.hEvent, RT_INDEFINITE_WAIT);
+        if (RT_SUCCESS(rc))
+        {
+            rc = Data.rc;
+            if (!RT_SUCCESS(rc))
+                WARN(("vdmaVBVACtlSubmitSyncCompletion returned %d\n", rc));
+        }
+        else
+            WARN(("RTSemEventWait failed %d\n", rc));
     }
+    else
+        WARN(("vdmaVBVACtlSubmit failed %d\n", rc));
+
+    RTSemEventDestroy(Data.hEvent);
 
-    return VINF_EOF;
+    return rc;
 }
 
-int vboxCmdVBVAEnable(PVGASTATE pVGAState, VBVABUFFER *pVBVA)
+static int vdmaVBVAPause(PVBOXVDMAHOST pVdma)
 {
-    struct VBOXVDMAHOST *pVdma = pVGAState->pVdma;
-    return VBoxVBVAExHSEnable(&pVdma->CmdVbva, pVBVA);
+    VBVAEXHOSTCTL Ctl;
+    Ctl.enmType = VBVAEXHOSTCTL_TYPE_HH_INTERNAL_PAUSE;
+    return vdmaVBVACtlSubmitSync(pVdma, &Ctl, VBVAEXHOSTCTL_SOURCE_HOST_ANY);
 }
 
-int vboxCmdVBVADisable(PVGASTATE pVGAState)
+static int vdmaVBVAResume(PVBOXVDMAHOST pVdma)
 {
-    struct VBOXVDMAHOST *pVdma = pVGAState->pVdma;
-    return VBoxVBVAExHSDisable(&pVdma->CmdVbva);
+    VBVAEXHOSTCTL Ctl;
+    Ctl.enmType = VBVAEXHOSTCTL_TYPE_HH_INTERNAL_RESUME;
+    return vdmaVBVACtlSubmitSync(pVdma, &Ctl, VBVAEXHOSTCTL_SOURCE_HOST_ANY);
 }
 
-static int vboxCmdVBVACmdSubmitPerform(PVGASTATE pVGAState)
+static int vboxVDMACmdSubmitPerform(struct VBOXVDMAHOST *pVdma)
 {
-    struct VBOXVDMAHOST *pVdma = pVGAState->pVdma;
     int rc = VBoxVBVAExHSCheckCommands(&pVdma->CmdVbva);
     switch (rc)
     {
         case VINF_SUCCESS:
-            return pVGAState->pDrv->pfnCrCmdNotifyCmds(pVGAState->pDrv);
+            return VBoxVDMAThreadEventNotify(&pVdma->Thread);
         case VINF_ALREADY_INITIALIZED:
         case VINF_EOF:
         case VERR_INVALID_STATE:
@@ -1926,17 +2315,70 @@ static int vboxCmdVBVACmdSubmitPerform(PVGASTATE pVGAState)
     }
 }
 
+
+int vboxCmdVBVACmdHostCtl(PPDMIDISPLAYVBVACALLBACKS pInterface,
+                                                               struct VBOXCRCMDCTL* pCmd, uint32_t cbCmd,
+                                                               PFNCRCTLCOMPLETION pfnCompletion,
+                                                               void *pvCompletion)
+{
+    PVGASTATE pVGAState = PPDMIDISPLAYVBVACALLBACKS_2_PVGASTATE(pInterface);
+    struct VBOXVDMAHOST *pVdma = pVGAState->pVdma;
+    return vdmaVBVACtlOpaqueHostSubmit(pVdma, pCmd, cbCmd, pfnCompletion, pvCompletion);
+}
+
+int vboxCmdVBVACmdCtl(PVGASTATE pVGAState, VBOXCMDVBVA_CTL *pCtl, uint32_t cbCtl)
+{
+    struct VBOXVDMAHOST *pVdma = pVGAState->pVdma;
+    int rc = VINF_SUCCESS;
+    switch (pCtl->u32Type)
+    {
+        case VBOXCMDVBVACTL_TYPE_3DCTL:
+            return vdmaVBVACtlOpaqueGuestSubmit(pVdma, pCtl, cbCtl);
+        case VBOXCMDVBVACTL_TYPE_ENABLE:
+            if (cbCtl != sizeof (VBOXCMDVBVA_CTL_ENABLE))
+            {
+                WARN(("incorrect enable size\n"));
+                rc = VERR_INVALID_PARAMETER;
+                break;
+            }
+            return vdmaVBVACtlEnableDisableSubmit(pVdma, (VBOXCMDVBVA_CTL_ENABLE*)pCtl);
+        default:
+            WARN(("unsupported type\n"));
+            rc = VERR_INVALID_PARAMETER;
+            break;
+    }
+
+    pCtl->i32Result = rc;
+    rc = VBoxSHGSMICommandComplete(pVdma->pHgsmi, pCtl);
+    AssertRC(rc);
+    return VINF_SUCCESS;
+}
+
 int vboxCmdVBVACmdSubmit(PVGASTATE pVGAState)
 {
-    return vboxCmdVBVACmdSubmitPerform(pVGAState);
+    if (!VBoxVBVAExHSIsEnabled(&pVGAState->pVdma->CmdVbva))
+    {
+        WARN(("vdma VBVA is disabled\n"));
+        return VERR_INVALID_STATE;
+    }
+
+    return vboxVDMACmdSubmitPerform(pVGAState->pVdma);
 }
 
 int vboxCmdVBVACmdFlush(PVGASTATE pVGAState)
 {
-    return vboxCmdVBVACmdSubmitPerform(pVGAState);
+    WARN(("flush\n"));
+    if (!VBoxVBVAExHSIsEnabled(&pVGAState->pVdma->CmdVbva))
+    {
+        WARN(("vdma VBVA is disabled\n"));
+        return VERR_INVALID_STATE;
+    }
+    return vboxVDMACmdSubmitPerform(pVGAState->pVdma);
 }
 
 void vboxCmdVBVACmdTimer(PVGASTATE pVGAState)
 {
-    vboxCmdVBVACmdSubmitPerform(pVGAState);
+    if (!VBoxVBVAExHSIsEnabled(&pVGAState->pVdma->CmdVbva))
+        return;
+    vboxVDMACmdSubmitPerform(pVGAState->pVdma);
 }
diff --git a/src/VBox/Devices/Makefile.kmk b/src/VBox/Devices/Makefile.kmk
index 8c72337..179a998 100644
--- a/src/VBox/Devices/Makefile.kmk
+++ b/src/VBox/Devices/Makefile.kmk
@@ -371,10 +371,11 @@ if !defined(VBOX_ONLY_EXTPACKS)         # Goes on almost to the end of the file.
       include $(PATH_SUB_CURRENT)/Network/lwip-new/Makefile.kmk
     endif
     Network/DevINIP.cpp_DEFS += VBOX_WITH_NEW_LWIP
+    VBoxDD_LWIP_INCS += Network # for lwipopts.h
     $(eval $(call def_vbox_lwip_private, \
                       VBoxDD, Network/lwip-new))
     $(eval $(call def_vbox_lwip_flags, \
-                      Network/DevINIP.cpp, Network/lwip-new))
+                      VBoxDD, Network/DevINIP.cpp, Network/lwip-new))
   endif
  endif # VBOX_WITH_INIP
 
@@ -449,7 +450,7 @@ if !defined(VBOX_ONLY_EXTPACKS)         # Goes on almost to the end of the file.
   ifdef VBOX_WITH_NEW_LWIP
     Storage/DrvVD.cpp_DEFS += VBOX_WITH_NEW_LWIP
     $(eval $(call def_vbox_lwip_flags, \
-                      Storage/DrvVD.cpp, Network/lwip-new))
+                      VBoxDD, Storage/DrvVD.cpp, Network/lwip-new))
   else
     Storage/DrvVD.cpp_INCS = $(LWIP_INCS)
   endif
diff --git a/src/VBox/Devices/Network/lwip-new/CHANGELOG b/src/VBox/Devices/Network/lwip-new/CHANGELOG
index 68954d9..cf77286 100644
--- a/src/VBox/Devices/Network/lwip-new/CHANGELOG
+++ b/src/VBox/Devices/Network/lwip-new/CHANGELOG
@@ -6,6 +6,10 @@ HISTORY
 
  ++ New features:
 
+  2014-01-17: Jiri Engelthaler
+  * icmp, icmp6, opt.h: patch #8027: Completed HW checksuming for IPv4 and
+    IPv6 ICMP's
+
   2012-03-25: Simon Goldschmidt (idea by Mason)
   * posix/*: added posix-compatibility include files posix/netdb.h and posix/sys/socket.h
     which are a simple wrapper to the correct lwIP include files.
@@ -80,6 +84,46 @@ HISTORY
 
  ++ Bugfixes:
 
+  2014-01-08: Stathis Voukelatos
+  * memp_std.h: patch #7928 Fixed size calculation in MALLOC memory pool
+    creation macro
+
+  2014-01-18: Brian Fahs
+  * tcp_out.c: patch #8237: tcp_rexmit_rto fails to update pcb->unsent_oversize
+    when necessary
+
+  2014-01-17: Grant Erickson, Jay Logue, Simon Goldschmidt
+  * ipv6.c, netif.c: patch #7913 Enable Support for IPv6 Loopback
+
+  2014-01-16: Stathis Voukelatos
+  * netif.c: patch #7902 Fixed netif_poll() operation when LWIP_LOOPBACK_MAX_PBUFS > 0
+
+  2014-01-14: "Freddie Chopin"
+  * snmp.h, mib2.c: fixed constness and spelling of sysdescr
+
+  2014-01-14: Simon Goldschmidt (patch by Thomas Faber)
+  * tcpip.c: patch #8241: Fix implicit declaration of ip_input with
+    LWIP_TCPIP_CORE_LOCKING_INPUT disabled
+
+  2014-01-14: chrysn
+  * timers.c: patch #8244 make timeouts usable reliably from outside of the
+    timeout routine
+
+  2014-01-10: Simon Goldschmidt
+  * ip_frag.c, ip6_frag.c: fixed bug #41041 Potential use-after-free in IPv6 reassembly
+
+  2014-01-10: Simon Goldschmidt
+  * memp.c: fixed bug #41188 Alignment error in memp_init() when MEMP_SEPARATE_POOLS==1
+
+  2014-01-10: Simon Goldschmidt
+  * tcp.c: fixed bug #39898 tcp_fasttmr() possible lock due to infinte queue process loop
+
+  2013-06-29: Simon Goldschmidt
+  * inet.h, sockets.h: partially fixed bug #37585: IPv6 compatibility (in socket structs)
+
+  2013-06-29: Simon Goldschmidt
+  * inet6.h: bug #37585/task #12600: fixed struct in6_addr.s6_addr to conform to spec
+
   2013-04-24: patch by Liam <morepork>
   * api_msg.c: patch #8008 Fix a potential null pointer dereference in assert
 
diff --git a/src/VBox/Devices/Network/lwip-new/Makefile.kmk b/src/VBox/Devices/Network/lwip-new/Makefile.kmk
index 396ec80..0a8bee5 100644
--- a/src/VBox/Devices/Network/lwip-new/Makefile.kmk
+++ b/src/VBox/Devices/Network/lwip-new/Makefile.kmk
@@ -15,13 +15,6 @@
 # hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
 #
 
-#
-# Recommended kmk flags:
-#
-# VBOX_WITH_NAT_SERVICE=1
-# VBOX_WITH_LWIP_NAT=1
-#
-
 LWIP_INCS += \
     src/include \
     src/include/ipv4 \
@@ -101,9 +94,6 @@ LWIP_SOURCES += \
 #     src/netif/ppp/vj.c
 
 
-define def_vbox_lwip_flags # VAR_BaseName, path/to/lwip/dir
-  $(strip $1)_INCS += $(foreach incdir, $(LWIP_INCS), $(strip $2)/$(incdir))
-endef
 
 define _def_vbox_lwip_use # VAR_BaseName, path/to/lwip/dir
   $(strip $1)_SOURCES += \
@@ -113,6 +103,25 @@ define _def_vbox_lwip_use # VAR_BaseName, path/to/lwip/dir
   # $(strip $2)/src/foo/bar.c_CFLAGS += -magic
 endef
 
+
+define def_vbox_lwip_flags # PROTO_BaseName, VAR_BaseName, path/to/lwip/dir
+  # add anything configured for the component via PROTO_BaseName
+  $(foreach suffix, INCS DEFS,
+    $(if $(value $(strip $1)_LWIP_$(suffix)),
+      $(eval #
+        $(strip $2)_$(suffix) += $(value $(strip $1)_LWIP_$(suffix))
+      )))
+
+  # add lwip's own includes
+  $(strip $2)_INCS += $(foreach incdir, $(LWIP_INCS), $(strip $3)/$(incdir))
+
+  # disable lwip assertions for some build types
+  $(strip $2)_DEFS.release  += LWIP_NOASSERT
+  $(strip $2)_DEFS.profile  += LWIP_NOASSERT
+  $(strip $2)_DEFS.kprofile += LWIP_NOASSERT
+endef
+
+
 ###
 ### Call this if you want to expose lwip to your component as a whole.
 ### In this case individual lwip files (added to _SOURCES of your
@@ -123,9 +132,10 @@ endef
 ###
 define def_vbox_lwip_public # VAR_BaseName, path/to/lwip/dir
   $(eval $(call _def_vbox_lwip_use, $1, $2))
-  $(eval $(call def_vbox_lwip_flags, $1, $2))
+  $(eval $(call def_vbox_lwip_flags, $1, $1, $2))
 endef
 
+
 ###
 ### Call this if you want to expose lwip only to a few selected files.
 ### In this case each lwip file is configured with lwip includes etc
@@ -137,7 +147,7 @@ endef
 define def_vbox_lwip_private # VAR_BaseName, path/to/lwip/dir
   $(eval $(call _def_vbox_lwip_use, $1, $2))
   $(foreach file, $(LWIP_SOURCES), \
-    $(eval $(call def_vbox_lwip_flags, $(strip $2)/$(file), $2)))
+    $(eval $(call def_vbox_lwip_flags, $1, $(strip $2)/$(file), $2)))
 endef
 
 
diff --git a/src/VBox/Devices/Network/lwip-new/src/api/tcpip.c b/src/VBox/Devices/Network/lwip-new/src/api/tcpip.c
index f959b58..7d4afbf 100644
--- a/src/VBox/Devices/Network/lwip-new/src/api/tcpip.c
+++ b/src/VBox/Devices/Network/lwip-new/src/api/tcpip.c
@@ -46,6 +46,7 @@
 #include "lwip/pbuf.h"
 #include "lwip/tcpip.h"
 #include "lwip/init.h"
+#include "lwip/ip.h"
 #include "netif/etharp.h"
 #include "netif/ppp_oe.h"
 
diff --git a/src/VBox/Devices/Network/lwip-new/src/core/ipv4/icmp.c b/src/VBox/Devices/Network/lwip-new/src/core/ipv4/icmp.c
index 464d14e..85e67eb 100644
--- a/src/VBox/Devices/Network/lwip-new/src/core/ipv4/icmp.c
+++ b/src/VBox/Devices/Network/lwip-new/src/core/ipv4/icmp.c
@@ -145,6 +145,7 @@ icmp_input(struct pbuf *p, struct netif *inp)
       LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: bad ICMP echo received\n"));
       goto lenerr;
     }
+#if CHECKSUM_CHECK_ICMP
     if (inet_chksum_pbuf(p) != 0) {
       LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: checksum failed for received ICMP echo\n"));
       pbuf_free(p);
@@ -152,6 +153,7 @@ icmp_input(struct pbuf *p, struct netif *inp)
       snmp_inc_icmpinerrors();
       return;
     }
+#endif
 #if LWIP_ICMP_ECHO_CHECK_INPUT_PBUF_LEN
     if (pbuf_header(p, (PBUF_IP_HLEN + PBUF_LINK_HLEN))) {
       /* p is not big enough to contain link headers
@@ -427,7 +429,9 @@ icmp_send_response(struct pbuf *p, u8_t type, u8_t code)
 
   /* calculate checksum */
   icmphdr->chksum = 0;
+#if CHECKSUM_GEN_ICMP
   icmphdr->chksum = inet_chksum(icmphdr, q->len);
+#endif
   ICMP_STATS_INC(icmp.xmit);
   /* increase number of messages attempted to send */
   snmp_inc_icmpoutmsgs();
diff --git a/src/VBox/Devices/Network/lwip-new/src/core/ipv4/ip4.c b/src/VBox/Devices/Network/lwip-new/src/core/ipv4/ip4.c
index 4cb40fe..ab051d4 100644
--- a/src/VBox/Devices/Network/lwip-new/src/core/ipv4/ip4.c
+++ b/src/VBox/Devices/Network/lwip-new/src/core/ipv4/ip4.c
@@ -879,11 +879,11 @@ err_t ip_output_if_opt(struct pbuf *p, ip_addr_t *src, ip_addr_t *dest,
   if (ip_addr_cmp(dest, &netif->ip_addr)) {
     /* Packet to self, enqueue it for loopback */
     LWIP_DEBUGF(IP_DEBUG, ("netif_loop_output()"));
-    return netif_loop_output(netif, p, dest);
+    return netif_loop_output(netif, p);
   }
 #if LWIP_IGMP
   if ((p->flags & PBUF_FLAG_MCASTLOOP) != 0) {
-    netif_loop_output(netif, p, dest);
+    netif_loop_output(netif, p);
   }
 #endif /* LWIP_IGMP */
 #endif /* ENABLE_LOOPBACK */
diff --git a/src/VBox/Devices/Network/lwip-new/src/core/ipv4/ip_frag.c b/src/VBox/Devices/Network/lwip-new/src/core/ipv4/ip_frag.c
index 8d18434..f68cc35 100644
--- a/src/VBox/Devices/Network/lwip-new/src/core/ipv4/ip_frag.c
+++ b/src/VBox/Devices/Network/lwip-new/src/core/ipv4/ip_frag.c
@@ -481,7 +481,6 @@ ip_reass(struct pbuf *p)
   struct ip_reass_helper *iprh;
   u16_t offset, len;
   u8_t clen;
-  struct ip_reassdata *ipr_prev = NULL;
 
   IPFRAG_STATS_INC(ip_frag.recv);
   snmp_inc_ipreasmreqds();
@@ -527,7 +526,6 @@ ip_reass(struct pbuf *p)
       IPFRAG_STATS_INC(ip_frag.cachehit);
       break;
     }
-    ipr_prev = ipr;
   }
 
   if (ipr == NULL) {
@@ -565,6 +563,7 @@ ip_reass(struct pbuf *p)
   /* find the right place to insert this pbuf */
   /* @todo: trim pbufs if fragments are overlapping */
   if (ip_reass_chain_frag_into_datagram_and_validate(ipr, p)) {
+    struct ip_reassdata *ipr_prev;
     /* the totally last fragment (flag more fragments = 0) was received at least
      * once AND all fragments are received */
     ipr->datagram_len += IP_HLEN;
@@ -579,7 +578,9 @@ ip_reass(struct pbuf *p)
     IPH_OFFSET_SET(fraghdr, 0);
     IPH_CHKSUM_SET(fraghdr, 0);
     /* @todo: do we need to set calculate the correct checksum? */
+#if CHECKSUM_GEN_IP
     IPH_CHKSUM_SET(fraghdr, inet_chksum(fraghdr, IP_HLEN));
+#endif /* CHECKSUM_GEN_IP */
 
     p = ipr->p;
 
@@ -592,6 +593,14 @@ ip_reass(struct pbuf *p)
       pbuf_cat(p, r);
       r = iprh->next_pbuf;
     }
+
+    /* find the previous entry in the linked list */
+    for (ipr_prev = reassdatagrams; ipr_prev != NULL; ipr_prev = ipr->next) {
+      if (ipr_prev->next == ipr) {
+        break;
+      }
+    }
+
     /* release the sources allocate for the fragment queue entry */
     ip_reass_dequeue_datagram(ipr, ipr_prev);
 
@@ -811,7 +820,9 @@ ip_frag(struct pbuf *p, struct netif *netif, ip_addr_t *dest)
     IPH_OFFSET_SET(iphdr, htons(tmp));
     IPH_LEN_SET(iphdr, htons(cop + IP_HLEN));
     IPH_CHKSUM_SET(iphdr, 0);
+#if CHECKSUM_GEN_IP
     IPH_CHKSUM_SET(iphdr, inet_chksum(iphdr, IP_HLEN));
+#endif /* CHECKSUM_GEN_IP */
 
 #if IP_FRAG_USES_STATIC_BUF
     if (last) {
diff --git a/src/VBox/Devices/Network/lwip-new/src/core/ipv6/icmp6.c b/src/VBox/Devices/Network/lwip-new/src/core/ipv6/icmp6.c
index 09d598f..28d6611 100644
--- a/src/VBox/Devices/Network/lwip-new/src/core/ipv6/icmp6.c
+++ b/src/VBox/Devices/Network/lwip-new/src/core/ipv6/icmp6.c
@@ -101,7 +101,7 @@ icmp6_input(struct pbuf *p, struct netif *inp)
 
   icmp6hdr = (struct icmp6_hdr *)p->payload;
 
-#if LWIP_ICMP6_CHECKSUM_CHECK
+#if CHECKSUM_CHECK_ICMP6
   if (ip6_chksum_pseudo(p, IP6_NEXTH_ICMP6, p->tot_len, ip6_current_src_addr(),
                         ip6_current_dest_addr()) != 0) {
     /* Checksum failed */
@@ -110,7 +110,7 @@ icmp6_input(struct pbuf *p, struct netif *inp)
     ICMP6_STATS_INC(icmp6.drop);
     return;
   }
-#endif /* LWIP_ICMP6_CHECKSUM_CHECK */
+#endif /* CHECKSUM_CHECK_ICMP6 */
 
   switch (icmp6hdr->type) {
   case ICMP6_TYPE_NA: /* Neighbor advertisement */
@@ -184,8 +184,10 @@ icmp6_input(struct pbuf *p, struct netif *inp)
     /* Set fields in reply. */
     ((struct icmp6_echo_hdr *)(r->payload))->type = ICMP6_TYPE_EREP;
     ((struct icmp6_echo_hdr *)(r->payload))->chksum = 0;
+#if CHECKSUM_GEN_ICMP6
     ((struct icmp6_echo_hdr *)(r->payload))->chksum = ip6_chksum_pseudo(r,
         IP6_NEXTH_ICMP6, r->tot_len, reply_src, ip6_current_src_addr());
+#endif /* CHECKSUM_GEN_ICMP6 */
 
     /* Send reply. */
     ICMP6_STATS_INC(icmp6.xmit);
@@ -218,8 +220,6 @@ void
 icmp6_proxy_input(struct pbuf *p, struct netif *inp)
 {
   struct icmp6_hdr *icmp6hdr;
-  struct pbuf * r;
-  ip6_addr_t * reply_src;
 
   ICMP6_STATS_INC(icmp6.recv);
 
@@ -394,8 +394,10 @@ icmp6_send_response(struct pbuf *p, u8_t code, u32_t data, u8_t type)
 
   /* calculate checksum */
   icmp6hdr->chksum = 0;
+#if CHECKSUM_GEN_ICMP6
   icmp6hdr->chksum = ip6_chksum_pseudo(q, IP6_NEXTH_ICMP6, q->tot_len,
     reply_src, reply_dest);
+#endif /* CHECKSUM_GEN_ICMP6 */
 
   ICMP6_STATS_INC(icmp6.xmit);
   ip6_output_if(q, reply_src, reply_dest, LWIP_ICMP6_HL, 0, IP6_NEXTH_ICMP6, netif);
diff --git a/src/VBox/Devices/Network/lwip-new/src/core/ipv6/ip6.c b/src/VBox/Devices/Network/lwip-new/src/core/ipv6/ip6.c
index b890073..43a1d21 100644
--- a/src/VBox/Devices/Network/lwip-new/src/core/ipv6/ip6.c
+++ b/src/VBox/Devices/Network/lwip-new/src/core/ipv6/ip6.c
@@ -947,10 +947,17 @@ ip6_output_if(struct pbuf *p, ip6_addr_t *src, ip6_addr_t *dest,
   ip6_debug_print(p);
 
 #if ENABLE_LOOPBACK
-  /* TODO implement loopback for v6
-  if (ip6_addr_cmp(dest, netif_ip6_addr(0))) {
-    return netif_loop_output(netif, p, dest);
-  }*/
+  {
+    int i;
+    for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) {
+      if (ip6_addr_isvalid(netif_ip6_addr_state(netif, i)) &&
+          ip6_addr_cmp(dest, netif_ip6_addr(netif, i))) {
+        /* Packet to self, enqueue it for loopback */
+        LWIP_DEBUGF(IP6_DEBUG, ("netif_loop_output()\n"));
+        return netif_loop_output(netif, p);
+      }
+    }
+  }
 #endif /* ENABLE_LOOPBACK */
 #if LWIP_IPV6_FRAG
   /* don't fragment if interface has mtu set to 0 [loopif] */
@@ -959,7 +966,7 @@ ip6_output_if(struct pbuf *p, ip6_addr_t *src, ip6_addr_t *dest,
   }
 #endif /* LWIP_IPV6_FRAG */
 
-  LWIP_DEBUGF(IP6_DEBUG, ("netif->output_ip6()"));
+  LWIP_DEBUGF(IP6_DEBUG, ("netif->output_ip6()\n"));
   return netif->output_ip6(netif, p, dest);
 }
 
diff --git a/src/VBox/Devices/Network/lwip-new/src/core/ipv6/mld6.c b/src/VBox/Devices/Network/lwip-new/src/core/ipv6/mld6.c
index 6b45ca0..f91f7ef 100644
--- a/src/VBox/Devices/Network/lwip-new/src/core/ipv6/mld6.c
+++ b/src/VBox/Devices/Network/lwip-new/src/core/ipv6/mld6.c
@@ -566,8 +566,10 @@ mld6_send(struct mld_group *group, u8_t type)
   mld_hdr->reserved = 0;
   ip6_addr_set(&(mld_hdr->multicast_address), &(group->group_address));
 
+#if CHECKSUM_GEN_ICMP6
   mld_hdr->chksum = ip6_chksum_pseudo(p, IP6_NEXTH_ICMP6, p->len,
     src_addr, &(group->group_address));
+#endif /* CHECKSUM_GEN_ICMP6 */
 
   /* Add hop-by-hop headers options: router alert with MLD value. */
   ip6_options_add_hbh_ra(p, IP6_NEXTH_ICMP6, IP6_ROUTER_ALERT_VALUE_MLD);
diff --git a/src/VBox/Devices/Network/lwip-new/src/core/ipv6/nd6.c b/src/VBox/Devices/Network/lwip-new/src/core/ipv6/nd6.c
index e0a063c..2eb74a7 100644
--- a/src/VBox/Devices/Network/lwip-new/src/core/ipv6/nd6.c
+++ b/src/VBox/Devices/Network/lwip-new/src/core/ipv6/nd6.c
@@ -888,8 +888,10 @@ nd6_send_ns(struct netif * netif, ip6_addr_t * target_addr, u8_t flags)
     target_addr = &multicast_address;
   }
 
+#if CHECKSUM_GEN_ICMP6
   ns_hdr->chksum = ip6_chksum_pseudo(p, IP6_NEXTH_ICMP6, p->len, src_addr,
     target_addr);
+#endif /* CHECKSUM_GEN_ICMP6 */
 
   /* Send the packet out. */
   ND6_STATS_INC(nd6.xmit);
@@ -960,8 +962,10 @@ nd6_send_na(struct netif * netif, ip6_addr_t * target_addr, u8_t flags)
     dest_addr = ip6_current_src_addr();
   }
 
+#if CHECKSUM_GEN_ICMP6
   na_hdr->chksum = ip6_chksum_pseudo(p, IP6_NEXTH_ICMP6, p->len, src_addr,
     dest_addr);
+#endif /* CHECKSUM_GEN_ICMP6 */
 
   /* Send the packet out. */
   ND6_STATS_INC(nd6.xmit);
@@ -1027,8 +1031,10 @@ nd6_send_rs(struct netif * netif)
     SMEMCPY(lladdr_opt->addr, netif->hwaddr, netif->hwaddr_len);
   }
 
+#if CHECKSUM_GEN_ICMP6
   rs_hdr->chksum = ip6_chksum_pseudo(p, IP6_NEXTH_ICMP6, p->len, src_addr,
     &multicast_address);
+#endif /* CHECKSUM_GEN_ICMP6 */
 
   /* Send the packet out. */
   ND6_STATS_INC(nd6.xmit);
diff --git a/src/VBox/Devices/Network/lwip-new/src/core/memp.c b/src/VBox/Devices/Network/lwip-new/src/core/memp.c
index 6d10979..d274373 100644
--- a/src/VBox/Devices/Network/lwip-new/src/core/memp.c
+++ b/src/VBox/Devices/Network/lwip-new/src/core/memp.c
@@ -201,7 +201,7 @@ static const char *memp_desc[MEMP_MAX] = {
  *   extern u8_t __attribute__((section(".onchip_mem"))) memp_memory_UDP_PCB_base[];
  */
 #define LWIP_MEMPOOL(name,num,size,desc) u8_t memp_memory_ ## name ## _base \
-  [((num) * (MEMP_SIZE + MEMP_ALIGN_SIZE(size)))];   
+  [LWIP_MEM_ALIGN_BUFFER((num) * (MEMP_SIZE + MEMP_ALIGN_SIZE(size)))];   
 #include "lwip/memp_std.h"
 
 /** This array holds the base of each memory pool. */
@@ -213,7 +213,7 @@ static u8_t *const memp_bases[] = {
 #else /* MEMP_SEPARATE_POOLS */
 
 /** This is the actual memory used by the pools (all pools in one big block). */
-static u8_t memp_memory[MEM_ALIGNMENT - 1 
+static u8_t memp_memory[MEM_ALIGNMENT - 1 /* XXX: LWIP_MEM_ALIGN_BUFFER */
 #define LWIP_MEMPOOL(name,num,size,desc) + ( (num) * (MEMP_SIZE + MEMP_ALIGN_SIZE(size) ) )
 #include "lwip/memp_std.h"
 ];
@@ -334,7 +334,7 @@ memp_overflow_check_all(void)
 #endif /* !MEMP_SEPARATE_POOLS */
   for (i = 0; i < MEMP_MAX; ++i) {
 #if MEMP_SEPARATE_POOLS
-    p = (struct memp *)(memp_bases[i]);
+    p = (struct memp *)LWIP_MEM_ALIGN(memp_bases[i]);
 #endif /* MEMP_SEPARATE_POOLS */
     for (j = 0; j < memp_num[i]; ++j) {
       memp_overflow_check_element_overflow(p, i);
@@ -346,7 +346,7 @@ memp_overflow_check_all(void)
 #endif /* !MEMP_SEPARATE_POOLS */
   for (i = 0; i < MEMP_MAX; ++i) {
 #if MEMP_SEPARATE_POOLS
-    p = (struct memp *)(memp_bases[i]);
+    p = (struct memp *)LWIP_MEM_ALIGN(memp_bases[i]);
 #endif /* MEMP_SEPARATE_POOLS */
     for (j = 0; j < memp_num[i]; ++j) {
       memp_overflow_check_element_underflow(p, i);
@@ -370,7 +370,7 @@ memp_overflow_init(void)
 #endif /* !MEMP_SEPARATE_POOLS */
   for (i = 0; i < MEMP_MAX; ++i) {
 #if MEMP_SEPARATE_POOLS
-    p = (struct memp *)(memp_bases[i]);
+    p = (struct memp *)LWIP_MEM_ALIGN(memp_bases[i]);
 #endif /* MEMP_SEPARATE_POOLS */
     for (j = 0; j < memp_num[i]; ++j) {
 #if MEMP_SANITY_REGION_BEFORE_ALIGNED > 0
@@ -415,7 +415,7 @@ memp_init(void)
     VALGRIND_CREATE_MEMPOOL(&memp_tab[i], MEMP_VALGRIND_RED_ZONE, 0);
 #endif
 #if MEMP_SEPARATE_POOLS
-    memp = (struct memp*)memp_bases[i];
+    memp = (struct memp*)LWIP_MEM_ALIGN(memp_bases[i]);
 #endif /* MEMP_SEPARATE_POOLS */
     /* create a linked list of memp elements */
     for (j = 0; j < memp_num[i]; ++j) {
diff --git a/src/VBox/Devices/Network/lwip-new/src/core/netif.c b/src/VBox/Devices/Network/lwip-new/src/core/netif.c
index 1004ed1..385711f 100644
--- a/src/VBox/Devices/Network/lwip-new/src/core/netif.c
+++ b/src/VBox/Devices/Network/lwip-new/src/core/netif.c
@@ -88,7 +88,19 @@ static u8_t netif_num;
 static err_t netif_null_output_ip6(struct netif *netif, struct pbuf *p, ip6_addr_t *ipaddr);
 #endif /* LWIP_IPV6 */
 
+#if LWIP_IPV6
+#define ipX_input(in, netif) (IP6H_V((const struct ip6_hdr *)in->payload) == 6) ? ip6_input(in, netif) : ip_input(in, netif)
+#else
+#define ipX_input(in, netif) ip_input(in, netif)
+#endif
+
 #if LWIP_HAVE_LOOPIF
+static err_t netif_loop_output_ipv4(struct netif *netif, struct pbuf *p, ip_addr_t* addr);
+#if LWIP_IPV6
+static err_t netif_loop_output_ipv6(struct netif *netif, struct pbuf *p, ip6_addr_t* addr);
+#endif
+
+
 static struct netif loop_netif;
 
 /**
@@ -108,7 +120,10 @@ netif_loopif_init(struct netif *netif)
 
   netif->name[0] = 'l';
   netif->name[1] = 'o';
-  netif->output = netif_loop_output;
+  netif->output = netif_loop_output_ipv4;
+#if LWIP_IPV6
+  netif->output_ip6 = netif_loop_output_ipv6;
+#endif
   return ERR_OK;
 }
 #endif /* LWIP_HAVE_LOOPIF */
@@ -127,6 +142,15 @@ netif_init(void)
 #else  /* NO_SYS */
   netif_add(&loop_netif, &loop_ipaddr, &loop_netmask, &loop_gw, NULL, netif_loopif_init, tcpip_input);
 #endif /* NO_SYS */
+
+#if LWIP_IPV6
+  loop_netif.ip6_addr[0].addr[0] = 0;
+  loop_netif.ip6_addr[0].addr[1] = 0;
+  loop_netif.ip6_addr[0].addr[2] = 0;
+  loop_netif.ip6_addr[0].addr[3] = PP_HTONL(0x00000001UL);
+  loop_netif.ip6_addr_state[0] = IP6_ADDR_VALID;
+#endif /* LWIP_IPV6 */
+
   netif_set_up(&loop_netif);
 
 #endif /* LWIP_HAVE_LOOPIF */
@@ -655,13 +679,11 @@ void netif_set_link_callback(struct netif *netif, netif_status_callback_fn link_
  *
  * @param netif the lwip network interface structure
  * @param p the (IP) packet to 'send'
- * @param ipaddr the ip address to send the packet to (not used)
  * @return ERR_OK if the packet has been sent
  *         ERR_MEM if the pbuf used to copy the packet couldn't be allocated
  */
 err_t
-netif_loop_output(struct netif *netif, struct pbuf *p,
-       ip_addr_t *ipaddr)
+netif_loop_output(struct netif *netif, struct pbuf *p)
 {
   struct pbuf *r;
   err_t err;
@@ -679,7 +701,6 @@ netif_loop_output(struct netif *netif, struct pbuf *p,
 #endif /* LWIP_HAVE_LOOPIF */
 #endif /* LWIP_SNMP */
   SYS_ARCH_DECL_PROTECT(lev);
-  LWIP_UNUSED_ARG(ipaddr);
 
   /* Allocate a new pbuf */
   r = pbuf_alloc(PBUF_LINK, p->tot_len, PBUF_RAM);
@@ -741,6 +762,23 @@ netif_loop_output(struct netif *netif, struct pbuf *p,
   return ERR_OK;
 }
 
+static err_t
+netif_loop_output_ipv4(struct netif *netif, struct pbuf *p, ip_addr_t* addr)
+{
+  LWIP_UNUSED_ARG(addr);
+  return netif_loop_output(netif, p);
+}
+
+#if LWIP_IPV6
+static err_t
+netif_loop_output_ipv6(struct netif *netif, struct pbuf *p, ip6_addr_t* addr)
+{
+  LWIP_UNUSED_ARG(addr);
+  return netif_loop_output(netif, p);
+}
+#endif
+
+
 /**
  * Call netif_poll() in the main loop of your application. This is to prevent
  * reentering non-reentrant functions like tcp_input(). Packets passed to
@@ -769,16 +807,22 @@ netif_poll(struct netif *netif)
     if (in != NULL) {
       struct pbuf *in_end = in;
 #if LWIP_LOOPBACK_MAX_PBUFS
-      u8_t clen = pbuf_clen(in);
-      /* adjust the number of pbufs on queue */
-      LWIP_ASSERT("netif->loop_cnt_current underflow",
-        ((netif->loop_cnt_current - clen) < netif->loop_cnt_current));
-      netif->loop_cnt_current -= clen;
+      u8_t clen = 1;
 #endif /* LWIP_LOOPBACK_MAX_PBUFS */
       while (in_end->len != in_end->tot_len) {
         LWIP_ASSERT("bogus pbuf: len != tot_len but next == NULL!", in_end->next != NULL);
         in_end = in_end->next;
+#if LWIP_LOOPBACK_MAX_PBUFS
+        clen++;
+#endif /* LWIP_LOOPBACK_MAX_PBUFS */
       }
+#if LWIP_LOOPBACK_MAX_PBUFS
+      /* adjust the number of pbufs on queue */
+      LWIP_ASSERT("netif->loop_cnt_current underflow",
+        ((netif->loop_cnt_current - clen) < netif->loop_cnt_current));
+      netif->loop_cnt_current -= clen;
+#endif /* LWIP_LOOPBACK_MAX_PBUFS */
+
       /* 'in_end' now points to the last pbuf from 'in' */
       if (in_end == netif->loop_last) {
         /* this was the last pbuf in the list */
@@ -798,7 +842,7 @@ netif_poll(struct netif *netif)
       snmp_add_ifinoctets(stats_if, in->tot_len);
       snmp_inc_ifinucastpkts(stats_if);
       /* loopback packets are always IP packets! */
-      if (ip_input(in, netif) != ERR_OK) {
+      if (ipX_input(in, netif) != ERR_OK) {
         pbuf_free(in);
       }
       /* Don't reference the packet any more! */
diff --git a/src/VBox/Devices/Network/lwip-new/src/core/snmp/mib2.c b/src/VBox/Devices/Network/lwip-new/src/core/snmp/mib2.c
index dcd3b62..fe1bf6d 100644
--- a/src/VBox/Devices/Network/lwip-new/src/core/snmp/mib2.c
+++ b/src/VBox/Devices/Network/lwip-new/src/core/snmp/mib2.c
@@ -772,8 +772,8 @@ static const s32_t sysservices = SNMP_SYSSERVICES;
 /** mib-2.system.sysDescr */
 static const u8_t sysdescr_len_default = 4;
 static const u8_t sysdescr_default[] = "lwIP";
-static u8_t* sysdescr_len_ptr = (u8_t*)&sysdescr_len_default;
-static u8_t* sysdescr_ptr = (u8_t*)&sysdescr_default[0];
+static const u8_t* sysdescr_len_ptr = &sysdescr_len_default;
+static const u8_t* sysdescr_ptr = &sysdescr_default[0];
 /** mib-2.system.sysContact */
 static const u8_t syscontact_len_default = 0;
 static const u8_t syscontact_default[] = "";
@@ -902,7 +902,7 @@ static u32_t snmpinpkts = 0,
  * @param src points to source
  * @param n number of octets to copy.
  */
-static void ocstrncpy(u8_t *dst, u8_t *src, u16_t n)
+static void ocstrncpy(u8_t *dst, const u8_t *src, u16_t n)
 {
   u16_t i = n;
   while (i > 0) {
@@ -918,7 +918,7 @@ static void ocstrncpy(u8_t *dst, u8_t *src, u16_t n)
  * @param src points to source
  * @param n number of sub identifiers to copy.
  */
-void objectidncpy(s32_t *dst, s32_t *src, u8_t n)
+void objectidncpy(s32_t *dst, const s32_t *src, u8_t n)
 {
   u8_t i = n;
   while(i > 0) {
@@ -933,7 +933,7 @@ void objectidncpy(s32_t *dst, s32_t *src, u8_t n)
  * @param str if non-NULL then copy str pointer
  * @param len points to string length, excluding zero terminator
  */
-void snmp_set_sysdesr(u8_t *str, u8_t *len)
+void snmp_set_sysdescr(const u8_t *str, const u8_t *len)
 {
   if (str != NULL)
   {
diff --git a/src/VBox/Devices/Network/lwip-new/src/core/stats.c b/src/VBox/Devices/Network/lwip-new/src/core/stats.c
index 06fbe0f..ff97853 100644
--- a/src/VBox/Devices/Network/lwip-new/src/core/stats.c
+++ b/src/VBox/Devices/Network/lwip-new/src/core/stats.c
@@ -86,7 +86,7 @@ stats_display_proto(struct stats_proto *proto, const char *name)
   LWIP_PLATFORM_DIAG(("cachehit: %"STAT_COUNTER_F"\n", proto->cachehit)); 
 }
 
-#if IGMP_STATS
+#if IGMP_STATS || MLD6_STATS
 void
 stats_display_igmp(struct stats_igmp *igmp, const char *name)
 {
@@ -106,7 +106,7 @@ stats_display_igmp(struct stats_igmp *igmp, const char *name)
   LWIP_PLATFORM_DIAG(("tx_leave: %"STAT_COUNTER_F"\n\t", igmp->tx_leave)); 
   LWIP_PLATFORM_DIAG(("tx_report: %"STAT_COUNTER_F"\n\t", igmp->tx_report)); 
 }
-#endif /* IGMP_STATS */
+#endif /* IGMP_STATS || MLD6_STATS */
 
 #if MEM_STATS || MEMP_STATS
 void
diff --git a/src/VBox/Devices/Network/lwip-new/src/core/tcp.c b/src/VBox/Devices/Network/lwip-new/src/core/tcp.c
index 7596562..ebf6f48 100644
--- a/src/VBox/Devices/Network/lwip-new/src/core/tcp.c
+++ b/src/VBox/Devices/Network/lwip-new/src/core/tcp.c
@@ -1005,7 +1005,12 @@ tcp_slowtmr_start:
      * (to the real destination - as done by proxy hanlder).
      */
     /* Check if this PCB has stayed too long in SYN-RCVD */
-    if (pcb->state == SYN_RCVD || pcb->state == SYN_RCVD_0) {
+    if (pcb->state == SYN_RCVD
+#if LWIP_CONNECTION_PROXY
+        || pcb->state == SYN_RCVD_0
+#endif
+        )
+    {
       if ((u32_t)(tcp_ticks - pcb->tmr) >
           TCP_SYN_RCVD_TIMEOUT / TCP_SLOW_INTERVAL) {
         ++pcb_remove;
@@ -1154,6 +1159,8 @@ tcp_fasttmr_start:
         }
       }
       pcb = next;
+    } else {
+      pcb = pcb->next;
     }
   }
 }
diff --git a/src/VBox/Devices/Network/lwip-new/src/core/tcp_out.c b/src/VBox/Devices/Network/lwip-new/src/core/tcp_out.c
index 0fcd0f1..9884efa 100644
--- a/src/VBox/Devices/Network/lwip-new/src/core/tcp_out.c
+++ b/src/VBox/Devices/Network/lwip-new/src/core/tcp_out.c
@@ -1262,11 +1262,16 @@ tcp_rexmit_rto(struct tcp_pcb *pcb)
   for (seg = pcb->unacked; seg->next != NULL; seg = seg->next);
   /* concatenate unsent queue after unacked queue */
   seg->next = pcb->unsent;
+#if TCP_OVERSIZE && TCP_OVERSIZE_DBGCHECK
+  /* if last unsent changed, we need to update unsent_oversize */
+  if (pcb->unsent == NULL) {
+    pcb->unsent_oversize = seg->oversize_left;
+  }
+#endif /* TCP_OVERSIZE && TCP_OVERSIZE_DBGCHECK*/
   /* unsent queue is the concatenated queue (of unacked, unsent) */
   pcb->unsent = pcb->unacked;
   /* unacked queue is now empty */
   pcb->unacked = NULL;
-  /* last unsent hasn't changed, no need to reset unsent_oversize */
 
   /* increment number of retransmissions */
   ++pcb->nrtx;
diff --git a/src/VBox/Devices/Network/lwip-new/src/core/timers.c b/src/VBox/Devices/Network/lwip-new/src/core/timers.c
index 02fef0f..601a905 100644
--- a/src/VBox/Devices/Network/lwip-new/src/core/timers.c
+++ b/src/VBox/Devices/Network/lwip-new/src/core/timers.c
@@ -79,7 +79,7 @@ static int tcpip_tcp_timer_active;
 #if LWIP_CONNECTION_PROXY
 /** global variable that shows if proxy timer is currently scheduled or not */
 static int proxy_udp_timer_active;
-#endif /* LWIP_TCP */
+#endif /* LWIP_CONNECTION_PROXY */
 
 
 #if LWIP_TCP
@@ -368,16 +368,34 @@ sys_timeout(u32_t msecs, sys_timeout_handler handler, void *arg)
 #endif /* LWIP_DEBUG_TIMERNAMES */
 {
   struct sys_timeo *timeout, *t;
+#if NO_SYS
+  u32_t now, diff;
+#endif
 
   timeout = (struct sys_timeo *)memp_malloc(MEMP_SYS_TIMEOUT);
   if (timeout == NULL) {
     LWIP_ASSERT("sys_timeout: timeout != NULL, pool MEMP_SYS_TIMEOUT is empty", timeout != NULL);
     return;
   }
+
+#if NO_SYS
+  now = sys_now();
+  if (next_timeout == NULL) {
+    diff = 0;
+    timeouts_last_time = now;
+  } else {
+    diff = now - timeouts_last_time;
+  }
+#endif
+
   timeout->next = NULL;
   timeout->h = handler;
   timeout->arg = arg;
+#if NO_SYS
+  timeout->time = msecs + diff;
+#else
   timeout->time = msecs;
+#endif
 #if LWIP_DEBUG_TIMERNAMES
   timeout->handler_name = handler_name;
   LWIP_DEBUGF(TIMERS_DEBUG, ("sys_timeout: %p msecs=%"U32_F" handler=%s arg=%p\n",
@@ -479,7 +497,7 @@ sys_check_timeouts(void)
       if (tmptimeout && (tmptimeout->time <= diff)) {
         /* timeout has expired */
         had_one = 1;
-        timeouts_last_time = now;
+        timeouts_last_time += tmptimeout->time;
         diff -= tmptimeout->time;
         next_timeout = tmptimeout->next;
         handler = tmptimeout->h;
diff --git a/src/VBox/Devices/Network/lwip-new/src/include/ipv4/lwip/autoip.h b/src/VBox/Devices/Network/lwip-new/src/include/ipv4/lwip/autoip.h
index e62b72e..b9f1873 100644
--- a/src/VBox/Devices/Network/lwip-new/src/include/ipv4/lwip/autoip.h
+++ b/src/VBox/Devices/Network/lwip-new/src/include/ipv4/lwip/autoip.h
@@ -94,6 +94,9 @@ struct autoip
 /** Set a struct autoip allocated by the application to work with */
 void autoip_set_struct(struct netif *netif, struct autoip *autoip);
 
+/** Remove a struct autoip previously set to the netif using autoip_set_struct() */
+#define autoip_remove_struct(netif) do { (netif)->autoip = NULL; } while (0)
+
 /** Start AutoIP client */
 err_t autoip_start(struct netif *netif);
 
diff --git a/src/VBox/Devices/Network/lwip-new/src/include/ipv4/lwip/inet.h b/src/VBox/Devices/Network/lwip-new/src/include/ipv4/lwip/inet.h
index 7bff49b..a6d2eda 100644
--- a/src/VBox/Devices/Network/lwip-new/src/include/ipv4/lwip/inet.h
+++ b/src/VBox/Devices/Network/lwip-new/src/include/ipv4/lwip/inet.h
@@ -40,9 +40,14 @@
 extern "C" {
 #endif
 
+/* If your port already typedef's in_addr_t, define IN_ADDR_T_DEFINED
+   to prevent this code from redefining it. */
+#if !defined(in_addr_t) && !defined(IN_ADDR_T_DEFINED)
+typedef u32_t in_addr_t;
+#endif
 /** For compatibility with BSD code */
 struct in_addr {
-  u32_t s_addr;
+  in_addr_t s_addr;
 };
 
 /** 255.255.255.255 */
@@ -89,6 +94,15 @@ struct in_addr {
 
 #define IN_LOOPBACKNET      IP_LOOPBACKNET
 
+#ifndef INET_ADDRSTRLEN
+#define INET_ADDRSTRLEN     IP4ADDR_STRLEN_MAX
+#endif
+#if LWIP_IPV6
+#ifndef INET6_ADDRSTRLEN
+#define INET6_ADDRSTRLEN    IP6ADDR_STRLEN_MAX
+#endif
+#endif
+
 #define inet_addr_from_ipaddr(target_inaddr, source_ipaddr) ((target_inaddr)->s_addr = ip4_addr_get_u32(source_ipaddr))
 #define inet_addr_to_ipaddr(target_ipaddr, source_inaddr)   (ip4_addr_set_u32(target_ipaddr, (source_inaddr)->s_addr))
 /* ATTENTION: the next define only works because both s_addr and ip_addr_t are an u32_t effectively! */
diff --git a/src/VBox/Devices/Network/lwip-new/src/include/ipv4/lwip/ip4_addr.h b/src/VBox/Devices/Network/lwip-new/src/include/ipv4/lwip/ip4_addr.h
index 923d4b0..af76856 100644
--- a/src/VBox/Devices/Network/lwip-new/src/include/ipv4/lwip/ip4_addr.h
+++ b/src/VBox/Devices/Network/lwip-new/src/include/ipv4/lwip/ip4_addr.h
@@ -228,6 +228,9 @@ u8_t ip4_addr_netmask_valid(u32_t netmask);
 #define ip4_addr3_16(ipaddr) ((u16_t)ip4_addr3(ipaddr))
 #define ip4_addr4_16(ipaddr) ((u16_t)ip4_addr4(ipaddr))
 
+#define IP4ADDR_STRLEN_MAX  16
+#define IPADDR_STRLEN_MAX   IP4ADDR_STRLEN_MAX
+
 /** For backwards compatibility */
 #define ip_ntoa(ipaddr)  ipaddr_ntoa(ipaddr)
 
diff --git a/src/VBox/Devices/Network/lwip-new/src/include/ipv6/lwip/inet6.h b/src/VBox/Devices/Network/lwip-new/src/include/ipv6/lwip/inet6.h
index dbf98df..8359521 100644
--- a/src/VBox/Devices/Network/lwip-new/src/include/ipv6/lwip/inet6.h
+++ b/src/VBox/Devices/Network/lwip-new/src/include/ipv6/lwip/inet6.h
@@ -58,7 +58,7 @@ struct in6_addr {
     u8_t  u8_addr[16];
     u32_t u32_addr[4];
   } un;
-#define s6_addr  un.u32_addr
+#define s6_addr  un.u8_addr
 };
 
 #define IN6ADDR_ANY_INIT {0,0,0,0}
diff --git a/src/VBox/Devices/Network/lwip-new/src/include/ipv6/lwip/ip6_addr.h b/src/VBox/Devices/Network/lwip-new/src/include/ipv6/lwip/ip6_addr.h
index 56da0d3..4e5f4a2 100644
--- a/src/VBox/Devices/Network/lwip-new/src/include/ipv6/lwip/ip6_addr.h
+++ b/src/VBox/Devices/Network/lwip-new/src/include/ipv6/lwip/ip6_addr.h
@@ -85,8 +85,6 @@ extern const ip6_addr_t ip6_addr_any;
 #define IP6_ADDR_ANY         ((ip6_addr_t *)&ip6_addr_any)
 
 
-
-
 #if BYTE_ORDER == BIG_ENDIAN
 /** Set an IPv6 partial address given by byte-parts. */
 #define IP6_ADDR(ip6addr, index, a,b,c,d) \
@@ -146,7 +144,6 @@ Little-endian version, stored in network order (no htonl). */
                                         (dest)->addr[3] = (src) == NULL ? 0 : htonl((src)->addr[3]);}while(0)
 
 
-
 /**
  * Determine if two IPv6 address are on the same network.
  *
@@ -170,6 +167,10 @@ Little-endian version, stored in network order (no htonl). */
                              ((ip6addr)->addr[2] == 0) && \
                              ((ip6addr)->addr[3] == 0)))
 
+#define ip6_addr_isloopback(ip6addr) (((ip6addr)->addr[0] == 0UL) && \
+                                      ((ip6addr)->addr[1] == 0UL) && \
+                                      ((ip6addr)->addr[2] == 0UL) && \
+                                      ((ip6addr)->addr[3] == PP_HTONL(0x00000001UL)))
 
 #define ip6_addr_isglobal(ip6addr) (((ip6addr)->addr[0] & PP_HTONL(0xe0000000UL)) == PP_HTONL(0x20000000UL))
 
@@ -270,6 +271,8 @@ Little-endian version, stored in network order (no htonl). */
                       ipaddr != NULL ? IP6_ADDR_BLOCK7(ipaddr) : 0,    \
                       ipaddr != NULL ? IP6_ADDR_BLOCK8(ipaddr) : 0))
 
+#define IP6ADDR_STRLEN_MAX    46
+
 int ip6addr_aton(const char *cp, ip6_addr_t *addr);
 /** returns ptr to static buffer; not reentrant! */
 char *ip6addr_ntoa(const ip6_addr_t *addr);
diff --git a/src/VBox/Devices/Network/lwip-new/src/include/lwip/debug.h b/src/VBox/Devices/Network/lwip-new/src/include/lwip/debug.h
index 0fe0413..fe66d4e 100644
--- a/src/VBox/Devices/Network/lwip-new/src/include/lwip/debug.h
+++ b/src/VBox/Devices/Network/lwip-new/src/include/lwip/debug.h
@@ -76,6 +76,8 @@
 #endif /* LWIP_ERROR */
 
 #ifdef LWIP_DEBUG
+/* let VBox override it to use logging */
+#ifndef LWIP_DEBUGF
 /** print debug message only if debug message type is enabled...
  *  AND is of correct type AND is at least LWIP_DBG_LEVEL
  */
@@ -90,8 +92,12 @@
                                  } \
                                } \
                              } while(0)
-
+#endif /* !LWIP_DEBUGF */
 #else  /* LWIP_DEBUG */
+#ifdef LWIP_DEBUG
+/* sanity check, this is going to fail with undefined variables anyway */
+#error LWIP_DEBUGF is defined without LWIP_DEBUG
+#endif
 #define LWIP_DEBUGF(debug, message) 
 #endif /* LWIP_DEBUG */
 
diff --git a/src/VBox/Devices/Network/lwip-new/src/include/lwip/memp_std.h b/src/VBox/Devices/Network/lwip-new/src/include/lwip/memp_std.h
index 592a282..8e1c99c 100644
--- a/src/VBox/Devices/Network/lwip-new/src/include/lwip/memp_std.h
+++ b/src/VBox/Devices/Network/lwip-new/src/include/lwip/memp_std.h
@@ -12,7 +12,7 @@
 #ifndef LWIP_MALLOC_MEMPOOL
 /* This treats "malloc pools" just like any other pool.
    The pools are a little bigger to provide 'size' as the amount of user data. */
-#define LWIP_MALLOC_MEMPOOL(num, size) LWIP_MEMPOOL(POOL_##size, num, (size + sizeof(struct memp_malloc_helper)), "MALLOC_"#size)
+#define LWIP_MALLOC_MEMPOOL(num, size) LWIP_MEMPOOL(POOL_##size, num, (size + LWIP_MEM_ALIGN_SIZE(sizeof(struct memp_malloc_helper))), "MALLOC_"#size)
 #define LWIP_MALLOC_MEMPOOL_START
 #define LWIP_MALLOC_MEMPOOL_END
 #endif /* LWIP_MALLOC_MEMPOOL */ 
diff --git a/src/VBox/Devices/Network/lwip-new/src/include/lwip/netif.h b/src/VBox/Devices/Network/lwip-new/src/include/lwip/netif.h
index 322d2d0..b2c8d87 100644
--- a/src/VBox/Devices/Network/lwip-new/src/include/lwip/netif.h
+++ b/src/VBox/Devices/Network/lwip-new/src/include/lwip/netif.h
@@ -359,7 +359,7 @@ void netif_set_link_callback(struct netif *netif, netif_status_callback_fn link_
 #endif /* LWIP_IGMP */
 
 #if ENABLE_LOOPBACK
-err_t netif_loop_output(struct netif *netif, struct pbuf *p, ip_addr_t *dest_ip);
+err_t netif_loop_output(struct netif *netif, struct pbuf *p);
 void netif_poll(struct netif *netif);
 #if !LWIP_NETIF_LOOPBACK_MULTITHREADING
 void netif_poll_all(void);
diff --git a/src/VBox/Devices/Network/lwip-new/src/include/lwip/netifapi.h b/src/VBox/Devices/Network/lwip-new/src/include/lwip/netifapi.h
index 33318ef..648151b 100644
--- a/src/VBox/Devices/Network/lwip-new/src/include/lwip/netifapi.h
+++ b/src/VBox/Devices/Network/lwip-new/src/include/lwip/netifapi.h
@@ -96,6 +96,9 @@ err_t netifapi_netif_common    ( struct netif *netif,
 #define netifapi_netif_set_default(n) netifapi_netif_common(n, netif_set_default, NULL)
 #define netifapi_dhcp_start(n)        netifapi_netif_common(n, NULL, dhcp_start)
 #define netifapi_dhcp_stop(n)         netifapi_netif_common(n, dhcp_stop, NULL)
+#define netifapi_dhcp_inform(n)       netifapi_netif_common(n, dhcp_inform, NULL)
+#define netifapi_dhcp_renew(n)        netifapi_netif_common(n, NULL, dhcp_renew)
+#define netifapi_dhcp_release(n)      netifapi_netif_common(n, NULL, dhcp_release)
 #define netifapi_autoip_start(n)      netifapi_netif_common(n, NULL, autoip_start)
 #define netifapi_autoip_stop(n)       netifapi_netif_common(n, NULL, autoip_stop)
 
diff --git a/src/VBox/Devices/Network/lwip-new/src/include/lwip/opt.h b/src/VBox/Devices/Network/lwip-new/src/include/lwip/opt.h
index 0da6fad..1cec8d4 100644
--- a/src/VBox/Devices/Network/lwip-new/src/include/lwip/opt.h
+++ b/src/VBox/Devices/Network/lwip-new/src/include/lwip/opt.h
@@ -1881,6 +1881,13 @@
 #endif
  
 /**
+ * CHECKSUM_GEN_ICMP6==1: Generate checksums in software for outgoing ICMP6 packets.
+ */
+#ifndef CHECKSUM_GEN_ICMP6
+#define CHECKSUM_GEN_ICMP6              1
+#endif
+ 
+/**
  * CHECKSUM_CHECK_IP==1: Check checksums in software for incoming IP packets.
  */
 #ifndef CHECKSUM_CHECK_IP
@@ -1902,6 +1909,20 @@
 #endif
 
 /**
+ * CHECKSUM_CHECK_ICMP==1: Check checksums in software for incoming ICMP packets.
+ */
+#ifndef CHECKSUM_CHECK_ICMP
+#define CHECKSUM_CHECK_ICMP             1
+#endif
+
+/**
+ * CHECKSUM_CHECK_ICMP6==1: Check checksums in software for incoming ICMPv6 packets
+ */
+#ifndef CHECKSUM_CHECK_ICMP6
+#define CHECKSUM_CHECK_ICMP6            1
+#endif
+
+/**
  * LWIP_CHECKSUM_ON_COPY==1: Calculate checksum when copying data from
  * application buffers to pbufs.
  */
@@ -1958,13 +1979,6 @@
 #endif
 
 /**
- * LWIP_ICMP6_CHECKSUM_CHECK==1: verify checksum on ICMPv6 packets
- */
-#ifndef LWIP_ICMP6_CHECKSUM_CHECK
-#define LWIP_ICMP6_CHECKSUM_CHECK       1
-#endif
-
-/**
  * LWIP_IPV6_MLD==1: Enable multicast listener discovery protocol.
  */
 #ifndef LWIP_IPV6_MLD
diff --git a/src/VBox/Devices/Network/lwip-new/src/include/lwip/snmp.h b/src/VBox/Devices/Network/lwip-new/src/include/lwip/snmp.h
index 2ed043d..7844cc1 100644
--- a/src/VBox/Devices/Network/lwip-new/src/include/lwip/snmp.h
+++ b/src/VBox/Devices/Network/lwip-new/src/include/lwip/snmp.h
@@ -98,7 +98,7 @@ struct snmp_obj_id
 };
 
 /* system */
-void snmp_set_sysdesr(u8_t* str, u8_t* len);
+void snmp_set_sysdescr(const u8_t* str, const u8_t* len);
 void snmp_set_sysobjid(struct snmp_obj_id *oid);
 void snmp_get_sysobjid_ptr(struct snmp_obj_id **oid);
 void snmp_inc_sysuptime(void);
@@ -231,7 +231,7 @@ void snmp_get_snmpenableauthentraps(u8_t *value);
 #else
 
 /* system */
-#define snmp_set_sysdesr(str, len)
+#define snmp_set_sysdescr(str, len)
 #define snmp_set_sysobjid(oid);
 #define snmp_get_sysobjid_ptr(oid)
 #define snmp_inc_sysuptime()
diff --git a/src/VBox/Devices/Network/lwip-new/src/include/lwip/sockets.h b/src/VBox/Devices/Network/lwip-new/src/include/lwip/sockets.h
index 7346137..853beea 100644
--- a/src/VBox/Devices/Network/lwip-new/src/include/lwip/sockets.h
+++ b/src/VBox/Devices/Network/lwip-new/src/include/lwip/sockets.h
@@ -48,33 +48,54 @@
 extern "C" {
 #endif
 
+/* If your port already typedef's sa_family_t, define SA_FAMILY_T_DEFINED
+   to prevent this code from redefining it. */
+#if !defined(sa_family_t) && !defined(SA_FAMILY_T_DEFINED)
+typedef u8_t sa_family_t;
+#endif
+/* If your port already typedef's in_port_t, define IN_PORT_T_DEFINED
+   to prevent this code from redefining it. */
+#if !defined(in_port_t) && !defined(IN_PORT_T_DEFINED)
+typedef u16_t in_port_t;
+#endif
+
 /* members are in network byte order */
 struct sockaddr_in {
-  u8_t sin_len;
-  u8_t sin_family;
-  u16_t sin_port;
-  struct in_addr sin_addr;
+  u8_t            sin_len;
+  sa_family_t     sin_family;
+  in_port_t       sin_port;
+  struct in_addr  sin_addr;
 #define SIN_ZERO_LEN 8
-  char sin_zero[SIN_ZERO_LEN];
+  char            sin_zero[SIN_ZERO_LEN];
 };
 
 #if LWIP_IPV6
 struct sockaddr_in6 {
-  u8_t sin6_len;             /* length of this structure */
-  u8_t sin6_family;          /* AF_INET6                 */
-  u16_t sin6_port;           /* Transport layer port #   */
-  u32_t sin6_flowinfo;       /* IPv6 flow information    */
-  struct in6_addr sin6_addr; /* IPv6 address             */
+  u8_t            sin6_len;      /* length of this structure */
+  sa_family_t     sin6_family;   /* AF_INET6                 */
+  in_port_t       sin6_port;     /* Transport layer port #   */
+  u32_t           sin6_flowinfo; /* IPv6 flow information    */
+  struct in6_addr sin6_addr;     /* IPv6 address             */
 };
 #endif /* LWIP_IPV6 */
 
 struct sockaddr {
-  u8_t sa_len;
-  u8_t sa_family;
+  u8_t        sa_len;
+  sa_family_t sa_family;
 #if LWIP_IPV6
-  u8_t sa_data[22];
+  char        sa_data[22];
 #else /* LWIP_IPV6 */
-  u8_t sa_data[14];
+  char        sa_data[14];
+#endif /* LWIP_IPV6 */
+};
+
+struct sockaddr_storage {
+  u8_t        s2_len;
+  sa_family_t ss_family;
+  char        s2_data1[2];
+  u32_t       s2_data2[3];
+#if LWIP_IPV6
+  u32_t       s2_data3[2];
 #endif /* LWIP_IPV6 */
 };
 
@@ -146,10 +167,12 @@ struct linger {
 #define PF_UNSPEC       AF_UNSPEC
 
 #define IPPROTO_IP      0
+#define IPPROTO_ICMP    1 
 #define IPPROTO_TCP     6
 #define IPPROTO_UDP     17
 #if LWIP_IPV6
 #define IPPROTO_IPV6    41
+#define IPPROTO_ICMPV6  58
 #endif /* LWIP_IPV6 */
 #define IPPROTO_UDPLITE 136
 
diff --git a/src/VBox/Devices/Network/lwip-new/vbox/VBoxLwipCore.cpp b/src/VBox/Devices/Network/lwip-new/vbox/VBoxLwipCore.cpp
index db07f70..f848e7b 100644
--- a/src/VBox/Devices/Network/lwip-new/vbox/VBoxLwipCore.cpp
+++ b/src/VBox/Devices/Network/lwip-new/vbox/VBoxLwipCore.cpp
@@ -74,7 +74,7 @@ static DECLCALLBACK(void) lwipCoreUserCallback(void *pvArg)
         pUserClbk->pfn(pUserClbk->pvUser);
 
     /* wake up caller on EMT/main */
-    lwip_sys_sem_signal(&g_LwipCore.LwipTcpIpSem);
+    sys_sem_signal(&g_LwipCore.LwipTcpIpSem);
     LogFlowFuncLeave();
 }
 
@@ -129,14 +129,14 @@ int vboxLwipCoreInitialize(PFNRT1 pfnCallback, void *pvCallbackArg)
 
         if (g_LwipCore.iLWIPInitiatorCounter == 0)
         {
-            lwipRc = lwip_sys_sem_new(&g_LwipCore.LwipTcpIpSem, 0);
+            lwipRc = sys_sem_new(&g_LwipCore.LwipTcpIpSem, 0);
             if (lwipRc != ERR_OK)
             {
                 LogFlow(("%s: sys_sem_new error %d\n", __FUNCTION__, lwipRc));
                 goto done;
             }
 
-            lwip_tcpip_init(lwipCoreInitDone, &callback);
+            tcpip_init(lwipCoreInitDone, &callback);
         }
         else
         {
@@ -148,7 +148,7 @@ int vboxLwipCoreInitialize(PFNRT1 pfnCallback, void *pvCallbackArg)
             }
         }
 
-        lwip_sys_sem_wait(&g_LwipCore.LwipTcpIpSem, 0);
+        sys_sem_wait(&g_LwipCore.LwipTcpIpSem);
         ++g_LwipCore.iLWIPInitiatorCounter;
     }
   done:
@@ -211,7 +211,7 @@ void vboxLwipCoreFinalize(PFNRT1 pfnCallback, void *pvCallbackArg)
         }
 
         if (lwipRc == ERR_OK)
-            lwip_sys_sem_wait(&g_LwipCore.LwipTcpIpSem, 0);
+            sys_sem_wait(&g_LwipCore.LwipTcpIpSem);
     }
 
     LogFlowFuncLeave();
diff --git a/src/VBox/Devices/Network/lwip-new/vbox/include/lwip-log.h b/src/VBox/Devices/Network/lwip-new/vbox/include/lwip-log.h
new file mode 100644
index 0000000..f66ca8d
--- /dev/null
+++ b/src/VBox/Devices/Network/lwip-new/vbox/include/lwip-log.h
@@ -0,0 +1,93 @@
+/* -*- indent-tabs-mode: nil; -*- */
+#ifndef __VBOX_LWIP_LOG_H__
+#define __VBOX_LWIP_LOG_H__
+
+#include <VBox/log.h>
+
+#ifdef LWIP_DEBUG
+/*
+ * All LWIP_DBG_* constants fit into a byte, so we use upper bits to
+ * encode the VBox log group.
+ *
+ * Mapping between FOO_DEBUG and LOG_GROUP_LWIP_FOO is straightforward
+ * except for IP4 where extra '4' was added to the group names to make
+ * it possible to specify lwip_ip4* instead of lwip_ip*, where the
+ * latter would enable both IP4 and IP6 logging.
+ *
+ * We ignore LWIP_DBG_STATE &c since in our scheme they would traslate
+ * into additional log groups and require combinatorial explosion.  We
+ * probably can use LWIP_DBG_TYPES_ON for finer selection if need be
+ * (for internal debugging only, as it requires recompilation).
+ *
+ * Debug levels are mapped to RT debug levels so lwip's default level
+ * ends up as RT's level4.  Non-default levels are currently not used
+ * much in lwip sources, so enable l4 to get the logs.
+ */
+
+#define LWIP_DEBUGF_LOG_GROUP_SHIFT 8
+#define LWIP_DEBUGF_LOG_GROUP(_g) \
+    (((_g) << LWIP_DEBUGF_LOG_GROUP_SHIFT) | LWIP_DBG_ON)
+
+#define API_LIB_DEBUG    LWIP_DEBUGF_LOG_GROUP(LOG_GROUP_LWIP_API_LIB)
+#define API_MSG_DEBUG    LWIP_DEBUGF_LOG_GROUP(LOG_GROUP_LWIP_API_MSG)
+#define ETHARP_DEBUG     LWIP_DEBUGF_LOG_GROUP(LOG_GROUP_LWIP_ETHARP)
+#define ICMP_DEBUG       LWIP_DEBUGF_LOG_GROUP(LOG_GROUP_LWIP_ICMP)
+#define IGMP_DEBUG       LWIP_DEBUGF_LOG_GROUP(LOG_GROUP_LWIP_IGMP)
+#define INET_DEBUG       LWIP_DEBUGF_LOG_GROUP(LOG_GROUP_LWIP_INET)
+#define IP_DEBUG         LWIP_DEBUGF_LOG_GROUP(LOG_GROUP_LWIP_IP4)
+#define IP_REASS_DEBUG   LWIP_DEBUGF_LOG_GROUP(LOG_GROUP_LWIP_IP4_REASS)
+#define IP6_DEBUG        LWIP_DEBUGF_LOG_GROUP(LOG_GROUP_LWIP_IP6)
+#define MEM_DEBUG        LWIP_DEBUGF_LOG_GROUP(LOG_GROUP_LWIP_MEM)
+#define MEMP_DEBUG       LWIP_DEBUGF_LOG_GROUP(LOG_GROUP_LWIP_MEMP)
+#define NETIF_DEBUG      LWIP_DEBUGF_LOG_GROUP(LOG_GROUP_LWIP_NETIF)
+#define PBUF_DEBUG       LWIP_DEBUGF_LOG_GROUP(LOG_GROUP_LWIP_PBUF)
+#define RAW_DEBUG        LWIP_DEBUGF_LOG_GROUP(LOG_GROUP_LWIP_RAW)
+#define SOCKETS_DEBUG    LWIP_DEBUGF_LOG_GROUP(LOG_GROUP_LWIP_SOCKETS)
+#define SYS_DEBUG        LWIP_DEBUGF_LOG_GROUP(LOG_GROUP_LWIP_SYS)
+#define TCP_CWND_DEBUG   LWIP_DEBUGF_LOG_GROUP(LOG_GROUP_LWIP_TCP_CWND)
+#define TCP_DEBUG        LWIP_DEBUGF_LOG_GROUP(LOG_GROUP_LWIP_TCP)
+#define TCP_FR_DEBUG     LWIP_DEBUGF_LOG_GROUP(LOG_GROUP_LWIP_TCP_FR)
+#define TCP_INPUT_DEBUG  LWIP_DEBUGF_LOG_GROUP(LOG_GROUP_LWIP_TCP_INPUT)
+#define TCP_OUTPUT_DEBUG LWIP_DEBUGF_LOG_GROUP(LOG_GROUP_LWIP_TCP_OUTPUT)
+#define TCP_QLEN_DEBUG   LWIP_DEBUGF_LOG_GROUP(LOG_GROUP_LWIP_TCP_QLEN)
+#define TCP_RST_DEBUG    LWIP_DEBUGF_LOG_GROUP(LOG_GROUP_LWIP_TCP_RST)
+#define TCP_RTO_DEBUG    LWIP_DEBUGF_LOG_GROUP(LOG_GROUP_LWIP_TCP_RTO)
+#define TCP_WND_DEBUG    LWIP_DEBUGF_LOG_GROUP(LOG_GROUP_LWIP_TCP_WND)
+#define TCPIP_DEBUG      LWIP_DEBUGF_LOG_GROUP(LOG_GROUP_LWIP_TCPIP)
+#define TIMERS_DEBUG     LWIP_DEBUGF_LOG_GROUP(LOG_GROUP_LWIP_TIMERS)
+#define UDP_DEBUG        LWIP_DEBUGF_LOG_GROUP(LOG_GROUP_LWIP_UDP)
+
+/*
+ * The following symbols are for debugging of modules that are not
+ * compiled in.  They are listed here for reference but there're no
+ * log groups defined for them currently.
+ */
+#undef AUTOIP_DEBUG
+#undef DHCP_DEBUG
+#undef DNS_DEBUG
+#undef PPP_DEBUG
+#undef SLIP_DEBUG
+#undef SNMP_MIB_DEBUG
+#undef SNMP_MSG_DEBUG
+
+#ifdef LOG_ENABLED
+
+#define LWIP_DEBUGF(_when, _args)                                       \
+    do {                                                                \
+        const VBOX_LOGGROUP _group = (_when) >> LWIP_DEBUGF_LOG_GROUP_SHIFT; \
+        if (_group >= LOG_GROUP_DEFAULT) {                              \
+            /* severe => l1; serious => l2; warning => l3; default => l4 */ \
+            const unsigned int _level =                                 \
+                1 << (LWIP_DBG_MASK_LEVEL+1 - ((_when) & LWIP_DBG_MASK_LEVEL)); \
+            LogIt(LOG_INSTANCE, _level, _group, _args);                 \
+        }                                                               \
+    } while (0)
+
+#else  /* !LOG_ENABLED */
+
+#define LWIP_DEBUGF(_when, _args) do { } while (0)
+
+#endif /* !LOG_ENABLED */
+
+#endif /* LWIP_DEBUG */
+#endif /* __VBOX_LWIP_LOG_H__ */
diff --git a/src/VBox/Devices/Network/lwip-new/vbox/include/lwip-namespace.h b/src/VBox/Devices/Network/lwip-new/vbox/include/lwip-namespace.h
index f5e3f35..41c0ffe 100644
--- a/src/VBox/Devices/Network/lwip-new/vbox/include/lwip-namespace.h
+++ b/src/VBox/Devices/Network/lwip-new/vbox/include/lwip-namespace.h
@@ -88,11 +88,14 @@
 #define netif_set_netmask lwip_netif_set_netmask
 #define netif_set_up lwip_netif_set_up
 #if MEM_LIBC_MALLOC == 0
-#define mem_free lwip_mem_free
+#if MEM_USE_POOLS == 0
 #define mem_init lwip_mem_init
+#define mem_trim lwip_mem_trim
+#endif  /* !MEM_USE_POOLS */
 #define mem_malloc lwip_mem_malloc
-#define mem_realloc lwip_mem_realloc
-#endif
+#define mem_calloc lwip_mem_calloc
+#define mem_free lwip_mem_free
+#endif  /* !MEM_LIBC_MALLOC */
 #define memp_free lwip_memp_free
 #define memp_init lwip_memp_init
 #define memp_malloc lwip_memp_malloc
@@ -147,7 +150,7 @@
 #define sys_sem_free lwip_sys_sem_free
 #define sys_sem_new lwip_sys_sem_new
 #define sys_sem_signal lwip_sys_sem_signal
-#define lwip_sys_sem_wait lwip_sys_arch_sem_wait
+#define lwip_sys_sem_wait sys_sem_wait
 #define sys_arch_sem_wait lwip_sys_arch_sem_wait
 #endif
 #define sys_timeout_debug lwip_sys_timeout_debug
@@ -221,19 +224,4 @@
 #define lwip_pbuf_init()
 #define lwip_etharp_init()
 
-#ifndef htons
-# define htons   lwip_htons
-#endif
-
-#ifndef ntohs
-# define ntohs   lwip_ntohs
-#endif
-
-#ifndef htonl
-# define htonl   lwip_htonl
-#endif
-
-#ifndef ntohl
-# define ntohl   lwip_ntohl
-#endif
 #endif  /* _VBOX_LWIP_NAMESPACE_H_ */
diff --git a/src/VBox/Devices/Network/lwip-new/vbox/include/lwipopts.h b/src/VBox/Devices/Network/lwipopts.h
similarity index 76%
copy from src/VBox/Devices/Network/lwip-new/vbox/include/lwipopts.h
copy to src/VBox/Devices/Network/lwipopts.h
index befb1d2..bc71931 100644
--- a/src/VBox/Devices/Network/lwip-new/vbox/include/lwipopts.h
+++ b/src/VBox/Devices/Network/lwipopts.h
@@ -110,23 +110,21 @@
 #define SYS_LIGHTWEIGHT_PROT 1
 
 /** Attempt to get rid of htons etc. macro issues. */
-#define LWIP_PREFIX_BYTEORDER_FUNCS
-
-#define LWIP_NOASSERT 0
+#undef LWIP_PREFIX_BYTEORDER_FUNCS
 
 #define LWIP_TCPIP_CORE_LOCKING_INPUT 0
 #define LWIP_TCPIP_CORE_LOCKING 0
 #define LWIP_TCP 1
 #define LWIP_SOCKET 1
 #define LWIP_ARP 1
-#define ARP_PROXY 1
+#define ARP_PROXY 0
 #define LWIP_ETHERNET 1
 #define LWIP_COMPAT_SOCKETS 0
 #define LWIP_COMPAT_MUTEX 1
 
 #define LWIP_IPV6 1
-#define LWIP_IPV6_FORWARD 1
-#define LWIP_ND6_PROXY 1
+#define LWIP_IPV6_FORWARD 0
+#define LWIP_ND6_PROXY 0
 
 #define LWIP_ND6_ALLOW_RA_UPDATES       (!LWIP_IPV6_FORWARD)
 #define LWIP_IPV6_SEND_ROUTER_SOLICIT   (!LWIP_IPV6_FORWARD)
@@ -143,8 +141,8 @@
 /** 
  * aka Slirp mode.
  */
-#define LWIP_CONNECTION_PROXY 1
-#define IP_FORWARD            1
+#define LWIP_CONNECTION_PROXY 0
+#define IP_FORWARD            0
 
 /* MEMP_NUM_SYS_TIMEOUT: the number of simultaneously active
    timeouts. */
@@ -156,51 +154,8 @@
 
 /* Debugging stuff. */
 #ifdef DEBUG
-/* filter in debugging severity */
-# define DBG_TYPES_ON (LWIP_DBG_ON | LWIP_DBG_TRACE | LWIP_DBG_STATE | LWIP_DBG_FRESH | LWIP_DBG_HALT)
-# define DBG_MIN_LEVEL 0
-
-# define LWIP_DEBUG LWIP_DBG_ON
-/* Ethernet & ARP debugging */
-# define ETHARP_DEBUG    LWIP_DBG_ON
-/* IPv4 debugging */
-# define IP_DEBUG    LWIP_DBG_ON
-# define IP_REASS_DEBUG  LWIP_DBG_ON
-/* IPv6 debugging */
-# define IP6_DEBUG LWIP_DBG_ON
-/* ICMP debugging */
-# define ICMP_DEBUG  LWIP_DBG_ON
-/* TCP debugging */
-# define TCP_DEBUG   LWIP_DBG_ON
-# define TCP_INPUT_DEBUG LWIP_DBG_ON
-# define TCP_FR_DEBUG    LWIP_DBG_ON
-# define TCP_RTO_DEBUG   LWIP_DBG_ON
-# define TCP_CWND_DEBUG  LWIP_DBG_ON
-# define TCP_WND_DEBUG   LWIP_DBG_ON
-# define TCP_OUTPUT_DEBUG    LWIP_DBG_ON
-# define TCP_RST_DEBUG   LWIP_DBG_ON
-# define TCP_QLEN_DEBUG  LWIP_DBG_ON
-/* RAW API debugging */
-/* API debugging */
-# define NETIF_DEBUG LWIP_DBG_ON
-# define PBUF_DEBUG  LWIP_DBG_ON
-# define API_LIB_DEBUG   LWIP_DBG_ON
-# define API_MSG_DEBUG   LWIP_DBG_ON
-# define SOCKETS_DEBUG   LWIP_DBG_ON
-
-# define INET_DEBUG  LWIP_DBG_ON
-# define RAW_DEBUG   LWIP_DBG_ON
-# define MEM_DEBUG   LWIP_DBG_ON
-# define MEMP_DEBUG  LWIP_DBG_ON
-# define SYS_DEBUG   LWIP_DBG_ON
-
-# define UDP_DEBUG   LWIP_DBG_ON
-# define TCPIP_DEBUG LWIP_DBG_ON
-# define DHCP_DEBUG  LWIP_DBG_ON
-
-# define LWIP_PROXY_DEBUG LWIP_DBG_ON
-/* Debug checks */
-# define TCP_OVERSIZE_DBGCHECK 1
+# define LWIP_DEBUG
+# include "lwip-log.h"
 #endif /* DEBUG */
 
 /* printf formatter definitions */
diff --git a/src/VBox/Devices/PC/BIOS/VBoxBiosAlternative.asm b/src/VBox/Devices/PC/BIOS/VBoxBiosAlternative.asm
index ef96042..068c36e 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.8', 000h, 000h
+    db  'VirtualBox 4.3.10', 000h
 _bios_prefix_string:                         ; 0xf0dba LB 0x8
     db  'BIOS: ', 000h, 000h
 _isotag:                                     ; 0xf0dc2 LB 0x6
@@ -16025,4 +16025,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, 04fh
+    db  030h, 036h, 02fh, 032h, 033h, 02fh, 039h, 039h, 000h, 0fch, 026h
diff --git a/src/VBox/Devices/PC/BIOS/VBoxBiosAlternative.md5sum b/src/VBox/Devices/PC/BIOS/VBoxBiosAlternative.md5sum
index d8860ac..3de9199 100644
--- a/src/VBox/Devices/PC/BIOS/VBoxBiosAlternative.md5sum
+++ b/src/VBox/Devices/PC/BIOS/VBoxBiosAlternative.md5sum
@@ -1 +1 @@
-57043783b40423d82ef1605eae6b1822 *VBoxPcBios.rom
+bb8dc7f1c69895d10cad2dadc4306b6d *VBoxPcBios.rom
diff --git a/src/VBox/Devices/Storage/DrvHostBase.cpp b/src/VBox/Devices/Storage/DrvHostBase.cpp
index cca91d2..5c588f2 100644
--- a/src/VBox/Devices/Storage/DrvHostBase.cpp
+++ b/src/VBox/Devices/Storage/DrvHostBase.cpp
@@ -4,7 +4,7 @@
  */
 
 /*
- * Copyright (C) 2006-2011 Oracle Corporation
+ * Copyright (C) 2006-2014 Oracle Corporation
  *
  * This file is part of VirtualBox Open Source Edition (OSE), as
  * available from http://www.virtualbox.org. This file is free software;
@@ -872,7 +872,7 @@ static int drvHostBaseOpen(PDRVHOSTBASE pThis, PRTFILE pFileDevice, bool fReadOn
                     else
                     {
                         strcpy(szName1, *pszVendor ? pszVendor : pszProduct);
-                        RTStrPrintf(szName2, sizeof(szName2), "%s %s (#%u)", *pszVendor ? pszVendor : pszProduct, i);
+                        RTStrPrintf(szName2, sizeof(szName2), "%s (#%u)", *pszVendor ? pszVendor : pszProduct, i);
                     }
                 }
                 else
diff --git a/src/VBox/Devices/VMMDev/VMMDevHGCM.cpp b/src/VBox/Devices/VMMDev/VMMDevHGCM.cpp
index 8ee189c..ca942b1 100644
--- a/src/VBox/Devices/VMMDev/VMMDevHGCM.cpp
+++ b/src/VBox/Devices/VMMDev/VMMDevHGCM.cpp
@@ -515,6 +515,9 @@ int vmmdevHGCMConnect (PVMMDEV pThis, VMMDevHGCMConnect *pHGCMConnect, RTGCPHYS
         pHGCMConnectCopy->loc.type = VMMDevHGCMLoc_LocalHost_Existing;
 
         rc = pThis->pHGCMDrv->pfnConnect (pThis->pHGCMDrv, pCmd, &pHGCMConnectCopy->loc, &pHGCMConnectCopy->u32ClientID);
+
+        if (RT_FAILURE(rc))
+            vmmdevHGCMRemoveCommand(pThis, pCmd);
     }
     else
     {
@@ -554,6 +557,8 @@ static int vmmdevHGCMConnectSaved (PVMMDEV pThis, VMMDevHGCMConnect *pHGCMConnec
         {
             *pfHGCMCalled = true;
         }
+        /* else
+         *  ... the caller will also execute vmmdevHGCMRemoveCommand() for us */
     }
     else
     {
@@ -580,6 +585,9 @@ int vmmdevHGCMDisconnect (PVMMDEV pThis, VMMDevHGCMDisconnect *pHGCMDisconnect,
         pCmd->paLinPtrs = NULL;
 
         rc = pThis->pHGCMDrv->pfnDisconnect (pThis->pHGCMDrv, pCmd, pHGCMDisconnect->u32ClientID);
+
+        if (RT_FAILURE(rc))
+            vmmdevHGCMRemoveCommand(pThis, pCmd);
     }
     else
     {
@@ -614,6 +622,8 @@ static int vmmdevHGCMDisconnectSaved (PVMMDEV pThis, VMMDevHGCMDisconnect *pHGCM
         {
             *pfHGCMCalled = true;
         }
+        /* else
+         *  ... the caller will also execute vmmdevHGCMRemoveCommand() for us */
     }
     else
     {
@@ -1735,6 +1745,8 @@ static int vmmdevHGCMCallSaved (PVMMDEV pThis, VMMDevHGCMCall *pHGCMCall, RTGCPH
         {
             *pfHGCMCalled = true;
         }
+        /* else
+         *  ... the caller will also execute vmmdevHGCMRemoveCommand() for us */
     }
 
     return rc;
diff --git a/src/VBox/Frontends/VirtualBox/src/globals/UIExtraDataEventHandler.cpp b/src/VBox/Frontends/VirtualBox/src/globals/UIExtraDataEventHandler.cpp
index 60d63aa..5128b76 100644
--- a/src/VBox/Frontends/VirtualBox/src/globals/UIExtraDataEventHandler.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/globals/UIExtraDataEventHandler.cpp
@@ -95,9 +95,20 @@ public slots:
                 Assert(!!vboxGlobal().settings());
             }
         }
-#ifdef Q_WS_MAC
         else if (vboxGlobal().isVMConsoleProcess())
         {
+            /* Take care about HID LEDs sync */
+            if (strKey == GUI_HidLedsSync)
+            {
+                /* If extra data GUI/HidLedsSync is not present in VM config or set
+                 * to 1 then sync is enabled. Otherwise, it is disabled. */
+
+                /* (temporary disabled by default) */
+                bool f = (strValue == "1") ? true : false;
+                emit sigHidLedsSyncStateChanged(f);
+            }
+
+#ifdef Q_WS_MAC
             /* Check for the currently running machine */
             if (strId == vboxGlobal().managedVMUuid())
             {
@@ -108,8 +119,8 @@ public slots:
                     emit sigDockIconAppearanceChange(f);
                 }
             }
-        }
 #endif /* Q_WS_MAC */
+        }
     }
 
 signals:
@@ -117,6 +128,7 @@ signals:
     void sigGUILanguageChange(QString strLang);
     void sigSelectorShortcutsChanged();
     void sigMachineShortcutsChanged();
+    void sigHidLedsSyncStateChanged(bool fEnabled);
 #ifdef RT_OS_DARWIN
     void sigPresentationModeChange(bool fEnabled);
     void sigDockIconAppearanceChange(bool fEnabled);
@@ -190,6 +202,10 @@ UIExtraDataEventHandler::UIExtraDataEventHandler()
             this, SIGNAL(sigMachineShortcutsChanged()),
             Qt::QueuedConnection);
 
+    connect(m_pHandler, SIGNAL(sigHidLedsSyncStateChanged(bool)),
+            this, SIGNAL(sigHidLedsSyncStateChanged(bool)),
+            Qt::QueuedConnection);
+
 #ifdef Q_WS_MAC
     connect(m_pHandler, SIGNAL(sigPresentationModeChange(bool)),
             this, SIGNAL(sigPresentationModeChange(bool)),
diff --git a/src/VBox/Frontends/VirtualBox/src/globals/UIExtraDataEventHandler.h b/src/VBox/Frontends/VirtualBox/src/globals/UIExtraDataEventHandler.h
index 99a3df2..92a035a 100644
--- a/src/VBox/Frontends/VirtualBox/src/globals/UIExtraDataEventHandler.h
+++ b/src/VBox/Frontends/VirtualBox/src/globals/UIExtraDataEventHandler.h
@@ -38,6 +38,7 @@ signals:
     void sigGUILanguageChange(QString strLang);
     void sigSelectorShortcutsChanged();
     void sigMachineShortcutsChanged();
+    void sigHidLedsSyncStateChanged(bool fEnabled);
 #ifdef RT_OS_DARWIN
     void sigPresentationModeChange(bool fEnabled);
     void sigDockIconAppearanceChange(bool fEnabled);
diff --git a/src/VBox/Frontends/VirtualBox/src/platform/darwin/UICocoaApplication.h b/src/VBox/Frontends/VirtualBox/src/platform/darwin/UICocoaApplication.h
index c9b785a..e11f536 100644
--- a/src/VBox/Frontends/VirtualBox/src/platform/darwin/UICocoaApplication.h
+++ b/src/VBox/Frontends/VirtualBox/src/platform/darwin/UICocoaApplication.h
@@ -17,9 +17,19 @@
 #ifndef ___darwin_VBoxCocoaApplication_h
 #define ___darwin_VBoxCocoaApplication_h
 
+/* Qt includes: */
+#include <QMap>
+
+/* GUI includes: */
 #include "VBoxCocoaHelper.h"
+
 ADD_COCOA_NATIVE_REF(UICocoaApplicationPrivate);
 ADD_COCOA_NATIVE_REF(NSAutoreleasePool);
+ADD_COCOA_NATIVE_REF(NSString);
+ADD_COCOA_NATIVE_REF(NSWindow);
+
+/* Forward declarations: */
+class QWidget;
 
 /** Event handler callback.
  * @returns true if handled, false if not.
@@ -29,6 +39,9 @@ ADD_COCOA_NATIVE_REF(NSAutoreleasePool);
  */
 typedef bool (*PFNVBOXCACALLBACK)(const void *pvCocoaEvent, const void *pvCarbonEvent, void *pvUser);
 
+/** Native notification callback type for QWidget. */
+typedef void (*PfnNativeNotificationCallbackForQWidget)(const QString &strNativeNotificationName, QWidget *pWidget);
+
 /* C++ singleton for our private NSApplication object */
 class UICocoaApplication
 {
@@ -39,11 +52,21 @@ public:
     void registerForNativeEvents(uint32_t fMask, PFNVBOXCACALLBACK pfnCallback, void *pvUser);
     void unregisterForNativeEvents(uint32_t fMask, PFNVBOXCACALLBACK pfnCallback, void *pvUser);
 
+    /** Register passed @a pWidget to native notification @a strNativeNotificationName, using @a pCallback as handler. */
+    void registerToNativeNotification(const QString &strNativeNotificationName, QWidget *pWidget, PfnNativeNotificationCallbackForQWidget pCallback);
+    /** Unregister passed @a pWidget from native notification @a strNativeNotificationName. */
+    void unregisterFromNativeNotification(const QString &strNativeNotificationName, QWidget *pWidget);
+    /** Redirects native notification @a pstrNativeNotificationName for window @a pWindow to registered listener. */
+    void nativeNotificationProxy(NativeNSStringRef pstrNativeNotificationName, NativeNSWindowRef pWindow);
+
 private:
     UICocoaApplication();
     static UICocoaApplication *m_pInstance;
     NativeUICocoaApplicationPrivateRef m_pNative;
     NativeNSAutoreleasePoolRef m_pPool;
+
+    /** Map of notification callbacks registered for corresponding QWidget(s). */
+    QMap<QWidget*, QMap<QString, PfnNativeNotificationCallbackForQWidget> > m_callbacks;
 };
 
 #endif /* ___darwin_VBoxCocoaApplication_h */
diff --git a/src/VBox/Frontends/VirtualBox/src/platform/darwin/UICocoaApplication.mm b/src/VBox/Frontends/VirtualBox/src/platform/darwin/UICocoaApplication.mm
index c451471..994e747 100644
--- a/src/VBox/Frontends/VirtualBox/src/platform/darwin/UICocoaApplication.mm
+++ b/src/VBox/Frontends/VirtualBox/src/platform/darwin/UICocoaApplication.mm
@@ -15,7 +15,7 @@
  * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
  */
 
-/* Local includes */
+/* GUI includes: */
 #include "UICocoaApplication.h"
 #include "VBoxUtils-darwin.h"
 
@@ -67,6 +67,10 @@
 - (void)sendEvent:(NSEvent *)theEvent;
 - (void)setCallback:(uint32_t)fMask :(PFNVBOXCACALLBACK)pfnCallback :(void *)pvUser;
 - (void)unsetCallback:(uint32_t)fMask :(PFNVBOXCACALLBACK)pfnCallback :(void *)pvUser;
+
+- (void)registerToNotification :(NSString*)pstrNotificationName :(NSWindow*)pWindow;
+- (void)unregisterFromNotification :(NSString*)pstrNotificationName :(NSWindow*)pWindow;
+- (void)notificationCallback :(NSNotification*)notification;
 @end /* @interface UICocoaApplicationPrivate */
 
 @implementation UICocoaApplicationPrivate
@@ -159,6 +163,45 @@
         fNewMask |= pData->fMask;
     m_fMask = fNewMask;
 }
+
+/** Register @a pWindow to cocoa notification @a pstrNotificationName. */
+- (void) registerToNotification :(NSString*)pstrNotificationName :(NSWindow*)pWindow
+{
+    /* Register notification observer: */
+    [[NSNotificationCenter defaultCenter] addObserver:self
+                                             selector:@selector(notificationCallback:)
+                                                 name:pstrNotificationName
+                                               object:pWindow];
+}
+
+/** Unregister @a pWindow from cocoa notification @a pstrNotificationName. */
+- (void) unregisterFromNotification :(NSString*)pstrNotificationName :(NSWindow*)pWindow
+{
+    /* Uninstall notification observer: */
+    [[NSNotificationCenter defaultCenter] removeObserver:self
+                                                    name:pstrNotificationName
+                                                  object:pWindow];
+}
+
+/** Redirects cocoa @a notification to UICocoaApplication instance. */
+- (void) notificationCallback :(NSNotification*)notification
+{
+    /* Get current notification name: */
+    NSString *pstrName = [notification name];
+
+    /* Define known notification names: */
+    NSString *spstrWillEnterFullscreenNotification = @"NSWindowWillEnterFullScreenNotification";
+    NSString *spstrDidEnterFullscreenNotification  = @"NSWindowDidEnterFullScreenNotification";
+    NSString *spstrWillExitFullscreenNotification  = @"NSWindowWillExitFullScreenNotification";
+    NSString *spstrDidExitFullscreenNotification   = @"NSWindowDidExitFullScreenNotification";
+
+    /* Redirect known notifications to UICocoaApplication instance: */
+    if (   [pstrName isEqualToString :spstrWillEnterFullscreenNotification]
+        || [pstrName isEqualToString :spstrDidEnterFullscreenNotification]
+        || [pstrName isEqualToString :spstrWillExitFullscreenNotification]
+        || [pstrName isEqualToString :spstrDidExitFullscreenNotification])
+        UICocoaApplication::instance()->nativeNotificationProxy(pstrName, [notification object]);
+}
 @end /* @implementation UICocoaApplicationPrivate */
 
 /* C++ singleton for our private NSApplication object */
@@ -200,3 +243,52 @@ void UICocoaApplication::unregisterForNativeEvents(uint32_t fMask, PFNVBOXCACALL
     [m_pNative unsetCallback:fMask :pfnCallback :pvUser];
 }
 
+void UICocoaApplication::registerToNativeNotification(const QString &strNativeNotificationName, QWidget *pWidget, PfnNativeNotificationCallbackForQWidget pCallback)
+{
+    /* Make sure it is not registered yet: */
+    AssertReturnVoid(!m_callbacks.contains(pWidget) || !m_callbacks[pWidget].contains(strNativeNotificationName));
+
+    /* Remember callback: */
+    m_callbacks[pWidget][strNativeNotificationName] = pCallback;
+
+    /* Register observer: */
+    NativeNSStringRef pstrNativeNotificationName = darwinToNativeString(strNativeNotificationName.toLatin1().constData());
+    NativeNSWindowRef pWindow = darwinToNativeWindow(pWidget);
+    [m_pNative registerToNotification :pstrNativeNotificationName :pWindow];
+}
+
+void UICocoaApplication::unregisterFromNativeNotification(const QString &strNativeNotificationName, QWidget *pWidget)
+{
+    /* Make sure it is registered yet: */
+    AssertReturnVoid(m_callbacks.contains(pWidget) && m_callbacks[pWidget].contains(strNativeNotificationName));
+
+    /* Forget callback: */
+    m_callbacks[pWidget].remove(strNativeNotificationName);
+    if (m_callbacks[pWidget].isEmpty())
+        m_callbacks.remove(pWidget);
+
+    /* Unregister observer: */
+    NativeNSStringRef pstrNativeNotificationName = darwinToNativeString(strNativeNotificationName.toLatin1().constData());
+    NativeNSWindowRef pWindow = darwinToNativeWindow(pWidget);
+    [m_pNative unregisterFromNotification :pstrNativeNotificationName :pWindow];
+}
+
+void UICocoaApplication::nativeNotificationProxy(NativeNSStringRef pstrNotificationName, NativeNSWindowRef pWindow)
+{
+    /* Get notification name: */
+    QString strNotificationName = darwinFromNativeString(pstrNotificationName);
+
+    /* Check if existing widget(s) have corresponding notification handler: */
+    const QList<QWidget*> &keys1 = m_callbacks.keys();
+    for (int i = 0; i < keys1.size(); ++i)
+    {
+        QWidget *pWidget = keys1[i];
+        if (darwinToNativeWindow(pWidget) == pWindow)
+        {
+            const QMap<QString, PfnNativeNotificationCallbackForQWidget> &callbacks = m_callbacks[pWidget];
+            if (callbacks.contains(strNotificationName))
+                callbacks[strNotificationName](strNotificationName, pWidget);
+        }
+    }
+}
+
diff --git a/src/VBox/Frontends/VirtualBox/src/platform/darwin/VBoxUtils-darwin-cocoa.mm b/src/VBox/Frontends/VirtualBox/src/platform/darwin/VBoxUtils-darwin-cocoa.mm
index f34c197..6ce8db8 100644
--- a/src/VBox/Frontends/VirtualBox/src/platform/darwin/VBoxUtils-darwin-cocoa.mm
+++ b/src/VBox/Frontends/VirtualBox/src/platform/darwin/VBoxUtils-darwin-cocoa.mm
@@ -35,6 +35,10 @@
 #include <Carbon/Carbon.h>
 #include "DarwinKeyboard.h"
 
+/** Easy way of dynamical call for 10.7 AppKit functionality we do not yet support. */
+#define NSWindowCollectionBehaviorFullScreenPrimary (1 << 7)
+#define NSFullScreenWindowMask (1 << 14)
+
 NativeNSWindowRef darwinToNativeWindowImpl(NativeNSViewRef pView)
 {
     NativeNSWindowRef window = NULL;
@@ -92,6 +96,11 @@ NativeNSStringRef darwinToNativeString(const char* pcszString)
     return [NSString stringWithUTF8String: pcszString];
 }
 
+QString darwinFromNativeString(NativeNSStringRef pString)
+{
+    return [pString cStringUsingEncoding :NSASCIIStringEncoding];
+}
+
 void darwinSetShowsToolbarButtonImpl(NativeNSWindowRef pWindow, bool fEnabled)
 {
     [pWindow setShowsToolbarButton:fEnabled];
@@ -176,6 +185,40 @@ void darwinMinaturizeWindow(NativeNSWindowRef pWindow)
 //    [pWindow performMiniaturize:nil];
 }
 
+void darwinEnableFullscreenSupport(NativeNSWindowRef pWindow)
+{
+    [pWindow setCollectionBehavior :NSWindowCollectionBehaviorFullScreenPrimary];
+}
+
+void darwinEnableTransienceSupport(NativeNSWindowRef pWindow)
+{
+    [pWindow setCollectionBehavior :NSWindowCollectionBehaviorTransient];
+}
+
+void darwinToggleFullscreenMode(NativeNSWindowRef pWindow)
+{
+    /* Toggle native fullscreen mode for passed pWindow. This method is available since 10.7 only.
+     * To automatically sync this method subsequent calls we performing it on the main (GUI) thread. */
+    if ([pWindow respondsToSelector: @selector(toggleFullScreen:)])
+        [pWindow performSelectorOnMainThread: @selector(toggleFullScreen:) withObject: (id)nil waitUntilDone :NO];
+}
+
+bool darwinIsInFullscreenMode(NativeNSWindowRef pWindow)
+{
+    /* Check whether passed pWindow is in native fullscreen mode. */
+    return [pWindow styleMask] & NSFullScreenWindowMask;
+}
+
+bool darwinScreensHaveSeparateSpaces()
+{
+    /* Check whether screens have separate spaces.
+     * This method is available since 10.9 only. */
+    if ([NSScreen respondsToSelector: @selector(screensHaveSeparateSpaces)])
+        return [NSScreen performSelector: @selector(screensHaveSeparateSpaces)];
+    else
+        return false;
+}
+
 void darwinSetDockIconMenu(QMenu* pMenu)
 {
     extern void qt_mac_set_dock_menu(QMenu *);
diff --git a/src/VBox/Frontends/VirtualBox/src/platform/darwin/VBoxUtils-darwin.cpp b/src/VBox/Frontends/VirtualBox/src/platform/darwin/VBoxUtils-darwin.cpp
index 1fe6424..a7aa965 100644
--- a/src/VBox/Frontends/VirtualBox/src/platform/darwin/VBoxUtils-darwin.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/platform/darwin/VBoxUtils-darwin.cpp
@@ -138,6 +138,26 @@ void darwinMinaturizeWindow(QWidget *pWidget)
     return ::darwinMinaturizeWindow(::darwinToNativeWindow(pWidget));
 }
 
+void darwinEnableFullscreenSupport(QWidget *pWidget)
+{
+    return ::darwinEnableFullscreenSupport(::darwinToNativeWindow(pWidget));
+}
+
+void darwinEnableTransienceSupport(QWidget *pWidget)
+{
+    return ::darwinEnableTransienceSupport(::darwinToNativeWindow(pWidget));
+}
+
+void darwinToggleFullscreenMode(QWidget *pWidget)
+{
+    return ::darwinToggleFullscreenMode(::darwinToNativeWindow(pWidget));
+}
+
+bool darwinIsInFullscreenMode(QWidget *pWidget)
+{
+    return ::darwinIsInFullscreenMode(::darwinToNativeWindow(pWidget));
+}
+
 void darwinInstallResizeDelegate(QWidget *pWidget)
 {
     ::darwinInstallResizeDelegate(::darwinToNativeWindow(pWidget));
diff --git a/src/VBox/Frontends/VirtualBox/src/platform/darwin/VBoxUtils-darwin.h b/src/VBox/Frontends/VirtualBox/src/platform/darwin/VBoxUtils-darwin.h
index 3798cf8..ed75cd2 100644
--- a/src/VBox/Frontends/VirtualBox/src/platform/darwin/VBoxUtils-darwin.h
+++ b/src/VBox/Frontends/VirtualBox/src/platform/darwin/VBoxUtils-darwin.h
@@ -49,6 +49,7 @@ RT_C_DECLS_BEGIN
 NativeNSWindowRef darwinToNativeWindowImpl(NativeNSViewRef pView);
 NativeNSViewRef darwinToNativeViewImpl(NativeNSWindowRef pWindow);
 NativeNSStringRef darwinToNativeString(const char* pcszString);
+QString darwinFromNativeString(NativeNSStringRef pString);
 
 /********************************************************************************
  *
@@ -77,6 +78,11 @@ int  darwinWindowToolBarHeight(NativeNSWindowRef pWindow);
 bool darwinIsToolbarVisible(NativeNSWindowRef pWindow);
 bool darwinIsWindowMaximized(NativeNSWindowRef pWindow);
 void darwinMinaturizeWindow(NativeNSWindowRef pWindow);
+void darwinEnableFullscreenSupport(NativeNSWindowRef pWindow);
+void darwinEnableTransienceSupport(NativeNSWindowRef pWindow);
+void darwinToggleFullscreenMode(NativeNSWindowRef pWindow);
+bool darwinIsInFullscreenMode(NativeNSWindowRef pWindow);
+bool darwinScreensHaveSeparateSpaces();
 
 bool darwinOpenFile(NativeNSStringRef pstrFile);
 
@@ -238,6 +244,10 @@ int  darwinWindowToolBarHeight(QWidget *pWidget);
 bool darwinIsToolbarVisible(QToolBar *pToolBar);
 bool darwinIsWindowMaximized(QWidget *pWidget);
 void darwinMinaturizeWindow(QWidget *pWidget);
+void darwinEnableFullscreenSupport(QWidget *pWidget);
+void darwinEnableTransienceSupport(QWidget *pWidget);
+void darwinToggleFullscreenMode(QWidget *pWidget);
+bool darwinIsInFullscreenMode(QWidget *pWidget);
 bool darwinOpenFile(const QString &strFile);
 
 QString darwinSystemLanguage(void);
diff --git a/src/VBox/Frontends/VirtualBox/src/runtime/UIFrameBuffer.cpp b/src/VBox/Frontends/VirtualBox/src/runtime/UIFrameBuffer.cpp
index d2c546e..19e3bab 100644
--- a/src/VBox/Frontends/VirtualBox/src/runtime/UIFrameBuffer.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/runtime/UIFrameBuffer.cpp
@@ -283,6 +283,14 @@ STDMETHODIMP UIFrameBuffer::RequestResize(ULONG uScreenId, ULONG uPixelFormat,
  */
 STDMETHODIMP UIFrameBuffer::NotifyUpdate(ULONG uX, ULONG uY, ULONG uWidth, ULONG uHeight)
 {
+    /* Retina screens with physical-to-logical scaling requires
+     * odd/even pixel updates to be taken into account,
+     * otherwise we have artifacts on the borders of incoming rectangle. */
+    uX = qMax(0, (int)uX - 1);
+    uY = qMax(0, (int)uY - 1);
+    uWidth = qMin((int)m_width, (int)uWidth + 2);
+    uHeight = qMin((int)m_height, (int)uHeight + 2);
+
     LogRel2(("UIFrameBuffer::NotifyUpdate: Origin=%lux%lu, Size=%lux%lu\n",
              (unsigned long)uX, (unsigned long)uY,
              (unsigned long)uWidth, (unsigned long)uHeight));
diff --git a/src/VBox/Frontends/VirtualBox/src/runtime/UIKeyboardHandler.cpp b/src/VBox/Frontends/VirtualBox/src/runtime/UIKeyboardHandler.cpp
index 9688241..670f6e4 100644
--- a/src/VBox/Frontends/VirtualBox/src/runtime/UIKeyboardHandler.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/runtime/UIKeyboardHandler.cpp
@@ -1212,13 +1212,11 @@ bool UIKeyboardHandler::keyEventHandleNormal(int iKey, uint8_t uScan, int fFlags
      * we are updating the list of pressed keys and preparing scancodes: */
     if ((fFlags & KeyPressed) || (m_pressedKeys[uScan] & uWhatPressed))
     {
-        /* Check if the guest has the same view on the modifier keys
-         * (NumLock, CapsLock, ScrollLock) as the X server.
-         * If not, send KeyPress events to synchronize the state: */
-#if !defined(Q_WS_MAC) && !defined(Q_WS_WIN)
-        if (fFlags & KeyPressed)
-            fixModifierState(pCodes, puCodesCount);
-#endif
+        /* If HID LEDs sync is disabled or not supported, check if the guest has the
+         * same view on the modifier keys (NumLock, CapsLock, ScrollLock) as the host. */
+        if (!machineLogic()->isHidLedsSyncEnabled())
+            if (fFlags & KeyPressed)
+                fixModifierState(pCodes, puCodesCount);
 
         /* Prepend 'extended' scancode if needed: */
         if (fFlags & KeyExtended)
diff --git a/src/VBox/Frontends/VirtualBox/src/runtime/UIMachine.cpp b/src/VBox/Frontends/VirtualBox/src/runtime/UIMachine.cpp
index fb985cd..0e24a86 100644
--- a/src/VBox/Frontends/VirtualBox/src/runtime/UIMachine.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/runtime/UIMachine.cpp
@@ -22,9 +22,6 @@
 #include "UIActionPoolRuntime.h"
 #include "UIMachineLogic.h"
 #include "UIMachineWindow.h"
-#ifdef Q_WS_MAC
-# include <ApplicationServices/ApplicationServices.h>
-#endif /* Q_WS_MAC */
 
 /* Visual state interface: */
 class UIVisualState : public QObject
@@ -39,9 +36,6 @@ public:
         , m_type(type)
         , m_pSession(pSession)
         , m_pMachineLogic(0)
-#ifdef Q_WS_MAC
-        , m_fadeToken(kCGDisplayFadeReservationInvalidToken)
-#endif /* Q_WS_MAC */
     {
     }
 
@@ -65,26 +59,10 @@ public:
     UIMachineLogic* machineLogic() const { return m_pMachineLogic; }
 
     /* Method to prepare change one visual state to another: */
-    bool prepareChange(UIVisualStateType previousVisualStateType)
+    bool prepareChange()
     {
         m_pMachineLogic = UIMachineLogic::create(this, m_pSession, visualStateType());
-        bool fResult = m_pMachineLogic->checkAvailability();
-#ifdef Q_WS_MAC
-        /* If the new is or the old type was fullscreen we add the blending
-         * transition between the mode switches.
-         * TODO: make this more general. */
-        if (   fResult
-            && (   visualStateType() == UIVisualStateType_Fullscreen
-                || previousVisualStateType == UIVisualStateType_Fullscreen))
-        {
-            /* Fade to black */
-            CGAcquireDisplayFadeReservation(kCGMaxDisplayReservationInterval, &m_fadeToken);
-            CGDisplayFade(m_fadeToken, 0.3, kCGDisplayBlendNormal, kCGDisplayBlendSolidColor, 0.0, 0.0, 0.0, true);
-        }
-#else /* Q_WS_MAC */
-        Q_UNUSED(previousVisualStateType);
-#endif /* !Q_WS_MAC */
-        return fResult;
+        return m_pMachineLogic->checkAvailability();
     }
 
     /* Method to change one visual state to another: */
@@ -94,31 +72,12 @@ public:
         m_pMachineLogic->prepare();
     }
 
-    /* Method to finish change one visual state to another: */
-    void finishChange()
-    {
-#ifdef Q_WS_MAC
-        /* If there is a valid fade token, fade back to normal color in any
-         * case. */
-        if (m_fadeToken != kCGDisplayFadeReservationInvalidToken)
-        {
-            /* Fade back to the normal gamma */
-            CGDisplayFade(m_fadeToken, 0.5, kCGDisplayBlendSolidColor, kCGDisplayBlendNormal, 0.0, 0.0, 0.0, false);
-            CGReleaseDisplayFadeReservation(m_fadeToken);
-            m_fadeToken = kCGDisplayFadeReservationInvalidToken;
-        }
-#endif /* Q_WS_MAC */
-    }
-
 protected:
 
     /* Variables: */
     UIVisualStateType m_type;
     UISession *m_pSession;
     UIMachineLogic *m_pMachineLogic;
-#ifdef Q_WS_MAC
-    CGDisplayFadeReservationToken m_fadeToken;
-#endif /* Q_WS_MAC */
 };
 
 UIMachine::UIMachine(UIMachine **ppSelf, const CSession &session)
@@ -199,12 +158,9 @@ void UIMachine::sltChangeVisualState(UIVisualStateType newVisualStateType)
     /* Create new state: */
     UIVisualState *pNewVisualState = new UIVisualState(this, m_pSession, newVisualStateType);
 
-    /* Get previous visual state type: */
-    UIVisualStateType previousVisualStateType = m_pVisualState ? m_pVisualState->visualStateType() : UIVisualStateType_Normal;
-
     /* First we have to check if the selected mode is available at all.
      * Only then we delete the old mode and switch to the new mode. */
-    if (pNewVisualState->prepareChange(previousVisualStateType))
+    if (pNewVisualState->prepareChange())
     {
         /* Delete previous state: */
         delete m_pVisualState;
@@ -212,9 +168,6 @@ void UIMachine::sltChangeVisualState(UIVisualStateType newVisualStateType)
         /* Set the new mode as current mode: */
         m_pVisualState = pNewVisualState;
         m_pVisualState->change();
-
-        /* Finish any setup: */
-        m_pVisualState->finishChange();
     }
     else
     {
diff --git a/src/VBox/Frontends/VirtualBox/src/runtime/UIMachineLogic.cpp b/src/VBox/Frontends/VirtualBox/src/runtime/UIMachineLogic.cpp
index e7ced6d..de3b11c 100644
--- a/src/VBox/Frontends/VirtualBox/src/runtime/UIMachineLogic.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/runtime/UIMachineLogic.cpp
@@ -55,6 +55,7 @@
 #include "UIConverter.h"
 #include "UIModalWindowManager.h"
 #include "UIMedium.h"
+#include "UIExtraDataEventHandler.h"
 #ifdef Q_WS_MAC
 # include "DockIconPreview.h"
 # include "UIExtraDataEventHandler.h"
@@ -398,6 +399,30 @@ void UIMachineLogic::notifyAbout3DOverlayVisibilityChange(bool fVisible)
     }
 }
 
+void UIMachineLogic::sltChangeVisualStateToNormal()
+{
+    uisession()->setRequestedVisualState(UIVisualStateType_Invalid);
+    uisession()->changeVisualState(UIVisualStateType_Normal);
+}
+
+void UIMachineLogic::sltChangeVisualStateToFullscreen()
+{
+    uisession()->setRequestedVisualState(UIVisualStateType_Invalid);
+    uisession()->changeVisualState(UIVisualStateType_Fullscreen);
+}
+
+void UIMachineLogic::sltChangeVisualStateToSeamless()
+{
+    uisession()->setRequestedVisualState(UIVisualStateType_Invalid);
+    uisession()->changeVisualState(UIVisualStateType_Seamless);
+}
+
+void UIMachineLogic::sltChangeVisualStateToScale()
+{
+    uisession()->setRequestedVisualState(UIVisualStateType_Invalid);
+    uisession()->changeVisualState(UIVisualStateType_Scale);
+}
+
 void UIMachineLogic::sltMachineStateChanged()
 {
     /* Get machine state: */
@@ -510,6 +535,11 @@ void UIMachineLogic::sltMouseCapabilityChanged()
         pAction->setChecked(false);
 }
 
+void UIMachineLogic::sltHidLedsSyncStateChanged(bool fEnabled)
+{
+    m_isHidLedsSyncEnabled = fEnabled;
+}
+
 void UIMachineLogic::sltKeyboardLedsChanged()
 {
     /* Here we have to update host LED lock states using values provided by UISession:
@@ -572,25 +602,29 @@ void UIMachineLogic::sltShowWindows()
 
 void UIMachineLogic::sltGuestMonitorChange(KGuestMonitorChangedEventType, ulong, QRect)
 {
-    /* Deliver event to all machine-windows: */
+    LogRel(("UIMachineLogic: Guest-screen count changed.\n"));
+
+    /* Make sure all machine-window(s) have proper geometry: */
     foreach (UIMachineWindow *pMachineWindow, machineWindows())
-        pMachineWindow->handleScreenCountChange();
+        pMachineWindow->showInNecessaryMode();
 }
 
 void UIMachineLogic::sltHostScreenCountChanged()
 {
-    /* Deliver event to all machine-windows: */
+    LogRel(("UIMachineLogic: Host-screen count changed.\n"));
+
+    /* Make sure all machine-window(s) have proper geometry: */
     foreach (UIMachineWindow *pMachineWindow, machineWindows())
-        pMachineWindow->handleScreenCountChange();
+        pMachineWindow->showInNecessaryMode();
 }
 
 void UIMachineLogic::sltHostScreenGeometryChanged()
 {
-    LogRelFlow(("UIMachineLogic: Host-screen geometry changed.\n"));
+    LogRel(("UIMachineLogic: Host-screen geometry changed.\n"));
 
-    /* Deliver event to all machine-windows: */
+    /* Make sure all machine-window(s) have proper geometry: */
     foreach (UIMachineWindow *pMachineWindow, machineWindows())
-        pMachineWindow->handleScreenGeometryChange();
+        pMachineWindow->showInNecessaryMode();
 }
 
 UIMachineLogic::UIMachineLogic(QObject *pParent, UISession *pSession, UIVisualStateType visualStateType)
@@ -618,7 +652,28 @@ UIMachineLogic::UIMachineLogic(QObject *pParent, UISession *pSession, UIVisualSt
     , m_DockIconPreviewMonitor(0)
 #endif /* Q_WS_MAC */
     , m_pHostLedsState(NULL)
+    , m_isHidLedsSyncEnabled(false)
 {
+    /* Setup HID LEDs synchronization. */
+#if defined(Q_WS_MAC) || defined(Q_WS_WIN)
+    /* Read initial extradata value. */
+    QString strHidLedsSyncSettings = session().GetMachine().GetExtraData(GUI_HidLedsSync);
+
+    /* If extra data GUI/HidLedsSync is not present in VM config or set
+     * to 1 then sync is enabled. Otherwise, it is disabled. */
+
+    /* (temporary disabled by default) */
+    if (strHidLedsSyncSettings == "1")
+        m_isHidLedsSyncEnabled = true;
+    else
+        m_isHidLedsSyncEnabled = false;
+
+    /* Subscribe to GUI_HidLedsSync extradata changes in order to
+     * be able to enable or disable feature dynamically. */
+    connect(gEDataEvents, SIGNAL(sigHidLedsSyncStateChanged(bool)), this, SLOT(sltHidLedsSyncStateChanged(bool)));
+#else
+    m_isHidLedsSyncEnabled = false;
+#endif
 }
 
 void UIMachineLogic::setMachineWindowsCreated(bool fIsWindowsCreated)
@@ -691,14 +746,6 @@ void UIMachineLogic::retranslateUi()
     }
 }
 
-bool UIMachineLogic::isHidLedsSyncEnabled()
-{
-    QString strHidLedsSyncSettings = session().GetMachine().GetExtraData(GUI_HidLedsSync);
-    if (strHidLedsSyncSettings == "1")
-        return true;
-    return false;
-}
-
 #ifdef Q_WS_MAC
 void UIMachineLogic::updateDockOverlay()
 {
diff --git a/src/VBox/Frontends/VirtualBox/src/runtime/UIMachineLogic.h b/src/VBox/Frontends/VirtualBox/src/runtime/UIMachineLogic.h
index d8b7104..69b84bd 100644
--- a/src/VBox/Frontends/VirtualBox/src/runtime/UIMachineLogic.h
+++ b/src/VBox/Frontends/VirtualBox/src/runtime/UIMachineLogic.h
@@ -97,11 +97,23 @@ public:
     /* API: 3D overlay visibility stuff: */
     virtual void notifyAbout3DOverlayVisibilityChange(bool fVisible);
 
+    /** Performs HID LEDs sync. */
+    bool isHidLedsSyncEnabled() { return m_isHidLedsSyncEnabled; };
+
 protected slots:
 
     /** Checks if some visual-state type was requested. */
     virtual void sltCheckForRequestedVisualStateType() {}
 
+    /** Requests visual-state change to 'normal' (window). */
+    virtual void sltChangeVisualStateToNormal();
+    /** Requests visual-state change to 'fullscreen'. */
+    virtual void sltChangeVisualStateToFullscreen();
+    /** Requests visual-state change to 'seamless'. */
+    virtual void sltChangeVisualStateToSeamless();
+    /** Requests visual-state change to 'scale'. */
+    virtual void sltChangeVisualStateToScale();
+
     /* Console callback handlers: */
     virtual void sltMachineStateChanged();
     virtual void sltAdditionsStateChanged();
@@ -132,7 +144,6 @@ protected:
     void setMouseHandler(UIMouseHandler *pMouseHandler);
     void addMachineWindow(UIMachineWindow *pMachineWindow);
     void retranslateUi();
-    bool isHidLedsSyncEnabled();
 #ifdef Q_WS_MAC
     bool isDockIconPreviewEnabled() const { return m_fIsDockIconEnabled; }
     void setDockIconPreviewEnabled(bool fIsDockIconPreviewEnabled) { m_fIsDockIconEnabled = fIsDockIconPreviewEnabled; }
@@ -232,6 +243,7 @@ private slots:
 #endif /* RT_OS_DARWIN */
 
     /* Handlers: Keyboard LEDs sync logic: */
+    void sltHidLedsSyncStateChanged(bool fEnabled);
     void sltSwitchKeyboardLedsToGuestLeds();
     void sltSwitchKeyboardLedsToPreviousLeds();
 
@@ -277,6 +289,7 @@ private:
 #endif /* Q_WS_MAC */
 
     void *m_pHostLedsState;
+    bool m_isHidLedsSyncEnabled;
 
     /* Friend classes: */
     friend class UIMachineWindow;
diff --git a/src/VBox/Frontends/VirtualBox/src/runtime/UIMachineView.cpp b/src/VBox/Frontends/VirtualBox/src/runtime/UIMachineView.cpp
index 5eb78a0..9f396a2 100644
--- a/src/VBox/Frontends/VirtualBox/src/runtime/UIMachineView.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/runtime/UIMachineView.cpp
@@ -375,7 +375,7 @@ UIMachineView::UIMachineView(  UIMachineWindow *pMachineWindow
                              , bool bAccelerate2DVideo
 #endif /* VBOX_WITH_VIDEOHWACCEL */
                              )
-    : QAbstractScrollArea(pMachineWindow)
+    : QAbstractScrollArea(pMachineWindow->centralWidget())
     , m_pMachineWindow(pMachineWindow)
     , m_uScreenId(uScreenId)
     , m_pFrameBuffer(0)
diff --git a/src/VBox/Frontends/VirtualBox/src/runtime/UIMachineWindow.cpp b/src/VBox/Frontends/VirtualBox/src/runtime/UIMachineWindow.cpp
index 08fa1b1..776589f 100644
--- a/src/VBox/Frontends/VirtualBox/src/runtime/UIMachineWindow.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/runtime/UIMachineWindow.cpp
@@ -441,26 +441,6 @@ void UIMachineWindow::cleanupMachineView()
     m_pMachineView = 0;
 }
 
-void UIMachineWindow::handleScreenCountChange()
-{
-    /* Ignore if window is minimized: */
-    if (isMinimized())
-        return;
-
-    /* Make sure window is in necessary mode: */
-    showInNecessaryMode();
-}
-
-void UIMachineWindow::handleScreenGeometryChange()
-{
-    /* Ignore if window is minimized: */
-    if (isMinimized())
-        return;
-
-    /* Make sure window is in necessary mode: */
-    showInNecessaryMode();
-}
-
 void UIMachineWindow::updateAppearanceOf(int iElement)
 {
     /* Update window title: */
@@ -527,3 +507,19 @@ Qt::Alignment UIMachineWindow::viewAlignment(UIVisualStateType visualStateType)
     return 0;
 }
 
+#ifdef Q_WS_MAC
+void UIMachineWindow::handleNativeNotification(const QString &strNativeNotificationName, QWidget *pWidget)
+{
+    /* Handle arrived notification: */
+    LogRel(("UIMachineWindow::handleNativeNotification: Notification '%s' received.\n",
+            strNativeNotificationName.toAscii().constData()));
+    if (UIMachineWindow *pMachineWindow = qobject_cast<UIMachineWindow*>(pWidget))
+    {
+        /* Redirect arrived notification: */
+        LogRel(("UIMachineWindow::handleNativeNotification: Redirecting '%s' notification to corresponding machine-window...\n",
+                strNativeNotificationName.toAscii().constData()));
+        pMachineWindow->handleNativeNotification(strNativeNotificationName);
+    }
+}
+#endif /* Q_WS_MAC */
+
diff --git a/src/VBox/Frontends/VirtualBox/src/runtime/UIMachineWindow.h b/src/VBox/Frontends/VirtualBox/src/runtime/UIMachineWindow.h
index d41b37b..c942442 100644
--- a/src/VBox/Frontends/VirtualBox/src/runtime/UIMachineWindow.h
+++ b/src/VBox/Frontends/VirtualBox/src/runtime/UIMachineWindow.h
@@ -55,6 +55,7 @@ public:
     void cleanup();
 
     /* Public getters: */
+    ulong screenId() const { return m_uScreenId; }
     UIMachineView* machineView() const { return m_pMachineView; }
     UIMachineLogic* machineLogic() const { return m_pMachineLogic; }
     UISession* uisession() const;
@@ -93,6 +94,12 @@ protected:
 #endif /* Q_WS_X11 */
     void closeEvent(QCloseEvent *pEvent);
 
+#ifdef Q_WS_MAC
+    /** Mac OS X: Handles native notifications.
+      * @param  strNativeNotificationName  Native notification name. */
+    virtual void handleNativeNotification(const QString & /* strNativeNotificationName */) {}
+#endif /* Q_WS_MAC */
+
     /* Prepare helpers: */
     virtual void prepareSessionConnections();
     virtual void prepareMainLayout();
@@ -113,10 +120,6 @@ protected:
     virtual void cleanupMainLayout() {}
     virtual void cleanupSessionConnections() {}
 
-    /* Visibility stuff: */
-    void handleScreenCountChange();
-    void handleScreenGeometryChange();
-
     /* Update stuff: */
     virtual void updateAppearanceOf(int iElement);
 #ifdef VBOX_WITH_DEBUGGER_GUI
@@ -128,6 +131,13 @@ protected:
     static Qt::WindowFlags windowFlags(UIVisualStateType visualStateType);
     static Qt::Alignment viewAlignment(UIVisualStateType visualStateType);
 
+#ifdef Q_WS_MAC
+    /** Mac OS X: Handles native notifications.
+      * @param  strNativeNotificationName  Native notification name.
+      * @param  pWidget                    Widget, notification related to. */
+    static void handleNativeNotification(const QString &strNativeNotificationName, QWidget *pWidget);
+#endif /* Q_WS_MAC */
+
     /* Variables: */
     UIMachineLogic *m_pMachineLogic;
     UIMachineView *m_pMachineView;
diff --git a/src/VBox/Frontends/VirtualBox/src/runtime/UIMouseHandler.cpp b/src/VBox/Frontends/VirtualBox/src/runtime/UIMouseHandler.cpp
index fde4205..309aa1a 100644
--- a/src/VBox/Frontends/VirtualBox/src/runtime/UIMouseHandler.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/runtime/UIMouseHandler.cpp
@@ -21,6 +21,7 @@
 #include <QDesktopWidget>
 #include <QMouseEvent>
 #include <QTouchEvent>
+#include <QTimer>
 
 /* GUI includes: */
 #include "VBoxGlobal.h"
@@ -425,6 +426,21 @@ void UIMouseHandler::sltMousePointerShapeChanged()
     }
 }
 
+void UIMouseHandler::sltMaybeActivateHoveredWindow()
+{
+    /* Are we still have hovered window to activate? */
+    if (m_pHoveredWindow && !m_pHoveredWindow->isActiveWindow())
+    {
+        /* Activate it: */
+        m_pHoveredWindow->activateWindow();
+#ifdef Q_WS_X11
+        /* On X11 its not enough to just activate window if you
+         * want to raise it also, so we will make it separately: */
+        m_pHoveredWindow->raise();
+#endif /* Q_WS_X11 */
+    }
+}
+
 /* Mouse-handler constructor: */
 UIMouseHandler::UIMouseHandler(UIMachineLogic *pMachineLogic)
     : QObject(pMachineLogic)
@@ -547,13 +563,25 @@ bool UIMouseHandler::eventFilter(QObject *pWatched, QEvent *pEvent)
                 case QEvent::MouseMove:
                 case QEvent::MouseButtonRelease:
                 {
+                    /* Get mouse-event: */
+                    QMouseEvent *pOldMouseEvent = static_cast<QMouseEvent*>(pEvent);
+
+                    /* Check which viewport(s) we *probably* hover: */
+                    QWidgetList probablyHoveredViewports;
+                    foreach (QWidget *pViewport, m_viewports)
+                    {
+                        QPoint posInViewport = pViewport->mapFromGlobal(pOldMouseEvent->globalPos());
+                        if (pViewport->geometry().adjusted(0, 0, 1, 1).contains(posInViewport))
+                            probablyHoveredViewports << pViewport;
+                    }
+                    /* Determine actually hovered viewport: */
+                    QWidget *pHoveredWidget = probablyHoveredViewports.isEmpty() ? 0 :
+                                              probablyHoveredViewports.contains(pWatchedWidget) ? pWatchedWidget :
+                                              probablyHoveredViewports.first();
+
                     /* Check if we should propagate this event to another window: */
-                    QWidget *pHoveredWidget = QApplication::widgetAt(QCursor::pos());
                     if (pHoveredWidget && pHoveredWidget != pWatchedWidget && m_viewports.values().contains(pHoveredWidget))
                     {
-                        /* Get current mouse-move event: */
-                        QMouseEvent *pOldMouseEvent = static_cast<QMouseEvent*>(pEvent);
-
                         /* Prepare redirected mouse-move event: */
                         QMouseEvent *pNewMouseEvent = new QMouseEvent(pOldMouseEvent->type(),
                                                                       pHoveredWidget->mapFromGlobal(pOldMouseEvent->globalPos()),
@@ -584,13 +612,14 @@ bool UIMouseHandler::eventFilter(QObject *pWatched, QEvent *pEvent)
                         m_windows.values().contains(pWatchedWidget->window()) &&
                         QApplication::activeWindow() != pWatchedWidget->window())
                     {
-                        /* Activating hovered machine window: */
-                        pWatchedWidget->window()->activateWindow();
-#ifdef Q_WS_X11
-                        /* On X11 its not enough to just activate window if you
-                         * want to raise it also, so we will make it separately: */
-                        pWatchedWidget->window()->raise();
-#endif /* Q_WS_X11 */
+                        /* Put request for hovered window activation in 300msec: */
+                        m_pHoveredWindow = pWatchedWidget->window();
+                        QTimer::singleShot(300, this, SLOT(sltMaybeActivateHoveredWindow()));
+                    }
+                    else
+                    {
+                        /* Revoke request for hovered window activation: */
+                        m_pHoveredWindow = 0;
                     }
 
                     /* This event should be also processed using next 'case': */
diff --git a/src/VBox/Frontends/VirtualBox/src/runtime/UIMouseHandler.h b/src/VBox/Frontends/VirtualBox/src/runtime/UIMouseHandler.h
index f94c9f5..b659a58 100644
--- a/src/VBox/Frontends/VirtualBox/src/runtime/UIMouseHandler.h
+++ b/src/VBox/Frontends/VirtualBox/src/runtime/UIMouseHandler.h
@@ -24,6 +24,7 @@
 #include <QPoint>
 #include <QMap>
 #include <QRect>
+#include <QPointer>
 
 /* GUI includes: */
 #include "UIDefs.h"
@@ -85,6 +86,9 @@ protected slots:
     /* Mouse pointer-shape-change handler: */
     virtual void sltMousePointerShapeChanged();
 
+    /** Activate hovered window if any. */
+    void sltMaybeActivateHoveredWindow();
+
 protected:
 
     /* Mouse-handler constructor/destructor: */
@@ -125,6 +129,9 @@ protected:
     /* Registered machine-view-viewport(s): */
     QMap<ulong, QWidget*> m_viewports;
 
+    /** Hovered window to be activated. */
+    QPointer<QWidget> m_pHoveredWindow;
+
     /* Other mouse variables: */
     QPoint m_lastMousePos;
     QPoint m_capturedMousePos;
diff --git a/src/VBox/Frontends/VirtualBox/src/runtime/UISession.cpp b/src/VBox/Frontends/VirtualBox/src/runtime/UISession.cpp
index fcfffe0..8fbdd92 100644
--- a/src/VBox/Frontends/VirtualBox/src/runtime/UISession.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/runtime/UISession.cpp
@@ -349,6 +349,16 @@ void UISession::powerUp()
                  : "disabled"));
 #endif
 
+/* Check if HID LEDs sync is enabled and add a log message about it. */
+#if defined(Q_WS_MAC) || defined(Q_WS_WIN)
+    if(uimachine()->machineLogic()->isHidLedsSyncEnabled())
+        LogRel(("HID LEDs sync is enabled.\n"));
+    else
+        LogRel(("HID LEDs sync is disabled.\n"));
+#else
+    LogRel(("HID LEDs sync is not supported on this platform.\n"));
+#endif
+
 #ifdef VBOX_GUI_WITH_PIDFILE
     vboxGlobal().createPidfile();
 #endif
@@ -654,38 +664,6 @@ void UISession::sltInstallGuestAdditionsFrom(const QString &strSource)
     }
 }
 
-void UISession::sltChangeVisualStateToNormal()
-{
-    /* Reset requests: */
-    setRequestedVisualState(UIVisualStateType_Invalid);
-    /* Request change: */
-    m_pMachine->asyncChangeVisualState(UIVisualStateType_Normal);
-}
-
-void UISession::sltChangeVisualStateToFullscreen()
-{
-    /* Reset requests: */
-    setRequestedVisualState(UIVisualStateType_Invalid);
-    /* Request change: */
-    m_pMachine->asyncChangeVisualState(UIVisualStateType_Fullscreen);
-}
-
-void UISession::sltChangeVisualStateToSeamless()
-{
-    /* Reset requests: */
-    setRequestedVisualState(UIVisualStateType_Invalid);
-    /* Request change: */
-    m_pMachine->asyncChangeVisualState(UIVisualStateType_Seamless);
-}
-
-void UISession::sltChangeVisualStateToScale()
-{
-    /* Reset requests: */
-    setRequestedVisualState(UIVisualStateType_Invalid);
-    /* Request change: */
-    m_pMachine->asyncChangeVisualState(UIVisualStateType_Scale);
-}
-
 void UISession::sltCloseRuntimeUI()
 {
     /* First, we have to hide any opened modal/popup widgets.
@@ -842,11 +820,9 @@ void UISession::sltGuestMonitorChange(KGuestMonitorChangedEventType changeType,
     /* Ignore KGuestMonitorChangedEventType_NewOrigin change event: */
     if (changeType == KGuestMonitorChangedEventType_NewOrigin)
         return;
-    /* Ignore KGuestMonitorChangedEventType_Disabled event if there is only one window visible: */
+    /* Ignore KGuestMonitorChangedEventType_Disabled event for primary screen: */
     AssertMsg(countOfVisibleWindows() > 0, ("All machine windows are hidden!"));
-    if (   changeType == KGuestMonitorChangedEventType_Disabled
-        && countOfVisibleWindows() == 1
-        && isScreenVisible(uScreenId))
+    if (changeType == KGuestMonitorChangedEventType_Disabled && uScreenId == 0)
         return;
 
     /* Process KGuestMonitorChangedEventType_Enabled change event: */
diff --git a/src/VBox/Frontends/VirtualBox/src/runtime/UISession.h b/src/VBox/Frontends/VirtualBox/src/runtime/UISession.h
index 6543c13..27c8998 100644
--- a/src/VBox/Frontends/VirtualBox/src/runtime/UISession.h
+++ b/src/VBox/Frontends/VirtualBox/src/runtime/UISession.h
@@ -255,15 +255,6 @@ public slots:
 
 private slots:
 
-    /** Requests visual-state change to 'normal' (window). */
-    void sltChangeVisualStateToNormal();
-    /** Requests visual-state change to 'fullscreen'. */
-    void sltChangeVisualStateToFullscreen();
-    /** Requests visual-state change to 'seamless'. */
-    void sltChangeVisualStateToSeamless();
-    /** Requests visual-state change to 'scale'. */
-    void sltChangeVisualStateToScale();
-
     /* Handler: Close Runtime UI stuff: */
     void sltCloseRuntimeUI();
 
diff --git a/src/VBox/Frontends/VirtualBox/src/runtime/fullscreen/UIMachineLogicFullscreen.cpp b/src/VBox/Frontends/VirtualBox/src/runtime/fullscreen/UIMachineLogicFullscreen.cpp
index 3fffc3c..bb37d74 100644
--- a/src/VBox/Frontends/VirtualBox/src/runtime/fullscreen/UIMachineLogicFullscreen.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/runtime/fullscreen/UIMachineLogicFullscreen.cpp
@@ -29,11 +29,15 @@
 #ifdef Q_WS_MAC
 # include "UIExtraDataEventHandler.h"
 # include "VBoxUtils.h"
+# include "UIFrameBuffer.h"
 # include <Carbon/Carbon.h>
 #endif /* Q_WS_MAC */
 
 UIMachineLogicFullscreen::UIMachineLogicFullscreen(QObject *pParent, UISession *pSession)
     : UIMachineLogic(pParent, pSession, UIVisualStateType_Fullscreen)
+#ifdef Q_WS_MAC
+    , m_fadeToken(kCGDisplayFadeReservationInvalidToken)
+#endif /* Q_WS_MAC */
 {
     /* Create multiscreen layout: */
     m_pScreenLayout = new UIMultiScreenLayout(this);
@@ -81,9 +85,9 @@ void UIMachineLogicFullscreen::maybeAdjustGuestScreenSize()
 {
     /* We should rebuild screen-layout: */
     m_pScreenLayout->rebuild();
-    /* And update machine-windows sizes finally: */
+    /* Make sure all machine-window(s) have proper geometry: */
     foreach (UIMachineWindow *pMachineWindow, machineWindows())
-        pMachineWindow->handleScreenGeometryChange();
+        pMachineWindow->showInNecessaryMode();
 }
 
 int UIMachineLogicFullscreen::hostScreenForGuestScreen(int iScreenId) const
@@ -96,6 +100,160 @@ bool UIMachineLogicFullscreen::hasHostScreenForGuestScreen(int iScreenId) const
     return m_pScreenLayout->hasHostScreenForGuestScreen(iScreenId);
 }
 
+#ifdef RT_OS_DARWIN
+void UIMachineLogicFullscreen::sltHandleNativeFullscreenWillEnter()
+{
+    /* Make sure this method is only used for ML and next: */
+    AssertReturnVoid(vboxGlobal().osRelease() > MacOSXRelease_Lion);
+
+    /* Get sender machine-window: */
+    UIMachineWindow *pMachineWindow = qobject_cast<UIMachineWindow*>(sender());
+    AssertReturnVoid(pMachineWindow);
+
+    /* Fade to black: */
+    fadeToBlack();
+}
+
+void UIMachineLogicFullscreen::sltHandleNativeFullscreenDidEnter()
+{
+    /* Make sure this method is only used for ML and next: */
+    AssertReturnVoid(vboxGlobal().osRelease() > MacOSXRelease_Lion);
+
+    /* Get sender machine-window: */
+    UIMachineWindow *pMachineWindow = qobject_cast<UIMachineWindow*>(sender());
+    AssertReturnVoid(pMachineWindow);
+
+    /* Add machine-window to corresponding set: */
+    m_fullscreenMachineWindows.insert(pMachineWindow);
+    AssertReturnVoid(m_fullscreenMachineWindows.contains(pMachineWindow));
+
+    /* Fade to normal if necessary: */
+    QSet<UIMachineWindow*> visibleMachineWindows;
+    foreach (UIMachineWindow *pMachineWindow, machineWindows())
+        if (uisession()->isScreenVisible(pMachineWindow->screenId()))
+            visibleMachineWindows << pMachineWindow;
+    if (   !darwinScreensHaveSeparateSpaces()
+        || m_fullscreenMachineWindows == visibleMachineWindows)
+        fadeToNormal();
+}
+
+void UIMachineLogicFullscreen::sltHandleNativeFullscreenWillExit()
+{
+    /* Make sure this method is only used for ML and next: */
+    AssertReturnVoid(vboxGlobal().osRelease() > MacOSXRelease_Lion);
+
+    /* Get sender machine-window: */
+    UIMachineWindow *pMachineWindow = qobject_cast<UIMachineWindow*>(sender());
+    AssertReturnVoid(pMachineWindow);
+
+    /* Fade to black: */
+    fadeToBlack();
+}
+
+void UIMachineLogicFullscreen::sltHandleNativeFullscreenDidExit()
+{
+    /* Make sure this method is only used for ML and next: */
+    AssertReturnVoid(vboxGlobal().osRelease() > MacOSXRelease_Lion);
+
+    /* Get sender machine-window: */
+    UIMachineWindow *pMachineWindow = qobject_cast<UIMachineWindow*>(sender());
+    AssertReturnVoid(pMachineWindow);
+
+    /* Remove machine-window from corresponding set: */
+    bool fResult = m_fullscreenMachineWindows.remove(pMachineWindow);
+    AssertReturnVoid(fResult && !m_fullscreenMachineWindows.contains(pMachineWindow));
+    Q_UNUSED(fResult);
+
+    /* If that window was invalidated: */
+    if (m_invalidFullscreenMachineWindows.contains(pMachineWindow))
+    {
+        LogRel(("UIMachineLogicFullscreen::sltHandleNativeFullscreenDidExit: "
+                "Machine-window #%d exited invalidated fullscreen, revalidate it.\n",
+                (int)pMachineWindow->screenId()));
+
+        /* Exclude window from invalidation list: */
+        m_invalidFullscreenMachineWindows.remove(pMachineWindow);
+
+        /* Revalidate 'fullscreen' window: */
+        revalidateFullscreenWindow(pMachineWindow);
+    }
+    /* If there are no invalidated windows: */
+    else if (m_invalidFullscreenMachineWindows.isEmpty())
+    {
+        /* If there are 'fullscreen' windows: */
+        if (!m_fullscreenMachineWindows.isEmpty())
+        {
+            LogRel(("UIMachineLogicFullscreen::sltHandleNativeFullscreenDidExit: "
+                    "Machine-window exited fullscreen, asking others to exit too...\n"));
+
+            /* Ask window(s) to exit 'fullscreen' mode: */
+            emit sigNotifyAboutNativeFullscreenShouldBeExited();
+        }
+        /* If there are no 'fullscreen' windows: */
+        else
+        {
+            LogRel(("UIMachineLogicFullscreen::sltHandleNativeFullscreenDidExit: "
+                    "Machine-window(s) exited fullscreen, changing visual-state to requested...\n"));
+
+            /* Change visual-state to requested: */
+            UIVisualStateType type = uisession()->requestedVisualState();
+            if (type == UIVisualStateType_Invalid)
+                type = UIVisualStateType_Normal;
+            uisession()->setRequestedVisualState(UIVisualStateType_Invalid);
+            uisession()->changeVisualState(type);
+
+            /* Fade to normal: */
+            fadeToNormal();
+        }
+    }
+}
+
+void UIMachineLogicFullscreen::sltChangeVisualStateToNormal()
+{
+    /* Base-class handling for Lion and previous: */
+    if (vboxGlobal().osRelease() <= MacOSXRelease_Lion)
+        UIMachineLogic::sltChangeVisualStateToNormal();
+    /* Special handling for ML and next: */
+    else
+    {
+        /* Request 'normal' (window) visual-state: */
+        uisession()->setRequestedVisualState(UIVisualStateType_Normal);
+        /* Ask window(s) to exit 'fullscreen' mode: */
+        emit sigNotifyAboutNativeFullscreenShouldBeExited();
+    }
+}
+
+void UIMachineLogicFullscreen::sltChangeVisualStateToSeamless()
+{
+    /* Base-class handling for Lion and previous: */
+    if (vboxGlobal().osRelease() <= MacOSXRelease_Lion)
+        UIMachineLogic::sltChangeVisualStateToSeamless();
+    /* Special handling for ML and next: */
+    else
+    {
+        /* Request 'seamless' visual-state: */
+        uisession()->setRequestedVisualState(UIVisualStateType_Seamless);
+        /* Ask window(s) to exit 'fullscreen' mode: */
+        emit sigNotifyAboutNativeFullscreenShouldBeExited();
+    }
+}
+
+void UIMachineLogicFullscreen::sltChangeVisualStateToScale()
+{
+    /* Base-class handling for Lion and previous: */
+    if (vboxGlobal().osRelease() <= MacOSXRelease_Lion)
+        UIMachineLogic::sltChangeVisualStateToScale();
+    /* Special handling for ML and next: */
+    else
+    {
+        /* Request 'scale' visual-state: */
+        uisession()->setRequestedVisualState(UIVisualStateType_Scale);
+        /* Ask window(s) to exit 'fullscreen' mode: */
+        emit sigNotifyAboutNativeFullscreenShouldBeExited();
+    }
+}
+#endif /* RT_OS_DARWIN */
+
 void UIMachineLogicFullscreen::sltMachineStateChanged()
 {
     /* Call to base-class: */
@@ -112,9 +270,9 @@ void UIMachineLogicFullscreen::sltMachineStateChanged()
         uisession()->forgetPreviousMachineState();
         /* We should rebuild screen-layout: */
         m_pScreenLayout->rebuild();
-        /* We should update machine-windows sizes: */
+        /* Make sure all machine-window(s) have proper geometry: */
         foreach (UIMachineWindow *pMachineWindow, machineWindows())
-            pMachineWindow->handleScreenGeometryChange();
+            pMachineWindow->showInNecessaryMode();
     }
 }
 
@@ -123,35 +281,69 @@ void UIMachineLogicFullscreen::sltChangePresentationMode(bool /* fEnabled */)
 {
     setPresentationModeEnabled(true);
 }
+#endif /* Q_WS_MAC */
 
 void UIMachineLogicFullscreen::sltScreenLayoutChanged()
 {
-    setPresentationModeEnabled(true);
+    LogRel(("UIMachineLogicFullscreen: Multi-screen layout changed.\n"));
+
+#ifdef Q_WS_MAC
+    /* For Lion and previous: */
+    if (vboxGlobal().osRelease() <= MacOSXRelease_Lion)
+    {
+        /* Make sure all machine-window(s) have proper geometry: */
+        foreach (UIMachineWindow *pMachineWindow, machineWindows())
+            pMachineWindow->showInNecessaryMode();
+        /* Update 'presentation mode': */
+        setPresentationModeEnabled(true);
+    }
+    /* Revalidate 'fullscreen' windows for ML and next: */
+    else revalidateFullscreenWindows();
+#else /* !Q_WS_MAC */
+    /* Make sure all machine-window(s) have proper geometry: */
+    foreach (UIMachineWindow *pMachineWindow, machineWindows())
+        pMachineWindow->showInNecessaryMode();
+#endif /* !Q_WS_MAC */
 }
-#endif /* Q_WS_MAC */
 
 void UIMachineLogicFullscreen::sltGuestMonitorChange(KGuestMonitorChangedEventType changeType, ulong uScreenId, QRect screenGeo)
 {
-    LogRelFlow(("UIMachineLogicFullscreen: Guest-screen count changed.\n"));
+    LogRel(("UIMachineLogicFullscreen: Guest-screen count changed.\n"));
 
     /* Update multi-screen layout before any window update: */
     if (changeType == KGuestMonitorChangedEventType_Enabled ||
         changeType == KGuestMonitorChangedEventType_Disabled)
         m_pScreenLayout->rebuild();
 
+#ifdef Q_WS_MAC
+    /* Call to base-class for Lion and previous: */
+    if (vboxGlobal().osRelease() <= MacOSXRelease_Lion)
+        UIMachineLogic::sltGuestMonitorChange(changeType, uScreenId, screenGeo);
+    /* Revalidate 'fullscreen' windows for ML and next: */
+    else revalidateFullscreenWindows();
+#else /* !Q_WS_MAC */
     /* Call to base-class: */
     UIMachineLogic::sltGuestMonitorChange(changeType, uScreenId, screenGeo);
+#endif /* !Q_WS_MAC */
 }
 
 void UIMachineLogicFullscreen::sltHostScreenCountChanged()
 {
-    LogRelFlow(("UIMachineLogicFullscreen: Host-screen count changed.\n"));
+    LogRel(("UIMachineLogicFullscreen: Host-screen count changed.\n"));
 
     /* Update multi-screen layout before any window update: */
     m_pScreenLayout->rebuild();
 
+#ifdef Q_WS_MAC
+    /* Call to base-class for Lion and previous: */
+    if (vboxGlobal().osRelease() <= MacOSXRelease_Lion)
+        UIMachineLogic::sltHostScreenCountChanged();
+    /* Revalidate 'fullscreen' windows for ML and next: */
+    else revalidateFullscreenWindows();
+#else /* !Q_WS_MAC */
     /* Call to base-class: */
     UIMachineLogic::sltHostScreenCountChanged();
+#endif /* !Q_WS_MAC */
 }
 
 void UIMachineLogicFullscreen::prepareActionGroups()
@@ -180,19 +372,21 @@ void UIMachineLogicFullscreen::prepareActionConnections()
 
     /* "View" actions connections: */
     connect(gActionPool->action(UIActionIndexRuntime_Toggle_Fullscreen), SIGNAL(triggered(bool)),
-            uisession(), SLOT(sltChangeVisualStateToNormal()));
+            this, SLOT(sltChangeVisualStateToNormal()));
     connect(gActionPool->action(UIActionIndexRuntime_Toggle_Seamless), SIGNAL(triggered(bool)),
-            uisession(), SLOT(sltChangeVisualStateToSeamless()));
+            this, SLOT(sltChangeVisualStateToSeamless()));
     connect(gActionPool->action(UIActionIndexRuntime_Toggle_Scale), SIGNAL(triggered(bool)),
-            uisession(), SLOT(sltChangeVisualStateToScale()));
+            this, SLOT(sltChangeVisualStateToScale()));
 }
 
 #ifdef Q_WS_MAC
 void UIMachineLogicFullscreen::prepareOtherConnections()
 {
-    /* Presentation mode connection: */
-    connect(gEDataEvents, SIGNAL(sigPresentationModeChange(bool)),
-            this, SLOT(sltChangePresentationMode(bool)));
+    /* Make sure 'presentation mode' preference handling
+     * is updated at runtime for Lion and previous: */
+    if (vboxGlobal().osRelease() <= MacOSXRelease_Lion)
+        connect(gEDataEvents, SIGNAL(sigPresentationModeChange(bool)),
+                this, SLOT(sltChangePresentationMode(bool)));
 }
 #endif /* Q_WS_MAC */
 
@@ -202,10 +396,13 @@ void UIMachineLogicFullscreen::prepareMachineWindows()
     if (isMachineWindowsCreated())
         return;
 
-#ifdef Q_WS_MAC // TODO: Is that "darwinSetFrontMostProcess" really need here?
+#ifdef Q_WS_MAC
     /* We have to make sure that we are getting the front most process.
      * This is necessary for Qt versions > 4.3.3: */
-    ::darwinSetFrontMostProcess();
+    darwinSetFrontMostProcess();
+
+    /* Fade to black: */
+    fadeToBlack();
 #endif /* Q_WS_MAC */
 
     /* Update the multi-screen layout: */
@@ -216,17 +413,41 @@ void UIMachineLogicFullscreen::prepareMachineWindows()
         addMachineWindow(UIMachineWindow::create(this, cScreenId));
 
     /* Connect multi-screen layout change handler: */
-    for (int i = 0; i < machineWindows().size(); ++i)
-        connect(m_pScreenLayout, SIGNAL(sigScreenLayoutChanged()),
-                static_cast<UIMachineWindowFullscreen*>(machineWindows()[i]), SLOT(sltShowInNecessaryMode()));
-
-#ifdef Q_WS_MAC
-    /* If the user change the screen, we have to decide again if the
-     * presentation mode should be changed. */
     connect(m_pScreenLayout, SIGNAL(sigScreenLayoutChanged()),
             this, SLOT(sltScreenLayoutChanged()));
-    /* Note: Presentation mode has to be set *after* the windows are created. */
+
+#ifdef Q_WS_MAC
+    /* Activate 'presentation mode': */
     setPresentationModeEnabled(true);
+
+    /* For Lion and previous fade to normal: */
+    if (vboxGlobal().osRelease() <= MacOSXRelease_Lion)
+        fadeToNormal();
+
+    /* For ML and next: */
+    if (vboxGlobal().osRelease() > MacOSXRelease_Lion)
+    {
+        /* Enable native fullscreen support: */
+        foreach (UIMachineWindow *pMachineWindow, machineWindows())
+        {
+            /* Logic => window signals: */
+            connect(this, SIGNAL(sigNotifyAboutNativeFullscreenShouldBeEntered(UIMachineWindow*)),
+                    pMachineWindow, SLOT(sltEnterNativeFullscreen(UIMachineWindow*)));
+            connect(this, SIGNAL(sigNotifyAboutNativeFullscreenShouldBeExited(UIMachineWindow*)),
+                    pMachineWindow, SLOT(sltExitNativeFullscreen(UIMachineWindow*)));
+            /* Window => logic signals: */
+            connect(pMachineWindow, SIGNAL(sigNotifyAboutNativeFullscreenWillEnter()),
+                    this, SLOT(sltHandleNativeFullscreenWillEnter()));
+            connect(pMachineWindow, SIGNAL(sigNotifyAboutNativeFullscreenDidEnter()),
+                    this, SLOT(sltHandleNativeFullscreenDidEnter()));
+            connect(pMachineWindow, SIGNAL(sigNotifyAboutNativeFullscreenWillExit()),
+                    this, SLOT(sltHandleNativeFullscreenWillExit()));
+            connect(pMachineWindow, SIGNAL(sigNotifyAboutNativeFullscreenDidExit()),
+                    this, SLOT(sltHandleNativeFullscreenDidExit()));
+        }
+        /* Revalidate 'fullscreen' windows: */
+        revalidateFullscreenWindows();
+    }
 #endif /* Q_WS_MAC */
 
     /* Mark machine-window(s) created: */
@@ -249,15 +470,25 @@ void UIMachineLogicFullscreen::cleanupMachineWindows()
     if (!isMachineWindowsCreated())
         return;
 
+#ifdef Q_WS_MAC
+    /* For Lion and previous fade to black: */
+    if (vboxGlobal().osRelease() <= MacOSXRelease_Lion)
+        fadeToBlack();
+#endif/* Q_WS_MAC */
+
     /* Mark machine-window(s) destroyed: */
     setMachineWindowsCreated(false);
 
-    /* Cleanup machine-window(s): */
+    /* Destroy machine-window(s): */
     foreach (UIMachineWindow *pMachineWindow, machineWindows())
         UIMachineWindow::destroy(pMachineWindow);
 
 #ifdef Q_WS_MAC
+    /* Deactivate 'presentation mode': */
     setPresentationModeEnabled(false);
+
+    /* Fade to normal: */
+    fadeToNormal();
 #endif/* Q_WS_MAC */
 }
 
@@ -265,11 +496,11 @@ void UIMachineLogicFullscreen::cleanupActionConnections()
 {
     /* "View" actions disconnections: */
     disconnect(gActionPool->action(UIActionIndexRuntime_Toggle_Fullscreen), SIGNAL(triggered(bool)),
-               uisession(), SLOT(sltChangeVisualStateToNormal()));
+               this, SLOT(sltChangeVisualStateToNormal()));
     disconnect(gActionPool->action(UIActionIndexRuntime_Toggle_Seamless), SIGNAL(triggered(bool)),
-               uisession(), SLOT(sltChangeVisualStateToSeamless()));
+               this, SLOT(sltChangeVisualStateToSeamless()));
     disconnect(gActionPool->action(UIActionIndexRuntime_Toggle_Scale), SIGNAL(triggered(bool)),
-               uisession(), SLOT(sltChangeVisualStateToScale()));
+               this, SLOT(sltChangeVisualStateToScale()));
 
     /* Call to base-class: */
     UIMachineLogic::cleanupActionConnections();
@@ -297,21 +528,162 @@ void UIMachineLogicFullscreen::cleanupActionGroups()
 #ifdef Q_WS_MAC
 void UIMachineLogicFullscreen::setPresentationModeEnabled(bool fEnabled)
 {
-    /* First check if we are on a screen which contains the Dock or the
-     * Menubar (which hasn't to be the same), only than the
-     * presentation mode have to be changed. */
-    if (   fEnabled
-        && m_pScreenLayout->isHostTaskbarCovert())
+    /* Should we enable it? */
+    if (fEnabled)
     {
-        QString testStr = vboxGlobal().virtualBox().GetExtraData(GUI_PresentationModeEnabled).toLower();
-        /* Default to false if it is an empty value */
-        if (testStr.isEmpty() || testStr == "false")
-            SetSystemUIMode(kUIModeAllHidden, 0);
+        /* For Lion and previous: */
+        if (vboxGlobal().osRelease() <= MacOSXRelease_Lion)
+        {
+            /* Check if we have screen which contains the Dock or the Menubar (which hasn't to be the same),
+             * only than the 'presentation mode' have to be changed. */
+            if (m_pScreenLayout->isHostTaskbarCovert())
+            {
+                /* Load 'presentation mode' preference: */
+                QString strPresentationMode = vboxGlobal().virtualBox().GetExtraData(GUI_PresentationModeEnabled).toLower();
+                /* Default to 'false' if it is an empty value: */
+                if (strPresentationMode.isEmpty() || strPresentationMode == "false")
+                    SetSystemUIMode(kUIModeAllHidden, 0);
+                else
+                    SetSystemUIMode(kUIModeAllSuppressed, 0);
+            }
+        }
+        /* For ML and next: */
         else
+        {
+            /* I am not sure we have to check anything here.
+             * Without 'presentation mode' native fullscreen works pretty bad,
+             * so we have to enable it anyway: */
             SetSystemUIMode(kUIModeAllSuppressed, 0);
+        }
+    }
+    /* Should we disable it? */
+    else SetSystemUIMode(kUIModeNormal, 0);
+}
+
+void UIMachineLogicFullscreen::fadeToBlack()
+{
+    /* Make sure fade-token invalid: */
+    if (m_fadeToken != kCGDisplayFadeReservationInvalidToken)
+        return;
+
+    /* Acquire fade-token: */
+    CGAcquireDisplayFadeReservation(kCGMaxDisplayReservationInterval, &m_fadeToken);
+    CGDisplayFade(m_fadeToken, 0.3, kCGDisplayBlendNormal, kCGDisplayBlendSolidColor, 0.0, 0.0, 0.0, true);
+}
+
+void UIMachineLogicFullscreen::fadeToNormal()
+{
+    /* Make sure fade-token valid: */
+    if (m_fadeToken == kCGDisplayFadeReservationInvalidToken)
+        return;
+
+    /* Release fade-token: */
+    CGDisplayFade(m_fadeToken, 0.5, kCGDisplayBlendSolidColor, kCGDisplayBlendNormal, 0.0, 0.0, 0.0, false);
+    CGReleaseDisplayFadeReservation(m_fadeToken);
+    m_fadeToken = kCGDisplayFadeReservationInvalidToken;
+}
+
+void UIMachineLogicFullscreen::revalidateFullscreenWindow(UIMachineWindow *pMachineWindow)
+{
+    LogRel(("UIMachineLogicFullscreen::revalidateFullscreenWindow #%d begin.\n", pMachineWindow->screenId()));
+
+    /* Make sure window is not already invalidated: */
+    if (m_invalidFullscreenMachineWindows.contains(pMachineWindow))
+        return;
+
+    /* Ignore window if it is in 'fullscreen transition': */
+    if (qobject_cast<UIMachineWindowFullscreen*>(pMachineWindow)->isInFullscreenTransition())
+        return;
+
+    /* Get screen ID: */
+    ulong uScreenID = pMachineWindow->screenId();
+
+    /* Validate window which can't be fullscreen: */
+    if (uScreenID != 0 && !darwinScreensHaveSeparateSpaces())
+    {
+        /* Make sure window have proper geometry: */
+        pMachineWindow->showInNecessaryMode();
     }
+    /* Validate window which can be fullscreen: */
     else
-        SetSystemUIMode(kUIModeNormal, 0);
+    {
+        /* Validate window which is not in fullscreen: */
+        if (!darwinIsInFullscreenMode(pMachineWindow))
+        {
+            /* If that window
+             * 1. should really be shown and
+             * 2. is mapped to some host-screen: */
+            if (   uisession()->isScreenVisible(uScreenID)
+                && hasHostScreenForGuestScreen(uScreenID))
+            {
+                LogRel(("UIMachineLogicFullscreen::revalidateFullscreenWindow: "
+                        "Ask machine-window #%d to enter fullscreen.\n", (int)uScreenID));
+
+                /* Fade to black: */
+                fadeToBlack();
+
+                /* Update 'presentation mode': */
+                setPresentationModeEnabled(true);
+
+                /* Make sure window have proper geometry and shown: */
+                pMachineWindow->showInNecessaryMode();
+
+                /* Ask window to enter 'fullscreen' mode: */
+                emit sigNotifyAboutNativeFullscreenShouldBeEntered(pMachineWindow);
+            }
+            /* If that window
+             * is shown while shouldn't: */
+            else if (pMachineWindow->isVisible())
+            {
+                /* Else make sure that window is hidden: */
+                pMachineWindow->showInNecessaryMode();
+
+                /* Fade to normal: */
+                fadeToNormal();
+            }
+        }
+        /* Validate window which is in fullscreen: */
+        else
+        {
+            /* Variables to compare: */
+            const int iWantedHostScreenIndex = hostScreenForGuestScreen((int)uScreenID);
+            const int iCurrentHostScreenIndex = QApplication::desktop()->screenNumber(pMachineWindow);
+            const QSize frameBufferSize((int)uisession()->frameBuffer(uScreenID)->width(), (int)uisession()->frameBuffer(uScreenID)->height());
+            const QSize screenSize = QApplication::desktop()->screenGeometry(iWantedHostScreenIndex).size();
+
+            /* If that window
+             * 1. shouldn't really be shown or
+             * 2. isn't mapped to some host-screen or
+             * 3. should be located on another host-screen than currently or
+             * 4. have another frame-buffer size than actually should. */
+            if (   !uisession()->isScreenVisible(uScreenID)
+                || !hasHostScreenForGuestScreen(uScreenID)
+                || iWantedHostScreenIndex != iCurrentHostScreenIndex
+                || frameBufferSize != screenSize)
+            {
+                LogRel(("UIMachineLogicFullscreen::revalidateFullscreenWindow: "
+                        "Ask machine-window #%d to exit fullscreen.\n", (int)uScreenID));
+
+                /* Fade to black: */
+                fadeToBlack();
+
+                /* Mark window as invalidated: */
+                m_invalidFullscreenMachineWindows << pMachineWindow;
+
+                /* Ask window to exit 'fullscreen' mode: */
+                emit sigNotifyAboutNativeFullscreenShouldBeExited(pMachineWindow);
+            }
+        }
+    }
+
+    LogRel(("UIMachineLogicFullscreen::revalidateFullscreenWindow #%d end.\n", pMachineWindow->screenId()));
+}
+
+void UIMachineLogicFullscreen::revalidateFullscreenWindows()
+{
+    /* Revalidate all fullscreen windows: */
+    foreach (UIMachineWindow *pMachineWindow, machineWindows())
+        revalidateFullscreenWindow(pMachineWindow);
 }
 #endif /* Q_WS_MAC */
 
diff --git a/src/VBox/Frontends/VirtualBox/src/runtime/fullscreen/UIMachineLogicFullscreen.h b/src/VBox/Frontends/VirtualBox/src/runtime/fullscreen/UIMachineLogicFullscreen.h
index a60b86d..931a08f 100644
--- a/src/VBox/Frontends/VirtualBox/src/runtime/fullscreen/UIMachineLogicFullscreen.h
+++ b/src/VBox/Frontends/VirtualBox/src/runtime/fullscreen/UIMachineLogicFullscreen.h
@@ -17,9 +17,14 @@
 #ifndef ___UIMachineLogicFullscreen_h___
 #define ___UIMachineLogicFullscreen_h___
 
-/* Local includes: */
+/* GUI includes: */
 #include "UIMachineLogic.h"
 
+/* Other includes: */
+#ifdef Q_WS_MAC
+# include <ApplicationServices/ApplicationServices.h>
+#endif /* Q_WS_MAC */
+
 /* Forward declarations: */
 class UIMultiScreenLayout;
 
@@ -28,6 +33,14 @@ class UIMachineLogicFullscreen : public UIMachineLogic
 {
     Q_OBJECT;
 
+#ifdef RT_OS_DARWIN
+signals:
+    /** Mac OS X: Notifies listeners about native fullscreen mode should be entered on @a pMachineWindow. */
+    void sigNotifyAboutNativeFullscreenShouldBeEntered(UIMachineWindow *pMachineWindow = 0);
+    /** Mac OS X: Notifies listeners about native fullscreen mode should be exited on @a pMachineWindow. */
+    void sigNotifyAboutNativeFullscreenShouldBeExited(UIMachineWindow *pMachineWindow = 0);
+#endif /* RT_OS_DARWIN */
+
 protected:
 
     /* Constructor/destructor: */
@@ -44,13 +57,34 @@ protected:
 
 private slots:
 
+#ifdef RT_OS_DARWIN
+    /** Mac OS X: Handles native notification about 'fullscreen' will be entered. */
+    void sltHandleNativeFullscreenWillEnter();
+    /** Mac OS X: Handles native notification about 'fullscreen' entered. */
+    void sltHandleNativeFullscreenDidEnter();
+    /** Mac OS X: Handles native notification about 'fullscreen' will be exited. */
+    void sltHandleNativeFullscreenWillExit();
+    /** Mac OS X: Handles native notification about 'fullscreen' exited. */
+    void sltHandleNativeFullscreenDidExit();
+
+    /** Mac OS X: Requests visual-state change from 'fullscreen' to 'normal' (window). */
+    void sltChangeVisualStateToNormal();
+    /** Mac OS X: Requests visual-state change from 'fullscreen' to 'seamless'. */
+    void sltChangeVisualStateToSeamless();
+    /** Mac OS X: Requests visual-state change from 'fullscreen' to 'scale'. */
+    void sltChangeVisualStateToScale();
+#endif /* RT_OS_DARWIN */
+
     /* Handler: Console callback stuff: */
     void sltMachineStateChanged();
 
 #ifdef Q_WS_MAC
     void sltChangePresentationMode(bool fEnabled);
-    void sltScreenLayoutChanged();
 #endif /* Q_WS_MAC */
+
+    /** Updates machine-window(s) location/size on screen-layout changes. */
+    void sltScreenLayoutChanged();
+
     void sltGuestMonitorChange(KGuestMonitorChangedEventType changeType, ulong uScreenId, QRect screenGeo);
     void sltHostScreenCountChanged();
 
@@ -76,11 +110,31 @@ private:
 
 #ifdef Q_WS_MAC
     void setPresentationModeEnabled(bool fEnabled);
+
+    /** Mac OS X: Performs fade to black if possible. */
+    void fadeToBlack();
+    /** Mac OS X: Performs fade to normal if possible. */
+    void fadeToNormal();
+
+    /** Mac OS X: Revalidates 'fullscreen' mode for @a pMachineWindow. */
+    void revalidateFullscreenWindow(UIMachineWindow *pMachineWindow);
+    /** Mac OS X: Revalidates 'fullscreen' mode for all windows. */
+    void revalidateFullscreenWindows();
 #endif /* Q_WS_MAC */
 
     /* Variables: */
     UIMultiScreenLayout *m_pScreenLayout;
 
+#ifdef Q_WS_MAC
+    /** Mac OS X: Fade token. */
+    CGDisplayFadeReservationToken m_fadeToken;
+
+    /** Mac OS X: Contains machine-window(s) marked as 'fullscreen'. */
+    QSet<UIMachineWindow*> m_fullscreenMachineWindows;
+    /** Mac OS X: Contains machine-window(s) marked as 'invalid fullscreen'. */
+    QSet<UIMachineWindow*> m_invalidFullscreenMachineWindows;
+#endif /* Q_WS_MAC */
+
     /* Friend classes: */
     friend class UIMachineLogic;
     friend class UIMachineWindowFullscreen;
diff --git a/src/VBox/Frontends/VirtualBox/src/runtime/fullscreen/UIMachineWindowFullscreen.cpp b/src/VBox/Frontends/VirtualBox/src/runtime/fullscreen/UIMachineWindowFullscreen.cpp
index 3e0b4f7..5a92e6b 100644
--- a/src/VBox/Frontends/VirtualBox/src/runtime/fullscreen/UIMachineWindowFullscreen.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/runtime/fullscreen/UIMachineWindowFullscreen.cpp
@@ -31,6 +31,10 @@
 #include "UIMachineView.h"
 #include "UIMachineDefs.h"
 #include "UIMiniToolBar.h"
+#ifdef Q_WS_MAC
+# include "VBoxUtils-darwin.h"
+# include "UICocoaApplication.h"
+#endif /* Q_WS_MAC */
 
 /* COM includes: */
 #include "CSnapshot.h"
@@ -39,9 +43,57 @@ UIMachineWindowFullscreen::UIMachineWindowFullscreen(UIMachineLogic *pMachineLog
     : UIMachineWindow(pMachineLogic, uScreenId)
     , m_pMainMenu(0)
     , m_pMiniToolBar(0)
+#ifdef Q_WS_MAC
+    , m_fIsInFullscreenTransition(false)
+#endif /* Q_WS_MAC */
 {
 }
 
+#ifdef Q_WS_MAC
+void UIMachineWindowFullscreen::handleNativeNotification(const QString &strNativeNotificationName)
+{
+    /* Make sure this method is only used for ML and next: */
+    AssertReturnVoid(vboxGlobal().osRelease() > MacOSXRelease_Lion);
+
+    /* Log all arrived notifications: */
+    LogRel(("UIMachineWindowFullscreen::handleNativeNotification: Notification '%s' received.\n",
+            strNativeNotificationName.toAscii().constData()));
+
+    /* Handle 'NSWindowWillEnterFullScreenNotification' notification: */
+    if (strNativeNotificationName == "NSWindowWillEnterFullScreenNotification")
+    {
+        LogRel(("UIMachineWindowFullscreen::handleNativeNotification: "
+                "Native fullscreen mode about to enter, notifying listener...\n"));
+        emit sigNotifyAboutNativeFullscreenWillEnter();
+    }
+    /* Handle 'NSWindowDidEnterFullScreenNotification' notification: */
+    else if (strNativeNotificationName == "NSWindowDidEnterFullScreenNotification")
+    {
+        /* Mark window transition complete: */
+        m_fIsInFullscreenTransition = false;
+        LogRel(("UIMachineWindowFullscreen::handleNativeNotification: "
+                "Native fullscreen mode entered, notifying listener...\n"));
+        emit sigNotifyAboutNativeFullscreenDidEnter();
+    }
+    /* Handle 'NSWindowWillExitFullScreenNotification' notification: */
+    else if (strNativeNotificationName == "NSWindowWillExitFullScreenNotification")
+    {
+        LogRel(("UIMachineWindowFullscreen::handleNativeNotification: "
+                "Native fullscreen mode about to exit, notifying listener...\n"));
+        emit sigNotifyAboutNativeFullscreenWillExit();
+    }
+    /* Handle 'NSWindowDidExitFullScreenNotification' notification: */
+    else if (strNativeNotificationName == "NSWindowDidExitFullScreenNotification")
+    {
+        /* Mark window transition complete: */
+        m_fIsInFullscreenTransition = false;
+        LogRel(("UIMachineWindowFullscreen::handleNativeNotification: "
+                "Native fullscreen mode exited, notifying listener...\n"));
+        emit sigNotifyAboutNativeFullscreenDidExit();
+    }
+}
+#endif /* Q_WS_MAC */
+
 void UIMachineWindowFullscreen::sltMachineStateChanged()
 {
     /* Call to base-class: */
@@ -61,6 +113,63 @@ void UIMachineWindowFullscreen::sltPopupMainMenu()
     }
 }
 
+#ifdef Q_WS_MAC
+void UIMachineWindowFullscreen::sltEnterNativeFullscreen(UIMachineWindow *pMachineWindow)
+{
+    /* Make sure this slot is called only under ML and next: */
+    AssertReturnVoid(vboxGlobal().osRelease() > MacOSXRelease_Lion);
+
+    /* Make sure it is NULL or 'this' window passed: */
+    if (pMachineWindow && pMachineWindow != this)
+        return;
+
+    /* Make sure this window should be shown at all: */
+    if (!uisession()->isScreenVisible(m_uScreenId))
+        return;
+
+    /* Make sure this window has fullscreen logic: */
+    UIMachineLogicFullscreen *pFullscreenLogic = qobject_cast<UIMachineLogicFullscreen*>(machineLogic());
+    if (!pFullscreenLogic)
+        return;
+
+    /* Make sure this window mapped to some host-screen: */
+    if (!pFullscreenLogic->hasHostScreenForGuestScreen(m_uScreenId))
+        return;
+
+    /* Mark window 'transitioned to fullscreen': */
+    m_fIsInFullscreenTransition = true;
+
+    /* Enter native fullscreen mode if necessary: */
+    if (   (darwinScreensHaveSeparateSpaces() || m_uScreenId == 0)
+        && !darwinIsInFullscreenMode(this))
+        darwinToggleFullscreenMode(this);
+}
+
+void UIMachineWindowFullscreen::sltExitNativeFullscreen(UIMachineWindow *pMachineWindow)
+{
+    /* Make sure this slot is called only under ML and next: */
+    AssertReturnVoid(vboxGlobal().osRelease() > MacOSXRelease_Lion);
+
+    /* Make sure it is NULL or 'this' window passed: */
+    if (pMachineWindow && pMachineWindow != this)
+        return;
+
+    /* Mark window 'transitioned from fullscreen': */
+    m_fIsInFullscreenTransition = true;
+
+    /* Exit native fullscreen mode if necessary: */
+    if (   (darwinScreensHaveSeparateSpaces() || m_uScreenId == 0)
+        && darwinIsInFullscreenMode(this))
+        darwinToggleFullscreenMode(this);
+}
+#endif /* Q_WS_MAC */
+
+void UIMachineWindowFullscreen::sltRevokeFocus()
+{
+    /* Revoke stolen focus: */
+    m_pMachineView->setFocus();
+}
+
 void UIMachineWindowFullscreen::prepareMenu()
 {
     /* Call to base-class: */
@@ -87,6 +196,28 @@ void UIMachineWindowFullscreen::prepareVisualState()
 
     /* Prepare mini-toolbar: */
     prepareMiniToolbar();
+
+#ifdef Q_WS_MAC
+    /* Native fullscreen stuff on ML and next: */
+    if (vboxGlobal().osRelease() > MacOSXRelease_Lion)
+    {
+        /* Enable fullscreen support for every screen which requires it: */
+        if (darwinScreensHaveSeparateSpaces() || m_uScreenId == 0)
+            darwinEnableFullscreenSupport(this);
+        /* Enable transience support for other screens: */
+        else
+            darwinEnableTransienceSupport(this);
+        /* Register to native fullscreen notifications: */
+        UICocoaApplication::instance()->registerToNativeNotification("NSWindowWillEnterFullScreenNotification", this,
+                                                                     UIMachineWindow::handleNativeNotification);
+        UICocoaApplication::instance()->registerToNativeNotification("NSWindowDidEnterFullScreenNotification", this,
+                                                                     UIMachineWindow::handleNativeNotification);
+        UICocoaApplication::instance()->registerToNativeNotification("NSWindowWillExitFullScreenNotification", this,
+                                                                     UIMachineWindow::handleNativeNotification);
+        UICocoaApplication::instance()->registerToNativeNotification("NSWindowDidExitFullScreenNotification", this,
+                                                                     UIMachineWindow::handleNativeNotification);
+    }
+#endif /* Q_WS_MAC */
 }
 
 void UIMachineWindowFullscreen::prepareMiniToolbar()
@@ -115,11 +246,14 @@ void UIMachineWindowFullscreen::prepareMiniToolbar()
     for (int i=0; i < actions.size(); ++i)
         menus << actions.at(i)->menu();
     m_pMiniToolBar->addMenus(menus);
+#ifndef RT_OS_DARWIN
     connect(m_pMiniToolBar, SIGNAL(sigMinimizeAction()), this, SLOT(showMinimized()));
+#endif /* !RT_OS_DARWIN */
     connect(m_pMiniToolBar, SIGNAL(sigExitAction()),
             gActionPool->action(UIActionIndexRuntime_Toggle_Fullscreen), SLOT(trigger()));
     connect(m_pMiniToolBar, SIGNAL(sigCloseAction()),
             gActionPool->action(UIActionIndexRuntime_Simple_Close), SLOT(trigger()));
+    connect(m_pMiniToolBar, SIGNAL(sigNotifyAboutFocusStolen()), this, SLOT(sltRevokeFocus()));
 }
 
 void UIMachineWindowFullscreen::cleanupMiniToolbar()
@@ -137,6 +271,18 @@ void UIMachineWindowFullscreen::cleanupMiniToolbar()
 
 void UIMachineWindowFullscreen::cleanupVisualState()
 {
+#ifdef Q_WS_MAC
+    /* Native fullscreen stuff on ML and next: */
+    if (vboxGlobal().osRelease() > MacOSXRelease_Lion)
+    {
+        /* Unregister from native fullscreen notifications: */
+        UICocoaApplication::instance()->unregisterFromNativeNotification("NSWindowWillEnterFullScreenNotification", this);
+        UICocoaApplication::instance()->unregisterFromNativeNotification("NSWindowDidEnterFullScreenNotification", this);
+        UICocoaApplication::instance()->unregisterFromNativeNotification("NSWindowWillExitFullScreenNotification", this);
+        UICocoaApplication::instance()->unregisterFromNativeNotification("NSWindowDidExitFullScreenNotification", this);
+    }
+#endif /* Q_WS_MAC */
+
     /* Cleanup mini-toolbar: */
     cleanupMiniToolbar();
 
@@ -162,8 +308,18 @@ void UIMachineWindowFullscreen::placeOnScreen()
     QRect workingArea = QApplication::desktop()->screenGeometry(iScreen);
     /* Move to the appropriate position: */
     move(workingArea.topLeft());
+#ifdef Q_WS_MAC
+    /* Resize to the appropriate size on Lion and previous: */
+    if (vboxGlobal().osRelease() <= MacOSXRelease_Lion)
+        resize(workingArea.size());
+    /* Resize to the appropriate size on ML and next
+     * only if that screen has no own user-space: */
+    else if (!darwinScreensHaveSeparateSpaces() && m_uScreenId != 0)
+        resize(workingArea.size());
+#else /* !Q_WS_MAC */
     /* Resize to the appropriate size: */
     resize(workingArea.size());
+#endif /* !Q_WS_MAC */
     /* Adjust guest screen size if necessary: */
     machineView()->maybeAdjustGuestScreenSize();
     /* Move mini-toolbar into appropriate place: */
@@ -175,42 +331,42 @@ void UIMachineWindowFullscreen::placeOnScreen()
 
 void UIMachineWindowFullscreen::showInNecessaryMode()
 {
-    /* Should we show window?: */
-    if (uisession()->isScreenVisible(m_uScreenId))
-    {
-        /* Do we have the seamless logic? */
-        if (UIMachineLogicFullscreen *pFullscreenLogic = qobject_cast<UIMachineLogicFullscreen*>(machineLogic()))
-        {
-            /* Is this guest screen has own host screen? */
-            if (pFullscreenLogic->hasHostScreenForGuestScreen(m_uScreenId))
-            {
-                /* Make sure the window is maximized and placed on valid screen: */
-                placeOnScreen();
-
-#ifdef Q_WS_WIN
-                /* On Windows we should activate main window first,
-                 * because entering fullscreen there doesn't means window will be auto-activated,
-                 * so no window-activation event will be received
-                 * and no keyboard-hook created otherwise... */
-                if (m_uScreenId == 0)
-                    setWindowState(windowState() | Qt::WindowActive);
-#endif /* Q_WS_WIN */
-
-                /* Show in fullscreen mode: */
-                showFullScreen();
-
-                /* Make sure the window is placed on valid screen again
-                 * after window is shown & window's decorations applied.
-                 * That is required (still?) due to X11 Window Geometry Rules. */
-                placeOnScreen();
-
-                /* Return early: */
-                return;
-            }
-        }
-    }
-    /* Hide in other cases: */
-    hide();
+    /* Make sure this window should be shown at all: */
+    if (!uisession()->isScreenVisible(m_uScreenId))
+        return hide();
+
+    /* Make sure this window has fullscreen logic: */
+    UIMachineLogicFullscreen *pFullscreenLogic = qobject_cast<UIMachineLogicFullscreen*>(machineLogic());
+    if (!pFullscreenLogic)
+        return hide();
+
+    /* Make sure this window mapped to some host-screen: */
+    if (!pFullscreenLogic->hasHostScreenForGuestScreen(m_uScreenId))
+        return hide();
+
+    /* Make sure this window is not minimized: */
+    if (isMinimized())
+        return;
+
+    /* Make sure this window is maximized and placed on valid screen: */
+    placeOnScreen();
+
+#ifdef Q_WS_MAC
+    /* ML and next using native stuff, so we can call for simple show(): */
+    if (vboxGlobal().osRelease() > MacOSXRelease_Lion) show();
+    /* Lion and previous using Qt stuff, so we should call for showFullScreen(): */
+    else showFullScreen();
+#else /* !Q_WS_MAC */
+    /* Show in fullscreen mode: */
+    showFullScreen();
+#endif /* !Q_WS_MAC */
+
+#ifdef Q_WS_X11
+    /* Make sure the window is placed on valid screen again
+     * after window is shown & window's decorations applied.
+     * That is required (still?) due to X11 Window Geometry Rules. */
+    placeOnScreen();
+#endif /* Q_WS_X11 */
 }
 
 void UIMachineWindowFullscreen::updateAppearanceOf(int iElement)
diff --git a/src/VBox/Frontends/VirtualBox/src/runtime/fullscreen/UIMachineWindowFullscreen.h b/src/VBox/Frontends/VirtualBox/src/runtime/fullscreen/UIMachineWindowFullscreen.h
index c1caf08..8b73359 100644
--- a/src/VBox/Frontends/VirtualBox/src/runtime/fullscreen/UIMachineWindowFullscreen.h
+++ b/src/VBox/Frontends/VirtualBox/src/runtime/fullscreen/UIMachineWindowFullscreen.h
@@ -30,22 +30,48 @@ class UIMachineWindowFullscreen : public UIMachineWindow
 {
     Q_OBJECT;
 
+#ifdef RT_OS_DARWIN
+signals:
+    /** Mac OS X: Notifies listener about native 'fullscreen' will be entered. */
+    void sigNotifyAboutNativeFullscreenWillEnter();
+    /** Mac OS X: Notifies listener about native 'fullscreen' entered. */
+    void sigNotifyAboutNativeFullscreenDidEnter();
+    /** Mac OS X: Notifies listener about native 'fullscreen' will be exited. */
+    void sigNotifyAboutNativeFullscreenWillExit();
+    /** Mac OS X: Notifies listener about native 'fullscreen' exited. */
+    void sigNotifyAboutNativeFullscreenDidExit();
+#endif /* RT_OS_DARWIN */
+
 protected:
 
     /* Constructor: */
     UIMachineWindowFullscreen(UIMachineLogic *pMachineLogic, ulong uScreenId);
 
+#ifdef Q_WS_MAC
+    /** Mac OS X: Handles native notifications @a strNativeNotificationName for 'fullscreen' window. */
+    void handleNativeNotification(const QString &strNativeNotificationName);
+    /** Mac OS X: Returns whether window is in 'fullscreen' transition. */
+    bool isInFullscreenTransition() const { return m_fIsInFullscreenTransition; }
+#endif /* Q_WS_MAC */
+
 private slots:
 
     /* Session event-handlers: */
     void sltMachineStateChanged();
 
-    /* Show in necessary mode: */
-    void sltShowInNecessaryMode() { showInNecessaryMode(); }
-
     /* Popup main-menu: */
     void sltPopupMainMenu();
 
+#ifdef RT_OS_DARWIN
+    /** Mac OS X: Commands @a pMachineWindow to enter native 'fullscreen' mode if possible. */
+    void sltEnterNativeFullscreen(UIMachineWindow *pMachineWindow);
+    /** Mac OS X: Commands @a pMachineWindow to exit native 'fullscreen' mode if possible. */
+    void sltExitNativeFullscreen(UIMachineWindow *pMachineWindow);
+#endif /* RT_OS_DARWIN */
+
+    /** Revokes keyboard-focus. */
+    void sltRevokeFocus();
+
 private:
 
     /* Prepare helpers: */
@@ -69,6 +95,13 @@ private:
     QMenu *m_pMainMenu;
     UIRuntimeMiniToolBar *m_pMiniToolBar;
 
+#ifdef Q_WS_MAC
+    /** Mac OS X: Reflects whether window is in 'fullscreen' transition. */
+    bool m_fIsInFullscreenTransition;
+    /** Mac OS X: Allows 'fullscreen' API access: */
+    friend class UIMachineLogicFullscreen;
+#endif /* Q_WS_MAC */
+
     /* Factory support: */
     friend class UIMachineWindow;
 };
diff --git a/src/VBox/Frontends/VirtualBox/src/runtime/normal/UIMachineLogicNormal.cpp b/src/VBox/Frontends/VirtualBox/src/runtime/normal/UIMachineLogicNormal.cpp
index 040c6d8..2a3f79f 100644
--- a/src/VBox/Frontends/VirtualBox/src/runtime/normal/UIMachineLogicNormal.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/runtime/normal/UIMachineLogicNormal.cpp
@@ -98,11 +98,11 @@ void UIMachineLogicNormal::prepareActionConnections()
 
     /* "View" actions connections: */
     connect(gActionPool->action(UIActionIndexRuntime_Toggle_Fullscreen), SIGNAL(triggered(bool)),
-            uisession(), SLOT(sltChangeVisualStateToFullscreen()));
+            this, SLOT(sltChangeVisualStateToFullscreen()));
     connect(gActionPool->action(UIActionIndexRuntime_Toggle_Seamless), SIGNAL(triggered(bool)),
-            uisession(), SLOT(sltChangeVisualStateToSeamless()));
+            this, SLOT(sltChangeVisualStateToSeamless()));
     connect(gActionPool->action(UIActionIndexRuntime_Toggle_Scale), SIGNAL(triggered(bool)),
-            uisession(), SLOT(sltChangeVisualStateToScale()));
+            this, SLOT(sltChangeVisualStateToScale()));
 
     /* "Device" actions connections: */
     connect(gActionPool->action(UIActionIndexRuntime_Menu_SharedFolders)->menu(), SIGNAL(aboutToShow()),
@@ -156,11 +156,11 @@ void UIMachineLogicNormal::cleanupActionConnections()
 {
     /* "View" actions disconnections: */
     disconnect(gActionPool->action(UIActionIndexRuntime_Toggle_Fullscreen), SIGNAL(triggered(bool)),
-               uisession(), SLOT(sltChangeVisualStateToFullscreen()));
+               this, SLOT(sltChangeVisualStateToFullscreen()));
     disconnect(gActionPool->action(UIActionIndexRuntime_Toggle_Seamless), SIGNAL(triggered(bool)),
-               uisession(), SLOT(sltChangeVisualStateToSeamless()));
+               this, SLOT(sltChangeVisualStateToSeamless()));
     disconnect(gActionPool->action(UIActionIndexRuntime_Toggle_Scale), SIGNAL(triggered(bool)),
-               uisession(), SLOT(sltChangeVisualStateToScale()));
+               this, SLOT(sltChangeVisualStateToScale()));
 
     /* Call to base-class: */
     UIMachineLogic::cleanupActionConnections();
diff --git a/src/VBox/Frontends/VirtualBox/src/runtime/normal/UIMachineWindowNormal.cpp b/src/VBox/Frontends/VirtualBox/src/runtime/normal/UIMachineWindowNormal.cpp
index 049e886..2aad2f1 100644
--- a/src/VBox/Frontends/VirtualBox/src/runtime/normal/UIMachineWindowNormal.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/runtime/normal/UIMachineWindowNormal.cpp
@@ -600,12 +600,16 @@ bool UIMachineWindowNormal::event(QEvent *pEvent)
 
 void UIMachineWindowNormal::showInNecessaryMode()
 {
-    /* Show window if we have to: */
-    if (uisession()->isScreenVisible(m_uScreenId))
-        show();
-    /* Else hide window: */
-    else
-        hide();
+    /* Make sure this window should be shown at all: */
+    if (!uisession()->isScreenVisible(m_uScreenId))
+        return hide();
+
+    /* Make sure this window is not minimized: */
+    if (isMinimized())
+        return;
+
+    /* Show in normal mode: */
+    show();
 }
 
 /**
diff --git a/src/VBox/Frontends/VirtualBox/src/runtime/scale/UIMachineLogicScale.cpp b/src/VBox/Frontends/VirtualBox/src/runtime/scale/UIMachineLogicScale.cpp
index b423ea4..832e111 100644
--- a/src/VBox/Frontends/VirtualBox/src/runtime/scale/UIMachineLogicScale.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/runtime/scale/UIMachineLogicScale.cpp
@@ -75,11 +75,11 @@ void UIMachineLogicScale::prepareActionConnections()
 
     /* "View" actions connections: */
     connect(gActionPool->action(UIActionIndexRuntime_Toggle_Scale), SIGNAL(triggered(bool)),
-            uisession(), SLOT(sltChangeVisualStateToNormal()));
+            this, SLOT(sltChangeVisualStateToNormal()));
     connect(gActionPool->action(UIActionIndexRuntime_Toggle_Fullscreen), SIGNAL(triggered(bool)),
-            uisession(), SLOT(sltChangeVisualStateToFullscreen()));
+            this, SLOT(sltChangeVisualStateToFullscreen()));
     connect(gActionPool->action(UIActionIndexRuntime_Toggle_Seamless), SIGNAL(triggered(bool)),
-            uisession(), SLOT(sltChangeVisualStateToSeamless()));
+            this, SLOT(sltChangeVisualStateToSeamless()));
 }
 
 void UIMachineLogicScale::prepareMachineWindows()
@@ -125,11 +125,11 @@ void UIMachineLogicScale::cleanupActionConnections()
 {
     /* "View" actions disconnections: */
     disconnect(gActionPool->action(UIActionIndexRuntime_Toggle_Scale), SIGNAL(triggered(bool)),
-               uisession(), SLOT(sltChangeVisualStateToNormal()));
+               this, SLOT(sltChangeVisualStateToNormal()));
     disconnect(gActionPool->action(UIActionIndexRuntime_Toggle_Fullscreen), SIGNAL(triggered(bool)),
-               uisession(), SLOT(sltChangeVisualStateToFullscreen()));
+               this, SLOT(sltChangeVisualStateToFullscreen()));
     disconnect(gActionPool->action(UIActionIndexRuntime_Toggle_Seamless), SIGNAL(triggered(bool)),
-               uisession(), SLOT(sltChangeVisualStateToSeamless()));
+               this, SLOT(sltChangeVisualStateToSeamless()));
 
     /* Call to base-class: */
     UIMachineLogic::cleanupActionConnections();
diff --git a/src/VBox/Frontends/VirtualBox/src/runtime/scale/UIMachineWindowScale.cpp b/src/VBox/Frontends/VirtualBox/src/runtime/scale/UIMachineWindowScale.cpp
index 3407365..891cd4e 100644
--- a/src/VBox/Frontends/VirtualBox/src/runtime/scale/UIMachineWindowScale.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/runtime/scale/UIMachineWindowScale.cpp
@@ -196,12 +196,16 @@ void UIMachineWindowScale::cleanupMenu()
 
 void UIMachineWindowScale::showInNecessaryMode()
 {
-    /* Show window if we have to: */
-    if (uisession()->isScreenVisible(m_uScreenId))
-        show();
-    /* Else hide window: */
-    else
-        hide();
+    /* Make sure this window should be shown at all: */
+    if (!uisession()->isScreenVisible(m_uScreenId))
+        return hide();
+
+    /* Make sure this window is not minimized: */
+    if (isMinimized())
+        return;
+
+    /* Show in normal mode: */
+    show();
 }
 
 bool UIMachineWindowScale::event(QEvent *pEvent)
diff --git a/src/VBox/Frontends/VirtualBox/src/runtime/seamless/UIMachineLogicSeamless.cpp b/src/VBox/Frontends/VirtualBox/src/runtime/seamless/UIMachineLogicSeamless.cpp
index 9987050..9eb85fb 100644
--- a/src/VBox/Frontends/VirtualBox/src/runtime/seamless/UIMachineLogicSeamless.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/runtime/seamless/UIMachineLogicSeamless.cpp
@@ -81,9 +81,9 @@ void UIMachineLogicSeamless::maybeAdjustGuestScreenSize()
 {
     /* We should rebuild screen-layout: */
     m_pScreenLayout->rebuild();
-    /* We should update machine-windows sizes: */
+    /* Make sure all machine-window(s) have proper geometry: */
     foreach (UIMachineWindow *pMachineWindow, machineWindows())
-        pMachineWindow->handleScreenGeometryChange();
+        pMachineWindow->showInNecessaryMode();
 }
 
 int UIMachineLogicSeamless::hostScreenForGuestScreen(int iScreenId) const
@@ -139,12 +139,19 @@ void UIMachineLogicSeamless::sltMachineStateChanged()
         uisession()->forgetPreviousMachineState();
         /* We should rebuild screen-layout: */
         m_pScreenLayout->rebuild();
-        /* We should update machine-windows sizes: */
+        /* Make sure all machine-window(s) have proper geometry: */
         foreach (UIMachineWindow *pMachineWindow, machineWindows())
-            pMachineWindow->handleScreenGeometryChange();
+            pMachineWindow->showInNecessaryMode();
     }
 }
 
+void UIMachineLogicSeamless::sltScreenLayoutChanged()
+{
+    /* Make sure all machine-window(s) have proper geometry: */
+    foreach (UIMachineWindow *pMachineWindow, machineWindows())
+        pMachineWindow->showInNecessaryMode();
+}
+
 void UIMachineLogicSeamless::sltGuestMonitorChange(KGuestMonitorChangedEventType changeType, ulong uScreenId, QRect screenGeo)
 {
     LogRelFlow(("UIMachineLogicSeamless: Guest-screen count changed.\n"));
@@ -199,11 +206,11 @@ void UIMachineLogicSeamless::prepareActionConnections()
 
     /* "View" actions connections: */
     connect(gActionPool->action(UIActionIndexRuntime_Toggle_Seamless), SIGNAL(triggered(bool)),
-            uisession(), SLOT(sltChangeVisualStateToNormal()));
+            this, SLOT(sltChangeVisualStateToNormal()));
     connect(gActionPool->action(UIActionIndexRuntime_Toggle_Fullscreen), SIGNAL(triggered(bool)),
-            uisession(), SLOT(sltChangeVisualStateToFullscreen()));
+            this, SLOT(sltChangeVisualStateToFullscreen()));
     connect(gActionPool->action(UIActionIndexRuntime_Toggle_Scale), SIGNAL(triggered(bool)),
-            uisession(), SLOT(sltChangeVisualStateToScale()));
+            this, SLOT(sltChangeVisualStateToScale()));
 }
 
 void UIMachineLogicSeamless::prepareMachineWindows()
@@ -212,23 +219,22 @@ void UIMachineLogicSeamless::prepareMachineWindows()
     if (isMachineWindowsCreated())
         return;
 
-#ifdef Q_WS_MAC // TODO: Is that really need here?
+#ifdef Q_WS_MAC
     /* We have to make sure that we are getting the front most process.
      * This is necessary for Qt versions > 4.3.3: */
-    ::darwinSetFrontMostProcess();
+    darwinSetFrontMostProcess();
 #endif /* Q_WS_MAC */
 
     /* Update the multi-screen layout: */
     m_pScreenLayout->update();
 
-    /* Create machine window(s): */
+    /* Create machine-window(s): */
     for (uint cScreenId = 0; cScreenId < session().GetMachine().GetMonitorCount(); ++cScreenId)
         addMachineWindow(UIMachineWindow::create(this, cScreenId));
 
     /* Connect multi-screen layout change handler: */
-    for (int i = 0; i < machineWindows().size(); ++i)
-        connect(m_pScreenLayout, SIGNAL(sigScreenLayoutChanged()),
-                static_cast<UIMachineWindowSeamless*>(machineWindows()[i]), SLOT(sltShowInNecessaryMode()));
+    connect(m_pScreenLayout, SIGNAL(sigScreenLayoutChanged()),
+            this, SLOT(sltScreenLayoutChanged()));
 
     /* Mark machine-window(s) created: */
     setMachineWindowsCreated(true);
@@ -253,7 +259,7 @@ void UIMachineLogicSeamless::cleanupMachineWindows()
     /* Mark machine-window(s) destroyed: */
     setMachineWindowsCreated(false);
 
-    /* Cleanup machine-window(s): */
+    /* Destroy machine-window(s): */
     foreach (UIMachineWindow *pMachineWindow, machineWindows())
         UIMachineWindow::destroy(pMachineWindow);
 }
@@ -262,11 +268,11 @@ void UIMachineLogicSeamless::cleanupActionConnections()
 {
     /* "View" actions disconnections: */
     disconnect(gActionPool->action(UIActionIndexRuntime_Toggle_Seamless), SIGNAL(triggered(bool)),
-               uisession(), SLOT(sltChangeVisualStateToNormal()));
+               this, SLOT(sltChangeVisualStateToNormal()));
     disconnect(gActionPool->action(UIActionIndexRuntime_Toggle_Fullscreen), SIGNAL(triggered(bool)),
-               uisession(), SLOT(sltChangeVisualStateToFullscreen()));
+               this, SLOT(sltChangeVisualStateToFullscreen()));
     disconnect(gActionPool->action(UIActionIndexRuntime_Toggle_Scale), SIGNAL(triggered(bool)),
-               uisession(), SLOT(sltChangeVisualStateToScale()));
+               this, SLOT(sltChangeVisualStateToScale()));
 
     /* Call to base-class: */
     UIMachineLogic::cleanupActionConnections();
diff --git a/src/VBox/Frontends/VirtualBox/src/runtime/seamless/UIMachineLogicSeamless.h b/src/VBox/Frontends/VirtualBox/src/runtime/seamless/UIMachineLogicSeamless.h
index 8bebedd..e2cf300 100644
--- a/src/VBox/Frontends/VirtualBox/src/runtime/seamless/UIMachineLogicSeamless.h
+++ b/src/VBox/Frontends/VirtualBox/src/runtime/seamless/UIMachineLogicSeamless.h
@@ -53,6 +53,9 @@ private slots:
     /* Handler: Console callback stuff: */
     void sltMachineStateChanged();
 
+    /** Updates machine-window(s) location/size on screen-layout changes. */
+    void sltScreenLayoutChanged();
+
     void sltGuestMonitorChange(KGuestMonitorChangedEventType changeType, ulong uScreenId, QRect screenGeo);
     void sltHostScreenCountChanged();
 
diff --git a/src/VBox/Frontends/VirtualBox/src/runtime/seamless/UIMachineWindowSeamless.cpp b/src/VBox/Frontends/VirtualBox/src/runtime/seamless/UIMachineWindowSeamless.cpp
index bc87b27..4b3a8a7 100644
--- a/src/VBox/Frontends/VirtualBox/src/runtime/seamless/UIMachineWindowSeamless.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/runtime/seamless/UIMachineWindowSeamless.cpp
@@ -70,6 +70,12 @@ void UIMachineWindowSeamless::sltPopupMainMenu()
     }
 }
 
+void UIMachineWindowSeamless::sltRevokeFocus()
+{
+    /* Revoke stolen focus: */
+    m_pMachineView->setFocus();
+}
+
 void UIMachineWindowSeamless::prepareMenu()
 {
     /* Call to base-class: */
@@ -151,6 +157,7 @@ void UIMachineWindowSeamless::prepareMiniToolbar()
             gActionPool->action(UIActionIndexRuntime_Toggle_Seamless), SLOT(trigger()));
     connect(m_pMiniToolBar, SIGNAL(sigCloseAction()),
             gActionPool->action(UIActionIndexRuntime_Simple_Close), SLOT(trigger()));
+    connect(m_pMiniToolBar, SIGNAL(sigNotifyAboutFocusStolen()), this, SLOT(sltRevokeFocus()));
 }
 #endif /* !Q_WS_MAC */
 
@@ -213,28 +220,28 @@ void UIMachineWindowSeamless::placeOnScreen()
 
 void UIMachineWindowSeamless::showInNecessaryMode()
 {
-    /* Should we show window?: */
-    if (uisession()->isScreenVisible(m_uScreenId))
-    {
-        /* Do we have the seamless logic? */
-        if (UIMachineLogicSeamless *pSeamlessLogic = qobject_cast<UIMachineLogicSeamless*>(machineLogic()))
-        {
-            /* Is this guest screen has own host screen? */
-            if (pSeamlessLogic->hasHostScreenForGuestScreen(m_uScreenId))
-            {
-                /* Make sure the window is maximized and placed on valid screen: */
-                placeOnScreen();
+    /* Make sure this window should be shown at all: */
+    if (!uisession()->isScreenVisible(m_uScreenId))
+        return hide();
 
-                /* Show in normal mode: */
-                show();
+    /* Make sure this window has seamless logic: */
+    UIMachineLogicSeamless *pSeamlessLogic = qobject_cast<UIMachineLogicSeamless*>(machineLogic());
+    if (!pSeamlessLogic)
+        return hide();
 
-                /* Return early: */
-                return;
-            }
-        }
-    }
-    /* Hide in other cases: */
-    hide();
+    /* Make sure this window mapped to some host-screen: */
+    if (!pSeamlessLogic->hasHostScreenForGuestScreen(m_uScreenId))
+        return hide();
+
+    /* Make sure this window is not minimized: */
+    if (isMinimized())
+        return;
+
+    /* Make sure this window is maximized and placed on valid screen: */
+    placeOnScreen();
+
+    /* Show in normal mode: */
+    show();
 }
 
 #ifndef Q_WS_MAC
diff --git a/src/VBox/Frontends/VirtualBox/src/runtime/seamless/UIMachineWindowSeamless.h b/src/VBox/Frontends/VirtualBox/src/runtime/seamless/UIMachineWindowSeamless.h
index 007ee30..a7bfea8 100644
--- a/src/VBox/Frontends/VirtualBox/src/runtime/seamless/UIMachineWindowSeamless.h
+++ b/src/VBox/Frontends/VirtualBox/src/runtime/seamless/UIMachineWindowSeamless.h
@@ -42,12 +42,12 @@ private slots:
     void sltMachineStateChanged();
 #endif /* !Q_WS_MAC */
 
-    /* Show in necessary mode: */
-    void sltShowInNecessaryMode() { showInNecessaryMode(); }
-
     /* Popup main menu: */
     void sltPopupMainMenu();
 
+    /** Revokes keyboard-focus. */
+    void sltRevokeFocus();
+
 private:
 
     /* Prepare helpers: */
diff --git a/src/VBox/Frontends/VirtualBox/src/settings/global/UIGlobalSettingsInput.cpp b/src/VBox/Frontends/VirtualBox/src/settings/global/UIGlobalSettingsInput.cpp
index 59c4ac0..b2dd494 100644
--- a/src/VBox/Frontends/VirtualBox/src/settings/global/UIGlobalSettingsInput.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/settings/global/UIGlobalSettingsInput.cpp
@@ -496,10 +496,13 @@ void UIHotKeyTableModel::sort(int iColumn, Qt::SortOrder order /* = Qt::Ascendin
 
 void UIHotKeyTableModel::applyFilter()
 {
-    /* Erase items first: */
-    beginRemoveRows(QModelIndex(), 0, m_filteredShortcuts.size() - 1);
-    m_filteredShortcuts.clear();
-    endRemoveRows();
+    /* Erase items first if necessary: */
+    if (!m_filteredShortcuts.isEmpty())
+    {
+        beginRemoveRows(QModelIndex(), 0, m_filteredShortcuts.size() - 1);
+        m_filteredShortcuts.clear();
+        endRemoveRows();
+    }
 
     /* If filter is empty: */
     if (m_strFilter.isEmpty())
@@ -520,8 +523,13 @@ void UIHotKeyTableModel::applyFilter()
             m_filteredShortcuts << item;
         }
     }
-    beginInsertRows(QModelIndex(), 0, m_filteredShortcuts.size() - 1);
-    endInsertRows();
+
+    /* Add items finally if necessary: */
+    if (!m_filteredShortcuts.isEmpty())
+    {
+        beginInsertRows(QModelIndex(), 0, m_filteredShortcuts.size() - 1);
+        endInsertRows();
+    }
 }
 
 
diff --git a/src/VBox/Frontends/VirtualBox/src/widgets/UIMiniToolBar.cpp b/src/VBox/Frontends/VirtualBox/src/widgets/UIMiniToolBar.cpp
index 987d527..98c5ea5 100644
--- a/src/VBox/Frontends/VirtualBox/src/widgets/UIMiniToolBar.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/widgets/UIMiniToolBar.cpp
@@ -192,11 +192,6 @@ void UIRuntimeMiniToolBar::adjustGeometry()
 
     /* Simulate toolbar auto-hiding: */
     simulateToolbarAutoHiding();
-
-    /* Due to [probably] Qt bug QMdiSubWindow still
-     * can receive focus even if focus policy is Qt::NoFocus,
-     * We should return the focus to our parent: */
-    parentWidget()->setFocus();
 }
 
 void UIRuntimeMiniToolBar::sltHandleToolbarResize()
@@ -259,6 +254,8 @@ void UIRuntimeMiniToolBar::prepare()
     /* Prepare mini-toolbar: */
     m_pToolbar = new UIMiniToolBar;
     {
+        /* Make sure we have no focus: */
+        m_pToolbar->setFocusPolicy(Qt::NoFocus);
         /* Propagate known options to child: */
         m_pToolbar->setAutoHide(m_fAutoHide);
         m_pToolbar->setAlignment(m_alignment);
@@ -270,14 +267,16 @@ void UIRuntimeMiniToolBar::prepare()
         /* Configure child connections: */
         connect(m_pToolbar, SIGNAL(sigResized()), this, SLOT(sltHandleToolbarResize()));
         connect(m_pToolbar, SIGNAL(sigAutoHideToggled()), this, SLOT(sltAutoHideToggled()));
+#ifndef RT_OS_DARWIN
         connect(m_pToolbar, SIGNAL(sigMinimizeAction()), this, SIGNAL(sigMinimizeAction()));
+#endif /* !RT_OS_DARWIN */
         connect(m_pToolbar, SIGNAL(sigExitAction()), this, SIGNAL(sigExitAction()));
         connect(m_pToolbar, SIGNAL(sigCloseAction()), this, SIGNAL(sigCloseAction()));
         /* Add child to mdi-area: */
         m_pEmbeddedToolbar = m_pMdiArea->addSubWindow(m_pToolbar, Qt::Window | Qt::FramelessWindowHint);
         /* Make sure we have no focus: */
-        m_pToolbar->setFocusPolicy(Qt::NoFocus);
         m_pEmbeddedToolbar->setFocusPolicy(Qt::NoFocus);
+        m_pEmbeddedToolbar->installEventFilter(this);
     }
 
     /* Prepare hover-enter/leave timers: */
@@ -339,6 +338,19 @@ void UIRuntimeMiniToolBar::leaveEvent(QEvent*)
         m_pHoverLeaveTimer->start();
 }
 
+bool UIRuntimeMiniToolBar::eventFilter(QObject *pWatched, QEvent *pEvent)
+{
+    /* Due to Qt bug QMdiArea can
+     * 1. steal focus from current application focus-widget
+     * 3. and even request focus stealing if QMdiArea hidden yet.
+     * We have to notify listeners about such facts.. */
+    if (pWatched && m_pEmbeddedToolbar && pWatched == m_pEmbeddedToolbar &&
+        pEvent->type() == QEvent::FocusIn)
+        emit sigNotifyAboutFocusStolen();
+    /* Call to base-class: */
+    return QWidget::eventFilter(pWatched, pEvent);
+}
+
 void UIRuntimeMiniToolBar::updateAutoHideAnimationBounds()
 {
     /* Update animation: */
@@ -426,7 +438,9 @@ UIMiniToolBar::UIMiniToolBar()
     /* Variables: Contents stuff: */
     , m_pAutoHideAction(0)
     , m_pLabel(0)
+#ifndef RT_OS_DARWIN
     , m_pMinimizeAction(0)
+#endif /* !RT_OS_DARWIN */
     , m_pRestoreAction(0)
     , m_pCloseAction(0)
     /* Variables: Menu stuff: */
@@ -606,12 +620,14 @@ void UIMiniToolBar::prepare()
     /* Right label margin: */
     m_margins << widgetForAction(addWidget(new QWidget));
 
+#ifndef RT_OS_DARWIN
     /* Minimize action: */
     m_pMinimizeAction = new QAction(this);
     m_pMinimizeAction->setIcon(UIIconPool::iconSet(":/minimize_16px.png"));
     m_pMinimizeAction->setToolTip(tr("Minimize Window"));
     connect(m_pMinimizeAction, SIGNAL(triggered()), this, SIGNAL(sigMinimizeAction()));
     addAction(m_pMinimizeAction);
+#endif /* !RT_OS_DARWIN */
 
     /* Exit action: */
     m_pRestoreAction = new QAction(this);
diff --git a/src/VBox/Frontends/VirtualBox/src/widgets/UIMiniToolBar.h b/src/VBox/Frontends/VirtualBox/src/widgets/UIMiniToolBar.h
index 7c3215c..26b85a4 100644
--- a/src/VBox/Frontends/VirtualBox/src/widgets/UIMiniToolBar.h
+++ b/src/VBox/Frontends/VirtualBox/src/widgets/UIMiniToolBar.h
@@ -53,7 +53,9 @@ class UIRuntimeMiniToolBar : public QWidget
 signals:
 
     /* Notifiers: Action stuff: */
+#ifndef RT_OS_DARWIN
     void sigMinimizeAction();
+#endif /* !RT_OS_DARWIN */
     void sigExitAction();
     void sigCloseAction();
 
@@ -61,6 +63,9 @@ signals:
     void sigHoverEnter();
     void sigHoverLeave();
 
+    /** Notifies listeners about we stole focus. */
+    void sigNotifyAboutFocusStolen();
+
 public:
 
     /* Constructor/destructor: */
@@ -107,6 +112,10 @@ private:
     void enterEvent(QEvent *pEvent);
     void leaveEvent(QEvent *pEvent);
 
+    /** Filters @a pEvent if <i>this</i> object has been
+      * installed as an event-filter for the @a pWatched. */
+    bool eventFilter(QObject *pWatched, QEvent *pEvent);
+
     /* Helper: Hover stuff: */
     void updateAutoHideAnimationBounds();
     void simulateToolbarAutoHiding();
@@ -151,7 +160,9 @@ signals:
 
     /* Notifiers: Action stuff: */
     void sigAutoHideToggled();
+#ifndef RT_OS_DARWIN
     void sigMinimizeAction();
+#endif /* !RT_OS_DARWIN */
     void sigExitAction();
     void sigCloseAction();
 
@@ -201,7 +212,9 @@ private:
     /* Variables: Contents stuff: */
     QAction *m_pAutoHideAction;
     QLabel *m_pLabel;
+#ifndef RT_OS_DARWIN
     QAction *m_pMinimizeAction;
+#endif /* !RT_OS_DARWIN */
     QAction *m_pRestoreAction;
     QAction *m_pCloseAction;
 
diff --git a/src/VBox/Frontends/VirtualBox/src/wizards/newvm/UIWizardNewVMPageBasic1.cpp b/src/VBox/Frontends/VirtualBox/src/wizards/newvm/UIWizardNewVMPageBasic1.cpp
index 40d264b..37f1607 100644
--- a/src/VBox/Frontends/VirtualBox/src/wizards/newvm/UIWizardNewVMPageBasic1.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/wizards/newvm/UIWizardNewVMPageBasic1.cpp
@@ -103,8 +103,8 @@ static const osTypePattern gs_OSTypePattern[] =
     { QRegExp("((Mac)|(Tig)|(Leop)|(os[ ]*x)).*32",                                             Qt::CaseInsensitive), "MacOS" },
 
     /* Code names for Linux distributions: */
-    { QRegExp("((edgy)|(feisty)|(gutsy)|(hardy)|(intrepid)|(jaunty)|(karmic)|(lucid)|(maverick)|(natty)|(oneiric)|(precise)|(quantal)|(raring)).*64",    Qt::CaseInsensitive), "Ubuntu_64" },
-    { QRegExp("((edgy)|(feisty)|(gutsy)|(hardy)|(intrepid)|(jaunty)|(karmic)|(lucid)|(maverick)|(natty)|(oneiric)|(precise)|(quantal)|(raring)).*32",    Qt::CaseInsensitive), "Ubuntu" },
+    { QRegExp("((edgy)|(feisty)|(gutsy)|(hardy)|(intrepid)|(jaunty)|(karmic)|(lucid)|(maverick)|(natty)|(oneiric)|(precise)|(quantal)|(raring)|(saucy)|(trusty)).*64",    Qt::CaseInsensitive), "Ubuntu_64" },
+    { QRegExp("((edgy)|(feisty)|(gutsy)|(hardy)|(intrepid)|(jaunty)|(karmic)|(lucid)|(maverick)|(natty)|(oneiric)|(precise)|(quantal)|(raring)|(saucy)|(trusty)).*32",    Qt::CaseInsensitive), "Ubuntu" },
     { QRegExp("((sarge)|(etch)|(lenny)|(squeeze)|(wheezy)|(jessie)|(sid)).*64",                                                                          Qt::CaseInsensitive), "Debian_64" },
     { QRegExp("((sarge)|(etch)|(lenny)|(squeeze)|(wheezy)|(jessie)|(sid)).*32",                                                                          Qt::CaseInsensitive), "Debian" },
     { QRegExp("((moonshine)|(werewolf)|(sulphur)|(cambridge)|(leonidas)|(constantine)|(goddard)|(laughlin)|(lovelock)|(verne)|(beefy)|(spherical)).*64", Qt::CaseInsensitive), "Fedora_64" },
diff --git a/src/VBox/GuestHost/OpenGL/include/cr_server.h b/src/VBox/GuestHost/OpenGL/include/cr_server.h
index 8efdef5..b215d4c 100644
--- a/src/VBox/GuestHost/OpenGL/include/cr_server.h
+++ b/src/VBox/GuestHost/OpenGL/include/cr_server.h
@@ -33,6 +33,7 @@
 #include <VBox/VBoxVideo.h>
 #include <VBox/Hardware/VBoxVideoVBE.h>
 #include <VBox/VBoxVideo3D.h>
+#include <VBox/VBoxVideoHost3D.h>
 
 #ifdef __cplusplus
 extern "C" {
@@ -232,7 +233,7 @@ typedef struct {
     GLboolean bVisible;      /*guest window is visible*/
     GLubyte   u8Unused;       /*redirect to FBO instead of real host window*/
     GLboolean bFbDraw;       /*GL_FRONT buffer is drawn to directly*/
-    GLboolean fReserved;
+    GLboolean fIsDummyRefference;
 
     GLint       cVisibleRects;    /*count of visible rects*/
     GLint      *pVisibleRects;    /*visible rects left, top, right, bottom*/
@@ -406,8 +407,6 @@ typedef struct {
     uint32_t fBlitterMode;
     CR_BLITTER Blitter;
 
-    VBOXCRCMD_CLTINFO CltInfo;
-
     CR_SERVER_RPW RpwWorker;
 
     /** configuration options */
@@ -485,6 +484,8 @@ typedef struct {
 
     SPUDispatchTable TmpCtxDispatch;
 
+    VBOXCRCMD_SVRENABLE_INFO CrCmdClientInfo;
+
 #ifdef VBOX_WITH_CRSERVER_DUMPER
     CR_RECORDER Recorder;
     CR_BLITTER RecorderBlitter;
@@ -565,9 +566,13 @@ extern DECLEXPORT(void) crServerVBoxSetNotifyEventCB(PFNCRSERVERNOTIFYEVENT pfnC
 extern DECLEXPORT(int32_t) crVBoxServerCrHgsmiCmd(struct VBOXVDMACMD_CHROMIUM_CMD *pCmd, uint32_t cbCmd);
 extern DECLEXPORT(int32_t) crVBoxServerCrHgsmiCtl(struct VBOXVDMACMD_CHROMIUM_CTL *pCtl, uint32_t cbCtl);
 
-extern DECLEXPORT(int32_t) crVBoxServerCrCmdNotifyCmds();
 #endif
 
+extern DECLEXPORT(int32_t) crVBoxServerHgcmEnable(HVBOXCRCMDCTL_REMAINING_HOST_COMMAND hRHCmd, PFNVBOXCRCMDCTL_REMAINING_HOST_COMMAND pfnRHCmd);
+extern DECLEXPORT(int32_t) crVBoxServerHgcmDisable();
+
+extern int crVBoxServerHostCtl(VBOXCRCMDCTL *pCtl, uint32_t cbCtl);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/src/VBox/GuestHost/OpenGL/include/cr_vreg.h b/src/VBox/GuestHost/OpenGL/include/cr_vreg.h
index 353178d..0f5786b 100644
--- a/src/VBox/GuestHost/OpenGL/include/cr_vreg.h
+++ b/src/VBox/GuestHost/OpenGL/include/cr_vreg.h
@@ -63,6 +63,20 @@ DECLINLINE(void) VBoxRectScaled(const RTRECT *pRect, float xScale, float yScale,
     *pResult = *pRect;
     VBoxRectScale(pResult, xScale, yScale);
 }
+
+DECLINLINE(void) VBoxRectUnscale(PRTRECT pRect, float xScale, float yScale)
+{
+    pRect->xLeft = CR_FLOAT_RCAST(int32_t, pRect->xLeft / xScale);
+    pRect->yTop = CR_FLOAT_RCAST(int32_t, pRect->yTop / yScale);
+    pRect->xRight = CR_FLOAT_RCAST(int32_t, pRect->xRight / xScale);
+    pRect->yBottom = CR_FLOAT_RCAST(int32_t, pRect->yBottom / yScale);
+}
+
+DECLINLINE(void) VBoxRectUnscaled(const RTRECT *pRect, float xScale, float yScale, PRTRECT pResult)
+{
+    *pResult = *pRect;
+    VBoxRectUnscale(pResult, xScale, yScale);
+}
 #endif
 
 DECLINLINE(void) VBoxRectIntersect(PRTRECT pRect1, const RTRECT * pRect2)
@@ -190,8 +204,8 @@ VBOXVREGDECL(int) VBoxVrListClone(const VBOXVR_LIST *pList, VBOXVR_LIST *pDstLis
 VBOXVREGDECL(int) VBoxVrListRectsIntersect(PVBOXVR_LIST pList, uint32_t cRects, const RTRECT * aRects, bool *pfChanged);
 VBOXVREGDECL(int) VBoxVrListIntersect(PVBOXVR_LIST pList, const VBOXVR_LIST *pList2, bool *pfChanged);
 
-VBOXVREGDECL(int) VBoxVrInit();
-VBOXVREGDECL(void) VBoxVrTerm();
+VBOXVREGDECL(int) VBoxVrInit(void);
+VBOXVREGDECL(void) VBoxVrTerm(void);
 
 typedef struct VBOXVR_LIST_ITERATOR
 {
diff --git a/src/VBox/GuestHost/OpenGL/packer/pack_pixels.c b/src/VBox/GuestHost/OpenGL/packer/pack_pixels.c
index 19f2a1d..2508643 100644
--- a/src/VBox/GuestHost/OpenGL/packer/pack_pixels.c
+++ b/src/VBox/GuestHost/OpenGL/packer/pack_pixels.c
@@ -143,7 +143,8 @@ void PACK_APIENTRY crPackBitmap(GLsizei width, GLsizei height,
     WRITE_DATA( 24, GLuint, noimagedata );
     WRITE_DATA( 28, GLint, (GLint) (uintptr_t) bitmap);
 
-    crBitmapCopy(width, height, (GLubyte *)(data_ptr + 32), bitmap, unpack);
+    if (!noimagedata)
+        crBitmapCopy(width, height, (GLubyte *)(data_ptr + 32), bitmap, unpack);
 
     crHugePacket( CR_BITMAP_OPCODE, data_ptr );
     crPackFree( data_ptr );
diff --git a/src/VBox/GuestHost/OpenGL/util/blitter.cpp b/src/VBox/GuestHost/OpenGL/util/blitter.cpp
index 8dcf1cb..a14c091 100644
--- a/src/VBox/GuestHost/OpenGL/util/blitter.cpp
+++ b/src/VBox/GuestHost/OpenGL/util/blitter.cpp
@@ -1575,7 +1575,7 @@ static int ctTdBltSdCreate(PCR_BLITTER pBlitter, uint32_t width, uint32_t height
 
 static int ctTdBltSdGet(PCR_TEXDATA pTex, uint32_t width, uint32_t height, PCR_TEXDATA *ppScaledCache)
 {
-    Assert(pTex->Flags.Entered);
+    Assert(CrBltIsEntered(pTex->pBlitter));
 
     PCR_TEXDATA pScaledCache;
 
diff --git a/src/VBox/GuestHost/OpenGL/util/htable.cpp b/src/VBox/GuestHost/OpenGL/util/htable.cpp
index f84804f..bb9434c 100644
--- a/src/VBox/GuestHost/OpenGL/util/htable.cpp
+++ b/src/VBox/GuestHost/OpenGL/util/htable.cpp
@@ -65,7 +65,7 @@ int crHTableRealloc(PCRHTABLE pTbl, uint32_t cNewSize)
         void **pvNewData = (void**)RTMemAllocZ(sizeof (pTbl->paData[0]) * cNewSize);
         if (!pvNewData)
         {
-            WARN(("RTMemAllocZ failed for size (%d)", sizeof (pTbl->paData[0]) * cNewSize));
+            WARN(("RTMemAllocZ failed for size (%d)", (int)(sizeof (pTbl->paData[0]) * cNewSize)));
             return VERR_NO_MEMORY;
         }
         memcpy(pvNewData, pTbl->paData, sizeof (pTbl->paData[0]) * pTbl->cSize);
diff --git a/src/VBox/HostDrivers/VBoxNetFlt/darwin/VBoxNetFlt-darwin.cpp b/src/VBox/HostDrivers/VBoxNetFlt/darwin/VBoxNetFlt-darwin.cpp
index 673699b..be095dc 100644
--- a/src/VBox/HostDrivers/VBoxNetFlt/darwin/VBoxNetFlt-darwin.cpp
+++ b/src/VBox/HostDrivers/VBoxNetFlt/darwin/VBoxNetFlt-darwin.cpp
@@ -4,7 +4,7 @@
  */
 
 /*
- * Copyright (C) 2006-2012 Oracle Corporation
+ * Copyright (C) 2006-2014 Oracle Corporation
  *
  * This file is part of VirtualBox Open Source Edition (OSE), as
  * available from http://www.virtualbox.org. This file is free software;
@@ -138,11 +138,88 @@ static VBOXNETFLTGLOBALS g_VBoxNetFltGlobals;
  * It is used for tagging mbufs. */
 static mbuf_tag_id_t g_idTag;
 
-/** the offset of the struct ifnet::if_pcount variable. */
+/** The offset of the struct ifnet::if_pcount variable.
+ * @remarks Initial value is valid for Lion and earlier. We adjust it on attach
+ *          for later releases.  */
 static unsigned g_offIfNetPCount = sizeof(void *) * (1 /*if_softc*/ + 1 /*if_name*/ + 2 /*if_link*/ + 2 /*if_addrhead*/ + 1 /*if_check_multi*/)
                                  + sizeof(u_long) /*if_refcnt*/;
 /** Macro for accessing ifnet::if_pcount. */
 #define VBOX_GET_PCOUNT(pIfNet) ( *(int *)((uintptr_t)pIfNet + g_offIfNetPCount) )
+/** The size of area of ifnet structure we try to locate if_pcount in. */
+#define VBOXNETFLT_DARWIN_IFNET_SIZE 256
+/** Indicates whether g_offIfNetPCount has been adjusted already (no point in
+ * doing it more than once). */
+static bool g_fNetPCountFound  = false;
+
+
+/**
+ * Change the promiscuous setting and try spot the changed in @a pIfNet.
+ *
+ * @returns Offset of potential p_count field.
+ * @param   pIfNet      The interface we're attaching to.
+ * @param   iPromisc    Whether to enable (1) or disable (0) promiscuous mode.
+ *
+ * @note    This implementation relies on if_pcount to be aligned on sizeof(int).
+ */
+static unsigned vboxNetFltDarwinSetAndDiff(ifnet_t pIfNet, int iPromisc)
+{
+    int aiSavedState[VBOXNETFLT_DARWIN_IFNET_SIZE / sizeof(int)];
+    memcpy(aiSavedState, pIfNet, sizeof(aiSavedState));
+
+    ifnet_set_promiscuous(pIfNet, iPromisc);
+
+    int const iDiff = iPromisc ? 1 : -1;
+
+    /*
+     * We assume that ifnet structure will never have less members in front of if_pcount
+     * than it used to have in Lion. If this turns out to be false assumption we will
+     * have to start from zero offset.
+     */
+    for (unsigned i = g_offIfNetPCount / sizeof(int); i < RT_ELEMENTS(aiSavedState); i++)
+        if (((int*)pIfNet)[i] - aiSavedState[i] == iDiff)
+            return i * sizeof(int);
+
+    return 0;
+}
+
+
+/**
+ * Detect and adjust the offset of ifnet::if_pcount.
+ *
+ * @param   pIfNet      The interface we're attaching to.
+ */
+static void vboxNetFltDarwinDetectPCountOffset(ifnet_t pIfNet)
+{
+    if (g_fNetPCountFound)
+        return;
+
+    /*
+     * It would be nice to use locking at this point, but it is not available via KPI.
+     * This is why we try several times. At each attempt we modify if_pcount four times
+     * to rule out false detections.
+     */
+    unsigned offTry1, offTry2, offTry3, offTry4;
+    for (int iAttempt = 0; iAttempt < 3; iAttempt++)
+    {
+        offTry1 = vboxNetFltDarwinSetAndDiff(pIfNet, 1);
+        offTry2 = vboxNetFltDarwinSetAndDiff(pIfNet, 1);
+        offTry3 = vboxNetFltDarwinSetAndDiff(pIfNet, 0);
+        offTry4 = vboxNetFltDarwinSetAndDiff(pIfNet, 0);
+        if (offTry1 == offTry2 && offTry2 == offTry3 && offTry3 == offTry4)
+        {
+            if (g_offIfNetPCount != offTry1)
+            {
+                Log(("VBoxNetFltDarwinDetectPCountOffset: Adjusted if_pcount offset to %x from %x.\n", offTry1, g_offIfNetPCount));
+                g_offIfNetPCount = offTry1;
+                g_fNetPCountFound = true;
+            }
+            break;
+        }
+    }
+
+    if (g_offIfNetPCount != offTry1)
+        LogRel(("VBoxNetFlt: Failed to detect promiscuous count, all traffic may reach wire (%x != %x).\n", g_offIfNetPCount, offTry1));
+}
 
 
 /**
@@ -955,6 +1032,9 @@ static int vboxNetFltDarwinAttachToInterface(PVBOXNETFLTINS pThis, bool fRedisco
     ASMAtomicUoWritePtr(&pThis->u.s.pIfNet, pIfNet);
     RTSpinlockReleaseNoInts(pThis->hSpinlock);
 
+    /* Adjust g_offIfNetPCount as it varies for different versions of xnu. */
+    vboxNetFltDarwinDetectPCountOffset(pIfNet);
+
     /* Prevent stuck-in-dock issue by associating interface receive thread with kernel thread. */
     vboxNetFltSendDummy(pIfNet);
 
diff --git a/src/VBox/HostServices/SharedOpenGL/Makefile.kmk b/src/VBox/HostServices/SharedOpenGL/Makefile.kmk
index baf6c70..971c1c9 100644
--- a/src/VBox/HostServices/SharedOpenGL/Makefile.kmk
+++ b/src/VBox/HostServices/SharedOpenGL/Makefile.kmk
@@ -264,6 +264,12 @@ VBoxOGLrenderspu_OBJCFLAGS.darwin = -Wno-shadow
 VBoxOGLrenderspu_SOURCES.darwin  = \
 	render/renderspu_cocoa.c \
 	render/renderspu_cocoa_helper.m
+ifdef VBOX_WITH_CRHGSMI
+VBoxOGLrenderspu_DEFS += VBOX_WITH_CRHGSMI
+endif
+ifdef VBOX_WITH_VDMA
+VBoxOGLrenderspu_DEFS += VBOX_WITH_VDMA
+endif
 VBoxOGLrenderspu_LDFLAGS.darwin += -install_name $(VBOX_DYLD_EXECUTABLE_PATH)/VBoxOGLrenderspu.dylib
 VBoxOGLrenderspu_LIBS = \
 	$(PATH_STAGE_LIB)/VBoxOGLhostspuload$(VBOX_SUFF_LIB) \
diff --git a/src/VBox/HostServices/SharedOpenGL/crserver/crservice.cpp b/src/VBox/HostServices/SharedOpenGL/crserver/crservice.cpp
index 4388fde..77ddf19 100644
--- a/src/VBox/HostServices/SharedOpenGL/crserver/crservice.cpp
+++ b/src/VBox/HostServices/SharedOpenGL/crserver/crservice.cpp
@@ -961,7 +961,7 @@ static void crScreenshotHandle(CRVBOXHGCMTAKESCREENSHOT *pScreenshot, uint32_t i
 /*
  * We differentiate between a function handler for the guest and one for the host.
  */
-static DECLCALLBACK(int) svcHostCall (void *, uint32_t u32Function, uint32_t cParms, VBOXHGCMSVCPARM paParms[])
+static int svcHostCallPerform(uint32_t u32Function, uint32_t cParms, VBOXHGCMSVCPARM paParms[])
 {
     int rc = VINF_SUCCESS;
 
@@ -979,10 +979,6 @@ static DECLCALLBACK(int) svcHostCall (void *, uint32_t u32Function, uint32_t cPa
 
     switch (u32Function)
     {
-        case SHCRGL_HOST_FN_CRCMD_NOTIFY_CMDS:
-        {
-            rc = crVBoxServerCrCmdNotifyCmds();
-        } break;
 #ifdef VBOX_WITH_CRHGSMI
         case SHCRGL_HOST_FN_CRHGSMI_CMD:
         {
@@ -1476,6 +1472,73 @@ static DECLCALLBACK(int) svcHostCall (void *, uint32_t u32Function, uint32_t cPa
     return rc;
 }
 
+int crVBoxServerHostCtl(VBOXCRCMDCTL *pCtl, uint32_t cbCtl)
+{
+    if ((cbCtl - sizeof (VBOXCRCMDCTL)) % sizeof(VBOXHGCMSVCPARM))
+    {
+        WARN(("invalid param size"));
+        return VERR_INVALID_PARAMETER;
+    }
+    uint32_t cParams = (cbCtl - sizeof (VBOXCRCMDCTL)) / sizeof (VBOXHGCMSVCPARM);
+    return svcHostCallPerform(pCtl->u32Function, cParams, (VBOXHGCMSVCPARM*)(pCtl + 1));
+}
+
+static DECLCALLBACK(int) svcHostCall(void *, uint32_t u32Function, uint32_t cParms, VBOXHGCMSVCPARM paParms[])
+{
+    switch (u32Function)
+    {
+        case SHCRGL_HOST_FN_CTL:
+        {
+            if (cParms != 1)
+            {
+                WARN(("cParams != 1"));
+                return VERR_INVALID_PARAMETER;
+            }
+
+            if (paParms->type != VBOX_HGCM_SVC_PARM_PTR)
+            {
+                WARN(("invalid param type"));
+                return VERR_INVALID_PARAMETER;
+            }
+
+            if (paParms->u.pointer.size < sizeof (VBOXCRCMDCTL))
+            {
+                WARN(("invalid param size"));
+                return VERR_INVALID_PARAMETER;
+            }
+
+            VBOXCRCMDCTL *pCtl = (VBOXCRCMDCTL*)paParms->u.pointer.addr;
+            switch (pCtl->enmType)
+            {
+                case VBOXCRCMDCTL_TYPE_HGCM:
+                {
+                    return crVBoxServerHostCtl(pCtl, paParms->u.pointer.size);
+                }
+                case VBOXCRCMDCTL_TYPE_DISABLE:
+                {
+                    if (paParms->u.pointer.size != sizeof (VBOXCRCMDCTL))
+                        WARN(("invalid param size"));
+                    return crVBoxServerHgcmDisable();
+                }
+                case VBOXCRCMDCTL_TYPE_ENABLE:
+                {
+                    if (paParms->u.pointer.size != sizeof (VBOXCRCMDCTL_ENABLE))
+                        WARN(("invalid param size"));
+                    VBOXCRCMDCTL_ENABLE *pEnable = (VBOXCRCMDCTL_ENABLE*)pCtl;
+                    return crVBoxServerHgcmEnable(pEnable->hRHCmd, pEnable->pfnRHCmd);
+                }
+                default:
+                    WARN(("invalid function"));
+                    return VERR_INVALID_PARAMETER;
+            }
+            WARN(("should not be here!"));
+            return VERR_INTERNAL_ERROR;
+        }
+        default:
+            return svcHostCallPerform(u32Function, cParms, paParms);
+    }
+}
+
 extern "C" DECLCALLBACK(DECLEXPORT(int)) VBoxHGCMSvcLoad (VBOXHGCMSVCFNTABLE *ptable)
 {
     int rc = VINF_SUCCESS;
diff --git a/src/VBox/HostServices/SharedOpenGL/crserverlib/server.h b/src/VBox/HostServices/SharedOpenGL/crserverlib/server.h
index 0b8b464..677bcf0 100644
--- a/src/VBox/HostServices/SharedOpenGL/crserverlib/server.h
+++ b/src/VBox/HostServices/SharedOpenGL/crserverlib/server.h
@@ -115,7 +115,7 @@ GLboolean crServerClientInBeginEnd(const CRClient *client);
 
 GLint crServerDispatchCreateContextEx(const char *dpyName, GLint visualBits, GLint shareCtx, GLint preloadCtxID, int32_t internalID);
 GLint crServerDispatchWindowCreateEx(const char *dpyName, GLint visBits, GLint preloadWinID);
-GLint crServerMuralInit(CRMuralInfo *mural, const char *dpyName, GLint visBits, GLint preloadWinID);
+GLint crServerMuralInit(CRMuralInfo *mural, GLboolean fGuestWindow, GLint visBits, GLint preloadWinID);
 void crServerMuralTerm(CRMuralInfo *mural);
 GLboolean crServerMuralSize(CRMuralInfo *mural, GLint width, GLint height);
 void crServerMuralPosition(CRMuralInfo *mural, GLint x, GLint y);
@@ -155,6 +155,8 @@ HCR_FRAMEBUFFER CrPMgrFbGetNextEnabled(HCR_FRAMEBUFFER hFb);
 HCR_FRAMEBUFFER CrPMgrFbGetFirstInitialized();
 HCR_FRAMEBUFFER CrPMgrFbGetNextInitialized(HCR_FRAMEBUFFER hFb);
 
+int CrFbRegionsClear(HCR_FRAMEBUFFER hFb);
+
 
 #define CR_SERVER_FBO_BB_IDX(_mural) ((_mural)->iBbBuffer)
 #define CR_SERVER_FBO_FB_IDX(_mural) (((_mural)->iBbBuffer + 1) % ((_mural)->cBuffers))
@@ -425,7 +427,7 @@ typedef DECLCALLBACKPTR(bool, PFNCR_FRAMEBUFFER_ENTRIES_VISITOR_CB)(HCR_FRAMEBUF
 bool CrFbHas3DData(HCR_FRAMEBUFFER hFb);
 void CrFbVisitCreatedEntries(HCR_FRAMEBUFFER hFb, PFNCR_FRAMEBUFFER_ENTRIES_VISITOR_CB pfnVisitorCb, void *pvContext);
 int CrFbResize(HCR_FRAMEBUFFER hFb, const struct VBVAINFOSCREEN * pScreen, void *pvVRAM);
-int CrFbBltGetContents(HCR_FRAMEBUFFER hFb, const RTRECT *pSrcRect, uint32_t cRects, const RTRECT *pPrects, CR_BLITTER_IMG *pImg);
+int CrFbBltGetContents(HCR_FRAMEBUFFER hFb, const RTRECT *pSrcRect, const RTRECT *pDstRect, uint32_t cRects, const RTRECT *pPrects, CR_BLITTER_IMG *pImg);
 bool CrFbIsEnabled(HCR_FRAMEBUFFER hFb);
 int CrFbEntryCreateForTexId(HCR_FRAMEBUFFER hFb, GLuint idTex, uint32_t fFlags, HCR_FRAMEBUFFER_ENTRY *phEntry);
 int CrFbEntryCreateForTexData(HCR_FRAMEBUFFER hFb, struct CR_TEXDATA *pTex, uint32_t fFlags, HCR_FRAMEBUFFER_ENTRY *phEntry);
diff --git a/src/VBox/HostServices/SharedOpenGL/crserverlib/server_main.c b/src/VBox/HostServices/SharedOpenGL/crserverlib/server_main.c
index 89b9c61..1a7e360 100644
--- a/src/VBox/HostServices/SharedOpenGL/crserverlib/server_main.c
+++ b/src/VBox/HostServices/SharedOpenGL/crserverlib/server_main.c
@@ -59,6 +59,8 @@ CRServer cr_server;
 
 int tearingdown = 0; /* can't be static */
 
+static DECLCALLBACK(int) crVBoxCrCmdCmd(HVBOXCRCMDSVR hSvr, PVBOXCMDVBVA_HDR pCmd, uint32_t cbCmd);
+
 DECLINLINE(int32_t) crVBoxServerClientGet(uint32_t u32ClientID, CRClient **ppClient)
 {
     CRClient *pClient = NULL;
@@ -161,7 +163,7 @@ static void crServerTearDown( void )
 
     /* sync our state with renderspu,
      * do it before mural & context deletion to avoid deleting currently set murals/contexts*/
-    cr_server.head_spu->dispatch_table.MakeCurrent(0, 0, 0);
+    cr_server.head_spu->dispatch_table.MakeCurrent(CR_RENDER_DEFAULT_WINDOW_ID, 0, CR_RENDER_DEFAULT_CONTEXT_ID);
 
     /* Deallocate all semaphores */
     crFreeHashtable(cr_server.semaphores, crFree);
@@ -529,6 +531,38 @@ GLboolean crVBoxServerInit(void)
     return GL_TRUE;
 }
 
+static int32_t crVBoxServerAddClientObj(uint32_t u32ClientID, CRClient **ppNewClient)
+{
+    CRClient *newClient;
+
+    if (cr_server.numClients>=CR_MAX_CLIENTS)
+    {
+        if (ppNewClient)
+            *ppNewClient = NULL;
+        return VERR_MAX_THRDS_REACHED;
+    }
+
+    newClient = (CRClient *) crCalloc(sizeof(CRClient));
+    crDebug("crServer: AddClient u32ClientID=%d", u32ClientID);
+
+    newClient->spu_id = 0;
+    newClient->currentCtxInfo = &cr_server.MainContextInfo;
+    newClient->currentContextNumber = -1;
+    newClient->conn = crNetAcceptClient(cr_server.protocol, NULL,
+                                        cr_server.tcpip_port,
+                                        cr_server.mtu, 0);
+    newClient->conn->u32ClientID = u32ClientID;
+
+    cr_server.clients[cr_server.numClients++] = newClient;
+
+    crServerAddToRunQueue(newClient);
+
+    if (ppNewClient)
+        *ppNewClient = newClient;
+
+    return VINF_SUCCESS;
+}
+
 int32_t crVBoxServerAddClient(uint32_t u32ClientID)
 {
     CRClient *newClient;
@@ -744,6 +778,17 @@ extern DECLEXPORT(int32_t) crVBoxServerClientGetCaps(uint32_t u32ClientID, uint3
     return VINF_SUCCESS;
 }
 
+static int32_t crVBoxServerClientObjSetVersion(CRClient *pClient, uint32_t vMajor, uint32_t vMinor)
+{
+    pClient->conn->vMajor = vMajor;
+    pClient->conn->vMinor = vMinor;
+
+    if (vMajor != CR_PROTOCOL_VERSION_MAJOR
+        || vMinor != CR_PROTOCOL_VERSION_MINOR)
+        return VERR_NOT_SUPPORTED;
+    return VINF_SUCCESS;
+}
+
 int32_t crVBoxServerClientSetVersion(uint32_t u32ClientID, uint32_t vMajor, uint32_t vMinor)
 {
     CRClient *pClient=NULL;
@@ -760,15 +805,14 @@ int32_t crVBoxServerClientSetVersion(uint32_t u32ClientID, uint32_t vMajor, uint
     }
     if (!pClient) return VERR_INVALID_PARAMETER;
 
-    pClient->conn->vMajor = vMajor;
-    pClient->conn->vMinor = vMinor;
+    return crVBoxServerClientObjSetVersion(pClient, vMajor, vMinor);
+}
 
-    if (vMajor != CR_PROTOCOL_VERSION_MAJOR
-        || vMinor != CR_PROTOCOL_VERSION_MINOR)
-    {
-        return VERR_NOT_SUPPORTED;
-    }
-    else return VINF_SUCCESS;
+static int32_t crVBoxServerClientObjSetPID(CRClient *pClient, uint64_t pid)
+{
+    pClient->pid = pid;
+
+    return VINF_SUCCESS;
 }
 
 int32_t crVBoxServerClientSetPID(uint32_t u32ClientID, uint64_t pid)
@@ -787,9 +831,7 @@ int32_t crVBoxServerClientSetPID(uint32_t u32ClientID, uint64_t pid)
     }
     if (!pClient) return VERR_INVALID_PARAMETER;
 
-    pClient->pid = pid;
-
-    return VINF_SUCCESS;
+    return crVBoxServerClientObjSetPID(pClient, pid);
 }
 
 int
@@ -1004,7 +1046,7 @@ CRMuralInfo * crServerGetDummyMural(GLint visualBits)
             crWarning("crCalloc failed!");
             return NULL;
         }
-        id = crServerMuralInit(pMural, "", visualBits, 0);
+        id = crServerMuralInit(pMural, GL_FALSE, visualBits, 0);
         if (id < 0)
         {
             crWarning("crServerMuralInit failed!");
@@ -2599,8 +2641,6 @@ DECLEXPORT(int32_t) crVBoxServerLoadState(PSSMHANDLE pSSM, uint32_t version)
 
     if (version >= SHCROGL_SSM_VERSION_WITH_SCREEN_INFO)
     {
-        HCR_FRAMEBUFFER hFb;
-
         rc = CrPMgrLoadState(pSSM, version);
         AssertRCReturn(rc, rc);
     }
@@ -2885,10 +2925,37 @@ DECLEXPORT(int32_t) crVBoxServerSetScreenViewport(int sIndex, int32_t x, int32_t
     return VINF_SUCCESS;
 }
 
+static void crVBoxServerDefaultContextSet()
+{
+    GLint spuWindow, spuCtx;
+
+    if (cr_server.MainContextInfo.SpuContext)
+    {
+        CRMuralInfo *pMural = crServerGetDummyMural(cr_server.MainContextInfo.CreateInfo.realVisualBits);
+        if (!pMural)
+        {
+            WARN(("dummy mural is NULL"));
+            spuCtx = CR_RENDER_DEFAULT_CONTEXT_ID;
+            spuWindow = CR_RENDER_DEFAULT_WINDOW_ID;
+        }
+        else
+        {
+            spuCtx = cr_server.MainContextInfo.SpuContext;
+            spuWindow = pMural->CreateInfo.realVisualBits;
+        }
+    }
+    else
+    {
+        spuCtx = CR_RENDER_DEFAULT_CONTEXT_ID;
+        spuWindow = CR_RENDER_DEFAULT_WINDOW_ID;
+    }
+
+    cr_server.head_spu->dispatch_table.MakeCurrent(spuWindow, 0, spuCtx);
+}
 
 #ifdef VBOX_WITH_CRHGSMI
 
-static int32_t crVBoxServerCmdVbvaCrCmdProcess(struct VBOXCMDVBVA_CRCMD_CMD *pCmd)
+static int32_t crVBoxServerCmdVbvaCrCmdProcess(struct VBOXCMDVBVA_CRCMD_CMD *pCmd, uint32_t cbCmd)
 {
     int32_t rc;
     uint32_t cBuffers = pCmd->cBuffers;
@@ -2901,29 +2968,35 @@ static int32_t crVBoxServerCmdVbvaCrCmdProcess(struct VBOXCMDVBVA_CRCMD_CMD *pCm
 
     if (!g_pvVRamBase)
     {
-        crWarning("g_pvVRamBase is not initialized");
+        WARN(("g_pvVRamBase is not initialized"));
         return VERR_INVALID_STATE;
     }
 
     if (!cBuffers)
     {
-        crWarning("zero buffers passed in!");
+        WARN(("zero buffers passed in!"));
         return VERR_INVALID_PARAMETER;
     }
 
     cParams = cBuffers-1;
 
+    if (cbCmd != RT_OFFSETOF(VBOXCMDVBVA_CRCMD_CMD, aBuffers[cBuffers]))
+    {
+        WARN(("invalid buffer size"));
+        return VERR_INVALID_PARAMETER;
+    }
+
     cbHdr = pCmd->aBuffers[0].cbBuffer;
     pHdr = VBOXCRHGSMI_PTR_SAFE(pCmd->aBuffers[0].offBuffer, cbHdr, CRVBOXHGSMIHDR);
     if (!pHdr)
     {
-        crWarning("invalid header buffer!");
+        WARN(("invalid header buffer!"));
         return VERR_INVALID_PARAMETER;
     }
 
     if (cbHdr < sizeof (*pHdr))
     {
-        crWarning("invalid header buffer size!");
+        WARN(("invalid header buffer size!"));
         return VERR_INVALID_PARAMETER;
     }
 
@@ -3187,24 +3260,110 @@ static int32_t crVBoxServerCmdVbvaCrCmdProcess(struct VBOXCMDVBVA_CRCMD_CMD *pCm
     return rc;
 }
 
-static int32_t crVBoxServerCrCmdProcess(PVBOXCMDVBVA_HDR pCmd, uint32_t cbCmd)
+static DECLCALLBACK(int) crVBoxCrCmdEnable(HVBOXCRCMDSVR hSvr, VBOXCRCMD_SVRENABLE_INFO *pInfo)
+{
+    cr_server.CrCmdClientInfo = *pInfo;
+
+    crVBoxServerDefaultContextSet();
+
+    return VINF_SUCCESS;
+}
+
+static DECLCALLBACK(int) crVBoxCrCmdDisable(HVBOXCRCMDSVR hSvr)
+{
+    cr_server.head_spu->dispatch_table.MakeCurrent(0, 0, 0);
+
+    memset(&cr_server.CrCmdClientInfo, 0, sizeof (cr_server.CrCmdClientInfo));
+
+    return VINF_SUCCESS;
+}
+
+static DECLCALLBACK(int) crVBoxCrCmdHostCtl(HVBOXCRCMDSVR hSvr, uint8_t* pCmd, uint32_t cbCmd)
 {
+    return crVBoxServerHostCtl((VBOXCRCMDCTL*)pCmd, cbCmd);
+}
+
+static DECLCALLBACK(int) crVBoxCrCmdGuestCtl(HVBOXCRCMDSVR hSvr, uint8_t* pCmd, uint32_t cbCmd)
+{
+    VBOXCMDVBVA_3DCTL *pCtl = (VBOXCMDVBVA_3DCTL*)pCmd;
+    if (cbCmd < sizeof (VBOXCMDVBVA_3DCTL))
+    {
+        WARN(("invalid buffer size"));
+        return VERR_INVALID_PARAMETER;
+    }
+
+    switch (pCtl->u32Type)
+    {
+        case VBOXCMDVBVA3DCTL_TYPE_CONNECT:
+        {
+            VBOXCMDVBVA_3DCTL_CONNECT *pConnect = (VBOXCMDVBVA_3DCTL_CONNECT*)pCtl;
+
+            return VERR_NOT_SUPPORTED;
+        }
+        case VBOXCMDVBVA3DCTL_TYPE_DISCONNECT:
+        {
+            return VERR_NOT_SUPPORTED;
+        }
+        case VBOXCMDVBVA3DCTL_TYPE_CMD:
+        {
+            VBOXCMDVBVA_3DCTL_CMD *p3DCmd;
+            if (cbCmd < sizeof (VBOXCMDVBVA_3DCTL_CMD))
+            {
+                WARN(("invalid size"));
+                return VERR_INVALID_PARAMETER;
+            }
+
+            p3DCmd = (VBOXCMDVBVA_3DCTL_CMD*)pCmd;
+
+            return crVBoxCrCmdCmd(NULL, &p3DCmd->Cmd, cbCmd - RT_OFFSETOF(VBOXCMDVBVA_3DCTL_CMD, Cmd));
+        }
+        default:
+            WARN(("invalid function"));
+            return VERR_INVALID_PARAMETER;
+    }
+}
+
+static DECLCALLBACK(int) crVBoxCrCmdSaveState(HVBOXCRCMDSVR hSvr, PSSMHANDLE pSSM)
+{
+    AssertFailed();
+    return VERR_NOT_IMPLEMENTED;
+}
+
+static DECLCALLBACK(int) crVBoxCrCmdLoadState(HVBOXCRCMDSVR hSvr, PSSMHANDLE pSSM, uint32_t u32Version)
+{
+    AssertFailed();
+    return VERR_NOT_IMPLEMENTED;
+}
+
+
+static DECLCALLBACK(int) crVBoxCrCmdCmd(HVBOXCRCMDSVR hSvr, PVBOXCMDVBVA_HDR pCmd, uint32_t cbCmd)
+{
+    AssertFailed();
     switch (pCmd->u8OpCode)
     {
         case VBOXCMDVBVA_OPTYPE_CRCMD:
         {
-            VBOXCMDVBVA_CRCMD *pCrCmdDr = (VBOXCMDVBVA_CRCMD*)pCmd;
-            VBOXCMDVBVA_CRCMD_CMD *pCrCmd = &pCrCmdDr->Cmd;
-            int rc = crVBoxServerCmdVbvaCrCmdProcess(pCrCmd);
+            VBOXCMDVBVA_CRCMD *pCrCmdDr;
+            VBOXCMDVBVA_CRCMD_CMD *pCrCmd;
+            int rc;
+            pCrCmdDr = (VBOXCMDVBVA_CRCMD*)pCmd;
+            pCrCmd = &pCrCmdDr->Cmd;
+            if (cbCmd < sizeof (VBOXCMDVBVA_CRCMD))
+            {
+                WARN(("invalid buffer size"));
+                pCmd->u.i8Result = -1;
+                break;
+            }
+            rc = crVBoxServerCmdVbvaCrCmdProcess(pCrCmd, cbCmd - RT_OFFSETOF(VBOXCMDVBVA_CRCMD, Cmd));
             if (RT_SUCCESS(rc))
             {
             /* success */
-                pCmd->i8Result = 0;
+                pCmd->u.i8Result = 0;
             }
             else
             {
-                crWarning("crVBoxServerCmdVbvaCrCmdProcess failed, rc %d", rc);
-                pCmd->i8Result = -1;
+                WARN(("crVBoxServerCmdVbvaCrCmdProcess failed, rc %d", rc));
+                pCmd->u.i8Result = -1;
             }
             break;
         }
@@ -3215,34 +3374,11 @@ static int32_t crVBoxServerCrCmdProcess(PVBOXCMDVBVA_HDR pCmd, uint32_t cbCmd)
         }
         default:
             WARN(("unsupported command"));
-            pCmd->i8Result = -1;
+            pCmd->u.i8Result = -1;
     }
     return VINF_SUCCESS;
 }
 
-int32_t crVBoxServerCrCmdNotifyCmds()
-{
-    PVBOXCMDVBVA_HDR pCmd = NULL;
-    uint32_t cbCmd;
-
-    for (;;)
-    {
-        int rc = cr_server.CltInfo.pfnCmdGet(cr_server.CltInfo.hClient, &pCmd, &cbCmd);
-        if (rc == VINF_EOF)
-            return VINF_SUCCESS;
-        if (!RT_SUCCESS(rc))
-            return rc;
-
-        rc = crVBoxServerCrCmdProcess(pCmd, cbCmd);
-        if (!RT_SUCCESS(rc))
-            return rc;
-    }
-
-    /* should not be here! */
-    AssertFailed();
-    return VERR_INTERNAL_ERROR;
-}
-
 /* We moved all CrHgsmi command processing to crserverlib to keep the logic of dealing with CrHgsmi commands in one place.
  *
  * For now we need the notion of CrHgdmi commands in the crserver_lib to be able to complete it asynchronously once it is really processed.
@@ -3272,7 +3408,7 @@ int32_t crVBoxServerCrHgsmiCmd(struct VBOXVDMACMD_CHROMIUM_CMD *pCmd, uint32_t c
 
     if (!g_pvVRamBase)
     {
-        crWarning("g_pvVRamBase is not initialized");
+        WARN(("g_pvVRamBase is not initialized"));
 
         crServerCrHgsmiCmdComplete(pCmd, VERR_INVALID_STATE);
         return VINF_SUCCESS;
@@ -3280,7 +3416,7 @@ int32_t crVBoxServerCrHgsmiCmd(struct VBOXVDMACMD_CHROMIUM_CMD *pCmd, uint32_t c
 
     if (!cBuffers)
     {
-        crWarning("zero buffers passed in!");
+        WARN(("zero buffers passed in!"));
 
         crServerCrHgsmiCmdComplete(pCmd, VERR_INVALID_PARAMETER);
         return VINF_SUCCESS;
@@ -3292,7 +3428,7 @@ int32_t crVBoxServerCrHgsmiCmd(struct VBOXVDMACMD_CHROMIUM_CMD *pCmd, uint32_t c
     pHdr = VBOXCRHGSMI_PTR_SAFE(pCmd->aBuffers[0].offBuffer, cbHdr, CRVBOXHGSMIHDR);
     if (!pHdr)
     {
-        crWarning("invalid header buffer!");
+        WARN(("invalid header buffer!"));
 
         crServerCrHgsmiCmdComplete(pCmd, VERR_INVALID_PARAMETER);
         return VINF_SUCCESS;
@@ -3300,7 +3436,7 @@ int32_t crVBoxServerCrHgsmiCmd(struct VBOXVDMACMD_CHROMIUM_CMD *pCmd, uint32_t c
 
     if (cbHdr < sizeof (*pHdr))
     {
-        crWarning("invalid header buffer size!");
+        WARN(("invalid header buffer size!"));
 
         crServerCrHgsmiCmdComplete(pCmd, VERR_INVALID_PARAMETER);
         return VINF_SUCCESS;
@@ -3595,7 +3731,14 @@ int32_t crVBoxServerCrHgsmiCtl(struct VBOXVDMACMD_CHROMIUM_CTL *pCtl, uint32_t c
             PVBOXVDMACMD_CHROMIUM_CTL_CRHGSMI_SETUP pSetup = (PVBOXVDMACMD_CHROMIUM_CTL_CRHGSMI_SETUP)pCtl;
             g_pvVRamBase = (uint8_t*)pSetup->pvVRamBase;
             g_cbVRam = pSetup->cbVRam;
-            cr_server.CltInfo = *pSetup->pCrCmdClientInfo;
+            pSetup->CrCmdServerInfo.hSvr = NULL;
+            pSetup->CrCmdServerInfo.pfnEnable = crVBoxCrCmdEnable;
+            pSetup->CrCmdServerInfo.pfnDisable = crVBoxCrCmdDisable;
+            pSetup->CrCmdServerInfo.pfnCmd = crVBoxCrCmdCmd;
+            pSetup->CrCmdServerInfo.pfnHostCtl = crVBoxCrCmdHostCtl;
+            pSetup->CrCmdServerInfo.pfnGuestCtl = crVBoxCrCmdGuestCtl;
+            pSetup->CrCmdServerInfo.pfnSaveState = crVBoxCrCmdSaveState;
+            pSetup->CrCmdServerInfo.pfnLoadState = crVBoxCrCmdLoadState;
             rc = VINF_SUCCESS;
             break;
         }
@@ -3628,4 +3771,39 @@ int32_t crVBoxServerCrHgsmiCtl(struct VBOXVDMACMD_CHROMIUM_CTL *pCtl, uint32_t c
     return rc;
 }
 
+int32_t crVBoxServerHgcmEnable(HVBOXCRCMDCTL_REMAINING_HOST_COMMAND hRHCmd, PFNVBOXCRCMDCTL_REMAINING_HOST_COMMAND pfnRHCmd)
+{
+    int rc = VINF_SUCCESS;
+    uint8_t* pCtl;
+    uint32_t cbCtl;
+
+    if (cr_server.numClients)
+    {
+        WARN(("cr_server.numClients(%d) is not NULL", cr_server.numClients));
+        return VERR_INVALID_STATE;
+    }
+
+    for (pCtl = pfnRHCmd(hRHCmd, &cbCtl, rc); pCtl; pCtl = pfnRHCmd(hRHCmd, &cbCtl, rc))
+    {
+        rc = crVBoxCrCmdHostCtl(NULL, pCtl, cbCtl);
+    }
+
+    crVBoxServerDefaultContextSet();
+
+    return VINF_SUCCESS;
+}
+
+int32_t crVBoxServerHgcmDisable()
+{
+    if (cr_server.numClients)
+    {
+        WARN(("cr_server.numClients(%d) is not NULL", cr_server.numClients));
+        return VERR_INVALID_STATE;
+    }
+
+    cr_server.head_spu->dispatch_table.MakeCurrent(0, 0, 0);
+
+    return VINF_SUCCESS;
+}
+
 #endif
diff --git a/src/VBox/HostServices/SharedOpenGL/crserverlib/server_muralfbo.cpp b/src/VBox/HostServices/SharedOpenGL/crserverlib/server_muralfbo.cpp
index e9ae9e7..10cdf5c 100644
--- a/src/VBox/HostServices/SharedOpenGL/crserverlib/server_muralfbo.cpp
+++ b/src/VBox/HostServices/SharedOpenGL/crserverlib/server_muralfbo.cpp
@@ -194,7 +194,6 @@ static int crServerRedirMuralDbSyncFb(CRMuralInfo *mural, HCR_FRAMEBUFFER hFb, C
         for (uint32_t i = 0; i < mural->cBuffers; ++i)
         {
             VBOXVR_TEXTURE Tex;
-            int rc;
             Tex.width = mural->width;
             Tex.height = mural->height;
             Tex.hwid = mural->aidColorTexs[i];
@@ -687,7 +686,8 @@ DECLEXPORT(int) crServerVBoxScreenshotGet(uint32_t u32Screen, uint32_t width, ui
             || pScreen->u32LineSize != pitch
             || pScreen->u16BitsPerPixel != 32)
     {
-        RTRECT Rect;
+        RTRECT SrcRect;
+        RTRECT DstRect;
 
         pScreenshot->Img.cbData = pScreen->u32LineSize * pScreen->u32Height;
         if (!pvBuffer)
@@ -711,11 +711,15 @@ DECLEXPORT(int) crServerVBoxScreenshotGet(uint32_t u32Screen, uint32_t width, ui
         pScreenshot->Img.height = height;
         pScreenshot->Img.bpp = 32;
         pScreenshot->Img.pitch = pitch;
-        Rect.xLeft = 0;
-        Rect.yTop = 0;
-        Rect.xRight = pScreen->u32Width;
-        Rect.yBottom = pScreen->u32Height;
-        int rc = CrFbBltGetContents(hFb, &Rect, 1, &Rect, &pScreenshot->Img);
+        SrcRect.xLeft = 0;
+        SrcRect.yTop = 0;
+        SrcRect.xRight = pScreen->u32Width;
+        SrcRect.yBottom = pScreen->u32Height;
+        DstRect.xLeft = 0;
+        DstRect.yTop = 0;
+        DstRect.xRight = width;
+        DstRect.yBottom = height;
+        int rc = CrFbBltGetContents(hFb, &SrcRect, &DstRect, 1, &DstRect, &pScreenshot->Img);
         if (!RT_SUCCESS(rc))
         {
             WARN(("CrFbBltGetContents failed %d", rc));
diff --git a/src/VBox/HostServices/SharedOpenGL/crserverlib/server_presenter.cpp b/src/VBox/HostServices/SharedOpenGL/crserverlib/server_presenter.cpp
index 49fa537..e1dca82 100644
--- a/src/VBox/HostServices/SharedOpenGL/crserverlib/server_presenter.cpp
+++ b/src/VBox/HostServices/SharedOpenGL/crserverlib/server_presenter.cpp
@@ -247,8 +247,8 @@ static void crFbBltImg(const CR_BLITTER_IMG *pSrc, const RTPOINT *pSrcDataPoint,
     int32_t srcY = pCopyRect->yTop - pSrcDataPoint->y;
     Assert(srcX >= 0);
     Assert(srcY >= 0);
-    Assert(srcX < pSrc->width);
-    Assert(srcY < pSrc->height);
+    Assert(srcX < (int32_t)pSrc->width);
+    Assert(srcY < (int32_t)pSrc->height);
 
     int32_t dstX = pCopyRect->xLeft - pDstDataPoint->x;
     int32_t dstY = pCopyRect->yTop - pDstDataPoint->y;
@@ -258,7 +258,7 @@ static void crFbBltImg(const CR_BLITTER_IMG *pSrc, const RTPOINT *pSrcDataPoint,
     uint8_t *pu8Src = ((uint8_t*)pSrc->pvData) + pSrc->pitch * (!fSrcInvert ? srcY : pSrc->height - srcY - 1) + srcX * 4;
     uint8_t *pu8Dst = ((uint8_t*)pDst->pvData) + pDst->pitch * dstY + dstX * 4;
 
-    crFbBltMem(pu8Src, fSrcInvert ? -pSrc->pitch : pSrc->pitch, pu8Dst, pDst->pitch, pCopyRect->xRight - pCopyRect->xLeft, pCopyRect->yBottom - pCopyRect->yTop);
+    crFbBltMem(pu8Src, fSrcInvert ? -((int32_t)pSrc->pitch) : (int32_t)pSrc->pitch, pu8Dst, pDst->pitch, pCopyRect->xRight - pCopyRect->xLeft, pCopyRect->yBottom - pCopyRect->yTop);
 }
 
 static void crFbBltImgScaled(const CR_BLITTER_IMG *pSrc, const RTPOINT *pSrcDataPoint, bool fSrcInvert, const RTRECT *pCopyRect, const RTPOINT *pDstDataPoint, float strX, float strY, CR_BLITTER_IMG *pDst)
@@ -267,8 +267,8 @@ static void crFbBltImgScaled(const CR_BLITTER_IMG *pSrc, const RTPOINT *pSrcData
     int32_t srcY = pCopyRect->yTop - pSrcDataPoint->y;
     Assert(srcX >= 0);
     Assert(srcY >= 0);
-    Assert(srcX < pSrc->width);
-    Assert(srcY < pSrc->height);
+    Assert(srcX < (int32_t)pSrc->width);
+    Assert(srcY < (int32_t)pSrc->height);
 
     RTPOINT ScaledDtsDataPoint;
     RTRECT ScaledCopyRect;
@@ -315,10 +315,68 @@ static void crFbBltImgScaled(const CR_BLITTER_IMG *pSrc, const RTPOINT *pSrcData
                         ScaledDstWidth,
                         ScaledDstHeight,
                         pu8Src,
-                        fSrcInvert ? -pSrc->pitch : pSrc->pitch,
+                        fSrcInvert ? -((int32_t)pSrc->pitch) : (int32_t)pSrc->pitch,
                         pCopyRect->xRight - pCopyRect->xLeft, pCopyRect->yBottom - pCopyRect->yTop);
 }
 
+static void crFbBltImgScaledRects(const CR_BLITTER_IMG *pSrc, const RTPOINT *pSrcDataPoint, bool fSrcInvert, const RTRECT *pCopyRect, const RTPOINT *pDstDataPoint, float strX, float strY, CR_BLITTER_IMG *pDst)
+{
+    int32_t srcX = pCopyRect->xLeft - pSrcDataPoint->x;
+    int32_t srcY = pCopyRect->yTop - pSrcDataPoint->y;
+    Assert(srcX >= 0);
+    Assert(srcY >= 0);
+
+    RTRECT UnscaledCopyRect;
+    VBoxRectUnscaled(pCopyRect, strX, strY, &UnscaledCopyRect);
+
+    srcX = CR_FLOAT_RCAST(int32_t, srcX / strX);
+    srcY = CR_FLOAT_RCAST(int32_t, srcY / strY);
+
+    int32_t UnscaledSrcWidth = UnscaledCopyRect.xRight - UnscaledCopyRect.xLeft;
+    int32_t delta = (int32_t)pSrc->width - srcX - UnscaledSrcWidth;
+    if (delta < 0)
+        UnscaledSrcWidth += delta;
+
+    if (UnscaledSrcWidth <= 0)
+    {
+        LOG(("UnscaledSrcWidth <= 0"));
+        if (UnscaledSrcWidth < 0)
+            WARN(("src width (%d) < 0", UnscaledSrcWidth));
+        return;
+    }
+
+    int32_t UnscaledSrcHeight = UnscaledCopyRect.yBottom - UnscaledCopyRect.yTop;
+    delta = (int32_t)pSrc->height - srcY - UnscaledSrcHeight;
+    if (delta < 0)
+        UnscaledSrcHeight += delta;
+
+    if (UnscaledSrcHeight <= 0)
+    {
+        LOG(("UnscaledSrcHeight <= 0"));
+        if (UnscaledSrcHeight < 0)
+            WARN(("src height (%d) < 0", UnscaledSrcHeight));
+        return;
+    }
+
+    int32_t dstX = pCopyRect->xLeft - pDstDataPoint->x;
+    int32_t dstY = pCopyRect->yTop - pDstDataPoint->y;
+    Assert(dstX >= 0);
+    Assert(dstY >= 0);
+
+
+    uint8_t *pu8Src = ((uint8_t*)pSrc->pvData) + pSrc->pitch * (!fSrcInvert ? srcY : pSrc->height - srcY - 1) + srcX * 4;
+    uint8_t *pu8Dst = ((uint8_t*)pDst->pvData) + pDst->pitch * dstY + dstX * 4;
+
+    CrBmpScale32(pu8Dst, pDst->pitch,
+                        pCopyRect->xRight - pCopyRect->xLeft,
+                        pCopyRect->yBottom - pCopyRect->yTop,
+                        pu8Src,
+                        fSrcInvert ? -pSrc->pitch : pSrc->pitch,
+                        UnscaledSrcWidth,
+                        UnscaledSrcHeight
+                        );
+}
+
 static void crFbImgFromScreenVram(const VBVAINFOSCREEN *pScreen, void *pvVram, CR_BLITTER_IMG *pImg)
 {
     pImg->pvData = pvVram;
@@ -337,7 +395,7 @@ static void crFbImgFromFb(HCR_FRAMEBUFFER hFb, CR_BLITTER_IMG *pImg)
     crFbImgFromScreenVram(pScreen, pvVram, pImg);
 }
 
-static int crFbBltGetContentsDirect(HCR_FRAMEBUFFER hFb, const RTRECT *pSrcRect, uint32_t cRects, const RTRECT *pRects, CR_BLITTER_IMG *pImg)
+static int crFbBltGetContentsDirect(HCR_FRAMEBUFFER hFb, const RTRECT *pSrcRect, const RTRECT *pDstRect, uint32_t cRects, const RTRECT *pRects, CR_BLITTER_IMG *pImg)
 {
     VBOXVR_LIST List;
     uint32_t c2DRects = 0;
@@ -347,15 +405,17 @@ static int crFbBltGetContentsDirect(HCR_FRAMEBUFFER hFb, const RTRECT *pSrcRect,
     RTPOINT ScaledEntryPoint = {0};
 
     VBOXVR_SCR_COMPOSITOR_CONST_ITERATOR Iter;
-    RTPOINT SrcPoint = {pSrcRect->xLeft, pSrcRect->yTop};
-    float strX = ((float)pImg->width) / (pSrcRect->xRight - pSrcRect->xLeft);
-    float strY = ((float)pImg->height) / (pSrcRect->yBottom - pSrcRect->yTop);
+    int32_t srcWidth = pSrcRect->xRight - pSrcRect->xLeft;
+    int32_t srcHeight = pSrcRect->yBottom - pSrcRect->yTop;
+    int32_t dstWidth = pDstRect->xRight - pDstRect->xLeft;
+    int32_t dstHeight = pDstRect->yBottom - pDstRect->yTop;
 
-    RTPOINT ScaledSrcPoint;
-    ScaledSrcPoint.x = CR_FLOAT_RCAST(int32_t, strX * SrcPoint.x);
-    ScaledSrcPoint.y = CR_FLOAT_RCAST(int32_t, strY * SrcPoint.y);
+    RTPOINT DstPoint = {pDstRect->xLeft, pDstRect->yTop};
+    float strX = ((float)dstWidth) / srcWidth;
+    float strY = ((float)dstHeight) / srcHeight;
+    bool fScale = (dstWidth != srcWidth || dstHeight != srcHeight);
 
-    RTPOINT ZeroPoint = {0, 0};
+    const RTPOINT ZeroPoint = {0, 0};
 
     VBoxVrListInit(&List);
     int rc = VBoxVrListRectsAdd(&List, 1, CrVrScrCompositorRectGet(&hFb->Compositor), NULL);
@@ -387,18 +447,24 @@ static int crFbBltGetContentsDirect(HCR_FRAMEBUFFER hFb, const RTRECT *pSrcRect,
             goto end;
         }
 
-        for (uint32_t i = 0; i < cRects; ++i)
+        for (uint32_t j = 0; j < cRegions; ++j)
         {
-            const RTRECT * pRect = &pRects[i];
-            for (uint32_t j = 0; j < cRegions; ++j)
+            /* rects are in dst coordinates,
+             * while the pReg is in source coords
+             * convert */
+            const RTRECT * pReg = &pRegions[j];
+            RTRECT ScaledReg;
+            /* scale */
+            VBoxRectScaled(pReg, strX, strY, &ScaledReg);
+            /* translate */
+            VBoxRectTranslate(&ScaledReg, pDstRect->xLeft, pDstRect->yTop);
+
+            for (uint32_t i = 0; i < cRects; ++i)
             {
-                const RTRECT * pReg = &pRegions[j];
-                RTRECT Intersection;
-                VBoxRectIntersected(pRect, pReg, &Intersection);
-                if (VBoxRectIsZero(&Intersection))
-                    continue;
+                const RTRECT * pRect = &pRects[i];
 
-                VBoxRectScale(&Intersection, strX, strY);
+                RTRECT Intersection;
+                VBoxRectIntersected(pRect, &ScaledReg, &Intersection);
                 if (VBoxRectIsZero(&Intersection))
                     continue;
 
@@ -454,8 +520,8 @@ static int crFbBltGetContentsDirect(HCR_FRAMEBUFFER hFb, const RTRECT *pSrcRect,
 
                     width = CR_FLOAT_RCAST(uint32_t, strX * pVrTex->width);
                     height = CR_FLOAT_RCAST(uint32_t, strY * pVrTex->height);
-                    ScaledEntryPoint.x = CR_FLOAT_RCAST(int32_t, strX * CrVrScrCompositorEntryRectGet(pEntry)->xLeft);
-                    ScaledEntryPoint.y = CR_FLOAT_RCAST(int32_t, strY * CrVrScrCompositorEntryRectGet(pEntry)->yTop);
+                    ScaledEntryPoint.x = CR_FLOAT_RCAST(int32_t, strX * CrVrScrCompositorEntryRectGet(pEntry)->xLeft) + pDstRect->xLeft;
+                    ScaledEntryPoint.y = CR_FLOAT_RCAST(int32_t, strY * CrVrScrCompositorEntryRectGet(pEntry)->yTop) + pDstRect->yTop;
                 }
 
                 rc = CrTdBltDataAcquireScaled(pTex, GL_BGRA, false, width, height, &pSrcImg);
@@ -467,7 +533,7 @@ static int crFbBltGetContentsDirect(HCR_FRAMEBUFFER hFb, const RTRECT *pSrcRect,
 
                 bool fInvert = !(CrVrScrCompositorEntryFlagsGet(pEntry) & CRBLT_F_INVERT_SRC_YCOORDS);
 
-                crFbBltImg(pSrcImg, &ScaledEntryPoint, fInvert, &Intersection, &ScaledSrcPoint, pImg);
+                crFbBltImg(pSrcImg, &ScaledEntryPoint, fInvert, &Intersection, &ZeroPoint, pImg);
 
                 CrTdBltDataReleaseScaled(pTex, pSrcImg);
             }
@@ -502,36 +568,34 @@ static int crFbBltGetContentsDirect(HCR_FRAMEBUFFER hFb, const RTRECT *pSrcRect,
             goto end;
         }
 
-        RTPOINT Pos = {0};
         const RTRECT *pCompRect = CrVrScrCompositorRectGet(&hFb->Compositor);
 
-        uint32_t fbWidth = (pCompRect->xRight - pCompRect->xLeft);
-        uint32_t fbHeight = pCompRect->yBottom - pCompRect->yTop;
-
-        uint32_t stretchedWidth = CR_FLOAT_RCAST(uint32_t, strX * fbWidth);
-        uint32_t stretchedHeight = CR_FLOAT_RCAST(uint32_t, strY * fbHeight);
-
         CR_BLITTER_IMG FbImg;
 
-        bool fScale = fbWidth != stretchedWidth || fbHeight != stretchedHeight;
-
         crFbImgFromFb(hFb, &FbImg);
 
-        for (uint32_t i = 0; i < cRects; ++i)
+        for (uint32_t j = 0; j < c2DRects; ++j)
         {
-            const RTRECT * pRect = &pRects[i];
-            for (uint32_t j = 0; j < c2DRects; ++j)
+            const RTRECT * p2DRect = &p2DRects[j];
+            RTRECT ScaledReg;
+            /* scale */
+            VBoxRectScaled(p2DRect, strX, strY, &ScaledReg);
+            /* translate */
+            VBoxRectTranslate(&ScaledReg, pDstRect->xLeft, pDstRect->yTop);
+
+            for (uint32_t i = 0; i < cRects; ++i)
             {
-                const RTRECT * p2DRect = &p2DRects[j];
+                const RTRECT * pRect = &pRects[i];
                 RTRECT Intersection;
-                VBoxRectIntersected(pRect, p2DRect, &Intersection);
+
+                VBoxRectIntersected(pRect, &ScaledReg, &Intersection);
                 if (VBoxRectIsZero(&Intersection))
                     continue;
 
                 if (!fScale)
-                    crFbBltImg(&FbImg, &ZeroPoint, false, &Intersection, &SrcPoint, pImg);
+                    crFbBltImg(&FbImg, &DstPoint, false, &Intersection, &ZeroPoint, pImg);
                 else
-                    crFbBltImgScaled(&FbImg, &ZeroPoint, false, &Intersection, &SrcPoint, strX, strY, pImg);
+                    crFbBltImgScaledRects(&FbImg, &DstPoint, false, &Intersection, &ZeroPoint, strX, strY, pImg);
             }
         }
     }
@@ -549,10 +613,21 @@ end:
     return rc;
 }
 
-static int crFbBltGetContentsScaleCPU(HCR_FRAMEBUFFER hFb, const RTRECT *pSrcRect, uint32_t cRects, const RTRECT *pRects, CR_BLITTER_IMG *pImg)
+static int crFbBltGetContentsScaleCPU(HCR_FRAMEBUFFER hFb, const RTRECT *pSrcRect, const RTRECT *pDstRect, uint32_t cRects, const RTRECT *pRects, CR_BLITTER_IMG *pImg)
 {
-    uint32_t srcWidth = pSrcRect->xRight - pSrcRect->xLeft;
-    uint32_t srcHeight = pSrcRect->yBottom - pSrcRect->yTop;
+    int32_t srcWidth = pSrcRect->xRight - pSrcRect->xLeft;
+    int32_t srcHeight = pSrcRect->yBottom - pSrcRect->yTop;
+    int32_t dstWidth = pDstRect->xRight - pDstRect->xLeft;
+    int32_t dstHeight = pDstRect->yBottom - pDstRect->yTop;
+
+    RTPOINT DstPoint = {pDstRect->xLeft, pDstRect->yTop};
+    float strX = ((float)dstWidth) / srcWidth;
+    float strY = ((float)dstHeight) / srcHeight;
+
+    RTRECT DstRect;
+    VBoxRectUnscaled(pDstRect, strX, strY, &DstRect);
+    DstRect.xRight = DstRect.xLeft + srcWidth;
+    DstRect.yBottom = DstRect.yTop + srcHeight;
 
     /* destination is bigger than the source, do 3D data stretching with CPU */
     CR_BLITTER_IMG Img;
@@ -569,7 +644,7 @@ static int crFbBltGetContentsScaleCPU(HCR_FRAMEBUFFER hFb, const RTRECT *pSrcRec
     Img.bpp = pImg->bpp;
     Img.pitch = Img.width * 4;
 
-    int rc = CrFbBltGetContents(hFb, pSrcRect, cRects, pRects, &Img);
+    int rc = CrFbBltGetContents(hFb, pSrcRect, &DstRect, cRects, pRects, &Img);
     if (RT_SUCCESS(rc))
     {
         CrBmpScale32((uint8_t *)pImg->pvData,
@@ -588,21 +663,187 @@ static int crFbBltGetContentsScaleCPU(HCR_FRAMEBUFFER hFb, const RTRECT *pSrcRec
 
 }
 
-int CrFbBltGetContents(HCR_FRAMEBUFFER hFb, const RTRECT *pSrcRect, uint32_t cRects, const RTRECT *pRects, CR_BLITTER_IMG *pImg)
+int CrFbBltGetContents(HCR_FRAMEBUFFER hFb, const RTRECT *pSrcRect, const RTRECT *pDstRect, uint32_t cRects, const RTRECT *pRects, CR_BLITTER_IMG *pImg)
 {
     uint32_t srcWidth = pSrcRect->xRight - pSrcRect->xLeft;
     uint32_t srcHeight = pSrcRect->yBottom - pSrcRect->yTop;
-    if ((srcWidth == pImg->width
-            && srcHeight == pImg->height)
+    uint32_t dstWidth = pDstRect->xRight - pDstRect->xLeft;
+    uint32_t dstHeight = pDstRect->yBottom - pDstRect->yTop;
+    if ((srcWidth == dstWidth
+            && srcHeight == dstHeight)
             || !CrFbHas3DData(hFb)
-            || (srcWidth * srcHeight > pImg->width * pImg->height))
+            || (srcWidth * srcHeight > dstWidth * dstHeight))
     {
-        return crFbBltGetContentsDirect(hFb, pSrcRect, cRects, pRects, pImg);
+        return crFbBltGetContentsDirect(hFb, pSrcRect, pDstRect, cRects, pRects, pImg);
     }
 
-    return crFbBltGetContentsScaleCPU(hFb, pSrcRect, cRects, pRects, pImg);
+    return crFbBltGetContentsScaleCPU(hFb, pSrcRect, pDstRect, cRects, pRects, pImg);
 }
 
+#if 0
+static int crFbBltPutContentsVram(HCR_FRAMEBUFFER hFb, const RTPOINT *pDstPoint, uint32_t cRects, const RTRECT *pRects, CR_BLITTER_IMG *pImg, float strX, float strY)
+{
+    const RTRECT *pCompRect = CrVrScrCompositorRectGet(&hFb->Compositor);
+    const RTPOINT ZeroPoint = {0};
+
+    uint32_t fbWidth = (pCompRect->xRight - pCompRect->xLeft);
+    uint32_t fbHeight = pCompRect->yBottom - pCompRect->yTop;
+
+    uint32_t stretchedWidth = CR_FLOAT_RCAST(uint32_t, strX * fbWidth);
+    uint32_t stretchedHeight = CR_FLOAT_RCAST(uint32_t, strY * fbHeight);
+
+    CR_BLITTER_IMG FbImg;
+
+    bool fScale = fbWidth != stretchedWidth || fbHeight != stretchedHeight;
+
+    crFbImgFromFb(hFb, &FbImg);
+
+    RTRECT Intersection;
+
+    for (uint32_t i = 0; i < cRects; ++i)
+    {
+        const RTRECT * pRect = &pRects[i];
+        VBoxRectIntersected(pRect, pCompRect, &Intersection);
+
+        if (VBoxRectIsZero(&Intersection))
+            continue;
+
+        if (!fScale)
+            crFbBltImg(pImg, pDstPoint, false, &Intersection, &ZeroPoint, &FbImg);
+        else
+            crFbBltImgScaled(pImg, pDstPoint, false, &Intersection, &ZeroPoint, strX, strY, &FbImg);
+    }
+
+    return VINF_SUCCESS;
+}
+
+int CrFbBltPutContents(HCR_FRAMEBUFFER hFb, const RTRECT *pDstRect, uint32_t cRects, const RTRECT *pRects, CR_BLITTER_IMG *pImg)
+{
+    RTPOINT DstPoint = {pDstRect->xLeft, pDstRect->yTop};
+    float strX = ((float)pImg->width) / (pDstRect->xRight - pDstRect->xLeft);
+    float strY = ((float)pImg->height) / (pDstRect->yBottom - pDstRect->yTop);
+
+    int rc = CrFbEntryRegionsAdd(hFb, NULL, const RTPOINT *pPos, cRects, pRects, true)
+    if (!hFb->cUpdating)
+    {
+        WARN(("not updating\n"));
+        return VERR_INVALID_STATE;
+    }
+}
+
+int CrFbBltPutContentsNe(HCR_FRAMEBUFFER hFb, const RTRECT *pDstRect, uint32_t cRects, const RTRECT *pRects, CR_BLITTER_IMG *pImg)
+{
+    uint32_t cCompRects;
+    const RTRECT *pCompRects;
+    int rc = CrVrScrCompositorRegionsGet(&hFb->Compositor, &cCompRects, NULL, NULL, &pCompRects);
+    if (!RT_SUCCESS(rc))
+    {
+        WARN(("CrVrScrCompositorRegionsGet failed rc %d", rc));
+        return rc;
+    }
+
+    bool fRegChanged = false;
+    for (uint32_t i = 0; i < cCompRects; ++i)
+    {
+        const RTRECT *pCompRect = pCompRects[i];
+        for (uint32_t j = 0; j < cRects; ++j)
+        {
+            const RTRECT *pRect = pRects[j];
+            if (VBoxRectIsIntersect(pCompRect, pRect))
+            {
+                fRegChanged = true;
+                break;
+            }
+        }
+    }
+
+    if (fRegChanged)
+    {
+        rc = CrFbUpdateBegin(hFb);
+        if (RT_SUCCESS(rc))
+        {
+            rc = CrFbBltPutContents(hFb, pDstRect, cRects, pRects, pImg);
+            if (!RT_SUCCESS(rc))
+                WARN(("CrFbBltPutContents failed rc %d", rc));
+            CrFbUpdateEnd(hFb);
+        }
+        else
+            WARN(("CrFbUpdateBegin failed rc %d", rc));
+
+        return rc;
+    }
+
+    return crFbBltPutContentsVram(HCR_FRAMEBUFFER hFb, const RTPOINT *pDstPoint, uint32_t cRects, const RTRECT *pRects, CR_BLITTER_IMG *pImg, float strX, float strY);
+
+    const RTPOINT ZeroPoint = {0, 0};
+
+    c2DRects = VBoxVrListRectsCount(&List);
+    if (c2DRects)
+    {
+        if (g_CrPresenter.cbTmpBuf2 < c2DRects * sizeof (RTRECT))
+        {
+            if (g_CrPresenter.pvTmpBuf2)
+                RTMemFree(g_CrPresenter.pvTmpBuf2);
+
+            g_CrPresenter.cbTmpBuf2 = (c2DRects + 10) * sizeof (RTRECT);
+            g_CrPresenter.pvTmpBuf2 = RTMemAlloc(g_CrPresenter.cbTmpBuf2);
+            if (!g_CrPresenter.pvTmpBuf2)
+            {
+                WARN(("RTMemAlloc failed!"));
+                g_CrPresenter.cbTmpBuf2 = 0;
+                rc = VERR_NO_MEMORY;
+                goto end;
+            }
+        }
+
+        RTRECT *p2DRects  = (RTRECT *)g_CrPresenter.pvTmpBuf2;
+
+        rc = VBoxVrListRectsGet(&List, c2DRects, p2DRects);
+        if (!RT_SUCCESS(rc))
+        {
+            WARN(("VBoxVrListRectsGet failed, rc %d", rc));
+            goto end;
+        }
+
+        RTPOINT Pos = {0};
+        const RTRECT *pCompRect = CrVrScrCompositorRectGet(&hFb->Compositor);
+
+        CR_BLITTER_IMG FbImg;
+
+        crFbImgFromFb(hFb, &FbImg);
+
+        for (uint32_t i = 0; i < cRects; ++i)
+        {
+            const RTRECT * pRect = &pRects[i];
+            for (uint32_t j = 0; j < c2DRects; ++j)
+            {
+                const RTRECT * p2DRect = &p2DRects[j];
+                RTRECT Intersection;
+                VBoxRectIntersected(pRect, p2DRect, &Intersection);
+                if (VBoxRectIsZero(&Intersection))
+                    continue;
+
+                if (!fScale)
+                    crFbBltImg(&FbImg, &ZeroPoint, false, &Intersection, &SrcPoint, pImg);
+                else
+                    crFbBltImgScaled(&FbImg, &ZeroPoint, false, &Intersection, &SrcPoint, strX, strY, pImg);
+            }
+        }
+    }
+
+end:
+
+    if (pEnteredTex)
+        CrTdBltLeave(pEnteredTex);
+
+    if (pEnteredBlitter)
+        CrBltLeave(pEnteredBlitter);
+
+    VBoxVrListClear(&List);
+
+    return rc;
+}
+#endif
 
 int CrFbResize(CR_FRAMEBUFFER *pFb, const struct VBVAINFOSCREEN * pScreen, void *pvVRAM)
 {
@@ -3583,7 +3824,7 @@ HCR_FRAMEBUFFER CrPMgrFbGetEnabled(uint32_t idScreen)
 
 static HCR_FRAMEBUFFER crPMgrFbGetNextEnabled(uint32_t i)
 {
-    for (;i < cr_server.screenCount; ++i)
+    for (;i < (uint32_t)cr_server.screenCount; ++i)
     {
         HCR_FRAMEBUFFER hFb = CrPMgrFbGetEnabled(i);
         if (hFb)
@@ -3595,7 +3836,7 @@ static HCR_FRAMEBUFFER crPMgrFbGetNextEnabled(uint32_t i)
 
 static HCR_FRAMEBUFFER crPMgrFbGetNextInitialized(uint32_t i)
 {
-    for (;i < cr_server.screenCount; ++i)
+    for (;i < (uint32_t)cr_server.screenCount; ++i)
     {
         HCR_FRAMEBUFFER hFb = CrPMgrFbGetInitialized(i);
         if (hFb)
@@ -3943,7 +4184,7 @@ int CrPMgrHlpGlblUpdateBegin(CR_FBMAP *pMap)
 /*helper function that calls CrFbUpdateEnd for all framebuffers being updated */
 void CrPMgrHlpGlblUpdateEnd(CR_FBMAP *pMap)
 {
-    for (uint32_t i = 0; i < cr_server.screenCount; ++i)
+    for (uint32_t i = 0; i < (uint32_t)cr_server.screenCount; ++i)
     {
         if (!CrFBmIsSet(pMap, i))
             continue;
@@ -4412,12 +4653,12 @@ int32_t crVBoxServerCrCmdBltProcess(PVBOXCMDVBVA_HDR pCmd, uint32_t cbCmd)
     if (u8Flags & (VBOXCMDVBVA_OPF_ALLOC_DSTPRIMARY | VBOXCMDVBVA_OPF_ALLOC_SRCPRIMARY))
     {
         VBOXCMDVBVA_BLT_PRIMARY *pBlt = (VBOXCMDVBVA_BLT_PRIMARY*)pCmd;
-        uint8_t u8PrimaryID = pBlt->Hdr.u8PrimaryID;
+        uint8_t u8PrimaryID = pBlt->Hdr.u.u8PrimaryID;
         HCR_FRAMEBUFFER hFb = CrPMgrFbGetEnabled(u8PrimaryID);
         if (!hFb)
         {
             WARN(("request to present on disabled framebuffer, ignore"));
-            pCmd->i8Result = -1;
+            pCmd->u.i8Result = -1;
             return VINF_SUCCESS;
         }
 
@@ -4435,7 +4676,7 @@ int32_t crVBoxServerCrCmdBltProcess(PVBOXCMDVBVA_HDR pCmd, uint32_t cbCmd)
             {
                 WARN(("RTMemAlloc failed!"));
                 g_CrPresenter.cbTmpBuf = 0;
-                pCmd->i8Result = -1;
+                pCmd->u.i8Result = -1;
                 return VINF_SUCCESS;
             }
         }
@@ -4455,23 +4696,24 @@ int32_t crVBoxServerCrCmdBltProcess(PVBOXCMDVBVA_HDR pCmd, uint32_t cbCmd)
                 if (u8Flags & VBOXCMDVBVA_OPF_ALLOC_DSTID)
                 {
                     /* TexPresent */
-                    texId = pBlt->alloc.id;
+                    texId = pBlt->alloc.u.id;
                 }
                 else
                 {
-                    VBOXCMDVBVAOFFSET offVRAM = pBlt->alloc.offVRAM;
+                    VBOXCMDVBVAOFFSET offVRAM = pBlt->alloc.u.offVRAM;
                     const VBVAINFOSCREEN *pScreen = CrFbGetScreenInfo(hFb);
                     uint32_t cbScreen = pScreen->u32LineSize * pScreen->u32Height;
                     if (offVRAM >= g_cbVRam
                             || offVRAM + cbScreen >= g_cbVRam)
                     {
                         WARN(("invalid param"));
-                        pCmd->i8Result = -1;
+                        pCmd->u.i8Result = -1;
                         return VINF_SUCCESS;
                     }
 
                     uint8_t *pu8Buf = g_pvVRamBase + offVRAM;
                     texId = 0;
+//                    cr_server.CrCmdClientInfo.pfnCltScrUpdateBegin(cr_server.CrCmdClientInfo.hCltScr);
                     /*todo: notify VGA device to perform updates */
                 }
 
@@ -4481,7 +4723,7 @@ int32_t crVBoxServerCrCmdBltProcess(PVBOXCMDVBVA_HDR pCmd, uint32_t cbCmd)
             {
                 /* blit from one primary to another primary, wow */
                 WARN(("not implemented"));
-                pCmd->i8Result = -1;
+                pCmd->u.i8Result = -1;
                 return VINF_SUCCESS;
             }
         }
@@ -4491,38 +4733,43 @@ int32_t crVBoxServerCrCmdBltProcess(PVBOXCMDVBVA_HDR pCmd, uint32_t cbCmd)
             /* blit from primary to non-primary */
             if (u8Flags & VBOXCMDVBVA_OPF_ALLOC_DSTID)
             {
-                uint32_t texId = pBlt->alloc.id;
+                uint32_t texId = pBlt->alloc.u.id;
                 WARN(("not implemented"));
-                pCmd->i8Result = -1;
+                pCmd->u.i8Result = -1;
                 return VINF_SUCCESS;
             }
             else
             {
-                VBOXCMDVBVAOFFSET offVRAM = pBlt->alloc.offVRAM;
+                VBOXCMDVBVAOFFSET offVRAM = pBlt->alloc.u.offVRAM;
                 const VBVAINFOSCREEN *pScreen = CrFbGetScreenInfo(hFb);
                 uint32_t cbScreen = pScreen->u32LineSize * pScreen->u32Height;
                 if (offVRAM >= g_cbVRam
                         || offVRAM + cbScreen >= g_cbVRam)
                 {
                     WARN(("invalid param"));
-                    pCmd->i8Result = -1;
+                    pCmd->u.i8Result = -1;
                     return VINF_SUCCESS;
                 }
 
                 uint8_t *pu8Buf = g_pvVRamBase + offVRAM;
 
-                RTRECT Rect;
-                Rect.xLeft = pBlt->Pos.x;
-                Rect.yTop = pBlt->Pos.y;
-                Rect.xRight = Rect.xLeft + pScreen->u32Width;
-                Rect.yBottom = Rect.yTop + pScreen->u32Height;
+                RTRECT SrcRect;
+                SrcRect.xLeft = 0;
+                SrcRect.yTop = 0;
+                SrcRect.xRight = pScreen->u32Width;
+                SrcRect.yBottom = pScreen->u32Height;
+                RTRECT DstRect;
+                DstRect.xLeft = pBlt->Pos.x;
+                DstRect.yTop = pBlt->Pos.y;
+                DstRect.xRight = DstRect.xLeft + pScreen->u32Width;
+                DstRect.yBottom = DstRect.yTop + pScreen->u32Height;
                 CR_BLITTER_IMG Img;
                 crFbImgFromScreenVram(pScreen, pu8Buf, &Img);
-                int rc = CrFbBltGetContents(hFb, &Rect, cRects, pRects, &Img);
+                int rc = CrFbBltGetContents(hFb, &SrcRect, &DstRect, cRects, pRects, &Img);
                 if (!RT_SUCCESS(rc))
                 {
                     WARN(("CrFbBltGetContents failed %d", rc));
-                    pCmd->i8Result = -1;
+                    pCmd->u.i8Result = -1;
                     return VINF_SUCCESS;
                 }
             }
@@ -4531,10 +4778,10 @@ int32_t crVBoxServerCrCmdBltProcess(PVBOXCMDVBVA_HDR pCmd, uint32_t cbCmd)
     else
     {
         WARN(("not implemented"));
-        pCmd->i8Result = -1;
+        pCmd->u.i8Result = -1;
         return VINF_SUCCESS;
     }
 
-    pCmd->i8Result = 0;
+    pCmd->u.i8Result = 0;
     return VINF_SUCCESS;
 }
diff --git a/src/VBox/HostServices/SharedOpenGL/crserverlib/server_stream.c b/src/VBox/HostServices/SharedOpenGL/crserverlib/server_stream.c
index bfadeda..2967079 100644
--- a/src/VBox/HostServices/SharedOpenGL/crserverlib/server_stream.c
+++ b/src/VBox/HostServices/SharedOpenGL/crserverlib/server_stream.c
@@ -281,6 +281,28 @@ crServerDeleteClient( CRClient *client )
         pNode->next = cr_server.pCleanupClient;
         cr_server.pCleanupClient = pNode;
     }
+
+    if (!cr_server.numClients)
+    {
+        /* if no clients, the guest driver may be unloaded,
+         * and thus the visible regions situation might not be under control anymore,
+         * so cleanup the 3D framebuffer data here
+         * @todo: what really should happen is that guest driver on unload
+         * posts some request to host that would copy the current framebuffer 3D data to the 2D buffer
+         * (i.e. to the memory used by the standard IFramebuffer API) */
+        HCR_FRAMEBUFFER hFb;
+        for (hFb = CrPMgrFbGetFirstEnabled(); hFb; hFb = CrPMgrFbGetNextEnabled(hFb))
+        {
+            int rc = CrFbUpdateBegin(hFb);
+            if (RT_SUCCESS(rc))
+            {
+                CrFbRegionsClear(hFb);
+                CrFbUpdateEnd(hFb);
+            }
+            else
+                WARN(("CrFbUpdateBegin failed %d", rc));
+        }
+    }
 }
 
 /**
diff --git a/src/VBox/HostServices/SharedOpenGL/crserverlib/server_window.c b/src/VBox/HostServices/SharedOpenGL/crserverlib/server_window.c
index b74c622..6935125 100644
--- a/src/VBox/HostServices/SharedOpenGL/crserverlib/server_window.c
+++ b/src/VBox/HostServices/SharedOpenGL/crserverlib/server_window.c
@@ -18,26 +18,43 @@ crServerDispatchWindowCreate(const char *dpyName, GLint visBits)
     return crServerDispatchWindowCreateEx(dpyName, visBits, -1);
 }
 
-GLint crServerMuralInit(CRMuralInfo *mural, const char *dpyName, GLint visBits, GLint preloadWinID)
+GLint crServerMuralInit(CRMuralInfo *mural, GLboolean fGuestWindow, GLint visBits, GLint preloadWinID)
 {
     CRMuralInfo *defaultMural;
     GLint dims[2];
     GLint windowID = -1;
-    GLint spuWindow;
-    int rc;
+    GLint spuWindow = 0;
     GLint realVisBits = visBits;
+    const char *dpyName = "";
 
     crMemset(mural, 0, sizeof (*mural));
 
     if (cr_server.fVisualBitsDefault)
         realVisBits = cr_server.fVisualBitsDefault;
 
-    /*
-     * Have first SPU make a new window.
-     */
-    spuWindow = cr_server.head_spu->dispatch_table.WindowCreate( dpyName, realVisBits );
-    if (spuWindow < 0) {
-        return spuWindow;
+#ifdef RT_OS_DARWIN
+    if (fGuestWindow)
+    {
+        CRMuralInfo *dummy = crServerGetDummyMural(visBits);
+        if (!dummy)
+        {
+            WARN(("crServerGetDummyMural failed"));
+            return -1;
+        }
+        spuWindow = dummy->spuWindow;
+        mural->fIsDummyRefference = GL_TRUE;
+    }
+    else
+#endif
+    {
+        /*
+         * Have first SPU make a new window.
+         */
+        spuWindow = cr_server.head_spu->dispatch_table.WindowCreate( dpyName, realVisBits );
+        if (spuWindow < 0) {
+            return spuWindow;
+        }
+        mural->fIsDummyRefference = GL_FALSE;
     }
 
     /* get initial window size */
@@ -121,7 +138,7 @@ GLint crServerDispatchWindowCreateEx(const char *dpyName, GLint visBits, GLint p
         return -1;
     }
 
-    windowID = crServerMuralInit(mural, dpyName, visBits, preloadWinID);
+    windowID = crServerMuralInit(mural, GL_TRUE, visBits, preloadWinID);
     if (windowID < 0)
     {
         crWarning("crServerMuralInit failed!");
@@ -181,7 +198,7 @@ void crServerMuralTerm(CRMuralInfo *mural)
          * which might lead to muralFBO (offscreen rendering) gl entities being created in a scope of that context */
         cr_server.head_spu->dispatch_table.MakeCurrent(dummyMural->spuWindow, 0, cr_server.MainContextInfo.SpuContext);
         cr_server.currentWindow = -1;
-        cr_server.currentMural = NULL;
+        cr_server.currentMural = dummyMural;
     }
     else
     {
@@ -202,7 +219,10 @@ void crServerMuralTerm(CRMuralInfo *mural)
     	}
     }
 
-    cr_server.head_spu->dispatch_table.WindowDestroy( mural->spuWindow );
+    if (!mural->fIsDummyRefference)
+        cr_server.head_spu->dispatch_table.WindowDestroy( mural->spuWindow );
+
+    mural->spuWindow = 0;
 
     if (mural->pVisibleRects)
     {
diff --git a/src/VBox/HostServices/SharedOpenGL/render/renderspu_wgl.c b/src/VBox/HostServices/SharedOpenGL/render/renderspu_wgl.c
index 1175b29..1bd745a 100644
--- a/src/VBox/HostServices/SharedOpenGL/render/renderspu_wgl.c
+++ b/src/VBox/HostServices/SharedOpenGL/render/renderspu_wgl.c
@@ -1232,13 +1232,42 @@ GLboolean renderspu_SystemVBoxCreateWindow( VisualInfo *visual, GLboolean showIt
     return GL_TRUE;
 }
 
+static void renderspuWindowRgnApply(WindowInfo *window)
+{
+    HRGN hRgn = window->hRgn;
+    if (hRgn)
+    {
+        /* note: according to the docs, SetWindowRgn owns the regions after it is called,
+         * and the regions will be freed automatically when needed,
+         * i.e. the caller should not do that.
+         * this is why we need to make a copy of the regions to be passed in */
+
+        int result;
+        hRgn = CreateRectRgn(0, 0, 0, 0);
+        if (!hRgn)
+        {
+            WARN(("CreateRectRgn failed"));
+            return;
+        }
+
+        result =  CombineRgn(hRgn, window->hRgn, NULL, RGN_COPY);
+        if (result == ERROR)
+        {
+            WARN(("CombineRgn failed"));
+            return;
+        }
+    }
+
+    SetWindowRgn(window->hWnd, hRgn, true);
+}
+
 /* Either show or hide the render SPU's window. */
 void renderspu_SystemShowWindow( WindowInfo *window, GLboolean showIt )
 {
     if (showIt)
     {
         crDebug("SHOW renderspu_SystemShowWindow: %x", window->hWnd);
-        SetWindowRgn(window->hWnd, window->hRgn, true);
+        renderspuWindowRgnApply(window);
     }
     else
     {
@@ -1246,7 +1275,9 @@ void renderspu_SystemShowWindow( WindowInfo *window, GLboolean showIt )
         crDebug("HIDE renderspu_SystemShowWindow: %x", window->hWnd);
         hRgn = CreateRectRgn(0, 0, 0, 0);
         SetWindowRgn(window->hWnd, hRgn, true);
-        DeleteObject(hRgn);
+        /* note: according to the docs, SetWindowRgn owns the regions after it is called,
+         * and the regions will be freed automatically when needed,
+         * i.e. the caller should not do that */
     }
     window->visible = showIt;
 }
@@ -1571,12 +1602,12 @@ void renderspu_SystemWindowVisibleRegion(WindowInfo *window, GLint cRects, const
         DeleteObject(hTmpRgn);
     }
 
+    window->hRgn = hRgn;
+
     if (window->visible)
-        SetWindowRgn(window->hWnd, hRgn, true);
+        renderspuWindowRgnApply(window);
 
     crDebug("Render SPU: SetWindowRgn (%x, cRects=%i)", window->hWnd, cRects);
-
-    window->hRgn = hRgn;
 }
 
 static void renderspuHandleWindowMessages( HWND hWnd )
diff --git a/src/VBox/Installer/darwin/VirtualBox_mpkg/Localizable.strings b/src/VBox/Installer/darwin/VirtualBox_mpkg/Localizable.strings
index 6831370..0a2e8ee 100644
--- a/src/VBox/Installer/darwin/VirtualBox_mpkg/Localizable.strings
+++ b/src/VBox/Installer/darwin/VirtualBox_mpkg/Localizable.strings
@@ -9,8 +9,8 @@
 'choiceVBoxCLI_title' = '@VBOX_PRODUCT@ Command Line Utilities';
 'choiceVBoxCLI_msg' = 'Installs the @VBOX_PRODUCT@ command line utilities into /usr/bin.';
 
-'RUNNING_VMS_TLE' = "Running VirtualBox VMs detected!";
-'RUNNING_VMS_MSG' = "The installer has detected running Virtual Machines. Please shutdown all running VirtualBox machines and then restart the installation.";
+'RUNNING_VMS_TLE' = "Running VirtualBox virtual machines detected!";
+'RUNNING_VMS_MSG' = "The installer has detected running virtual machines. Please shut down all running VirtualBox machines and then restart the installation.";
 
 'UNSUPPORTED_HW_MACHINE_TLE' = "Unsupported hardware architecture detected!";
 'UNSUPPORTED_HW_MACHINE_MSG' = "The installer has detected an unsupported architecture. VirtualBox only runs on the x86 and amd64 architectures.";
diff --git a/src/VBox/Installer/darwin/VirtualBox_mpkg/distribution.dist b/src/VBox/Installer/darwin/VirtualBox_mpkg/distribution.dist
index 82cd329..3749e35 100644
--- a/src/VBox/Installer/darwin/VirtualBox_mpkg/distribution.dist
+++ b/src/VBox/Installer/darwin/VirtualBox_mpkg/distribution.dist
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <!--
 #
-# Copyright (C) 2008-2012 Oracle Corporation
+# Copyright (C) 2008-2014 Oracle Corporation
 #
 # This file is part of VirtualBox Open Source Edition (OSE), as
 # available from http://www.virtualbox.org. This file is free software;
@@ -18,6 +18,7 @@
     <installation-check script="checkPrerequisite()"></installation-check>
     <domains enable_anywhere="false" enable_currentUserHome="false" enable_localSystem="true"/>
     <script>
+//<![CDATA[
     /* js:pkmk:start */
     function checkPrerequisite()
     {
@@ -53,9 +54,27 @@
 
        try
        {
+           /* The following shell script uses tools which were added in 10.8
+              (Mountain Lion) and later, in particular pgrep and pkill. */
+           if (system.compareVersions(system.version['ProductVersion'], '10.8') >= 0)
+           {
+               /* Embedded scripts are not available here. So, just do a
+                  command line checking if any VBoxXPCOMIPCD has more than one
+                  client, and if there are none, kill all the usual suspects to
+                  get a clean slate. This is done because the VirtualBox event
+                  handling had a bug which allowed no longer present passive
+                  event listeners to block VBoxSVC processes from exiting until
+                  the waiting time was elapsed. In the extreme case this was
+                  infinitely long, blocking updates. */
+               system.run('/bin/sh', '-c', 'pids=`/usr/bin/pgrep VBoxXPCOMIPCD` rc=0; [ -z "$pids" ] && rc=1; for i in $pids; do c=`/usr/sbin/lsof -p $i | /usr/bin/grep -E \'^[^ ]+ +[^ ]+ +[^ ]+ +[^ ]+ +unix\' | wc -l`; [ $c -le 2 ] || rc=1; done; if [ $rc -eq 0 ]; then pkill -KILL \'^(VirtualBox)|(VBoxNetDHCP)|(VBoxNetNAT)|(VBoxHeadless)|(VBoxXPCOMIPCD)|(VBoxSVC)$\'; sleep 1; fi');
+           }
+       } catch (e) { system.log(e); }
+
+       try
+       {
            /* Embedded scripts are not available here. So, just do a command
               line checking for running VMs instead. */
-           rcScript = system.run('/bin/sh', '-c', '/bin/ps -e | /usr/bin/grep -E "VirtualBox.*startvm|VBoxNetDHCP|VBoxNetNAT|VBoxHeadless|VBoxSVC" | /usr/bin/grep -qv grep');
+           rcScript = system.run('/bin/sh', '-c', '/bin/ps -e | /usr/bin/grep -E \'[V]irtualBox.*startvm|[V]BoxNetDHCP|[V]BoxNetNAT|[V]BoxHeadless|[V]BoxSVC\'');
            result = (rcScript != 0);
            system.log("system.run /bin/sh .. returned: " + rcScript + " result=" + result);
        } catch (e) { system.log(e); result = false; }
@@ -72,6 +91,7 @@
        return result;
     }
     /* js:pkmk:end */
+//]]>
     </script>
     <background file="background.tif" alignment="topleft" scaling="none"/>
     <welcome file="Welcome.rtf" mime-type="text/rtf" uti="public.rtf"/>
diff --git a/src/VBox/Installer/linux/run-inst.sh b/src/VBox/Installer/linux/run-inst.sh
index 2d15f90..e196489 100755
--- a/src/VBox/Installer/linux/run-inst.sh
+++ b/src/VBox/Installer/linux/run-inst.sh
@@ -162,7 +162,8 @@ EOF
     for i in $DEFAULT_VERSIONED_FILE_NAMES; do
         rm -f "$i-"* 2> /dev/null
     done
-    rm -f "/usr/lib/$PACKAGE" "/usr/lib64/$PACKAGE" "/usr/share/$PACKAGE"
+    rm -f "/usr/lib/$PACKAGE" "/usr/lib64/$PACKAGE" "/usr/share/$PACKAGE" \
+        "/usr/lib/i386-linux-gnu/$PACKAGE" "/usr/lib/x86_64-linux-gnu/$PACKAGE"
 
     # And any packages left under /opt
     for i in "/opt/$PACKAGE-"*; do
@@ -180,15 +181,11 @@ cpu=`uname -m`;
 case "$cpu" in
   i[3456789]86|x86)
     cpu="x86"
-    lib_path="/usr/lib"
+    lib_candidates="/usr/lib/i386-linux-gnu /usr/lib /lib"
     ;;
   x86_64|amd64)
     cpu="amd64"
-    if test -d "/usr/lib64"; then
-      lib_path="/usr/lib64"
-    else
-      lib_path="/usr/lib"
-    fi
+    lib_candidates="/usr/lib/x86_64-linux-gnu /usr/lib64 /usr/lib /lib64 /lib"
     ;;
   *)
     cpu="unknown"
@@ -198,6 +195,20 @@ if [ ! -r "$ARCH_PACKAGE" ]; then
   info "Detected unsupported $cpu machine type."
   exit 1
 fi
+# Find the most appropriate libary folder by seeing which of the candidate paths
+# are actually in the shared linker path list and choosing the first.  We look
+# for Debian-specific paths first, then LSB ones, then the new RedHat ones.
+libs=`ldconfig -v 2>/dev/null | grep -v ^$'\t'`
+for i in $lib_candidates; do
+  if echo $libs | grep -q $i; then
+    lib_path=$i
+    break
+  fi
+done
+if [ ! -x "$lib_path" ]; then
+  info "Unable to determine correct library path."
+  exit 1
+fi
 
 # Sensible default actions
 ACTION="install"
diff --git a/src/VBox/Main/include/ApplianceImpl.h b/src/VBox/Main/include/ApplianceImpl.h
index 7080d14..937ebbf 100644
--- a/src/VBox/Main/include/ApplianceImpl.h
+++ b/src/VBox/Main/include/ApplianceImpl.h
@@ -264,6 +264,7 @@ struct VirtualSystemDescriptionEntry
     Utf8Str strExtraConfigCurrent;          // extra configuration key=value strings (type-dependent); current value, either from interpret() or setFinalValue()
 
     uint32_t ulSizeMB;                      // hard disk images only: a copy of ovf::DiskImage::ulSuggestedSizeMB
+    bool skipIt;                            ///< used during export to skip some parts if it's needed
 };
 
 class ATL_NO_VTABLE VirtualSystemDescription :
diff --git a/src/VBox/Main/include/ConsoleImpl.h b/src/VBox/Main/include/ConsoleImpl.h
index 220ff7b..5e5cb69 100644
--- a/src/VBox/Main/include/ConsoleImpl.h
+++ b/src/VBox/Main/include/ConsoleImpl.h
@@ -4,7 +4,7 @@
  */
 
 /*
- * Copyright (C) 2005-2013 Oracle Corporation
+ * Copyright (C) 2005-2014 Oracle Corporation
  *
  * This file is part of VirtualBox Open Source Edition (OSE), as
  * available from http://www.virtualbox.org. This file is free software;
@@ -540,6 +540,9 @@ private:
     HRESULT createSharedFolder(const Utf8Str &strName, const SharedFolderData &aData);
     HRESULT removeSharedFolder(const Utf8Str &strName);
 
+    HRESULT suspendBeforeConfigChange(PUVM pUVM, AutoWriteLock *pAlock, bool *pfResume);
+    void    resumeAfterConfigChange(PUVM pUVM);
+
     static DECLCALLBACK(int) configConstructor(PUVM pUVM, PVM pVM, void *pvConsole);
     int configConstructorInner(PUVM pUVM, PVM pVM, AutoWriteLock *pAlock);
     int configCfgmOverlay(PCFGMNODE pRoot, IVirtualBox *pVirtualBox, IMachine *pMachine);
@@ -567,7 +570,8 @@ private:
                                bool fForceUnmount,
                                bool fHotplug,
                                PUVM pUVM,
-                               DeviceType_T *paLedDevType);
+                               DeviceType_T *paLedDevType,
+                               PCFGMNODE *ppLunL0);
     int configMedium(PCFGMNODE pLunL0,
                      bool fPassthrough,
                      DeviceType_T enmType,
@@ -581,7 +585,7 @@ private:
                      IMedium *pMedium,
                      MachineState_T aMachineState,
                      HRESULT *phrc);
-    static DECLCALLBACK(int) reconfigureMediumAttachment(Console *pConsole,
+    static DECLCALLBACK(int) reconfigureMediumAttachment(Console *pThis,
                                                          PUVM pUVM,
                                                          const char *pcszDevice,
                                                          unsigned uInstance,
diff --git a/src/VBox/Main/include/DisplayImpl.h b/src/VBox/Main/include/DisplayImpl.h
index b1239ca..4bc1415 100644
--- a/src/VBox/Main/include/DisplayImpl.h
+++ b/src/VBox/Main/include/DisplayImpl.h
@@ -166,14 +166,15 @@ public:
     int handleVHWACommandProcess(PVBOXVHWACMD pCommand);
 #endif
 #ifdef VBOX_WITH_CRHGSMI
-    int  handleCrCmdNotifyCmds();
     void handleCrHgsmiCommandProcess(PVBOXVDMACMD_CHROMIUM_CMD pCmd, uint32_t cbCmd);
     void handleCrHgsmiControlProcess(PVBOXVDMACMD_CHROMIUM_CTL pCtl, uint32_t cbCtl);
 
     void handleCrHgsmiCommandCompletion(int32_t result, uint32_t u32Function, PVBOXHGCMSVCPARM pParam);
     void handleCrHgsmiControlCompletion(int32_t result, uint32_t u32Function, PVBOXHGCMSVCPARM pParam);
 #endif
-
+    int  handleCrHgcmCtlSubmit(struct VBOXCRCMDCTL* pCmd, uint32_t cbCmd,
+                                        PFNCRCTLCOMPLETION pfnCompletion,
+                                        void *pvCompletion);
 #if defined(VBOX_WITH_HGCM) && defined(VBOX_WITH_CROGL)
     void  handleCrAsyncCmdCompletion(int32_t result, uint32_t u32Function, PVBOXHGCMSVCPARM pParam);
     void  handleCrVRecScreenshotPerform(uint32_t uScreen,
@@ -264,14 +265,17 @@ private:
 #endif
 
 #ifdef VBOX_WITH_CRHGSMI
-    static DECLCALLBACK(int)  displayCrCmdNotifyCmds(PPDMIDISPLAYCONNECTOR pInterface);
     static DECLCALLBACK(void)  displayCrHgsmiCommandProcess(PPDMIDISPLAYCONNECTOR pInterface, PVBOXVDMACMD_CHROMIUM_CMD pCmd, uint32_t cbCmd);
     static DECLCALLBACK(void)  displayCrHgsmiControlProcess(PPDMIDISPLAYCONNECTOR pInterface, PVBOXVDMACMD_CHROMIUM_CTL pCtl, uint32_t cbCtl);
 
     static DECLCALLBACK(void)  displayCrHgsmiCommandCompletion(int32_t result, uint32_t u32Function, PVBOXHGCMSVCPARM pParam, void *pvContext);
     static DECLCALLBACK(void)  displayCrHgsmiControlCompletion(int32_t result, uint32_t u32Function, PVBOXHGCMSVCPARM pParam, void *pvContext);
 #endif
-
+    static DECLCALLBACK(int)  displayCrHgcmCtlSubmit(PPDMIDISPLAYCONNECTOR pInterface,
+                                        struct VBOXCRCMDCTL* pCmd, uint32_t cbCmd,
+                                        PFNCRCTLCOMPLETION pfnCompletion,
+                                        void *pvCompletion);
+    static DECLCALLBACK(void)  displayCrHgcmCtlSubmitCompletion(int32_t result, uint32_t u32Function, PVBOXHGCMSVCPARM pParam, void *pvContext);
 #ifdef VBOX_WITH_HGSMI
     static DECLCALLBACK(int)   displayVBVAEnable(PPDMIDISPLAYCONNECTOR pInterface, unsigned uScreenId, PVBVAHOSTFLAGS pHostFlags);
     static DECLCALLBACK(void)  displayVBVADisable(PPDMIDISPLAYCONNECTOR pInterface, unsigned uScreenId);
diff --git a/src/VBox/Main/include/EventImpl.h b/src/VBox/Main/include/EventImpl.h
index e2979ce..414ce01 100644
--- a/src/VBox/Main/include/EventImpl.h
+++ b/src/VBox/Main/include/EventImpl.h
@@ -144,7 +144,7 @@ public:
     void FinalRelease();
 
     // public initializer/uninitializer for internal purposes only
-    HRESULT init(IUnknown *aParent);
+    HRESULT init();
     void uninit();
 
     // IEventSource methods
diff --git a/src/VBox/Main/include/MachineImpl.h b/src/VBox/Main/include/MachineImpl.h
index cea78f3..0ad4265 100644
--- a/src/VBox/Main/include/MachineImpl.h
+++ b/src/VBox/Main/include/MachineImpl.h
@@ -1219,6 +1219,8 @@ private:
     /** client token for this machine */
     ClientToken *mClientToken;
 
+    int miNATNetworksStarted;
+
     static DECLCALLBACK(int) taskHandler(RTTHREAD thread, void *pvUser);
 };
 
diff --git a/src/VBox/Main/src-all/EventImpl.cpp b/src/VBox/Main/src-all/EventImpl.cpp
index 0d19c3b..820f84b 100644
--- a/src/VBox/Main/src-all/EventImpl.cpp
+++ b/src/VBox/Main/src-all/EventImpl.cpp
@@ -4,7 +4,7 @@
  */
 
 /*
- * Copyright (C) 2010-2012 Oracle Corporation
+ * Copyright (C) 2010-2014 Oracle Corporation
  *
  * This file is part of VirtualBox Open Source Edition (OSE), as
  * available from http://www.virtualbox.org. This file is free software;
@@ -120,7 +120,7 @@ HRESULT VBoxEvent::init(IEventSource *aSource, VBoxEventType_T aType, BOOL aWait
 
             if (RT_FAILURE(vrc))
             {
-                AssertFailed ();
+                AssertFailed();
                 return setError(E_FAIL,
                                 tr("Internal error (%Rrc)"), vrc);
             }
@@ -155,19 +155,21 @@ STDMETHODIMP VBoxEvent::COMGETTER(Type)(VBoxEventType_T *aType)
     CheckComArgNotNull(aType);
 
     AutoCaller autoCaller(this);
-    if (FAILED(autoCaller.rc())) return autoCaller.rc();
+    if (FAILED(autoCaller.rc()))
+        return autoCaller.rc();
 
-    // never  changes till event alive, no locking?
+    // never changes while event alive, no locking
     *aType = m->mType;
     return S_OK;
 }
 
-STDMETHODIMP VBoxEvent::COMGETTER(Source)(IEventSource* *aSource)
+STDMETHODIMP VBoxEvent::COMGETTER(Source)(IEventSource **aSource)
 {
     CheckComArgOutPointerValid(aSource);
 
     AutoCaller autoCaller(this);
-    if (FAILED(autoCaller.rc())) return autoCaller.rc();
+    if (FAILED(autoCaller.rc()))
+        return autoCaller.rc();
 
     m->mSource.queryInterfaceTo(aSource);
     return S_OK;
@@ -178,9 +180,10 @@ STDMETHODIMP VBoxEvent::COMGETTER(Waitable)(BOOL *aWaitable)
     CheckComArgNotNull(aWaitable);
 
     AutoCaller autoCaller(this);
-    if (FAILED(autoCaller.rc())) return autoCaller.rc();
+    if (FAILED(autoCaller.rc()))
+        return autoCaller.rc();
 
-    // never  changes till event alive, no locking?
+    // never changes while event alive, no locking
     *aWaitable = m->mWaitable;
     return S_OK;
 }
@@ -189,7 +192,8 @@ STDMETHODIMP VBoxEvent::COMGETTER(Waitable)(BOOL *aWaitable)
 STDMETHODIMP VBoxEvent::SetProcessed()
 {
     AutoCaller autoCaller(this);
-    if (FAILED(autoCaller.rc())) return autoCaller.rc();
+    if (FAILED(autoCaller.rc()))
+        return autoCaller.rc();
 
     AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
 
@@ -209,7 +213,8 @@ STDMETHODIMP VBoxEvent::WaitProcessed(LONG aTimeout, BOOL *aResult)
     CheckComArgNotNull(aResult);
 
     AutoCaller autoCaller(this);
-    if (FAILED(autoCaller.rc())) return autoCaller.rc();
+    if (FAILED(autoCaller.rc()))
+        return autoCaller.rc();
 
     {
         AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
@@ -249,8 +254,7 @@ STDMETHODIMP VBoxEvent::WaitProcessed(LONG aTimeout, BOOL *aResult)
 typedef std::list<Bstr> VetoList;
 struct VBoxVetoEvent::Data
 {
-    Data()
-        :
+    Data() :
         mVetoed(FALSE)
     {}
     BOOL                    mVetoed;
@@ -281,7 +285,8 @@ HRESULT VBoxVetoEvent::init(IEventSource *aSource, VBoxEventType_T aType)
     HRESULT rc = S_OK;
     // all veto events are waitable
     rc = VBoxEvent::init(aSource, aType, TRUE);
-    if (FAILED(rc)) return rc;
+    if (FAILED(rc))
+        return rc;
 
     m->mVetoed = FALSE;
     m->mVetoList.clear();
@@ -300,7 +305,8 @@ void VBoxVetoEvent::uninit()
 STDMETHODIMP VBoxVetoEvent::AddVeto(IN_BSTR aVeto)
 {
     AutoCaller autoCaller(this);
-    if (FAILED(autoCaller.rc())) return autoCaller.rc();
+    if (FAILED(autoCaller.rc()))
+        return autoCaller.rc();
 
     AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
 
@@ -312,12 +318,13 @@ STDMETHODIMP VBoxVetoEvent::AddVeto(IN_BSTR aVeto)
     return S_OK;
 }
 
-STDMETHODIMP VBoxVetoEvent::IsVetoed(BOOL * aResult)
+STDMETHODIMP VBoxVetoEvent::IsVetoed(BOOL *aResult)
 {
     CheckComArgOutPointerValid(aResult);
 
     AutoCaller autoCaller(this);
-    if (FAILED(autoCaller.rc())) return autoCaller.rc();
+    if (FAILED(autoCaller.rc()))
+        return autoCaller.rc();
 
     AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
 
@@ -326,13 +333,14 @@ STDMETHODIMP VBoxVetoEvent::IsVetoed(BOOL * aResult)
     return S_OK;
 }
 
-STDMETHODIMP  VBoxVetoEvent::GetVetos(ComSafeArrayOut(BSTR, aVetos))
+STDMETHODIMP VBoxVetoEvent::GetVetos(ComSafeArrayOut(BSTR, aVetos))
 {
     if (ComSafeArrayOutIsNull(aVetos))
         return E_POINTER;
 
     AutoCaller autoCaller(this);
-    if (FAILED(autoCaller.rc())) return autoCaller.rc();
+    if (FAILED(autoCaller.rc()))
+        return autoCaller.rc();
 
     AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
     com::SafeArray<BSTR> vetos(m->mVetoList.size());
@@ -351,8 +359,8 @@ STDMETHODIMP  VBoxVetoEvent::GetVetos(ComSafeArrayOut(BSTR, aVetos))
 }
 
 static const int FirstEvent = (int)VBoxEventType_LastWildcard + 1;
-static const int LastEvent  = (int)VBoxEventType_Last;
-static const int NumEvents  = LastEvent - FirstEvent;
+static const int LastEvent = (int)VBoxEventType_Last;
+static const int NumEvents = LastEvent - FirstEvent;
 
 /**
  * Class replacing std::list and able to provide required stability
@@ -367,24 +375,19 @@ public:
      * We have to be double linked, as structural modifications in list are delayed
      * till element removed, so we have to know our previous one to update its next
      */
-    EventMapRecord* mNext;
+    EventMapRecord *mNext;
     bool            mAlive;
 private:
-    EventMapRecord* mPrev;
-    ListenerRecord* mRef; /* must be weak reference */
+    EventMapRecord *mPrev;
+    ListenerRecord *mRef; /* must be weak reference */
     int32_t         mRefCnt;
 
 public:
-    EventMapRecord(ListenerRecord* aRef)
-        :
-        mNext(0),
-        mAlive(true),
-        mPrev(0),
-        mRef(aRef),
-        mRefCnt(1)
+    EventMapRecord(ListenerRecord *aRef) :
+        mNext(0), mAlive(true), mPrev(0), mRef(aRef), mRefCnt(1)
     {}
 
-    EventMapRecord(EventMapRecord& aOther)
+    EventMapRecord(EventMapRecord &aOther)
     {
         mNext = aOther.mNext;
         mPrev = aOther.mPrev;
@@ -408,7 +411,8 @@ public:
 
     void release()
     {
-        if (ASMAtomicDecS32(&mRefCnt) <= 0) delete this;
+        if (ASMAtomicDecS32(&mRefCnt) <= 0)
+            delete this;
     }
 
     // Called when an element is no longer needed
@@ -418,7 +422,7 @@ public:
         release();
     }
 
-    ListenerRecord* ref()
+    ListenerRecord *ref()
     {
         return mAlive ? mRef : 0;
     }
@@ -473,7 +477,7 @@ public:
         EventMapRecord *pCur = mHead;
         while (pCur)
         {
-            EventMapRecord* aNext = pCur->mNext;
+            EventMapRecord *aNext = pCur->mNext;
             if (pCur->ref() == aRec)
             {
                 if (pCur == mHead)
@@ -495,13 +499,13 @@ public:
     {
         EventMapRecord *mCur;
 
-        iterator()
-            : mCur(0)
+        iterator() :
+            mCur(0)
         {}
 
         explicit
-        iterator(EventMapRecord *aCur)
-            : mCur(aCur)
+        iterator(EventMapRecord *aCur) :
+            mCur(aCur)
         {
             // Prevent element removal, till we're at it
             if (mCur)
@@ -539,13 +543,13 @@ public:
         }
 
         bool
-        operator==(const EventMapList::iterator& aOther) const
+        operator==(const EventMapList::iterator &aOther) const
         {
             return mCur == aOther.mCur;
         }
 
         bool
-        operator!=(const EventMapList::iterator& aOther) const
+        operator!=(const EventMapList::iterator &aOther) const
         {
             return mCur != aOther.mCur;
         }
@@ -563,7 +567,7 @@ public:
 };
 
 typedef EventMapList EventMap[NumEvents];
-typedef std::map<IEvent*, int32_t> PendingEventsMap;
+typedef std::map<IEvent *, int32_t> PendingEventsMap;
 typedef std::deque<ComPtr<IEvent> > PassiveQueue;
 
 class ListenerRecord
@@ -571,7 +575,7 @@ class ListenerRecord
 private:
     ComPtr<IEventListener>        mListener;
     BOOL                          mActive;
-    EventSource*                  mOwner;
+    EventSource                  *mOwner;
 
     RTSEMEVENT                    mQEvent;
     RTCRITSECT                    mcsQLock;
@@ -580,24 +584,29 @@ private:
     uint64_t                      mLastRead;
 
 public:
-    ListenerRecord(IEventListener*                    aListener,
-                   com::SafeArray<VBoxEventType_T>&   aInterested,
-                   BOOL                               aActive,
-                   EventSource*                       aOwner);
+    ListenerRecord(IEventListener *aListener,
+                   com::SafeArray<VBoxEventType_T> &aInterested,
+                   BOOL aActive,
+                   EventSource *aOwner);
     ~ListenerRecord();
 
-    HRESULT process(IEvent* aEvent, BOOL aWaitable, PendingEventsMap::iterator& pit, AutoLockBase& alock);
-    HRESULT enqueue(IEvent* aEvent);
-    HRESULT dequeue(IEvent* *aEvent, LONG aTimeout, AutoLockBase& aAlock);
-    HRESULT eventProcessed(IEvent * aEvent, PendingEventsMap::iterator& pit);
+    HRESULT process(IEvent *aEvent, BOOL aWaitable, PendingEventsMap::iterator &pit, AutoLockBase &alock);
+    HRESULT enqueue(IEvent *aEvent);
+    HRESULT dequeue(IEvent **aEvent, LONG aTimeout, AutoLockBase &aAlock);
+    HRESULT eventProcessed(IEvent *aEvent, PendingEventsMap::iterator &pit);
+    void shutdown();
+
     void addRef()
     {
         ASMAtomicIncS32(&mRefCnt);
     }
+
     void release()
     {
-        if (ASMAtomicDecS32(&mRefCnt) <= 0) delete this;
+        if (ASMAtomicDecS32(&mRefCnt) <= 0)
+            delete this;
     }
+
     BOOL isActive()
     {
         return mActive;
@@ -611,15 +620,13 @@ template<typename Held>
 class RecordHolder
 {
 public:
-    RecordHolder(Held* lr)
-    :
-    held(lr)
+    RecordHolder(Held *lr) :
+        held(lr)
     {
         addref();
     }
-    RecordHolder(const RecordHolder& that)
-    :
-    held(that.held)
+    RecordHolder(const RecordHolder &that) :
+        held(that.held)
     {
         addref();
     }
@@ -633,7 +640,7 @@ public:
         release();
     }
 
-    Held* obj()
+    Held *obj()
     {
         return held;
     }
@@ -644,7 +651,7 @@ public:
         return *this;
     }
 private:
-    Held* held;
+    Held *held;
 
     void addref()
     {
@@ -656,7 +663,7 @@ private:
         if (held)
             held->release();
     }
-    void safe_assign (Held *that_p)
+    void safe_assign(Held *that_p)
     {
         if (that_p)
             that_p->addRef();
@@ -665,14 +672,17 @@ private:
     }
 };
 
-typedef std::map<IEventListener*, RecordHolder<ListenerRecord> >  Listeners;
+typedef std::map<IEventListener *, RecordHolder<ListenerRecord> > Listeners;
 
 struct EventSource::Data
 {
-    Data() {}
+    Data() : fShutdown(false)
+    {}
+
     Listeners                     mListeners;
     EventMap                      mEvMap;
     PendingEventsMap              mPendingMap;
+    bool                          fShutdown;
 };
 
 /**
@@ -685,24 +695,22 @@ static BOOL implies(VBoxEventType_T who, VBoxEventType_T what)
         case VBoxEventType_Any:
             return TRUE;
         case VBoxEventType_Vetoable:
-            return     (what == VBoxEventType_OnExtraDataCanChange)
-                    || (what == VBoxEventType_OnCanShowWindow);
+            return    (what == VBoxEventType_OnExtraDataCanChange)
+                   || (what == VBoxEventType_OnCanShowWindow);
         case VBoxEventType_MachineEvent:
-            return     (what == VBoxEventType_OnMachineStateChanged)
-                    || (what == VBoxEventType_OnMachineDataChanged)
-                    || (what == VBoxEventType_OnMachineRegistered)
-                    || (what == VBoxEventType_OnSessionStateChanged)
-                    || (what == VBoxEventType_OnGuestPropertyChanged);
+            return    (what == VBoxEventType_OnMachineStateChanged)
+                   || (what == VBoxEventType_OnMachineDataChanged)
+                   || (what == VBoxEventType_OnMachineRegistered)
+                   || (what == VBoxEventType_OnSessionStateChanged)
+                   || (what == VBoxEventType_OnGuestPropertyChanged);
         case VBoxEventType_SnapshotEvent:
-            return     (what == VBoxEventType_OnSnapshotTaken)
-                    || (what == VBoxEventType_OnSnapshotDeleted)
-                    || (what == VBoxEventType_OnSnapshotChanged)
-                    ;
+            return    (what == VBoxEventType_OnSnapshotTaken)
+                   || (what == VBoxEventType_OnSnapshotDeleted)
+                   || (what == VBoxEventType_OnSnapshotChanged) ;
         case VBoxEventType_InputEvent:
-            return     (what == VBoxEventType_OnKeyboardLedsChanged)
-                    || (what == VBoxEventType_OnMousePointerShapeChanged)
-                    || (what == VBoxEventType_OnMouseCapabilityChanged)
-                    ;
+            return    (what == VBoxEventType_OnKeyboardLedsChanged)
+                   || (what == VBoxEventType_OnMousePointerShapeChanged)
+                   || (what == VBoxEventType_OnMouseCapabilityChanged);
         case VBoxEventType_Invalid:
             return FALSE;
         default:
@@ -712,17 +720,14 @@ static BOOL implies(VBoxEventType_T who, VBoxEventType_T what)
     return who == what;
 }
 
-ListenerRecord::ListenerRecord(IEventListener*                  aListener,
-                               com::SafeArray<VBoxEventType_T>& aInterested,
-                               BOOL                             aActive,
-                               EventSource*                     aOwner)
-    :
-    mActive(aActive),
-    mOwner(aOwner),
-    mRefCnt(0)
+ListenerRecord::ListenerRecord(IEventListener *aListener,
+                               com::SafeArray<VBoxEventType_T> &aInterested,
+                               BOOL aActive,
+                               EventSource *aOwner) :
+    mActive(aActive), mOwner(aOwner), mRefCnt(0)
 {
     mListener = aListener;
-    EventMap* aEvMap = &aOwner->m->mEvMap;
+    EventMap *aEvMap = &aOwner->m->mEvMap;
 
     for (size_t i = 0; i < aInterested.size(); ++i)
     {
@@ -740,12 +745,12 @@ ListenerRecord::ListenerRecord(IEventListener*                  aListener,
     if (!mActive)
     {
         ::RTCritSectInit(&mcsQLock);
-        ::RTSemEventCreate (&mQEvent);
+        ::RTSemEventCreate(&mQEvent);
         mLastRead = RTTimeMilliTS();
     }
     else
     {
-        mQEvent =NIL_RTSEMEVENT;
+        mQEvent = NIL_RTSEMEVENT;
         RT_ZERO(mcsQLock);
         mLastRead = 0;
     }
@@ -754,7 +759,7 @@ ListenerRecord::ListenerRecord(IEventListener*                  aListener,
 ListenerRecord::~ListenerRecord()
 {
     /* Remove references to us from the event map */
-    EventMap* aEvMap = &mOwner->m->mEvMap;
+    EventMap *aEvMap = &mOwner->m->mEvMap;
     for (int j = FirstEvent; j < LastEvent; j++)
     {
         (*aEvMap)[j - FirstEvent].remove(this);
@@ -764,7 +769,7 @@ ListenerRecord::~ListenerRecord()
     {
         // at this moment nobody could add elements to our queue, so we can safely
         // clean it up, otherwise there will be pending events map elements
-        PendingEventsMap* aPem = &mOwner->m->mPendingMap;
+        PendingEventsMap *aPem = &mOwner->m->mPendingMap;
         while (true)
         {
             ComPtr<IEvent> aEvent;
@@ -786,21 +791,21 @@ ListenerRecord::~ListenerRecord()
         }
 
         ::RTCritSectDelete(&mcsQLock);
-        ::RTSemEventDestroy(mQEvent);
     }
+    shutdown();
 }
 
-HRESULT ListenerRecord::process(IEvent*                     aEvent,
-                                BOOL                        aWaitable,
-                                PendingEventsMap::iterator& pit,
-                                AutoLockBase&               aAlock)
+HRESULT ListenerRecord::process(IEvent *aEvent,
+                                BOOL aWaitable,
+                                PendingEventsMap::iterator &pit,
+                                AutoLockBase &aAlock)
 {
     if (mActive)
     {
         /*
          * We release lock here to allow modifying ops on EventSource inside callback.
          */
-        HRESULT rc =  S_OK;
+        HRESULT rc = S_OK;
         if (mListener)
         {
             aAlock.release();
@@ -818,7 +823,7 @@ HRESULT ListenerRecord::process(IEvent*                     aEvent,
 }
 
 
-HRESULT ListenerRecord::enqueue (IEvent* aEvent)
+HRESULT ListenerRecord::enqueue(IEvent *aEvent)
 {
     AssertMsg(!mActive, ("must be passive\n"));
 
@@ -829,7 +834,7 @@ HRESULT ListenerRecord::enqueue (IEvent* aEvent)
     // and events keep coming, or queue is oversized we shall unregister this listener.
     uint64_t sinceRead = RTTimeMilliTS() - mLastRead;
     size_t queueSize = mQueue.size();
-    if ( (queueSize > 1000) || ((queueSize > 500) && (sinceRead > 60 * 1000)))
+    if ((queueSize > 1000) || ((queueSize > 500) && (sinceRead > 60 * 1000)))
     {
         ::RTCritSectLeave(&mcsQLock);
         return E_ABORT;
@@ -845,15 +850,15 @@ HRESULT ListenerRecord::enqueue (IEvent* aEvent)
 
     ::RTCritSectLeave(&mcsQLock);
 
-     // notify waiters
+    // notify waiters
     ::RTSemEventSignal(mQEvent);
 
     return S_OK;
 }
 
-HRESULT ListenerRecord::dequeue (IEvent*       *aEvent,
-                                 LONG          aTimeout,
-                                 AutoLockBase& aAlock)
+HRESULT ListenerRecord::dequeue(IEvent **aEvent,
+                                LONG aTimeout,
+                                AutoLockBase &aAlock)
 {
     if (mActive)
         return VBOX_E_INVALID_OBJECT_STATE;
@@ -865,7 +870,8 @@ HRESULT ListenerRecord::dequeue (IEvent*       *aEvent,
 
     mLastRead = RTTimeMilliTS();
 
-    if (mQueue.empty())    {
+    if (mQueue.empty())
+    {
         ::RTCritSectLeave(&mcsQLock);
         // Speed up common case
         if (aTimeout == 0)
@@ -893,7 +899,7 @@ HRESULT ListenerRecord::dequeue (IEvent*       *aEvent,
     return S_OK;
 }
 
-HRESULT ListenerRecord::eventProcessed (IEvent* aEvent, PendingEventsMap::iterator& pit)
+HRESULT ListenerRecord::eventProcessed(IEvent *aEvent, PendingEventsMap::iterator &pit)
 {
     if (--pit->second == 0)
     {
@@ -905,6 +911,16 @@ HRESULT ListenerRecord::eventProcessed (IEvent* aEvent, PendingEventsMap::iterat
     return S_OK;
 }
 
+void ListenerRecord::shutdown()
+{
+    if (mQEvent != NIL_RTSEMEVENT)
+    {
+        RTSEMEVENT tmp = mQEvent;
+        mQEvent = NIL_RTSEMEVENT;
+        ::RTSemEventDestroy(tmp);
+    }
+}
+
 EventSource::EventSource()
 {}
 
@@ -924,7 +940,7 @@ void EventSource::FinalRelease()
     BaseFinalRelease();
 }
 
-HRESULT EventSource::init(IUnknown *)
+HRESULT EventSource::init()
 {
     HRESULT rc = S_OK;
 
@@ -938,32 +954,58 @@ HRESULT EventSource::init(IUnknown *)
 
 void EventSource::uninit()
 {
+    {
+        // First of all (before even thinking about entering the uninit span):
+        // make sure that all listeners are are shut down (no pending events or
+        // wait calls), because they cannot be alive without the associated
+        // event source. Otherwise API clients which use long-term (or
+        // indefinite) waits will block VBoxSVC termination (just one example)
+        // for a long time or even infinitely long.
+        AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
+        if (!m->fShutdown)
+        {
+            m->fShutdown = true;
+            for (Listeners::iterator it = m->mListeners.begin();
+                 it != m->mListeners.end();
+                 ++it)
+            {
+                it->second.obj()->shutdown();
+            }
+        }
+    }
+
     AutoUninitSpan autoUninitSpan(this);
     if (autoUninitSpan.uninitDone())
         return;
+
     m->mListeners.clear();
     // m->mEvMap shall be cleared at this point too by destructors, assert?
 }
 
-STDMETHODIMP EventSource::RegisterListener(IEventListener * aListener,
+STDMETHODIMP EventSource::RegisterListener(IEventListener *aListener,
                                            ComSafeArrayIn(VBoxEventType_T, aInterested),
-                                           BOOL             aActive)
+                                           BOOL aActive)
 {
     CheckComArgNotNull(aListener);
     CheckComArgSafeArrayNotNull(aInterested);
 
     AutoCaller autoCaller(this);
-    if (FAILED(autoCaller.rc())) return autoCaller.rc();
+    if (FAILED(autoCaller.rc()))
+        return autoCaller.rc();
 
     {
         AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
 
+        if (m->fShutdown)
+            return setError(VBOX_E_INVALID_OBJECT_STATE,
+                            tr("This event source is already shut down"));
+
         Listeners::const_iterator it = m->mListeners.find(aListener);
         if (it != m->mListeners.end())
             return setError(E_INVALIDARG,
                             tr("This listener already registered"));
 
-        com::SafeArray<VBoxEventType_T> interested(ComSafeArrayInArg (aInterested));
+        com::SafeArray<VBoxEventType_T> interested(ComSafeArrayInArg(aInterested));
         RecordHolder<ListenerRecord> lrh(new ListenerRecord(aListener, interested, aActive, this));
         m->mListeners.insert(Listeners::value_type(aListener, lrh));
     }
@@ -975,12 +1017,13 @@ STDMETHODIMP EventSource::RegisterListener(IEventListener * aListener,
     return S_OK;
 }
 
-STDMETHODIMP EventSource::UnregisterListener(IEventListener * aListener)
+STDMETHODIMP EventSource::UnregisterListener(IEventListener *aListener)
 {
     CheckComArgNotNull(aListener);
 
     AutoCaller autoCaller(this);
-    if (FAILED(autoCaller.rc())) return autoCaller.rc();
+    if (FAILED(autoCaller.rc()))
+        return autoCaller.rc();
 
     HRESULT rc;
     {
@@ -990,6 +1033,7 @@ STDMETHODIMP EventSource::UnregisterListener(IEventListener * aListener)
 
         if (it != m->mListeners.end())
         {
+            it->second.obj()->shutdown();
             m->mListeners.erase(it);
             // destructor removes refs from the event map
             rc = S_OK;
@@ -1011,15 +1055,16 @@ STDMETHODIMP EventSource::UnregisterListener(IEventListener * aListener)
     return rc;
 }
 
-STDMETHODIMP EventSource::FireEvent(IEvent * aEvent,
-                                    LONG     aTimeout,
-                                    BOOL     *aProcessed)
+STDMETHODIMP EventSource::FireEvent(IEvent *aEvent,
+                                    LONG aTimeout,
+                                    BOOL *aProcessed)
 {
     CheckComArgNotNull(aEvent);
     CheckComArgOutPointerValid(aProcessed);
 
     AutoCaller autoCaller(this);
-    if (FAILED(autoCaller.rc())) return autoCaller.rc();
+    if (FAILED(autoCaller.rc()))
+        return autoCaller.rc();
 
     HRESULT hrc;
     BOOL aWaitable = FALSE;
@@ -1028,6 +1073,10 @@ STDMETHODIMP EventSource::FireEvent(IEvent * aEvent,
     do {
         AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
 
+        if (m->fShutdown)
+            return setError(VBOX_E_INVALID_OBJECT_STATE,
+                            tr("This event source is already shut down"));
+
         VBoxEventType_T evType;
         hrc = aEvent->COMGETTER(Type)(&evType);
         AssertComRCReturn(hrc, hrc);
@@ -1074,7 +1123,10 @@ STDMETHODIMP EventSource::FireEvent(IEvent * aEvent,
             {
                 Listeners::iterator lit = m->mListeners.find(record.obj()->mListener);
                 if (lit != m->mListeners.end())
+                {
+                    lit->second.obj()->shutdown();
                     m->mListeners.erase(lit);
+                }
             }
             // anything else to do with cbRc?
         }
@@ -1090,18 +1142,23 @@ STDMETHODIMP EventSource::FireEvent(IEvent * aEvent,
 }
 
 
-STDMETHODIMP EventSource::GetEvent(IEventListener * aListener,
-                                   LONG             aTimeout,
-                                   IEvent  **       aEvent)
+STDMETHODIMP EventSource::GetEvent(IEventListener *aListener,
+                                   LONG aTimeout,
+                                   IEvent **aEvent)
 {
 
     CheckComArgNotNull(aListener);
 
     AutoCaller autoCaller(this);
-    if (FAILED(autoCaller.rc())) return autoCaller.rc();
+    if (FAILED(autoCaller.rc()))
+        return autoCaller.rc();
 
     AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
 
+    if (m->fShutdown)
+        return setError(VBOX_E_INVALID_OBJECT_STATE,
+                        tr("This event source is already shut down"));
+
     Listeners::iterator it = m->mListeners.find(aListener);
     HRESULT rc;
 
@@ -1117,17 +1174,22 @@ STDMETHODIMP EventSource::GetEvent(IEventListener * aListener,
     return rc;
 }
 
-STDMETHODIMP EventSource::EventProcessed(IEventListener * aListener,
-                                         IEvent *         aEvent)
+STDMETHODIMP EventSource::EventProcessed(IEventListener *aListener,
+                                         IEvent *aEvent)
 {
     CheckComArgNotNull(aListener);
     CheckComArgNotNull(aEvent);
 
     AutoCaller autoCaller(this);
-    if (FAILED(autoCaller.rc())) return autoCaller.rc();
+    if (FAILED(autoCaller.rc()))
+        return autoCaller.rc();
 
     AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
 
+    if (m->fShutdown)
+        return setError(VBOX_E_INVALID_OBJECT_STATE,
+                        tr("This event source is already shut down"));
+
     Listeners::iterator it = m->mListeners.find(aListener);
     HRESULT rc;
 
@@ -1136,11 +1198,11 @@ STDMETHODIMP EventSource::EventProcessed(IEventListener * aListener,
 
     if (it != m->mListeners.end())
     {
-        ListenerRecord* aRecord = it->second.obj();
+        ListenerRecord *aRecord = it->second.obj();
 
         if (aRecord->isActive())
             return setError(E_INVALIDARG,
-                        tr("Only applicable to passive listeners"));
+                            tr("Only applicable to passive listeners"));
 
         if (aWaitable)
         {
@@ -1246,14 +1308,14 @@ public:
         BaseFinalRelease();
     }
 
-    HRESULT init(IEventSource* aSource)
+    HRESULT init(IEventSource *aSource)
     {
         mSource = aSource;
         return S_OK;
     }
 
     // IEventListener methods
-    STDMETHOD(HandleEvent)(IEvent * aEvent)
+    STDMETHOD(HandleEvent)(IEvent *aEvent)
     {
         BOOL fProcessed = FALSE;
         if (mSource)
@@ -1269,7 +1331,7 @@ class ATL_NO_VTABLE EventSourceAggregator :
 {
     typedef std::list <ComPtr<IEventSource> > EventSourceList;
     /* key is weak reference */
-    typedef std::map<IEventListener*, ComPtr<IEventListener> > ProxyListenerMap;
+    typedef std::map<IEventListener *, ComPtr<IEventListener> > ProxyListenerMap;
 
     EventSourceList           mEventSources;
     ProxyListenerMap          mListenerProxies;
@@ -1308,28 +1370,28 @@ public:
     HRESULT init(ComSafeArrayIn(IEventSource *, aSources));
 
     // IEventSource methods
-    STDMETHOD(CreateListener)(IEventListener ** aListener);
-    STDMETHOD(CreateAggregator)(ComSafeArrayIn(IEventSource*, aSubordinates),
-                                IEventSource **               aAggregator);
-    STDMETHOD(RegisterListener)(IEventListener * aListener,
+    STDMETHOD(CreateListener)(IEventListener **aListener);
+    STDMETHOD(CreateAggregator)(ComSafeArrayIn(IEventSource *, aSubordinates),
+                                IEventSource **aAggregator);
+    STDMETHOD(RegisterListener)(IEventListener *aListener,
                                 ComSafeArrayIn(VBoxEventType_T, aInterested),
-                                BOOL             aActive);
-    STDMETHOD(UnregisterListener)(IEventListener * aListener);
-    STDMETHOD(FireEvent)(IEvent * aEvent,
-                         LONG     aTimeout,
-                         BOOL     *aProcessed);
-    STDMETHOD(GetEvent)(IEventListener * aListener,
-                        LONG      aTimeout,
-                        IEvent  * *aEvent);
-    STDMETHOD(EventProcessed)(IEventListener * aListener,
-                              IEvent *         aEvent);
+                                BOOL aActive);
+    STDMETHOD(UnregisterListener)(IEventListener *aListener);
+    STDMETHOD(FireEvent)(IEvent *aEvent,
+                         LONG aTimeout,
+                         BOOL *aProcessed);
+    STDMETHOD(GetEvent)(IEventListener *aListener,
+                        LONG aTimeout,
+                        IEvent **aEvent);
+    STDMETHOD(EventProcessed)(IEventListener *aListener,
+                              IEvent *aEvent);
 
   protected:
-    HRESULT createProxyListener(IEventListener * aListener,
-                                IEventListener * *aProxy);
-    HRESULT getProxyListener   (IEventListener * aListener,
-                                IEventListener * *aProxy);
-    HRESULT removeProxyListener(IEventListener * aListener);
+    HRESULT createProxyListener(IEventListener *aListener,
+                                IEventListener **aProxy);
+    HRESULT getProxyListener(IEventListener *aListener,
+                             IEventListener **aProxy);
+    HRESULT removeProxyListener(IEventListener *aListener);
 };
 
 #ifdef VBOX_WITH_XPCOM
@@ -1348,12 +1410,13 @@ NS_IMPL_THREADSAFE_ISUPPORTS1_CI(EventSourceAggregator, IEventSource)
 #endif
 
 
-STDMETHODIMP EventSource::CreateListener(IEventListener ** aListener)
+STDMETHODIMP EventSource::CreateListener(IEventListener **aListener)
 {
     CheckComArgOutPointerValid(aListener);
 
     AutoCaller autoCaller(this);
-    if (FAILED(autoCaller.rc())) return autoCaller.rc();
+    if (FAILED(autoCaller.rc()))
+        return autoCaller.rc();
 
     ComObjPtr<PassiveEventListener> listener;
 
@@ -1365,13 +1428,14 @@ STDMETHODIMP EventSource::CreateListener(IEventListener ** aListener)
 }
 
 
-STDMETHODIMP EventSource::CreateAggregator(ComSafeArrayIn(IEventSource*, aSubordinates),
-                                           IEventSource **               aResult)
+STDMETHODIMP EventSource::CreateAggregator(ComSafeArrayIn(IEventSource *, aSubordinates),
+                                           IEventSource **aResult)
 {
     CheckComArgOutPointerValid(aResult);
 
     AutoCaller autoCaller(this);
-    if (FAILED(autoCaller.rc())) return autoCaller.rc();
+    if (FAILED(autoCaller.rc()))
+        return autoCaller.rc();
 
     ComObjPtr<EventSourceAggregator> agg;
 
@@ -1383,12 +1447,11 @@ STDMETHODIMP EventSource::CreateAggregator(ComSafeArrayIn(IEventSource*, aSubord
     if (FAILED(rc))
         return rc;
 
-
     agg.queryInterfaceTo(aResult);
     return S_OK;
 }
 
-HRESULT  EventSourceAggregator::init(ComSafeArrayIn(IEventSource*, aSourcesIn))
+HRESULT EventSourceAggregator::init(ComSafeArrayIn(IEventSource *, aSourcesIn))
 {
     HRESULT rc;
 
@@ -1398,7 +1461,7 @@ HRESULT  EventSourceAggregator::init(ComSafeArrayIn(IEventSource*, aSourcesIn))
     rc = mSource.createObject();
     ComAssertMsgRet(SUCCEEDED(rc), ("Could not create source (%Rhrc)", rc),
                     E_FAIL);
-    rc = mSource->init((IEventSource*)this);
+    rc = mSource->init();
     ComAssertMsgRet(SUCCEEDED(rc), ("Could not init source (%Rhrc)", rc),
                     E_FAIL);
 
@@ -1418,26 +1481,27 @@ HRESULT  EventSourceAggregator::init(ComSafeArrayIn(IEventSource*, aSourcesIn))
     return rc;
 }
 
-STDMETHODIMP EventSourceAggregator::CreateListener(IEventListener ** aListener)
+STDMETHODIMP EventSourceAggregator::CreateListener(IEventListener **aListener)
 {
     return mSource->CreateListener(aListener);
 }
 
-STDMETHODIMP EventSourceAggregator::CreateAggregator(ComSafeArrayIn(IEventSource*, aSubordinates),
-                                                     IEventSource **               aResult)
+STDMETHODIMP EventSourceAggregator::CreateAggregator(ComSafeArrayIn(IEventSource *, aSubordinates),
+                                                     IEventSource **aResult)
 {
     return mSource->CreateAggregator(ComSafeArrayInArg(aSubordinates), aResult);
 }
 
-STDMETHODIMP EventSourceAggregator::RegisterListener(IEventListener * aListener,
+STDMETHODIMP EventSourceAggregator::RegisterListener(IEventListener *aListener,
                                                      ComSafeArrayIn(VBoxEventType_T, aInterested),
-                                                     BOOL             aActive)
+                                                     BOOL aActive)
 {
     CheckComArgNotNull(aListener);
     CheckComArgSafeArrayNotNull(aInterested);
 
     AutoCaller autoCaller(this);
-    if (FAILED(autoCaller.rc())) return autoCaller.rc();
+    if (FAILED(autoCaller.rc()))
+        return autoCaller.rc();
 
     HRESULT rc;
 
@@ -1462,12 +1526,13 @@ STDMETHODIMP EventSourceAggregator::RegisterListener(IEventListener * aListener,
     return rc;
 }
 
-STDMETHODIMP EventSourceAggregator::UnregisterListener(IEventListener * aListener)
+STDMETHODIMP EventSourceAggregator::UnregisterListener(IEventListener *aListener)
 {
     CheckComArgNotNull(aListener);
 
     AutoCaller autoCaller(this);
-    if (FAILED(autoCaller.rc())) return autoCaller.rc();
+    if (FAILED(autoCaller.rc()))
+        return autoCaller.rc();
 
     HRESULT rc = S_OK;
 
@@ -1490,19 +1555,20 @@ STDMETHODIMP EventSourceAggregator::UnregisterListener(IEventListener * aListene
 
 }
 
-STDMETHODIMP EventSourceAggregator::FireEvent(IEvent * aEvent,
-                                              LONG     aTimeout,
-                                              BOOL     *aProcessed)
+STDMETHODIMP EventSourceAggregator::FireEvent(IEvent *aEvent,
+                                              LONG aTimeout,
+                                              BOOL *aProcessed)
 {
     CheckComArgNotNull(aEvent);
     CheckComArgOutPointerValid(aProcessed);
 
     AutoCaller autoCaller(this);
-    if (FAILED(autoCaller.rc())) return autoCaller.rc();
+    if (FAILED(autoCaller.rc()))
+        return autoCaller.rc();
 
     HRESULT rc = S_OK;
     AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
-    /* Aggresgator event source shalln't have direct event firing, but we may
+    /* Aggregator event source shall not have direct event firing, but we may
        wish to support aggregation chains */
     for (EventSourceList::const_iterator it = mEventSources.begin(); it != mEventSources.end();
          ++it)
@@ -1517,21 +1583,21 @@ STDMETHODIMP EventSourceAggregator::FireEvent(IEvent * aEvent,
     return S_OK;
 }
 
-STDMETHODIMP EventSourceAggregator::GetEvent(IEventListener * aListener,
-                                             LONG             aTimeout,
-                                             IEvent  **       aEvent)
+STDMETHODIMP EventSourceAggregator::GetEvent(IEventListener *aListener,
+                                             LONG aTimeout,
+                                             IEvent **aEvent)
 {
     return mSource->GetEvent(aListener, aTimeout, aEvent);
 }
 
-STDMETHODIMP EventSourceAggregator::EventProcessed(IEventListener * aListener,
-                                                   IEvent *         aEvent)
+STDMETHODIMP EventSourceAggregator::EventProcessed(IEventListener *aListener,
+                                                   IEvent *aEvent)
 {
     return mSource->EventProcessed(aListener, aEvent);
 }
 
-HRESULT EventSourceAggregator::createProxyListener(IEventListener * aListener,
-                                                   IEventListener * *aProxy)
+HRESULT EventSourceAggregator::createProxyListener(IEventListener *aListener,
+                                                   IEventListener **aProxy)
 {
     ComObjPtr<ProxyEventListener> proxy;
 
@@ -1554,8 +1620,8 @@ HRESULT EventSourceAggregator::createProxyListener(IEventListener * aListener,
     return S_OK;
 }
 
-HRESULT EventSourceAggregator::getProxyListener(IEventListener * aListener,
-                                                IEventListener * *aProxy)
+HRESULT EventSourceAggregator::getProxyListener(IEventListener *aListener,
+                                                IEventListener **aProxy)
 {
     ProxyListenerMap::const_iterator it = mListenerProxies.find(aListener);
     if (it == mListenerProxies.end())
@@ -1566,7 +1632,7 @@ HRESULT EventSourceAggregator::getProxyListener(IEventListener * aListener,
     return S_OK;
 }
 
-HRESULT EventSourceAggregator::removeProxyListener(IEventListener * aListener)
+HRESULT EventSourceAggregator::removeProxyListener(IEventListener *aListener)
 {
     ProxyListenerMap::iterator it = mListenerProxies.find(aListener);
     if (it == mListenerProxies.end())
diff --git a/src/VBox/Main/src-client/ConsoleImpl.cpp b/src/VBox/Main/src-client/ConsoleImpl.cpp
index 78d97f7..d0c74c2 100644
--- a/src/VBox/Main/src-client/ConsoleImpl.cpp
+++ b/src/VBox/Main/src-client/ConsoleImpl.cpp
@@ -4,7 +4,7 @@
  */
 
 /*
- * Copyright (C) 2005-2013 Oracle Corporation
+ * Copyright (C) 2005-2014 Oracle Corporation
  *
  * This file is part of VirtualBox Open Source Edition (OSE), as
  * available from http://www.virtualbox.org. This file is free software;
@@ -489,7 +489,7 @@ HRESULT Console::init(IMachine *aMachine, IInternalMachineControl *aControl, Loc
 
     // Event source may be needed by other children
     unconst(mEventSource).createObject();
-    rc = mEventSource->init(static_cast<IConsole*>(this));
+    rc = mEventSource->init();
     AssertComRCReturnRC(rc);
 
     mcAudioRefs = 0;
@@ -2394,7 +2394,7 @@ HRESULT Console::doCPURemove(ULONG aCpu, PUVM pUVM)
          */
         PVMREQ pReq;
         vrc = VMR3ReqCallU(pUVM, 0, &pReq, 0 /* no wait! */, VMREQFLAGS_VBOX_STATUS,
-                           (PFNRT)Console::unplugCpu, 3,
+                           (PFNRT)unplugCpu, 3,
                            this, pUVM, (VMCPUID)aCpu);
         if (vrc == VERR_TIMEOUT || RT_SUCCESS(vrc))
         {
@@ -2500,7 +2500,7 @@ HRESULT Console::doCPUAdd(ULONG aCpu, PUVM pUVM)
      */
     PVMREQ pReq;
     int vrc = VMR3ReqCallU(pUVM, 0, &pReq, 0 /* no wait! */, VMREQFLAGS_VBOX_STATUS,
-                           (PFNRT)Console::plugCpu, 3,
+                           (PFNRT)plugCpu, 3,
                            this, pUVM, aCpu);
 
     /* release the lock before a VMR3* call (EMT will call us back)! */
@@ -3505,6 +3505,83 @@ HRESULT Console::convertBusPortDeviceToLun(StorageBus_T enmBus, LONG port, LONG
 
 // private methods
 /////////////////////////////////////////////////////////////////////////////
+    
+/**
+ * Suspend the VM before we do any medium or network attachment change.
+ *
+ * @param pUVM              Safe VM handle.
+ * @param pAlock            The automatic lock instance. This is for when we have
+ *                          to leave it in order to avoid deadlocks.
+ * @param pfSuspend         where to store the information if we need to resume
+ *                          afterwards.
+ */
+HRESULT Console::suspendBeforeConfigChange(PUVM pUVM, AutoWriteLock *pAlock, bool *pfResume)
+{
+    *pfResume = false;
+    VMSTATE enmVMState = VMR3GetStateU(pUVM);
+    switch (enmVMState)
+    {
+        case VMSTATE_RESETTING:
+        case VMSTATE_RUNNING:
+        {
+            LogFlowFunc(("Suspending the VM...\n"));
+            /* disable the callback to prevent Console-level state change */
+            mVMStateChangeCallbackDisabled = true;
+            if (pAlock)
+                pAlock->release();
+            int rc = VMR3Suspend(pUVM, VMSUSPENDREASON_RECONFIG);
+            if (pAlock)
+                pAlock->acquire();
+            mVMStateChangeCallbackDisabled = false;
+            if (RT_FAILURE(rc))
+                return setErrorInternal(VBOX_E_INVALID_VM_STATE,
+                                        COM_IIDOF(IConsole),
+                                        getStaticComponentName(),
+                                        Utf8StrFmt("Couldn't suspend VM for medium change (%Rrc)", rc),
+                                        false /*aWarning*/,
+                                        true /*aLogIt*/);
+            *pfResume = true;
+            break;
+        }
+        case VMSTATE_SUSPENDED:
+            break;
+        default:
+            return setErrorInternal(VBOX_E_INVALID_VM_STATE,
+                                    COM_IIDOF(IConsole),
+                                    getStaticComponentName(),
+                                    Utf8StrFmt("Invalid VM state '%s' for changing medium",
+                                        VMR3GetStateName(enmVMState)),
+                                    false /*aWarning*/,
+                                    true /*aLogIt*/);
+    }
+
+    return S_OK;
+}
+
+/**
+ * Resume the VM after we did any medium or network attachment change.
+ * This is the counterpart to Console::suspendBeforeConfigChange().
+ *
+ * @param pUVM              Safe VM handle.
+ */
+void Console::resumeAfterConfigChange(PUVM pUVM)
+{
+    LogFlowFunc(("Resuming the VM...\n"));
+    /* disable the callback to prevent Console-level state change */
+    mVMStateChangeCallbackDisabled = true;
+    int rc = VMR3Resume(pUVM, VMRESUMEREASON_RECONFIG);
+    mVMStateChangeCallbackDisabled = false;
+    AssertRC(rc);
+    if (RT_FAILURE(rc))
+    {
+        VMSTATE enmVMState = VMR3GetStateU(pUVM);
+        if (enmVMState == VMSTATE_SUSPENDED)
+        {
+            /* too bad, we failed. try to sync the console state with the VMM state */
+            vmstateChangeCallback(pUVM, VMSTATE_SUSPENDED, enmVMState, this);
+        }
+    }
+}
 
 /**
  * Process a medium change.
@@ -3574,26 +3651,23 @@ HRESULT Console::doMediumChange(IMediumAttachment *aMediumAttachment, bool fForc
     AssertComRC(rc);
 
     /*
+     * Suspend the VM first. The VM must not be running since it might have
+     * pending I/O to the drive which is being changed.
+     */
+    bool fResume = false;
+    rc = suspendBeforeConfigChange(pUVM, &alock, &fResume);
+    if (FAILED(rc))
+        return rc;
+
+    /*
      * Call worker in EMT, that's faster and safer than doing everything
      * using VMR3ReqCall. Note that we separate VMR3ReqCall from VMR3ReqWait
      * here to make requests from under the lock in order to serialize them.
      */
     PVMREQ pReq;
-    int vrc = VMR3ReqCallU(pUVM,
-                           VMCPUID_ANY,
-                           &pReq,
-                           0 /* no wait! */,
-                           VMREQFLAGS_VBOX_STATUS,
-                           (PFNRT)Console::changeRemovableMedium,
-                           8,
-                           this,
-                           pUVM,
-                           pszDevice,
-                           uInstance,
-                           enmBus,
-                           fUseHostIOCache,
-                           aMediumAttachment,
-                           fForce);
+    int vrc = VMR3ReqCallU(pUVM, VMCPUID_ANY, &pReq, 0 /* no wait! */, VMREQFLAGS_VBOX_STATUS,
+                           (PFNRT)changeRemovableMedium, 8,
+                           this, pUVM, pszDevice, uInstance, enmBus, fUseHostIOCache, aMediumAttachment, fForce);
 
     /* release the lock before waiting for a result (EMT will call us back!) */
     alock.release();
@@ -3607,6 +3681,9 @@ HRESULT Console::doMediumChange(IMediumAttachment *aMediumAttachment, bool fForc
     }
     VMR3ReqFree(pReq);
 
+    if (fResume)
+        resumeAfterConfigChange(pUVM);
+
     if (RT_SUCCESS(vrc))
     {
         LogFlowThisFunc(("Returns S_OK\n"));
@@ -3642,8 +3719,9 @@ HRESULT Console::doMediumChange(IMediumAttachment *aMediumAttachment, bool fForc
  * @param   fPassthrough    Enables using passthrough mode of the host DVD drive if applicable.
  *
  * @thread  EMT
+ * @note The VM must not be running since it might have pending I/O to the drive which is being changed.
  */
-DECLCALLBACK(int) Console::changeRemovableMedium(Console *pConsole,
+DECLCALLBACK(int) Console::changeRemovableMedium(Console *pThis,
                                                  PUVM pUVM,
                                                  const char *pcszDevice,
                                                  unsigned uInstance,
@@ -3652,112 +3730,49 @@ DECLCALLBACK(int) Console::changeRemovableMedium(Console *pConsole,
                                                  IMediumAttachment *aMediumAtt,
                                                  bool fForce)
 {
-    LogFlowFunc(("pConsole=%p uInstance=%u pszDevice=%p:{%s} enmBus=%u, aMediumAtt=%p, fForce=%d\n",
-                 pConsole, uInstance, pcszDevice, pcszDevice, enmBus, aMediumAtt, fForce));
+    LogFlowFunc(("pThis=%p uInstance=%u pszDevice=%p:{%s} enmBus=%u, aMediumAtt=%p, fForce=%d\n",
+                 pThis, uInstance, pcszDevice, pcszDevice, enmBus, aMediumAtt, fForce));
 
-    AssertReturn(pConsole, VERR_INVALID_PARAMETER);
+    AssertReturn(pThis, VERR_INVALID_PARAMETER);
 
-    AutoCaller autoCaller(pConsole);
+    AutoCaller autoCaller(pThis);
     AssertComRCReturn(autoCaller.rc(), VERR_ACCESS_DENIED);
 
     /*
-     * Suspend the VM first.
-     *
-     * The VM must not be running since it might have pending I/O to
-     * the drive which is being changed.
+     * Check the VM for correct state.
      */
-    bool fResume;
     VMSTATE enmVMState = VMR3GetStateU(pUVM);
-    switch (enmVMState)
-    {
-        case VMSTATE_RESETTING:
-        case VMSTATE_RUNNING:
-        {
-            LogFlowFunc(("Suspending the VM...\n"));
-            /* disable the callback to prevent Console-level state change */
-            pConsole->mVMStateChangeCallbackDisabled = true;
-            int rc = VMR3Suspend(pUVM, VMSUSPENDREASON_RECONFIG);
-            pConsole->mVMStateChangeCallbackDisabled = false;
-            AssertRCReturn(rc, rc);
-            fResume = true;
-            break;
-        }
-
-        case VMSTATE_SUSPENDED:
-        case VMSTATE_CREATED:
-        case VMSTATE_OFF:
-            fResume = false;
-            break;
-
-        case VMSTATE_RUNNING_LS:
-        case VMSTATE_RUNNING_FT:
-            return setErrorInternal(VBOX_E_INVALID_VM_STATE,
-                                    COM_IIDOF(IConsole),
-                                    getStaticComponentName(),
-                                    (enmVMState == VMSTATE_RUNNING_LS) ? Utf8Str(tr("Cannot change drive during live migration")) : Utf8Str(tr("Cannot change drive during fault tolerant syncing")),
-                                    false /*aWarning*/,
-                                    true /*aLogIt*/);
-
-        default:
-            AssertMsgFailedReturn(("enmVMState=%d\n", enmVMState), VERR_ACCESS_DENIED);
-    }
+    AssertReturn(enmVMState == VMSTATE_SUSPENDED, VERR_INVALID_STATE);
 
     /* Determine the base path for the device instance. */
     PCFGMNODE pCtlInst;
     pCtlInst = CFGMR3GetChildF(CFGMR3GetRootU(pUVM), "Devices/%s/%u/", pcszDevice, uInstance);
     AssertReturn(pCtlInst, VERR_INTERNAL_ERROR);
 
-    int rc = VINF_SUCCESS;
-    int rcRet = VINF_SUCCESS;
-
-    rcRet = pConsole->configMediumAttachment(pCtlInst,
-                                             pcszDevice,
-                                             uInstance,
-                                             enmBus,
-                                             fUseHostIOCache,
-                                             false /* fSetupMerge */,
-                                             false /* fBuiltinIOCache */,
-                                             0 /* uMergeSource */,
-                                             0 /* uMergeTarget */,
-                                             aMediumAtt,
-                                             pConsole->mMachineState,
-                                             NULL /* phrc */,
-                                             true /* fAttachDetach */,
-                                             fForce /* fForceUnmount */,
-                                             false  /* fHotplug */,
-                                             pUVM,
-                                             NULL /* paLedDevType */);
-    /** @todo this dumps everything attached to this device instance, which
-     * is more than necessary. Dumping the changed LUN would be enough. */
-    CFGMR3Dump(pCtlInst);
-
-    /*
-     * Resume the VM if necessary.
-     */
-    if (fResume)
-    {
-        LogFlowFunc(("Resuming the VM...\n"));
-        /* disable the callback to prevent Console-level state change */
-        pConsole->mVMStateChangeCallbackDisabled = true;
-        rc = VMR3Resume(pUVM, VMRESUMEREASON_RECONFIG);
-        pConsole->mVMStateChangeCallbackDisabled = false;
-        AssertRC(rc);
-        if (RT_FAILURE(rc))
-        {
-            /* too bad, we failed. try to sync the console state with the VMM state */
-            vmstateChangeCallback(pUVM, VMSTATE_SUSPENDED, enmVMState, pConsole);
-        }
-        /// @todo (r=dmik) if we failed with drive mount, then the VMR3Resume
-        // error (if any) will be hidden from the caller. For proper reporting
-        // of such multiple errors to the caller we need to enhance the
-        // IVirtualBoxError interface. For now, give the first error the higher
-        // priority.
-        if (RT_SUCCESS(rcRet))
-            rcRet = rc;
-    }
-
-    LogFlowFunc(("Returning %Rrc\n", rcRet));
-    return rcRet;
+    PCFGMNODE pLunL0 = NULL;
+    int rc = pThis->configMediumAttachment(pCtlInst,
+                                           pcszDevice,
+                                           uInstance,
+                                           enmBus,
+                                           fUseHostIOCache,
+                                           false /* fSetupMerge */,
+                                           false /* fBuiltinIOCache */,
+                                           0 /* uMergeSource */,
+                                           0 /* uMergeTarget */,
+                                           aMediumAtt,
+                                           pThis->mMachineState,
+                                           NULL /* phrc */,
+                                           true /* fAttachDetach */,
+                                           fForce /* fForceUnmount */,
+                                           false  /* fHotplug */,
+                                           pUVM,
+                                           NULL /* paLedDevType */,
+                                           &pLunL0);
+    /* Dump the changed LUN if possible, dump the complete device otherwise */
+    CFGMR3Dump(pLunL0 ? pLunL0 : pCtlInst);
+
+    LogFlowFunc(("Returning %Rrc\n", rc));
+    return rc;
 }
 
 
@@ -3829,26 +3844,23 @@ HRESULT Console::doStorageDeviceAttach(IMediumAttachment *aMediumAttachment, PUV
     AssertComRC(rc);
 
     /*
+     * Suspend the VM first. The VM must not be running since it might have
+     * pending I/O to the drive which is being changed.
+     */
+    bool fResume = false;
+    rc = suspendBeforeConfigChange(pUVM, &alock, &fResume);
+    if (FAILED(rc))
+        return rc;
+
+    /*
      * Call worker in EMT, that's faster and safer than doing everything
      * using VMR3ReqCall. Note that we separate VMR3ReqCall from VMR3ReqWait
      * here to make requests from under the lock in order to serialize them.
      */
     PVMREQ pReq;
-    int vrc = VMR3ReqCallU(pUVM,
-                           VMCPUID_ANY,
-                           &pReq,
-                           0 /* no wait! */,
-                           VMREQFLAGS_VBOX_STATUS,
-                           (PFNRT)Console::attachStorageDevice,
-                           8,
-                           this,
-                           pUVM,
-                           pszDevice,
-                           uInstance,
-                           enmBus,
-                           fUseHostIOCache,
-                           aMediumAttachment,
-                           fSilent);
+    int vrc = VMR3ReqCallU(pUVM, VMCPUID_ANY, &pReq, 0 /* no wait! */, VMREQFLAGS_VBOX_STATUS,
+                           (PFNRT)attachStorageDevice, 8,
+                           this, pUVM, pszDevice, uInstance, enmBus, fUseHostIOCache, aMediumAttachment, fSilent);
 
     /* release the lock before waiting for a result (EMT will call us back!) */
     alock.release();
@@ -3862,6 +3874,9 @@ HRESULT Console::doStorageDeviceAttach(IMediumAttachment *aMediumAttachment, PUV
     }
     VMR3ReqFree(pReq);
 
+    if (fResume)
+        resumeAfterConfigChange(pUVM);
+
     if (RT_SUCCESS(vrc))
     {
         LogFlowThisFunc(("Returns S_OK\n"));
@@ -3891,8 +3906,9 @@ HRESULT Console::doStorageDeviceAttach(IMediumAttachment *aMediumAttachment, PUV
  * @param   fSilent         Flag whether to inform the guest about the attached device.
  *
  * @thread  EMT
+ * @note The VM must not be running since it might have pending I/O to the drive which is being changed.
  */
-DECLCALLBACK(int) Console::attachStorageDevice(Console *pConsole,
+DECLCALLBACK(int) Console::attachStorageDevice(Console *pThis,
                                                PUVM pUVM,
                                                const char *pcszDevice,
                                                unsigned uInstance,
@@ -3901,113 +3917,49 @@ DECLCALLBACK(int) Console::attachStorageDevice(Console *pConsole,
                                                IMediumAttachment *aMediumAtt,
                                                bool fSilent)
 {
-    LogFlowFunc(("pConsole=%p uInstance=%u pszDevice=%p:{%s} enmBus=%u, aMediumAtt=%p\n",
-                 pConsole, uInstance, pcszDevice, pcszDevice, enmBus, aMediumAtt));
+    LogFlowFunc(("pThis=%p uInstance=%u pszDevice=%p:{%s} enmBus=%u, aMediumAtt=%p\n",
+                 pThis, uInstance, pcszDevice, pcszDevice, enmBus, aMediumAtt));
 
-    AssertReturn(pConsole, VERR_INVALID_PARAMETER);
+    AssertReturn(pThis, VERR_INVALID_PARAMETER);
 
-    AutoCaller autoCaller(pConsole);
+    AutoCaller autoCaller(pThis);
     AssertComRCReturn(autoCaller.rc(), VERR_ACCESS_DENIED);
 
     /*
-     * Suspend the VM first.
-     *
-     * The VM must not be running since it might have pending I/O to
-     * the drive which is being changed.
+     * Check the VM for correct state.
      */
-    bool fResume;
     VMSTATE enmVMState = VMR3GetStateU(pUVM);
-    switch (enmVMState)
-    {
-        case VMSTATE_RESETTING:
-        case VMSTATE_RUNNING:
-        {
-            LogFlowFunc(("Suspending the VM...\n"));
-            /* disable the callback to prevent Console-level state change */
-            pConsole->mVMStateChangeCallbackDisabled = true;
-            int rc = VMR3Suspend(pUVM, VMSUSPENDREASON_RECONFIG);
-            pConsole->mVMStateChangeCallbackDisabled = false;
-            AssertRCReturn(rc, rc);
-            fResume = true;
-            break;
-        }
-
-        case VMSTATE_SUSPENDED:
-        case VMSTATE_CREATED:
-        case VMSTATE_OFF:
-            fResume = false;
-            break;
-
-        case VMSTATE_RUNNING_LS:
-        case VMSTATE_RUNNING_FT:
-            return setErrorInternal(VBOX_E_INVALID_VM_STATE,
-                                    COM_IIDOF(IConsole),
-                                    getStaticComponentName(),
-                                    (enmVMState == VMSTATE_RUNNING_LS) ? Utf8Str(tr("Cannot change drive during live migration")) : Utf8Str(tr("Cannot change drive during fault tolerant syncing")),
-                                    false /*aWarning*/,
-                                    true /*aLogIt*/);
-
-        default:
-            AssertMsgFailedReturn(("enmVMState=%d\n", enmVMState), VERR_ACCESS_DENIED);
-    }
+    AssertReturn(enmVMState == VMSTATE_SUSPENDED, VERR_INVALID_STATE);
 
     /* Determine the base path for the device instance. */
     PCFGMNODE pCtlInst;
     pCtlInst = CFGMR3GetChildF(CFGMR3GetRootU(pUVM), "Devices/%s/%u/", pcszDevice, uInstance);
     AssertReturn(pCtlInst, VERR_INTERNAL_ERROR);
 
-    int rc = VINF_SUCCESS;
-    int rcRet = VINF_SUCCESS;
-
-    rcRet = pConsole->configMediumAttachment(pCtlInst,
-                                             pcszDevice,
-                                             uInstance,
-                                             enmBus,
-                                             fUseHostIOCache,
-                                             false /* fSetupMerge */,
-                                             false /* fBuiltinIOCache */,
-                                             0 /* uMergeSource */,
-                                             0 /* uMergeTarget */,
-                                             aMediumAtt,
-                                             pConsole->mMachineState,
-                                             NULL /* phrc */,
-                                             true /* fAttachDetach */,
-                                             false /* fForceUnmount */,
-                                             !fSilent /* fHotplug */,
-                                             pUVM,
-                                             NULL /* paLedDevType */);
-    /** @todo this dumps everything attached to this device instance, which
-     * is more than necessary. Dumping the changed LUN would be enough. */
-    CFGMR3Dump(pCtlInst);
-
-    /*
-     * Resume the VM if necessary.
-     */
-    if (fResume)
-    {
-        LogFlowFunc(("Resuming the VM...\n"));
-        /* disable the callback to prevent Console-level state change */
-        pConsole->mVMStateChangeCallbackDisabled = true;
-        rc = VMR3Resume(pUVM, VMRESUMEREASON_RECONFIG);
-        pConsole->mVMStateChangeCallbackDisabled = false;
-        AssertRC(rc);
-        if (RT_FAILURE(rc))
-        {
-            /* too bad, we failed. try to sync the console state with the VMM state */
-            vmstateChangeCallback(pUVM, VMSTATE_SUSPENDED, enmVMState, pConsole);
-        }
-        /** @todo  if we failed with drive mount, then the VMR3Resume
-         * error (if any) will be hidden from the caller. For proper reporting
-         * of such multiple errors to the caller we need to enhance the
-         * IVirtualBoxError interface. For now, give the first error the higher
-         * priority.
-         */
-        if (RT_SUCCESS(rcRet))
-            rcRet = rc;
-    }
-
-    LogFlowFunc(("Returning %Rrc\n", rcRet));
-    return rcRet;
+    PCFGMNODE pLunL0 = NULL;
+    int rc = pThis->configMediumAttachment(pCtlInst,
+                                           pcszDevice,
+                                           uInstance,
+                                           enmBus,
+                                           fUseHostIOCache,
+                                           false /* fSetupMerge */,
+                                           false /* fBuiltinIOCache */,
+                                           0 /* uMergeSource */,
+                                           0 /* uMergeTarget */,
+                                           aMediumAtt,
+                                           pThis->mMachineState,
+                                           NULL /* phrc */,
+                                           true /* fAttachDetach */,
+                                           false /* fForceUnmount */,
+                                           !fSilent /* fHotplug */,
+                                           pUVM,
+                                           NULL /* paLedDevType */,
+                                           &pLunL0);
+    /* Dump the changed LUN if possible, dump the complete device otherwise */
+    CFGMR3Dump(pLunL0 ? pLunL0 : pCtlInst);
+
+    LogFlowFunc(("Returning %Rrc\n", rc));
+    return rc;
 }
 
 /**
@@ -4075,25 +4027,23 @@ HRESULT Console::doStorageDeviceDetach(IMediumAttachment *aMediumAttachment, PUV
     AssertComRC(rc);
 
     /*
+     * Suspend the VM first. The VM must not be running since it might have
+     * pending I/O to the drive which is being changed.
+     */
+    bool fResume = false;
+    rc = suspendBeforeConfigChange(pUVM, &alock, &fResume);
+    if (FAILED(rc))
+        return rc;
+
+    /*
      * Call worker in EMT, that's faster and safer than doing everything
      * using VMR3ReqCall. Note that we separate VMR3ReqCall from VMR3ReqWait
      * here to make requests from under the lock in order to serialize them.
      */
     PVMREQ pReq;
-    int vrc = VMR3ReqCallU(pUVM,
-                           VMCPUID_ANY,
-                           &pReq,
-                           0 /* no wait! */,
-                           VMREQFLAGS_VBOX_STATUS,
-                           (PFNRT)Console::detachStorageDevice,
-                           7,
-                           this,
-                           pUVM,
-                           pszDevice,
-                           uInstance,
-                           enmBus,
-                           aMediumAttachment,
-                           fSilent);
+    int vrc = VMR3ReqCallU(pUVM, VMCPUID_ANY, &pReq, 0 /* no wait! */, VMREQFLAGS_VBOX_STATUS,
+                           (PFNRT)detachStorageDevice, 7,
+                           this, pUVM, pszDevice, uInstance, enmBus, aMediumAttachment, fSilent);
 
     /* release the lock before waiting for a result (EMT will call us back!) */
     alock.release();
@@ -4107,6 +4057,9 @@ HRESULT Console::doStorageDeviceDetach(IMediumAttachment *aMediumAttachment, PUV
     }
     VMR3ReqFree(pReq);
 
+    if (fResume)
+        resumeAfterConfigChange(pUVM);
+
     if (RT_SUCCESS(vrc))
     {
         LogFlowThisFunc(("Returns S_OK\n"));
@@ -4135,8 +4088,9 @@ HRESULT Console::doStorageDeviceDetach(IMediumAttachment *aMediumAttachment, PUV
  * @param   fSilent         Flag whether to notify the guest about the detached device.
  *
  * @thread  EMT
+ * @note The VM must not be running since it might have pending I/O to the drive which is being changed.
  */
-DECLCALLBACK(int) Console::detachStorageDevice(Console *pConsole,
+DECLCALLBACK(int) Console::detachStorageDevice(Console *pThis,
                                                PUVM pUVM,
                                                const char *pcszDevice,
                                                unsigned uInstance,
@@ -4144,55 +4098,19 @@ DECLCALLBACK(int) Console::detachStorageDevice(Console *pConsole,
                                                IMediumAttachment *pMediumAtt,
                                                bool fSilent)
 {
-    LogFlowFunc(("pConsole=%p uInstance=%u pszDevice=%p:{%s} enmBus=%u, pMediumAtt=%p\n",
-                 pConsole, uInstance, pcszDevice, pcszDevice, enmBus, pMediumAtt));
+    LogFlowFunc(("pThis=%p uInstance=%u pszDevice=%p:{%s} enmBus=%u, pMediumAtt=%p\n",
+                 pThis, uInstance, pcszDevice, pcszDevice, enmBus, pMediumAtt));
 
-    AssertReturn(pConsole, VERR_INVALID_PARAMETER);
+    AssertReturn(pThis, VERR_INVALID_PARAMETER);
 
-    AutoCaller autoCaller(pConsole);
+    AutoCaller autoCaller(pThis);
     AssertComRCReturn(autoCaller.rc(), VERR_ACCESS_DENIED);
 
     /*
-     * Suspend the VM first.
-     *
-     * The VM must not be running since it might have pending I/O to
-     * the drive which is being changed.
+     * Check the VM for correct state.
      */
-    bool fResume;
     VMSTATE enmVMState = VMR3GetStateU(pUVM);
-    switch (enmVMState)
-    {
-        case VMSTATE_RESETTING:
-        case VMSTATE_RUNNING:
-        {
-            LogFlowFunc(("Suspending the VM...\n"));
-            /* disable the callback to prevent Console-level state change */
-            pConsole->mVMStateChangeCallbackDisabled = true;
-            int rc = VMR3Suspend(pUVM, VMSUSPENDREASON_RECONFIG);
-            pConsole->mVMStateChangeCallbackDisabled = false;
-            AssertRCReturn(rc, rc);
-            fResume = true;
-            break;
-        }
-
-        case VMSTATE_SUSPENDED:
-        case VMSTATE_CREATED:
-        case VMSTATE_OFF:
-            fResume = false;
-            break;
-
-        case VMSTATE_RUNNING_LS:
-        case VMSTATE_RUNNING_FT:
-            return setErrorInternal(VBOX_E_INVALID_VM_STATE,
-                                    COM_IIDOF(IConsole),
-                                    getStaticComponentName(),
-                                    (enmVMState == VMSTATE_RUNNING_LS) ? Utf8Str(tr("Cannot change drive during live migration")) : Utf8Str(tr("Cannot change drive during fault tolerant syncing")),
-                                    false /*aWarning*/,
-                                    true /*aLogIt*/);
-
-        default:
-            AssertMsgFailedReturn(("enmVMState=%d\n", enmVMState), VERR_ACCESS_DENIED);
-    }
+    AssertReturn(enmVMState == VMSTATE_SUSPENDED, VERR_INVALID_STATE);
 
     /* Determine the base path for the device instance. */
     PCFGMNODE pCtlInst;
@@ -4234,7 +4152,7 @@ DECLCALLBACK(int) Console::detachStorageDevice(Console *pConsole,
         CFGMR3RemoveNode(pLunL0);
 
         Utf8Str devicePath = Utf8StrFmt("%s/%u/LUN#%u", pcszDevice, uInstance, uLUN);
-        pConsole->mapMediumAttachments.erase(devicePath);
+        pThis->mapMediumAttachments.erase(devicePath);
 
     }
     else
@@ -4242,32 +4160,6 @@ DECLCALLBACK(int) Console::detachStorageDevice(Console *pConsole,
 
     CFGMR3Dump(pCtlInst);
 
-    /*
-     * Resume the VM if necessary.
-     */
-    if (fResume)
-    {
-        LogFlowFunc(("Resuming the VM...\n"));
-        /* disable the callback to prevent Console-level state change */
-        pConsole->mVMStateChangeCallbackDisabled = true;
-        rc = VMR3Resume(pUVM, VMRESUMEREASON_RECONFIG);
-        pConsole->mVMStateChangeCallbackDisabled = false;
-        AssertRC(rc);
-        if (RT_FAILURE(rc))
-        {
-            /* too bad, we failed. try to sync the console state with the VMM state */
-            vmstateChangeCallback(pUVM, VMSTATE_SUSPENDED, enmVMState, pConsole);
-        }
-        /** @todo: if we failed with drive mount, then the VMR3Resume
-         * error (if any) will be hidden from the caller. For proper reporting
-         * of such multiple errors to the caller we need to enhance the
-         * IVirtualBoxError interface. For now, give the first error the higher
-         * priority.
-         */
-        if (RT_SUCCESS(rcRet))
-            rcRet = rc;
-    }
-
     LogFlowFunc(("Returning %Rrc\n", rcRet));
     return rcRet;
 }
@@ -4507,13 +4399,21 @@ HRESULT Console::doNetworkAdapterChange(PUVM pUVM,
     AssertComRCReturnRC(autoCaller.rc());
 
     /*
+     * Suspend the VM first.
+     */
+    bool fResume = false;
+    int rc = suspendBeforeConfigChange(pUVM, NULL, &fResume);
+    if (FAILED(rc))
+        return rc;
+
+    /*
      * Call worker in EMT, that's faster and safer than doing everything
      * using VM3ReqCall. Note that we separate VMR3ReqCall from VMR3ReqWait
      * here to make requests from under the lock in order to serialize them.
      */
     PVMREQ pReq;
     int vrc = VMR3ReqCallU(pUVM, 0 /*idDstCpu*/, &pReq, 0 /* no wait! */, VMREQFLAGS_VBOX_STATUS,
-                           (PFNRT)Console::changeNetworkAttachment, 6,
+                           (PFNRT)changeNetworkAttachment, 6,
                            this, pUVM, pszDevice, uInstance, uLun, aNetworkAdapter);
 
     if (vrc == VERR_TIMEOUT || RT_SUCCESS(vrc))
@@ -4525,6 +4425,9 @@ HRESULT Console::doNetworkAdapterChange(PUVM pUVM,
     }
     VMR3ReqFree(pReq);
 
+    if (fResume)
+        resumeAfterConfigChange(pUVM);
+
     if (RT_SUCCESS(vrc))
     {
         LogFlowThisFunc(("Returns S_OK\n"));
@@ -4551,6 +4454,7 @@ HRESULT Console::doNetworkAdapterChange(PUVM pUVM,
  *
  * @thread  EMT
  * @note Locks the Console object for writing.
+ * @note The VM must not be running.
  */
 DECLCALLBACK(int) Console::changeNetworkAttachment(Console *pThis,
                                                    PUVM pUVM,
@@ -4586,76 +4490,21 @@ DECLCALLBACK(int) Console::changeNetworkAttachment(Console *pThis,
     Log(("pszDevice=%s uLun=%d uInstance=%d\n", pszDevice, uLun, uInstance));
 
     /*
-     * Suspend the VM first.
-     *
-     * The VM must not be running since it might have pending I/O to
-     * the drive which is being changed.
+     * Check the VM for correct state.
      */
-    bool fResume;
     VMSTATE enmVMState = VMR3GetStateU(pUVM);
-    switch (enmVMState)
-    {
-        case VMSTATE_RESETTING:
-        case VMSTATE_RUNNING:
-        {
-            LogFlowFunc(("Suspending the VM...\n"));
-            /* disable the callback to prevent Console-level state change */
-            pThis->mVMStateChangeCallbackDisabled = true;
-            int rc = VMR3Suspend(pUVM, VMSUSPENDREASON_RECONFIG);
-            pThis->mVMStateChangeCallbackDisabled = false;
-            AssertRCReturn(rc, rc);
-            fResume = true;
-            break;
-        }
-
-        case VMSTATE_SUSPENDED:
-        case VMSTATE_CREATED:
-        case VMSTATE_OFF:
-            fResume = false;
-            break;
-
-        default:
-            AssertLogRelMsgFailedReturn(("enmVMState=%d\n", enmVMState), VERR_ACCESS_DENIED);
-    }
-
-    int rc = VINF_SUCCESS;
-    int rcRet = VINF_SUCCESS;
+    AssertReturn(enmVMState == VMSTATE_SUSPENDED, VERR_INVALID_STATE);
 
     PCFGMNODE pCfg = NULL;          /* /Devices/Dev/.../Config/ */
     PCFGMNODE pLunL0 = NULL;        /* /Devices/Dev/0/LUN#0/ */
     PCFGMNODE pInst = CFGMR3GetChildF(CFGMR3GetRootU(pUVM), "Devices/%s/%d/", pszDevice, uInstance);
     AssertRelease(pInst);
 
-    rcRet = pThis->configNetwork(pszDevice, uInstance, uLun, aNetworkAdapter, pCfg, pLunL0, pInst,
-                                 true /*fAttachDetach*/, false /*fIgnoreConnectFailure*/);
-
-    /*
-     * Resume the VM if necessary.
-     */
-    if (fResume)
-    {
-        LogFlowFunc(("Resuming the VM...\n"));
-        /* disable the callback to prevent Console-level state change */
-        pThis->mVMStateChangeCallbackDisabled = true;
-        rc = VMR3Resume(pUVM, VMRESUMEREASON_RECONFIG);
-        pThis->mVMStateChangeCallbackDisabled = false;
-        AssertRC(rc);
-        if (RT_FAILURE(rc))
-        {
-            /* too bad, we failed. try to sync the console state with the VMM state */
-            vmstateChangeCallback(pUVM, VMSTATE_SUSPENDED, enmVMState, pThis);
-        }
-        /// @todo (r=dmik) if we failed with drive mount, then the VMR3Resume
-        // error (if any) will be hidden from the caller. For proper reporting
-        // of such multiple errors to the caller we need to enhance the
-        // IVirtualBoxError interface. For now, give the first error the higher
-        // priority.
-        if (RT_SUCCESS(rcRet))
-            rcRet = rc;
-    }
+    int rc = pThis->configNetwork(pszDevice, uInstance, uLun, aNetworkAdapter, pCfg, pLunL0, pInst,
+                                  true /*fAttachDetach*/, false /*fIgnoreConnectFailure*/);
 
-    LogFlowFunc(("Returning %Rrc\n", rcRet));
-    return rcRet;
+    LogFlowFunc(("Returning %Rrc\n", rc));
+    return rc;
 }
 
 
@@ -5703,23 +5552,11 @@ HRESULT Console::onlineMergeMedium(IMediumAttachment *aMediumAttachment,
         AssertRCReturn(vrc2, E_FAIL);
     }
 
-    vrc = VMR3ReqCallWaitU(ptrVM.rawUVM(),
-                           VMCPUID_ANY,
-                           (PFNRT)reconfigureMediumAttachment,
-                           13,
-                           this,
-                           ptrVM.rawUVM(),
-                           pcszDevice,
-                           uInstance,
-                           enmBus,
-                           fUseHostIOCache,
-                           fBuiltinIOCache,
-                           true /* fSetupMerge */,
-                           aSourceIdx,
-                           aTargetIdx,
-                           aMediumAttachment,
-                           mMachineState,
-                           &rc);
+    vrc = VMR3ReqCallWaitU(ptrVM.rawUVM(), VMCPUID_ANY,
+                           (PFNRT)reconfigureMediumAttachment, 13,
+                           this, ptrVM.rawUVM(), pcszDevice, uInstance, enmBus, fUseHostIOCache,
+                           fBuiltinIOCache, true /* fSetupMerge */, aSourceIdx, aTargetIdx,
+                           aMediumAttachment, mMachineState, &rc);
     /* error handling is after resuming the VM */
 
     if (mMachineState == MachineState_DeletingSnapshotOnline)
@@ -5777,23 +5614,11 @@ HRESULT Console::onlineMergeMedium(IMediumAttachment *aMediumAttachment,
     /* Update medium chain and state now, so that the VM can continue. */
     rc = mControl->FinishOnlineMergeMedium();
 
-    vrc = VMR3ReqCallWaitU(ptrVM.rawUVM(),
-                           VMCPUID_ANY,
-                           (PFNRT)reconfigureMediumAttachment,
-                           13,
-                           this,
-                           ptrVM.rawUVM(),
-                           pcszDevice,
-                           uInstance,
-                           enmBus,
-                           fUseHostIOCache,
-                           fBuiltinIOCache,
-                           false /* fSetupMerge */,
-                           0 /* uMergeSource */,
-                           0 /* uMergeTarget */,
-                           aMediumAttachment,
-                           mMachineState,
-                           &rc);
+    vrc = VMR3ReqCallWaitU(ptrVM.rawUVM(), VMCPUID_ANY,
+                           (PFNRT)reconfigureMediumAttachment, 13,
+                           this, ptrVM.rawUVM(), pcszDevice, uInstance, enmBus, fUseHostIOCache,
+                           fBuiltinIOCache, false /* fSetupMerge */, 0 /* uMergeSource */,
+                           0 /* uMergeTarget */, aMediumAttachment, mMachineState, &rc);
     /* error handling is after resuming the VM */
 
     if (mMachineState == MachineState_DeletingSnapshotOnline)
@@ -8236,7 +8061,6 @@ HRESULT Console::attachUSBDevice(IUSBDevice *aHostDevice, ULONG aMaskedIfs)
                                (PFNRT)usbAttachCallback, 9,
                                this, ptrVM.rawUVM(), aHostDevice, uuid.raw(), fRemote,
                                Address.c_str(), pvRemoteBackend, portVersion, aMaskedIfs);
-
     if (RT_SUCCESS(vrc))
     {
         /* Create a OUSBDevice and add it to the device list */
@@ -9461,7 +9285,7 @@ DECLCALLBACK(int) Console::powerUpThread(RTTHREAD Thread, void *pvUser)
 /**
  * Reconfigures a medium attachment (part of taking or deleting an online snapshot).
  *
- * @param   pConsole      Reference to the console object.
+ * @param   pThis         Reference to the console object.
  * @param   pUVM          The VM handle.
  * @param   lInstance     The instance of the controller.
  * @param   pcszDevice    The name of the controller type.
@@ -9475,7 +9299,7 @@ DECLCALLBACK(int) Console::powerUpThread(RTTHREAD Thread, void *pvUser)
  * @return  VBox status code.
  */
 /* static */
-DECLCALLBACK(int) Console::reconfigureMediumAttachment(Console *pConsole,
+DECLCALLBACK(int) Console::reconfigureMediumAttachment(Console *pThis,
                                                        PUVM pUVM,
                                                        const char *pcszDevice,
                                                        unsigned uInstance,
@@ -9491,11 +9315,9 @@ DECLCALLBACK(int) Console::reconfigureMediumAttachment(Console *pConsole,
 {
     LogFlowFunc(("pUVM=%p aMediumAtt=%p phrc=%p\n", pUVM, aMediumAtt, phrc));
 
-    int             rc;
     HRESULT         hrc;
     Bstr            bstr;
     *phrc = S_OK;
-#define RC_CHECK() do { if (RT_FAILURE(rc)) { AssertMsgFailed(("rc=%Rrc\n", rc)); return rc; } } while (0)
 #define H() do { if (FAILED(hrc)) { AssertMsgFailed(("hrc=%Rhrc (%#x)\n", hrc, hrc)); *phrc = hrc; return VERR_GENERAL_FAILURE; } } while (0)
 
     /* Ignore attachments other than hard disks, since at the moment they are
@@ -9511,29 +9333,33 @@ DECLCALLBACK(int) Console::reconfigureMediumAttachment(Console *pConsole,
     AssertReturn(pCtlInst, VERR_INTERNAL_ERROR);
 
     /* Update the device instance configuration. */
-    rc = pConsole->configMediumAttachment(pCtlInst,
-                                          pcszDevice,
-                                          uInstance,
-                                          enmBus,
-                                          fUseHostIOCache,
-                                          fBuiltinIOCache,
-                                          fSetupMerge,
-                                          uMergeSource,
-                                          uMergeTarget,
-                                          aMediumAtt,
-                                          aMachineState,
-                                          phrc,
-                                          true /* fAttachDetach */,
-                                          false /* fForceUnmount */,
-                                          false /* fHotplug */,
-                                          pUVM,
-                                          NULL /* paLedDevType */);
-    /** @todo this dumps everything attached to this device instance, which
-     * is more than necessary. Dumping the changed LUN would be enough. */
-    CFGMR3Dump(pCtlInst);
-    RC_CHECK();
+    PCFGMNODE pLunL0 = NULL;
+    int rc = pThis->configMediumAttachment(pCtlInst,
+                                           pcszDevice,
+                                           uInstance,
+                                           enmBus,
+                                           fUseHostIOCache,
+                                           fBuiltinIOCache,
+                                           fSetupMerge,
+                                           uMergeSource,
+                                           uMergeTarget,
+                                           aMediumAtt,
+                                           aMachineState,
+                                           phrc,
+                                           true /* fAttachDetach */,
+                                           false /* fForceUnmount */,
+                                           false /* fHotplug */,
+                                           pUVM,
+                                           NULL /* paLedDevType */,
+                                           &pLunL0);
+    /* Dump the changed LUN if possible, dump the complete device otherwise */
+    CFGMR3Dump(pLunL0 ? pLunL0 : pCtlInst);
+    if (RT_FAILURE(rc))
+    {
+        AssertMsgFailed(("rc=%Rrc\n", rc));
+        return rc;
+    }
 
-#undef RC_CHECK
 #undef H
 
     LogFlowFunc(("Returns success\n"));
@@ -9715,23 +9541,11 @@ DECLCALLBACK(int) Console::fntTakeSnapshotWorker(RTTHREAD Thread, void *pvUser)
                  * don't release the lock since reconfigureMediumAttachment
                  * isn't going to need the Console lock.
                  */
-                vrc = VMR3ReqCallWaitU(ptrVM.rawUVM(),
-                                       VMCPUID_ANY,
-                                       (PFNRT)reconfigureMediumAttachment,
-                                       13,
-                                       that,
-                                       ptrVM.rawUVM(),
-                                       pcszDevice,
-                                       lInstance,
-                                       enmBus,
-                                       fUseHostIOCache,
-                                       fBuiltinIOCache,
-                                       false /* fSetupMerge */,
-                                       0 /* uMergeSource */,
-                                       0 /* uMergeTarget */,
-                                       atts[i],
-                                       that->mMachineState,
-                                       &rc);
+                vrc = VMR3ReqCallWaitU(ptrVM.rawUVM(), VMCPUID_ANY,
+                                       (PFNRT)reconfigureMediumAttachment, 13,
+                                       that, ptrVM.rawUVM(), pcszDevice, lInstance, enmBus, fUseHostIOCache,
+                                       fBuiltinIOCache, false /* fSetupMerge */, 0 /* uMergeSource */,
+                                       0 /* uMergeTarget */, atts[i], that->mMachineState, &rc);
                 if (RT_FAILURE(vrc))
                     throw setErrorStatic(E_FAIL, Console::tr("%Rrc"), vrc);
                 if (FAILED(rc))
diff --git a/src/VBox/Main/src-client/ConsoleImpl2.cpp b/src/VBox/Main/src-client/ConsoleImpl2.cpp
index b762a06..78feac8 100644
--- a/src/VBox/Main/src-client/ConsoleImpl2.cpp
+++ b/src/VBox/Main/src-client/ConsoleImpl2.cpp
@@ -1924,7 +1924,8 @@ int Console::configConstructorInner(PUVM pUVM, PVM pVM, AutoWriteLock *pAlock)
                                             false /* fForceUnmount */,
                                             false /* fHotplug */,
                                             pUVM,
-                                            paLedDevType);
+                                            paLedDevType,
+                                            NULL /* ppLunL0 */);
                 if (RT_FAILURE(rc))
                     return rc;
             }
@@ -3414,7 +3415,8 @@ int Console::configMediumAttachment(PCFGMNODE pCtlInst,
                                     bool fForceUnmount,
                                     bool fHotplug,
                                     PUVM pUVM,
-                                    DeviceType_T *paLedDevType)
+                                    DeviceType_T *paLedDevType,
+                                    PCFGMNODE *ppLunL0)
 {
     // InsertConfig* throws
     try
@@ -3485,6 +3487,8 @@ int Console::configMediumAttachment(PCFGMNODE pCtlInst,
         }
 
         InsertConfigNode(pCtlInst, Utf8StrFmt("LUN#%u", uLUN).c_str(), &pLunL0);
+        if (ppLunL0)
+            *ppLunL0 = pLunL0;
 
         PCFGMNODE pCfg = CFGMR3GetChild(pCtlInst, "Config");
         if (pCfg)
diff --git a/src/VBox/Main/src-client/DisplayImpl.cpp b/src/VBox/Main/src-client/DisplayImpl.cpp
index b627085..3477a07 100644
--- a/src/VBox/Main/src-client/DisplayImpl.cpp
+++ b/src/VBox/Main/src-client/DisplayImpl.cpp
@@ -4300,31 +4300,9 @@ void Display::handleCrHgsmiControlCompletion(int32_t result, uint32_t u32Functio
     mpDrv->pVBVACallbacks->pfnCrHgsmiControlCompleteAsync(mpDrv->pVBVACallbacks, (PVBOXVDMACMD_CHROMIUM_CTL)pParam->u.pointer.addr, result);
 }
 
-int Display::handleCrCmdNotifyCmds()
-{
-    int rc = VERR_INVALID_FUNCTION;
-
-    if (mhCrOglSvc)
-    {
-        VBOXHGCMSVCPARM dummy;
-        VMMDev *pVMMDev = mParent->getVMMDev();
-        if (pVMMDev)
-        {
-            /* no completion callback is specified with this call,
-             * the CrOgl code will complete the CrHgsmi command once it processes it */
-            rc = pVMMDev->hgcmHostFastCallAsync(mhCrOglSvc, SHCRGL_HOST_FN_CRCMD_NOTIFY_CMDS, &dummy, NULL, NULL);
-            AssertRC(rc);
-        }
-        else
-            rc = VERR_INVALID_STATE;
-    }
-
-    return rc;
-}
-
 void Display::handleCrHgsmiCommandProcess(PVBOXVDMACMD_CHROMIUM_CMD pCmd, uint32_t cbCmd)
 {
-    int rc = VERR_INVALID_FUNCTION;
+    int rc = VERR_NOT_SUPPORTED;
     VBOXHGCMSVCPARM parm;
     parm.type = VBOX_HGCM_SVC_PARM_PTR;
     parm.u.pointer.addr = pCmd;
@@ -4352,7 +4330,7 @@ void Display::handleCrHgsmiCommandProcess(PVBOXVDMACMD_CHROMIUM_CMD pCmd, uint32
 
 void Display::handleCrHgsmiControlProcess(PVBOXVDMACMD_CHROMIUM_CTL pCtl, uint32_t cbCtl)
 {
-    int rc = VERR_INVALID_FUNCTION;
+    int rc = VERR_NOT_SUPPORTED;
     VBOXHGCMSVCPARM parm;
     parm.type = VBOX_HGCM_SVC_PARM_PTR;
     parm.u.pointer.addr = pCtl;
@@ -4376,13 +4354,6 @@ void Display::handleCrHgsmiControlProcess(PVBOXVDMACMD_CHROMIUM_CTL pCtl, uint32
     handleCrHgsmiControlCompletion(rc, SHCRGL_HOST_FN_CRHGSMI_CTL, &parm);
 }
 
-DECLCALLBACK(int)  Display::displayCrCmdNotifyCmds(PPDMIDISPLAYCONNECTOR pInterface)
-{
-    PDRVMAINDISPLAY pDrv = PDMIDISPLAYCONNECTOR_2_MAINDISPLAY(pInterface);
-
-    return pDrv->pDisplay->handleCrCmdNotifyCmds();
-}
-
 DECLCALLBACK(void) Display::displayCrHgsmiCommandProcess(PPDMIDISPLAYCONNECTOR pInterface, PVBOXVDMACMD_CHROMIUM_CMD pCmd, uint32_t cbCmd)
 {
     PDRVMAINDISPLAY pDrv = PDMIDISPLAYCONNECTOR_2_MAINDISPLAY(pInterface);
@@ -4411,6 +4382,48 @@ DECLCALLBACK(void) Display::displayCrHgsmiControlCompletion(int32_t result, uint
 }
 #endif
 
+DECLCALLBACK(void)  Display::displayCrHgcmCtlSubmitCompletion(int32_t result, uint32_t u32Function, PVBOXHGCMSVCPARM pParam, void *pvContext)
+{
+    VBOXCRCMDCTL *pCmd = (VBOXCRCMDCTL*)pParam->u.pointer.addr;
+    if (pCmd->pfnInternal)
+        ((PFNCRCTLCOMPLETION)pCmd->pfnInternal)(pCmd, pParam->u.pointer.size, result, pvContext);
+}
+
+int  Display::handleCrHgcmCtlSubmit(struct VBOXCRCMDCTL* pCmd, uint32_t cbCmd,
+                                        PFNCRCTLCOMPLETION pfnCompletion,
+                                        void *pvCompletion)
+{
+    VMMDev *pVMMDev = mParent->getVMMDev();
+    if (!pVMMDev)
+    {
+        AssertMsgFailed(("no vmmdev\n"));
+        return VERR_INVALID_STATE;
+    }
+
+    Assert(mhCrOglSvc);
+    VBOXHGCMSVCPARM parm;
+    parm.type = VBOX_HGCM_SVC_PARM_PTR;
+    parm.u.pointer.addr = pCmd;
+    parm.u.pointer.size = cbCmd;
+
+    pCmd->pfnInternal = (void(*)())pfnCompletion;
+    int rc = pVMMDev->hgcmHostFastCallAsync(mhCrOglSvc, SHCRGL_HOST_FN_CTL, &parm, displayCrHgcmCtlSubmitCompletion, pvCompletion);
+    if (!RT_SUCCESS(rc))
+        AssertMsgFailed(("hgcmHostFastCallAsync failed rc %n", rc));
+
+    return rc;
+}
+
+DECLCALLBACK(int)  Display::displayCrHgcmCtlSubmit(PPDMIDISPLAYCONNECTOR pInterface,
+                                    struct VBOXCRCMDCTL* pCmd, uint32_t cbCmd,
+                                    PFNCRCTLCOMPLETION pfnCompletion,
+                                    void *pvCompletion)
+{
+    PDRVMAINDISPLAY pDrv = PDMIDISPLAYCONNECTOR_2_MAINDISPLAY(pInterface);
+    Display *pThis = pDrv->pDisplay;
+    return pThis->handleCrHgcmCtlSubmit(pCmd, cbCmd, pfnCompletion, pvCompletion);
+}
+
 #if defined(VBOX_WITH_HGCM) && defined(VBOX_WITH_CROGL)
 DECLCALLBACK(void)  Display::displayCrAsyncCmdCompletion(int32_t result, uint32_t u32Function, PVBOXHGCMSVCPARM pParam, void *pvContext)
 {
@@ -5034,10 +5047,10 @@ DECLCALLBACK(int) Display::drvConstruct(PPDMDRVINS pDrvIns, PCFGMNODE pCfg, uint
     pThis->IConnector.pfnVHWACommandProcess    = Display::displayVHWACommandProcess;
 #endif
 #ifdef VBOX_WITH_CRHGSMI
-    pThis->IConnector.pfnCrCmdNotifyCmds =  Display::displayCrCmdNotifyCmds;
     pThis->IConnector.pfnCrHgsmiCommandProcess = Display::displayCrHgsmiCommandProcess;
     pThis->IConnector.pfnCrHgsmiControlProcess = Display::displayCrHgsmiControlProcess;
 #endif
+    pThis->IConnector.pfnCrHgcmCtlSubmit       = Display::displayCrHgcmCtlSubmit;
 #ifdef VBOX_WITH_HGSMI
     pThis->IConnector.pfnVBVAEnable            = Display::displayVBVAEnable;
     pThis->IConnector.pfnVBVADisable           = Display::displayVBVADisable;
diff --git a/src/VBox/Main/src-client/GuestFileImpl.cpp b/src/VBox/Main/src-client/GuestFileImpl.cpp
index 4bd3c57..8a0ce53 100644
--- a/src/VBox/Main/src-client/GuestFileImpl.cpp
+++ b/src/VBox/Main/src-client/GuestFileImpl.cpp
@@ -160,7 +160,7 @@ int GuestFile::init(Console *pConsole, GuestSession *pSession,
         mData.mOpenInfo = openInfo;
 
         unconst(mEventSource).createObject();
-        HRESULT hr = mEventSource->init(static_cast<IGuestFile*>(this));
+        HRESULT hr = mEventSource->init();
         if (FAILED(hr))
             vrc = VERR_COM_UNEXPECTED;
     }
diff --git a/src/VBox/Main/src-client/GuestImpl.cpp b/src/VBox/Main/src-client/GuestImpl.cpp
index e41a6f6..41469b0 100644
--- a/src/VBox/Main/src-client/GuestImpl.cpp
+++ b/src/VBox/Main/src-client/GuestImpl.cpp
@@ -111,7 +111,7 @@ HRESULT Guest::init(Console *aParent)
 #ifdef VBOX_WITH_GUEST_CONTROL
     hr = unconst(mEventSource).createObject();
     if (SUCCEEDED(hr))
-        hr = mEventSource->init(static_cast<IGuest*>(this));
+        hr = mEventSource->init();
 #else
     hr = S_OK;
 #endif
diff --git a/src/VBox/Main/src-client/GuestProcessImpl.cpp b/src/VBox/Main/src-client/GuestProcessImpl.cpp
index cfd2d1d..4ccf1e4 100644
--- a/src/VBox/Main/src-client/GuestProcessImpl.cpp
+++ b/src/VBox/Main/src-client/GuestProcessImpl.cpp
@@ -188,7 +188,7 @@ int GuestProcess::init(Console *aConsole, GuestSession *aSession,
             vrc = VERR_NO_MEMORY;
         else
         {
-            hr = mEventSource->init(static_cast<IGuestProcess*>(this));
+            hr = mEventSource->init();
             if (FAILED(hr))
                 vrc = VERR_COM_UNEXPECTED;
         }
diff --git a/src/VBox/Main/src-client/GuestSessionImpl.cpp b/src/VBox/Main/src-client/GuestSessionImpl.cpp
index 31de6b1..433ac05 100644
--- a/src/VBox/Main/src-client/GuestSessionImpl.cpp
+++ b/src/VBox/Main/src-client/GuestSessionImpl.cpp
@@ -211,7 +211,7 @@ int GuestSession::init(Guest *pGuest, const GuestSessionStartupInfo &ssInfo,
             rc = VERR_NO_MEMORY;
         else
         {
-            hr = mEventSource->init(static_cast<IGuestSession*>(this));
+            hr = mEventSource->init();
             if (FAILED(hr))
                 rc = VERR_COM_UNEXPECTED;
         }
diff --git a/src/VBox/Main/src-client/KeyboardImpl.cpp b/src/VBox/Main/src-client/KeyboardImpl.cpp
index b8010e7..74154da 100644
--- a/src/VBox/Main/src-client/KeyboardImpl.cpp
+++ b/src/VBox/Main/src-client/KeyboardImpl.cpp
@@ -112,7 +112,7 @@ HRESULT Keyboard::init(Console *aParent)
     unconst(mParent) = aParent;
 
     unconst(mEventSource).createObject();
-    HRESULT rc = mEventSource->init(static_cast<IKeyboard*>(this));
+    HRESULT rc = mEventSource->init();
     AssertComRCReturnRC(rc);
 
     /* Confirm a successful initialization */
diff --git a/src/VBox/Main/src-client/MouseImpl.cpp b/src/VBox/Main/src-client/MouseImpl.cpp
index 94a79eb..652f2df 100644
--- a/src/VBox/Main/src-client/MouseImpl.cpp
+++ b/src/VBox/Main/src-client/MouseImpl.cpp
@@ -112,7 +112,7 @@ HRESULT Mouse::init (ConsoleMouseInterface *parent)
     unconst(mParent) = parent;
 
     unconst(mEventSource).createObject();
-    HRESULT rc = mEventSource->init(static_cast<IMouse*>(this));
+    HRESULT rc = mEventSource->init();
     AssertComRCReturnRC(rc);
     mMouseEvent.init(mEventSource, VBoxEventType_OnGuestMouse,
                      0, 0, 0, 0, 0, 0);
diff --git a/src/VBox/Main/src-client/VirtualBoxClientImpl.cpp b/src/VBox/Main/src-client/VirtualBoxClientImpl.cpp
index c421c93..0e2405a 100644
--- a/src/VBox/Main/src-client/VirtualBoxClientImpl.cpp
+++ b/src/VBox/Main/src-client/VirtualBoxClientImpl.cpp
@@ -81,7 +81,7 @@ HRESULT VirtualBoxClient::init()
 
     rc = unconst(mData.m_pEventSource).createObject();
     AssertComRCReturnRC(rc);
-    rc = mData.m_pEventSource->init(static_cast<IVirtualBoxClient *>(this));
+    rc = mData.m_pEventSource->init();
     AssertComRCReturnRC(rc);
 
     /* Setting up the VBoxSVC watcher thread. If anything goes wrong here it
diff --git a/src/VBox/Main/src-server/ApplianceImpl.cpp b/src/VBox/Main/src-server/ApplianceImpl.cpp
index 4c498fd..8d1e601 100644
--- a/src/VBox/Main/src-server/ApplianceImpl.cpp
+++ b/src/VBox/Main/src-server/ApplianceImpl.cpp
@@ -1530,8 +1530,10 @@ void VirtualSystemDescription::addEntry(VirtualSystemDescriptionType_T aType,
         = vsde.strExtraConfigCurrent
         = strExtraConfig;
     vsde.ulSizeMB = ulSizeMB;
+    vsde.skipIt = false;
 
     m->llDescriptions.push_back(vsde);
+
 }
 
 /**
diff --git a/src/VBox/Main/src-server/ApplianceImplExport.cpp b/src/VBox/Main/src-server/ApplianceImplExport.cpp
index 5980e1c..c8c5718 100644
--- a/src/VBox/Main/src-server/ApplianceImplExport.cpp
+++ b/src/VBox/Main/src-server/ApplianceImplExport.cpp
@@ -607,7 +607,13 @@ STDMETHODIMP Appliance::Write(IN_BSTR format, ComSafeArrayIn(ImportOptions_T, op
              ++it)
         {
             ComObjPtr<VirtualSystemDescription> vsdescThis = (*it);
-            vsdescThis->removeByType(VirtualSystemDescriptionType_CDROM);
+            std::list<VirtualSystemDescriptionEntry*> skipped = vsdescThis->findByType(VirtualSystemDescriptionType_CDROM);
+            std::list<VirtualSystemDescriptionEntry*>:: iterator pItSkipped = skipped.begin();
+            while (pItSkipped != skipped.end())
+            {
+                (*pItSkipped)->skipIt = true;
+                ++pItSkipped;
+            }
         }
     }
 
@@ -886,7 +892,8 @@ void Appliance::buildXML(AutoWriteLockBase& writeLock,
         Bstr bstrSrcFilePath(strSrcFilePath);
 
         //skip empty Medium. There are no information to add into section <References> or <DiskSection>
-        if (strSrcFilePath.isEmpty())
+        if (strSrcFilePath.isEmpty() ||
+            pDiskEntry->skipIt == true)
             continue;
 
         // Do NOT check here whether the file exists. FindMedium will figure
@@ -1516,7 +1523,8 @@ void Appliance::buildXMLForOneVirtualSystem(AutoWriteLockBase& writeLock,
                         lAutomaticAllocation = 1;
 
                         //skip empty Medium. There are no information to add into section <References> or <DiskSection>
-                        if (desc.strVBoxCurrent.isNotEmpty())
+                        if (desc.strVBoxCurrent.isNotEmpty() &&
+                            desc.skipIt == false)
                         {
                             // the following references the "<Disks>" XML block
                             strHostResource = Utf8StrFmt("/disk/%s", strDiskID.c_str());
@@ -2091,7 +2099,8 @@ HRESULT Appliance::writeFSImpl(TaskOVF *pTask, AutoWriteLockBase& writeLock, PVD
             const Utf8Str &strSrcFilePath = pDiskEntry->strVBoxCurrent;
 
             //skip empty Medium. In common, It's may be empty CD/DVD
-            if (strSrcFilePath.isEmpty())
+            if (strSrcFilePath.isEmpty() ||
+                pDiskEntry->skipIt == true)
                 continue;
 
             // Do NOT check here whether the file exists. findHardDisk will
diff --git a/src/VBox/Main/src-server/HostDnsService.cpp b/src/VBox/Main/src-server/HostDnsService.cpp
index d4cd3a0..011528f 100644
--- a/src/VBox/Main/src-server/HostDnsService.cpp
+++ b/src/VBox/Main/src-server/HostDnsService.cpp
@@ -288,7 +288,7 @@ HRESULT HostDnsMonitorProxy::GetDomainName(BSTR *aDomainName)
     if (m->fModified)
         updateInfo();
 
-    LogRel(("HostDnsMonitorProxy::GetDomainName:%s\n", m->info->domain.c_str()));
+    LogRel(("HostDnsMonitorProxy::GetDomainName: %s\n", m->info->domain.c_str()));
 
     Utf8Str(m->info->domain.c_str()).cloneTo(aDomainName);
 
@@ -355,7 +355,7 @@ static void dumpHostDnsInformation(const HostDnsInformation& info)
 
 static void dumpHostDnsStrVector(const std::string& prefix, const std::vector<std::string>& v)
 {
-    int i = 0;
+    int i = 1;
     for (std::vector<std::string>::const_iterator it = v.begin();
          it != v.end();
          ++it, ++i)
diff --git a/src/VBox/Main/src-server/MachineImpl.cpp b/src/VBox/Main/src-server/MachineImpl.cpp
index b8eea6f..d790591 100644
--- a/src/VBox/Main/src-server/MachineImpl.cpp
+++ b/src/VBox/Main/src-server/MachineImpl.cpp
@@ -12858,28 +12858,6 @@ HRESULT SessionMachine::init(Machine *aMachine)
     {
         unconst(mNetworkAdapters[slot]).createObject();
         mNetworkAdapters[slot]->init(this, aMachine->mNetworkAdapters[slot]);
-
-        NetworkAttachmentType_T type;
-        HRESULT hrc;
-        hrc = mNetworkAdapters[slot]->COMGETTER(AttachmentType)(&type);
-        if (   SUCCEEDED(hrc)
-            && type == NetworkAttachmentType_NATNetwork)
-        {
-            Bstr name;
-            hrc = mNetworkAdapters[slot]->COMGETTER(NATNetwork)(name.asOutParam());
-            if (SUCCEEDED(hrc))
-            {
-                LogRel(("VM '%s' starts using NAT network '%ls'\n",
-                        mUserData->s.strName.c_str(), name.raw()));
-                aMachine->lockHandle()->unlockWrite();
-                mParent->natNetworkRefInc(name.raw());
-#ifdef RT_LOCK_STRICT
-                aMachine->lockHandle()->lockWrite(RT_SRC_POS);
-#else
-                aMachine->lockHandle()->lockWrite();
-#endif
-            }
-        }
     }
 
     /* create another bandwidth control object that will be mutable */
@@ -12892,6 +12870,8 @@ HRESULT SessionMachine::init(Machine *aMachine)
     /* Confirm a successful initialization when it's the case */
     autoInitSpan.setSucceeded();
 
+    miNATNetworksStarted = 0;
+
     LogFlowThisFuncLeave();
     return rc;
 }
@@ -13071,24 +13051,29 @@ void SessionMachine::uninit(Uninit::Reason aReason)
         mData->mSession.mRemoteControls.clear();
     }
 
-    for (ULONG slot = 0; slot < mNetworkAdapters.size(); slot++)
+    /* Remove all references to the NAT network service. The service will stop
+     * if all references (also from other VMs) are removed. */
+    for (; miNATNetworksStarted > 0; miNATNetworksStarted--)
     {
-        NetworkAttachmentType_T type;
-        HRESULT hrc;
-
-        hrc = mNetworkAdapters[slot]->COMGETTER(AttachmentType)(&type);
-        if (   SUCCEEDED(hrc)
-            && type == NetworkAttachmentType_NATNetwork)
+        for (ULONG slot = 0; slot < mNetworkAdapters.size(); slot++)
         {
-            Bstr name;
-            hrc = mNetworkAdapters[slot]->COMGETTER(NATNetwork)(name.asOutParam());
-            if (SUCCEEDED(hrc))
+            NetworkAttachmentType_T type;
+            HRESULT hrc;
+
+            hrc = mNetworkAdapters[slot]->COMGETTER(AttachmentType)(&type);
+            if (   SUCCEEDED(hrc)
+                && type == NetworkAttachmentType_NATNetwork)
             {
-                multilock.release();
-                LogRel(("VM '%s' stops using NAT network '%ls'\n",
-                        mUserData->s.strName.c_str(), name.raw()));
-                mParent->natNetworkRefDec(name.raw());
-                multilock.acquire();
+                Bstr name;
+                hrc = mNetworkAdapters[slot]->COMGETTER(NATNetwork)(name.asOutParam());
+                if (SUCCEEDED(hrc))
+                {
+                    multilock.release();
+                    LogRel(("VM '%s' stops using NAT network '%ls'\n",
+                            mUserData->s.strName.c_str(), name.raw()));
+                    mParent->natNetworkRefDec(name.raw());
+                    multilock.acquire();
+                }
             }
         }
     }
@@ -13261,6 +13246,37 @@ STDMETHODIMP SessionMachine::BeginPowerUp(IProgress *aProgress)
     if (!mData->mSession.mProgress.isNull())
         mData->mSession.mProgress->setOtherProgressObject(aProgress);
 
+    /* If we didn't reference the NAT network service yet, add a reference to
+     * force a start */
+    if (miNATNetworksStarted < 1)
+    {
+        for (ULONG slot = 0; slot < mNetworkAdapters.size(); slot++)
+        {
+            NetworkAttachmentType_T type;
+            HRESULT hrc;
+            hrc = mNetworkAdapters[slot]->COMGETTER(AttachmentType)(&type);
+            if (   SUCCEEDED(hrc)
+                && type == NetworkAttachmentType_NATNetwork)
+            {
+                Bstr name;
+                hrc = mNetworkAdapters[slot]->COMGETTER(NATNetwork)(name.asOutParam());
+                if (SUCCEEDED(hrc))
+                {
+                    LogRel(("VM '%s' starts using NAT network '%ls'\n",
+                            mUserData->s.strName.c_str(), name.raw()));
+                    mPeer->lockHandle()->unlockWrite();
+                    mParent->natNetworkRefInc(name.raw());
+#ifdef RT_LOCK_STRICT
+                    mPeer->lockHandle()->lockWrite(RT_SRC_POS);
+#else
+                    mPeer->lockHandle()->lockWrite();
+#endif
+                }
+            }
+        }
+        miNATNetworksStarted++;
+    }
+
     LogFlowThisFunc(("returns S_OK.\n"));
     return S_OK;
 }
diff --git a/src/VBox/Main/src-server/NATNetworkImpl.cpp b/src/VBox/Main/src-server/NATNetworkImpl.cpp
index c419420..6532725 100644
--- a/src/VBox/Main/src-server/NATNetworkImpl.cpp
+++ b/src/VBox/Main/src-server/NATNetworkImpl.cpp
@@ -154,7 +154,7 @@ HRESULT NATNetwork::init(VirtualBox *aVirtualBox, IN_BSTR aName)
     HRESULT hrc = unconst(m->pEventSource).createObject();
     if (FAILED(hrc)) throw hrc;
 
-    hrc = m->pEventSource->init(static_cast<INATNetwork *>(this));
+    hrc = m->pEventSource->init();
     if (FAILED(hrc)) throw hrc;
 
     /* Confirm a successful initialization */
@@ -209,7 +209,7 @@ HRESULT NATNetwork::init(VirtualBox *aVirtualBox,
     HRESULT hrc = unconst(m->pEventSource).createObject();
     if (FAILED(hrc)) throw hrc;
 
-    hrc = m->pEventSource->init(static_cast<INATNetwork *>(this));
+    hrc = m->pEventSource->init();
     if (FAILED(hrc)) throw hrc;
 
     autoInitSpan.setSucceeded();
diff --git a/src/VBox/Main/src-server/VirtualBoxImpl.cpp b/src/VBox/Main/src-server/VirtualBoxImpl.cpp
index e19e1f6..7c31923 100644
--- a/src/VBox/Main/src-server/VirtualBoxImpl.cpp
+++ b/src/VBox/Main/src-server/VirtualBoxImpl.cpp
@@ -509,7 +509,7 @@ HRESULT VirtualBox::init()
 
         /* events */
         if (SUCCEEDED(rc = unconst(m->pEventSource).createObject()))
-            rc = m->pEventSource->init(static_cast<IVirtualBox*>(this));
+            rc = m->pEventSource->init();
         if (FAILED(rc)) throw rc;
 
 #ifdef VBOX_WITH_EXTPACK
@@ -807,7 +807,11 @@ void VirtualBox::uninit()
     LogFlowThisFunc(("Releasing event source...\n"));
     if (m->pEventSource)
     {
-        // we don't perform uninit() as it's possible that some pending event refers to this source
+        // Must uninit the event source here, because it makes no sense that
+        // it survives longer than the base object. If someone gets an event
+        // with such an event source then that's life and it has to be dealt
+        // with appropriately on the API client side.
+        m->pEventSource->uninit();
         unconst(m->pEventSource).setNull();
     }
 
diff --git a/src/VBox/Main/src-server/darwin/iokit.cpp b/src/VBox/Main/src-server/darwin/iokit.cpp
index 7a7b105..69c572f 100644
--- a/src/VBox/Main/src-server/darwin/iokit.cpp
+++ b/src/VBox/Main/src-server/darwin/iokit.cpp
@@ -8,7 +8,7 @@
  */
 
 /*
- * Copyright (C) 2006-2012 Oracle Corporation
+ * Copyright (C) 2006-2014 Oracle Corporation
  *
  * This file is part of VirtualBox Open Source Edition (OSE), as
  * available from http://www.virtualbox.org. This file is free software;
@@ -1354,7 +1354,7 @@ PDARWINDVD DarwinGetDVDDrives(void)
                             if (*pszVendor && *pszProduct)
                                 RTStrPrintf(szName, sizeof(szName), "%s %s (#%u)", pszVendor, pszProduct, i);
                             else
-                                RTStrPrintf(szName, sizeof(szName), "%s %s (#%u)", *pszVendor ? pszVendor : pszProduct, i);
+                                RTStrPrintf(szName, sizeof(szName), "%s (#%u)", *pszVendor ? pszVendor : pszProduct, i);
                             break;
                         }
                     }
diff --git a/src/VBox/NetworkServices/DHCP/VBoxNetDHCP.cpp b/src/VBox/NetworkServices/DHCP/VBoxNetDHCP.cpp
index 39ddff8..6496b8a 100644
--- a/src/VBox/NetworkServices/DHCP/VBoxNetDHCP.cpp
+++ b/src/VBox/NetworkServices/DHCP/VBoxNetDHCP.cpp
@@ -624,10 +624,10 @@ extern "C" DECLEXPORT(int) TrustedMain(int argc, char **argv)
      * Try connect the server to the network.
      */
     rc = pDhcp->tryGoOnline();
-    if (rc)
+    if (RT_FAILURE(rc))
     {
         delete pDhcp;
-        return rc;
+        return 1;
     }
 
     /*
@@ -638,7 +638,7 @@ extern "C" DECLEXPORT(int) TrustedMain(int argc, char **argv)
     g_pDhcp = NULL;
     delete pDhcp;
 
-    return rc;
+    return 0;
 }
 
 
diff --git a/src/VBox/NetworkServices/NAT/Makefile.kmk b/src/VBox/NetworkServices/NAT/Makefile.kmk
index 619494f..6682b08 100644
--- a/src/VBox/NetworkServices/NAT/Makefile.kmk
+++ b/src/VBox/NetworkServices/NAT/Makefile.kmk
@@ -102,6 +102,7 @@ VBoxNetLwipNAT_SOURCES.win += \
     RTWinPoll.cpp \
     RTWinSocketPair.cpp
 
+VBoxNetLwipNAT_INCS += . # for lwipopts.h
 $(eval $(call def_vbox_lwip_public, \
     VBoxNetLwipNAT, ../../Devices/Network/lwip-new))
 endif
diff --git a/src/VBox/NetworkServices/NAT/VBoxNetLwipNAT.cpp b/src/VBox/NetworkServices/NAT/VBoxNetLwipNAT.cpp
index a8ccc06..01ee26e 100644
--- a/src/VBox/NetworkServices/NAT/VBoxNetLwipNAT.cpp
+++ b/src/VBox/NetworkServices/NAT/VBoxNetLwipNAT.cpp
@@ -15,6 +15,9 @@
  * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
  */
 
+/* Must be included before winutils.h (lwip/def.h), otherwise Windows build breaks. */
+#include <iprt/cpp/mem.h>
+
 #include "winutils.h"
 
 #include <VBox/com/assert.h>
@@ -73,6 +76,8 @@
 #include <vector>
 #include <string>
 
+#include <stdio.h>
+
 #include "../NetLib/VBoxNetLib.h"
 #include "../NetLib/VBoxNetBaseService.h"
 #include "../NetLib/utils.h"
@@ -81,11 +86,6 @@
 extern "C"
 {
 /* bunch of LWIP headers */
-#include "lwip/opt.h"
-#ifdef LWIP_SOCKET
-# undef LWIP_SOCKET
-# define LWIP_SOCKET 0
-#endif
 #include "lwip/sys.h"
 #include "lwip/pbuf.h"
 #include "lwip/netif.h"
@@ -132,6 +132,8 @@ typedef VECNATSERVICEPF::const_iterator CITERATORNATSERVICEPF;
 
 static int fetchNatPortForwardRules(const ComNatPtr&, bool, VECNATSERVICEPF&);
 
+static int vboxNetNATLogInit(int argc, char **argv);
+
 
 class VBoxNetLwipNAT: public VBoxNetBaseService, public NATNetworkEventAdapter
 {
@@ -239,6 +241,12 @@ HRESULT VBoxNetLwipNAT::HandleEvent(VBoxEventType_T aEventType,
 
             ComPtr<INATNetworkPortForwardEvent> pfEvt = pEvent;
 
+            hrc = pfEvt->COMGETTER(Create)(&fCreateFW);
+            AssertReturn(SUCCEEDED(hrc), hrc);
+
+            hrc = pfEvt->COMGETTER(Ipv6)(&fIPv6FW);
+            AssertReturn(SUCCEEDED(hrc), hrc);
+
             hrc = pfEvt->COMGETTER(Name)(name.asOutParam());
             AssertReturn(SUCCEEDED(hrc), hrc);
 
@@ -257,26 +265,13 @@ HRESULT VBoxNetLwipNAT::HandleEvent(VBoxEventType_T aEventType,
             hrc = pfEvt->COMGETTER(GuestPort)(&lGuestPort);
             AssertReturn(SUCCEEDED(hrc), hrc);
 
-            hrc = pfEvt->COMGETTER(Create)(&fCreateFW);
-            AssertReturn(SUCCEEDED(hrc), hrc);
-
-            hrc = pfEvt->COMGETTER(Ipv6)(&fIPv6FW);
-            AssertReturn(SUCCEEDED(hrc), hrc);
-
             VECNATSERVICEPF& rules = (fIPv6FW ?
                                       m_vecPortForwardRule6 :
                                       m_vecPortForwardRule4);
 
             NATSEVICEPORTFORWARDRULE r;
-
             RT_ZERO(r);
 
-            if (name.length() > sizeof(r.Pfr.szPfrName))
-            {
-                hrc = E_INVALIDARG;
-                goto port_forward_done;
-            }
-
             r.Pfr.fPfrIPv6 = fIPv6FW;
 
             switch (proto)
@@ -287,10 +282,39 @@ HRESULT VBoxNetLwipNAT::HandleEvent(VBoxEventType_T aEventType,
                 case NATProtocol_UDP:
                     r.Pfr.iPfrProto = IPPROTO_UDP;
                     break;
+
                 default:
+                    LogRel(("Event: %s %s port-forwarding rule \"%s\":"
+                            " invalid protocol %d\n",
+                            fCreateFW ? "Add" : "Remove",
+                            fIPv6FW ? "IPv6" : "IPv4",
+                            com::Utf8Str(name).c_str(),
+                            (int)proto));
                     goto port_forward_done;
             }
 
+            LogRel(("Event: %s %s port-forwarding rule \"%s\":"
+                    " %s %s%s%s:%d -> %s%s%s:%d\n",
+                    fCreateFW ? "Add" : "Remove",
+                    fIPv6FW ? "IPv6" : "IPv4",
+                    com::Utf8Str(name).c_str(),
+                    proto == NATProtocol_TCP ? "TCP" : "UDP",
+                    /* from */
+                    fIPv6FW ? "[" : "",
+                    com::Utf8Str(strHostAddr).c_str(),
+                    fIPv6FW ? "]" : "",
+                    lHostPort,
+                    /* to */
+                    fIPv6FW ? "[" : "",
+                    com::Utf8Str(strGuestAddr).c_str(),
+                    fIPv6FW ? "]" : "",
+                    lGuestPort));
+
+            if (name.length() > sizeof(r.Pfr.szPfrName))
+            {
+                hrc = E_INVALIDARG;
+                goto port_forward_done;
+            }
 
             RTStrPrintf(r.Pfr.szPfrName, sizeof(r.Pfr.szPfrName),
                       "%s", com::Utf8Str(name).c_str());
@@ -309,9 +333,9 @@ HRESULT VBoxNetLwipNAT::HandleEvent(VBoxEventType_T aEventType,
 
             if (fCreateFW) /* Addition */
             {
-                rules.push_back(r);
-
-                natServicePfRegister(rules.back());
+                int rc = natServicePfRegister(r);
+                if (RT_SUCCESS(rc))
+                    rules.push_back(r);
             }
             else /* Deletion */
             {
@@ -326,18 +350,17 @@ HRESULT VBoxNetLwipNAT::HandleEvent(VBoxEventType_T aEventType,
                         && natFw.Pfr.u16PfrGuestPort == r.Pfr.u16PfrGuestPort
                         && (strncmp(natFw.Pfr.szPfrGuestAddr, r.Pfr.szPfrGuestAddr, INET6_ADDRSTRLEN) == 0))
                     {
-                        fwspec *pFwCopy = (fwspec *)RTMemAllocZ(sizeof(fwspec));
-                        if (!pFwCopy)
-                        {
+                        RTCMemAutoPtr<fwspec> pFwCopy;
+                        if (RT_UNLIKELY(!pFwCopy.alloc()))
                             break;
-                        }
-                        memcpy(pFwCopy, &natFw.FWSpec, sizeof(fwspec));
 
-                        /* We shouldn't care about pFwCopy this memory will be freed when
-                         * will message will arrive to the destination.
-                         */
-                        portfwd_rule_del(pFwCopy);
+                        memcpy(pFwCopy.get(), &natFw.FWSpec, sizeof(natFw.FWSpec));
+
+                        int status = portfwd_rule_del(pFwCopy.get());
+                        if (status != 0)
+                            break;
 
+                        pFwCopy.release(); /* owned by lwip thread now */
                         rules.erase(it);
                         break;
                     }
@@ -402,10 +425,24 @@ void VBoxNetLwipNAT::onLwipTcpIpInit(void* arg)
                               &LwipIpAddr /* gateway address, @todo: is self IP acceptable? */,
                               g_pLwipNat /* state */,
                               VBoxNetLwipNAT::netifInit /* netif_init_fn */,
-                              lwip_tcpip_input /* netif_input_fn */);
+                              tcpip_input /* netif_input_fn */);
 
     AssertPtrReturnVoid(pNetif);
 
+    LogRel(("netif %c%c%d: mac %RTmac\n",
+            pNetif->name[0], pNetif->name[1], pNetif->num,
+            pNetif->hwaddr));
+    LogRel(("netif %c%c%d: inet %RTnaipv4 netmask %RTnaipv4\n",
+            pNetif->name[0], pNetif->name[1], pNetif->num,
+            pNetif->ip_addr, pNetif->netmask));
+    for (int i = 0; i < LWIP_IPV6_NUM_ADDRESSES; ++i) {
+        if (!ip6_addr_isinvalid(netif_ip6_addr_state(pNetif, i))) {
+            LogRel(("netif %c%c%d: inet6 %RTnaipv6\n",
+                    pNetif->name[0], pNetif->name[1], pNetif->num,
+                    netif_ip6_addr(pNetif, i)));
+        }
+    }
+
     netif_set_up(pNetif);
     netif_set_link_up(pNetif);
 
@@ -491,7 +528,7 @@ err_t VBoxNetLwipNAT::netifInit(netif *pNetif)
       | NETIF_FLAG_ETHERNET;             /* Lwip works with ethernet too */
 
     pNetif->linkoutput = netifLinkoutput; /* ether-level-pipe */
-    pNetif->output = lwip_etharp_output; /* ip-pipe */
+    pNetif->output = etharp_output;       /* ip-pipe */
 
     if (pNat->m_ProxyOptions.ipv6_enabled) {
         pNetif->output_ip6 = ethip6_output;
@@ -530,7 +567,10 @@ err_t VBoxNetLwipNAT::netifLinkoutput(netif *pNetif, pbuf *pPBuf)
 {
     AssertPtrReturn(pNetif, ERR_ARG);
     AssertPtrReturn(pPBuf, ERR_ARG);
-    AssertReturn((void *)g_pLwipNat == pNetif->state, ERR_ARG);
+
+    VBoxNetLwipNAT *self = static_cast<VBoxNetLwipNAT *>(pNetif->state);
+    AssertPtrReturn(self, ERR_IF);
+    AssertReturn(self == g_pLwipNat, ERR_ARG);
 
     LogFlowFunc(("ENTER: pNetif[%c%c%d], pPbuf:%p\n",
                  pNetif->name[0],
@@ -539,19 +579,31 @@ err_t VBoxNetLwipNAT::netifLinkoutput(netif *pNetif, pbuf *pPBuf)
                  pPBuf));
 
     RT_ZERO(VBoxNetLwipNAT::aXmitSeg);
-    
+
     size_t idx = 0;
     for (struct pbuf *q = pPBuf; q != NULL; q = q->next, ++idx)
     {
         AssertReturn(idx < RT_ELEMENTS(VBoxNetLwipNAT::aXmitSeg), ERR_MEM);
-        VBoxNetLwipNAT::aXmitSeg[idx].pv = q->payload; 
-        VBoxNetLwipNAT::aXmitSeg[idx].cb = q->len;
+
+#if ETH_PAD_SIZE
+        if (q == pPBuf)
+        {
+            VBoxNetLwipNAT::aXmitSeg[idx].pv = (uint8_t *)q->payload + ETH_PAD_SIZE;
+            VBoxNetLwipNAT::aXmitSeg[idx].cb = q->len - ETH_PAD_SIZE;
+        }
+        else
+#endif
+        {
+            VBoxNetLwipNAT::aXmitSeg[idx].pv = q->payload;
+            VBoxNetLwipNAT::aXmitSeg[idx].cb = q->len;
+        }
     }
 
-    int rc = g_pLwipNat->sendBufferOnWire(VBoxNetLwipNAT::aXmitSeg, idx, pPBuf->tot_len);
+    int rc = self->sendBufferOnWire(VBoxNetLwipNAT::aXmitSeg, idx,
+                                    pPBuf->tot_len - ETH_PAD_SIZE);
     AssertRCReturn(rc, ERR_IF);
 
-    g_pLwipNat->flushWire();
+    self->flushWire();
 
     LogFlowFunc(("LEAVE: %d\n", ERR_OK));
     return ERR_OK;
@@ -618,12 +670,10 @@ VBoxNetLwipNAT::~VBoxNetLwipNAT()
 
 int VBoxNetLwipNAT::natServicePfRegister(NATSEVICEPORTFORWARDRULE& natPf)
 {
-    int lrc = 0;
-    int rc = VINF_SUCCESS;
-    int socketSpec = SOCK_STREAM;
-    char *pszHostAddr;
-    int sockFamily = (natPf.Pfr.fPfrIPv6 ? PF_INET6 : PF_INET);
+    int lrc;
 
+    int sockFamily = (natPf.Pfr.fPfrIPv6 ? PF_INET6 : PF_INET);
+    int socketSpec;
     switch(natPf.Pfr.iPfrProto)
     {
         case IPPROTO_TCP:
@@ -633,18 +683,17 @@ int VBoxNetLwipNAT::natServicePfRegister(NATSEVICEPORTFORWARDRULE& natPf)
             socketSpec = SOCK_DGRAM;
             break;
         default:
-            return VERR_IGNORED; /* Ah, just ignore the garbage */
+            return VERR_IGNORED;
     }
 
-    pszHostAddr = natPf.Pfr.szPfrHostAddr;
-
-    /* XXX: workaround for inet_pton and an empty ipv4 address
-     * in rule declaration.
-     */
-    if (   sockFamily == PF_INET
-        && pszHostAddr[0] == 0)
-        pszHostAddr = (char *)"0.0.0.0"; /* XXX: fix it! without type cast */
-
+    const char *pszHostAddr = natPf.Pfr.szPfrHostAddr;
+    if (pszHostAddr[0] == '\0')
+    {
+        if (sockFamily == PF_INET)
+            pszHostAddr = "0.0.0.0";
+        else
+            pszHostAddr = "::";
+    }
 
     lrc = fwspec_set(&natPf.FWSpec,
                      sockFamily,
@@ -653,38 +702,54 @@ int VBoxNetLwipNAT::natServicePfRegister(NATSEVICEPORTFORWARDRULE& natPf)
                      natPf.Pfr.u16PfrHostPort,
                      natPf.Pfr.szPfrGuestAddr,
                      natPf.Pfr.u16PfrGuestPort);
+    if (lrc != 0)
+        return VERR_IGNORED;
 
-    AssertReturn(!lrc, VERR_IGNORED);
-
-    fwspec *pFwCopy = (fwspec *)RTMemAllocZ(sizeof(fwspec));
-    AssertPtrReturn(pFwCopy, VERR_IGNORED);
-
-    /*
-     * We need pass the copy, because we can't be sure
-     * how much this pointer will be valid in LWIP environment.
-     */
-    memcpy(pFwCopy, &natPf.FWSpec, sizeof(fwspec));
+    RTCMemAutoPtr<fwspec> pFwCopy;
+    if (RT_UNLIKELY(!pFwCopy.alloc()))
+    {
+        LogRel(("Unable to allocate memory for %s rule \"%s\"\n",
+                natPf.Pfr.fPfrIPv6 ? "IPv6" : "IPv4",
+                natPf.Pfr.szPfrName));
+        return VERR_IGNORED;
+    }
 
-    lrc = portfwd_rule_add(pFwCopy);
+    memcpy(pFwCopy.get(), &natPf.FWSpec, sizeof(natPf.FWSpec));
 
-    AssertReturn(!lrc, VERR_IGNORED);
+    lrc = portfwd_rule_add(pFwCopy.get());
+    if (lrc != 0)
+        return VERR_IGNORED;
 
+    pFwCopy.release();          /* owned by lwip thread now */
     return VINF_SUCCESS;
 }
 
 
-int VBoxNetLwipNAT::natServiceProcessRegisteredPf(VECNATSERVICEPF& vecRules){
+int VBoxNetLwipNAT::natServiceProcessRegisteredPf(VECNATSERVICEPF& vecRules)
+{
     ITERATORNATSERVICEPF it;
-    for (it = vecRules.begin();
-         it != vecRules.end(); ++it)
+    for (it = vecRules.begin(); it != vecRules.end(); ++it)
     {
-        int rc = natServicePfRegister((*it));
-        if (RT_FAILURE(rc))
-        {
-            LogRel(("PF: %s is ignored\n", (*it).Pfr.szPfrName));
-            continue;
-        }
+        NATSEVICEPORTFORWARDRULE &natPf = *it;
+
+        LogRel(("Loading %s port-forwarding rule \"%s\": %s %s%s%s:%d -> %s%s%s:%d\n",
+                natPf.Pfr.fPfrIPv6 ? "IPv6" : "IPv4",
+                natPf.Pfr.szPfrName,
+                natPf.Pfr.iPfrProto == IPPROTO_TCP ? "TCP" : "UDP",
+                /* from */
+                natPf.Pfr.fPfrIPv6 ? "[" : "",
+                natPf.Pfr.szPfrHostAddr,
+                natPf.Pfr.fPfrIPv6 ? "]" : "",
+                natPf.Pfr.u16PfrHostPort,
+                /* to */
+                natPf.Pfr.fPfrIPv6 ? "[" : "",
+                natPf.Pfr.szPfrGuestAddr,
+                natPf.Pfr.fPfrIPv6 ? "]" : "",
+                natPf.Pfr.u16PfrGuestPort));
+
+        natServicePfRegister(natPf);
     }
+
     return VINF_SUCCESS;
 }
 
@@ -795,7 +860,12 @@ int VBoxNetLwipNAT::init()
 
     /* end of COM initialization */
 
-    g_pLwipNat->tryGoOnline();
+    rc = g_pLwipNat->tryGoOnline();
+    if (RT_FAILURE(rc))
+    {
+        return rc;
+    }
+
     /* this starts LWIP thread */
     vboxLwipCoreInitialize(VBoxNetLwipNAT::onLwipTcpIpInit, this);
 
@@ -882,24 +952,41 @@ int VBoxNetLwipNAT::parseOpt(int rc, const RTGETOPTUNION& Val)
 
 int VBoxNetLwipNAT::processFrame(void *pvFrame, size_t cbFrame)
 {
-    AssertReturn(pvFrame && cbFrame, VERR_INVALID_PARAMETER);
-
-    struct  pbuf *pPbufHdr, *pPbuf;
-    pPbufHdr = pPbuf = pbuf_alloc(PBUF_RAW, cbFrame, PBUF_POOL);
+    AssertPtrReturn(pvFrame, VERR_INVALID_PARAMETER);
+    AssertReturn(cbFrame != 0, VERR_INVALID_PARAMETER);
 
-    AssertMsgReturn(pPbuf, ("NAT: Can't allocate send buffer cbFrame=%u\n", cbFrame), VERR_INTERNAL_ERROR);
-    AssertReturn(pPbufHdr->tot_len == cbFrame, VERR_INTERNAL_ERROR);
-                    
-    uint8_t *pu8Frame = (uint8_t *)pvFrame;
-    while(pPbuf)
+    struct pbuf *p = pbuf_alloc(PBUF_RAW, cbFrame + ETH_PAD_SIZE, PBUF_POOL);
+    if (RT_UNLIKELY(p == NULL))
     {
-        memcpy(pPbuf->payload, pu8Frame, pPbuf->len);
-        pu8Frame += pPbuf->len;
-        pPbuf = pPbuf->next;
+        return VERR_NO_MEMORY;
     }
 
-    m_LwipNetIf.input(pPbufHdr, &m_LwipNetIf);
-    
+    /*
+     * The code below is inlined version of:
+     *
+     *   pbuf_header(p, -ETH_PAD_SIZE); // hide padding
+     *   pbuf_take(p, pvFrame, cbFrame);
+     *   pbuf_header(p, ETH_PAD_SIZE);  // reveal padding
+     */
+    struct pbuf *q = p;
+    uint8_t *pu8Chunk = (uint8_t *)pvFrame;
+    do {
+        uint8_t *payload = (uint8_t *)q->payload;
+        size_t len = q->len;
+
+#if ETH_PAD_SIZE
+        if (RT_LIKELY(q == p))  // single pbuf is large enough
+        {
+            payload += ETH_PAD_SIZE;
+            len -= ETH_PAD_SIZE;
+        }
+#endif
+        memcpy(payload, pu8Chunk, len);
+        pu8Chunk += len;
+        q = q->next;
+    } while (RT_UNLIKELY(q != NULL));
+
+    m_LwipNetIf.input(p, &m_LwipNetIf);
     return VINF_SUCCESS;
 }
 
@@ -926,13 +1013,11 @@ int VBoxNetLwipNAT::processGSO(PCPDMNETWORKGSO pGso, size_t cbFrame)
                                   cSegs,
                                   &cbSegFrame);
 
-        struct pbuf *pPbuf = pbuf_alloc(PBUF_RAW, cbSegFrame, PBUF_POOL);
-
-        AssertMsgReturn(pPbuf, ("NAT: Can't allocate send buffer cbFrame=%u\n", cbSegFrame), VERR_INTERNAL_ERROR);
-        AssertReturn(!pPbuf->next && pPbuf->len == cbSegFrame, VERR_INTERNAL_ERROR);
-
-        memcpy(pPbuf->payload, pvSegFrame, cbSegFrame);
-        m_LwipNetIf.input(pPbuf, &g_pLwipNat->m_LwipNetIf);
+        int rc = processFrame(pvSegFrame, cbSegFrame);
+        if (RT_FAILURE(rc))
+        {
+            return rc;
+        }
     }
 
     return VINF_SUCCESS;
@@ -958,6 +1043,8 @@ int VBoxNetLwipNAT::run()
  */
 extern "C" DECLEXPORT(int) TrustedMain(int argc, char **argv, char **envp)
 {
+    int rc;
+
     LogFlowFuncEnter();
 
     NOREF(envp);
@@ -1048,37 +1135,148 @@ extern "C" DECLEXPORT(int) TrustedMain(int argc, char **argv, char **envp)
     }
 
     HRESULT hrc = com::Initialize();
-#ifdef VBOX_WITH_XPCOM
-    if (hrc == NS_ERROR_FILE_ACCESS_DENIED)
+    if (FAILED(hrc))
     {
-        char szHome[RTPATH_MAX] = "";
-        com::GetVBoxUserHomeDirectory(szHome, sizeof(szHome));
+#ifdef VBOX_WITH_XPCOM
+        if (hrc == NS_ERROR_FILE_ACCESS_DENIED)
+        {
+            char szHome[RTPATH_MAX] = "";
+            int vrc = com::GetVBoxUserHomeDirectory(szHome, sizeof(szHome), false);
+            if (RT_SUCCESS(vrc))
+            {
+                return RTMsgErrorExit(RTEXITCODE_FAILURE,
+                                      "Failed to initialize COM: %s: %Rhrf",
+                                      szHome, hrc);
+            }
+        }
+#endif  // VBOX_WITH_XPCOM
         return RTMsgErrorExit(RTEXITCODE_FAILURE,
-               "Failed to initialize COM because the global settings directory '%s' is not accessible!", szHome);
+                              "Failed to initialize COM: %Rhrf", hrc);
     }
-#endif
-    if (FAILED(hrc))
-        return RTMsgErrorExit(RTEXITCODE_FAILURE, "Failed to initialize COM!");
+
+    rc = vboxNetNATLogInit(argc, argv);
+    // shall we bail if we failed to init logging?
 
     g_pLwipNat = new VBoxNetLwipNAT(icmpsock4, icmpsock6);
 
     Log2(("NAT: initialization\n"));
-    int rc = g_pLwipNat->parseArgs(argc - 1, argv + 1);
-    AssertRC(rc);
+    rc = g_pLwipNat->parseArgs(argc - 1, argv + 1);
+    rc = (rc == 0) ? VINF_SUCCESS : VERR_GENERAL_FAILURE; /* XXX: FIXME */
 
-
-    if (!rc)
+    if (RT_SUCCESS(rc))
     {
+        rc = g_pLwipNat->init();
+    }
 
-        g_pLwipNat->init();
+    if (RT_SUCCESS(rc))
+    {
         g_pLwipNat->run();
-
     }
+
     delete g_pLwipNat;
     return 0;
 }
 
 
+static int vboxNetNATLogInit(int argc, char **argv)
+{
+    size_t cch;
+    int rc;
+
+    char szHome[RTPATH_MAX];
+    rc = com::GetVBoxUserHomeDirectory(szHome, sizeof(szHome), false);
+    if (RT_FAILURE(rc))
+        return rc;
+
+    const char *pcszNetwork = NULL;
+
+    // XXX: This duplicates information from VBoxNetBaseService.cpp.
+    // Perhaps option definitions should be exported as public static
+    // member of VBoxNetBaseService?
+    static const RTGETOPTDEF s_aOptions[] = {
+        { "--network", 'n', RTGETOPT_REQ_STRING }
+    };
+
+    RTGETOPTSTATE GetState;
+    RTGetOptInit(&GetState, argc, argv, s_aOptions, RT_ELEMENTS(s_aOptions), 1,
+                 RTGETOPTINIT_FLAGS_NO_STD_OPTS);
+
+    RTGETOPTUNION ValueUnion;
+    int ch;
+    while ((ch = RTGetOpt(&GetState, &ValueUnion)))
+    {
+        if (ch == 'n')
+        {
+            pcszNetwork = ValueUnion.psz;
+            break;
+        }
+    }
+
+    if (pcszNetwork == NULL)
+    {
+        return VERR_MISSING;
+    }
+
+    char szNetwork[RTPATH_MAX];
+    rc = RTStrCopy(szNetwork, sizeof(szNetwork), pcszNetwork);
+    if (RT_FAILURE(rc))
+    {
+        return rc;
+    }
+
+    // sanitize network name to be usable as a path component
+    for (char *p = szNetwork; *p != '\0'; ++p)
+    {
+        if (RTPATH_IS_SEP(*p))
+        {
+            *p = '_';
+        }
+    }
+
+    char szLogFile[RTPATH_MAX];
+    cch = RTStrPrintf(szLogFile, sizeof(szLogFile),
+                      "%s%c%s.log", szHome, RTPATH_DELIMITER, szNetwork);
+    if (cch >= sizeof(szLogFile))
+    {
+        return VERR_BUFFER_OVERFLOW;
+    }
+
+    // sanitize network name some more to be usable as environment variable
+    for (char *p = szNetwork; *p != '\0'; ++p)
+    {
+        if (*p != '_'
+            && (*p < '0' || '9' < *p)
+            && (*p < 'a' || 'z' < *p)
+            && (*p < 'A' || 'Z' < *p))
+        {
+            *p = '_';
+        }
+    }
+
+    char szEnvVarBase[128];
+    cch = RTStrPrintf(szEnvVarBase, sizeof(szEnvVarBase),
+                      "VBOXNET_%s_RELEASE_LOG", szNetwork);
+    if (cch >= sizeof(szEnvVarBase))
+    {
+        return VERR_BUFFER_OVERFLOW;
+    }
+
+    char szError[RTPATH_MAX + 128];
+    rc = com::VBoxLogRelCreate("NAT Network",
+                               szLogFile,
+                               RTLOGFLAGS_PREFIX_TIME_PROG,
+                               "all all.restrict -default.restrict",
+                               szEnvVarBase,
+                               RTLOGDEST_FILE,
+                               32768 /* cMaxEntriesPerGroup */,
+                               0 /* cHistory */,
+                               0 /* uHistoryFileTime */,
+                               0 /* uHistoryFileSize */,
+                               szError, sizeof(szError));
+    return rc;
+}
+
+
 static int fetchNatPortForwardRules(const ComNatPtr& nat, bool fIsIPv6, VECNATSERVICEPF& vec)
 {
     HRESULT hrc;
@@ -1095,7 +1293,8 @@ static int fetchNatPortForwardRules(const ComNatPtr& nat, bool fIsIPv6, VECNATSE
         Log(("%d-%s rule: %ls\n", idxRules, (fIsIPv6 ? "IPv6" : "IPv4"), rules[idxRules]));
         RT_ZERO(Rule);
 
-        int rc = netPfStrToPf(com::Utf8Str(rules[idxRules]).c_str(), 0, &Rule.Pfr);
+        int rc = netPfStrToPf(com::Utf8Str(rules[idxRules]).c_str(),
+                              fIsIPv6, &Rule.Pfr);
         if (RT_FAILURE(rc))
             continue;
 
diff --git a/src/VBox/Devices/Network/lwip-new/vbox/include/lwipopts.h b/src/VBox/NetworkServices/NAT/lwipopts.h
similarity index 77%
rename from src/VBox/Devices/Network/lwip-new/vbox/include/lwipopts.h
rename to src/VBox/NetworkServices/NAT/lwipopts.h
index befb1d2..2ac2645 100644
--- a/src/VBox/Devices/Network/lwip-new/vbox/include/lwipopts.h
+++ b/src/VBox/NetworkServices/NAT/lwipopts.h
@@ -1,5 +1,5 @@
-#ifndef VBOX_LWIP_OPTS_H_
-#define VBOX_LWIP_OPTS_H_
+#ifndef _VBOX_NETNAT_LWIP_OPTS_H_
+#define _VBOX_NETNAT_LWIP_OPTS_H_
 
 #include <iprt/mem.h>
 #include <iprt/alloca.h>    /* This may include malloc.h (msc), which is something that has
@@ -24,6 +24,9 @@
 #define MEM_ALIGNMENT 4
 #endif
 
+/* Padding before Ethernet header to make IP header aligned */
+#define ETH_PAD_SIZE 2
+
 /* IP */
 #define IP_REASSEMBLY 1
 #define IP_REASS_MAX_PBUFS      128
@@ -110,14 +113,12 @@
 #define SYS_LIGHTWEIGHT_PROT 1
 
 /** Attempt to get rid of htons etc. macro issues. */
-#define LWIP_PREFIX_BYTEORDER_FUNCS
-
-#define LWIP_NOASSERT 0
+#undef LWIP_PREFIX_BYTEORDER_FUNCS
 
 #define LWIP_TCPIP_CORE_LOCKING_INPUT 0
 #define LWIP_TCPIP_CORE_LOCKING 0
 #define LWIP_TCP 1
-#define LWIP_SOCKET 1
+#define LWIP_SOCKET 0
 #define LWIP_ARP 1
 #define ARP_PROXY 1
 #define LWIP_ETHERNET 1
@@ -156,51 +157,10 @@
 
 /* Debugging stuff. */
 #ifdef DEBUG
-/* filter in debugging severity */
-# define DBG_TYPES_ON (LWIP_DBG_ON | LWIP_DBG_TRACE | LWIP_DBG_STATE | LWIP_DBG_FRESH | LWIP_DBG_HALT)
-# define DBG_MIN_LEVEL 0
-
-# define LWIP_DEBUG LWIP_DBG_ON
-/* Ethernet & ARP debugging */
-# define ETHARP_DEBUG    LWIP_DBG_ON
-/* IPv4 debugging */
-# define IP_DEBUG    LWIP_DBG_ON
-# define IP_REASS_DEBUG  LWIP_DBG_ON
-/* IPv6 debugging */
-# define IP6_DEBUG LWIP_DBG_ON
-/* ICMP debugging */
-# define ICMP_DEBUG  LWIP_DBG_ON
-/* TCP debugging */
-# define TCP_DEBUG   LWIP_DBG_ON
-# define TCP_INPUT_DEBUG LWIP_DBG_ON
-# define TCP_FR_DEBUG    LWIP_DBG_ON
-# define TCP_RTO_DEBUG   LWIP_DBG_ON
-# define TCP_CWND_DEBUG  LWIP_DBG_ON
-# define TCP_WND_DEBUG   LWIP_DBG_ON
-# define TCP_OUTPUT_DEBUG    LWIP_DBG_ON
-# define TCP_RST_DEBUG   LWIP_DBG_ON
-# define TCP_QLEN_DEBUG  LWIP_DBG_ON
-/* RAW API debugging */
-/* API debugging */
-# define NETIF_DEBUG LWIP_DBG_ON
-# define PBUF_DEBUG  LWIP_DBG_ON
-# define API_LIB_DEBUG   LWIP_DBG_ON
-# define API_MSG_DEBUG   LWIP_DBG_ON
-# define SOCKETS_DEBUG   LWIP_DBG_ON
-
-# define INET_DEBUG  LWIP_DBG_ON
-# define RAW_DEBUG   LWIP_DBG_ON
-# define MEM_DEBUG   LWIP_DBG_ON
-# define MEMP_DEBUG  LWIP_DBG_ON
-# define SYS_DEBUG   LWIP_DBG_ON
-
-# define UDP_DEBUG   LWIP_DBG_ON
-# define TCPIP_DEBUG LWIP_DBG_ON
-# define DHCP_DEBUG  LWIP_DBG_ON
-
-# define LWIP_PROXY_DEBUG LWIP_DBG_ON
-/* Debug checks */
-# define TCP_OVERSIZE_DBGCHECK 1
+# define LWIP_DEBUG
+# include "lwip-log.h"
+
+# define LWIP_PROXY_DEBUG LWIP_DBG_OFF
 #endif /* DEBUG */
 
 /* printf formatter definitions */
@@ -216,7 +176,4 @@
 #define realloc(x,y) RTMemRealloc((x), (y))
 #define free(x) RTMemFree(x)
 
-
-#include "lwip-namespace.h"
-
-#endif
+#endif /* _VBOX_NETNAT_LWIP_OPTS_H_ */
diff --git a/src/VBox/NetworkServices/NAT/portfwd.c b/src/VBox/NetworkServices/NAT/portfwd.c
index c579caf..d459383 100644
--- a/src/VBox/NetworkServices/NAT/portfwd.c
+++ b/src/VBox/NetworkServices/NAT/portfwd.c
@@ -126,8 +126,6 @@ portfwd_pmgr_chan(struct pollmgr_handler *handler, SOCKET fd, int revents)
 }
 
 
-
-#ifndef RT_OS_WINDOWS
 int
 fwspec_set(struct fwspec *fwspec, int sdom, int stype,
            const char *src_addr_str, uint16_t src_port,
@@ -150,7 +148,7 @@ fwspec_set(struct fwspec *fwspec, int sdom, int stype,
 
     status = getaddrinfo(src_addr_str, NULL, &hints, &ai);
     if (status != 0) {
-        DPRINTF(("%s - %s\n", src_addr_str, gai_strerror(status)));
+        LogRel(("\"%s\": %s\n", src_addr_str, gai_strerror(status)));
         return -1;
     }
     LWIP_ASSERT1(ai != NULL);
@@ -161,7 +159,7 @@ fwspec_set(struct fwspec *fwspec, int sdom, int stype,
 
     status = getaddrinfo(dst_addr_str, NULL, &hints, &ai);
     if (status != 0) {
-        DPRINTF(("%s - %s\n", dst_addr_str, gai_strerror(status)));
+        LogRel(("\"%s\": %s\n", dst_addr_str, gai_strerror(status)));
         return -1;
     }
     LWIP_ASSERT1(ai != NULL);
@@ -181,57 +179,6 @@ fwspec_set(struct fwspec *fwspec, int sdom, int stype,
 
     return 0;
 }
-#else  /* RT_OS_WINDOWS */
-/**
- * Windows only provides inet_pton() since Vista, but XP already has
- * WSAStringToAddressA() that does what we want (NB: its AddressString
- * argument is not declared const).
- */
-int
-fwspec_set(struct fwspec *fwspec, int sdom, int stype,
-           const char *src_addr_str, uint16_t src_port,
-           const char *dst_addr_str, uint16_t dst_port)
-{
-    int saf;
-    int socklen;
-    int status;
-
-    LWIP_ASSERT1(sdom == PF_INET || sdom == PF_INET6);
-    LWIP_ASSERT1(stype == SOCK_STREAM || stype == SOCK_DGRAM);
-
-    fwspec->sdom = sdom;
-    fwspec->stype = stype;
-
-    saf = (sdom == PF_INET) ? AF_INET : AF_INET6;
-
-    fwspec->src.sa.sa_family = saf;
-    socklen = sizeof(fwspec->src);
-    status = WSAStringToAddressA((char *)src_addr_str, saf, NULL,
-                                  &fwspec->src.sa, &socklen);
-    if (status == SOCKET_ERROR) {
-        return -1;
-    }
-
-    fwspec->dst.sa.sa_family = saf;
-    socklen = sizeof(fwspec->dst);
-    status = WSAStringToAddressA((char *)dst_addr_str, saf, NULL,
-                                &fwspec->dst.sa, &socklen);
-    if (status == SOCKET_ERROR) {
-        return -1;
-    }
-
-    if (sdom == PF_INET) {
-        fwspec->src.sin.sin_port = htons(src_port);
-        fwspec->dst.sin.sin_port = htons(dst_port); 
-    }
-    else { /* PF_INET6 */
-        fwspec->src.sin6.sin6_port = htons(src_port);
-        fwspec->dst.sin6.sin6_port = htons(dst_port); 
-    }
-
-    return 0;
-}
-#endif /* RT_OS_WINDOWS */
 
 
 int
diff --git a/src/VBox/NetworkServices/NetLib/VBoxNetBaseService.cpp b/src/VBox/NetworkServices/NetLib/VBoxNetBaseService.cpp
index 0a01075..8e0cfd2 100644
--- a/src/VBox/NetworkServices/NetLib/VBoxNetBaseService.cpp
+++ b/src/VBox/NetworkServices/NetLib/VBoxNetBaseService.cpp
@@ -362,7 +362,7 @@ int VBoxNetBaseService::tryGoOnline(void)
     {
         m->m_pSession = NIL_RTR0PTR;
         LogRel(("VBoxNetBaseService: SUPR3Init -> %Rrc\n", rc));
-        return 1;
+        return rc;
     }
 
     char szPath[RTPATH_MAX];
@@ -370,14 +370,14 @@ int VBoxNetBaseService::tryGoOnline(void)
     if (RT_FAILURE(rc))
     {
         LogRel(("VBoxNetBaseService: RTPathExecDir -> %Rrc\n", rc));
-        return 1;
+        return rc;
     }
 
     rc = SUPR3LoadVMM(strcat(szPath, "/VMMR0.r0"));
     if (RT_FAILURE(rc))
     {
         LogRel(("VBoxNetBaseService: SUPR3LoadVMM(\"%s\") -> %Rrc\n", szPath, rc));
-        return 1;
+        return rc;
     }
 
     /*
@@ -406,7 +406,7 @@ int VBoxNetBaseService::tryGoOnline(void)
     if (RT_FAILURE(rc))
     {
         Log2(("VBoxNetBaseService: SUPR3CallVMMR0Ex(,VMMR0_DO_INTNET_OPEN,) failed, rc=%Rrc\n", rc));
-        goto bad;
+        return rc;
     }
     m->m_hIf = OpenReq.hIf;
     Log2(("successfully opened/created \"%s\" - hIf=%#x\n", OpenReq.szNetwork, m->m_hIf));
@@ -425,7 +425,7 @@ int VBoxNetBaseService::tryGoOnline(void)
     if (RT_FAILURE(rc))
     {
         Log2(("VBoxNetBaseService: SUPR3CallVMMR0Ex(,VMMR0_DO_INTNET_IF_GET_BUFFER_PTRS,) failed, rc=%Rrc\n", rc));
-        goto bad;
+        return rc;
     }
     pBuf = GetBufferPtrsReq.pRing3Buf;
     Log2(("pBuf=%p cbBuf=%d cbSend=%d cbRecv=%d\n",
@@ -448,9 +448,7 @@ int VBoxNetBaseService::tryGoOnline(void)
     /* bail out */
     Log2(("VBoxNetBaseService: SUPR3CallVMMR0Ex(,VMMR0_DO_INTNET_IF_SET_PROMISCUOUS_MODE,) failed, rc=%Rrc\n", rc));
 
-    return 0;
-    bad:
-        return 1;
+    return VINF_SUCCESS;
 }
 
 
diff --git a/src/VBox/NetworkServices/NetLib/VBoxNetPortForwardString.cpp b/src/VBox/NetworkServices/NetLib/VBoxNetPortForwardString.cpp
index aa43c41..c533302 100644
--- a/src/VBox/NetworkServices/NetLib/VBoxNetPortForwardString.cpp
+++ b/src/VBox/NetworkServices/NetLib/VBoxNetPortForwardString.cpp
@@ -321,34 +321,9 @@ int netPfStrToPf(const char *pcszStrPortForward, int fIPv6, PPORTFORWARDRULE pPf
     pPfr->fPfrIPv6 = fIPv6;
     pPfr->iPfrProto = proto;
 
-
-    if (strlen(pszHostAddr))
-    {
-        if (!fIPv6)
-            rc = RTNetStrToIPv4Addr(pszHostAddr, &pPfr->uPfrHostAddr.IPv4);
-#if 0 /* No IPv6 yet */
-        else
-            rc = RTNetStrToIPv6Addr(pszHostAddr, &pPfr->uPfrHostAddr.IPv6);
-#endif
-
-        if (RT_FAILURE(rc))
-            goto invalid_parameter;
-    }
-
     pPfr->u16PfrHostPort = u16HostPort;
 
-    if (strlen(pszGuestAddr))
-    {
-        if (!fIPv6)
-            rc = RTNetStrToIPv4Addr(pszGuestAddr, &pPfr->uPfrGuestAddr.IPv4);
-#if 0
-        else
-            rc = RTNetStrToIPv6Addr(pszGuestAddr, &pPfr->uPfrGuestAddr.IPv6);
-#endif
-        if (RT_FAILURE(rc))
-            goto invalid_parameter;
-    }
-    else
+    if (*pszGuestAddr == '\0')
         goto invalid_parameter; /* guest address should be defined */
 
     pPfr->u16PfrGuestPort = u16GuestPort;
diff --git a/src/VBox/NetworkServices/NetLib/VBoxPortForwardString.h b/src/VBox/NetworkServices/NetLib/VBoxPortForwardString.h
index f6647ff..3026452 100644
--- a/src/VBox/NetworkServices/NetLib/VBoxPortForwardString.h
+++ b/src/VBox/NetworkServices/NetLib/VBoxPortForwardString.h
@@ -42,10 +42,8 @@ typedef struct PORTFORWARDRULE
     int        fPfrIPv6;
     /* IPPROTO_{UDP,TCP} */
     int        iPfrProto;
-    RTNETADDRU uPfrHostAddr;
     char       szPfrHostAddr[INET6_ADDRSTRLEN];
     uint16_t   u16PfrHostPort;
-    RTNETADDRU uPfrGuestAddr;
     char       szPfrGuestAddr[INET6_ADDRSTRLEN];
     uint16_t   u16PfrGuestPort;
 } PORTFORWARDRULE, *PPORTFORWARDRULE;
diff --git a/src/VBox/Runtime/VBox/log-vbox.cpp b/src/VBox/Runtime/VBox/log-vbox.cpp
index a273273..390a9a5 100644
--- a/src/VBox/Runtime/VBox/log-vbox.cpp
+++ b/src/VBox/Runtime/VBox/log-vbox.cpp
@@ -257,6 +257,7 @@ RTDECL(PRTLOGGER) RTLogDefaultInit(void)
     ASSERT_LOG_GROUP(HGCM);
     ASSERT_LOG_GROUP(HM);
     ASSERT_LOG_GROUP(IOM);
+    ASSERT_LOG_GROUP(LWIP);
     ASSERT_LOG_GROUP(MAIN);
     ASSERT_LOG_GROUP(MM);
     ASSERT_LOG_GROUP(MM_HEAP);
diff --git a/src/VBox/Runtime/common/asm/ASMAtomicCmpXchgExU64.asm b/src/VBox/Runtime/common/asm/ASMAtomicCmpXchgExU64.asm
index da71254..f6963e1 100644
--- a/src/VBox/Runtime/common/asm/ASMAtomicCmpXchgExU64.asm
+++ b/src/VBox/Runtime/common/asm/ASMAtomicCmpXchgExU64.asm
@@ -36,8 +36,8 @@ BEGINCODE
 ;
 ; @param    pu64     x86:ebp+8   gcc:rdi  msc:rcx
 ; @param    u64New   x86:ebp+c   gcc:rsi  msc:rdx
-; @param    u64Old   x86:ebp+14  gcc:rcx  msc:r8
-; @param    u64Old   x86:ebp+1c  gcc:rdx  msc:r9
+; @param    u64Old   x86:ebp+14  gcc:rdx  msc:r8
+; @param    pu64Old  x86:ebp+1c  gcc:rcx  msc:r9
 ;
 ; @returns  bool result: true if successfully exchanged, false if not.
 ;           x86:al
@@ -49,9 +49,9 @@ BEGINPROC_EXPORTED ASMAtomicCmpXchgExU64
         lock cmpxchg [rcx], rdx
         mov     [r9], rax
  %else
-        mov     rax, rcx
+        mov     rax, rdx
         lock cmpxchg [rdi], rsi
-        mov     [rdx], rax
+        mov     [rcx], rax
  %endif
         setz    al
         movzx   eax, al
diff --git a/src/VBox/Runtime/common/asm/ASMAtomicCmpXchgU64.asm b/src/VBox/Runtime/common/asm/ASMAtomicCmpXchgU64.asm
index d6ee4d6..0474644 100644
--- a/src/VBox/Runtime/common/asm/ASMAtomicCmpXchgU64.asm
+++ b/src/VBox/Runtime/common/asm/ASMAtomicCmpXchgU64.asm
@@ -36,7 +36,7 @@ BEGINCODE
 ;
 ; @param    pu64     x86:ebp+8   gcc:rdi  msc:rcx
 ; @param    u64New   x86:ebp+c   gcc:rsi  msc:rdx
-; @param    u64Old   x86:ebp+14  gcc:rcx  msc:r8
+; @param    u64Old   x86:ebp+14  gcc:rdx  msc:r8
 ;
 ; @returns  bool result: true if successfully exchanged, false if not.
 ;           x86:al
@@ -47,7 +47,7 @@ BEGINPROC_EXPORTED ASMAtomicCmpXchgU64
         mov     rax, r8
         lock cmpxchg [rcx], rdx
  %else
-        mov     rax, rcx
+        mov     rax, rdx
         lock cmpxchg [rdi], rsi
  %endif
         setz    al
diff --git a/src/VBox/Runtime/common/asm/ASMCpuIdExSlow.asm b/src/VBox/Runtime/common/asm/ASMCpuIdExSlow.asm
index 53ef492..772aee3 100644
--- a/src/VBox/Runtime/common/asm/ASMCpuIdExSlow.asm
+++ b/src/VBox/Runtime/common/asm/ASMCpuIdExSlow.asm
@@ -36,8 +36,8 @@ BEGINCODE
 ;
 ; @param    uOperator   x86:ebp+8   gcc:rdi      msc:rcx
 ; @param    uInitEBX    x86:ebp+c   gcc:rsi      msc:rdx
-; @param    uInitECX    x86:ebp+10  gcc:rcx      msc:r8
-; @param    uInitEDX    x86:ebp+14  gcc:rdx      msc:r9
+; @param    uInitECX    x86:ebp+10  gcc:rdx      msc:r8
+; @param    uInitEDX    x86:ebp+14  gcc:rcx      msc:r9
 ; @param    pvEAX       x86:ebp+18  gcc:r8       msc:rbp+30h
 ; @param    pvEBX       x86:ebp+1c  gcc:r9       msc:rbp+38h
 ; @param    pvECX       x86:ebp+20  gcc:rbp+10h  msc:rbp+40h
@@ -65,6 +65,7 @@ BEGINPROC_EXPORTED ASMCpuIdExSlow
 %elifdef ASM_CALL64_GCC
         mov     eax, edi
         mov     ebx, esi
+        xchg    ecx, edx
         mov     r10, [rbp + 10h]
         mov     r11, [rbp + 18h]
 %elifdef RT_ARCH_X86
diff --git a/src/VBox/Runtime/common/asm/ASMCpuId_Idx_ECX.asm b/src/VBox/Runtime/common/asm/ASMCpuId_Idx_ECX.asm
index ca7f1fb..9992fb2 100644
--- a/src/VBox/Runtime/common/asm/ASMCpuId_Idx_ECX.asm
+++ b/src/VBox/Runtime/common/asm/ASMCpuId_Idx_ECX.asm
@@ -36,8 +36,8 @@ BEGINCODE
 ;
 ; @param    uOperator   x86:ebp+8   gcc:rdi  msc:rcx
 ; @param    uIdxECX     x86:ebp+c   gcc:rsi  msc:rdx
-; @param    pvEAX       x86:ebp+10  gcc:rcx  msc:r8
-; @param    pvEBX       x86:ebp+14  gcc:rdx  msc:r9
+; @param    pvEAX       x86:ebp+10  gcc:rdx  msc:r8
+; @param    pvEBX       x86:ebp+14  gcc:rcx  msc:r9
 ; @param    pvECX       x86:ebp+18  gcc:r8   msc:rsp+28h
 ; @param    pvEDX       x86:ebp+1c  gcc:r9   msc:rsp+30h
 ;
@@ -64,10 +64,10 @@ BEGINPROC_EXPORTED ASMCpuId_Idx_ECX
         mov     [rbx], edx
 
  %else
+        mov     rsi, rdx
+        mov     r11, rcx
         mov     eax, edi
-        xchg    rcx, rsi
-        mov     ecx, ecx                ; paranoia: clear upper bits
-        mov     r11, rdx
+        mov     ecx, esi
         xor     ebx, ebx
         xor     edx, edx
 
diff --git a/src/VBox/Runtime/common/string/strformatrt.cpp b/src/VBox/Runtime/common/string/strformatrt.cpp
index 5bf61a4..4dd69f1 100644
--- a/src/VBox/Runtime/common/string/strformatrt.cpp
+++ b/src/VBox/Runtime/common/string/strformatrt.cpp
@@ -56,6 +56,121 @@
 #include "internal/string.h"
 
 
+/**
+ * Helper function to format IPv6 address according to RFC 5952.
+ *
+ * @returns The number of bytes formatted.
+ * @param   pfnOutput       Pointer to output function.
+ * @param   pvArgOutput     Argument for the output function.
+ * @param   pIpv6Addr       IPv6 address
+ */
+static size_t rtstrFormatIPv6(PFNRTSTROUTPUT pfnOutput, void *pvArgOutput, PCRTNETADDRIPV6 pIpv6Addr)
+{
+    size_t cch = 0; /* result */
+
+    bool fEmbeddedIpv4;
+    size_t cwHexPart;
+    size_t cwZeroRun, cwLongestZeroRun;
+    size_t iZeroStart, iLongestZeroStart;
+    size_t idx;
+
+    Assert(pIpv6Addr != NULL);
+
+    /*
+     * Check for embedded IPv4 address.
+     *
+     * IPv4-compatible - ::11.22.33.44 (obsolete)
+     * IPv4-mapped     - ::ffff:11.22.33.44
+     * IPv4-translated - ::ffff:0:11.22.33.44 (RFC 2765)
+     */
+    fEmbeddedIpv4 = false;
+    cwHexPart = RT_ELEMENTS(pIpv6Addr->au16);
+    if (pIpv6Addr->au64[0] == 0
+        && (   (pIpv6Addr->au32[2] == 0
+                && (   pIpv6Addr->au32[3] != 0
+                    && pIpv6Addr->au32[3] != RT_H2BE_U32_C(1)))
+            || pIpv6Addr->au32[2] == RT_H2BE_U32_C(0x0000ffff)
+            || pIpv6Addr->au32[2] == RT_H2BE_U32_C(0xffff0000)))
+    {
+        fEmbeddedIpv4 = true;
+        cwHexPart -= 2;
+    }
+
+    cwZeroRun = cwLongestZeroRun = 0;
+    iZeroStart = iLongestZeroStart = -1;
+    for (idx = 0; idx <= cwHexPart; ++idx)
+    {
+        if (idx < cwHexPart && pIpv6Addr->au16[idx] == 0)
+        {
+            if (cwZeroRun == 0)
+            {
+                cwZeroRun = 1;
+                iZeroStart = idx;
+            }
+            else
+                ++cwZeroRun;
+        }
+        else
+        {
+            if (cwZeroRun != 0)
+            {
+                if (cwZeroRun > 1 && cwZeroRun > cwLongestZeroRun)
+                {
+                    cwLongestZeroRun = cwZeroRun;
+                    iLongestZeroStart = iZeroStart;
+                }
+                cwZeroRun = 0;
+                iZeroStart = -1;
+            }
+        }
+    }
+
+    if (cwLongestZeroRun == 0)
+    {
+        for (idx = 0; idx < cwHexPart; ++idx)
+            cch += RTStrFormat(pfnOutput, pvArgOutput, NULL, 0,
+                               "%s%x",
+                               idx == 0 ? "" : ":",
+                               RT_BE2H_U16(pIpv6Addr->au16[idx]));
+
+        if (fEmbeddedIpv4)
+            cch += RTStrFormat(pfnOutput, pvArgOutput, NULL, 0, ":");
+    }
+    else
+    {
+        const size_t iLongestZeroEnd = iLongestZeroStart + cwLongestZeroRun;
+
+        if (iLongestZeroStart == 0)
+            cch += RTStrFormat(pfnOutput, pvArgOutput, NULL, 0, ":");
+        else
+            for (idx = 0; idx < iLongestZeroStart; ++idx)
+                cch += RTStrFormat(pfnOutput, pvArgOutput, NULL, 0,
+                                   "%x:", RT_BE2H_U16(pIpv6Addr->au16[idx]));
+
+        if (iLongestZeroEnd == cwHexPart)
+            cch += RTStrFormat(pfnOutput, pvArgOutput, NULL, 0, ":");
+        else
+        {
+            for (idx = iLongestZeroEnd; idx < cwHexPart; ++idx)
+                cch += RTStrFormat(pfnOutput, pvArgOutput, NULL, 0,
+                                   ":%x", RT_BE2H_U16(pIpv6Addr->au16[idx]));
+
+            if (fEmbeddedIpv4)
+                cch += RTStrFormat(pfnOutput, pvArgOutput, NULL, 0, ":");
+        }
+    }
+
+    if (fEmbeddedIpv4)
+        cch += RTStrFormat(pfnOutput, pvArgOutput, NULL, 0,
+                           "%u.%u.%u.%u",
+                           pIpv6Addr->au8[12],
+                           pIpv6Addr->au8[13],
+                           pIpv6Addr->au8[14],
+                           pIpv6Addr->au8[15]);
+
+    return cch;
+}
+
 
 /**
  * Callback to format iprt formatting extentions.
@@ -394,24 +509,7 @@ DECLHIDDEN(size_t) rtstrFormatRt(PFNRTSTROUTPUT pfnOutput, void *pvArgOutput, co
                     case RTSF_IPV6:
                     {
                         if (VALID_PTR(u.pIpv6Addr))
-                            return RTStrFormat(pfnOutput, pvArgOutput, NULL, 0,
-                                               "%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x",
-                                               u.pIpv6Addr->au8[0],
-                                               u.pIpv6Addr->au8[1],
-                                               u.pIpv6Addr->au8[2],
-                                               u.pIpv6Addr->au8[3],
-                                               u.pIpv6Addr->au8[4],
-                                               u.pIpv6Addr->au8[5],
-                                               u.pIpv6Addr->au8[6],
-                                               u.pIpv6Addr->au8[7],
-                                               u.pIpv6Addr->au8[8],
-                                               u.pIpv6Addr->au8[9],
-                                               u.pIpv6Addr->au8[10],
-                                               u.pIpv6Addr->au8[11],
-                                               u.pIpv6Addr->au8[12],
-                                               u.pIpv6Addr->au8[13],
-                                               u.pIpv6Addr->au8[14],
-                                               u.pIpv6Addr->au8[15]);
+                            return rtstrFormatIPv6(pfnOutput, pvArgOutput, u.pIpv6Addr);
                         return pfnOutput(pvArgOutput, s_szNull, sizeof(s_szNull) - 1);
                     }
 
@@ -453,42 +551,11 @@ DECLHIDDEN(size_t) rtstrFormatRt(PFNRTSTROUTPUT pfnOutput, void *pvArgOutput, co
 
                                 case RTNETADDRTYPE_IPV6:
                                     if (u.pNetAddr->uPort == RTNETADDR_PORT_NA)
-                                        return RTStrFormat(pfnOutput, pvArgOutput, NULL, 0,
-                                                           "%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x",
-                                                           u.pNetAddr->uAddr.IPv6.au8[0],
-                                                           u.pNetAddr->uAddr.IPv6.au8[1],
-                                                           u.pNetAddr->uAddr.IPv6.au8[2],
-                                                           u.pNetAddr->uAddr.IPv6.au8[3],
-                                                           u.pNetAddr->uAddr.IPv6.au8[4],
-                                                           u.pNetAddr->uAddr.IPv6.au8[5],
-                                                           u.pNetAddr->uAddr.IPv6.au8[6],
-                                                           u.pNetAddr->uAddr.IPv6.au8[7],
-                                                           u.pNetAddr->uAddr.IPv6.au8[8],
-                                                           u.pNetAddr->uAddr.IPv6.au8[9],
-                                                           u.pNetAddr->uAddr.IPv6.au8[10],
-                                                           u.pNetAddr->uAddr.IPv6.au8[11],
-                                                           u.pNetAddr->uAddr.IPv6.au8[12],
-                                                           u.pNetAddr->uAddr.IPv6.au8[13],
-                                                           u.pNetAddr->uAddr.IPv6.au8[14],
-                                                           u.pNetAddr->uAddr.IPv6.au8[15]);
+                                        return rtstrFormatIPv6(pfnOutput, pvArgOutput, &u.pNetAddr->uAddr.IPv6);
+
                                     return RTStrFormat(pfnOutput, pvArgOutput, NULL, 0,
-                                                       "%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x %u",
-                                                       u.pNetAddr->uAddr.IPv6.au8[0],
-                                                       u.pNetAddr->uAddr.IPv6.au8[1],
-                                                       u.pNetAddr->uAddr.IPv6.au8[2],
-                                                       u.pNetAddr->uAddr.IPv6.au8[3],
-                                                       u.pNetAddr->uAddr.IPv6.au8[4],
-                                                       u.pNetAddr->uAddr.IPv6.au8[5],
-                                                       u.pNetAddr->uAddr.IPv6.au8[6],
-                                                       u.pNetAddr->uAddr.IPv6.au8[7],
-                                                       u.pNetAddr->uAddr.IPv6.au8[8],
-                                                       u.pNetAddr->uAddr.IPv6.au8[9],
-                                                       u.pNetAddr->uAddr.IPv6.au8[10],
-                                                       u.pNetAddr->uAddr.IPv6.au8[11],
-                                                       u.pNetAddr->uAddr.IPv6.au8[12],
-                                                       u.pNetAddr->uAddr.IPv6.au8[13],
-                                                       u.pNetAddr->uAddr.IPv6.au8[14],
-                                                       u.pNetAddr->uAddr.IPv6.au8[15],
+                                                       "[%RTnaipv6]:%u",
+                                                       &u.pNetAddr->uAddr.IPv6,
                                                        u.pNetAddr->uPort);
 
                                 case RTNETADDRTYPE_MAC:
diff --git a/src/VBox/Runtime/generic/env-generic.cpp b/src/VBox/Runtime/generic/env-generic.cpp
index 9afb4d8..0d9a13b 100644
--- a/src/VBox/Runtime/generic/env-generic.cpp
+++ b/src/VBox/Runtime/generic/env-generic.cpp
@@ -234,6 +234,11 @@ RTDECL(int) RTEnvClone(PRTENV pEnv, RTENV EnvToClone)
 #ifdef RTENV_HAVE_WENVIRON
         papszEnv  = NULL;
         papwszEnv = (PCRTUTF16 * const )_wenviron;
+        if (!papwszEnv)
+        {
+            _wgetenv(L"Path"); /* Force the CRT to initalize it. */
+            papwszEnv = (PCRTUTF16 * const)_wenviron;
+        }
         if (papwszEnv)
             while (papwszEnv[cVars])
                 cVars++;
diff --git a/src/VBox/Runtime/r0drv/nt/ntBldSymDb.cpp b/src/VBox/Runtime/r0drv/nt/ntBldSymDb.cpp
index 0c185de..0ffd6ca 100644
--- a/src/VBox/Runtime/r0drv/nt/ntBldSymDb.cpp
+++ b/src/VBox/Runtime/r0drv/nt/ntBldSymDb.cpp
@@ -749,6 +749,7 @@ static RTEXITCODE FigurePdbVersionInfo(const char *pszPdb, PRTNTSDBOSVER pVerInf
      *  - Windows_Win7.7600.16385.090713-1255.X64CHK
      *  - Windows_Win7SP1.7601.17514.101119-1850.AMD64FRE
      *  - Windows_Win8.9200.16384.120725-1247.X86CHK
+     *  - en_windows_8_1_symbols_debug_checked_x64_2712568
      */
     bool fFound = false;
     uint32_t i = u.Split.cComps - 1;
@@ -784,10 +785,11 @@ static RTEXITCODE FigurePdbVersionInfo(const char *pszPdb, PRTNTSDBOSVER pVerInf
             { RT_STR_TUPLE("Windows_Winmain.7100"),             6, 1, 0, 7100 }, /* RC */
             { RT_STR_TUPLE("Windows_Win7.7600"),                6, 1, 0, 7600 }, /* RC */
             { RT_STR_TUPLE("Windows_Win7SP1.7601"),             6, 1, 1, 7601 }, /* RC */
-            { RT_STR_TUPLE("Windows_Winmain.8102"),             6, 1, 0, 8102 }, /* preview */
-            { RT_STR_TUPLE("Windows_Winmain.8250"),             6, 1, 0, 8250 }, /* beta */
-            { RT_STR_TUPLE("Windows_Winmain.8400"),             6, 1, 0, 8400 }, /* RC */
-            { RT_STR_TUPLE("Windows_Win8.9200"),                6, 1, 0, 9200 }, /* RTM */
+            { RT_STR_TUPLE("Windows_Winmain.8102"),             6, 2, 0, 8102 }, /* preview */
+            { RT_STR_TUPLE("Windows_Winmain.8250"),             6, 2, 0, 8250 }, /* beta */
+            { RT_STR_TUPLE("Windows_Winmain.8400"),             6, 2, 0, 8400 }, /* RC */
+            { RT_STR_TUPLE("Windows_Win8.9200"),                6, 2, 0, 9200 }, /* RTM */
+            { RT_STR_TUPLE("en_windows_8_1"),                   6, 3, 0, 9600 }, /* RTM */
         };
 
         const char *pszComp  = u.Split.apszComps[i];
@@ -822,6 +824,7 @@ static RTEXITCODE FigurePdbVersionInfo(const char *pszPdb, PRTNTSDBOSVER pVerInf
             || RTStrIStr(pszComp, "_x86chk_")
             || RTStrIStr(pszComp, "-x86-DEBUG")
             || (RTStrIStr(pszComp, "-x86-") && RTStrIStr(pszComp, "-DEBUG"))
+            || RTStrIStr(pszComp, "_debug_checked_x86")
            )
         {
             pVerInfo->fChecked = true;
@@ -831,6 +834,7 @@ static RTEXITCODE FigurePdbVersionInfo(const char *pszPdb, PRTNTSDBOSVER pVerInf
                  || RTStrIStr(pszComp, ".amd64chk.")
                  || RTStrIStr(pszComp, ".x64.chk.")
                  || RTStrIStr(pszComp, ".x64chk.")
+                 || RTStrIStr(pszComp, "_debug_checked_x64")
                 )
         {
             pVerInfo->fChecked = true;
@@ -852,6 +856,11 @@ static RTEXITCODE FigurePdbVersionInfo(const char *pszPdb, PRTNTSDBOSVER pVerInf
             pVerInfo->fChecked = true;
             *penmArch = MYARCH_X86;
         }
+        else if (RTStrIStr(pszComp, "_x64"))
+        {
+            pVerInfo->fChecked = false;
+            *penmArch = MYARCH_AMD64;
+        }
         else
         {
             pVerInfo->fChecked = false;
@@ -1137,7 +1146,7 @@ int main(int argc, char **argv)
                 break;
 
             case 'V':
-                RTPrintf("$Revision: 85141 $");
+                RTPrintf("$Revision: 92629 $");
                 break;
 
             case 'h':
diff --git a/src/VBox/Runtime/r0drv/nt/symdbdata.h b/src/VBox/Runtime/r0drv/nt/symdbdata.h
index b997dd6..d23aca8 100644
--- a/src/VBox/Runtime/r0drv/nt/symdbdata.h
+++ b/src/VBox/Runtime/r0drv/nt/symdbdata.h
@@ -2741,7 +2741,7 @@ const RTNTSDBSET g_artNtSdbSets[] =
         /*.OsVerInfo = */
         {
             /* .uMajorVer = */ 6,
-            /* .uMinorVer = */ 1,
+            /* .uMinorVer = */ 2,
             /* .fChecked  = */ false,
             /* .fSmp      = */ true,
             /* .uCsdNo    = */ 0,
@@ -2763,7 +2763,7 @@ const RTNTSDBSET g_artNtSdbSets[] =
         /*.OsVerInfo = */
         {
             /* .uMajorVer = */ 6,
-            /* .uMinorVer = */ 1,
+            /* .uMinorVer = */ 2,
             /* .fChecked  = */ false,
             /* .fSmp      = */ true,
             /* .uCsdNo    = */ 0,
@@ -2785,7 +2785,7 @@ const RTNTSDBSET g_artNtSdbSets[] =
         /*.OsVerInfo = */
         {
             /* .uMajorVer = */ 6,
-            /* .uMinorVer = */ 1,
+            /* .uMinorVer = */ 2,
             /* .fChecked  = */ true,
             /* .fSmp      = */ true,
             /* .uCsdNo    = */ 0,
@@ -2807,7 +2807,7 @@ const RTNTSDBSET g_artNtSdbSets[] =
         /*.OsVerInfo = */
         {
             /* .uMajorVer = */ 6,
-            /* .uMinorVer = */ 1,
+            /* .uMinorVer = */ 2,
             /* .fChecked  = */ true,
             /* .fSmp      = */ true,
             /* .uCsdNo    = */ 0,
@@ -2824,6 +2824,94 @@ const RTNTSDBSET g_artNtSdbSets[] =
         },
     },
 # endif
+# ifdef RT_ARCH_X86
+    {   /* Source: s:\WinSyms\u\en_windows_8_1_symbols_x86_2712593\ntkrpamp.pdb\9DC1F995475C456C8D1AA9606E3106931\ntkrpamp.pdb */
+        /*.OsVerInfo = */
+        {
+            /* .uMajorVer = */ 6,
+            /* .uMinorVer = */ 3,
+            /* .fChecked  = */ false,
+            /* .fSmp      = */ true,
+            /* .uCsdNo    = */ 0,
+            /* .uBuildNo  = */ 9600,
+        },
+        /* .KPRCB = */
+        {
+            /* .offQuantumEnd                = */ 0x2239,
+            /* .cbQuantumEnd                 = */ 0x0001,
+            /* .offDpcQueueDepth             = */ 0x21ec,
+            /* .cbDpcQueueDepth              = */ 0x0004,
+            /* .offVendorString              = */ 0x3c7c,
+            /* .cbVendorString               = */ 0x000d,
+        },
+    },
+# endif
+# ifdef RT_ARCH_AMD64
+    {   /* Source: s:\WinSyms\u\en_windows_8_1_symbols_x64_2712576\ntkrnlmp.pdb\A9BBA3C139724A738BE17665DB4393CA1\ntkrnlmp.pdb */
+        /*.OsVerInfo = */
+        {
+            /* .uMajorVer = */ 6,
+            /* .uMinorVer = */ 3,
+            /* .fChecked  = */ false,
+            /* .fSmp      = */ true,
+            /* .uCsdNo    = */ 0,
+            /* .uBuildNo  = */ 9600,
+        },
+        /* .KPRCB = */
+        {
+            /* .offQuantumEnd                = */ 0x2de9,
+            /* .cbQuantumEnd                 = */ 0x0001,
+            /* .offDpcQueueDepth             = */ 0x2d98,
+            /* .cbDpcQueueDepth              = */ 0x0004,
+            /* .offVendorString              = */ 0x5958,
+            /* .cbVendorString               = */ 0x000d,
+        },
+    },
+# endif
+# ifdef RT_ARCH_X86
+    {   /* Source: s:\WinSyms\u\en_windows_8_1_symbols_debug_checked_x86_2712583\ntkrpamp.pdb\77DAB075113647B5888133D3F79B7B171\ntkrpamp.pdb */
+        /*.OsVerInfo = */
+        {
+            /* .uMajorVer = */ 6,
+            /* .uMinorVer = */ 3,
+            /* .fChecked  = */ true,
+            /* .fSmp      = */ true,
+            /* .uCsdNo    = */ 0,
+            /* .uBuildNo  = */ 9600,
+        },
+        /* .KPRCB = */
+        {
+            /* .offQuantumEnd                = */ 0x2239,
+            /* .cbQuantumEnd                 = */ 0x0001,
+            /* .offDpcQueueDepth             = */ 0x21ec,
+            /* .cbDpcQueueDepth              = */ 0x0004,
+            /* .offVendorString              = */ 0x3c7c,
+            /* .cbVendorString               = */ 0x000d,
+        },
+    },
+# endif
+# ifdef RT_ARCH_AMD64
+    {   /* Source: s:\WinSyms\u\en_windows_8_1_symbols_debug_checked_x64_2712568\ntkrnlmp.pdb\4C5FFE3E839647C5B9471D0C8F9710E11\ntkrnlmp.pdb */
+        /*.OsVerInfo = */
+        {
+            /* .uMajorVer = */ 6,
+            /* .uMinorVer = */ 3,
+            /* .fChecked  = */ true,
+            /* .fSmp      = */ true,
+            /* .uCsdNo    = */ 0,
+            /* .uBuildNo  = */ 9600,
+        },
+        /* .KPRCB = */
+        {
+            /* .offQuantumEnd                = */ 0x2de9,
+            /* .cbQuantumEnd                 = */ 0x0001,
+            /* .offDpcQueueDepth             = */ 0x2d98,
+            /* .cbDpcQueueDepth              = */ 0x0004,
+            /* .offVendorString              = */ 0x5958,
+            /* .cbVendorString               = */ 0x000d,
+        },
+    },
+# endif
 };
 #endif /* !RTNTSDB_NO_DATA */
 
diff --git a/src/VBox/Runtime/r3/linux/sysfs.cpp b/src/VBox/Runtime/r3/linux/sysfs.cpp
index f5dfc6a..1530933 100644
--- a/src/VBox/Runtime/r3/linux/sysfs.cpp
+++ b/src/VBox/Runtime/r3/linux/sysfs.cpp
@@ -53,8 +53,7 @@
  * Constructs the path of a sysfs file from the format parameters passed,
  * prepending a prefix if the path is relative.
  *
- * @returns The number of characters returned, or -1 and errno set to ERANGE on
- *          failure.
+ * @returns The number of characters returned, or an iprt error code on failure.
  *
  * @param   pszPrefix  The prefix to prepend if the path is relative.  Must end
  *                     in '/'.
@@ -70,8 +69,8 @@ static ssize_t rtLinuxConstructPathV(char *pszBuf, size_t cchBuf,
                                      const char *pszFormat, va_list va)
 {
     size_t cchPrefix = strlen(pszPrefix);
-    AssertReturnStmt(pszPrefix[cchPrefix - 1] == '/', errno = ERANGE, -1);
-    AssertReturnStmt(cchBuf > cchPrefix + 1, errno = ERANGE, -1);
+    AssertReturn(pszPrefix[cchPrefix - 1] == '/', VERR_INVALID_PARAMETER);
+    AssertReturn(cchBuf > cchPrefix + 1, VERR_INVALID_PARAMETER);
 
     /** @todo While RTStrPrintfV prevents overflows, it doesn't make it easy to
      *        check for truncations. RTPath should provide some formatters and
@@ -80,7 +79,7 @@ static ssize_t rtLinuxConstructPathV(char *pszBuf, size_t cchBuf,
     size_t cch = RTStrPrintfV(pszBuf, cchBuf, pszFormat, va);
     if (*pszBuf != '/')
     {
-        AssertReturnStmt(cchBuf >= cch + cchPrefix + 1, errno = ERANGE, -1);
+        AssertReturn(cchBuf >= cch + cchPrefix + 1, VERR_BUFFER_OVERFLOW);
         memmove(pszBuf + cchPrefix, pszBuf, cch + 1);
         memcpy(pszBuf, pszPrefix, cchPrefix);
         cch += cchPrefix;
@@ -93,8 +92,8 @@ static ssize_t rtLinuxConstructPathV(char *pszBuf, size_t cchBuf,
  * Constructs the path of a sysfs file from the format parameters passed,
  * prepending a prefix if the path is relative.
  *
- * @returns The number of characters returned, or -1 and errno set to ERANGE on
- *        failure.
+ * @returns The number of characters returned, or an iprt error code on failure.
+ * @note  Unused.
  *
  * @param   pszPrefix  The prefix to prepend if the path is relative.  Must end
  *                     in '/'.
@@ -131,7 +130,11 @@ static ssize_t rtLinuxConstructPath(char *pszBuf, size_t cchBuf,
  */
 static ssize_t rtLinuxSysFsConstructPath(char *pszBuf, size_t cchBuf, const char *pszFormat, va_list va)
 {
-    return rtLinuxConstructPathV(pszBuf, cchBuf, "/sys/", pszFormat, va);
+    ssize_t rc = rtLinuxConstructPathV(pszBuf, cchBuf, "/sys/", pszFormat, va);
+    if (rc >= 0)
+        return rc;
+    errno = ERANGE;
+    return -1;
 }
 
 
@@ -409,125 +412,118 @@ RTDECL(ssize_t) RTLinuxSysFsGetLinkDest(char *pszBuf, size_t cchBuf, const char
 }
 
 
-static ssize_t rtLinuxFindDevicePathRecursive(dev_t DevNum, RTFMODE fMode, const char *pszBasePath,
-                                              char *pszBuf, size_t cchBuf)
+/** Search for a device node with the number @a DevNum and the type (character
+ * or block) @a fMode below the path @a pszPath.  @a pszPath MUST point to a
+ * buffer of size at least RTPATH_MAX which will be modified during the function
+ * execution.  On successful return it will contain the path to the device node
+ * found. */
+/** @note This function previously used a local stack buffer of size RTPATH_MAX
+ *    to construct the path passed to the next recursive call, which used up 4K
+ *    of stack space per iteration and caused a stack overflow on a path with
+ *    too many components. */
+static int rtLinuxFindDevicePathRecursive(dev_t DevNum, RTFMODE fMode,
+                                          char *pszPath)
 {
+    int rc;
+    PRTDIR  pDir;
+    size_t const cchPath = strlen(pszPath);
+
     /*
      * Check assumptions made by the code below.
      */
-    size_t const cchBasePath = strlen(pszBasePath);
-    AssertReturnStmt(cchBasePath < RTPATH_MAX - 10U, errno = ENAMETOOLONG, -1);
-
-    ssize_t rcRet;
-    PRTDIR  pDir;
-    int rc = RTDirOpen(&pDir, pszBasePath);
+    AssertReturn(cchPath < RTPATH_MAX - 10U, VERR_BUFFER_OVERFLOW);
+    rc = RTDirOpen(&pDir, pszPath);
     if (RT_SUCCESS(rc))
     {
-        char szPath[RTPATH_MAX]; /** @todo 4K per recursion - can easily be optimized away by passing it along pszBasePath
-                                           and only remember the length. */
-        memcpy(szPath, pszBasePath, cchBasePath + 1);
-
         for (;;)
         {
             RTDIRENTRYEX Entry;
-            rc = RTDirReadEx(pDir, &Entry, NULL, RTFSOBJATTRADD_UNIX, RTPATH_F_ON_LINK);
+            rc = RTDirReadEx(pDir, &Entry, NULL, RTFSOBJATTRADD_UNIX,
+                             RTPATH_F_ON_LINK);
             if (RT_FAILURE(rc))
-            {
-                errno = rc == VERR_NO_MORE_FILES
-                      ? ENOENT
-                      : rc == VERR_BUFFER_OVERFLOW
-                      ? EOVERFLOW
-                      : EIO;
-                rcRet = -1;
                 break;
-            }
             if (RTFS_IS_SYMLINK(Entry.Info.Attr.fMode))
                 continue;
-
+            pszPath[cchPath] = '\0';
+            rc = RTPathAppend(pszPath, RTPATH_MAX, Entry.szName);
+            if (RT_FAILURE(rc))
+                break;
             /* Do the matching. */
             if (   Entry.Info.Attr.u.Unix.Device == DevNum
                 && (Entry.Info.Attr.fMode & RTFS_TYPE_MASK) == fMode)
-            {
-                rcRet = rtLinuxConstructPath(pszBuf, cchBuf, pszBasePath, "%s", Entry.szName);
                 break;
-            }
-
             /* Recurse into subdirectories. */
             if (!RTFS_IS_DIRECTORY(Entry.Info.Attr.fMode))
                 continue;
             if (Entry.szName[0] == '.')
                 continue;
-
-            szPath[cchBasePath] = '\0';
-            rc = RTPathAppend(szPath, sizeof(szPath) - 1, Entry.szName); /* -1: for slash */
-            if (RT_FAILURE(rc))
-            {
-                errno = ENAMETOOLONG;
-                rcRet = -1;
-                break;
-            }
-            strcat(&szPath[cchBasePath], "/");
-            rcRet = rtLinuxFindDevicePathRecursive(DevNum, fMode, szPath, pszBuf, cchBuf);
-            if (rcRet >= 0 || errno != ENOENT)
+            rc = rtLinuxFindDevicePathRecursive(DevNum, fMode, pszPath);
+            if (RT_SUCCESS(rc) || rc != VERR_NO_MORE_FILES)
                 break;
         }
         RTDirClose(pDir);
     }
-    else
-    {
-        rcRet = -1;
-        errno = RTErrConvertToErrno(rc);
-    }
-    return rcRet;
+    return rc;
 }
 
 
-RTDECL(ssize_t) RTLinuxFindDevicePathV(dev_t DevNum, RTFMODE fMode, char *pszBuf, size_t cchBuf,
-                                       const char *pszSuggestion, va_list va)
+RTDECL(ssize_t) RTLinuxFindDevicePathV(dev_t DevNum, RTFMODE fMode, char *pszBuf,
+                                       size_t cchBuf, const char *pszSuggestion,
+                                       va_list va)
 {
-    AssertReturnStmt(cchBuf >= 2, errno = EINVAL, -1);
-    AssertReturnStmt(   fMode == RTFS_TYPE_DEV_CHAR
-                     || fMode == RTFS_TYPE_DEV_BLOCK,
-                     errno = EINVAL, -1);
+    char szFilename[RTPATH_MAX];
+    int rc = VINF_TRY_AGAIN;
 
+    AssertReturn(cchBuf >= 2, VERR_INVALID_PARAMETER);
+    AssertReturn(   fMode == RTFS_TYPE_DEV_CHAR
+                 || fMode == RTFS_TYPE_DEV_BLOCK,
+                 VERR_INVALID_PARAMETER);
     if (pszSuggestion)
     {
         /*
          * Construct the filename and read the link.
          */
-        char szFilename[RTPATH_MAX];
-        int rc = rtLinuxConstructPathV(szFilename, sizeof(szFilename), "/dev/", pszSuggestion, va);
-        if (rc == -1)
-            return -1;
-
-        /*
-         * Check whether the caller's suggestion was right.
-         */
-        RTFSOBJINFO Info;
-        rc = RTPathQueryInfo(szFilename, &Info, RTFSOBJATTRADD_UNIX);
-        if (   RT_SUCCESS(rc)
-            && Info.Attr.u.Unix.Device == DevNum
-            && (Info.Attr.fMode & RTFS_TYPE_MASK) == fMode)
+        rc = rtLinuxConstructPathV(szFilename, sizeof(szFilename), "/dev/",
+                                   pszSuggestion, va);
+        if (rc > 0)
         {
-            size_t cchPath = strlen(szFilename);
-            if (cchPath >= cchBuf)
-            {
-                errno = EOVERFLOW;
-                return -1;
-            }
-            memcpy(pszBuf, szFilename, cchPath + 1);
-            return cchPath;
+            /*
+             * Check whether the caller's suggestion was right.
+             */
+            RTFSOBJINFO Info;
+            rc = RTPathQueryInfo(szFilename, &Info, RTFSOBJATTRADD_UNIX);
+            if (   rc == VERR_PATH_NOT_FOUND 
+                || rc == VERR_FILE_NOT_FOUND
+                || (   RT_SUCCESS(rc)
+                    && (   Info.Attr.u.Unix.Device != DevNum
+                        || (Info.Attr.fMode & RTFS_TYPE_MASK) != fMode)))
+            /* The suggestion was wrong, fall back on the brute force attack. */
+                rc = VINF_TRY_AGAIN;
         }
-
-        /* The suggestion was wrong, fall back on the brute force attack. */
     }
 
-    return rtLinuxFindDevicePathRecursive(DevNum, fMode, "/dev/", pszBuf, cchBuf);
+    if (rc == VINF_TRY_AGAIN)
+    {
+        RTStrCopy(szFilename, sizeof(szFilename), "/dev/");
+        rc = rtLinuxFindDevicePathRecursive(DevNum, fMode, szFilename);
+    }
+    if (RT_SUCCESS(rc))
+    {
+        size_t cchPath = strlen(szFilename);
+        if (cchPath >= cchBuf)
+            return VERR_BUFFER_OVERFLOW;
+        memcpy(pszBuf, szFilename, cchPath + 1);
+        return cchPath;
+    }
+    return rc;
 }
 
 
-RTDECL(ssize_t) RTLinuxFindDevicePath(dev_t DevNum, RTFMODE fMode, char *pszBuf, size_t cchBuf,
-                                      const char *pszSuggestion, ...)
+/** @todo Do we really need to return the string length?  If the caller is
+ * interested (the current ones aren't) they can check themselves. */
+RTDECL(ssize_t) RTLinuxFindDevicePath(dev_t DevNum, RTFMODE fMode, char *pszBuf,
+                                      size_t cchBuf, const char *pszSuggestion,
+                                      ...)
 {
     va_list va;
     va_start(va, pszSuggestion);
diff --git a/src/VBox/Runtime/r3/win/RTSystemQueryDmiString-win.cpp b/src/VBox/Runtime/r3/win/RTSystemQueryDmiString-win.cpp
index 2a0e3b5..8621a36 100644
--- a/src/VBox/Runtime/r3/win/RTSystemQueryDmiString-win.cpp
+++ b/src/VBox/Runtime/r3/win/RTSystemQueryDmiString-win.cpp
@@ -165,8 +165,11 @@ RTDECL(int) RTSystemQueryDmiString(RTSYSDMISTR enmString, char *pszBuf, size_t c
     /*
      * Before we do anything with COM, we have to initialize it.
      */
+    bool fUninit = true;
     HRESULT hrc = rtSystemDmiWinInitialize();
-    if (FAILED(hrc))
+    if (hrc == RPC_E_CHANGED_MODE)
+        fUninit = false;  /* don't fail if already initialized */
+    else if (FAILED(hrc))
         return VERR_NOT_SUPPORTED;
 
     int rc = VERR_NOT_SUPPORTED;
@@ -246,7 +249,8 @@ RTDECL(int) RTSystemQueryDmiString(RTSYSDMISTR enmString, char *pszBuf, size_t c
     }
     else
         hrc = E_OUTOFMEMORY;
-    rtSystemDmiWinTerminate();
+    if (fUninit)
+        rtSystemDmiWinTerminate();
     if (FAILED(hrc) && rc == VERR_NOT_SUPPORTED)
         rc = VERR_NOT_SUPPORTED;
     return rc;
diff --git a/src/VBox/Runtime/testcase/tstHandleTable.cpp b/src/VBox/Runtime/testcase/tstHandleTable.cpp
index bdebaf5..1759ca0 100644
--- a/src/VBox/Runtime/testcase/tstHandleTable.cpp
+++ b/src/VBox/Runtime/testcase/tstHandleTable.cpp
@@ -4,7 +4,7 @@
  */
 
 /*
- * Copyright (C) 2008-2011 Oracle Corporation
+ * Copyright (C) 2008-2014 Oracle Corporation
  *
  * This file is part of VirtualBox Open Source Edition (OSE), as
  * available from http://www.virtualbox.org. This file is free software;
@@ -119,7 +119,7 @@ static int tstHandleTableTest1(uint32_t uBase, uint32_t cMax, uint32_t cDelta, u
     RTPrintf(" c=%#x\n", c);
     if (fCallbacks && cRetainerCalls != 0)
     {
-        RTPrintf("tstHandleTable: FAILURE (%d) - cRetainerCalls=%#x expected 0!\n", __LINE__, i, cRetainerCalls);
+        RTPrintf("tstHandleTable: FAILURE (%d) - cRetainerCalls=%#x expected 0!\n", __LINE__, cRetainerCalls);
         g_cErrors++;
     }
 
@@ -243,7 +243,7 @@ static int tstHandleTableTest1(uint32_t uBase, uint32_t cMax, uint32_t cDelta, u
                          &&  RTHandleTableLookupWithCtx(hHT, hLookup, &i))
                 {
                     RTPrintf("\ntstHandleTable: FAILURE (%d) - i=%d, j=%d, RTHandleTableLookupWithCtx: succeeded with bad context\n",
-                             __LINE__, i, j, pvObj, pvExpect);
+                             __LINE__, i, j);
                     g_cErrors++;
                 }
             }
@@ -487,7 +487,7 @@ int main(int argc, char **argv)
                 return 1;
 
             case 'V':
-                RTPrintf("$Revision: 89632 $\n");
+                RTPrintf("$Revision: 92648 $\n");
                 return 0;
 
             default:
diff --git a/src/VBox/Runtime/testcase/tstMemAutoPtr.cpp b/src/VBox/Runtime/testcase/tstMemAutoPtr.cpp
index 7dc9def..2354d7b 100644
--- a/src/VBox/Runtime/testcase/tstMemAutoPtr.cpp
+++ b/src/VBox/Runtime/testcase/tstMemAutoPtr.cpp
@@ -4,7 +4,7 @@
  */
 
 /*
- * Copyright (C) 2008-2011 Oracle Corporation
+ * Copyright (C) 2008-2014 Oracle Corporation
  *
  * This file is part of VirtualBox Open Source Edition (OSE), as
  * available from http://www.virtualbox.org. This file is free software;
@@ -100,12 +100,12 @@ void tstMemAutoPtrDestructorCounter(T *aMem)
 {
     if (aMem == NULL)
     {
-        RTPrintf("tstMemAutoPtr(%d): Destructor called with NILL handle!\n");
+        RTPrintf("tstMemAutoPtr(): Destructor called with NULL handle!\n");
         g_cErrors++;
     }
     else if (!VALID_PTR(aMem))
     {
-        RTPrintf("tstMemAutoPtr(%d): Destructor called with a bad handle %p\n", aMem);
+        RTPrintf("tstMemAutoPtr(): Destructor called with a bad handle %p\n", aMem);
         g_cErrors++;
     }
     RTMemEfFreeNP(aMem);
diff --git a/src/VBox/Runtime/testcase/tstRTStrFormat.cpp b/src/VBox/Runtime/testcase/tstRTStrFormat.cpp
index b87c992..e0504e5 100644
--- a/src/VBox/Runtime/testcase/tstRTStrFormat.cpp
+++ b/src/VBox/Runtime/testcase/tstRTStrFormat.cpp
@@ -336,6 +336,97 @@ int main()
     CHECK42("%RTnaipv4", Ipv4Addr.u, "255.255.255.255");
 
     RTNETADDRIPV6 Ipv6Addr;
+
+    /* any */
+    memset(&Ipv6Addr, 0, sizeof(Ipv6Addr));
+    CHECK42("%RTnaipv6", &Ipv6Addr, "::");
+
+    /* loopback */
+    Ipv6Addr.au8[15] = 1;
+    CHECK42("%RTnaipv6", &Ipv6Addr, "::1");
+
+    /* IPv4-compatible */
+    Ipv6Addr.au8[12] = 1;
+    Ipv6Addr.au8[13] = 1;
+    Ipv6Addr.au8[14] = 1;
+    Ipv6Addr.au8[15] = 1;
+    CHECK42("%RTnaipv6", &Ipv6Addr, "::1.1.1.1");
+
+    /* IPv4-mapped */
+    Ipv6Addr.au16[5] = RT_H2N_U16_C(0xffff);
+    CHECK42("%RTnaipv6", &Ipv6Addr, "::ffff:1.1.1.1");
+
+    /* IPv4-translated */
+    Ipv6Addr.au16[4] = RT_H2N_U16_C(0xffff);
+    Ipv6Addr.au16[5] = RT_H2N_U16_C(0x0000);
+    CHECK42("%RTnaipv6", &Ipv6Addr, "::ffff:0:1.1.1.1");
+
+    /* single zero word is not abbreviated, leading zeroes are not printed */
+    Ipv6Addr.au16[0] = RT_H2N_U16_C(0x0000);
+    Ipv6Addr.au16[1] = RT_H2N_U16_C(0x0001);
+    Ipv6Addr.au16[2] = RT_H2N_U16_C(0x0000);
+    Ipv6Addr.au16[3] = RT_H2N_U16_C(0x0001);
+    Ipv6Addr.au16[4] = RT_H2N_U16_C(0x0000);
+    Ipv6Addr.au16[5] = RT_H2N_U16_C(0x0001);
+    Ipv6Addr.au16[6] = RT_H2N_U16_C(0x0000);
+    Ipv6Addr.au16[7] = RT_H2N_U16_C(0x0001);
+    CHECK42("%RTnaipv6", &Ipv6Addr, "0:1:0:1:0:1:0:1");
+
+    /* longest run is abbreviated (here: at the beginning) */
+    Ipv6Addr.au16[0] = RT_H2N_U16_C(0x0000);
+    Ipv6Addr.au16[1] = RT_H2N_U16_C(0x0000);
+    Ipv6Addr.au16[2] = RT_H2N_U16_C(0x0000);
+    Ipv6Addr.au16[3] = RT_H2N_U16_C(0x0001);
+    Ipv6Addr.au16[4] = RT_H2N_U16_C(0x0000);
+    Ipv6Addr.au16[5] = RT_H2N_U16_C(0x0000);
+    Ipv6Addr.au16[6] = RT_H2N_U16_C(0x0001);
+    Ipv6Addr.au16[7] = RT_H2N_U16_C(0x0000);
+    CHECK42("%RTnaipv6", &Ipv6Addr, "::1:0:0:1:0");
+
+    /* longest run is abbreviated (here: first) */
+    Ipv6Addr.au16[0] = RT_H2N_U16_C(0x0001);
+    Ipv6Addr.au16[1] = RT_H2N_U16_C(0x0000);
+    Ipv6Addr.au16[2] = RT_H2N_U16_C(0x0000);
+    Ipv6Addr.au16[3] = RT_H2N_U16_C(0x0000);
+    Ipv6Addr.au16[4] = RT_H2N_U16_C(0x0001);
+    Ipv6Addr.au16[5] = RT_H2N_U16_C(0x0000);
+    Ipv6Addr.au16[6] = RT_H2N_U16_C(0x0000);
+    Ipv6Addr.au16[7] = RT_H2N_U16_C(0x0001);
+    CHECK42("%RTnaipv6", &Ipv6Addr, "1::1:0:0:1");
+
+    /* longest run is abbreviated (here: second) */
+    Ipv6Addr.au16[0] = RT_H2N_U16_C(0x0001);
+    Ipv6Addr.au16[1] = RT_H2N_U16_C(0x0000);
+    Ipv6Addr.au16[2] = RT_H2N_U16_C(0x0000);
+    Ipv6Addr.au16[3] = RT_H2N_U16_C(0x0001);
+    Ipv6Addr.au16[4] = RT_H2N_U16_C(0x0000);
+    Ipv6Addr.au16[5] = RT_H2N_U16_C(0x0000);
+    Ipv6Addr.au16[6] = RT_H2N_U16_C(0x0000);
+    Ipv6Addr.au16[7] = RT_H2N_U16_C(0x0001);
+    CHECK42("%RTnaipv6", &Ipv6Addr, "1:0:0:1::1");
+
+    /* longest run is abbreviated (here: at the end) */
+    Ipv6Addr.au16[0] = RT_H2N_U16_C(0x0001);
+    Ipv6Addr.au16[1] = RT_H2N_U16_C(0x0000);
+    Ipv6Addr.au16[2] = RT_H2N_U16_C(0x0000);
+    Ipv6Addr.au16[3] = RT_H2N_U16_C(0x0001);
+    Ipv6Addr.au16[4] = RT_H2N_U16_C(0x0000);
+    Ipv6Addr.au16[5] = RT_H2N_U16_C(0x0000);
+    Ipv6Addr.au16[6] = RT_H2N_U16_C(0x0000);
+    Ipv6Addr.au16[7] = RT_H2N_U16_C(0x0000);
+    CHECK42("%RTnaipv6", &Ipv6Addr, "1:0:0:1::");
+
+    /* first of the two runs of equal length is abbreviated */
+    Ipv6Addr.au16[0] = RT_H2N_U16_C(0x2001);
+    Ipv6Addr.au16[1] = RT_H2N_U16_C(0x0db8);
+    Ipv6Addr.au16[2] = RT_H2N_U16_C(0x0000);
+    Ipv6Addr.au16[3] = RT_H2N_U16_C(0x0000);
+    Ipv6Addr.au16[4] = RT_H2N_U16_C(0x0001);
+    Ipv6Addr.au16[5] = RT_H2N_U16_C(0x0000);
+    Ipv6Addr.au16[6] = RT_H2N_U16_C(0x0000);
+    Ipv6Addr.au16[7] = RT_H2N_U16_C(0x0001);
+    CHECK42("%RTnaipv6", &Ipv6Addr, "2001:db8::1:0:0:1");
+
     Ipv6Addr.au16[0] = RT_H2N_U16_C(0x2001);
     Ipv6Addr.au16[1] = RT_H2N_U16_C(0x0db8);
     Ipv6Addr.au16[2] = RT_H2N_U16_C(0x85a3);
@@ -344,11 +435,26 @@ int main()
     Ipv6Addr.au16[5] = RT_H2N_U16_C(0x8a2e);
     Ipv6Addr.au16[6] = RT_H2N_U16_C(0x0370);
     Ipv6Addr.au16[7] = RT_H2N_U16_C(0x7334);
-    CHECK42("%RTnaipv6", &Ipv6Addr, "2001:0db8:85a3:0000:0000:8a2e:0370:7334");
+    CHECK42("%RTnaipv6", &Ipv6Addr, "2001:db8:85a3::8a2e:370:7334");
+
     Ipv6Addr.au64[0] = UINT64_MAX;
     Ipv6Addr.au64[1] = UINT64_MAX;
     CHECK42("%RTnaipv6", &Ipv6Addr, "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff");
 
+    RTNETADDR NetAddr;
+    memset(&NetAddr, 0, sizeof(NetAddr));
+
+    /* plain IPv6 address if port is not specified */
+    NetAddr.enmType = RTNETADDRTYPE_IPV6;
+    NetAddr.uAddr.au16[0] = RT_H2N_U16_C(0x0001);
+    NetAddr.uAddr.au16[7] = RT_H2N_U16_C(0x0001);
+    NetAddr.uPort = RTNETADDR_PORT_NA;
+    CHECK42("%RTnaddr", &NetAddr, "1::1");
+
+    /* square brackets around IPv6 address if port is specified */
+    NetAddr.uPort = 1;
+    CHECK42("%RTnaddr", &NetAddr, "[1::1]:1");
+
     CHECK42("%RTproc", (RTPROCESS)0xffffff, "00ffffff");
     CHECK42("%RTproc", (RTPROCESS)0x43455443, "43455443");
 
diff --git a/src/VBox/Storage/VD.cpp b/src/VBox/Storage/VD.cpp
index 1253599..5632e13 100644
--- a/src/VBox/Storage/VD.cpp
+++ b/src/VBox/Storage/VD.cpp
@@ -1917,7 +1917,7 @@ static int vdParentRead(void *pvUser, uint64_t uOffset, void *pvBuf,
     Segment.cbSeg = cbRead;
     RTSgBufInit(&SgBuf, &Segment, 1);
     vdIoCtxInit(&IoCtx, pParentState->pDisk, VDIOCTXTXDIR_READ, uOffset, cbRead, pParentState->pImage,
-                &SgBuf, NULL, NULL, VDIOCTX_FLAGS_SYNC);
+                &SgBuf, NULL, NULL, VDIOCTX_FLAGS_SYNC | VDIOCTX_FLAGS_ZERO_FREE_BLOCKS);
     int rc = vdReadHelperAsync(&IoCtx);
     ASMAtomicXchgBool(&pParentState->pDisk->fLocked, false);
     return rc;
diff --git a/src/VBox/Storage/VHD.cpp b/src/VBox/Storage/VHD.cpp
index 3af2eba..c563a26 100644
--- a/src/VBox/Storage/VHD.cpp
+++ b/src/VBox/Storage/VHD.cpp
@@ -2462,7 +2462,7 @@ static int vhdCompact(void *pBackendData, unsigned uPercentStart,
         if (pfnParentRead)
         {
             pvParent = RTMemTmpAlloc(pImage->cbDataBlock);
-            AssertBreakStmt(VALID_PTR(pvBuf), rc = VERR_NO_MEMORY);
+            AssertBreakStmt(VALID_PTR(pvParent), rc = VERR_NO_MEMORY);
         }
         pvBuf = RTMemTmpAlloc(pImage->cbDataBlock);
         AssertBreakStmt(VALID_PTR(pvBuf), rc = VERR_NO_MEMORY);
diff --git a/src/VBox/VMM/VMMAll/CPUMAllMsrs.cpp b/src/VBox/VMM/VMMAll/CPUMAllMsrs.cpp
index 9e1a40c..c34a3d4 100644
--- a/src/VBox/VMM/VMMAll/CPUMAllMsrs.cpp
+++ b/src/VBox/VMM/VMMAll/CPUMAllMsrs.cpp
@@ -181,6 +181,21 @@ static DECLCALLBACK(int) cpumMsrWr_Ia32TimestampCounter(PVMCPU pVCpu, uint32_t i
 
 
 /** @callback_method_impl{FNCPUMRDMSR} */
+static DECLCALLBACK(int) cpumMsrRd_Ia32PlatformId(PVMCPU pVCpu, uint32_t idMsr, PCCPUMMSRRANGE pRange, uint64_t *puValue)
+{
+    uint64_t uValue = pRange->uValue;
+    if (uValue & 0x1f00)
+    {
+        /* Max allowed bus ratio present. */
+        /** @todo Implement scaled BUS frequency. */
+    }
+
+    *puValue = uValue;
+    return VINF_SUCCESS;
+}
+
+
+/** @callback_method_impl{FNCPUMRDMSR} */
 static DECLCALLBACK(int) cpumMsrRd_Ia32ApicBase(PVMCPU pVCpu, uint32_t idMsr, PCCPUMMSRRANGE pRange, uint64_t *puValue)
 {
     PVM pVM = pVCpu->CTX_SUFF(pVM);
@@ -713,8 +728,20 @@ static DECLCALLBACK(int) cpumMsrWr_Ia32PerfEvtSelN(PVMCPU pVCpu, uint32_t idMsr,
 /** @callback_method_impl{FNCPUMRDMSR} */
 static DECLCALLBACK(int) cpumMsrRd_Ia32PerfStatus(PVMCPU pVCpu, uint32_t idMsr, PCCPUMMSRRANGE pRange, uint64_t *puValue)
 {
-    /** @todo implement IA32_PERFSTATUS. */
-    *puValue = pRange->uValue;
+    uint64_t uValue = pRange->uValue;
+
+    /* Always provide the max bus ratio for now.  XNU expects it. */
+    uValue &= ~((UINT64_C(0x1f) << 40) | RT_BIT_64(46));
+
+    PVM      pVM            = pVCpu->CTX_SUFF(pVM);
+    uint64_t uScalableBusHz = CPUMGetGuestScalableBusFrequency(pVM);
+    uint64_t uTscHz         = TMCpuTicksPerSecond(pVM);
+    uint8_t  uTscRatio      = (uint8_t)((uTscHz + uScalableBusHz / 2) / uScalableBusHz);
+    if (uTscRatio > 0x1f)
+        uTscRatio = 0x1f;
+    uValue |= (uint64_t)uTscRatio << 40;
+
+    *puValue = uValue;
     return VINF_SUCCESS;
 }
 
@@ -1493,6 +1520,18 @@ static DECLCALLBACK(int) cpumMsrWr_IntelEblCrPowerOn(PVMCPU pVCpu, uint32_t idMs
 
 
 /** @callback_method_impl{FNCPUMRDMSR} */
+static DECLCALLBACK(int) cpumMsrRd_IntelI7CoreThreadCount(PVMCPU pVCpu, uint32_t idMsr, PCCPUMMSRRANGE pRange, uint64_t *puValue)
+{
+    /* Note! According to cpuid_set_info in XNU (10.7.0), Westmere CPU only
+             have a 4-bit core count. */
+    uint16_t cCores   = pVCpu->CTX_SUFF(pVM)->cCpus;
+    uint16_t cThreads = cCores; /** @todo hyper-threading. */
+    *puValue = RT_MAKE_U32(cThreads, cCores);
+    return VINF_SUCCESS;
+}
+
+
+/** @callback_method_impl{FNCPUMRDMSR} */
 static DECLCALLBACK(int) cpumMsrRd_IntelP4EbcHardPowerOn(PVMCPU pVCpu, uint32_t idMsr, PCCPUMMSRRANGE pRange, uint64_t *puValue)
 {
     /** @todo P4 hard power on config */
@@ -1529,8 +1568,57 @@ static DECLCALLBACK(int) cpumMsrWr_IntelP4EbcSoftPowerOn(PVMCPU pVCpu, uint32_t
 /** @callback_method_impl{FNCPUMRDMSR} */
 static DECLCALLBACK(int) cpumMsrRd_IntelP4EbcFrequencyId(PVMCPU pVCpu, uint32_t idMsr, PCCPUMMSRRANGE pRange, uint64_t *puValue)
 {
-    /** @todo P4 bus frequency config  */
-    *puValue = pRange->uValue;
+    uint64_t uValue;
+    PVM      pVM            = pVCpu->CTX_SUFF(pVM);
+    uint64_t uScalableBusHz = CPUMGetGuestScalableBusFrequency(pVM);
+    if (pVM->cpum.s.GuestFeatures.uModel >= 2)
+    {
+        if (uScalableBusHz <= CPUM_SBUSFREQ_100MHZ && pVM->cpum.s.GuestFeatures.uModel <= 2)
+        {
+            uScalableBusHz = CPUM_SBUSFREQ_100MHZ;
+            uValue = 0;
+        }
+        else if (uScalableBusHz <= CPUM_SBUSFREQ_133MHZ)
+        {
+            uScalableBusHz = CPUM_SBUSFREQ_133MHZ;
+            uValue = 1;
+        }
+        else if (uScalableBusHz <= CPUM_SBUSFREQ_167MHZ)
+        {
+            uScalableBusHz = CPUM_SBUSFREQ_167MHZ;
+            uValue = 3;
+        }
+        else if (uScalableBusHz <= CPUM_SBUSFREQ_200MHZ)
+        {
+            uScalableBusHz = CPUM_SBUSFREQ_200MHZ;
+            uValue = 2;
+        }
+        else if (uScalableBusHz <= CPUM_SBUSFREQ_267MHZ && pVM->cpum.s.GuestFeatures.uModel > 2)
+        {
+            uScalableBusHz = CPUM_SBUSFREQ_267MHZ;
+            uValue = 0;
+        }
+        else
+        {
+            uScalableBusHz = CPUM_SBUSFREQ_333MHZ;
+            uValue = 6;
+        }
+        uValue <<= 16;
+
+        uint64_t uTscHz    = TMCpuTicksPerSecond(pVM);
+        uint8_t  uTscRatio = (uint8_t)((uTscHz + uScalableBusHz / 2) / uScalableBusHz);
+        uValue |= (uint32_t)uTscRatio << 24;
+
+        uValue |= pRange->uValue & ~UINT64_C(0xff0f0000);
+    }
+    else
+    {
+        /* Probably more stuff here, but intel doesn't want to tell us. */
+        uValue = pRange->uValue;
+        uValue &= ~(RT_BIT_64(21) | RT_BIT_64(22) | RT_BIT_64(23)); /* 100 MHz is only documented value */
+    }
+
+    *puValue = uValue;
     return VINF_SUCCESS;
 }
 
@@ -1544,66 +1632,61 @@ static DECLCALLBACK(int) cpumMsrWr_IntelP4EbcFrequencyId(PVMCPU pVCpu, uint32_t
 
 
 /** @callback_method_impl{FNCPUMRDMSR} */
-static DECLCALLBACK(int) cpumMsrRd_IntelPlatformInfo100MHz(PVMCPU pVCpu, uint32_t idMsr, PCCPUMMSRRANGE pRange, uint64_t *puValue)
+static DECLCALLBACK(int) cpumMsrRd_IntelP6FsbFrequency(PVMCPU pVCpu, uint32_t idMsr, PCCPUMMSRRANGE pRange, uint64_t *puValue)
 {
-    PVM pVM = pVCpu->CTX_SUFF(pVM);
+    /* Convert the scalable bus frequency to the encoding in the intel manual (for core+). */
+    uint64_t uScalableBusHz = CPUMGetGuestScalableBusFrequency(pVCpu->CTX_SUFF(pVM));
+    if (uScalableBusHz <= CPUM_SBUSFREQ_100MHZ)
+        *puValue = 5;
+    else if (uScalableBusHz <= CPUM_SBUSFREQ_133MHZ)
+        *puValue = 1;
+    else if (uScalableBusHz <= CPUM_SBUSFREQ_167MHZ)
+        *puValue = 3;
+    else if (uScalableBusHz <= CPUM_SBUSFREQ_200MHZ)
+        *puValue = 2;
+    else if (uScalableBusHz <= CPUM_SBUSFREQ_267MHZ)
+        *puValue = 0;
+    else if (uScalableBusHz <= CPUM_SBUSFREQ_333MHZ)
+        *puValue = 4;
+    else /*if (uScalableBusHz <= CPUM_SBUSFREQ_400MHZ)*/
+        *puValue = 6;
 
-    /* Just indicate a fixed TSC, no turbo boost, no programmable anything. */
-    uint64_t uTscHz = TMCpuTicksPerSecond(pVM);
-    uint8_t  uTsc100MHz = (uint8_t)(uTscHz / UINT32_C(100000000));
-    *puValue = ((uint32_t)uTsc100MHz << 8)   /* TSC invariant frequency. */
-             | ((uint64_t)uTsc100MHz << 40); /* The max turbo frequency. */
-
-    /* Ivy bridge has a minimum operating ratio as well. */
-    if (true) /** @todo detect sandy bridge. */
-        *puValue |= (uint64_t)uTsc100MHz << 48;
+    *puValue |= pRange->uValue & ~UINT64_C(0x7);
 
     return VINF_SUCCESS;
 }
 
 
 /** @callback_method_impl{FNCPUMRDMSR} */
-static DECLCALLBACK(int) cpumMsrRd_IntelPlatformInfo133MHz(PVMCPU pVCpu, uint32_t idMsr, PCCPUMMSRRANGE pRange, uint64_t *puValue)
+static DECLCALLBACK(int) cpumMsrRd_IntelPlatformInfo(PVMCPU pVCpu, uint32_t idMsr, PCCPUMMSRRANGE pRange, uint64_t *puValue)
 {
     /* Just indicate a fixed TSC, no turbo boost, no programmable anything. */
-    uint64_t uTscHz = TMCpuTicksPerSecond(pVCpu->CTX_SUFF(pVM));
-    uint8_t  uTsc133MHz = (uint8_t)(uTscHz / UINT32_C(133333333));
-    *puValue = ((uint32_t)uTsc133MHz << 8)   /* TSC invariant frequency. */
-             | ((uint64_t)uTsc133MHz << 40); /* The max turbo frequency. */
-    return VINF_SUCCESS;
-}
+    PVM      pVM            = pVCpu->CTX_SUFF(pVM);
+    uint64_t uScalableBusHz = CPUMGetGuestScalableBusFrequency(pVM);
+    uint64_t uTscHz         = TMCpuTicksPerSecond(pVM);
+    uint8_t  uTscRatio      = (uint8_t)((uTscHz + uScalableBusHz / 2) / uScalableBusHz);
+    uint64_t uValue         = ((uint32_t)uTscRatio << 8)   /* TSC invariant frequency. */
+                            | ((uint64_t)uTscRatio << 40); /* The max turbo frequency. */
 
-
-/** @callback_method_impl{FNCPUMRDMSR} */
-static DECLCALLBACK(int) cpumMsrRd_IntelFlexRatio100MHz(PVMCPU pVCpu, uint32_t idMsr, PCCPUMMSRRANGE pRange, uint64_t *puValue)
-{
-    uint64_t uValue = pRange->uValue & ~UINT64_C(0x1ff00);
-
-    uint64_t uTscHz = TMCpuTicksPerSecond(pVCpu->CTX_SUFF(pVM));
-    uint8_t  uTsc100MHz = (uint8_t)(uTscHz / UINT32_C(100000000));
-    uValue |= (uint32_t)uTsc100MHz << 8;
+    /* Ivy bridge has a minimum operating ratio as well. */
+    if (true) /** @todo detect sandy bridge. */
+        uValue |= (uint64_t)uTscRatio << 48;
 
     *puValue = uValue;
     return VINF_SUCCESS;
 }
 
 
-/** @callback_method_impl{FNCPUMWRMSR} */
-static DECLCALLBACK(int) cpumMsrWr_IntelFlexRatio100MHz(PVMCPU pVCpu, uint32_t idMsr, PCCPUMMSRRANGE pRange, uint64_t uValue, uint64_t uRawValue)
-{
-    /** @todo implement writing MSR_FLEX_RATIO. */
-    return VINF_SUCCESS;
-}
-
-
 /** @callback_method_impl{FNCPUMRDMSR} */
-static DECLCALLBACK(int) cpumMsrRd_IntelFlexRatio133MHz(PVMCPU pVCpu, uint32_t idMsr, PCCPUMMSRRANGE pRange, uint64_t *puValue)
+static DECLCALLBACK(int) cpumMsrRd_IntelFlexRatio(PVMCPU pVCpu, uint32_t idMsr, PCCPUMMSRRANGE pRange, uint64_t *puValue)
 {
     uint64_t uValue = pRange->uValue & ~UINT64_C(0x1ff00);
 
-    uint64_t uTscHz = TMCpuTicksPerSecond(pVCpu->CTX_SUFF(pVM));
-    uint8_t  uTsc133MHz = (uint8_t)(uTscHz / UINT32_C(133333333));
-    uValue |= (uint32_t)uTsc133MHz << 8;
+    PVM      pVM            = pVCpu->CTX_SUFF(pVM);
+    uint64_t uScalableBusHz = CPUMGetGuestScalableBusFrequency(pVM);
+    uint64_t uTscHz         = TMCpuTicksPerSecond(pVM);
+    uint8_t  uTscRatio      = (uint8_t)((uTscHz + uScalableBusHz / 2) / uScalableBusHz);
+    uValue |= (uint32_t)uTscRatio << 8;
 
     *puValue = uValue;
     return VINF_SUCCESS;
@@ -1611,7 +1694,7 @@ static DECLCALLBACK(int) cpumMsrRd_IntelFlexRatio133MHz(PVMCPU pVCpu, uint32_t i
 
 
 /** @callback_method_impl{FNCPUMWRMSR} */
-static DECLCALLBACK(int) cpumMsrWr_IntelFlexRatio133MHz(PVMCPU pVCpu, uint32_t idMsr, PCCPUMMSRRANGE pRange, uint64_t uValue, uint64_t uRawValue)
+static DECLCALLBACK(int) cpumMsrWr_IntelFlexRatio(PVMCPU pVCpu, uint32_t idMsr, PCCPUMMSRRANGE pRange, uint64_t uValue, uint64_t uRawValue)
 {
     /** @todo implement writing MSR_FLEX_RATIO. */
     return VINF_SUCCESS;
@@ -4308,6 +4391,7 @@ static const PFNCPUMRDMSR g_aCpumRdMsrFns[kCpumMsrRdFn_End] =
     cpumMsrRd_Ia32P5McAddr,
     cpumMsrRd_Ia32P5McType,
     cpumMsrRd_Ia32TimestampCounter,
+    cpumMsrRd_Ia32PlatformId,
     cpumMsrRd_Ia32ApicBase,
     cpumMsrRd_Ia32FeatureControl,
     cpumMsrRd_Ia32BiosSignId,
@@ -4384,13 +4468,13 @@ static const PFNCPUMRDMSR g_aCpumRdMsrFns[kCpumMsrRdFn_End] =
     cpumMsrRd_Amd64TscAux,
 
     cpumMsrRd_IntelEblCrPowerOn,
+    cpumMsrRd_IntelI7CoreThreadCount,
     cpumMsrRd_IntelP4EbcHardPowerOn,
     cpumMsrRd_IntelP4EbcSoftPowerOn,
     cpumMsrRd_IntelP4EbcFrequencyId,
-    cpumMsrRd_IntelPlatformInfo100MHz,
-    cpumMsrRd_IntelPlatformInfo133MHz,
-    cpumMsrRd_IntelFlexRatio100MHz,
-    cpumMsrRd_IntelFlexRatio133MHz,
+    cpumMsrRd_IntelP6FsbFrequency,
+    cpumMsrRd_IntelPlatformInfo,
+    cpumMsrRd_IntelFlexRatio,
     cpumMsrRd_IntelPkgCStConfigControl,
     cpumMsrRd_IntelPmgIoCaptureBase,
     cpumMsrRd_IntelLastBranchFromToN,
@@ -4626,8 +4710,7 @@ static const PFNCPUMWRMSR g_aCpumWrMsrFns[kCpumMsrWrFn_End] =
     cpumMsrWr_IntelP4EbcHardPowerOn,
     cpumMsrWr_IntelP4EbcSoftPowerOn,
     cpumMsrWr_IntelP4EbcFrequencyId,
-    cpumMsrWr_IntelFlexRatio100MHz,
-    cpumMsrWr_IntelFlexRatio133MHz,
+    cpumMsrWr_IntelFlexRatio,
     cpumMsrWr_IntelPkgCStConfigControl,
     cpumMsrWr_IntelPmgIoCaptureBase,
     cpumMsrWr_IntelLastBranchFromToN,
@@ -4999,6 +5082,7 @@ int cpumR3MsrStrictInitChecks(void)
     CPUM_ASSERT_RD_MSR_FN(Ia32P5McAddr);
     CPUM_ASSERT_RD_MSR_FN(Ia32P5McType);
     CPUM_ASSERT_RD_MSR_FN(Ia32TimestampCounter);
+    CPUM_ASSERT_RD_MSR_FN(Ia32PlatformId);
     CPUM_ASSERT_RD_MSR_FN(Ia32ApicBase);
     CPUM_ASSERT_RD_MSR_FN(Ia32FeatureControl);
     CPUM_ASSERT_RD_MSR_FN(Ia32BiosSignId);
@@ -5074,13 +5158,13 @@ int cpumR3MsrStrictInitChecks(void)
     CPUM_ASSERT_RD_MSR_FN(Amd64TscAux);
 
     CPUM_ASSERT_RD_MSR_FN(IntelEblCrPowerOn);
+    CPUM_ASSERT_RD_MSR_FN(IntelI7CoreThreadCount);
     CPUM_ASSERT_RD_MSR_FN(IntelP4EbcHardPowerOn);
     CPUM_ASSERT_RD_MSR_FN(IntelP4EbcSoftPowerOn);
     CPUM_ASSERT_RD_MSR_FN(IntelP4EbcFrequencyId);
-    CPUM_ASSERT_RD_MSR_FN(IntelPlatformInfo100MHz);
-    CPUM_ASSERT_RD_MSR_FN(IntelPlatformInfo133MHz);
-    CPUM_ASSERT_RD_MSR_FN(IntelFlexRatio100MHz);
-    CPUM_ASSERT_RD_MSR_FN(IntelFlexRatio133MHz);
+    CPUM_ASSERT_RD_MSR_FN(IntelP6FsbFrequency);
+    CPUM_ASSERT_RD_MSR_FN(IntelPlatformInfo);
+    CPUM_ASSERT_RD_MSR_FN(IntelFlexRatio);
     CPUM_ASSERT_RD_MSR_FN(IntelPkgCStConfigControl);
     CPUM_ASSERT_RD_MSR_FN(IntelPmgIoCaptureBase);
     CPUM_ASSERT_RD_MSR_FN(IntelLastBranchFromToN);
@@ -5305,8 +5389,7 @@ int cpumR3MsrStrictInitChecks(void)
     CPUM_ASSERT_WR_MSR_FN(IntelP4EbcHardPowerOn);
     CPUM_ASSERT_WR_MSR_FN(IntelP4EbcSoftPowerOn);
     CPUM_ASSERT_WR_MSR_FN(IntelP4EbcFrequencyId);
-    CPUM_ASSERT_WR_MSR_FN(IntelFlexRatio100MHz);
-    CPUM_ASSERT_WR_MSR_FN(IntelFlexRatio133MHz);
+    CPUM_ASSERT_WR_MSR_FN(IntelFlexRatio);
     CPUM_ASSERT_WR_MSR_FN(IntelPkgCStConfigControl);
     CPUM_ASSERT_WR_MSR_FN(IntelPmgIoCaptureBase);
     CPUM_ASSERT_WR_MSR_FN(IntelLastBranchFromToN);
@@ -5452,25 +5535,20 @@ int cpumR3MsrStrictInitChecks(void)
 
 
 /**
- * Gets the bus frequency.
+ * Gets the scalable bus frequency.
  *
  * The bus frequency is used as a base in several MSRs that gives the CPU and
  * other frequency ratios.
  *
- * @returns Bus frequency in Hz.
+ * @returns Scalable bus frequency in Hz. Will not return CPUM_SBUSFREQ_UNKNOWN.
  * @param   pVM                 Pointer to the shared VM structure.
  */
-VMMDECL(uint64_t) CPUMGetGuestBusFrequency(PVM pVM)
+VMMDECL(uint64_t) CPUMGetGuestScalableBusFrequency(PVM pVM)
 {
-    if (CPUMMICROARCH_IS_INTEL_CORE7(pVM->cpum.s.GuestFeatures.enmMicroarch))
-    {
-        return pVM->cpum.s.GuestFeatures.enmMicroarch >= kCpumMicroarch_Intel_Core7_SandyBridge
-            ? UINT64_C(100000000)  /* 100MHz */
-            : UINT64_C(133333333); /* 133MHz */
-    }
-
-    /* 133MHz */
-    return UINT64_C(133333333);
+    uint64_t uFreq = pVM->cpum.s.GuestInfo.uScalableBusFreq;
+    if (uFreq == CPUM_SBUSFREQ_UNKNOWN)
+        uFreq = CPUM_SBUSFREQ_100MHZ;
+    return uFreq;
 }
 
 
diff --git a/src/VBox/VMM/VMMAll/PGMAllPool.cpp b/src/VBox/VMM/VMMAll/PGMAllPool.cpp
index 91c4ce0..30fbd01 100644
--- a/src/VBox/VMM/VMMAll/PGMAllPool.cpp
+++ b/src/VBox/VMM/VMMAll/PGMAllPool.cpp
@@ -46,6 +46,7 @@
 RT_C_DECLS_BEGIN
 DECLINLINE(unsigned) pgmPoolTrackGetShadowEntrySize(PGMPOOLKIND enmKind);
 DECLINLINE(unsigned) pgmPoolTrackGetGuestEntrySize(PGMPOOLKIND enmKind);
+static void pgmPoolTrackClearPageUsers(PPGMPOOL pPool, PPGMPOOLPAGE pPage);
 static void pgmPoolTrackDeref(PPGMPOOL pPool, PPGMPOOLPAGE pPage);
 static int pgmPoolTrackAddUser(PPGMPOOL pPool, PPGMPOOLPAGE pPage, uint16_t iUser, uint32_t iUserTable);
 static void pgmPoolMonitorModifiedRemove(PPGMPOOL pPool, PPGMPOOLPAGE pPage);
@@ -1796,7 +1797,11 @@ void pgmPoolAddDirtyPage(PVM pVM, PPGMPOOL pPool, PPGMPOOLPAGE pPage)
     }
 
     Assert(pPool->cDirtyPages == RT_ELEMENTS(pPool->aDirtyPages) || pPool->aDirtyPages[pPool->idxFreeDirtyPage].uIdx == NIL_PGMPOOL_IDX);
-    return;
+
+    /*
+     * Clear all references to this shadow table. See @bugref{7298}.
+     */
+    pgmPoolTrackClearPageUsers(pPool, pPage);
 }
 # endif /* !IN_RING3 */
 
diff --git a/src/VBox/VMM/VMMR0/HMR0.cpp b/src/VBox/VMM/VMMR0/HMR0.cpp
index 6908eb6..9793d7a 100644
--- a/src/VBox/VMM/VMMR0/HMR0.cpp
+++ b/src/VBox/VMM/VMMR0/HMR0.cpp
@@ -1022,7 +1022,7 @@ static DECLCALLBACK(int32_t) hmR0EnableAllCpuOnce(void *pvUser)
 
             if (RTMpIsCpuPossible(RTMpCpuIdFromSetIndex(i)))
             {
-                rc = RTR0MemObjAllocCont(&g_HvmR0.aCpuInfo[i].hMemObj, PAGE_SIZE, true /* executable R0 mapping */);
+                rc = RTR0MemObjAllocCont(&g_HvmR0.aCpuInfo[i].hMemObj, PAGE_SIZE, false /* executable R0 mapping */);
                 AssertLogRelRCReturn(rc, rc);
 
                 void *pvR0 = RTR0MemObjAddress(g_HvmR0.aCpuInfo[i].hMemObj); Assert(pvR0);
diff --git a/src/VBox/VMM/VMMR0/HMVMXR0.cpp b/src/VBox/VMM/VMMR0/HMVMXR0.cpp
index 4eaf7d9..afd8325 100644
--- a/src/VBox/VMM/VMMR0/HMVMXR0.cpp
+++ b/src/VBox/VMM/VMMR0/HMVMXR0.cpp
@@ -2073,7 +2073,7 @@ static int hmR0VmxInitXcptBitmap(PVM pVM, PVMCPU pVCpu)
 static int hmR0VmxInitUpdatedGuestStateMask(PVMCPU pVCpu)
 {
     /* Initially the guest-state is up-to-date as there is nothing in the VMCS. */
-    pVCpu->hm.s.vmx.fUpdatedGuestState = HMVMX_UPDATED_GUEST_ALL;
+    HMVMXCPU_GST_RESET_TO(pVCpu, HMVMX_UPDATED_GUEST_ALL);
     return VINF_SUCCESS;
 }
 
@@ -2871,8 +2871,8 @@ DECLINLINE(uint32_t) hmR0VmxGetGuestIntrState(PVMCPU pVCpu, PCPUMCTX pMixedCtx)
     if (VMCPU_FF_IS_PENDING(pVCpu, VMCPU_FF_INHIBIT_INTERRUPTS))
     {
         /* If inhibition is active, RIP & RFLAGS should've been accessed (i.e. read previously from the VMCS or from ring-3). */
-        AssertMsg((pVCpu->hm.s.vmx.fUpdatedGuestState & (HMVMX_UPDATED_GUEST_RIP | HMVMX_UPDATED_GUEST_RFLAGS))
-                   == (HMVMX_UPDATED_GUEST_RIP | HMVMX_UPDATED_GUEST_RFLAGS), ("%#x\n", pVCpu->hm.s.vmx.fUpdatedGuestState));
+        AssertMsg(HMVMXCPU_GST_IS_SET(pVCpu, HMVMX_UPDATED_GUEST_RIP | HMVMX_UPDATED_GUEST_RFLAGS),
+                  ("%#x\n", HMVMXCPU_GST_VALUE(pVCpu)));
         if (pMixedCtx->rip != EMGetInhibitInterruptsPC(pVCpu))
         {
             /*
@@ -5221,7 +5221,16 @@ static int hmR0VmxCheckExitDueToEventDelivery(PVMCPU pVCpu, PCPUMCTX pMixedCtx,
  */
 static int hmR0VmxSaveGuestCR0(PVMCPU pVCpu, PCPUMCTX pMixedCtx)
 {
-    if (!(pVCpu->hm.s.vmx.fUpdatedGuestState & HMVMX_UPDATED_GUEST_CR0))
+    NOREF(pMixedCtx);
+
+    /*
+     * While in the middle of saving guest-CR0, we could get preempted and re-invoked from the preemption hook,
+     * see hmR0VmxLeave(). Safer to just make this code non-preemptible.
+     */
+    VMMRZCallRing3Disable(pVCpu);
+    HM_DISABLE_PREEMPT_IF_NEEDED();
+
+    if (!HMVMXCPU_GST_IS_UPDATED(pVCpu, HMVMX_UPDATED_GUEST_CR0))
     {
         uint32_t uVal    = 0;
         int rc = VMXReadVmcs32(VMX_VMCS_GUEST_CR0,            &uVal);
@@ -5233,8 +5242,11 @@ static int hmR0VmxSaveGuestCR0(PVMCPU pVCpu, PCPUMCTX pMixedCtx)
 
         uVal = (uShadow & pVCpu->hm.s.vmx.u32CR0Mask) | (uVal & ~pVCpu->hm.s.vmx.u32CR0Mask);
         CPUMSetGuestCR0(pVCpu, uVal);
-        pVCpu->hm.s.vmx.fUpdatedGuestState |= HMVMX_UPDATED_GUEST_CR0;
+        HMVMXCPU_GST_SET_UPDATED(pVCpu, HMVMX_UPDATED_GUEST_CR0);
     }
+
+    HM_RESTORE_PREEMPT_IF_NEEDED();
+    VMMRZCallRing3Enable(pVCpu);
     return VINF_SUCCESS;
 }
 
@@ -5253,7 +5265,7 @@ static int hmR0VmxSaveGuestCR0(PVMCPU pVCpu, PCPUMCTX pMixedCtx)
 static int hmR0VmxSaveGuestCR4(PVMCPU pVCpu, PCPUMCTX pMixedCtx)
 {
     int rc = VINF_SUCCESS;
-    if (!(pVCpu->hm.s.vmx.fUpdatedGuestState & HMVMX_UPDATED_GUEST_CR4))
+    if (!HMVMXCPU_GST_IS_UPDATED(pVCpu, HMVMX_UPDATED_GUEST_CR4))
     {
         uint32_t uVal    = 0;
         uint32_t uShadow = 0;
@@ -5264,7 +5276,7 @@ static int hmR0VmxSaveGuestCR4(PVMCPU pVCpu, PCPUMCTX pMixedCtx)
 
         uVal = (uShadow & pVCpu->hm.s.vmx.u32CR4Mask) | (uVal & ~pVCpu->hm.s.vmx.u32CR4Mask);
         CPUMSetGuestCR4(pVCpu, uVal);
-        pVCpu->hm.s.vmx.fUpdatedGuestState |= HMVMX_UPDATED_GUEST_CR4;
+        HMVMXCPU_GST_SET_UPDATED(pVCpu, HMVMX_UPDATED_GUEST_CR4);
     }
     return rc;
 }
@@ -5284,14 +5296,14 @@ static int hmR0VmxSaveGuestCR4(PVMCPU pVCpu, PCPUMCTX pMixedCtx)
 static int hmR0VmxSaveGuestRip(PVMCPU pVCpu, PCPUMCTX pMixedCtx)
 {
     int rc = VINF_SUCCESS;
-    if (!(pVCpu->hm.s.vmx.fUpdatedGuestState & HMVMX_UPDATED_GUEST_RIP))
+    if (!HMVMXCPU_GST_IS_UPDATED(pVCpu, HMVMX_UPDATED_GUEST_RIP))
     {
         uint64_t u64Val = 0;
         rc = VMXReadVmcsGstN(VMX_VMCS_GUEST_RIP, &u64Val);
         AssertRCReturn(rc, rc);
 
         pMixedCtx->rip = u64Val;
-        pVCpu->hm.s.vmx.fUpdatedGuestState |= HMVMX_UPDATED_GUEST_RIP;
+        HMVMXCPU_GST_SET_UPDATED(pVCpu, HMVMX_UPDATED_GUEST_RIP);
     }
     return rc;
 }
@@ -5311,14 +5323,14 @@ static int hmR0VmxSaveGuestRip(PVMCPU pVCpu, PCPUMCTX pMixedCtx)
 static int hmR0VmxSaveGuestRsp(PVMCPU pVCpu, PCPUMCTX pMixedCtx)
 {
     int rc = VINF_SUCCESS;
-    if (!(pVCpu->hm.s.vmx.fUpdatedGuestState & HMVMX_UPDATED_GUEST_RSP))
+    if (!HMVMXCPU_GST_IS_UPDATED(pVCpu, HMVMX_UPDATED_GUEST_RSP))
     {
         uint64_t u64Val = 0;
         rc = VMXReadVmcsGstN(VMX_VMCS_GUEST_RSP, &u64Val);
         AssertRCReturn(rc, rc);
 
         pMixedCtx->rsp = u64Val;
-        pVCpu->hm.s.vmx.fUpdatedGuestState |= HMVMX_UPDATED_GUEST_RSP;
+        HMVMXCPU_GST_SET_UPDATED(pVCpu, HMVMX_UPDATED_GUEST_RSP);
     }
     return rc;
 }
@@ -5337,7 +5349,7 @@ static int hmR0VmxSaveGuestRsp(PVMCPU pVCpu, PCPUMCTX pMixedCtx)
  */
 static int hmR0VmxSaveGuestRflags(PVMCPU pVCpu, PCPUMCTX pMixedCtx)
 {
-    if (!(pVCpu->hm.s.vmx.fUpdatedGuestState & HMVMX_UPDATED_GUEST_RFLAGS))
+    if (!HMVMXCPU_GST_IS_UPDATED(pVCpu, HMVMX_UPDATED_GUEST_RFLAGS))
     {
         uint32_t uVal = 0;
         int rc = VMXReadVmcs32(VMX_VMCS_GUEST_RFLAGS, &uVal);
@@ -5353,7 +5365,7 @@ static int hmR0VmxSaveGuestRflags(PVMCPU pVCpu, PCPUMCTX pMixedCtx)
             pMixedCtx->eflags.Bits.u2IOPL = pVCpu->hm.s.vmx.RealMode.Eflags.Bits.u2IOPL;
         }
 
-        pVCpu->hm.s.vmx.fUpdatedGuestState |= HMVMX_UPDATED_GUEST_RFLAGS;
+        HMVMXCPU_GST_SET_UPDATED(pVCpu,  HMVMX_UPDATED_GUEST_RFLAGS);
     }
     return VINF_SUCCESS;
 }
@@ -5420,7 +5432,7 @@ static void hmR0VmxSaveGuestIntrState(PVMCPU pVCpu, PCPUMCTX pMixedCtx)
 static int hmR0VmxSaveGuestActivityState(PVMCPU pVCpu, PCPUMCTX pMixedCtx)
 {
     /* Nothing to do for now until we make use of different guest-CPU activity state. Just update the flag. */
-    pVCpu->hm.s.vmx.fUpdatedGuestState |= HMVMX_UPDATED_GUEST_ACTIVITY_STATE;
+    HMVMXCPU_GST_SET_UPDATED(pVCpu, HMVMX_UPDATED_GUEST_ACTIVITY_STATE);
     return VINF_SUCCESS;
 }
 
@@ -5440,26 +5452,26 @@ static int hmR0VmxSaveGuestActivityState(PVMCPU pVCpu, PCPUMCTX pMixedCtx)
 static int hmR0VmxSaveGuestSysenterMsrs(PVMCPU pVCpu, PCPUMCTX pMixedCtx)
 {
     int rc = VINF_SUCCESS;
-    if (!(pVCpu->hm.s.vmx.fUpdatedGuestState & HMVMX_UPDATED_GUEST_SYSENTER_CS_MSR))
+    if (!HMVMXCPU_GST_IS_UPDATED(pVCpu, HMVMX_UPDATED_GUEST_SYSENTER_CS_MSR))
     {
         uint32_t u32Val = 0;
         rc = VMXReadVmcs32(VMX_VMCS32_GUEST_SYSENTER_CS, &u32Val);     AssertRCReturn(rc, rc);
         pMixedCtx->SysEnter.cs = u32Val;
-        pVCpu->hm.s.vmx.fUpdatedGuestState |= HMVMX_UPDATED_GUEST_SYSENTER_CS_MSR;
+        HMVMXCPU_GST_SET_UPDATED(pVCpu, HMVMX_UPDATED_GUEST_SYSENTER_CS_MSR);
     }
 
     uint64_t u64Val = 0;
-    if (!(pVCpu->hm.s.vmx.fUpdatedGuestState & HMVMX_UPDATED_GUEST_SYSENTER_EIP_MSR))
+    if (!HMVMXCPU_GST_IS_UPDATED(pVCpu, HMVMX_UPDATED_GUEST_SYSENTER_EIP_MSR))
     {
         rc = VMXReadVmcsGstN(VMX_VMCS_GUEST_SYSENTER_EIP, &u64Val);    AssertRCReturn(rc, rc);
         pMixedCtx->SysEnter.eip = u64Val;
-        pVCpu->hm.s.vmx.fUpdatedGuestState |= HMVMX_UPDATED_GUEST_SYSENTER_EIP_MSR;
+        HMVMXCPU_GST_SET_UPDATED(pVCpu, HMVMX_UPDATED_GUEST_SYSENTER_EIP_MSR);
     }
-    if (!(pVCpu->hm.s.vmx.fUpdatedGuestState & HMVMX_UPDATED_GUEST_SYSENTER_ESP_MSR))
+    if (!HMVMXCPU_GST_IS_UPDATED(pVCpu, HMVMX_UPDATED_GUEST_SYSENTER_ESP_MSR))
     {
         rc = VMXReadVmcsGstN(VMX_VMCS_GUEST_SYSENTER_ESP, &u64Val);    AssertRCReturn(rc, rc);
         pMixedCtx->SysEnter.esp = u64Val;
-        pVCpu->hm.s.vmx.fUpdatedGuestState |= HMVMX_UPDATED_GUEST_SYSENTER_ESP_MSR;
+        HMVMXCPU_GST_SET_UPDATED(pVCpu, HMVMX_UPDATED_GUEST_SYSENTER_ESP_MSR);
     }
     return rc;
 }
@@ -5480,12 +5492,12 @@ static int hmR0VmxSaveGuestSysenterMsrs(PVMCPU pVCpu, PCPUMCTX pMixedCtx)
 static int hmR0VmxSaveGuestFSBaseMsr(PVMCPU pVCpu, PCPUMCTX pMixedCtx)
 {
     int rc = VINF_SUCCESS;
-    if (!(pVCpu->hm.s.vmx.fUpdatedGuestState & HMVMX_UPDATED_GUEST_FS_BASE_MSR))
+    if (!HMVMXCPU_GST_IS_UPDATED(pVCpu, HMVMX_UPDATED_GUEST_FS_BASE_MSR))
     {
         uint64_t u64Val = 0;
         rc = VMXReadVmcsGstN(VMX_VMCS_GUEST_FS_BASE, &u64Val);   AssertRCReturn(rc, rc);
         pMixedCtx->fs.u64Base = u64Val;
-        pVCpu->hm.s.vmx.fUpdatedGuestState |= HMVMX_UPDATED_GUEST_FS_BASE_MSR;
+        HMVMXCPU_GST_SET_UPDATED(pVCpu, HMVMX_UPDATED_GUEST_FS_BASE_MSR);
     }
     return rc;
 }
@@ -5506,12 +5518,12 @@ static int hmR0VmxSaveGuestFSBaseMsr(PVMCPU pVCpu, PCPUMCTX pMixedCtx)
 static int hmR0VmxSaveGuestGSBaseMsr(PVMCPU pVCpu, PCPUMCTX pMixedCtx)
 {
     int rc = VINF_SUCCESS;
-    if (!(pVCpu->hm.s.vmx.fUpdatedGuestState & HMVMX_UPDATED_GUEST_GS_BASE_MSR))
+    if (!HMVMXCPU_GST_IS_UPDATED(pVCpu, HMVMX_UPDATED_GUEST_GS_BASE_MSR))
     {
         uint64_t u64Val = 0;
         rc = VMXReadVmcsGstN(VMX_VMCS_GUEST_GS_BASE, &u64Val);   AssertRCReturn(rc, rc);
         pMixedCtx->gs.u64Base = u64Val;
-        pVCpu->hm.s.vmx.fUpdatedGuestState |= HMVMX_UPDATED_GUEST_GS_BASE_MSR;
+        HMVMXCPU_GST_SET_UPDATED(pVCpu, HMVMX_UPDATED_GUEST_GS_BASE_MSR);
     }
     return rc;
 }
@@ -5532,7 +5544,7 @@ static int hmR0VmxSaveGuestGSBaseMsr(PVMCPU pVCpu, PCPUMCTX pMixedCtx)
  */
 static int hmR0VmxSaveGuestAutoLoadStoreMsrs(PVMCPU pVCpu, PCPUMCTX pMixedCtx)
 {
-    if (pVCpu->hm.s.vmx.fUpdatedGuestState & HMVMX_UPDATED_GUEST_AUTO_LOAD_STORE_MSRS)
+    if (HMVMXCPU_GST_IS_UPDATED(pVCpu, HMVMX_UPDATED_GUEST_AUTO_LOAD_STORE_MSRS))
         return VINF_SUCCESS;
 
 #ifdef VBOX_WITH_AUTO_MSR_LOAD_RESTORE
@@ -5557,7 +5569,7 @@ static int hmR0VmxSaveGuestAutoLoadStoreMsrs(PVMCPU pVCpu, PCPUMCTX pMixedCtx)
     }
 #endif
 
-    pVCpu->hm.s.vmx.fUpdatedGuestState |= HMVMX_UPDATED_GUEST_AUTO_LOAD_STORE_MSRS;
+    HMVMXCPU_GST_SET_UPDATED(pVCpu, HMVMX_UPDATED_GUEST_AUTO_LOAD_STORE_MSRS);
     return VINF_SUCCESS;
 }
 
@@ -5586,10 +5598,10 @@ static int hmR0VmxSaveGuestControlRegs(PVMCPU pVCpu, PCPUMCTX pMixedCtx)
 
     /* Guest CR2 - updated always during the world-switch or in #PF. */
     /* Guest CR3. Only changes with Nested Paging. This must be done -after- saving CR0 and CR4 from the guest! */
-    if (!(pVCpu->hm.s.vmx.fUpdatedGuestState & HMVMX_UPDATED_GUEST_CR3))
+    if (!HMVMXCPU_GST_IS_UPDATED(pVCpu, HMVMX_UPDATED_GUEST_CR3))
     {
-        Assert(pVCpu->hm.s.vmx.fUpdatedGuestState & HMVMX_UPDATED_GUEST_CR0);
-        Assert(pVCpu->hm.s.vmx.fUpdatedGuestState & HMVMX_UPDATED_GUEST_CR4);
+        Assert(HMVMXCPU_GST_IS_UPDATED(pVCpu, HMVMX_UPDATED_GUEST_CR0));
+        Assert(HMVMXCPU_GST_IS_UPDATED(pVCpu, HMVMX_UPDATED_GUEST_CR4));
 
         PVM pVM = pVCpu->CTX_SUFF(pVM);
         if (   pVM->hm.s.vmx.fUnrestrictedGuest
@@ -5634,7 +5646,7 @@ static int hmR0VmxSaveGuestControlRegs(PVMCPU pVCpu, PCPUMCTX pMixedCtx)
             }
         }
 
-        pVCpu->hm.s.vmx.fUpdatedGuestState |= HMVMX_UPDATED_GUEST_CR3;
+        HMVMXCPU_GST_SET_UPDATED(pVCpu, HMVMX_UPDATED_GUEST_CR3);
     }
 
     /*
@@ -5768,7 +5780,7 @@ DECLINLINE(int) hmR0VmxReadSegmentReg(PVMCPU pVCpu, uint32_t idxSel, uint32_t id
 static int hmR0VmxSaveGuestSegmentRegs(PVMCPU pVCpu, PCPUMCTX pMixedCtx)
 {
     /* Guest segment registers. */
-    if (!(pVCpu->hm.s.vmx.fUpdatedGuestState & HMVMX_UPDATED_GUEST_SEGMENT_REGS))
+    if (!HMVMXCPU_GST_IS_UPDATED(pVCpu, HMVMX_UPDATED_GUEST_SEGMENT_REGS))
     {
         int rc = hmR0VmxSaveGuestCR0(pVCpu, pMixedCtx);   AssertRCReturn(rc, rc);
         rc = VMXLOCAL_READ_SEG(CS, cs);                   AssertRCReturn(rc, rc);
@@ -5788,7 +5800,7 @@ static int hmR0VmxSaveGuestSegmentRegs(PVMCPU pVCpu, PCPUMCTX pMixedCtx)
             pMixedCtx->fs.Attr.u = pVCpu->hm.s.vmx.RealMode.AttrFS.u;
             pMixedCtx->gs.Attr.u = pVCpu->hm.s.vmx.RealMode.AttrGS.u;
         }
-        pVCpu->hm.s.vmx.fUpdatedGuestState |= HMVMX_UPDATED_GUEST_SEGMENT_REGS;
+        HMVMXCPU_GST_SET_UPDATED(pVCpu, HMVMX_UPDATED_GUEST_SEGMENT_REGS);
     }
 
     return VINF_SUCCESS;
@@ -5812,37 +5824,37 @@ static int hmR0VmxSaveGuestTableRegs(PVMCPU pVCpu, PCPUMCTX pMixedCtx)
     int rc = VINF_SUCCESS;
 
     /* Guest LDTR. */
-    if (!(pVCpu->hm.s.vmx.fUpdatedGuestState & HMVMX_UPDATED_GUEST_LDTR))
+    if (!HMVMXCPU_GST_IS_UPDATED(pVCpu, HMVMX_UPDATED_GUEST_LDTR))
     {
         rc = VMXLOCAL_READ_SEG(LDTR, ldtr);
         AssertRCReturn(rc, rc);
-        pVCpu->hm.s.vmx.fUpdatedGuestState |= HMVMX_UPDATED_GUEST_LDTR;
+        HMVMXCPU_GST_SET_UPDATED(pVCpu, HMVMX_UPDATED_GUEST_LDTR);
     }
 
     /* Guest GDTR. */
     uint64_t u64Val = 0;
     uint32_t u32Val = 0;
-    if (!(pVCpu->hm.s.vmx.fUpdatedGuestState & HMVMX_UPDATED_GUEST_GDTR))
+    if (!HMVMXCPU_GST_IS_UPDATED(pVCpu, HMVMX_UPDATED_GUEST_GDTR))
     {
         rc = VMXReadVmcsGstN(VMX_VMCS_GUEST_GDTR_BASE, &u64Val);        AssertRCReturn(rc, rc);
         rc = VMXReadVmcs32(VMX_VMCS32_GUEST_GDTR_LIMIT, &u32Val);       AssertRCReturn(rc, rc);
         pMixedCtx->gdtr.pGdt  = u64Val;
         pMixedCtx->gdtr.cbGdt = u32Val;
-        pVCpu->hm.s.vmx.fUpdatedGuestState |= HMVMX_UPDATED_GUEST_GDTR;
+        HMVMXCPU_GST_SET_UPDATED(pVCpu, HMVMX_UPDATED_GUEST_GDTR);
     }
 
     /* Guest IDTR. */
-    if (!(pVCpu->hm.s.vmx.fUpdatedGuestState & HMVMX_UPDATED_GUEST_IDTR))
+    if (!HMVMXCPU_GST_IS_UPDATED(pVCpu, HMVMX_UPDATED_GUEST_IDTR))
     {
         rc = VMXReadVmcsGstN(VMX_VMCS_GUEST_IDTR_BASE, &u64Val);        AssertRCReturn(rc, rc);
         rc = VMXReadVmcs32(VMX_VMCS32_GUEST_IDTR_LIMIT, &u32Val);       AssertRCReturn(rc, rc);
         pMixedCtx->idtr.pIdt  = u64Val;
         pMixedCtx->idtr.cbIdt = u32Val;
-        pVCpu->hm.s.vmx.fUpdatedGuestState |= HMVMX_UPDATED_GUEST_IDTR;
+        HMVMXCPU_GST_SET_UPDATED(pVCpu, HMVMX_UPDATED_GUEST_IDTR);
     }
 
     /* Guest TR. */
-    if (!(pVCpu->hm.s.vmx.fUpdatedGuestState & HMVMX_UPDATED_GUEST_TR))
+    if (!HMVMXCPU_GST_IS_UPDATED(pVCpu, HMVMX_UPDATED_GUEST_TR))
     {
         rc = hmR0VmxSaveGuestCR0(pVCpu, pMixedCtx);
         AssertRCReturn(rc, rc);
@@ -5853,7 +5865,7 @@ static int hmR0VmxSaveGuestTableRegs(PVMCPU pVCpu, PCPUMCTX pMixedCtx)
             rc = VMXLOCAL_READ_SEG(TR, tr);
             AssertRCReturn(rc, rc);
         }
-        pVCpu->hm.s.vmx.fUpdatedGuestState |= HMVMX_UPDATED_GUEST_TR;
+        HMVMXCPU_GST_SET_UPDATED(pVCpu, HMVMX_UPDATED_GUEST_TR);
     }
     return rc;
 }
@@ -5875,7 +5887,7 @@ static int hmR0VmxSaveGuestTableRegs(PVMCPU pVCpu, PCPUMCTX pMixedCtx)
  */
 static int hmR0VmxSaveGuestDR7(PVMCPU pVCpu, PCPUMCTX pMixedCtx)
 {
-    if (!(pVCpu->hm.s.vmx.fUpdatedGuestState & HMVMX_UPDATED_GUEST_DEBUG))
+    if (!HMVMXCPU_GST_IS_UPDATED(pVCpu, HMVMX_UPDATED_GUEST_DEBUG))
     {
         if (!pVCpu->hm.s.fUsingHyperDR7)
         {
@@ -5885,7 +5897,7 @@ static int hmR0VmxSaveGuestDR7(PVMCPU pVCpu, PCPUMCTX pMixedCtx)
             pMixedCtx->dr[7] = u32Val;
         }
 
-        pVCpu->hm.s.vmx.fUpdatedGuestState |= HMVMX_UPDATED_GUEST_DEBUG;
+        HMVMXCPU_GST_SET_UPDATED(pVCpu, HMVMX_UPDATED_GUEST_DEBUG);
     }
     return VINF_SUCCESS;
 }
@@ -5905,7 +5917,7 @@ static int hmR0VmxSaveGuestDR7(PVMCPU pVCpu, PCPUMCTX pMixedCtx)
 static int hmR0VmxSaveGuestApicState(PVMCPU pVCpu, PCPUMCTX pMixedCtx)
 {
     /* Updating TPR is already done in hmR0VmxPostRunGuest(). Just update the flag. */
-    pVCpu->hm.s.vmx.fUpdatedGuestState |= HMVMX_UPDATED_GUEST_APIC_STATE;
+    HMVMXCPU_GST_SET_UPDATED(pVCpu, HMVMX_UPDATED_GUEST_APIC_STATE);
     return VINF_SUCCESS;
 }
 
@@ -5925,7 +5937,7 @@ static int hmR0VmxSaveGuestState(PVMCPU pVCpu, PCPUMCTX pMixedCtx)
     Assert(pVCpu);
     Assert(pMixedCtx);
 
-    if (pVCpu->hm.s.vmx.fUpdatedGuestState == HMVMX_UPDATED_GUEST_ALL)
+    if (HMVMXCPU_GST_VALUE(pVCpu) == HMVMX_UPDATED_GUEST_ALL)
         return VINF_SUCCESS;
 
     /* Though we can longjmp to ring-3 due to log-flushes here and get recalled
@@ -5969,8 +5981,8 @@ static int hmR0VmxSaveGuestState(PVMCPU pVCpu, PCPUMCTX pMixedCtx)
     rc = hmR0VmxSaveGuestApicState(pVCpu, pMixedCtx);
     AssertLogRelMsgRCReturn(rc, ("hmR0VmxSaveGuestApicState failed! rc=%Rrc (pVCpu=%p)\n", rc, pVCpu), rc);
 
-    AssertMsg(pVCpu->hm.s.vmx.fUpdatedGuestState == HMVMX_UPDATED_GUEST_ALL,
-              ("Missed guest state bits while saving state; residue %RX32\n", pVCpu->hm.s.vmx.fUpdatedGuestState));
+    AssertMsg(HMVMXCPU_GST_VALUE(pVCpu) == HMVMX_UPDATED_GUEST_ALL,
+              ("Missed guest state bits while saving state; residue %RX32\n", HMVMXCPU_GST_VALUE(pVCpu)));
 
     if (VMMRZCallRing3IsEnabled(pVCpu))
         VMMR0LogFlushEnable(pVCpu);
@@ -6241,11 +6253,11 @@ static int hmR0VmxLeave(PVM pVM, PVMCPU pVCpu, PCPUMCTX pMixedCtx, bool fSaveGue
 
     /* Save the guest state if necessary. */
     if (   fSaveGuestState
-        && pVCpu->hm.s.vmx.fUpdatedGuestState != HMVMX_UPDATED_GUEST_ALL)
+        && HMVMXCPU_GST_VALUE(pVCpu) != HMVMX_UPDATED_GUEST_ALL)
     {
         int rc = hmR0VmxSaveGuestState(pVCpu, pMixedCtx);
         AssertRCReturn(rc, rc);
-        Assert(pVCpu->hm.s.vmx.fUpdatedGuestState == HMVMX_UPDATED_GUEST_ALL);
+        Assert(HMVMXCPU_GST_VALUE(pVCpu) == HMVMX_UPDATED_GUEST_ALL);
     }
 
     /* Restore host FPU state if necessary and resync on next R0 reentry .*/
@@ -6431,7 +6443,7 @@ static int hmR0VmxExitToRing3(PVM pVM, PVMCPU pVCpu, PCPUMCTX pMixedCtx, int rcE
                               | CPUM_CHANGED_IDTR
                               | CPUM_CHANGED_TR
                               | CPUM_CHANGED_HIDDEN_SEL_REGS);
-    Assert(pVCpu->hm.s.vmx.fUpdatedGuestState & HMVMX_UPDATED_GUEST_CR0);
+    Assert(HMVMXCPU_GST_IS_UPDATED(pVCpu, HMVMX_UPDATED_GUEST_CR0));
     if (   pVM->hm.s.fNestedPaging
         && CPUMIsGuestPagingEnabledEx(pMixedCtx))
     {
@@ -6443,7 +6455,7 @@ static int hmR0VmxExitToRing3(PVM pVM, PVMCPU pVCpu, PCPUMCTX pMixedCtx, int rcE
      */
     if (pVCpu->hm.s.fClearTrapFlag)
     {
-        Assert(pVCpu->hm.s.vmx.fUpdatedGuestState & HMVMX_UPDATED_GUEST_RFLAGS);
+        Assert(HMVMXCPU_GST_IS_UPDATED(pVCpu, HMVMX_UPDATED_GUEST_RFLAGS));
         pMixedCtx->eflags.Bits.u1TF = 0;
         pVCpu->hm.s.fClearTrapFlag = false;
     }
@@ -6572,7 +6584,7 @@ static void hmR0VmxEvaluatePendingEvent(PVMCPU pVCpu, PCPUMCTX pMixedCtx)
     bool fBlockMovSS    = RT_BOOL(uIntrState & VMX_VMCS_GUEST_INTERRUPTIBILITY_STATE_BLOCK_MOVSS);
     bool fBlockSti      = RT_BOOL(uIntrState & VMX_VMCS_GUEST_INTERRUPTIBILITY_STATE_BLOCK_STI);
 
-    Assert(!fBlockSti || (pVCpu->hm.s.vmx.fUpdatedGuestState & HMVMX_UPDATED_GUEST_RFLAGS));
+    Assert(!fBlockSti || HMVMXCPU_GST_IS_UPDATED(pVCpu, HMVMX_UPDATED_GUEST_RFLAGS));
     Assert(   !(uIntrState & VMX_VMCS_GUEST_INTERRUPTIBILITY_STATE_BLOCK_NMI)      /* We don't support block-by-NMI and SMI yet.*/
            && !(uIntrState & VMX_VMCS_GUEST_INTERRUPTIBILITY_STATE_BLOCK_SMI));
     Assert(!fBlockSti || pMixedCtx->eflags.Bits.u1IF);     /* Cannot set block-by-STI when interrupts are disabled. */
@@ -6635,6 +6647,26 @@ static void hmR0VmxEvaluatePendingEvent(PVMCPU pVCpu, PCPUMCTX pMixedCtx)
 
 
 /**
+ * Sets a pending-debug exception to be delivered to the guest if the guest is
+ * single-stepping.
+ *
+ * @param   pVCpu           Pointer to the VMCPU.
+ * @param   pMixedCtx       Pointer to the guest-CPU context. The data may be
+ *                          out-of-sync. Make sure to update the required fields
+ *                          before using them.
+ */
+DECLINLINE(void) hmR0VmxSetPendingDebugXcpt(PVMCPU pVCpu, PCPUMCTX pMixedCtx)
+{
+    Assert(HMVMXCPU_GST_IS_UPDATED(pVCpu, HMVMX_UPDATED_GUEST_RFLAGS));
+    if (pMixedCtx->eflags.Bits.u1TF)    /* We don't have any IA32_DEBUGCTL MSR for guests. Treat as all bits 0. */
+    {
+        int rc = VMXWriteVmcs32(VMX_VMCS_GUEST_PENDING_DEBUG_EXCEPTIONS, VMX_VMCS_GUEST_DEBUG_EXCEPTIONS_BS);
+        AssertRC(rc);
+    }
+}
+
+
+/**
  * Injects any pending events into the guest if the guest is in a state to
  * receive them.
  *
@@ -6654,7 +6686,7 @@ static int hmR0VmxInjectPendingEvent(PVMCPU pVCpu, PCPUMCTX pMixedCtx)
     bool fBlockMovSS    = RT_BOOL(uIntrState & VMX_VMCS_GUEST_INTERRUPTIBILITY_STATE_BLOCK_MOVSS);
     bool fBlockSti      = RT_BOOL(uIntrState & VMX_VMCS_GUEST_INTERRUPTIBILITY_STATE_BLOCK_STI);
 
-    Assert(!fBlockSti || (pVCpu->hm.s.vmx.fUpdatedGuestState & HMVMX_UPDATED_GUEST_RFLAGS));
+    Assert(!fBlockSti || HMVMXCPU_GST_IS_UPDATED(pVCpu, HMVMX_UPDATED_GUEST_RFLAGS));
     Assert(   !(uIntrState & VMX_VMCS_GUEST_INTERRUPTIBILITY_STATE_BLOCK_NMI)      /* We don't support block-by-NMI and SMI yet.*/
            && !(uIntrState & VMX_VMCS_GUEST_INTERRUPTIBILITY_STATE_BLOCK_SMI));
     Assert(!fBlockSti || pMixedCtx->eflags.Bits.u1IF);       /* Cannot set block-by-STI when interrupts are disabled. */
@@ -6698,28 +6730,31 @@ static int hmR0VmxInjectPendingEvent(PVMCPU pVCpu, PCPUMCTX pMixedCtx)
 #endif
     }
 
-    /* Delivery pending debug exception if the guest is single-stepping. Evaluate and set the BS bit. */
-    if (   !pVCpu->hm.s.fSingleInstruction
-        && !DBGFIsStepping(pVCpu))
+    /* Deliver pending debug exception if the guest is single-stepping. Evaluate and set the BS bit. */
+    if (   fBlockSti
+        || fBlockMovSS)
     {
-        int rc2 = hmR0VmxSaveGuestRflags(pVCpu, pMixedCtx);
-        AssertRCReturn(rc2, rc2);
-        if (pMixedCtx->eflags.Bits.u1TF)    /* We don't have any IA32_DEBUGCTL MSR for guests. Treat as all bits 0. */
+        if (   !pVCpu->hm.s.fSingleInstruction
+            && !DBGFIsStepping(pVCpu))
         {
             /*
              * The pending-debug exceptions field is cleared on all VM-exits except VMX_EXIT_TPR_BELOW_THRESHOLD,
              * VMX_EXIT_MTF, VMX_EXIT_APIC_WRITE and VMX_EXIT_VIRTUALIZED_EOI.
              * See Intel spec. 27.3.4 "Saving Non-Register State".
              */
-            rc2 = VMXWriteVmcs32(VMX_VMCS_GUEST_PENDING_DEBUG_EXCEPTIONS, VMX_VMCS_GUEST_DEBUG_EXCEPTIONS_BS);
+            int rc2 = hmR0VmxSaveGuestRflags(pVCpu, pMixedCtx);
             AssertRCReturn(rc2, rc2);
+            hmR0VmxSetPendingDebugXcpt(pVCpu, pMixedCtx);
+        }
+        else if (pMixedCtx->eflags.Bits.u1TF)
+        {
+            /*
+             * We are single-stepping in the hypervisor debugger using EFLAGS.TF. Clear interrupt inhibition as setting the
+             * BS bit would mean delivering a #DB to the guest upon VM-entry when it shouldn't be.
+             */
+            Assert(!(pVCpu->CTX_SUFF(pVM)->hm.s.vmx.Msrs.VmxProcCtls.n.allowed1 & VMX_VMCS_CTRL_PROC_EXEC_MONITOR_TRAP_FLAG));
+            uIntrState = 0;
         }
-    }
-    else
-    {
-        /* We are single-stepping in the hypervisor debugger, clear interrupt inhibition as setting the BS bit would mean
-           delivering a #DB to the guest upon VM-entry when it shouldn't be. */
-        uIntrState = 0;
     }
 
     /*
@@ -6962,7 +6997,7 @@ static int hmR0VmxInjectEventVmcs(PVMCPU pVCpu, PCPUMCTX pMixedCtx, uint64_t u64
             rc |= hmR0VmxSaveGuestTableRegs(pVCpu, pMixedCtx);
             rc |= hmR0VmxSaveGuestRipRspRflags(pVCpu, pMixedCtx);
             AssertRCReturn(rc, rc);
-            Assert(pVCpu->hm.s.vmx.fUpdatedGuestState & HMVMX_UPDATED_GUEST_RIP);
+            Assert(HMVMXCPU_GST_IS_UPDATED(pVCpu, HMVMX_UPDATED_GUEST_RIP));
 
             /* Check if the interrupt handler is present in the IVT (real-mode IDT). IDT limit is (4N - 1). */
             const size_t cbIdtEntry = sizeof(X86IDTR16);
@@ -7356,7 +7391,7 @@ static int hmR0VmxLoadGuestState(PVM pVM, PVMCPU pVCpu, PCPUMCTX pMixedCtx)
     /*
      * Load the guest-state into the VMCS.
      * Any ordering dependency among the sub-functions below must be explicitly stated using comments.
-     * Ideally, assert that the cross-dependent bits are up to date at the point of using it.
+     * Ideally, assert that the cross-dependent bits are up-to-date at the point of using it.
      */
     int rc = hmR0VmxSetupVMRunHandler(pVCpu, pMixedCtx);
     AssertLogRelMsgRCReturn(rc, ("hmR0VmxSetupVMRunHandler! rc=%Rrc (pVM=%p pVCpu=%p)\n", rc, pVM, pVCpu), rc);
@@ -7759,7 +7794,7 @@ static void hmR0VmxPostRunGuest(PVM pVM, PVMCPU pVCpu, PCPUMCTX pMixedCtx, PVMXT
 
     ASMAtomicWriteBool(&pVCpu->hm.s.fCheckedTLBFlush, false);   /* See HMInvalidatePageOnAllVCpus(): used for TLB-shootdowns. */
     ASMAtomicIncU32(&pVCpu->hm.s.cWorldSwitchExits);            /* Initialized in vmR3CreateUVM(): used for TLB-shootdowns. */
-    pVCpu->hm.s.vmx.fUpdatedGuestState = 0;                     /* Exits/longjmps to ring-3 requires saving the guest state. */
+    HMVMXCPU_GST_RESET_TO(pVCpu, 0);                            /* Exits/longjmps to ring-3 requires saving the guest state. */
     pVmxTransient->fVmcsFieldsRead     = 0;                     /* Transient fields need to be read from the VMCS. */
     pVmxTransient->fVectoringPF        = false;                 /* Vectoring page-fault needs to be determined later. */
 
@@ -8012,7 +8047,7 @@ static int hmR0VmxRunGuestCodeStep(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx)
 VMMR0DECL(int) VMXR0RunGuestCode(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx)
 {
     Assert(VMMRZCallRing3IsEnabled(pVCpu));
-    Assert(pVCpu->hm.s.vmx.fUpdatedGuestState == HMVMX_UPDATED_GUEST_ALL);
+    Assert(HMVMXCPU_GST_VALUE(pVCpu) == HMVMX_UPDATED_GUEST_ALL);
     HMVMX_ASSERT_PREEMPT_SAFE();
 
     VMMRZCallRing3SetNotification(pVCpu, hmR0VmxCallRing3Callback, pCtx);
@@ -8166,10 +8201,20 @@ DECLINLINE(int) hmR0VmxAdvanceGuestRip(PVMCPU pVCpu, PCPUMCTX pMixedCtx, PVMXTRA
 {
     int rc = hmR0VmxReadExitInstrLenVmcs(pVCpu, pVmxTransient);
     rc    |= hmR0VmxSaveGuestRip(pVCpu, pMixedCtx);
+    rc    |= hmR0VmxSaveGuestRflags(pVCpu, pMixedCtx);
     AssertRCReturn(rc, rc);
 
     pMixedCtx->rip += pVmxTransient->cbInstr;
     HMCPU_CF_SET(pVCpu, HM_CHANGED_GUEST_RIP);
+
+    /*
+     * Deliver a debug exception to the guest if it is single-stepping. Don't directly inject a #DB but use the
+     * pending debug exception field as it takes care of priority of events.
+     *
+     * See Intel spec. 32.2.1 "Debug Exceptions".
+     */
+    hmR0VmxSetPendingDebugXcpt(pVCpu, pMixedCtx);
+
     return rc;
 }
 
@@ -9803,6 +9848,7 @@ HMVMX_EXIT_DECL hmR0VmxExitIoInstr(PVMCPU pVCpu, PCPUMCTX pMixedCtx, PVMXTRANSIE
     bool     fIOWrite  = (   VMX_EXIT_QUALIFICATION_IO_DIRECTION(pVmxTransient->uExitQualification)
                           == VMX_EXIT_QUALIFICATION_IO_DIRECTION_OUT);
     bool     fIOString = VMX_EXIT_QUALIFICATION_IO_IS_STRING(pVmxTransient->uExitQualification);
+    bool     fStepping = RT_BOOL(pMixedCtx->eflags.Bits.u1TF);
     AssertReturn(uIOWidth <= 3 && uIOWidth != 2, VERR_HMVMX_IPE_1);
 
     /* I/O operation lookup arrays. */
@@ -9926,7 +9972,12 @@ HMVMX_EXIT_DECL hmR0VmxExitIoInstr(PVMCPU pVCpu, PCPUMCTX pMixedCtx, PVMXTRANSIE
 
         /* INS & OUTS with REP prefix modify RFLAGS. */
         if (fIOString)
+        {
+            /** @todo Single-step for INS/OUTS with REP prefix? */
             HMCPU_CF_SET(pVCpu, HM_CHANGED_GUEST_RFLAGS);
+        }
+        else if (fStepping)
+            hmR0VmxSetPendingDebugXcpt(pVCpu, pMixedCtx);
 
         /*
          * If any I/O breakpoints are armed, we need to check if one triggered
@@ -10619,6 +10670,7 @@ static int hmR0VmxExitXcptGP(PVMCPU pVCpu, PCPUMCTX pMixedCtx, PVMXTRANSIENT pVm
                 pMixedCtx->eflags.Bits.u1IF = 0;
                 pMixedCtx->rip += pDis->cbInstr;
                 HMCPU_CF_SET(pVCpu, HM_CHANGED_GUEST_RIP | HM_CHANGED_GUEST_RFLAGS);
+                hmR0VmxSetPendingDebugXcpt(pVCpu, pMixedCtx);
                 STAM_COUNTER_INC(&pVCpu->hm.s.StatExitCli);
                 break;
             }
@@ -10630,6 +10682,7 @@ static int hmR0VmxExitXcptGP(PVMCPU pVCpu, PCPUMCTX pMixedCtx, PVMXTRANSIENT pVm
                 EMSetInhibitInterruptsPC(pVCpu, pMixedCtx->rip);
                 Assert(VMCPU_FF_IS_PENDING(pVCpu, VMCPU_FF_INHIBIT_INTERRUPTS));
                 HMCPU_CF_SET(pVCpu, HM_CHANGED_GUEST_RIP | HM_CHANGED_GUEST_RFLAGS);
+                hmR0VmxSetPendingDebugXcpt(pVCpu, pMixedCtx);
                 STAM_COUNTER_INC(&pVCpu->hm.s.StatExitSti);
                 break;
             }
@@ -10646,8 +10699,9 @@ static int hmR0VmxExitXcptGP(PVMCPU pVCpu, PCPUMCTX pMixedCtx, PVMXTRANSIENT pVm
             case OP_POPF:
             {
                 Log4(("POPF CS:RIP %04x:%#RX64\n", pMixedCtx->cs.Sel, pMixedCtx->rip));
-                uint32_t cbParm = 0;
-                uint32_t uMask  = 0;
+                uint32_t cbParm;
+                uint32_t uMask;
+                bool     fStepping = RT_BOOL(pMixedCtx->eflags.Bits.u1TF);
                 if (pDis->fPrefix & DISPREFIX_OPSIZE)
                 {
                     cbParm = 4;
@@ -10682,18 +10736,21 @@ static int hmR0VmxExitXcptGP(PVMCPU pVCpu, PCPUMCTX pMixedCtx, PVMXTRANSIENT pVm
                 pMixedCtx->esp              += cbParm;
                 pMixedCtx->esp              &= uMask;
                 pMixedCtx->rip              += pDis->cbInstr;
-
                 HMCPU_CF_SET(pVCpu,  HM_CHANGED_GUEST_RIP
                                     | HM_CHANGED_GUEST_RSP
                                     | HM_CHANGED_GUEST_RFLAGS);
+                /* Generate a pending-debug exception when stepping over POPF regardless of how POPF modifies EFLAGS.TF. */
+                if (fStepping)
+                    hmR0VmxSetPendingDebugXcpt(pVCpu, pMixedCtx);
+
                 STAM_COUNTER_INC(&pVCpu->hm.s.StatExitPopf);
                 break;
             }
 
             case OP_PUSHF:
             {
-                uint32_t cbParm = 0;
-                uint32_t uMask  = 0;
+                uint32_t cbParm;
+                uint32_t uMask;
                 if (pDis->fPrefix & DISPREFIX_OPSIZE)
                 {
                     cbParm = 4;
@@ -10730,6 +10787,7 @@ static int hmR0VmxExitXcptGP(PVMCPU pVCpu, PCPUMCTX pMixedCtx, PVMXTRANSIENT pVm
                 pMixedCtx->esp               &= uMask;
                 pMixedCtx->rip               += pDis->cbInstr;
                 HMCPU_CF_SET(pVCpu, HM_CHANGED_GUEST_RIP | HM_CHANGED_GUEST_RSP);
+                hmR0VmxSetPendingDebugXcpt(pVCpu, pMixedCtx);
                 STAM_COUNTER_INC(&pVCpu->hm.s.StatExitPushf);
                 break;
             }
@@ -10740,6 +10798,7 @@ static int hmR0VmxExitXcptGP(PVMCPU pVCpu, PCPUMCTX pMixedCtx, PVMXTRANSIENT pVm
                  *        instruction reference. */
                 RTGCPTR  GCPtrStack = 0;
                 uint32_t uMask      = 0xffff;
+                bool     fStepping  = RT_BOOL(pMixedCtx->eflags.Bits.u1TF);
                 uint16_t aIretFrame[3];
                 if (pDis->fPrefix & (DISPREFIX_OPSIZE | DISPREFIX_ADDRSIZE))
                 {
@@ -10767,6 +10826,9 @@ static int hmR0VmxExitXcptGP(PVMCPU pVCpu, PCPUMCTX pMixedCtx, PVMXTRANSIENT pVm
                                     | HM_CHANGED_GUEST_SEGMENT_REGS
                                     | HM_CHANGED_GUEST_RSP
                                     | HM_CHANGED_GUEST_RFLAGS);
+                /* Generate a pending-debug exception when stepping over IRET regardless of how IRET modifies EFLAGS.TF. */
+                if (fStepping)
+                    hmR0VmxSetPendingDebugXcpt(pVCpu, pMixedCtx);
                 Log4(("IRET %#RX32 to %04x:%x\n", GCPtrStack, pMixedCtx->cs.Sel, pMixedCtx->ip));
                 STAM_COUNTER_INC(&pVCpu->hm.s.StatExitIret);
                 break;
@@ -10776,6 +10838,7 @@ static int hmR0VmxExitXcptGP(PVMCPU pVCpu, PCPUMCTX pMixedCtx, PVMXTRANSIENT pVm
             {
                 uint16_t uVector = pDis->Param1.uValue & 0xff;
                 hmR0VmxSetPendingIntN(pVCpu, pMixedCtx, uVector, pDis->cbInstr);
+                /* INT clears EFLAGS.TF, we mustn't set any pending debug exceptions here. */
                 STAM_COUNTER_INC(&pVCpu->hm.s.StatExitInt);
                 break;
             }
@@ -10785,6 +10848,7 @@ static int hmR0VmxExitXcptGP(PVMCPU pVCpu, PCPUMCTX pMixedCtx, PVMXTRANSIENT pVm
                 if (pMixedCtx->eflags.Bits.u1OF)
                 {
                     hmR0VmxSetPendingXcptOF(pVCpu, pMixedCtx, pDis->cbInstr);
+                    /* INTO clears EFLAGS.TF, we mustn't set any pending debug exceptions here. */
                     STAM_COUNTER_INC(&pVCpu->hm.s.StatExitInt);
                 }
                 break;
@@ -10796,6 +10860,8 @@ static int hmR0VmxExitXcptGP(PVMCPU pVCpu, PCPUMCTX pMixedCtx, PVMXTRANSIENT pVm
                                                                     EMCODETYPE_SUPERVISOR);
                 rc = VBOXSTRICTRC_VAL(rc2);
                 HMCPU_CF_SET(pVCpu, HM_CHANGED_ALL_GUEST);
+                /** @todo We have to set pending-debug exceptions here when the guest is
+                 *        single-stepping depending on the instruction that was interpreted. */
                 Log4(("#GP rc=%Rrc\n", rc));
                 break;
             }
diff --git a/src/VBox/VMM/VMMR3/CPUM.cpp b/src/VBox/VMM/VMMR3/CPUM.cpp
index dd81fc4..a7315d3 100644
--- a/src/VBox/VMM/VMMR3/CPUM.cpp
+++ b/src/VBox/VMM/VMMR3/CPUM.cpp
@@ -987,6 +987,14 @@ static int cpumR3CpuIdInstallAndExplodeLeaves(PVM pVM, PCPUM pCPUM, PCPUMCPUIDLE
     rc = cpumR3CpuIdExplodeFeatures(pCPUM->GuestInfo.paCpuIdLeavesR3, pCPUM->GuestInfo.cCpuIdLeaves, &pCPUM->GuestFeatures);
     AssertLogRelRCReturn(rc, rc);
 
+    /*
+     * Adjust the scalable bus frequency according to the CPUID information
+     * we're now using.
+     */
+    if (CPUMMICROARCH_IS_INTEL_CORE7(pVM->cpum.s.GuestFeatures.enmMicroarch))
+        pCPUM->GuestInfo.uScalableBusFreq = pCPUM->GuestFeatures.enmMicroarch >= kCpumMicroarch_Intel_Core7_SandyBridge
+                                          ? UINT64_C(100000000)  /* 100MHz */
+                                          : UINT64_C(133333333); /* 133MHz */
 
     /*
      * Populate the legacy arrays.  Currently used for everything, later only
diff --git a/src/VBox/VMM/VMMR3/CPUMR3CpuId.cpp b/src/VBox/VMM/VMMR3/CPUMR3CpuId.cpp
index e3d6f9a..2e094bf 100644
--- a/src/VBox/VMM/VMMR3/CPUMR3CpuId.cpp
+++ b/src/VBox/VMM/VMMR3/CPUMR3CpuId.cpp
@@ -770,6 +770,7 @@ static bool cpumR3IsEcxRelevantForCpuIdLeaf(uint32_t uLeaf, uint32_t *pcSubLeave
 {
     *pfFinalEcxUnchanged = false;
 
+    uint32_t auCur[4];
     uint32_t auPrev[4];
     ASMCpuIdExSlow(uLeaf, 0, 0, 0, &auPrev[0], &auPrev[1], &auPrev[2], &auPrev[3]);
 
@@ -777,7 +778,6 @@ static bool cpumR3IsEcxRelevantForCpuIdLeaf(uint32_t uLeaf, uint32_t *pcSubLeave
     uint32_t uSubLeaf = 1;
     for (;;)
     {
-        uint32_t auCur[4];
         ASMCpuIdExSlow(uLeaf, 0, uSubLeaf, 0, &auCur[0], &auCur[1], &auCur[2], &auCur[3]);
         if (memcmp(auCur, auPrev, sizeof(auCur)))
             break;
@@ -792,33 +792,76 @@ static bool cpumR3IsEcxRelevantForCpuIdLeaf(uint32_t uLeaf, uint32_t *pcSubLeave
     }
 
     /* Count sub-leaves. */
+    uint32_t cRepeats = 0;
     uSubLeaf = 0;
     for (;;)
     {
-        uint32_t auCur[4];
         ASMCpuIdExSlow(uLeaf, 0, uSubLeaf, 0, &auCur[0], &auCur[1], &auCur[2], &auCur[3]);
 
-        /* Exactly when this terminates isn't quite consistent.  When working
-           0xb, we should probably only check if ebx == 0... */
+        /* Figuring out when to stop isn't entirely straight forward as we need
+           to cover undocumented behavior up to a point and implementation shortcuts. */
+
+        /* 1. Look for zero values. */
         if (   auCur[0] == 0
             && auCur[1] == 0
             && (auCur[2] == 0 || auCur[2] == uSubLeaf)
-            && (auCur[3] == 0 || uLeaf == 0xb) )
+            && (auCur[3] == 0 || uLeaf == 0xb /* edx is fixed */) )
+            break;
+
+        /* 2. Look for more than 4 repeating value sets. */
+        if (   auCur[0] == auPrev[0]
+            && auCur[1] == auPrev[1]
+            && (    auCur[2] == auPrev[2]
+                || (   auCur[2]  == uSubLeaf
+                    && auPrev[2] == uSubLeaf - 1) )
+            && auCur[3] == auPrev[3])
         {
-            if (auCur[2] == uSubLeaf)
-                *pfFinalEcxUnchanged = true;
-            *pcSubLeaves = uSubLeaf + 1;
-            return true;
+            cRepeats++;
+            if (cRepeats > 4)
+                break;
         }
+        else
+            cRepeats = 0;
 
-        /* Advance / give up. */
-        uSubLeaf++;
+        /* 3. Leaf 0xb level type 0 check. */
+        if (   uLeaf == 0xb
+            && (auCur[3]  & 0xff00) == 0
+            && (auPrev[3] & 0xff00) == 0)
+            break;
+
+        /* 99. Give up. */
         if (uSubLeaf >= 128)
         {
+#ifndef IN_VBOX_CPU_REPORT
+            /* Ok, limit it according to the documentation if possible just to
+               avoid annoying users with these detection issues. */
+            uint32_t cDocLimit = UINT32_MAX;
+            if (uLeaf == 0x4)
+                cDocLimit = 4;
+            else if (uLeaf == 0x7)
+                cDocLimit = 1;
+            else if (uLeaf == 0xf)
+                cDocLimit = 2;
+            if (cDocLimit != UINT32_MAX)
+            {
+                *pfFinalEcxUnchanged = auCur[2] == uSubLeaf;
+                *pcSubLeaves = cDocLimit + 3;
+                return true;
+            }
+#endif
             *pcSubLeaves = UINT32_MAX;
             return true;
         }
+
+        /* Advance. */
+        uSubLeaf++;
+        memcpy(auPrev, auCur, sizeof(auCur));
     }
+
+    /* Standard exit. */
+    *pfFinalEcxUnchanged = auCur[2] == uSubLeaf;
+    *pcSubLeaves = uSubLeaf + 1 - cRepeats;
+    return true;
 }
 
 
diff --git a/src/VBox/VMM/VMMR3/CPUMR3Db.cpp b/src/VBox/VMM/VMMR3/CPUMR3Db.cpp
index f6e3942..26cfb85 100644
--- a/src/VBox/VMM/VMMR3/CPUMR3Db.cpp
+++ b/src/VBox/VMM/VMMR3/CPUMR3Db.cpp
@@ -48,6 +48,8 @@ typedef struct CPUMDBENTRY
     uint8_t         uStepping;
     /** The microarchitecture. */
     CPUMMICROARCH   enmMicroarch;
+    /** Scalable bus frequency used for reporting other frequencies. */
+    uint64_t        uScalableBusFreq;
     /** Flags (TBD). */
     uint32_t        fFlags;
     /** The maximum physical address with of the CPU.  This should correspond to
@@ -174,6 +176,7 @@ typedef struct CPUMDBENTRY
 
 #include "cpus/Intel_Core_i7_3960X.h"
 #include "cpus/Intel_Core_i5_3570.h"
+#include "cpus/Intel_Core_i7_2635QM.h"
 #include "cpus/Intel_Xeon_X5482_3_20GHz.h"
 #include "cpus/Intel_Pentium_M_processor_2_00GHz.h"
 #include "cpus/Intel_Pentium_4_3_00GHz.h"
@@ -181,6 +184,7 @@ typedef struct CPUMDBENTRY
 #include "cpus/AMD_FX_8150_Eight_Core.h"
 #include "cpus/AMD_Phenom_II_X6_1100T.h"
 #include "cpus/Quad_Core_AMD_Opteron_2384.h"
+#include "cpus/AMD_Athlon_64_X2_Dual_Core_4200.h"
 #include "cpus/AMD_Athlon_64_3200.h"
 
 #include "cpus/VIA_QuadCore_L4700_1_2_GHz.h"
@@ -207,6 +211,9 @@ static CPUMDBENTRY const * const g_apCpumDbEntries[] =
 #ifdef VBOX_CPUDB_Intel_Core_i7_3960X
     &g_Entry_Intel_Core_i7_3960X,
 #endif
+#ifdef VBOX_CPUDB_Intel_Core_i7_2635QM
+    &g_Entry_Intel_Core_i7_2635QM,
+#endif
 #ifdef Intel_Pentium_M_processor_2_00GHz
     &g_Entry_Intel_Pentium_M_processor_2_00GHz,
 #endif
@@ -226,6 +233,9 @@ static CPUMDBENTRY const * const g_apCpumDbEntries[] =
 #ifdef VBOX_CPUDB_Quad_Core_AMD_Opteron_2384
     &g_Entry_Quad_Core_AMD_Opteron_2384,
 #endif
+#ifdef VBOX_CPUDB_AMD_Athlon_64_X2_Dual_Core_4200
+    &g_Entry_AMD_Athlon_64_X2_Dual_Core_4200,
+#endif
 #ifdef VBOX_CPUDB_AMD_Athlon_64_3200
     &g_Entry_AMD_Athlon_64_3200,
 #endif
@@ -667,6 +677,7 @@ int cpumR3DbGetCpuInfo(const char *pszName, PCPUMINFO pInfo)
     pInfo->fMsrMask             = pEntry->fMsrMask;
     pInfo->iFirstExtCpuIdLeaf   = 0; /* Set by caller. */
     pInfo->uPadding             = 0;
+    pInfo->uScalableBusFreq     = pEntry->uScalableBusFreq;
     pInfo->paCpuIdLeavesR0      = NIL_RTR0PTR;
     pInfo->paMsrRangesR0        = NIL_RTR0PTR;
     pInfo->paCpuIdLeavesRC      = NIL_RTRCPTR;
diff --git a/src/VBox/VMM/VMMR3/CSAM.cpp b/src/VBox/VMM/VMMR3/CSAM.cpp
index 5a36e4b..86cce49 100644
--- a/src/VBox/VMM/VMMR3/CSAM.cpp
+++ b/src/VBox/VMM/VMMR3/CSAM.cpp
@@ -71,7 +71,6 @@
 *******************************************************************************/
 static DECLCALLBACK(int) csamr3Save(PVM pVM, PSSMHANDLE pSSM);
 static DECLCALLBACK(int) csamr3Load(PVM pVM, PSSMHANDLE pSSM, uint32_t uVersion, uint32_t uPass);
-static DECLCALLBACK(int) csamR3LoadDummy(PVM pVM, PSSMHANDLE pSSM, uint32_t uVersion, uint32_t uPass);
 static DECLCALLBACK(int) CSAMCodePageWriteHandler(PVM pVM, RTGCPTR GCPtr, void *pvPtr, void *pvBuf, size_t cbBuf, PGMACCESSTYPE enmAccessType, void *pvUser);
 static DECLCALLBACK(int) CSAMCodePageInvalidate(PVM pVM, RTGCPTR GCPtr);
 
@@ -231,10 +230,7 @@ VMMR3_INT_DECL(int) CSAMR3Init(PVM pVM)
     if (HMIsEnabled(pVM))
     {
         pVM->fCSAMEnabled = false;
-        return SSMR3RegisterInternal(pVM, "CSAM", 0, CSAM_SSM_VERSION, 0,
-                                     NULL, NULL, NULL,
-                                     NULL, NULL, NULL,
-                                     NULL, csamR3LoadDummy, NULL);
+        return SSMR3RegisterStub(pVM, "CSAM", 0);
     }
 
     /*
@@ -569,15 +565,6 @@ static DECLCALLBACK(int) csamr3Save(PVM pVM, PSSMHANDLE pSSM)
 
 
 /**
- * @callback_method_impl{FNSSMINTLOADEXEC, Dummy load function for HM mode.}
- */
-DECLCALLBACK(int) csamR3LoadDummy(PVM pVM, PSSMHANDLE pSSM, uint32_t uVersion, uint32_t uPass)
-{
-    return SSMR3SkipToEndOfUnit(pSSM);
-}
-
-
-/**
  * Execute state load operation.
  *
  * @returns VBox status code.
diff --git a/src/VBox/VMM/VMMR3/PATM.cpp b/src/VBox/VMM/VMMR3/PATM.cpp
index 47c52ed..6477371 100644
--- a/src/VBox/VMM/VMMR3/PATM.cpp
+++ b/src/VBox/VMM/VMMR3/PATM.cpp
@@ -145,10 +145,7 @@ VMMR3_INT_DECL(int) PATMR3Init(PVM pVM)
     if (HMIsEnabled(pVM))
     {
         pVM->fPATMEnabled = false;
-        return SSMR3RegisterInternal(pVM, "PATM", 0, PATM_SSM_VERSION, 0,
-                                     NULL, NULL, NULL,
-                                     NULL, NULL, NULL,
-                                     NULL, patmR3LoadDummy, NULL);
+        return SSMR3RegisterStub(pVM, "PATM", 0);
     }
 
     /*
diff --git a/src/VBox/VMM/VMMR3/PATMSSM.cpp b/src/VBox/VMM/VMMR3/PATMSSM.cpp
index 01f3d6a..ea44713 100644
--- a/src/VBox/VMM/VMMR3/PATMSSM.cpp
+++ b/src/VBox/VMM/VMMR3/PATMSSM.cpp
@@ -803,15 +803,6 @@ DECLCALLBACK(int) patmR3Save(PVM pVM, PSSMHANDLE pSSM)
 
 
 /**
- * @callback_method_impl{FNSSMINTLOADEXEC, Dummy load function for HM mode.}
- */
-DECLCALLBACK(int) patmR3LoadDummy(PVM pVM, PSSMHANDLE pSSM, uint32_t uVersion, uint32_t uPass)
-{
-    return SSMR3SkipToEndOfUnit(pSSM);
-}
-
-
-/**
  * Execute state load operation.
  *
  * @returns VBox status code.
diff --git a/src/VBox/VMM/VMMR3/SSM.cpp b/src/VBox/VMM/VMMR3/SSM.cpp
index b351cb0..5d77327 100644
--- a/src/VBox/VMM/VMMR3/SSM.cpp
+++ b/src/VBox/VMM/VMMR3/SSM.cpp
@@ -1419,6 +1419,37 @@ VMMR3DECL(int) SSMR3RegisterExternal(PUVM pUVM, const char *pszName, uint32_t uI
 
 
 /**
+ * @callback_method_impl{FNSSMINTLOADEXEC,
+ * Stub that skips the whole unit (see SSMR3RegisterStub).}
+ */
+static DECLCALLBACK(int) ssmR3LoadExecStub(PVM pVM, PSSMHANDLE pSSM, uint32_t uVersion, uint32_t uPass)
+{
+    NOREF(pVM); NOREF(uVersion); NOREF(uPass);
+    return SSMR3SkipToEndOfUnit(pSSM);
+}
+
+
+/**
+ * Registers a stub state loader for working around legacy.
+ *
+ * This is used to deal with irelevant PATM and CSAM saved state units in HM
+ * mode and when built without raw-mode.
+ *
+ * @returns VBox status code.
+ * @param   pVM                 The VM handle.
+ * @param   pszName             Data unit name.
+ * @param   uInstance           Instance number.
+ */
+VMMR3DECL(int) SSMR3RegisterStub(PVM pVM, const char *pszName, uint32_t uInstance)
+{
+    return SSMR3RegisterInternal(pVM, pszName, uInstance, UINT32_MAX, 0,
+                                 NULL, NULL, NULL,
+                                 NULL, NULL, NULL,
+                                 NULL, ssmR3LoadExecStub, NULL);
+}
+
+
+/**
  * Deregister one or more PDM Device data units.
  *
  * @returns VBox status.
diff --git a/src/VBox/VMM/VMMR3/VM.cpp b/src/VBox/VMM/VMMR3/VM.cpp
index a13224b..36effa6 100644
--- a/src/VBox/VMM/VMMR3/VM.cpp
+++ b/src/VBox/VMM/VMMR3/VM.cpp
@@ -1165,6 +1165,15 @@ static int vmR3InitDoCompleted(PVM pVM, VMINITCOMPLETED enmWhat)
         rc = HMR3InitCompleted(pVM, enmWhat);
     if (RT_SUCCESS(rc))
         rc = PGMR3InitCompleted(pVM, enmWhat);
+#ifndef VBOX_WITH_RAW_MODE
+    if (enmWhat == VMINITCOMPLETED_RING3)
+    {
+        if (RT_SUCCESS(rc))
+            rc = SSMR3RegisterStub(pVM, "CSAM", 0);
+        if (RT_SUCCESS(rc))
+            rc = SSMR3RegisterStub(pVM, "PATM", 0);
+    }
+#endif
     return rc;
 }
 
diff --git a/src/VBox/VMM/VMMR3/cpus/AMD_Athlon_64_3200.h b/src/VBox/VMM/VMMR3/cpus/AMD_Athlon_64_3200.h
index ea7072b..774e2ae 100644
--- a/src/VBox/VMM/VMMR3/cpus/AMD_Athlon_64_3200.h
+++ b/src/VBox/VMM/VMMR3/cpus/AMD_Athlon_64_3200.h
@@ -204,6 +204,7 @@ static CPUMDBENTRY const g_Entry_AMD_Athlon_64_3200 =
     /*.uModel           = */ 4,
     /*.uStepping        = */ 8,
     /*.enmMicroarch     = */ kCpumMicroarch_AMD_K8_130nm,
+    /*.uScalableBusFreq = */ CPUM_SBUSFREQ_UNKNOWN,
     /*.fFlags           = */ 0,
     /*.cMaxPhysAddrWidth= */ 40,
     /*.paCpuIdLeaves    = */ NULL_ALONE(g_aCpuIdLeaves_AMD_Athlon_64_3200),
diff --git a/src/VBox/VMM/VMMR3/cpus/AMD_Athlon_64_3200.h b/src/VBox/VMM/VMMR3/cpus/AMD_Athlon_64_X2_Dual_Core_4200.h
similarity index 58%
copy from src/VBox/VMM/VMMR3/cpus/AMD_Athlon_64_3200.h
copy to src/VBox/VMM/VMMR3/cpus/AMD_Athlon_64_X2_Dual_Core_4200.h
index ea7072b..0c5557b 100644
--- a/src/VBox/VMM/VMMR3/cpus/AMD_Athlon_64_3200.h
+++ b/src/VBox/VMM/VMMR3/cpus/AMD_Athlon_64_X2_Dual_Core_4200.h
@@ -1,7 +1,11 @@
-/* $Id: AMD_Athlon_64_3200.h $ */
+/* $Id: AMD_Athlon_64_X2_Dual_Core_4200.h $ */
 /** @file
- * CPU database entry "AMD Athlon 64 3200+".
- * Generated at 2013-07-12T02:09:05Z by VBoxCpuReport v4.3.53r91376 on win.x86.
+ * CPU database entry "AMD Athlon 64 X2 Dual Core 4200+".
+ * Generated at 2014-02-28T15:19:16Z by VBoxCpuReport v4.3.53r92578 on linux.amd64                                                        .
+ *                                                                                                                                        .
+ * @remarks Possible that we're missing a few special MSRs due to no                                                                      .
+ *          magic register value capabilities in the linux hosted                                                                         .
+ *          MSR probing code.
  */
 
 /*
@@ -16,29 +20,29 @@
  * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
  */
 
-#ifndef VBOX_CPUDB_AMD_Athlon_64_3200
-#define VBOX_CPUDB_AMD_Athlon_64_3200
+#ifndef VBOX_CPUDB_AMD_Athlon_64_X2_Dual_Core_4200
+#define VBOX_CPUDB_AMD_Athlon_64_X2_Dual_Core_4200
 
 
 #ifndef CPUM_DB_STANDALONE
 /**
- * CPUID leaves for AMD Athlon(tm) 64 Processor 3200+.
+ * CPUID leaves for AMD Athlon(tm) 64 X2 Dual Core Processor 4200+.
  */
-static CPUMCPUIDLEAF const g_aCpuIdLeaves_AMD_Athlon_64_3200[] = 
+static CPUMCPUIDLEAF const g_aCpuIdLeaves_AMD_Athlon_64_X2_Dual_Core_4200[] =
 {
     { 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x68747541, 0x444d4163, 0x69746e65, 0 },
-    { 0x00000001, 0x00000000, 0x00000000, 0x00000f48, 0x00000800, 0x00000000, 0x078bfbff, 0 },
+    { 0x00000001, 0x00000000, 0x00000000, 0x00040fb2, 0x01020800, 0x00002001, 0x178bfbff, 0 },
     { 0x80000000, 0x00000000, 0x00000000, 0x80000018, 0x68747541, 0x444d4163, 0x69746e65, 0 },
-    { 0x80000001, 0x00000000, 0x00000000, 0x00000f48, 0x0000010a, 0x00000000, 0xe1d3fbff, 0 },
+    { 0x80000001, 0x00000000, 0x00000000, 0x00040fb2, 0x000008d1, 0x0000001f, 0xebd3fbff, 0 },
     { 0x80000002, 0x00000000, 0x00000000, 0x20444d41, 0x6c687441, 0x74286e6f, 0x3620296d, 0 },
-    { 0x80000003, 0x00000000, 0x00000000, 0x72502034, 0x7365636f, 0x20726f73, 0x30303233, 0 },
-    { 0x80000004, 0x00000000, 0x00000000, 0x0000002b, 0x00000000, 0x00000000, 0x00000000, 0 },
+    { 0x80000003, 0x00000000, 0x00000000, 0x32582034, 0x61754420, 0x6f43206c, 0x50206572, 0 },
+    { 0x80000004, 0x00000000, 0x00000000, 0x65636f72, 0x726f7373, 0x30323420, 0x00002b30, 0 },
     { 0x80000005, 0x00000000, 0x00000000, 0xff08ff08, 0xff20ff20, 0x40020140, 0x40020140, 0 },
-    { 0x80000006, 0x00000000, 0x00000000, 0x00000000, 0x42004200, 0x04008140, 0x00000000, 0 },
-    { 0x80000007, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x0000000f, 0 },
-    { 0x80000008, 0x00000000, 0x00000000, 0x00003028, 0x00000000, 0x00000000, 0x00000000, 0 },
+    { 0x80000006, 0x00000000, 0x00000000, 0x00000000, 0x42004200, 0x02008140, 0x00000000, 0 },
+    { 0x80000007, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x0000003f, 0 },
+    { 0x80000008, 0x00000000, 0x00000000, 0x00003028, 0x00000000, 0x00000001, 0x00000000, 0 },
     { 0x80000009, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0 },
-    { 0x8000000a, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0 },
+    { 0x8000000a, 0x00000000, 0x00000000, 0x00000001, 0x00000040, 0x00000000, 0x00000000, 0 },
     { 0x8000000b, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0 },
     { 0x8000000c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0 },
     { 0x8000000d, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0 },
@@ -53,41 +57,40 @@ static CPUMCPUIDLEAF const g_aCpuIdLeaves_AMD_Athlon_64_3200[] =
     { 0x80000016, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0 },
     { 0x80000017, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0 },
     { 0x80000018, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0 },
-    { 0x8fffffff, 0x00000000, 0x00000000, 0x53275449, 0x4d414820, 0x2052454d, 0x454d4954, 0 },
 };
 #endif /* !CPUM_DB_STANDALONE */
 
 
 #ifndef CPUM_DB_STANDALONE
 /**
- * MSR ranges for AMD Athlon(tm) 64 Processor 3200+.
+ * MSR ranges for AMD Athlon(tm) 64 X2 Dual Core Processor 4200+.
  */
-static CPUMMSRRANGE const g_aMsrRanges_AMD_Athlon_64_3200[] = 
+static CPUMMSRRANGE const g_aMsrRanges_AMD_Athlon_64_X2_Dual_Core_4200[] =
 {
     MAL(0x00000000, "IA32_P5_MC_ADDR", 0x00000402),
     MAL(0x00000001, "IA32_P5_MC_TYPE", 0x00000401),
-    MFN(0x00000010, "IA32_TIME_STAMP_COUNTER", Ia32TimestampCounter, Ia32TimestampCounter), /* value=0x28`4505cb65 */
-    MFX(0x0000001b, "IA32_APIC_BASE", Ia32ApicBase, Ia32ApicBase, UINT32_C(0xfee00900), 0, UINT64_C(0xffffff00000006ff)),
+    MFN(0x00000010, "IA32_TIME_STAMP_COUNTER", Ia32TimestampCounter, Ia32TimestampCounter), /* value=0x7e`171166b8 */
+    MFX(0x0000001b, "IA32_APIC_BASE", Ia32ApicBase, Ia32ApicBase, UINT32_C(0xfee00800), 0, UINT64_C(0xffffff00000006ff)),
     MFX(0x0000002a, "EBL_CR_POWERON", IntelEblCrPowerOn, ReadOnly, 0, 0, 0), /* value=0x0 */
-    MFO(0x0000008b, "AMD_K8_PATCH_LEVEL", AmdK8PatchLevel), /* value=0x39 */
+    MFO(0x0000008b, "AMD_K8_PATCH_LEVEL", AmdK8PatchLevel), /* value=0x0 */
     MFX(0x000000fe, "IA32_MTRRCAP", Ia32MtrrCap, ReadOnly, 0x508, 0, 0), /* value=0x508 */
-    MFX(0x00000174, "IA32_SYSENTER_CS", Ia32SysEnterCs, Ia32SysEnterCs, 0, ~(uint64_t)UINT32_MAX, 0), /* value=0x8 */
-    MFX(0x00000175, "IA32_SYSENTER_ESP", Ia32SysEnterEsp, Ia32SysEnterEsp, 0, ~(uint64_t)UINT32_MAX, 0), /* value=0x8059e000 */
-    MFX(0x00000176, "IA32_SYSENTER_EIP", Ia32SysEnterEip, Ia32SysEnterEip, 0, ~(uint64_t)UINT32_MAX, 0), /* value=0x81872950 */
+    MFX(0x00000174, "IA32_SYSENTER_CS", Ia32SysEnterCs, Ia32SysEnterCs, 0, ~(uint64_t)UINT32_MAX, 0), /* value=0x10 */
+    MFX(0x00000175, "IA32_SYSENTER_ESP", Ia32SysEnterEsp, Ia32SysEnterEsp, 0, ~(uint64_t)UINT32_MAX, 0), /* value=0x0 */
+    MFX(0x00000176, "IA32_SYSENTER_EIP", Ia32SysEnterEip, Ia32SysEnterEip, 0, ~(uint64_t)UINT32_MAX, 0), /* value=0x8103ca80 */
     MFX(0x00000179, "IA32_MCG_CAP", Ia32McgCap, ReadOnly, 0x105, 0, 0), /* value=0x105 */
     MFX(0x0000017a, "IA32_MCG_STATUS", Ia32McgStatus, Ia32McgStatus, 0, UINT64_C(0xfffffffffffffff8), 0), /* value=0x0 */
     MFX(0x0000017b, "IA32_MCG_CTL", Ia32McgCtl, Ia32McgCtl, 0, UINT64_C(0xffffffffffffffe0), 0), /* value=0x1f */
     MFX(0x000001d9, "IA32_DEBUGCTL", Ia32DebugCtl, Ia32DebugCtl, 0, UINT64_C(0xffffffffffffff80), 0x40), /* value=0x0 */
-    MFO(0x000001db, "P6_LAST_BRANCH_FROM_IP", P6LastBranchFromIp), /* value=0xffffffed`bf1be178 */
-    MFO(0x000001dc, "P6_LAST_BRANCH_TO_IP", P6LastBranchToIp), /* value=0xffff7f49`bf1bedec */
+    MFO(0x000001db, "P6_LAST_BRANCH_FROM_IP", P6LastBranchFromIp), /* value=0xffffffff`a0425995 */
+    MFO(0x000001dc, "P6_LAST_BRANCH_TO_IP", P6LastBranchToIp), /* value=0xffffffff`8103124a */
     MFO(0x000001dd, "P6_LAST_INT_FROM_IP", P6LastIntFromIp), /* value=0x0 */
     MFO(0x000001de, "P6_LAST_INT_TO_IP", P6LastIntToIp), /* value=0x0 */
     MFX(0x00000200, "IA32_MTRR_PHYS_BASE0", Ia32MtrrPhysBaseN, Ia32MtrrPhysBaseN, 0x0, 0, UINT64_C(0xffffff0000000ff8)), /* value=0x6 */
-    MFX(0x00000201, "IA32_MTRR_PHYS_MASK0", Ia32MtrrPhysMaskN, Ia32MtrrPhysMaskN, 0x0, 0, UINT64_C(0xffffff00000007ff)), /* value=0xff`c0000800 */
-    MFX(0x00000202, "IA32_MTRR_PHYS_BASE1", Ia32MtrrPhysBaseN, Ia32MtrrPhysBaseN, 0x1, 0, UINT64_C(0xffffff0000000ff8)), /* value=0xf8000001 */
-    MFX(0x00000203, "IA32_MTRR_PHYS_MASK1", Ia32MtrrPhysMaskN, Ia32MtrrPhysMaskN, 0x1, 0, UINT64_C(0xffffff00000007ff)), /* value=0xff`fc000800 */
-    MFX(0x00000204, "IA32_MTRR_PHYS_BASE2", Ia32MtrrPhysBaseN, Ia32MtrrPhysBaseN, 0x2, 0, UINT64_C(0xffffff0000000ff8)), /* value=0x0 */
-    MFX(0x00000205, "IA32_MTRR_PHYS_MASK2", Ia32MtrrPhysMaskN, Ia32MtrrPhysMaskN, 0x2, 0, UINT64_C(0xffffff00000007ff)), /* value=0x0 */
+    MFX(0x00000201, "IA32_MTRR_PHYS_MASK0", Ia32MtrrPhysMaskN, Ia32MtrrPhysMaskN, 0x0, 0, UINT64_C(0xffffff00000007ff)), /* value=0xff`80000800 */
+    MFX(0x00000202, "IA32_MTRR_PHYS_BASE1", Ia32MtrrPhysBaseN, Ia32MtrrPhysBaseN, 0x1, 0, UINT64_C(0xffffff0000000ff8)), /* value=0x80000006 */
+    MFX(0x00000203, "IA32_MTRR_PHYS_MASK1", Ia32MtrrPhysMaskN, Ia32MtrrPhysMaskN, 0x1, 0, UINT64_C(0xffffff00000007ff)), /* value=0xff`c0000800 */
+    MFX(0x00000204, "IA32_MTRR_PHYS_BASE2", Ia32MtrrPhysBaseN, Ia32MtrrPhysBaseN, 0x2, 0, UINT64_C(0xffffff0000000ff8)), /* value=0xf8000001 */
+    MFX(0x00000205, "IA32_MTRR_PHYS_MASK2", Ia32MtrrPhysMaskN, Ia32MtrrPhysMaskN, 0x2, 0, UINT64_C(0xffffff00000007ff)), /* value=0xff`ff000800 */
     MFX(0x00000206, "IA32_MTRR_PHYS_BASE3", Ia32MtrrPhysBaseN, Ia32MtrrPhysBaseN, 0x3, 0, UINT64_C(0xffffff0000000ff8)), /* value=0x0 */
     MFX(0x00000207, "IA32_MTRR_PHYS_MASK3", Ia32MtrrPhysMaskN, Ia32MtrrPhysMaskN, 0x3, 0, UINT64_C(0xffffff00000007ff)), /* value=0x0 */
     MFX(0x00000208, "IA32_MTRR_PHYS_BASE4", Ia32MtrrPhysBaseN, Ia32MtrrPhysBaseN, 0x4, 0, UINT64_C(0xffffff0000000ff8)), /* value=0x0 */
@@ -112,108 +115,74 @@ static CPUMMSRRANGE const g_aMsrRanges_AMD_Athlon_64_3200[] =
     MFS(0x00000277, "IA32_PAT", Ia32Pat, Ia32Pat, Guest.msrPAT),
     MFZ(0x000002ff, "IA32_MTRR_DEF_TYPE", Ia32MtrrDefType, Ia32MtrrDefType, GuestMsrs.msr.MtrrDefType, 0, UINT64_C(0xfffffffffffff3f8)),
     RFN(0x00000400, 0x00000413, "IA32_MCi_CTL_STATUS_ADDR_MISC", Ia32McCtlStatusAddrMiscN, Ia32McCtlStatusAddrMiscN),
-    MFX(0xc0000080, "AMD64_EFER", Amd64Efer, Amd64Efer, 0x800, 0xfe, UINT64_C(0xfffffffffffff200)),
-    MFN(0xc0000081, "AMD64_STAR", Amd64SyscallTarget, Amd64SyscallTarget), /* value=0x0 */
-    MFN(0xc0000082, "AMD64_STAR64", Amd64LongSyscallTarget, Amd64LongSyscallTarget), /* value=0x0 */
-    MFN(0xc0000083, "AMD64_STARCOMPAT", Amd64CompSyscallTarget, Amd64CompSyscallTarget), /* value=0x0 */
-    MFX(0xc0000084, "AMD64_SYSCALL_FLAG_MASK", Amd64SyscallFlagMask, Amd64SyscallFlagMask, 0, ~(uint64_t)UINT32_MAX, 0), /* value=0x0 */
-    MFN(0xc0000100, "AMD64_FS_BASE", Amd64FsBase, Amd64FsBase), /* value=0x81913800 */
-    MFN(0xc0000101, "AMD64_GS_BASE", Amd64GsBase, Amd64GsBase), /* value=0x0 */
+    MFX(0xc0000080, "AMD64_EFER", Amd64Efer, Amd64Efer, 0xd01, 0xfe, UINT64_C(0xffffffffffff8200)),
+    MFN(0xc0000081, "AMD64_STAR", Amd64SyscallTarget, Amd64SyscallTarget), /* value=0x230010`00000000 */
+    MFN(0xc0000082, "AMD64_STAR64", Amd64LongSyscallTarget, Amd64LongSyscallTarget), /* value=0xffffffff`81011d20 */
+    MFN(0xc0000083, "AMD64_STARCOMPAT", Amd64CompSyscallTarget, Amd64CompSyscallTarget), /* value=0xffffffff`8103ccb0 */
+    MFX(0xc0000084, "AMD64_SYSCALL_FLAG_MASK", Amd64SyscallFlagMask, Amd64SyscallFlagMask, 0, ~(uint64_t)UINT32_MAX, 0), /* value=0x3700 */
+    MFN(0xc0000100, "AMD64_FS_BASE", Amd64FsBase, Amd64FsBase), /* value=0x1da4880 */
+    MFN(0xc0000101, "AMD64_GS_BASE", Amd64GsBase, Amd64GsBase), /* value=0xffff8800`28300000 */
     MFN(0xc0000102, "AMD64_KERNEL_GS_BASE", Amd64KernelGsBase, Amd64KernelGsBase), /* value=0x0 */
+    MFX(0xc0000103, "AMD64_TSC_AUX", Amd64TscAux, Amd64TscAux, 0, ~(uint64_t)UINT32_MAX, 0), /* value=0x1 */
     RSN(0xc0010000, 0xc0010003, "AMD_K8_PERF_CTL_n", AmdK8PerfCtlN, AmdK8PerfCtlN, 0x0, UINT64_C(0xffffffff00200000), 0),
     RSN(0xc0010004, 0xc0010007, "AMD_K8_PERF_CTR_n", AmdK8PerfCtrN, AmdK8PerfCtrN, 0x0, UINT64_C(0xffff000000000000), 0),
-    MFX(0xc0010010, "AMD_K8_SYS_CFG", AmdK8SysCfg, AmdK8SysCfg, 0x160601, UINT64_C(0xffffffffffc0f800), 0), /* value=0x160601 */
-    MFX(0xc0010015, "AMD_K8_HW_CFG", AmdK8HwCr, AmdK8HwCr, 0xc000000, UINT64_C(0xffffffff3ff00000), 0), /* value=0xc000000 */
-    MFW(0xc0010016, "AMD_K8_IORR_BASE_0", AmdK8IorrBaseN, AmdK8IorrBaseN, UINT64_C(0xffffff0000000fe7)), /* value=0x0 */
+    MFX(0xc0010010, "AMD_K8_SYS_CFG", AmdK8SysCfg, AmdK8SysCfg, 0x760601, UINT64_C(0xffffffffff80f800), 0), /* value=0x760601 */
+    MFX(0xc0010015, "AMD_K8_HW_CFG", AmdK8HwCr, AmdK8HwCr, 0x2000060, UINT64_C(0xffffffff3ff00020), 0), /* value=0x2000060 */
+    MFW(0xc0010016, "AMD_K8_IORR_BASE_0", AmdK8IorrBaseN, AmdK8IorrBaseN, UINT64_C(0xffffff0000000fe7)), /* value=0xa30000 */
     MFW(0xc0010017, "AMD_K8_IORR_MASK_0", AmdK8IorrMaskN, AmdK8IorrMaskN, UINT64_C(0xffffff00000007ff)), /* value=0x0 */
-    MFX(0xc0010018, "AMD_K8_IORR_BASE_1", AmdK8IorrBaseN, AmdK8IorrBaseN, 0x1, UINT64_C(0xffffff0000000fe7), 0), /* value=0xf8000018 */
-    MFX(0xc0010019, "AMD_K8_IORR_MASK_1", AmdK8IorrMaskN, AmdK8IorrMaskN, 0x1, UINT64_C(0xffffff00000007ff), 0), /* value=0xff`fc000800 */
-    MFW(0xc001001a, "AMD_K8_TOP_MEM", AmdK8TopOfMemN, AmdK8TopOfMemN, UINT64_C(0xffffff00007fffff)), /* value=0x40000000 */
-    MFX(0xc001001d, "AMD_K8_TOP_MEM2", AmdK8TopOfMemN, AmdK8TopOfMemN, 0x1, UINT64_C(0xffffff00007fffff), 0), /* value=0x0 */
-    MVI(0xc001001e, "AMD_K8_MANID", 0x20),
-    MFX(0xc001001f, "AMD_K8_NB_CFG1", AmdK8NbCfg1, AmdK8NbCfg1, 0, UINT64_C(0xffffff0000000000), 0), /* value=0x11`00000008 */
+    MFX(0xc0010018, "AMD_K8_IORR_BASE_1", AmdK8IorrBaseN, AmdK8IorrBaseN, 0x1, UINT64_C(0xffffff0000000fe7), 0), /* value=0x0 */
+    MFX(0xc0010019, "AMD_K8_IORR_MASK_1", AmdK8IorrMaskN, AmdK8IorrMaskN, 0x1, UINT64_C(0xffffff00000007ff), 0), /* value=0x0 */
+    MFW(0xc001001a, "AMD_K8_TOP_MEM", AmdK8TopOfMemN, AmdK8TopOfMemN, UINT64_C(0xffffff00007fffff)), /* value=0xc0000000 */
+    MFX(0xc001001d, "AMD_K8_TOP_MEM2", AmdK8TopOfMemN, AmdK8TopOfMemN, 0x1, UINT64_C(0xffffff00007fffff), 0), /* value=0x1`40000000 */
+    MVI(0xc001001e, "AMD_K8_MANID", 0x52),
+    MFX(0xc001001f, "AMD_K8_NB_CFG1", AmdK8NbCfg1, AmdK8NbCfg1, 0, UINT64_C(0x3fbf000000000000), 0), /* value=0x400001`00100008 */
     MFN(0xc0010020, "AMD_K8_PATCH_LOADER", WriteOnly, AmdK8PatchLoader),
-    MVX(0xc0010021, "AMD_K8_UNK_c001_0021", 0, UINT64_C(0xfffffffe00000000), 0),
-    MFX(0xc0010022, "AMD_K8_MC_XCPT_REDIR", AmdK8McXcptRedir, AmdK8McXcptRedir, 0, UINT64_C(0xfffffffeffffffff), 0), /* value=0x0 */
+    MFN(0xc0010021, "AMD_K8_UNK_c001_0021", WriteOnly, IgnoreWrite),
     RFN(0xc0010030, 0xc0010035, "AMD_K8_CPU_NAME_n", AmdK8CpuNameN, AmdK8CpuNameN),
-    MFX(0xc001003e, "AMD_K8_HTC", AmdK8HwThermalCtrl, AmdK8HwThermalCtrl, 0, UINT64_MAX, 0), /* value=0x0 */
-    MFI(0xc001003f, "AMD_K8_STC", AmdK8SwThermalCtrl), /* value=0x0 */
-    MFX(0xc0010041, "AMD_K8_FIDVID_CTL", AmdK8FidVidControl, AmdK8FidVidControl, UINT64_C(0x4e200000000c), 0x33, UINT64_C(0xfff00000fffee0c0)), /* value=0x4e20`0000000c */
-    MFX(0xc0010042, "AMD_K8_FIDVID_STATUS", AmdK8FidVidStatus, ReadOnly, UINT64_C(0x200000c0c0c), 0, 0), /* value=0x200`000c0c0c */
-    MVO(0xc0010043, "AMD_K8_THERMTRIP_STATUS", 0x521020),
+    MFX(0xc001003e, "AMD_K8_HTC", AmdK8HwThermalCtrl, AmdK8HwThermalCtrl, 0, UINT64_C(0xfffffffff0e088fc), 0), /* value=0x0 */
+    MFX(0xc001003f, "AMD_K8_STC", AmdK8SwThermalCtrl, AmdK8SwThermalCtrl, 0, UINT64_C(0xfffffffff0e088e0), 0), /* value=0x0 */
+    MFX(0xc0010041, "AMD_K8_FIDVID_CTL", AmdK8FidVidControl, AmdK8FidVidControl, UINT64_C(0x100001202), 0xc31, UINT64_C(0xfff00000fffec0c0)), /* value=0x1`00001202 */
+    MFX(0xc0010042, "AMD_K8_FIDVID_STATUS", AmdK8FidVidStatus, ReadOnly, UINT64_C(0x310c12120c0e0202), 0, 0), /* value=0x310c1212`0c0e0202 */
+    MVO(0xc0010043, "AMD_K8_THERMTRIP_STATUS", 0x4e1a24),
     RFN(0xc0010044, 0xc0010048, "AMD_K8_MC_CTL_MASK_n", AmdK8McCtlMaskN, AmdK8McCtlMaskN),
     RSN(0xc0010050, 0xc0010053, "AMD_K8_SMI_ON_IO_TRAP_n", AmdK8SmiOnIoTrapN, AmdK8SmiOnIoTrapN, 0x0, 0, UINT64_C(0x1f00000000000000)),
-    MFX(0xc0010054, "AMD_K8_SMI_ON_IO_TRAP_CTL_STS", AmdK8SmiOnIoTrapCtlSts, AmdK8SmiOnIoTrapCtlSts, 0, 0, UINT64_C(0xffffffffffff1f00)), /* value=0x0 */
-    MFX(0xc0010111, "AMD_K8_SMM_BASE", AmdK8SmmBase, AmdK8SmmBase, 0, ~(uint64_t)UINT32_MAX, 0), /* value=0x98000 */
+    MFX(0xc0010054, "AMD_K8_SMI_ON_IO_TRAP_CTL_STS", AmdK8SmiOnIoTrapCtlSts, AmdK8SmiOnIoTrapCtlSts, 0, ~(uint64_t)UINT32_MAX, UINT32_C(0xffff1f00)), /* value=0x0 */
+    MFX(0xc0010055, "AMD_K8_INT_PENDING_MSG", AmdK8IntPendingMessage, AmdK8IntPendingMessage, 0, ~(uint64_t)UINT32_MAX, UINT32_C(0xe0000000)), /* value=0x3000000 */
+    MVO(0xc0010060, "AMD_K8_BIST_RESULT", 0),
+    MFX(0xc0010111, "AMD_K8_SMM_BASE", AmdK8SmmBase, AmdK8SmmBase, 0, ~(uint64_t)UINT32_MAX, 0), /* value=0x98200 */
     MFX(0xc0010112, "AMD_K8_SMM_ADDR", AmdK8SmmAddr, AmdK8SmmAddr, 0, UINT64_C(0xffffff000001ffff), 0), /* value=0x0 */
     MFX(0xc0010113, "AMD_K8_SMM_MASK", AmdK8SmmMask, AmdK8SmmMask, 0, UINT64_C(0xffffff00000188c0), 0), /* value=0x1 */
-    MVX(0xc0010114, "AMD_K8_UNK_c001_0114", 0, 0, UINT64_C(0xffffffffffffffe4)),
-    MVX(0xc0010115, "AMD_K8_UNK_c001_0115", 0, 0, UINT64_C(0xffff800000000000)),
-    MVX(0xc0010116, "AMD_K8_UNK_c001_0116", 0, 0, UINT64_C(0xffff0000ffff0000)),
-    MVX(0xc0010117, "AMD_K8_UNK_c001_0117", 0, 0, UINT64_C(0xffff800000000000)),
-    MVX(0xc0010118, "AMD_K8_UNK_c001_0118",0,0,0),
-    MVX(0xc0010119, "AMD_K8_UNK_c001_0119",0,0,0),
-    MVX(0xc001011a, "AMD_K8_UNK_c001_011a", 0, 0, UINT64_C(0xffffffff00000fff)),
-    MVX(0xc001011b, "AMD_K8_UNK_c001_011b", 0, 0, ~(uint64_t)UINT32_MAX),
-    MVX(0xc001011c, "AMD_K8_UNK_c001_011c", UINT32_C(0xdb1f5000), 0, UINT64_C(0xffffffff00000fff)),
-    MFX(0xc0011000, "AMD_K7_MCODE_CTL", AmdK7MicrocodeCtl, AmdK7MicrocodeCtl, 0, ~(uint64_t)UINT32_MAX, 0x204), /* value=0x0 */
-    MFX(0xc0011001, "AMD_K7_APIC_CLUSTER_ID", AmdK7ClusterIdMaybe, AmdK7ClusterIdMaybe, 0, ~(uint64_t)UINT32_MAX, 0), /* value=0x0 */
-    MFX(0xc0011004, "AMD_K8_CPUID_CTL_STD01", AmdK8CpuIdCtlStd01hEdcx, AmdK8CpuIdCtlStd01hEdcx, 0, ~(uint64_t)UINT32_MAX, 0), /* value=0x78bfbff */
-    MFX(0xc0011005, "AMD_K8_CPUID_CTL_EXT01", AmdK8CpuIdCtlExt01hEdcx, AmdK8CpuIdCtlExt01hEdcx, 0, ~(uint64_t)UINT32_MAX, 0), /* value=0xf1f3fbff */
-    MFX(0xc0011006, "AMD_K7_DEBUG_STS?", AmdK7DebugStatusMaybe, AmdK7DebugStatusMaybe, 0, ~(uint64_t)UINT32_MAX, 0), /* value=0x0 */
-    MFN(0xc0011007, "AMD_K7_BH_TRACE_BASE?", AmdK7BHTraceBaseMaybe, AmdK7BHTraceBaseMaybe), /* value=0x0 */
-    MFN(0xc0011008, "AMD_K7_BH_TRACE_PTR?", AmdK7BHTracePtrMaybe, AmdK7BHTracePtrMaybe), /* value=0x0 */
-    MFN(0xc0011009, "AMD_K7_BH_TRACE_LIM?", AmdK7BHTraceLimitMaybe, AmdK7BHTraceLimitMaybe), /* value=0x0 */
-    MFX(0xc001100a, "AMD_K7_HDT_CFG?", AmdK7HardwareDebugToolCfgMaybe, AmdK7HardwareDebugToolCfgMaybe, 0, ~(uint64_t)UINT32_MAX, 0), /* value=0x0 */
-    MFX(0xc001100b, "AMD_K7_FAST_FLUSH_COUNT?", AmdK7FastFlushCountMaybe, AmdK7FastFlushCountMaybe, 0, ~(uint64_t)UINT32_MAX, 0), /* value=0x7c0 */
-    MFX(0xc001100c, "AMD_K7_NODE_ID", AmdK7NodeId, AmdK7NodeId, 0, ~(uint64_t)UINT32_MAX, 0), /* value=0x20906 */
-    MVX(0xc001100d, "AMD_K8_LOGICAL_CPUS_NUM?", 0x10a, 0, 0),
-    MVX(0xc001100e, "AMD_K8_WRMSR_BP?", 0, ~(uint64_t)UINT32_MAX, 0),
-    MVX(0xc001100f, "AMD_K8_WRMSR_BP_MASK?", 0, ~(uint64_t)UINT32_MAX, 0),
-    MVX(0xc0011010, "AMD_K8_BH_TRACE_CTL?", 0, ~(uint64_t)UINT32_MAX, 0),
-    MVX(0xc0011011, "AMD_K8_BH_TRACE_USRD?", 0, 0, 0), /* value=0xc0011011`00000283 */
-    MVX(0xc0011014, "AMD_K8_XCPT_BP_RIP?", 0, 0, 0),
-    MVX(0xc0011015, "AMD_K8_XCPT_BP_RIP_MASK?", 0, 0, 0),
-    MVX(0xc0011016, "AMD_K8_COND_HDT_VAL?", 0, 0, 0),
-    MVX(0xc0011017, "AMD_K8_COND_HDT_VAL_MASK?", 0, 0, 0),
-    MVX(0xc0011018, "AMD_K8_XCPT_BP_CTL?", 0, ~(uint64_t)UINT32_MAX, 0),
-    MVX(0xc001101d, "AMD_K8_NB_BIST?", 0, UINT64_C(0xfffffffffc000000), 0),
-    MVI(0xc001101e, "AMD_K8_THERMTRIP_2?", 0x521020), /* Villain? */
-    MVX(0xc001101f, "AMD_K8_NB_CFG?", UINT64_C(0x1100000008), UINT64_C(0xffffff0000000000), 0),
-    MFX(0xc0011020, "AMD_K7_LS_CFG", AmdK7LoadStoreCfg, AmdK7LoadStoreCfg, 0, ~(uint64_t)UINT32_MAX, 0), /* value=0x1000 */
-    MFX(0xc0011021, "AMD_K7_IC_CFG", AmdK7InstrCacheCfg, AmdK7InstrCacheCfg, 0x800, ~(uint64_t)UINT32_MAX, 0), /* value=0x800 */
-    MFX(0xc0011022, "AMD_K7_DC_CFG", AmdK7DataCacheCfg, AmdK7DataCacheCfg, 0, ~(uint64_t)UINT32_MAX, 0), /* value=0x24000008 */
-    MFN(0xc0011023, "AMD_K7_BU_CFG", AmdK7BusUnitCfg, AmdK7BusUnitCfg), /* Villain? value=0x2020 */
-    MFX(0xc0011024, "AMD_K7_DEBUG_CTL_2?", AmdK7DebugCtl2Maybe, AmdK7DebugCtl2Maybe, 0, UINT64_C(0xffffffffffffff00), 0), /* value=0x0 */
-    MFN(0xc0011025, "AMD_K7_DR0_DATA_MATCH?", AmdK7Dr0DataMatchMaybe, AmdK7Dr0DataMatchMaybe), /* value=0x0 */
-    MFN(0xc0011026, "AMD_K7_DR0_DATA_MATCH?", AmdK7Dr0DataMaskMaybe, AmdK7Dr0DataMaskMaybe), /* value=0x0 */
-    MFX(0xc0011027, "AMD_K7_DR0_ADDR_MASK", AmdK7DrXAddrMaskN, AmdK7DrXAddrMaskN, 0x0, UINT64_C(0xfffffffffffff000), 0), /* value=0x0 */
+    MFX(0xc0010114, "AMD_K8_VM_CR", AmdK8VmCr, AmdK8VmCr, 0, ~(uint64_t)UINT32_MAX, UINT32_C(0xffffffe0)), /* value=0x0 */
+    MFX(0xc0010115, "AMD_K8_IGNNE", AmdK8IgnNe, AmdK8IgnNe, 0, ~(uint64_t)UINT32_MAX, UINT32_C(0xfffffffe)), /* value=0x0 */
+    MFN(0xc0010116, "AMD_K8_SMM_CTL", WriteOnly, AmdK8SmmCtl),
+    MFX(0xc0010117, "AMD_K8_VM_HSAVE_PA", AmdK8VmHSavePa, AmdK8VmHSavePa, 0, 0, UINT64_C(0xffffff0000000fff)), /* value=0x0 */
 };
 #endif /* !CPUM_DB_STANDALONE */
 
 
 /**
- * Database entry for AMD Athlon(tm) 64 Processor 3200+.
+ * Database entry for AMD Athlon(tm) 64 X2 Dual Core Processor 4200+.
  */
-static CPUMDBENTRY const g_Entry_AMD_Athlon_64_3200 = 
+static CPUMDBENTRY const g_Entry_AMD_Athlon_64_X2_Dual_Core_4200 =
 {
-    /*.pszName          = */ "AMD Athlon 64 3200+",
-    /*.pszFullName      = */ "AMD Athlon(tm) 64 Processor 3200+",
+    /*.pszName          = */ "AMD Athlon 64 X2 Dual Core 4200+",
+    /*.pszFullName      = */ "AMD Athlon(tm) 64 X2 Dual Core Processor 4200+",
     /*.enmVendor        = */ CPUMCPUVENDOR_AMD,
     /*.uFamily          = */ 15,
-    /*.uModel           = */ 4,
-    /*.uStepping        = */ 8,
-    /*.enmMicroarch     = */ kCpumMicroarch_AMD_K8_130nm,
+    /*.uModel           = */ 75,
+    /*.uStepping        = */ 2,
+    /*.enmMicroarch     = */ kCpumMicroarch_AMD_K8_90nm_AMDV,
+    /*.uScalableBusFreq = */ CPUM_SBUSFREQ_UNKNOWN,
     /*.fFlags           = */ 0,
     /*.cMaxPhysAddrWidth= */ 40,
-    /*.paCpuIdLeaves    = */ NULL_ALONE(g_aCpuIdLeaves_AMD_Athlon_64_3200),
-    /*.cCpuIdLeaves     = */ ZERO_ALONE(RT_ELEMENTS(g_aCpuIdLeaves_AMD_Athlon_64_3200)),
+    /*.paCpuIdLeaves    = */ NULL_ALONE(g_aCpuIdLeaves_AMD_Athlon_64_X2_Dual_Core_4200),
+    /*.cCpuIdLeaves     = */ ZERO_ALONE(RT_ELEMENTS(g_aCpuIdLeaves_AMD_Athlon_64_X2_Dual_Core_4200)),
     /*.enmUnknownCpuId  = */ CPUMUKNOWNCPUID_DEFAULTS,
     /*.DefUnknownCpuId  = */ { 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
     /*.fMsrMask         = */ UINT32_MAX,
-    /*.cMsrRanges       = */ ZERO_ALONE(RT_ELEMENTS(g_aMsrRanges_AMD_Athlon_64_3200)),
-    /*.paMsrRanges      = */ NULL_ALONE(g_aMsrRanges_AMD_Athlon_64_3200),
+    /*.cMsrRanges       = */ ZERO_ALONE(RT_ELEMENTS(g_aMsrRanges_AMD_Athlon_64_X2_Dual_Core_4200)),
+    /*.paMsrRanges      = */ NULL_ALONE(g_aMsrRanges_AMD_Athlon_64_X2_Dual_Core_4200),
 };
 
-#endif /* !VBOX_DB_AMD_Athlon_64_3200 */
+#endif /* !VBOX_DB_AMD_Athlon_64_X2_Dual_Core_4200 */
 
diff --git a/src/VBox/VMM/VMMR3/cpus/AMD_FX_8150_Eight_Core.h b/src/VBox/VMM/VMMR3/cpus/AMD_FX_8150_Eight_Core.h
index 8efb945..f798207 100644
--- a/src/VBox/VMM/VMMR3/cpus/AMD_FX_8150_Eight_Core.h
+++ b/src/VBox/VMM/VMMR3/cpus/AMD_FX_8150_Eight_Core.h
@@ -363,6 +363,7 @@ static CPUMDBENTRY const g_Entry_AMD_FX_8150_Eight_Core =
     /*.uModel           = */ 1,
     /*.uStepping        = */ 2,
     /*.enmMicroarch     = */ kCpumMicroarch_AMD_15h_Bulldozer,
+    /*.uScalableBusFreq = */ CPUM_SBUSFREQ_UNKNOWN,
     /*.fFlags           = */ 0,
     /*.cMaxPhysAddrWidth= */ 48,
     /*.paCpuIdLeaves    = */ NULL_ALONE(g_aCpuIdLeaves_AMD_FX_8150_Eight_Core),
diff --git a/src/VBox/VMM/VMMR3/cpus/AMD_Phenom_II_X6_1100T.h b/src/VBox/VMM/VMMR3/cpus/AMD_Phenom_II_X6_1100T.h
index fc9eb23..8caceec 100644
--- a/src/VBox/VMM/VMMR3/cpus/AMD_Phenom_II_X6_1100T.h
+++ b/src/VBox/VMM/VMMR3/cpus/AMD_Phenom_II_X6_1100T.h
@@ -252,6 +252,7 @@ static CPUMDBENTRY const g_Entry_AMD_Phenom_II_X6_1100T =
     /*.uModel           = */ 10,
     /*.uStepping        = */ 0,
     /*.enmMicroarch     = */ kCpumMicroarch_AMD_K10,
+    /*.uScalableBusFreq = */ CPUM_SBUSFREQ_UNKNOWN,
     /*.fFlags           = */ 0,
     /*.cMaxPhysAddrWidth= */ 48,
     /*.paCpuIdLeaves    = */ NULL_ALONE(g_aCpuIdLeaves_AMD_Phenom_II_X6_1100T),
diff --git a/src/VBox/VMM/VMMR3/cpus/Intel_Core_i5_3570.h b/src/VBox/VMM/VMMR3/cpus/Intel_Core_i5_3570.h
index 30d2c84..7e4c6f5 100644
--- a/src/VBox/VMM/VMMR3/cpus/Intel_Core_i5_3570.h
+++ b/src/VBox/VMM/VMMR3/cpus/Intel_Core_i5_3570.h
@@ -63,13 +63,13 @@ static CPUMMSRRANGE const g_aMsrRanges_Intel_Core_i5_3570[] =
     MFX(0x00000001, "IA32_P5_MC_TYPE", Ia32P5McType, Ia32P5McType, 0, 0, UINT64_MAX), /* value=0x0 */
     MFX(0x00000006, "IA32_MONITOR_FILTER_LINE_SIZE", Ia32MonitorFilterLineSize, Ia32MonitorFilterLineSize, 0, 0, UINT64_C(0xffffffffffff0000)), /* value=0x40 */
     MFN(0x00000010, "IA32_TIME_STAMP_COUNTER", Ia32TimestampCounter, Ia32TimestampCounter), /* value=0x4293`b0a3f54a */
-    MVO(0x00000017, "IA32_PLATFORM_ID", UINT64_C(0x4000000000000)),
+    MFV(0x00000017, "IA32_PLATFORM_ID", Ia32PlatformId, ReadOnly, UINT64_C(0x4000000000000)),
     MFX(0x0000001b, "IA32_APIC_BASE", Ia32ApicBase, Ia32ApicBase, UINT32_C(0xfee00c00), 0, UINT64_C(0xfffffff0000002ff)),
     MFX(0x0000002a, "EBL_CR_POWERON", IntelEblCrPowerOn, ReadOnly, 0, 0, 0), /* value=0x0 */
     MVX(0x0000002e, "I7_UNK_0000_002e", 0, 0x400, UINT64_C(0xfffffffffffffbff)),
     MVX(0x00000033, "TEST_CTL", 0, 0, UINT64_C(0xffffffff7fffffff)),
     MVO(0x00000034, "P6_UNK_0000_0034", 0x285),
-    MVO(0x00000035, "P6_UNK_0000_0035", 0x40004),
+    MFO(0x00000035, "MSR_CORE_THREAD_COUNT", IntelI7CoreThreadCount), /* value=0x40004*/
     MVO(0x00000036, "I7_UNK_0000_0036", UINT64_C(0x1000000000105df2)),
     MFO(0x0000003a, "IA32_FEATURE_CONTROL", Ia32FeatureControl), /* value=0x5 */
     MVX(0x0000003e, "I7_UNK_0000_003e", 0x1, 0, UINT64_C(0xfffffffffffffffe)),
@@ -77,7 +77,7 @@ static CPUMMSRRANGE const g_aMsrRanges_Intel_Core_i5_3570[] =
     MVX(0x0000008b, "BBL_CR_D3|BIOS_SIGN", UINT64_C(0x1900000000), 0x1, UINT32_C(0xfffffffe)),
     MFO(0x0000009b, "IA32_SMM_MONITOR_CTL", Ia32SmmMonitorCtl), /* value=0x0 */
     RSN(0x000000c1, 0x000000c8, "IA32_PMCn", Ia32PmcN, Ia32PmcN, 0x0, ~(uint64_t)UINT32_MAX, 0),
-    MFO(0x000000ce, "MSR_PLATFORM_INFO", IntelPlatformInfo100MHz), /* value=0x81010'e0012200*/
+    MFO(0x000000ce, "MSR_PLATFORM_INFO", IntelPlatformInfo), /* value=0x81010'e0012200*/
     MFX(0x000000e2, "MSR_PKG_CST_CONFIG_CONTROL", IntelPkgCStConfigControl, IntelPkgCStConfigControl, 0, 0, UINT64_C(0xffffffffe1ffffff)), /* value=0x1e008403 */
     MFX(0x000000e4, "MSR_PMG_IO_CAPTURE_BASE", IntelPmgIoCaptureBase, IntelPmgIoCaptureBase, 0, 0, UINT64_C(0xfffffffffff80000)), /* value=0x10414 */
     MFN(0x000000e7, "IA32_MPERF", Ia32MPerf, Ia32MPerf), /* value=0x3a`2c710584 */
@@ -98,7 +98,7 @@ static CPUMMSRRANGE const g_aMsrRanges_Intel_Core_i5_3570[] =
     MFX(0x00000179, "IA32_MCG_CAP", Ia32McgCap, ReadOnly, 0xc09, 0, 0), /* value=0xc09 */
     MFX(0x0000017a, "IA32_MCG_STATUS", Ia32McgStatus, Ia32McgStatus, 0, 0, UINT64_C(0xfffffffffffffff8)), /* value=0x0 */
     RSN(0x00000186, 0x0000018d, "IA32_PERFEVTSELn", Ia32PerfEvtSelN, Ia32PerfEvtSelN, 0x0, 0, UINT64_C(0xffffffff00080000)),
-    MFX(0x00000194, "CLOCK_FLEX_MAX", IntelFlexRatio100MHz, IntelFlexRatio100MHz, 0x190000, 0x1e00ff, UINT64_C(0xffffffffffe00000)),
+    MFX(0x00000194, "CLOCK_FLEX_MAX", IntelFlexRatio, IntelFlexRatio, 0x190000, 0x1e00ff, UINT64_C(0xffffffffffe00000)),
     MFX(0x00000198, "IA32_PERF_STATUS", Ia32PerfStatus, ReadOnly, UINT64_C(0x1d2400001000), 0, 0), /* value=0x1d24`00001000 */
     MFX(0x00000199, "IA32_PERF_CTL", Ia32PerfCtl, Ia32PerfCtl, 0x1000, 0, 0), /* Might bite. value=0x1000 */
     MFX(0x0000019a, "IA32_CLOCK_MODULATION", Ia32ClockModulation, Ia32ClockModulation, 0, 0, UINT64_C(0xffffffffffffffe0)), /* value=0x0 */
@@ -319,6 +319,7 @@ static CPUMDBENTRY const g_Entry_Intel_Core_i5_3570 =
     /*.uModel           = */ 58,
     /*.uStepping        = */ 9,
     /*.enmMicroarch     = */ kCpumMicroarch_Intel_Core7_IvyBridge,
+    /*.uScalableBusFreq = */ CPUM_SBUSFREQ_100MHZ,
     /*.fFlags           = */ 0,
     /*.cMaxPhysAddrWidth= */ 36,
     /*.paCpuIdLeaves    = */ NULL_ALONE(g_aCpuIdLeaves_Intel_Core_i5_3570),
diff --git a/src/VBox/VMM/VMMR3/cpus/Intel_Core_i5_3570.h b/src/VBox/VMM/VMMR3/cpus/Intel_Core_i7_2635QM.h
similarity index 63%
copy from src/VBox/VMM/VMMR3/cpus/Intel_Core_i5_3570.h
copy to src/VBox/VMM/VMMR3/cpus/Intel_Core_i7_2635QM.h
index 30d2c84..72ab084 100644
--- a/src/VBox/VMM/VMMR3/cpus/Intel_Core_i5_3570.h
+++ b/src/VBox/VMM/VMMR3/cpus/Intel_Core_i7_2635QM.h
@@ -1,7 +1,7 @@
-/* $Id: Intel_Core_i5_3570.h $ */
+/* $Id: Intel_Core_i7_2635QM.h $ */
 /** @file
- * CPU database entry "Intel Core i5-3570".
- * Generated at 2013-12-13T16:13:56Z by VBoxCpuReport v4.3.53r91216 on linux.amd64.
+ * CPU database entry "Intel Core i7-2635QM".
+ * Generated at 2014-02-28T18:53:09Z by VBoxCpuReport v4.3.53r92586 on darwin.amd64.
  */
 
 /*
@@ -16,35 +16,41 @@
  * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
  */
 
-#ifndef VBOX_CPUDB_Intel_Core_i5_3570
-#define VBOX_CPUDB_Intel_Core_i5_3570
+#ifndef VBOX_CPUDB_Intel_Core_i7_2635QM
+#define VBOX_CPUDB_Intel_Core_i7_2635QM
 
 
 #ifndef CPUM_DB_STANDALONE
 /**
- * CPUID leaves for Intel(R) Core(TM) i5-3570 CPU @ 3.40GHz.
+ * CPUID leaves for Intel(R) Core(TM) i7-2635QM CPU @ 2.00GHz.
  */
-static CPUMCPUIDLEAF const g_aCpuIdLeaves_Intel_Core_i5_3570[] = 
+static CPUMCPUIDLEAF const g_aCpuIdLeaves_Intel_Core_i7_2635QM[] = 
 {
     { 0x00000000, 0x00000000, 0x00000000, 0x0000000d, 0x756e6547, 0x6c65746e, 0x49656e69, 0 },
-    { 0x00000001, 0x00000000, 0x00000000, 0x000306a9, 0x04100800, 0x7fbae3ff, 0xbfebfbff, 0 },
-    { 0x00000002, 0x00000000, 0x00000000, 0x76035a01, 0x00f0b0ff, 0x00000000, 0x00ca0000, 0 },
+    { 0x00000001, 0x00000000, 0x00000000, 0x000206a7, 0x04100800, 0x1fbae3bf, 0xbfebfbff, 0 },
+    { 0x00000002, 0x00000000, 0x00000000, 0x76035a01, 0x00f0b2ff, 0x00000000, 0x00ca0000, 0 },
     { 0x00000003, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0 },
-    { 0x00000004, 0x00000000, 0x00000000, 0x1c004121, 0x01c0003f, 0x0000003f, 0x00000000, 0 },
-    { 0x00000005, 0x00000000, 0x00000000, 0x00000040, 0x00000040, 0x00000003, 0x00001120, 0 },
+    { 0x00000004, 0x00000000, UINT32_MAX, 0x1c004121, 0x01c0003f, 0x0000003f, 0x00000000, 0 },
+    { 0x00000004, 0x00000001, UINT32_MAX, 0x1c004122, 0x01c0003f, 0x0000003f, 0x00000000, 0 },
+    { 0x00000004, 0x00000002, UINT32_MAX, 0x1c004143, 0x01c0003f, 0x000001ff, 0x00000000, 0 },
+    { 0x00000004, 0x00000003, UINT32_MAX, 0x1c03c163, 0x02c0003f, 0x00001fff, 0x00000006, 0 },
+    { 0x00000004, 0x00000004, UINT32_MAX, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0 },
+    { 0x00000005, 0x00000000, 0x00000000, 0x00000040, 0x00000040, 0x00000003, 0x00021120, 0 },
     { 0x00000006, 0x00000000, 0x00000000, 0x00000077, 0x00000002, 0x00000009, 0x00000000, 0 },
-    { 0x00000007, 0x00000000, 0x00000000, 0x00000000, 0x00000281, 0x00000000, 0x00000000, 0 },
+    { 0x00000007, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0 },
     { 0x00000008, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0 },
     { 0x00000009, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0 },
-    { 0x0000000a, 0x00000000, 0x00000000, 0x07300803, 0x00000000, 0x00000000, 0x00000603, 0 },
-    { 0x0000000b, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000100, 0x00000004, 0 },
+    { 0x0000000a, 0x00000000, 0x00000000, 0x07300403, 0x00000000, 0x00000000, 0x00000603, 0 },
     { 0x0000000c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0 },
-    { 0x0000000d, 0x00000000, 0x00000000, 0x00000007, 0x00000340, 0x00000340, 0x00000000, 0 },
+    { 0x0000000d, 0x00000000, UINT32_MAX, 0x00000007, 0x00000340, 0x00000340, 0x00000000, 0 },
+    { 0x0000000d, 0x00000001, UINT32_MAX, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0 },
+    { 0x0000000d, 0x00000002, UINT32_MAX, 0x00000100, 0x00000240, 0x00000000, 0x00000000, 0 },
+    { 0x0000000d, 0x00000003, UINT32_MAX, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0 },
     { 0x80000000, 0x00000000, 0x00000000, 0x80000008, 0x00000000, 0x00000000, 0x00000000, 0 },
     { 0x80000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x28100800, 0 },
-    { 0x80000002, 0x00000000, 0x00000000, 0x20202020, 0x20202020, 0x65746e49, 0x2952286c, 0 },
-    { 0x80000003, 0x00000000, 0x00000000, 0x726f4320, 0x4d542865, 0x35692029, 0x3735332d, 0 },
-    { 0x80000004, 0x00000000, 0x00000000, 0x50432030, 0x20402055, 0x30342e33, 0x007a4847, 0 },
+    { 0x80000002, 0x00000000, 0x00000000, 0x20202020, 0x6e492020, 0x286c6574, 0x43202952, 0 },
+    { 0x80000003, 0x00000000, 0x00000000, 0x2865726f, 0x20294d54, 0x322d3769, 0x51353336, 0 },
+    { 0x80000004, 0x00000000, 0x00000000, 0x5043204d, 0x20402055, 0x30302e32, 0x007a4847, 0 },
     { 0x80000005, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0 },
     { 0x80000006, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x01006040, 0x00000000, 0 },
     { 0x80000007, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000100, 0 },
@@ -55,94 +61,89 @@ static CPUMCPUIDLEAF const g_aCpuIdLeaves_Intel_Core_i5_3570[] =
 
 #ifndef CPUM_DB_STANDALONE
 /**
- * MSR ranges for Intel(R) Core(TM) i5-3570 CPU @ 3.40GHz.
+ * MSR ranges for Intel(R) Core(TM) i7-2635QM CPU @ 2.00GHz.
  */
-static CPUMMSRRANGE const g_aMsrRanges_Intel_Core_i5_3570[] = 
+static CPUMMSRRANGE const g_aMsrRanges_Intel_Core_i7_2635QM[] = 
 {
     MFX(0x00000000, "IA32_P5_MC_ADDR", Ia32P5McAddr, Ia32P5McAddr, 0, UINT64_C(0xffffffffffffffe0), 0), /* value=0x1f */
     MFX(0x00000001, "IA32_P5_MC_TYPE", Ia32P5McType, Ia32P5McType, 0, 0, UINT64_MAX), /* value=0x0 */
     MFX(0x00000006, "IA32_MONITOR_FILTER_LINE_SIZE", Ia32MonitorFilterLineSize, Ia32MonitorFilterLineSize, 0, 0, UINT64_C(0xffffffffffff0000)), /* value=0x40 */
-    MFN(0x00000010, "IA32_TIME_STAMP_COUNTER", Ia32TimestampCounter, Ia32TimestampCounter), /* value=0x4293`b0a3f54a */
-    MVO(0x00000017, "IA32_PLATFORM_ID", UINT64_C(0x4000000000000)),
-    MFX(0x0000001b, "IA32_APIC_BASE", Ia32ApicBase, Ia32ApicBase, UINT32_C(0xfee00c00), 0, UINT64_C(0xfffffff0000002ff)),
+    MFN(0x00000010, "IA32_TIME_STAMP_COUNTER", Ia32TimestampCounter, Ia32TimestampCounter), /* value=0x94d`1967512c */
+    MFX(0x00000017, "IA32_PLATFORM_ID", Ia32PlatformId, ReadOnly, UINT64_C(0x10000000000000), 0, 0), /* value=0x100000`00000000 */
+    MFX(0x0000001b, "IA32_APIC_BASE", Ia32ApicBase, Ia32ApicBase, UINT32_C(0xfee00800), 0, UINT64_C(0xfffffff0000002ff)),
     MFX(0x0000002a, "EBL_CR_POWERON", IntelEblCrPowerOn, ReadOnly, 0, 0, 0), /* value=0x0 */
     MVX(0x0000002e, "I7_UNK_0000_002e", 0, 0x400, UINT64_C(0xfffffffffffffbff)),
     MVX(0x00000033, "TEST_CTL", 0, 0, UINT64_C(0xffffffff7fffffff)),
-    MVO(0x00000034, "P6_UNK_0000_0034", 0x285),
-    MVO(0x00000035, "P6_UNK_0000_0035", 0x40004),
-    MVO(0x00000036, "I7_UNK_0000_0036", UINT64_C(0x1000000000105df2)),
+    MVO(0x00000034, "P6_UNK_0000_0034", 0x5),
+    MFO(0x00000035, "MSR_CORE_THREAD_COUNT", IntelI7CoreThreadCount), /* value=0x40008 */
     MFO(0x0000003a, "IA32_FEATURE_CONTROL", Ia32FeatureControl), /* value=0x5 */
-    MVX(0x0000003e, "I7_UNK_0000_003e", 0x1, 0, UINT64_C(0xfffffffffffffffe)),
+    MVX(0x0000003e, "I7_UNK_0000_003e", 0, 0, UINT64_C(0xfffffffffffffffe)),
     MFN(0x00000079, "IA32_BIOS_UPDT_TRIG", WriteOnly, IgnoreWrite),
-    MVX(0x0000008b, "BBL_CR_D3|BIOS_SIGN", UINT64_C(0x1900000000), 0x1, UINT32_C(0xfffffffe)),
+    MFX(0x0000008b, "BBL_CR_D3|BIOS_SIGN", Ia32BiosSignId, Ia32BiosSignId, 0, 0, UINT32_C(0xfffffffe)), /* value=0x28`00000000 */
     MFO(0x0000009b, "IA32_SMM_MONITOR_CTL", Ia32SmmMonitorCtl), /* value=0x0 */
-    RSN(0x000000c1, 0x000000c8, "IA32_PMCn", Ia32PmcN, Ia32PmcN, 0x0, ~(uint64_t)UINT32_MAX, 0),
-    MFO(0x000000ce, "MSR_PLATFORM_INFO", IntelPlatformInfo100MHz), /* value=0x81010'e0012200*/
-    MFX(0x000000e2, "MSR_PKG_CST_CONFIG_CONTROL", IntelPkgCStConfigControl, IntelPkgCStConfigControl, 0, 0, UINT64_C(0xffffffffe1ffffff)), /* value=0x1e008403 */
-    MFX(0x000000e4, "MSR_PMG_IO_CAPTURE_BASE", IntelPmgIoCaptureBase, IntelPmgIoCaptureBase, 0, 0, UINT64_C(0xfffffffffff80000)), /* value=0x10414 */
-    MFN(0x000000e7, "IA32_MPERF", Ia32MPerf, Ia32MPerf), /* value=0x3a`2c710584 */
-    MFN(0x000000e8, "IA32_APERF", Ia32APerf, Ia32APerf), /* value=0x39`f97c8410 */
+    RSN(0x000000c1, 0x000000c4, "IA32_PMCn", Ia32PmcN, Ia32PmcN, 0x0, ~(uint64_t)UINT32_MAX, 0),
+    MFO(0x000000ce, "IA32_PLATFORM_INFO", IntelPlatformInfo), /* value=0x800`60011400 */
+    MFX(0x000000e2, "MSR_PKG_CST_CONFIG_CONTROL", IntelPkgCStConfigControl, IntelPkgCStConfigControl, 0, 0, UINT64_C(0xffffffffe1ffffff)), /* value=0x405 */
+    MFX(0x000000e4, "MSR_PMG_IO_CAPTURE_BASE", IntelPmgIoCaptureBase, IntelPmgIoCaptureBase, 0, 0, UINT64_C(0xfffffffffff80000)), /* value=0x20414 */
+    MFN(0x000000e7, "IA32_MPERF", Ia32MPerf, Ia32MPerf), /* value=0x6a`9190b14b */
+    MFN(0x000000e8, "IA32_APERF", Ia32APerf, Ia32APerf), /* value=0x69`df4de05c */
     MFX(0x000000fe, "IA32_MTRRCAP", Ia32MtrrCap, ReadOnly, 0xd0a, 0, 0), /* value=0xd0a */
-    MVX(0x00000102, "I7_IB_UNK_0000_0102", 0, 0, UINT64_C(0xffffffff7fff8000)),
-    MVX(0x00000103, "I7_IB_UNK_0000_0103", 0, 0, UINT64_C(0xffffffffffffff00)),
-    MVX(0x00000104, "I7_IB_UNK_0000_0104", 0, 0, UINT64_C(0xfffffffffffffffe)),
     MFN(0x00000132, "CPUID1_FEATURE_MASK", IntelCpuId1FeatureMaskEax, IntelCpuId1FeatureMaskEax), /* value=0xffffffff`ffffffff */
     MFN(0x00000133, "CPUIDD_01_FEATURE_MASK", IntelCpuId1FeatureMaskEcdx, IntelCpuId1FeatureMaskEcdx), /* value=0xffffffff`ffffffff */
     MFN(0x00000134, "CPUID80000001_FEATURE_MASK", IntelCpuId80000001FeatureMaskEcdx, IntelCpuId80000001FeatureMaskEcdx), /* value=0xffffffff`ffffffff */
     MFX(0x0000013c, "I7_SB_AES_NI_CTL", IntelI7SandyAesNiCtl, IntelI7SandyAesNiCtl, 0, 0, UINT64_C(0xfffffffffffffffc)), /* value=0x0 */
-    MVX(0x00000140, "I7_IB_UNK_0000_0140", 0, 0, UINT64_C(0xfffffffffffffffe)),
-    MVX(0x00000142, "I7_IB_UNK_0000_0142", 0, 0, UINT64_C(0xfffffffffffffffc)),
-    MFX(0x00000174, "IA32_SYSENTER_CS", Ia32SysEnterCs, Ia32SysEnterCs, 0, ~(uint64_t)UINT32_MAX, 0), /* value=0x10 */
-    MFX(0x00000175, "IA32_SYSENTER_ESP", Ia32SysEnterEsp, Ia32SysEnterEsp, 0, 0, UINT64_C(0xffff800000000000)), /* value=0x0 */
-    MFX(0x00000176, "IA32_SYSENTER_EIP", Ia32SysEnterEip, Ia32SysEnterEip, 0, 0, UINT64_C(0xffff800000000000)), /* value=0xffffffff`8159cbe0 */
+    MFX(0x00000174, "IA32_SYSENTER_CS", Ia32SysEnterCs, Ia32SysEnterCs, 0, ~(uint64_t)UINT32_MAX, 0), /* value=0xb */
+    MFX(0x00000175, "IA32_SYSENTER_ESP", Ia32SysEnterEsp, Ia32SysEnterEsp, 0, 0, UINT64_C(0xffff800000000000)), /* value=0xffffff80`22904080 */
+    MFX(0x00000176, "IA32_SYSENTER_EIP", Ia32SysEnterEip, Ia32SysEnterEip, 0, 0, UINT64_C(0xffff800000000000)), /* value=0xffffff80`222f3030 */
     MFX(0x00000179, "IA32_MCG_CAP", Ia32McgCap, ReadOnly, 0xc09, 0, 0), /* value=0xc09 */
     MFX(0x0000017a, "IA32_MCG_STATUS", Ia32McgStatus, Ia32McgStatus, 0, 0, UINT64_C(0xfffffffffffffff8)), /* value=0x0 */
-    RSN(0x00000186, 0x0000018d, "IA32_PERFEVTSELn", Ia32PerfEvtSelN, Ia32PerfEvtSelN, 0x0, 0, UINT64_C(0xffffffff00080000)),
-    MFX(0x00000194, "CLOCK_FLEX_MAX", IntelFlexRatio100MHz, IntelFlexRatio100MHz, 0x190000, 0x1e00ff, UINT64_C(0xffffffffffe00000)),
-    MFX(0x00000198, "IA32_PERF_STATUS", Ia32PerfStatus, ReadOnly, UINT64_C(0x1d2400001000), 0, 0), /* value=0x1d24`00001000 */
-    MFX(0x00000199, "IA32_PERF_CTL", Ia32PerfCtl, Ia32PerfCtl, 0x1000, 0, 0), /* Might bite. value=0x1000 */
+    RSN(0x00000186, 0x00000189, "IA32_PERFEVTSELn", Ia32PerfEvtSelN, Ia32PerfEvtSelN, 0x0, 0, UINT64_C(0xffffffff00080000)),
+    MFX(0x00000194, "CLOCK_FLEX_MAX", IntelFlexRatio, IntelFlexRatio, 0, 0xe0000, UINT64_C(0xfffffffffff00000)), /* value=0x0 */
+    MFX(0x00000198, "IA32_PERF_STATUS", Ia32PerfStatus, ReadOnly, UINT64_C(0x1d4d00000e00), 0, 0), /* value=0x1d4d`00000e00 */
+    MFX(0x00000199, "IA32_PERF_CTL", Ia32PerfCtl, Ia32PerfCtl, 0x1d00, 0, 0), /* Might bite. value=0x1d00 */
     MFX(0x0000019a, "IA32_CLOCK_MODULATION", Ia32ClockModulation, Ia32ClockModulation, 0, 0, UINT64_C(0xffffffffffffffe0)), /* value=0x0 */
-    MFX(0x0000019b, "IA32_THERM_INTERRUPT", Ia32ThermInterrupt, Ia32ThermInterrupt, 0x1000013, 0, UINT64_C(0xfffffffffe0000e8)), /* value=0x1000013 */
-    MFX(0x0000019c, "IA32_THERM_STATUS", Ia32ThermStatus, Ia32ThermStatus, UINT32_C(0x884c0000), UINT32_C(0xf87f0fff), UINT64_C(0xffffffff0780f000)), /* value=0x884c0000 */
+    MFX(0x0000019b, "IA32_THERM_INTERRUPT", Ia32ThermInterrupt, Ia32ThermInterrupt, 0, 0, UINT64_C(0xfffffffffe0000e8)), /* value=0x0 */
+    MFX(0x0000019c, "IA32_THERM_STATUS", Ia32ThermStatus, Ia32ThermStatus, UINT32_C(0x883d0000), UINT32_C(0xf87f0fff), UINT64_C(0xffffffff0780f000)), /* value=0x883d0000 */
     MFX(0x0000019d, "IA32_THERM2_CTL", Ia32Therm2Ctl, ReadOnly, 0, 0, 0), /* value=0x0 */
     MFX(0x000001a0, "IA32_MISC_ENABLE", Ia32MiscEnable, Ia32MiscEnable, 0x850089, 0x1080, UINT64_C(0xffffffbbff3aef72)), /* value=0x850089 */
-    MFX(0x000001a2, "I7_MSR_TEMPERATURE_TARGET", IntelI7TemperatureTarget, IntelI7TemperatureTarget, 0x691400, 0xffff00, UINT64_C(0xfffffffff00000ff)), /* value=0x691400 */
+    MFX(0x000001a2, "I7_MSR_TEMPERATURE_TARGET", IntelI7TemperatureTarget, IntelI7TemperatureTarget, 0x640e00, 0xffff00, UINT64_C(0xfffffffff00000ff)), /* value=0x640e00 */
     MVX(0x000001a4, "I7_UNK_0000_01a4", 0, 0, UINT64_C(0xfffffffffffff7f0)),
     RSN(0x000001a6, 0x000001a7, "I7_MSR_OFFCORE_RSP_n", IntelI7MsrOffCoreResponseN, IntelI7MsrOffCoreResponseN, 0x0, 0, UINT64_C(0xffffffc000007000)),
     MVX(0x000001a8, "I7_UNK_0000_01a8", 0, 0, UINT64_C(0xfffffffffffffffc)),
-    MFX(0x000001aa, "MSR_MISC_PWR_MGMT", IntelI7MiscPwrMgmt, IntelI7MiscPwrMgmt, 0, 0, UINT64_C(0xffffffffffbffffe)), /* value=0x400000 */
-    MFX(0x000001ad, "I7_MSR_TURBO_RATIO_LIMIT", IntelI7TurboRatioLimit, ReadOnly, 0x24252626, 0, 0), /* value=0x24252626 */
-    MVX(0x000001b0, "IA32_ENERGY_PERF_BIAS", 0x6, 0, UINT64_C(0xfffffffffffffff0)),
-    MVX(0x000001b1, "IA32_PACKAGE_THERM_STATUS", UINT32_C(0x88490000), UINT32_C(0xf87f0fff), UINT64_C(0xffffffff0780f000)),
-    MVX(0x000001b2, "IA32_PACKAGE_THERM_INTERRUPT", 0x1000003, 0, UINT64_C(0xfffffffffe0000e8)),
+    MFX(0x000001aa, "MSR_MISC_PWR_MGMT", IntelI7MiscPwrMgmt, IntelI7MiscPwrMgmt, 0, 0, UINT64_C(0xffffffffffbffffe)), /* value=0x400001 */
+    MFX(0x000001ad, "I7_MSR_TURBO_RATIO_LIMIT", IntelI7TurboRatioLimit, ReadOnly, 0x1a1a1c1d, 0, 0), /* value=0x1a1a1c1d */
+    MVX(0x000001b0, "IA32_ENERGY_PERF_BIAS", 0x4, 0, UINT64_C(0xfffffffffffffff0)),
+    MVX(0x000001b1, "IA32_PACKAGE_THERM_STATUS", UINT32_C(0x883a0000), UINT32_C(0xf87f0fff), UINT64_C(0xffffffff0780f000)),
+    MVX(0x000001b2, "IA32_PACKAGE_THERM_INTERRUPT", 0, 0, UINT64_C(0xfffffffffe0000e8)),
     MVO(0x000001c6, "I7_UNK_0000_01c6", 0x3),
     MFX(0x000001c8, "MSR_LBR_SELECT", IntelI7LbrSelect, IntelI7LbrSelect, 0, 0, UINT64_C(0xfffffffffffffe00)), /* value=0x0 */
-    MFX(0x000001c9, "MSR_LASTBRANCH_TOS", IntelLastBranchTos, IntelLastBranchTos, 0, 0, UINT64_C(0xfffffffffffffff0)), /* value=0x8 */
+    MFX(0x000001c9, "MSR_LASTBRANCH_TOS", IntelLastBranchTos, IntelLastBranchTos, 0, 0, UINT64_C(0xfffffffffffffff0)), /* value=0xc */
     MFX(0x000001d9, "IA32_DEBUGCTL", Ia32DebugCtl, Ia32DebugCtl, 0, 0, UINT64_C(0xffffffffffff803c)), /* value=0x0 */
-    MFO(0x000001db, "P6_LAST_BRANCH_FROM_IP", P6LastBranchFromIp), /* value=0x7fffffff`a061f4c9 */
-    MFO(0x000001dc, "P6_LAST_BRANCH_TO_IP", P6LastBranchToIp), /* value=0xffffffff`810473c0 */
+    MFO(0x000001db, "P6_LAST_BRANCH_FROM_IP", P6LastBranchFromIp), /* value=0x7fffff7f`a4a6e188 */
+    MFO(0x000001dc, "P6_LAST_BRANCH_TO_IP", P6LastBranchToIp), /* value=0xffffff80`222d5ad0 */
     MFX(0x000001dd, "P6_LAST_INT_FROM_IP", P6LastIntFromIp, P6LastIntFromIp, 0, 0, UINT64_C(0x7fff800000000000)), /* value=0x0 */
     MFX(0x000001de, "P6_LAST_INT_TO_IP", P6LastIntToIp, P6LastIntToIp, 0, 0, UINT64_C(0xffff800000000000)), /* value=0x0 */
+    MVO(0x000001e1, "I7_SB_UNK_0000_01e1", 0x2),
     MFO(0x000001f0, "I7_VLW_CAPABILITY", IntelI7VirtualLegacyWireCap), /* value=0x74 */
-    MFO(0x000001f2, "IA32_SMRR_PHYSBASE", Ia32SmrrPhysBase), /* value=0xdb000006 */
-    MFO(0x000001f3, "IA32_SMRR_PHYSMASK", Ia32SmrrPhysMask), /* value=0xff800800 */
-    MFX(0x000001fc, "I7_MSR_POWER_CTL", IntelI7PowerCtl, IntelI7PowerCtl, 0, 0x20, UINT64_C(0xffffffffffc20000)), /* value=0x14005f */
-    MFX(0x00000200, "IA32_MTRR_PHYS_BASE0", Ia32MtrrPhysBaseN, Ia32MtrrPhysBaseN, 0x0, 0, UINT64_C(0xfffffff000000ff8)), /* value=0x6 */
-    MFX(0x00000201, "IA32_MTRR_PHYS_MASK0", Ia32MtrrPhysMaskN, Ia32MtrrPhysMaskN, 0x0, 0, UINT64_C(0xfffffff0000007ff)), /* value=0xc`00000800 */
-    MFX(0x00000202, "IA32_MTRR_PHYS_BASE1", Ia32MtrrPhysBaseN, Ia32MtrrPhysBaseN, 0x1, 0, UINT64_C(0xfffffff000000ff8)), /* value=0x4`00000006 */
+    MFO(0x000001f2, "IA32_SMRR_PHYSBASE", Ia32SmrrPhysBase), /* value=0x0 */
+    MFO(0x000001f3, "IA32_SMRR_PHYSMASK", Ia32SmrrPhysMask), /* value=0x0 */
+    MFX(0x000001fc, "I7_MSR_POWER_CTL", IntelI7PowerCtl, IntelI7PowerCtl, 0, 0x20, UINT64_C(0xfffffffffff20000)), /* value=0x4005f */
+    MFX(0x00000200, "IA32_MTRR_PHYS_BASE0", Ia32MtrrPhysBaseN, Ia32MtrrPhysBaseN, 0x0, 0, UINT64_C(0xfffffff000000ff8)), /* value=0xc0000000 */
+    MFX(0x00000201, "IA32_MTRR_PHYS_MASK0", Ia32MtrrPhysMaskN, Ia32MtrrPhysMaskN, 0x0, 0, UINT64_C(0xfffffff0000007ff)), /* value=0xf`c0000800 */
+    MFX(0x00000202, "IA32_MTRR_PHYS_BASE1", Ia32MtrrPhysBaseN, Ia32MtrrPhysBaseN, 0x1, 0, UINT64_C(0xfffffff000000ff8)), /* value=0xa0000000 */
     MFX(0x00000203, "IA32_MTRR_PHYS_MASK1", Ia32MtrrPhysMaskN, Ia32MtrrPhysMaskN, 0x1, 0, UINT64_C(0xfffffff0000007ff)), /* value=0xf`e0000800 */
-    MFX(0x00000204, "IA32_MTRR_PHYS_BASE2", Ia32MtrrPhysBaseN, Ia32MtrrPhysBaseN, 0x2, 0, UINT64_C(0xfffffff000000ff8)), /* value=0xe0000000 */
-    MFX(0x00000205, "IA32_MTRR_PHYS_MASK2", Ia32MtrrPhysMaskN, Ia32MtrrPhysMaskN, 0x2, 0, UINT64_C(0xfffffff0000007ff)), /* value=0xf`e0000800 */
-    MFX(0x00000206, "IA32_MTRR_PHYS_BASE3", Ia32MtrrPhysBaseN, Ia32MtrrPhysBaseN, 0x3, 0, UINT64_C(0xfffffff000000ff8)), /* value=0xdc000000 */
+    MFX(0x00000204, "IA32_MTRR_PHYS_BASE2", Ia32MtrrPhysBaseN, Ia32MtrrPhysBaseN, 0x2, 0, UINT64_C(0xfffffff000000ff8)), /* value=0x90000000 */
+    MFX(0x00000205, "IA32_MTRR_PHYS_MASK2", Ia32MtrrPhysMaskN, Ia32MtrrPhysMaskN, 0x2, 0, UINT64_C(0xfffffff0000007ff)), /* value=0xf`f0000800 */
+    MFX(0x00000206, "IA32_MTRR_PHYS_BASE3", Ia32MtrrPhysBaseN, Ia32MtrrPhysBaseN, 0x3, 0, UINT64_C(0xfffffff000000ff8)), /* value=0x8c000000 */
     MFX(0x00000207, "IA32_MTRR_PHYS_MASK3", Ia32MtrrPhysMaskN, Ia32MtrrPhysMaskN, 0x3, 0, UINT64_C(0xfffffff0000007ff)), /* value=0xf`fc000800 */
-    MFX(0x00000208, "IA32_MTRR_PHYS_BASE4", Ia32MtrrPhysBaseN, Ia32MtrrPhysBaseN, 0x4, 0, UINT64_C(0xfffffff000000ff8)), /* value=0xdb800000 */
+    MFX(0x00000208, "IA32_MTRR_PHYS_BASE4", Ia32MtrrPhysBaseN, Ia32MtrrPhysBaseN, 0x4, 0, UINT64_C(0xfffffff000000ff8)), /* value=0x8b800000 */
     MFX(0x00000209, "IA32_MTRR_PHYS_MASK4", Ia32MtrrPhysMaskN, Ia32MtrrPhysMaskN, 0x4, 0, UINT64_C(0xfffffff0000007ff)), /* value=0xf`ff800800 */
-    MFX(0x0000020a, "IA32_MTRR_PHYS_BASE5", Ia32MtrrPhysBaseN, Ia32MtrrPhysBaseN, 0x5, 0, UINT64_C(0xfffffff000000ff8)), /* value=0x4`1f000000 */
-    MFX(0x0000020b, "IA32_MTRR_PHYS_MASK5", Ia32MtrrPhysMaskN, Ia32MtrrPhysMaskN, 0x5, 0, UINT64_C(0xfffffff0000007ff)), /* value=0xf`ff000800 */
-    MFX(0x0000020c, "IA32_MTRR_PHYS_BASE6", Ia32MtrrPhysBaseN, Ia32MtrrPhysBaseN, 0x6, 0, UINT64_C(0xfffffff000000ff8)), /* value=0x4`1e800000 */
-    MFX(0x0000020d, "IA32_MTRR_PHYS_MASK6", Ia32MtrrPhysMaskN, Ia32MtrrPhysMaskN, 0x6, 0, UINT64_C(0xfffffff0000007ff)), /* value=0xf`ff800800 */
-    MFX(0x0000020e, "IA32_MTRR_PHYS_BASE7", Ia32MtrrPhysBaseN, Ia32MtrrPhysBaseN, 0x7, 0, UINT64_C(0xfffffff000000ff8)), /* value=0x4`1e600000 */
-    MFX(0x0000020f, "IA32_MTRR_PHYS_MASK7", Ia32MtrrPhysMaskN, Ia32MtrrPhysMaskN, 0x7, 0, UINT64_C(0xfffffff0000007ff)), /* value=0xf`ffe00800 */
+    MFX(0x0000020a, "IA32_MTRR_PHYS_BASE5", Ia32MtrrPhysBaseN, Ia32MtrrPhysBaseN, 0x5, 0, UINT64_C(0xfffffff000000ff8)), /* value=0x0 */
+    MFX(0x0000020b, "IA32_MTRR_PHYS_MASK5", Ia32MtrrPhysMaskN, Ia32MtrrPhysMaskN, 0x5, 0, UINT64_C(0xfffffff0000007ff)), /* value=0x0 */
+    MFX(0x0000020c, "IA32_MTRR_PHYS_BASE6", Ia32MtrrPhysBaseN, Ia32MtrrPhysBaseN, 0x6, 0, UINT64_C(0xfffffff000000ff8)), /* value=0x0 */
+    MFX(0x0000020d, "IA32_MTRR_PHYS_MASK6", Ia32MtrrPhysMaskN, Ia32MtrrPhysMaskN, 0x6, 0, UINT64_C(0xfffffff0000007ff)), /* value=0x0 */
+    MFX(0x0000020e, "IA32_MTRR_PHYS_BASE7", Ia32MtrrPhysBaseN, Ia32MtrrPhysBaseN, 0x7, 0, UINT64_C(0xfffffff000000ff8)), /* value=0x0 */
+    MFX(0x0000020f, "IA32_MTRR_PHYS_MASK7", Ia32MtrrPhysMaskN, Ia32MtrrPhysMaskN, 0x7, 0, UINT64_C(0xfffffff0000007ff)), /* value=0x0 */
     MFX(0x00000210, "IA32_MTRR_PHYS_BASE8", Ia32MtrrPhysBaseN, Ia32MtrrPhysBaseN, 0x8, 0, UINT64_C(0xfffffff000000ff8)), /* value=0x0 */
     MFX(0x00000211, "IA32_MTRR_PHYS_MASK8", Ia32MtrrPhysMaskN, Ia32MtrrPhysMaskN, 0x8, 0, UINT64_C(0xfffffff0000007ff)), /* value=0x0 */
     MFX(0x00000212, "IA32_MTRR_PHYS_BASE9", Ia32MtrrPhysBaseN, Ia32MtrrPhysBaseN, 0x9, 0, UINT64_C(0xfffffff000000ff8)), /* value=0x0 */
@@ -161,7 +162,7 @@ static CPUMMSRRANGE const g_aMsrRanges_Intel_Core_i5_3570[] =
     MFS(0x00000277, "IA32_PAT", Ia32Pat, Ia32Pat, Guest.msrPAT),
     RSN(0x00000280, 0x00000281, "IA32_MC0_CTLn", Ia32McNCtl2, Ia32McNCtl2, 0x0, 0, UINT64_C(0xffffffffbfff8000)),
     MFX(0x00000282, "IA32_MC2_CTL2", Ia32McNCtl2, Ia32McNCtl2, 0x2, 0x40007fff, UINT64_C(0xffffffffbfff8000)), /* value=0x0 */
-    MFX(0x00000283, "IA32_MC3_CTL2", Ia32McNCtl2, Ia32McNCtl2, 0x3, 0, UINT64_C(0xffffffffbfff8000)), /* value=0x40000001 */
+    MFX(0x00000283, "IA32_MC3_CTL2", Ia32McNCtl2, Ia32McNCtl2, 0x3, 0, UINT64_C(0xffffffffbfff8000)), /* value=0x0 */
     MFX(0x00000284, "IA32_MC4_CTL2", Ia32McNCtl2, Ia32McNCtl2, 0x4, 0x40007fff, UINT64_C(0xffffffffbfff8000)), /* value=0x0 */
     RSN(0x00000285, 0x00000288, "IA32_MC5_CTLn", Ia32McNCtl2, Ia32McNCtl2, 0x5, 0, UINT64_C(0xffffffffbfff8000)),
     MVX(0x000002e0, "I7_SB_NO_EVICT_MODE", 0, 0, UINT64_C(0xfffffffffffffffc)),
@@ -169,30 +170,28 @@ static CPUMMSRRANGE const g_aMsrRanges_Intel_Core_i5_3570[] =
     MVX(0x000002e7, "I7_IB_UNK_0000_02e7", 0x1, 0x1, UINT64_C(0xfffffffffffffffe)),
     MFZ(0x000002ff, "IA32_MTRR_DEF_TYPE", Ia32MtrrDefType, Ia32MtrrDefType, GuestMsrs.msr.MtrrDefType, 0, UINT64_C(0xfffffffffffff3f8)),
     MVO(0x00000305, "I7_SB_UNK_0000_0305", 0),
-    MFX(0x00000309, "IA32_FIXED_CTR0", Ia32FixedCtrN, Ia32FixedCtrN, 0x0, 0, UINT64_C(0xffff000000000000)), /* value=0x46 */
-    MFX(0x0000030a, "IA32_FIXED_CTR1", Ia32FixedCtrN, Ia32FixedCtrN, 0x1, 0x816506, UINT64_C(0xffff000000000000)), /* value=0xffff`d65aa6fb */
-    MFX(0x0000030b, "IA32_FIXED_CTR2", Ia32FixedCtrN, Ia32FixedCtrN, 0x2, 0, UINT64_C(0xffff000000000000)), /* value=0x264 */
+    RSN(0x00000309, 0x0000030b, "IA32_FIXED_CTRn", Ia32FixedCtrN, Ia32FixedCtrN, 0x0, 0, UINT64_C(0xffff000000000000)),
     MFX(0x00000345, "IA32_PERF_CAPABILITIES", Ia32PerfCapabilities, ReadOnly, 0x31c3, 0, 0), /* value=0x31c3 */
-    MFX(0x0000038d, "IA32_FIXED_CTR_CTRL", Ia32FixedCtrCtrl, Ia32FixedCtrCtrl, 0, 0, UINT64_C(0xfffffffffffff000)), /* value=0xb0 */
+    MFX(0x0000038d, "IA32_FIXED_CTR_CTRL", Ia32FixedCtrCtrl, Ia32FixedCtrCtrl, 0, 0, UINT64_C(0xfffffffffffff000)), /* value=0x0 */
     MFX(0x0000038e, "IA32_PERF_GLOBAL_STATUS", Ia32PerfGlobalStatus, ReadOnly, 0, 0, 0), /* value=0x0 */
-    MFX(0x0000038f, "IA32_PERF_GLOBAL_CTRL", Ia32PerfGlobalCtrl, Ia32PerfGlobalCtrl, 0, 0, UINT64_C(0xfffffff8ffffff00)), /* value=0x7`000000ff */
-    MFX(0x00000390, "IA32_PERF_GLOBAL_OVF_CTRL", Ia32PerfGlobalOvfCtrl, Ia32PerfGlobalOvfCtrl, 0, UINT64_C(0xe0000007000000ff), UINT64_C(0x1ffffff8ffffff00)), /* value=0x0 */
-    MFX(0x00000391, "I7_UNC_PERF_GLOBAL_CTRL", IntelI7UncPerfGlobalCtrl, IntelI7UncPerfGlobalCtrl, 0, 0, UINT64_C(0xffffffff1fffffe0)), /* value=0x2000000f */
+    MFX(0x0000038f, "IA32_PERF_GLOBAL_CTRL", Ia32PerfGlobalCtrl, Ia32PerfGlobalCtrl, 0, 0, UINT64_C(0xfffffff8fffffff0)), /* value=0xf */
+    MFX(0x00000390, "IA32_PERF_GLOBAL_OVF_CTRL", Ia32PerfGlobalOvfCtrl, Ia32PerfGlobalOvfCtrl, 0, UINT64_C(0xe00000070000000f), UINT64_C(0x1ffffff8fffffff0)), /* value=0x0 */
+    MFX(0x00000391, "I7_UNC_PERF_GLOBAL_CTRL", IntelI7UncPerfGlobalCtrl, IntelI7UncPerfGlobalCtrl, 0, 0, UINT64_C(0xffffffff1fffffe0)), /* value=0x0 */
     MFX(0x00000392, "I7_UNC_PERF_GLOBAL_STATUS", IntelI7UncPerfGlobalStatus, IntelI7UncPerfGlobalStatus, 0, 0xf, UINT64_C(0xfffffffffffffff0)), /* value=0x0 */
     MFX(0x00000393, "I7_UNC_PERF_GLOBAL_OVF_CTRL", IntelI7UncPerfGlobalOvfCtrl, IntelI7UncPerfGlobalOvfCtrl, 0, 0x3, UINT64_C(0xfffffffffffffffc)), /* value=0x0 */
     MFX(0x00000394, "I7_UNC_PERF_FIXED_CTR_CTRL", IntelI7UncPerfFixedCtrCtrl, IntelI7UncPerfFixedCtrCtrl, 0, 0, UINT64_C(0xffffffffffafffff)), /* value=0x0 */
-    MFX(0x00000395, "I7_UNC_PERF_FIXED_CTR", IntelI7UncPerfFixedCtr, IntelI7UncPerfFixedCtr, 0, 0, UINT64_C(0xffff000000000000)), /* value=0x1950 */
+    MFX(0x00000395, "I7_UNC_PERF_FIXED_CTR", IntelI7UncPerfFixedCtr, IntelI7UncPerfFixedCtr, 0, 0, UINT64_C(0xffff000000000000)), /* value=0x0 */
     MFO(0x00000396, "I7_UNC_CBO_CONFIG", IntelI7UncCBoxConfig), /* value=0x5 */
-    MVX(0x00000397, "I7_IB_UNK_0000_0397", 0, 0, UINT64_C(0xfffffffffffffff0)),
+    MVX(0x00000397, "I7_SB_UNK_0000_0397", 0, 0, UINT64_C(0xfffffffffffffff0)),
     MFX(0x000003b0, "I7_UNC_ARB_PERF_CTR0", IntelI7UncArbPerfCtrN, IntelI7UncArbPerfCtrN, 0, 0, UINT64_C(0xfffff00000000000)), /* value=0x0 */
     MFX(0x000003b1, "I7_UNC_ARB_PERF_CTR1", IntelI7UncArbPerfCtrN, IntelI7UncArbPerfCtrN, 0, 0, UINT64_C(0xfffff00000000000)), /* value=0x0 */
-    MFX(0x000003b2, "I7_UNC_ARB_PERF_EVT_SEL0", IntelI7UncArbPerfEvtSelN, IntelI7UncArbPerfEvtSelN, 0, 0, UINT64_C(0xffffffffc0230000)), /* value=0x0 */
-    MFX(0x000003b3, "I7_UNC_ARB_PERF_EVT_SEL1", IntelI7UncArbPerfEvtSelN, IntelI7UncArbPerfEvtSelN, 0, 0, UINT64_C(0xffffffffc0230000)), /* value=0x0 */
+    MFX(0x000003b2, "I7_UNC_ARB_PERF_EVT_SEL0", IntelI7UncArbPerfEvtSelN, IntelI7UncArbPerfEvtSelN, 0, 0, UINT64_C(0xffffffffe0230000)), /* value=0x0 */
+    MFX(0x000003b3, "I7_UNC_ARB_PERF_EVT_SEL1", IntelI7UncArbPerfEvtSelN, IntelI7UncArbPerfEvtSelN, 0, 0, UINT64_C(0xffffffffe0230000)), /* value=0x0 */
     MFX(0x000003f1, "IA32_PEBS_ENABLE", Ia32PebsEnable, Ia32PebsEnable, 0, 0, UINT64_C(0x7ffffff0fffffff0)), /* value=0x0 */
     MFX(0x000003f6, "I7_MSR_PEBS_LD_LAT", IntelI7PebsLdLat, IntelI7PebsLdLat, 0, UINT64_C(0xffffffffffff0000), 0), /* value=0xffff */
-    MFX(0x000003f8, "I7_MSR_PKG_C3_RESIDENCY", IntelI7PkgCnResidencyN, ReadOnly, 0x3, 0, UINT64_MAX), /* value=0x7`7827f19a */
+    MFX(0x000003f8, "I7_MSR_PKG_C3_RESIDENCY", IntelI7PkgCnResidencyN, ReadOnly, 0x3, 0, UINT64_MAX), /* value=0x0 */
     RSN(0x000003f9, 0x000003fa, "I7_MSR_PKG_Cn_RESIDENCY", IntelI7PkgCnResidencyN, ReadOnly, 0x6, 0, UINT64_MAX),
-    MFX(0x000003fc, "I7_MSR_CORE_C3_RESIDENCY", IntelI7CoreCnResidencyN, ReadOnly, 0x3, 0, UINT64_MAX), /* value=0x1`3e604592 */
+    MFX(0x000003fc, "I7_MSR_CORE_C3_RESIDENCY", IntelI7CoreCnResidencyN, ReadOnly, 0x3, 0, UINT64_MAX), /* value=0x278ad50 */
     RSN(0x000003fd, 0x000003fe, "I7_MSR_CORE_Cn_RESIDENCY", IntelI7CoreCnResidencyN, ReadOnly, 0x6, 0, UINT64_MAX),
     RFN(0x00000400, 0x00000423, "IA32_MCi_CTL_STATUS_ADDR_MISC", Ia32McCtlStatusAddrMiscN, Ia32McCtlStatusAddrMiscN),
     MFX(0x00000480, "IA32_VMX_BASIC", Ia32VmxBase, ReadOnly, UINT64_C(0xda040000000010), 0, 0), /* value=0xda0400`00000010 */
@@ -204,131 +203,124 @@ static CPUMMSRRANGE const g_aMsrRanges_Intel_Core_i5_3570[] =
     MFX(0x00000486, "IA32_VMX_CR0_FIXED0", Ia32VmxCr0Fixed0, ReadOnly, UINT32_C(0x80000021), 0, 0), /* value=0x80000021 */
     MFX(0x00000487, "IA32_VMX_CR0_FIXED1", Ia32VmxCr0Fixed1, ReadOnly, UINT32_MAX, 0, 0), /* value=0xffffffff */
     MFX(0x00000488, "IA32_VMX_CR4_FIXED0", Ia32VmxCr4Fixed0, ReadOnly, 0x2000, 0, 0), /* value=0x2000 */
-    MFX(0x00000489, "IA32_VMX_CR4_FIXED1", Ia32VmxCr4Fixed1, ReadOnly, 0x1767ff, 0, 0), /* value=0x1767ff */
+    MFX(0x00000489, "IA32_VMX_CR4_FIXED1", Ia32VmxCr4Fixed1, ReadOnly, 0x627ff, 0, 0), /* value=0x627ff */
     MFX(0x0000048a, "IA32_VMX_VMCS_ENUM", Ia32VmxVmcsEnum, ReadOnly, 0x2a, 0, 0), /* value=0x2a */
-    MFX(0x0000048b, "IA32_VMX_PROCBASED_CTLS2", Ia32VmxProcBasedCtls2, ReadOnly, UINT64_C(0x8ff00000000), 0, 0), /* value=0x8ff`00000000 */
+    MFX(0x0000048b, "IA32_VMX_PROCBASED_CTLS2", Ia32VmxProcBasedCtls2, ReadOnly, UINT64_C(0xff00000000), 0, 0), /* value=0xff`00000000 */
     MFX(0x0000048c, "IA32_VMX_EPT_VPID_CAP", Ia32VmxEptVpidCap, ReadOnly, UINT64_C(0xf0106114141), 0, 0), /* value=0xf01`06114141 */
     MFX(0x0000048d, "IA32_VMX_TRUE_PINBASED_CTLS", Ia32VmxTruePinbasedCtls, ReadOnly, UINT64_C(0x7f00000016), 0, 0), /* value=0x7f`00000016 */
     MFX(0x0000048e, "IA32_VMX_TRUE_PROCBASED_CTLS", Ia32VmxTrueProcbasedCtls, ReadOnly, UINT64_C(0xfff9fffe04006172), 0, 0), /* value=0xfff9fffe`04006172 */
     MFX(0x0000048f, "IA32_VMX_TRUE_EXIT_CTLS", Ia32VmxTrueExitCtls, ReadOnly, UINT64_C(0x7fffff00036dfb), 0, 0), /* value=0x7fffff`00036dfb */
     MFX(0x00000490, "IA32_VMX_TRUE_ENTRY_CTLS", Ia32VmxTrueEntryCtls, ReadOnly, UINT64_C(0xffff000011fb), 0, 0), /* value=0xffff`000011fb */
-    RSN(0x000004c1, 0x000004c8, "IA32_A_PMCn", Ia32PmcN, Ia32PmcN, 0x0, 0, UINT64_C(0xffff000000000000)),
-    MFX(0x00000600, "IA32_DS_AREA", Ia32DsArea, Ia32DsArea, 0, 0, UINT64_C(0xffff800000000000)), /* value=0xffff8804`07da1cc0 */
-    MFX(0x00000601, "I7_SB_MSR_VR_CURRENT_CONFIG", IntelI7SandyVrCurrentConfig, IntelI7SandyVrCurrentConfig, 0, UINT32_C(0x80001fff), 0x7fffe000), /* value=0x18141494`80000380 */
-    MVX(0x00000602, "I7_IB_UNK_0000_0602", UINT64_C(0x1814149480000170), UINT32_C(0x80001fff), 0x7fffe000),
-    MFX(0x00000603, "I7_SB_MSR_VR_MISC_CONFIG", IntelI7SandyVrMiscConfig, IntelI7SandyVrMiscConfig, 0, UINT32_C(0x80ffffff), UINT64_C(0xffffffff7f000000)), /* value=0x802c2c2c */
-    MVX(0x00000604, "I7_IB_UNK_0000_0602", UINT32_C(0x80686868), UINT32_C(0x80ffffff), UINT64_C(0xffffffff7f000000)),
+    RSN(0x000004c1, 0x000004c4, "IA32_A_PMCn", Ia32PmcN, Ia32PmcN, 0x0, 0, UINT64_C(0xffff000000000000)),
+    MVO(0x00000502, "I7_SB_UNK_0000_0502", 0),
+    MFN(0x00000600, "IA32_DS_AREA", Ia32DsArea, Ia32DsArea), /* value=0x0 */
+    MFX(0x00000601, "I7_SB_MSR_VR_CURRENT_CONFIG", IntelI7SandyVrCurrentConfig, IntelI7SandyVrCurrentConfig, 0, UINT32_C(0x80001fff), 0x7fffe000), /* value=0x18141494`8000030c */
+    MVX(0x00000602, "I7_IB_UNK_0000_0602", UINT64_C(0x1814149480000104), UINT32_C(0x80001fff), 0x7fffe000),
+    MFX(0x00000603, "I7_SB_MSR_VR_MISC_CONFIG", IntelI7SandyVrMiscConfig, IntelI7SandyVrMiscConfig, 0, UINT32_C(0x80ffffff), UINT64_C(0xffffffff7f000000)), /* value=0x80303030 */
+    MVX(0x00000604, "I7_IB_UNK_0000_0602", UINT32_C(0x80646464), UINT32_C(0x80ffffff), UINT64_C(0xffffffff7f000000)),
     MFO(0x00000606, "I7_SB_MSR_RAPL_POWER_UNIT", IntelI7SandyRaplPowerUnit), /* value=0xa1003 */
-    MFX(0x0000060a, "I7_SB_MSR_PKGC3_IRTL", IntelI7SandyPkgCnIrtlN, IntelI7SandyPkgCnIrtlN, 0x3, 0, UINT64_C(0xffffffffffff6000)), /* value=0x883b */
+    MVX(0x00000609, "I7_SB_UNK_0000_0609", 0, 0, UINT64_C(0xffffffffffffff00)),
+    MFX(0x0000060a, "I7_SB_MSR_PKGC3_IRTL", IntelI7SandyPkgCnIrtlN, IntelI7SandyPkgCnIrtlN, 0x3, 0, UINT64_C(0xffffffffffff6000)), /* value=0x8c02 */
     RSN(0x0000060b, 0x0000060c, "I7_SB_MSR_PKGC6_IRTn", IntelI7SandyPkgCnIrtlN, IntelI7SandyPkgCnIrtlN, 0x6, 0, UINT64_C(0xffffffffffff6000)),
-    MFO(0x0000060d, "I7_SB_MSR_PKG_C2_RESIDENCY", IntelI7SandyPkgC2Residency), /* value=0x76c`bd67b914 */
-    MFX(0x00000610, "I7_SB_MSR_PKG_POWER_LIMIT", IntelI7RaplPkgPowerLimit, IntelI7RaplPkgPowerLimit, 0, UINT64_C(0x80ffffff00ffffff), UINT64_C(0x7f000000ff000000)), /* value=0x80008302`00148268 */
-    MFO(0x00000611, "I7_SB_MSR_PKG_ENERGY_STATUS", IntelI7RaplPkgEnergyStatus), /* value=0x3451b969 */
-    MFO(0x00000614, "I7_SB_MSR_PKG_POWER_INFO", IntelI7RaplPkgPowerInfo), /* value=0xd0000`01e00268 */
+    MFO(0x0000060d, "I7_SB_MSR_PKG_C2_RESIDENCY", IntelI7SandyPkgC2Residency), /* value=0x11`06f311d4 */
+    MFX(0x00000610, "I7_SB_MSR_PKG_POWER_LIMIT", IntelI7RaplPkgPowerLimit, IntelI7RaplPkgPowerLimit, 0, UINT64_C(0x80ffffff00ffffff), UINT64_C(0x7f000000ff000000)), /* value=0x800001c2`00dc8168 */
+    MFO(0x00000611, "I7_SB_MSR_PKG_ENERGY_STATUS", IntelI7RaplPkgEnergyStatus), /* value=0x55a9ec99 */
+    MFO(0x00000614, "I7_SB_MSR_PKG_POWER_INFO", IntelI7RaplPkgPowerInfo), /* value=0x100240`01200168 */
     MFX(0x00000638, "I7_SB_MSR_PP0_POWER_LIMIT", IntelI7RaplPp0PowerLimit, IntelI7RaplPp0PowerLimit, 0, UINT32_C(0x80ffffff), UINT64_C(0xffffffff7f000000)), /* value=0x80000000 */
-    MFO(0x00000639, "I7_SB_MSR_PP0_ENERGY_STATUS", IntelI7RaplPp0EnergyStatus), /* value=0x357de52e */
+    MFO(0x00000639, "I7_SB_MSR_PP0_ENERGY_STATUS", IntelI7RaplPp0EnergyStatus), /* value=0x1dcdc9a0 */
     MFX(0x0000063a, "I7_SB_MSR_PP0_POLICY", IntelI7RaplPp0Policy, IntelI7RaplPp0Policy, 0, 0, UINT64_C(0xffffffffffffffe0)), /* value=0x0 */
     MFX(0x00000640, "I7_HW_MSR_PP0_POWER_LIMIT", IntelI7RaplPp1PowerLimit, IntelI7RaplPp1PowerLimit, 0, UINT32_C(0x80ffffff), UINT64_C(0xffffffff7f000000)), /* value=0x80000000 */
-    MFO(0x00000641, "I7_HW_MSR_PP0_ENERGY_STATUS", IntelI7RaplPp1EnergyStatus), /* value=0x6eeef */
+    MFO(0x00000641, "I7_HW_MSR_PP0_ENERGY_STATUS", IntelI7RaplPp1EnergyStatus), /* value=0x39748b6 */
     MFX(0x00000642, "I7_HW_MSR_PP0_POLICY", IntelI7RaplPp1Policy, IntelI7RaplPp1Policy, 0, 0, UINT64_C(0xffffffffffffffe0)), /* value=0x10 */
-    MFO(0x00000648, "I7_IB_MSR_CONFIG_TDP_NOMINAL", IntelI7IvyConfigTdpNominal), /* value=0x22 */
-    MFO(0x00000649, "I7_IB_MSR_CONFIG_TDP_LEVEL1", IntelI7IvyConfigTdpLevel1), /* value=0x1e00000`00000000 */
-    MFO(0x0000064a, "I7_IB_MSR_CONFIG_TDP_LEVEL2", IntelI7IvyConfigTdpLevel2), /* value=0x1e00000`00000000 */
-    MFO(0x0000064b, "I7_IB_MSR_CONFIG_TDP_CONTROL", IntelI7IvyConfigTdpControl), /* value=0x80000000 */
-    MFX(0x0000064c, "I7_IB_MSR_TURBO_ACTIVATION_RATIO", IntelI7IvyTurboActivationRatio, IntelI7IvyTurboActivationRatio, 0, 0, UINT64_C(0xffffffff7fffff00)), /* value=0x80000000 */
     RFN(0x00000680, 0x0000068f, "MSR_LASTBRANCH_n_FROM_IP", IntelLastBranchFromN, IntelLastBranchFromN),
-    RFN(0x000006c0, 0x000006cf, "MSR_LASTBRANCH_n_TO_IP", IntelLastBranchFromN, IntelLastBranchFromN),
-    MFX(0x000006e0, "IA32_TSC_DEADLINE", Ia32TscDeadline, Ia32TscDeadline, 0, UINT64_C(0xb280452208b), 0), /* value=0x4293`ef1535a6 */
-    MVX(0x00000700, "I7_IB_UNK_0000_0700", 0, 0, UINT64_C(0xffffffffe0230000)),
-    MVX(0x00000701, "I7_IB_UNK_0000_0701", 0, 0, UINT64_C(0xffffffffe0230000)),
-    MVX(0x00000702, "I7_IB_UNK_0000_0702", 0, 0, UINT64_C(0xffffffffe0230000)),
-    MVX(0x00000703, "I7_IB_UNK_0000_0703", 0, 0, UINT64_C(0xffffffffe0230000)),
-    MVX(0x00000704, "I7_IB_UNK_0000_0704", 0, 0, UINT64_C(0xfffffffffffffff0)),
-    MVX(0x00000705, "I7_IB_UNK_0000_0705", 0, 0xf, UINT64_C(0xfffffffffffffff0)),
-    MVX(0x00000706, "I7_IB_UNK_0000_0706", 0, 0, UINT64_C(0xfffff00000000000)),
-    MVX(0x00000707, "I7_IB_UNK_0000_0707", 0, 0, UINT64_C(0xfffff00000000000)),
-    MVX(0x00000708, "I7_IB_UNK_0000_0708", 0, 0, UINT64_C(0xfffff00000000000)),
-    MVX(0x00000709, "I7_IB_UNK_0000_0709", 0, 0, UINT64_C(0xfffff00000000000)),
-    MVX(0x00000710, "I7_IB_UNK_0000_0710", 0, 0, UINT64_C(0xffffffffe0230000)),
-    MVX(0x00000711, "I7_IB_UNK_0000_0711", 0, 0, UINT64_C(0xffffffffe0230000)),
-    MVX(0x00000712, "I7_IB_UNK_0000_0712", 0, 0, UINT64_C(0xffffffffe0230000)),
-    MVX(0x00000713, "I7_IB_UNK_0000_0713", 0, 0, UINT64_C(0xffffffffe0230000)),
-    MVX(0x00000714, "I7_IB_UNK_0000_0714", 0, 0, UINT64_C(0xfffffffffffffff0)),
-    MVX(0x00000715, "I7_IB_UNK_0000_0715", 0, 0xf, UINT64_C(0xfffffffffffffff0)),
-    MVX(0x00000716, "I7_IB_UNK_0000_0716", 0, 0, UINT64_C(0xfffff00000000000)),
-    MVX(0x00000717, "I7_IB_UNK_0000_0717", 0, 0, UINT64_C(0xfffff00000000000)),
-    MVX(0x00000718, "I7_IB_UNK_0000_0718", 0, 0, UINT64_C(0xfffff00000000000)),
-    MVX(0x00000719, "I7_IB_UNK_0000_0719", 0, 0, UINT64_C(0xfffff00000000000)),
-    MVX(0x00000720, "I7_IB_UNK_0000_0720", 0, 0, UINT64_C(0xffffffffe0230000)),
-    MVX(0x00000721, "I7_IB_UNK_0000_0721", 0, 0, UINT64_C(0xffffffffe0230000)),
-    MVX(0x00000722, "I7_IB_UNK_0000_0722", 0, 0, UINT64_C(0xffffffffe0230000)),
-    MVX(0x00000723, "I7_IB_UNK_0000_0723", 0, 0, UINT64_C(0xffffffffe0230000)),
-    MVX(0x00000724, "I7_IB_UNK_0000_0724", 0, 0, UINT64_C(0xfffffffffffffff0)),
-    MVX(0x00000725, "I7_IB_UNK_0000_0725", 0, 0xf, UINT64_C(0xfffffffffffffff0)),
-    MVX(0x00000726, "I7_IB_UNK_0000_0726", 0, 0, UINT64_C(0xfffff00000000000)),
-    MVX(0x00000727, "I7_IB_UNK_0000_0727", 0, 0, UINT64_C(0xfffff00000000000)),
-    MVX(0x00000728, "I7_IB_UNK_0000_0728", 0, 0, UINT64_C(0xfffff00000000000)),
-    MVX(0x00000729, "I7_IB_UNK_0000_0729", 0, 0, UINT64_C(0xfffff00000000000)),
-    MVX(0x00000730, "I7_IB_UNK_0000_0730", 0, 0, UINT64_C(0xffffffffe0230000)),
-    MVX(0x00000731, "I7_IB_UNK_0000_0731", 0, 0, UINT64_C(0xffffffffe0230000)),
-    MVX(0x00000732, "I7_IB_UNK_0000_0732", 0, 0, UINT64_C(0xffffffffe0230000)),
-    MVX(0x00000733, "I7_IB_UNK_0000_0733", 0, 0, UINT64_C(0xffffffffe0230000)),
-    MVX(0x00000734, "I7_IB_UNK_0000_0734", 0, 0, UINT64_C(0xfffffffffffffff0)),
-    MVX(0x00000735, "I7_IB_UNK_0000_0735", 0, 0xf, UINT64_C(0xfffffffffffffff0)),
-    MVX(0x00000736, "I7_IB_UNK_0000_0736", 0, 0, UINT64_C(0xfffff00000000000)),
-    MVX(0x00000737, "I7_IB_UNK_0000_0737", 0, 0, UINT64_C(0xfffff00000000000)),
-    MVX(0x00000738, "I7_IB_UNK_0000_0738", 0, 0, UINT64_C(0xfffff00000000000)),
-    MVX(0x00000739, "I7_IB_UNK_0000_0739", 0, 0, UINT64_C(0xfffff00000000000)),
-    MVX(0x00000740, "I7_IB_UNK_0000_0740", 0, 0, UINT64_C(0xffffffffe0230000)),
-    MVX(0x00000741, "I7_IB_UNK_0000_0741", 0, 0, UINT64_C(0xffffffffe0230000)),
-    MVX(0x00000742, "I7_IB_UNK_0000_0742", 0, 0, UINT64_C(0xffffffffe0230000)),
-    MVX(0x00000743, "I7_IB_UNK_0000_0743", 0, 0, UINT64_C(0xffffffffe0230000)),
-    MVX(0x00000744, "I7_IB_UNK_0000_0744", 0, 0, UINT64_C(0xfffffffffffffff0)),
-    MVX(0x00000745, "I7_IB_UNK_0000_0745", 0, 0xf, UINT64_C(0xfffffffffffffff0)),
-    MVX(0x00000746, "I7_IB_UNK_0000_0746", 0, 0, UINT64_C(0xfffff00000000000)),
-    MVX(0x00000747, "I7_IB_UNK_0000_0747", 0, 0, UINT64_C(0xfffff00000000000)),
-    MVX(0x00000748, "I7_IB_UNK_0000_0748", 0, 0, UINT64_C(0xfffff00000000000)),
-    MVX(0x00000749, "I7_IB_UNK_0000_0749", 0, 0, UINT64_C(0xfffff00000000000)),
-    RFN(0x00000800, 0x000008ff, "IA32_X2APIC_n", Ia32X2ApicN, Ia32X2ApicN),
-    MFN(0x00000c80, "IA32_DEBUG_INTERFACE", Ia32DebugInterface, Ia32DebugInterface), /* value=0x0 */
-    MVX(0x00000c81, "I7_IB_UNK_0000_0c81", 0, 0, 0),
-    MVX(0x00000c82, "I7_IB_UNK_0000_0c82", 0, ~(uint64_t)UINT32_MAX, 0),
-    MVX(0x00000c83, "I7_IB_UNK_0000_0c83", 0, ~(uint64_t)UINT32_MAX, 0),
+    RFN(0x000006c0, 0x000006cf, "MSR_LASTBRANCH_n_TO_IP", IntelLastBranchToN, IntelLastBranchToN),
+    MFX(0x000006e0, "IA32_TSC_DEADLINE", Ia32TscDeadline, Ia32TscDeadline, 0, UINT64_C(0x1000000018), 0), /* value=0x94d`402e841f */
+    MVX(0x00000700, "MSR_UNC_CBO_0_PERFEVTSEL0", 0, 0, UINT64_C(0xffffffffe0230000)),
+    MVX(0x00000701, "MSR_UNC_CBO_0_PERFEVTSEL1", 0, 0, UINT64_C(0xffffffffe0230000)),
+    MVX(0x00000702, "MSR_UNC_CBO_0_PERFEVTSEL2?", 0, 0, UINT64_C(0xffffffffe0230000)),
+    MVX(0x00000703, "MSR_UNC_CBO_0_PERFEVTSEL3?", 0, 0, UINT64_C(0xffffffffe0230000)),
+    MVX(0x00000704, "MSR_UNC_CBO_0_UNK_4", 0, 0, UINT64_C(0xfffffffffffffff0)),
+    MVX(0x00000705, "MSR_UNC_CBO_0_UNK_5", 0, 0xf, UINT64_C(0xfffffffffffffff0)),
+    MVX(0x00000706, "MSR_UNC_CBO_0_PER_CTR0", 0, 0, UINT64_C(0xfffff00000000000)),
+    MVX(0x00000707, "MSR_UNC_CBO_0_PER_CTR1", 0, 0, UINT64_C(0xfffff00000000000)),
+    MVX(0x00000708, "MSR_UNC_CBO_0_PER_CTR2?", 0, 0, UINT64_C(0xfffff00000000000)),
+    MVX(0x00000709, "MSR_UNC_CBO_0_PER_CTR3?", 0, 0, UINT64_C(0xfffff00000000000)),
+    MVX(0x00000710, "MSR_UNC_CBO_1_PERFEVTSEL0", 0, 0, UINT64_C(0xffffffffe0230000)),
+    MVX(0x00000711, "MSR_UNC_CBO_1_PERFEVTSEL1", 0, 0, UINT64_C(0xffffffffe0230000)),
+    MVX(0x00000712, "MSR_UNC_CBO_1_PERFEVTSEL2?", 0, 0, UINT64_C(0xffffffffe0230000)),
+    MVX(0x00000713, "MSR_UNC_CBO_1_PERFEVTSEL3?", 0, 0, UINT64_C(0xffffffffe0230000)),
+    MVX(0x00000714, "MSR_UNC_CBO_1_UNK_4", 0, 0, UINT64_C(0xfffffffffffffff0)),
+    MVX(0x00000715, "MSR_UNC_CBO_1_UNK_5", 0, 0xf, UINT64_C(0xfffffffffffffff0)),
+    MVX(0x00000716, "MSR_UNC_CBO_1_PER_CTR0", 0, 0, UINT64_C(0xfffff00000000000)),
+    MVX(0x00000717, "MSR_UNC_CBO_1_PER_CTR1", 0, 0, UINT64_C(0xfffff00000000000)),
+    MVX(0x00000718, "MSR_UNC_CBO_1_PER_CTR2?", 0, 0, UINT64_C(0xfffff00000000000)),
+    MVX(0x00000719, "MSR_UNC_CBO_1_PER_CTR3?", 0, 0, UINT64_C(0xfffff00000000000)),
+    MVX(0x00000720, "MSR_UNC_CBO_2_PERFEVTSEL0", 0, 0, UINT64_C(0xffffffffe0230000)),
+    MVX(0x00000721, "MSR_UNC_CBO_2_PERFEVTSEL1", 0, 0, UINT64_C(0xffffffffe0230000)),
+    MVX(0x00000722, "MSR_UNC_CBO_2_PERFEVTSEL2?", 0, 0, UINT64_C(0xffffffffe0230000)),
+    MVX(0x00000723, "MSR_UNC_CBO_2_PERFEVTSEL3?", 0, 0, UINT64_C(0xffffffffe0230000)),
+    MVX(0x00000724, "MSR_UNC_CBO_2_UNK_4", 0, 0, UINT64_C(0xfffffffffffffff0)),
+    MVX(0x00000725, "MSR_UNC_CBO_2_UNK_5", 0, 0xf, UINT64_C(0xfffffffffffffff0)),
+    MVX(0x00000726, "MSR_UNC_CBO_2_PER_CTR0", 0, 0, UINT64_C(0xfffff00000000000)),
+    MVX(0x00000727, "MSR_UNC_CBO_2_PER_CTR1", 0, 0, UINT64_C(0xfffff00000000000)),
+    MVX(0x00000728, "MSR_UNC_CBO_2_PER_CTR2?", 0, 0, UINT64_C(0xfffff00000000000)),
+    MVX(0x00000729, "MSR_UNC_CBO_2_PER_CTR3?", 0, 0, UINT64_C(0xfffff00000000000)),
+    MVX(0x00000730, "MSR_UNC_CBO_3_PERFEVTSEL0", 0, 0, UINT64_C(0xffffffffe0230000)),
+    MVX(0x00000731, "MSR_UNC_CBO_3_PERFEVTSEL1", 0, 0, UINT64_C(0xffffffffe0230000)),
+    MVX(0x00000732, "MSR_UNC_CBO_3_PERFEVTSEL2?", 0, 0, UINT64_C(0xffffffffe0230000)),
+    MVX(0x00000733, "MSR_UNC_CBO_3_PERFEVTSEL3?", 0, 0, UINT64_C(0xffffffffe0230000)),
+    MVX(0x00000734, "MSR_UNC_CBO_3_UNK_4", 0, 0, UINT64_C(0xfffffffffffffff0)),
+    MVX(0x00000735, "MSR_UNC_CBO_3_UNK_5", 0, 0xf, UINT64_C(0xfffffffffffffff0)),
+    MVX(0x00000736, "MSR_UNC_CBO_3_PER_CTR0", 0, 0, UINT64_C(0xfffff00000000000)),
+    MVX(0x00000737, "MSR_UNC_CBO_3_PER_CTR1", 0, 0, UINT64_C(0xfffff00000000000)),
+    MVX(0x00000738, "MSR_UNC_CBO_3_PER_CTR2?", 0, 0, UINT64_C(0xfffff00000000000)),
+    MVX(0x00000739, "MSR_UNC_CBO_3_PER_CTR3?", 0, 0, UINT64_C(0xfffff00000000000)),
+    MVX(0x00000740, "MSR_UNC_CBO_4_PERFEVTSEL0?", 0, 0, UINT64_C(0xffffffffe0230000)),
+    MVX(0x00000741, "MSR_UNC_CBO_4_PERFEVTSEL1?", 0, 0, UINT64_C(0xffffffffe0230000)),
+    MVX(0x00000742, "MSR_UNC_CBO_4_PERFEVTSEL2?", 0, 0, UINT64_C(0xffffffffe0230000)),
+    MVX(0x00000743, "MSR_UNC_CBO_4_PERFEVTSEL3?", 0, 0, UINT64_C(0xffffffffe0230000)),
+    MVX(0x00000744, "MSR_UNC_CBO_4_UNK_4", 0, 0, UINT64_C(0xfffffffffffffff0)),
+    MVX(0x00000745, "MSR_UNC_CBO_4_UNK_5", 0, 0xf, UINT64_C(0xfffffffffffffff0)),
+    MVX(0x00000746, "MSR_UNC_CBO_4_PER_CTR0?", 0, 0, UINT64_C(0xfffff00000000000)),
+    MVX(0x00000747, "MSR_UNC_CBO_4_PER_CTR1?", 0, 0, UINT64_C(0xfffff00000000000)),
+    MVX(0x00000748, "MSR_UNC_CBO_4_PER_CTR2?", 0, 0, UINT64_C(0xfffff00000000000)),
+    MVX(0x00000749, "MSR_UNC_CBO_4_PER_CTR3?", 0, 0, UINT64_C(0xfffff00000000000)),
     MFX(0xc0000080, "AMD64_EFER", Amd64Efer, Amd64Efer, 0xd01, 0x400, UINT64_C(0xfffffffffffff2fe)),
-    MFN(0xc0000081, "AMD64_STAR", Amd64SyscallTarget, Amd64SyscallTarget), /* value=0x230010`00000000 */
-    MFN(0xc0000082, "AMD64_STAR64", Amd64LongSyscallTarget, Amd64LongSyscallTarget), /* value=0xffffffff`8159b620 */
-    MFN(0xc0000083, "AMD64_STARCOMPAT", Amd64CompSyscallTarget, Amd64CompSyscallTarget), /* value=0xffffffff`8159ce10 */
-    MFX(0xc0000084, "AMD64_SYSCALL_FLAG_MASK", Amd64SyscallFlagMask, Amd64SyscallFlagMask, 0, ~(uint64_t)UINT32_MAX, 0), /* value=0x43700 */
-    MFN(0xc0000100, "AMD64_FS_BASE", Amd64FsBase, Amd64FsBase), /* value=0x908880 */
-    MFN(0xc0000101, "AMD64_GS_BASE", Amd64GsBase, Amd64GsBase), /* value=0xffff8804`1e200000 */
-    MFN(0xc0000102, "AMD64_KERNEL_GS_BASE", Amd64KernelGsBase, Amd64KernelGsBase), /* value=0x0 */
+    MFN(0xc0000081, "AMD64_STAR", Amd64SyscallTarget, Amd64SyscallTarget), /* value=0x1b0008`00000000 */
+    MFN(0xc0000082, "AMD64_STAR64", Amd64LongSyscallTarget, Amd64LongSyscallTarget), /* value=0xffffff80`222f2fd0 */
+    MFN(0xc0000083, "AMD64_STARCOMPAT", Amd64CompSyscallTarget, Amd64CompSyscallTarget), /* value=0x0 */
+    MFX(0xc0000084, "AMD64_SYSCALL_FLAG_MASK", Amd64SyscallFlagMask, Amd64SyscallFlagMask, 0, ~(uint64_t)UINT32_MAX, 0), /* value=0x4700 */
+    MFN(0xc0000100, "AMD64_FS_BASE", Amd64FsBase, Amd64FsBase), /* value=0x0 */
+    MFN(0xc0000101, "AMD64_GS_BASE", Amd64GsBase, Amd64GsBase), /* value=0xffffff81`0500f000 */
+    MFN(0xc0000102, "AMD64_KERNEL_GS_BASE", Amd64KernelGsBase, Amd64KernelGsBase), /* value=0x7fff`7b14d3f0 */
     MFX(0xc0000103, "AMD64_TSC_AUX", Amd64TscAux, Amd64TscAux, 0, 0, ~(uint64_t)UINT32_MAX), /* value=0x0 */
 };
 #endif /* !CPUM_DB_STANDALONE */
 
 
 /**
- * Database entry for Intel(R) Core(TM) i5-3570 CPU @ 3.40GHz.
+ * Database entry for Intel(R) Core(TM) i7-2635QM CPU @ 2.00GHz.
  */
-static CPUMDBENTRY const g_Entry_Intel_Core_i5_3570 = 
+static CPUMDBENTRY const g_Entry_Intel_Core_i7_2635QM = 
 {
-    /*.pszName          = */ "Intel Core i5-3570",
-    /*.pszFullName      = */ "Intel(R) Core(TM) i5-3570 CPU @ 3.40GHz",
+    /*.pszName          = */ "Intel Core i7-2635QM",
+    /*.pszFullName      = */ "Intel(R) Core(TM) i7-2635QM CPU @ 2.00GHz",
     /*.enmVendor        = */ CPUMCPUVENDOR_INTEL,
     /*.uFamily          = */ 6,
-    /*.uModel           = */ 58,
-    /*.uStepping        = */ 9,
-    /*.enmMicroarch     = */ kCpumMicroarch_Intel_Core7_IvyBridge,
+    /*.uModel           = */ 42,
+    /*.uStepping        = */ 7,
+    /*.enmMicroarch     = */ kCpumMicroarch_Intel_Core7_SandyBridge,
+    /*.uScalableBusFreq = */ CPUM_SBUSFREQ_100MHZ,
     /*.fFlags           = */ 0,
     /*.cMaxPhysAddrWidth= */ 36,
-    /*.paCpuIdLeaves    = */ NULL_ALONE(g_aCpuIdLeaves_Intel_Core_i5_3570),
-    /*.cCpuIdLeaves     = */ ZERO_ALONE(RT_ELEMENTS(g_aCpuIdLeaves_Intel_Core_i5_3570)),
+    /*.paCpuIdLeaves    = */ NULL_ALONE(g_aCpuIdLeaves_Intel_Core_i7_2635QM),
+    /*.cCpuIdLeaves     = */ ZERO_ALONE(RT_ELEMENTS(g_aCpuIdLeaves_Intel_Core_i7_2635QM)),
     /*.enmUnknownCpuId  = */ CPUMUKNOWNCPUID_LAST_STD_LEAF_WITH_ECX,
     /*.DefUnknownCpuId  = */ { 0x00000007, 0x00000340, 0x00000340, 0x00000000 },
     /*.fMsrMask         = */ UINT32_MAX,
-    /*.cMsrRanges       = */ ZERO_ALONE(RT_ELEMENTS(g_aMsrRanges_Intel_Core_i5_3570)),
-    /*.paMsrRanges      = */ NULL_ALONE(g_aMsrRanges_Intel_Core_i5_3570),
+    /*.cMsrRanges       = */ ZERO_ALONE(RT_ELEMENTS(g_aMsrRanges_Intel_Core_i7_2635QM)),
+    /*.paMsrRanges      = */ NULL_ALONE(g_aMsrRanges_Intel_Core_i7_2635QM),
 };
 
-#endif /* !VBOX_DB_Intel_Core_i5_3570 */
+#endif /* !VBOX_DB_Intel_Core_i7_2635QM */
 
diff --git a/src/VBox/VMM/VMMR3/cpus/Intel_Core_i7_3820QM.h b/src/VBox/VMM/VMMR3/cpus/Intel_Core_i7_3820QM.h
index 54dc9cb..0e7905e 100644
--- a/src/VBox/VMM/VMMR3/cpus/Intel_Core_i7_3820QM.h
+++ b/src/VBox/VMM/VMMR3/cpus/Intel_Core_i7_3820QM.h
@@ -63,13 +63,13 @@ static CPUMMSRRANGE const g_aMsrRanges_Intel_Core_i7_3820QM[] =
     MFX(0x00000001, "IA32_P5_MC_TYPE", Ia32P5McType, Ia32P5McType, 0, 0, UINT64_MAX), /* value=0x0 */
     MFX(0x00000006, "IA32_MONITOR_FILTER_LINE_SIZE", Ia32MonitorFilterLineSize, Ia32MonitorFilterLineSize, 0, 0, UINT64_C(0xffffffffffff0000)), /* value=0x40 */
     MFX(0x00000010, "IA32_TIME_STAMP_COUNTER", Ia32TimestampCounter, Ia32TimestampCounter, 0, 0, 0),
-    MVO(0x00000017, "IA32_PLATFORM_ID", UINT64_C(0x10000000000000)),
+    MFV(0x00000017, "IA32_PLATFORM_ID", Ia32PlatformId, ReadOnly, UINT64_C(0x10000000000000)),
     MFX(0x0000001b, "IA32_APIC_BASE", Ia32ApicBase, Ia32ApicBase, UINT32_C(0xfee00900), 0, UINT64_C(0xfffffff0000002ff)),
     MFX(0x0000002a, "EBL_CR_POWERON", IntelEblCrPowerOn, ReadOnly, 0, 0, 0), /* value=0x0 */
     MVX(0x0000002e, "I7_UNK_0000_002e", 0, 0x400, UINT64_C(0xfffffffffffffbff)),
     MVX(0x00000033, "TEST_CTL", 0, 0, UINT64_C(0xffffffff7fffffff)),
     MVO(0x00000034, "P6_UNK_0000_0034", 0xe),
-    MVO(0x00000035, "P6_UNK_0000_0035", 0x40008),
+    MFO(0x00000035, "MSR_CORE_THREAD_COUNT", IntelI7CoreThreadCount), /* value=0x40008*/
     MVO(0x00000036, "I7_UNK_0000_0036", 0x6c405eec),
     MFO(0x0000003a, "IA32_FEATURE_CONTROL", Ia32FeatureControl), /* value=0xff07 */
     MVX(0x0000003e, "I7_UNK_0000_003e", 0, 0, UINT64_C(0xfffffffffffffffe)),
@@ -361,6 +361,7 @@ static CPUMDBENTRY const g_Entry_Intel_Core_i7_3820QM =
     /*.uModel           = */ 58,
     /*.uStepping        = */ 9,
     /*.enmMicroarch     = */ kCpumMicroarch_Intel_Core7_IvyBridge,
+    /*.uScalableBusFreq = */ CPUM_SBUSFREQ_UNKNOWN,
     /*.fFlags           = */ 0,
     /*.cMaxPhysAddrWidth= */ 36,
     /*.paCpuIdLeaves    = */ NULL_ALONE(g_aCpuIdLeaves_Intel_Core_i7_3820QM),
diff --git a/src/VBox/VMM/VMMR3/cpus/Intel_Core_i7_3960X.h b/src/VBox/VMM/VMMR3/cpus/Intel_Core_i7_3960X.h
index 597ec14..6f74686 100644
--- a/src/VBox/VMM/VMMR3/cpus/Intel_Core_i7_3960X.h
+++ b/src/VBox/VMM/VMMR3/cpus/Intel_Core_i7_3960X.h
@@ -72,20 +72,20 @@ static CPUMMSRRANGE const g_aMsrRanges_Intel_Core_i7_3960X[] =
     MFX(0x00000001, "IA32_P5_MC_TYPE", Ia32P5McType, Ia32P5McType, 0, 0, UINT64_MAX), /* value=0x0 */
     MFX(0x00000006, "IA32_MONITOR_FILTER_LINE_SIZE", Ia32MonitorFilterLineSize, Ia32MonitorFilterLineSize, 0, 0, UINT64_C(0xffffffffffff0000)), /* value=0x40 */
     MFN(0x00000010, "IA32_TIME_STAMP_COUNTER", Ia32TimestampCounter, Ia32TimestampCounter), /* value=0x177ab4`48466b19 */
-    MVO(0x00000017, "IA32_PLATFORM_ID", UINT64_C(0x8000000000000)),
+    MFV(0x00000017, "IA32_PLATFORM_ID", Ia32PlatformId, ReadOnly, UINT64_C(0x8000000000000)),
     MFX(0x0000001b, "IA32_APIC_BASE", Ia32ApicBase, Ia32ApicBase, UINT32_C(0xfee00800), 0, UINT64_C(0xffffc000000002ff)),
     MFX(0x0000002a, "EBL_CR_POWERON", IntelEblCrPowerOn, ReadOnly, 0, 0, 0), /* value=0x0 */
     MVX(0x0000002e, "I7_UNK_0000_002e", 0, 0x400, UINT64_C(0xfffffffffffffbff)),
     MVX(0x00000033, "TEST_CTL", 0, 0, UINT64_C(0xffffffff7fffffff)),
     MVO(0x00000034, "P6_UNK_0000_0034", 0x4cb),
-    MVO(0x00000035, "P6_UNK_0000_0035", 0x6000c),
+    MFO(0x00000035, "MSR_CORE_THREAD_COUNT", IntelI7CoreThreadCount), /* value=0x6000c*/
     MFO(0x0000003a, "IA32_FEATURE_CONTROL", Ia32FeatureControl), /* value=0x5 */
     MVX(0x0000003e, "I7_UNK_0000_003e", 0x1, 0, UINT64_C(0xfffffffffffffffe)),
     MFN(0x00000079, "IA32_BIOS_UPDT_TRIG", WriteOnly, Ia32BiosUpdateTrigger),
     MVX(0x0000008b, "BBL_CR_D3|BIOS_SIGN", UINT64_C(0x61600000000), 0, UINT32_C(0xfffffffe)),
     MFO(0x0000009b, "IA32_SMM_MONITOR_CTL", Ia32SmmMonitorCtl), /* value=0x0 */
     RSN(0x000000c1, 0x000000c4, "IA32_PMCn", Ia32PmcN, Ia32PmcN, 0x0, ~(uint64_t)UINT32_MAX, 0),
-    MFO(0x000000ce, "MSR_PLATFORM_INFO", IntelPlatformInfo100MHz), /* value=0xc00'70012100*/
+    MFO(0x000000ce, "MSR_PLATFORM_INFO", IntelPlatformInfo), /* value=0xc00'70012100*/
     MFX(0x000000e2, "MSR_PKG_CST_CONFIG_CONTROL", IntelPkgCStConfigControl, IntelPkgCStConfigControl, 0, 0, UINT64_C(0xffffffffe1ffffff)), /* value=0x1e008400 */
     MFX(0x000000e4, "MSR_PMG_IO_CAPTURE_BASE", IntelPmgIoCaptureBase, IntelPmgIoCaptureBase, 0, 0, UINT64_C(0xfffffffffff80000)), /* value=0x20414 */
     MFN(0x000000e7, "IA32_MPERF", Ia32MPerf, Ia32MPerf), /* value=0x2be98e4 */
@@ -102,7 +102,7 @@ static CPUMMSRRANGE const g_aMsrRanges_Intel_Core_i7_3960X[] =
     MFX(0x0000017a, "IA32_MCG_STATUS", Ia32McgStatus, Ia32McgStatus, 0, 0, UINT64_C(0xfffffffffffffff8)), /* value=0x0 */
     MFX(0x0000017f, "I7_SB_ERROR_CONTROL", IntelI7SandyErrorControl, IntelI7SandyErrorControl, 0, 0xc, UINT64_C(0xffffffffffffffe1)), /* value=0x0 */
     RSN(0x00000186, 0x00000189, "IA32_PERFEVTSELn", Ia32PerfEvtSelN, Ia32PerfEvtSelN, 0x0, 0, UINT64_C(0xffffffff00080000)),
-    MFX(0x00000194, "CLOCK_FLEX_MAX", IntelFlexRatio100MHz, IntelFlexRatio100MHz, 0xf2100, 0xe0000, UINT64_C(0xfffffffffff00000)),
+    MFX(0x00000194, "CLOCK_FLEX_MAX", IntelFlexRatio, IntelFlexRatio, 0xf2100, 0xe0000, UINT64_C(0xfffffffffff00000)),
     MFX(0x00000198, "IA32_PERF_STATUS", Ia32PerfStatus, ReadOnly, UINT64_C(0x288300002400), 0, 0), /* value=0x2883`00002400 */
     MFX(0x00000199, "IA32_PERF_CTL", Ia32PerfCtl, Ia32PerfCtl, 0x2700, 0, 0), /* Might bite. value=0x2700 */
     MFX(0x0000019a, "IA32_CLOCK_MODULATION", Ia32ClockModulation, Ia32ClockModulation, 0, 0, UINT64_C(0xffffffffffffffe0)), /* value=0x0 */
@@ -349,6 +349,7 @@ static CPUMDBENTRY const g_Entry_Intel_Core_i7_3960X =
     /*.uModel           = */ 45,
     /*.uStepping        = */ 6,
     /*.enmMicroarch     = */ kCpumMicroarch_Intel_Core7_SandyBridge,
+    /*.uScalableBusFreq = */ CPUM_SBUSFREQ_100MHZ,
     /*.fFlags           = */ 0,
     /*.cMaxPhysAddrWidth= */ 46,
     /*.paCpuIdLeaves    = */ NULL_ALONE(g_aCpuIdLeaves_Intel_Core_i7_3960X),
diff --git a/src/VBox/VMM/VMMR3/cpus/Intel_Pentium_4_3_00GHz.h b/src/VBox/VMM/VMMR3/cpus/Intel_Pentium_4_3_00GHz.h
index 96fa39c..d272330 100644
--- a/src/VBox/VMM/VMMR3/cpus/Intel_Pentium_4_3_00GHz.h
+++ b/src/VBox/VMM/VMMR3/cpus/Intel_Pentium_4_3_00GHz.h
@@ -57,7 +57,7 @@ static CPUMMSRRANGE const g_aMsrRanges_Intel_Pentium_4_3_00GHz[] =
     MFO(0x00000001, "IA32_P5_MC_TYPE", Ia32P5McType), /* value=0xbe000300`1008081f */
     MFX(0x00000006, "IA32_MONITOR_FILTER_LINE_SIZE", Ia32MonitorFilterLineSize, Ia32MonitorFilterLineSize, 0, UINT64_C(0xffffffffffff0000), 0), /* value=0x40 */
     MFN(0x00000010, "IA32_TIME_STAMP_COUNTER", Ia32TimestampCounter, Ia32TimestampCounter), /* value=0x1ac`2077a134 */
-    MVI(0x00000017, "IA32_PLATFORM_ID", UINT64_C(0x12000000000000)),
+    MFV(0x00000017, "IA32_PLATFORM_ID", Ia32PlatformId, ReadOnly, UINT64_C(0x12000000000000)),
     MFX(0x0000001b, "IA32_APIC_BASE", Ia32ApicBase, Ia32ApicBase, UINT32_C(0xfee00800), 0x600, UINT64_C(0xffffff00000000ff)),
     MFX(0x0000002a, "P4_EBC_HARD_POWERON", IntelP4EbcHardPowerOn, IntelP4EbcHardPowerOn, 0, UINT64_MAX, 0), /* value=0x0 */
     MFX(0x0000002b, "P4_EBC_SOFT_POWERON", IntelP4EbcSoftPowerOn, IntelP4EbcSoftPowerOn, 0x7e, UINT64_C(0xffffffffffffff80), 0), /* value=0x7e */
@@ -257,6 +257,7 @@ static CPUMDBENTRY const g_Entry_Intel_Pentium_4_3_00GHz =
     /*.uModel           = */ 4,
     /*.uStepping        = */ 3,
     /*.enmMicroarch     = */ kCpumMicroarch_Intel_NB_Prescott2M,
+    /*.uScalableBusFreq = */ CPUM_SBUSFREQ_UNKNOWN,
     /*.fFlags           = */ 0,
     /*.cMaxPhysAddrWidth= */ 36,
     /*.paCpuIdLeaves    = */ NULL_ALONE(g_aCpuIdLeaves_Intel_Pentium_4_3_00GHz),
diff --git a/src/VBox/VMM/VMMR3/cpus/Intel_Pentium_M_processor_2_00GHz.h b/src/VBox/VMM/VMMR3/cpus/Intel_Pentium_M_processor_2_00GHz.h
index d07c4d3..fe287df 100644
--- a/src/VBox/VMM/VMMR3/cpus/Intel_Pentium_M_processor_2_00GHz.h
+++ b/src/VBox/VMM/VMMR3/cpus/Intel_Pentium_M_processor_2_00GHz.h
@@ -47,7 +47,7 @@ static CPUMMSRRANGE const g_aMsrRanges_Intel_Pentium_M_processor_2_00GHz[] =
     MFI(0x00000000, "IA32_P5_MC_ADDR", Ia32P5McAddr), /* value=0x0 */
     MFI(0x00000001, "IA32_P5_MC_TYPE", Ia32P5McType), /* value=0x0 */
     MFX(0x00000010, "IA32_TIME_STAMP_COUNTER", Ia32TimestampCounter, Ia32TimestampCounter, 0, ~(uint64_t)UINT32_MAX, 0), /* value=0x22`4d44782e */
-    MVO(0x00000017, "IA32_PLATFORM_ID", UINT64_C(0x140000d0248a28)),
+    MFV(0x00000017, "IA32_PLATFORM_ID", Ia32PlatformId, ReadOnly, UINT64_C(0x140000d0248a28)),
     MVX(0x00000018, "P6_UNK_0000_0018", 0, 0, 0),
     MFX(0x0000001b, "IA32_APIC_BASE", Ia32ApicBase, Ia32ApicBase, UINT32_C(0xfee00100), UINT64_C(0xffffffff00000600), 0xff),
     MFX(0x0000002a, "EBL_CR_POWERON", IntelEblCrPowerOn, IntelEblCrPowerOn, 0x45080000, UINT64_C(0xfffffffffff7ff7e), 0), /* value=0x45080000 */
@@ -88,7 +88,7 @@ static CPUMMSRRANGE const g_aMsrRanges_Intel_Pentium_M_processor_2_00GHz[] =
     MFX(0x000000c1, "IA32_PMC0", Ia32PmcN, Ia32PmcN, 0, ~(uint64_t)UINT32_MAX, 0), /* value=0x0 */
     MFX(0x000000c2, "IA32_PMC1", Ia32PmcN, Ia32PmcN, 0, ~(uint64_t)UINT32_MAX, 0), /* value=0x0 */
     MVI(0x000000c7, "P6_UNK_0000_00c7", UINT64_C(0x5a000000ac000000)),
-    MVO(0x000000cd, "P6_UNK_0000_00cd", 0),
+    MFX(0x000000cd, "MSR_FSB_FREQ", IntelP6FsbFrequency, ReadOnly, 0, 0, 0),
     MVO(0x000000ce, "P6_UNK_0000_00ce", UINT64_C(0x2812140000000000)),
     MFX(0x000000fe, "IA32_MTRRCAP", Ia32MtrrCap, ReadOnly, 0x508, 0, 0), /* value=0x508 */
     MVX(0x00000116, "BBL_CR_ADDR", UINT32_C(0xfe7efff0), UINT64_C(0xffffffff0000000f), 0),
@@ -196,6 +196,7 @@ static CPUMDBENTRY const g_Entry_Intel_Pentium_M_processor_2_00GHz =
     /*.uModel           = */ 13,
     /*.uStepping        = */ 6,
     /*.enmMicroarch     = */ kCpumMicroarch_Intel_P6_M_Dothan,
+    /*.uScalableBusFreq = */ CPUM_SBUSFREQ_UNKNOWN,
     /*.fFlags           = */ 0,
     /*.cMaxPhysAddrWidth= */ 32,
     /*.paCpuIdLeaves    = */ NULL_ALONE(g_aCpuIdLeaves_Intel_Pentium_M_processor_2_00GHz),
diff --git a/src/VBox/VMM/VMMR3/cpus/Intel_Xeon_X5482_3_20GHz.h b/src/VBox/VMM/VMMR3/cpus/Intel_Xeon_X5482_3_20GHz.h
index e307e65..45acf49 100644
--- a/src/VBox/VMM/VMMR3/cpus/Intel_Xeon_X5482_3_20GHz.h
+++ b/src/VBox/VMM/VMMR3/cpus/Intel_Xeon_X5482_3_20GHz.h
@@ -60,7 +60,7 @@ static CPUMMSRRANGE const g_aMsrRanges_Intel_Xeon_X5482_3_20GHz[] =
     MFX(0x00000001, "IA32_P5_MC_TYPE", Ia32P5McType, Ia32P5McType, 0, 0, UINT64_MAX), /* value=0x0 */
     MFX(0x00000006, "IA32_MONITOR_FILTER_LINE_SIZE", Ia32MonitorFilterLineSize, Ia32MonitorFilterLineSize, 0, 0, UINT64_C(0xffffffffffff0000)), /* value=0x40 */
     MFN(0x00000010, "IA32_TIME_STAMP_COUNTER", Ia32TimestampCounter, Ia32TimestampCounter), /* value=0x1358`d28c2c60 */
-    MVO(0x00000017, "IA32_PLATFORM_ID", UINT64_C(0x18000088e40822)),
+    MFV(0x00000017, "IA32_PLATFORM_ID", Ia32PlatformId, ReadOnly, UINT64_C(0x18000088e40822)),
     MFX(0x0000001b, "IA32_APIC_BASE", Ia32ApicBase, Ia32ApicBase, UINT32_C(0xfee00800), 0, UINT64_C(0xffffffc0000006ff)),
     MVX(0x00000021, "C2_UNK_0000_0021", 0, 0, UINT64_C(0xffffffffffffffc0)),
     MFX(0x0000002a, "EBL_CR_POWERON", IntelEblCrPowerOn, IntelEblCrPowerOn, UINT32_C(0xc2383400), UINT64_C(0xffffffffdff7df00), 0), /* value=0xc2383400 */
@@ -82,7 +82,7 @@ static CPUMMSRRANGE const g_aMsrRanges_Intel_Xeon_X5482_3_20GHz[] =
     MFX(0x000000ad, "C2_EMTTM_CR_TABLES_5", IntelCore2EmttmCrTablesN, IntelCore2EmttmCrTablesN, 0x612, ~(uint64_t)UINT32_MAX, 0), /* value=0x612 */
     RSN(0x000000c1, 0x000000c2, "IA32_PMCn", Ia32PmcN, Ia32PmcN, 0x0, ~(uint64_t)UINT32_MAX, 0),
     MVI(0x000000c7, "P6_UNK_0000_00c7", UINT64_C(0x2300000052000000)),
-    MVO(0x000000cd, "P6_UNK_0000_00cd", 0x806),
+    MFX(0x000000cd, "P6_MSR_FSB_FREQ", IntelP6FsbFrequency, ReadOnly, 0x806, 0, 0),
     MVO(0x000000ce, "P6_UNK_0000_00ce", UINT64_C(0x1208227f7f0710)),
     MVO(0x000000cf, "C2_UNK_0000_00cf", 0),
     MVO(0x000000e0, "C2_UNK_0000_00e0", 0x18820f0),
@@ -225,6 +225,7 @@ static CPUMDBENTRY const g_Entry_Intel_Xeon_X5482_3_20GHz =
     /*.uModel           = */ 23,
     /*.uStepping        = */ 6,
     /*.enmMicroarch     = */ kCpumMicroarch_Intel_Core2_Penryn,
+    /*.uScalableBusFreq = */ CPUM_SBUSFREQ_400MHZ,
     /*.fFlags           = */ 0,
     /*.cMaxPhysAddrWidth= */ 38,
     /*.paCpuIdLeaves    = */ NULL_ALONE(g_aCpuIdLeaves_Intel_Xeon_X5482_3_20GHz),
diff --git a/src/VBox/VMM/VMMR3/cpus/Quad_Core_AMD_Opteron_2384.h b/src/VBox/VMM/VMMR3/cpus/Quad_Core_AMD_Opteron_2384.h
index c9a27fd..04041a2 100644
--- a/src/VBox/VMM/VMMR3/cpus/Quad_Core_AMD_Opteron_2384.h
+++ b/src/VBox/VMM/VMMR3/cpus/Quad_Core_AMD_Opteron_2384.h
@@ -250,6 +250,7 @@ static CPUMDBENTRY const g_Entry_Quad_Core_AMD_Opteron_2384 =
     /*.uModel           = */ 4,
     /*.uStepping        = */ 2,
     /*.enmMicroarch     = */ kCpumMicroarch_AMD_K10,
+    /*.uScalableBusFreq = */ CPUM_SBUSFREQ_UNKNOWN,
     /*.fFlags           = */ 0,
     /*.cMaxPhysAddrWidth= */ 48,
     /*.paCpuIdLeaves    = */ NULL_ALONE(g_aCpuIdLeaves_Quad_Core_AMD_Opteron_2384),
diff --git a/src/VBox/VMM/VMMR3/cpus/VIA_QuadCore_L4700_1_2_GHz.h b/src/VBox/VMM/VMMR3/cpus/VIA_QuadCore_L4700_1_2_GHz.h
index 8ea4e5c..75d5e08 100644
--- a/src/VBox/VMM/VMMR3/cpus/VIA_QuadCore_L4700_1_2_GHz.h
+++ b/src/VBox/VMM/VMMR3/cpus/VIA_QuadCore_L4700_1_2_GHz.h
@@ -79,7 +79,7 @@ static CPUMMSRRANGE const g_aMsrRanges_VIA_QuadCore_L4700_1_2_GHz[] =
     RVI(0x0000009c, 0x000000c0, "ZERO_0000_009c_THRU_0000_00c0", 0),
     RSN(0x000000c1, 0x000000c3, "IA32_PMCn", Ia32PmcN, Ia32PmcN, 0x0, UINT64_C(0xffffff0000000000), 0), /* XXX: The range ended earlier than expected! */
     RVI(0x000000c4, 0x000000cc, "ZERO_0000_00c4_THRU_0000_00cc", 0),
-    MVO(0x000000cd, "P6_UNK_0000_00cd", 0),
+    MFX(0x000000cd, "MSR_FSB_FREQ", IntelP6FsbFrequency, ReadOnly, 0, 0, 0),
     RVI(0x000000ce, 0x000000e1, "ZERO_0000_00ce_THRU_0000_00e1", 0),
     MFI(0x000000e2, "MSR_PKG_CST_CONFIG_CONTROL", IntelPkgCStConfigControl), /* value=0x6a204 */
     MFX(0x000000e3, "C2_SMM_CST_MISC_INFO", IntelCore2SmmCStMiscInfo, IntelCore2SmmCStMiscInfo, 0, ~(uint64_t)UINT32_MAX, 0), /* value=0x0 */
@@ -384,6 +384,7 @@ static CPUMDBENTRY const g_Entry_VIA_QuadCore_L4700_1_2_GHz =
     /*.uModel           = */ 15,
     /*.uStepping        = */ 13,
     /*.enmMicroarch     = */ kCpumMicroarch_VIA_Isaiah,
+    /*.uScalableBusFreq = */ CPUM_SBUSFREQ_267MHZ, /*??*/
     /*.fFlags           = */ 0,
     /*.cMaxPhysAddrWidth= */ 36,
     /*.paCpuIdLeaves    = */ NULL_ALONE(g_aCpuIdLeaves_VIA_QuadCore_L4700_1_2_GHz),
diff --git a/src/VBox/VMM/include/CPUMInternal.h b/src/VBox/VMM/include/CPUMInternal.h
index d9f5f6c..b2fd41c 100644
--- a/src/VBox/VMM/include/CPUMInternal.h
+++ b/src/VBox/VMM/include/CPUMInternal.h
@@ -129,6 +129,7 @@ typedef enum CPUMMSRRDFN
     kCpumMsrRdFn_Ia32P5McAddr,
     kCpumMsrRdFn_Ia32P5McType,
     kCpumMsrRdFn_Ia32TimestampCounter,
+    kCpumMsrRdFn_Ia32PlatformId,            /**< Takes real CPU value for reference. */
     kCpumMsrRdFn_Ia32ApicBase,
     kCpumMsrRdFn_Ia32FeatureControl,
     kCpumMsrRdFn_Ia32BiosSignId,            /**< Range value returned. */
@@ -205,13 +206,13 @@ typedef enum CPUMMSRRDFN
     kCpumMsrRdFn_Amd64TscAux,
 
     kCpumMsrRdFn_IntelEblCrPowerOn,
+    kCpumMsrRdFn_IntelI7CoreThreadCount,
     kCpumMsrRdFn_IntelP4EbcHardPowerOn,
     kCpumMsrRdFn_IntelP4EbcSoftPowerOn,
     kCpumMsrRdFn_IntelP4EbcFrequencyId,
-    kCpumMsrRdFn_IntelPlatformInfo100MHz,
-    kCpumMsrRdFn_IntelPlatformInfo133MHz,
-    kCpumMsrRdFn_IntelFlexRatio100MHz,      /**< Takes real value as reference. */
-    kCpumMsrRdFn_IntelFlexRatio133MHz,      /**< Takes real value as reference. */
+    kCpumMsrRdFn_IntelP6FsbFrequency,       /**< Takes real value as reference. */
+    kCpumMsrRdFn_IntelPlatformInfo,
+    kCpumMsrRdFn_IntelFlexRatio,            /**< Takes real value as reference. */
     kCpumMsrRdFn_IntelPkgCStConfigControl,
     kCpumMsrRdFn_IntelPmgIoCaptureBase,
     kCpumMsrRdFn_IntelLastBranchFromToN,
@@ -455,8 +456,7 @@ typedef enum CPUMMSRWRFN
     kCpumMsrWrFn_IntelP4EbcHardPowerOn,
     kCpumMsrWrFn_IntelP4EbcSoftPowerOn,
     kCpumMsrWrFn_IntelP4EbcFrequencyId,
-    kCpumMsrWrFn_IntelFlexRatio100MHz,
-    kCpumMsrWrFn_IntelFlexRatio133MHz,
+    kCpumMsrWrFn_IntelFlexRatio,
     kCpumMsrWrFn_IntelPkgCStConfigControl,
     kCpumMsrWrFn_IntelPmgIoCaptureBase,
     kCpumMsrWrFn_IntelLastBranchFromToN,
@@ -745,13 +745,15 @@ typedef struct CPUMINFO
     /** The index of the first extended CPUID leaf in the array.
      *  Set to cCpuIdLeaves if none present. */
     uint32_t                    iFirstExtCpuIdLeaf;
+    /** Alignment padding.  */
+    uint32_t                    uPadding;
     /** How to handle unknown CPUID leaves. */
     CPUMUKNOWNCPUID             enmUnknownCpuIdMethod;
     /** For use with CPUMUKNOWNCPUID_DEFAULTS. */
     CPUMCPUID                   DefCpuId;
 
-    /** Alignment padding.  */
-    uint32_t                    uPadding;
+    /** Scalable bus frequency used for reporting other frequencies. */
+    uint64_t                    uScalableBusFreq;
 
     /** Pointer to the MSR ranges (ring-0 pointer). */
     R0PTRTYPE(PCPUMMSRRANGE)    paMsrRangesR0;
diff --git a/src/VBox/VMM/include/CPUMInternal.mac b/src/VBox/VMM/include/CPUMInternal.mac
index 4e18b4e..5e1f66b 100644
--- a/src/VBox/VMM/include/CPUMInternal.mac
+++ b/src/VBox/VMM/include/CPUMInternal.mac
@@ -89,7 +89,7 @@ struc CPUM
     .abPadding2           resb    4
 %endif
 
-    .GuestInfo            resb    RTHCPTR_CB*4 + RTRCPTR_CB*2 + 4*10
+    .GuestInfo            resb    RTHCPTR_CB*4 + RTRCPTR_CB*2 + 4*12
     .GuestFeatures        resb    32
     .HostFeatures         resb    32
 
diff --git a/src/VBox/VMM/include/HMInternal.h b/src/VBox/VMM/include/HMInternal.h
index b36272c..fc1c953 100644
--- a/src/VBox/VMM/include/HMInternal.h
+++ b/src/VBox/VMM/include/HMInternal.h
@@ -638,7 +638,7 @@ typedef struct HMCPU
         /** Current exception bitmap. */
         uint32_t                    u32XcptBitmap;
         /** The updated-guest-state mask. */
-        uint32_t                    fUpdatedGuestState;
+        volatile uint32_t           fUpdatedGuestState;
         /** Current EPTP. */
         RTHCPHYS                    HCPhysEPTP;
 
diff --git a/src/VBox/VMM/include/PATMInternal.h b/src/VBox/VMM/include/PATMInternal.h
index 1e0601d..837f9ed 100644
--- a/src/VBox/VMM/include/PATMInternal.h
+++ b/src/VBox/VMM/include/PATMInternal.h
@@ -566,7 +566,6 @@ DECLCALLBACK(int) patmVirtPageHandler(PVM pVM, RTGCPTR GCPtr, void *pvPtr, void
 
 DECLCALLBACK(int) patmR3Save(PVM pVM, PSSMHANDLE pSSM);
 DECLCALLBACK(int) patmR3Load(PVM pVM, PSSMHANDLE pSSM, uint32_t uVersion, uint32_t uPass);
-DECLCALLBACK(int) patmR3LoadDummy(PVM pVM, PSSMHANDLE pSSM, uint32_t uVersion, uint32_t uPass);
 
 #ifdef IN_RING3
 RTRCPTR         patmPatchGCPtr2GuestGCPtr(PVM pVM, PPATCHINFO pPatch, RCPTRTYPE(uint8_t *) pPatchGC);
diff --git a/src/VBox/VMM/testcase/tstGlobalConfig.cpp b/src/VBox/VMM/testcase/tstGlobalConfig.cpp
index 8e1b85d..8b71744 100644
--- a/src/VBox/VMM/testcase/tstGlobalConfig.cpp
+++ b/src/VBox/VMM/testcase/tstGlobalConfig.cpp
@@ -4,7 +4,7 @@
  */
 
 /*
- * Copyright (C) 2007-2012 Oracle Corporation
+ * Copyright (C) 2007-2014 Oracle Corporation
  *
  * This file is part of VirtualBox Open Source Edition (OSE), as
  * available from http://www.virtualbox.org. This file is free software;
@@ -69,7 +69,7 @@ int main(int argc, char **argv)
     }
     if (cch >= sizeof(Req.szName))
     {
-        RTPrintf("syntax error: the name is too long. (max %zu chars)\n", argv[1], sizeof(Req.szName) - 1);
+        RTPrintf("syntax error: the name '%s' is too long. (max %zu chars)\n", argv[1], sizeof(Req.szName) - 1);
         return 1;
     }
     memcpy(&Req.szName[0], argv[1], cch + 1);
diff --git a/src/VBox/VMM/testcase/tstInstrEmul.cpp b/src/VBox/VMM/testcase/tstInstrEmul.cpp
index dd66203..3173c48 100644
--- a/src/VBox/VMM/testcase/tstInstrEmul.cpp
+++ b/src/VBox/VMM/testcase/tstInstrEmul.cpp
@@ -4,7 +4,7 @@
  */
 
 /*
- * Copyright (C) 2006-2011 Oracle Corporation
+ * Copyright (C) 2006-2014 Oracle Corporation
  *
  * This file is part of VirtualBox Open Source Edition (OSE), as
  * available from http://www.virtualbox.org. This file is free software;
@@ -50,7 +50,7 @@ int main(int argc, char **argv)
     if (    !(eflags & X86_EFL_ZF)
         ||  val != UINT64_C(0x200000001))
     {
-        RTPrintf("tstInstrEmul: FAILURE - Lock cmpxchg8b failed the equal case! (val=%x%x)\n", val);
+        RTPrintf("tstInstrEmul: FAILURE - Lock cmpxchg8b failed the equal case! (val=%RX64)\n", val);
         return 1;
     }
     val = UINT64_C(0x123456789);
@@ -59,7 +59,7 @@ int main(int argc, char **argv)
         ||  eax != 0x23456789
         ||  edx != 0x1)
     {
-        RTPrintf("tstInstrEmul: FAILURE - Lock cmpxchg8b failed the non-equal case! (val=%x%x)\n", val);
+        RTPrintf("tstInstrEmul: FAILURE - Lock cmpxchg8b failed the non-equal case! (val=%RX64)\n", val);
         return 1;
     }
     RTPrintf("tstInstrEmul: Testing lock cmpxchg instruction emulation - SUCCESS\n");
@@ -73,7 +73,7 @@ int main(int argc, char **argv)
     if (    !(eflags & X86_EFL_ZF)
         ||  val != UINT64_C(0x200000001))
     {
-        RTPrintf("tstInstrEmul: FAILURE - Cmpxchg8b failed the equal case! (val=%x%x)\n", val);
+        RTPrintf("tstInstrEmul: FAILURE - Cmpxchg8b failed the equal case! (val=%RX64)\n", val);
         return 1;
     }
     val = UINT64_C(0x123456789);
@@ -82,7 +82,7 @@ int main(int argc, char **argv)
         ||  eax != 0x23456789
         ||  edx != 0x1)
     {
-        RTPrintf("tstInstrEmul: FAILURE - Cmpxchg8b failed the non-equal case! (val=%x%x)\n", val);
+        RTPrintf("tstInstrEmul: FAILURE - Cmpxchg8b failed the non-equal case! (val=%RX64)\n", val);
         return 1;
     }
     RTPrintf("tstInstrEmul: Testing cmpxchg instruction emulation - SUCCESS\n");
diff --git a/src/VBox/VMM/testcase/tstVMMFork.cpp b/src/VBox/VMM/testcase/tstVMMFork.cpp
index 5c03eda..b5e429e 100644
--- a/src/VBox/VMM/testcase/tstVMMFork.cpp
+++ b/src/VBox/VMM/testcase/tstVMMFork.cpp
@@ -4,7 +4,7 @@
  */
 
 /*
- * Copyright (C) 2006-2013 Oracle Corporation
+ * Copyright (C) 2006-2014 Oracle Corporation
  *
  * This file is part of VirtualBox Open Source Edition (OSE), as
  * available from http://www.virtualbox.org. This file is free software;
@@ -139,7 +139,7 @@ int main(int argc, char* argv[])
         }
 
         if (rcErrors > 0)
-            RTPrintf(TESTCASE ": error: %d error(s) during fork(). Cannot proceed to test the VM.\n");
+            RTPrintf(TESTCASE ": error: %d error(s) during fork(). Cannot proceed to test the VM.\n", rcErrors);
         else
             RTPrintf(TESTCASE ": fork() and VM test, SUCCESS.\n");
 
diff --git a/src/VBox/VMM/tools/Makefile.kmk b/src/VBox/VMM/tools/Makefile.kmk
index 107208d..0c32195 100644
--- a/src/VBox/VMM/tools/Makefile.kmk
+++ b/src/VBox/VMM/tools/Makefile.kmk
@@ -55,7 +55,7 @@ endif
 #
 #PROGRAMS += VBoxCpuReport - not on 4.3, supdrv interface currently missing.
 VBoxCpuReport_TEMPLATE := VBoxR3Static
-VBoxCpuReport_DEFS      = IN_VMM_R3
+VBoxCpuReport_DEFS      = IN_VMM_R3 IN_VBOX_CPU_REPORT
 VBoxCpuReport_INCS      = ../include
 VBoxCpuReport_SOURCES   = \
 	VBoxCpuReport.cpp \
diff --git a/src/VBox/VMM/tools/VBoxCpuReport.cpp b/src/VBox/VMM/tools/VBoxCpuReport.cpp
index b1b70cd..7267a24 100644
--- a/src/VBox/VMM/tools/VBoxCpuReport.cpp
+++ b/src/VBox/VMM/tools/VBoxCpuReport.cpp
@@ -71,6 +71,9 @@ static PRTSTREAM        g_pReportOut;
 /** The alternative debug stream. */
 static PRTSTREAM        g_pDebugOut;
 
+/** Snooping info storage for vbCpuRepGuessScalableBusFrequencyName. */
+static uint64_t         g_uMsrIntelP6FsbFrequency = UINT64_MAX;
+
 
 static void vbCpuRepDebug(const char *pszMsg, ...)
 {
@@ -623,7 +626,7 @@ static const char *getMsrNameHandled(uint32_t uMsr)
         case 0x00000032: return "P6_UNK_0000_0032"; /* P6_M_Dothan. */
         case 0x00000033: return "TEST_CTL";
         case 0x00000034: return "P6_UNK_0000_0034"; /* P6_M_Dothan. */
-        case 0x00000035: return "P6_UNK_0000_0035"; /* P6_M_Dothan. */
+        case 0x00000035: return CPUMMICROARCH_IS_INTEL_CORE7(g_enmMicroarch) ? "MSR_CORE_THREAD_COUNT" : "P6_UNK_0000_0035"; /* P6_M_Dothan. */
         case 0x00000036: return "I7_UNK_0000_0036"; /* SandyBridge, IvyBridge. */
         case 0x00000039: return "C2_UNK_0000_0039"; /* Core2_Penryn */
         case 0x0000003a: return "IA32_FEATURE_CONTROL";
@@ -693,7 +696,7 @@ static const char *getMsrNameHandled(uint32_t uMsr)
         case 0x000000c6: return g_enmMicroarch >= kCpumMicroarch_Intel_Core7_First ? "IA32_PMC5" : NULL;
         case 0x000000c7: return g_enmMicroarch >= kCpumMicroarch_Intel_Core7_First ? "IA32_PMC6" : "P6_UNK_0000_00c7"; /* P6_M_Dothan. */
         case 0x000000c8: return g_enmMicroarch >= kCpumMicroarch_Intel_Core7_First ? "IA32_PMC7" : NULL;
-        case 0x000000cd: return "P6_UNK_0000_00cd"; /* P6_M_Dothan. */
+        case 0x000000cd: return "MSR_FSB_FREQ"; /* P6_M_Dothan. */
         case 0x000000ce: return g_enmMicroarch >= kCpumMicroarch_Intel_Core7_First ? "IA32_PLATFORM_INFO" : "P6_UNK_0000_00ce"; /* P6_M_Dothan. */
         case 0x000000cf: return "C2_UNK_0000_00cf"; /* Core2_Penryn. */
         case 0x000000e0: return "C2_UNK_0000_00e0"; /* Core2_Penryn. */
@@ -947,7 +950,7 @@ static const char *getMsrNameHandled(uint32_t uMsr)
         case 0x00000394: return g_enmMicroarch < kCpumMicroarch_Intel_Core7_SandyBridge ? "I7_UNC_PERF_FIXED_CTR"  /* X */    : "I7_UNC_PERF_FIXED_CTR_CTRL"; /* >= S,H */
         case 0x00000395: return g_enmMicroarch < kCpumMicroarch_Intel_Core7_SandyBridge ? "I7_UNC_PERF_FIXED_CTR_CTRL" /* X*/ : "I7_UNC_PERF_FIXED_CTR";      /* >= S,H */
         case 0x00000396: return g_enmMicroarch < kCpumMicroarch_Intel_Core7_SandyBridge ? "I7_UNC_ADDR_OPCODE_MATCH" /* X */  : "I7_UNC_CBO_CONFIG";          /* >= S,H */
-        case 0x00000397: return g_enmMicroarch < kCpumMicroarch_Intel_Core7_IvyBridge   ? NULL                                : "I7_IB_UNK_0000_0397";
+        case 0x00000397: return g_enmMicroarch < kCpumMicroarch_Intel_Core7_SandyBridge ? NULL                                : "I7_SB_UNK_0000_0397";
         case 0x0000039c: return "I7_SB_MSR_PEBS_NUM_ALT";
         case 0x000003a0: return g_fIntelNetBurst ? "P4_MSR_BSU_ESCR0"   : NULL;
         case 0x000003a1: return g_fIntelNetBurst ? "P4_MSR_BSU_ESCR1"   : NULL;
@@ -1055,6 +1058,7 @@ static const char *getMsrNameHandled(uint32_t uMsr)
         case 0x00000603: return "I7_SB_MSR_VR_MISC_CONFIG"; /* SandyBridge, IvyBridge. */
         case 0x00000604: return "I7_IB_UNK_0000_0602";
         case 0x00000606: return "I7_SB_MSR_RAPL_POWER_UNIT"; /* SandyBridge, IvyBridge. */
+        case 0x00000609: return "I7_SB_UNK_0000_0609";  /* SandyBridge (non EP). */
         case 0x0000060a: return "I7_SB_MSR_PKGC3_IRTL"; /* SandyBridge, IvyBridge. */
         case 0x0000060b: return "I7_SB_MSR_PKGC6_IRTL"; /* SandyBridge, IvyBridge. */
         case 0x0000060c: return "I7_SB_MSR_PKGC7_IRTL"; /* SandyBridge, IvyBridge. */
@@ -1578,6 +1582,66 @@ static const char *getMsrNameHandled(uint32_t uMsr)
     }
 
     /*
+     * Uncore stuff on Sandy. Putting it here to avoid ugly microarch checks for each register.
+     * Note! These are found on model 42 (2a) but not 45 (2d), the latter is the EP variant.
+     */
+    if (g_enmMicroarch == kCpumMicroarch_Intel_Core7_SandyBridge)
+        switch (uMsr)
+        {
+            case 0x00000700: return "MSR_UNC_CBO_0_PERFEVTSEL0";
+            case 0x00000701: return "MSR_UNC_CBO_0_PERFEVTSEL1";
+            case 0x00000702: return "MSR_UNC_CBO_0_PERFEVTSEL2?";
+            case 0x00000703: return "MSR_UNC_CBO_0_PERFEVTSEL3?";
+            case 0x00000704: return "MSR_UNC_CBO_0_UNK_4";
+            case 0x00000705: return "MSR_UNC_CBO_0_UNK_5";
+            case 0x00000706: return "MSR_UNC_CBO_0_PER_CTR0";
+            case 0x00000707: return "MSR_UNC_CBO_0_PER_CTR1";
+            case 0x00000708: return "MSR_UNC_CBO_0_PER_CTR2?";
+            case 0x00000709: return "MSR_UNC_CBO_0_PER_CTR3?";
+            case 0x00000710: return "MSR_UNC_CBO_1_PERFEVTSEL0";
+            case 0x00000711: return "MSR_UNC_CBO_1_PERFEVTSEL1";
+            case 0x00000712: return "MSR_UNC_CBO_1_PERFEVTSEL2?";
+            case 0x00000713: return "MSR_UNC_CBO_1_PERFEVTSEL3?";
+            case 0x00000714: return "MSR_UNC_CBO_1_UNK_4";
+            case 0x00000715: return "MSR_UNC_CBO_1_UNK_5";
+            case 0x00000716: return "MSR_UNC_CBO_1_PER_CTR0";
+            case 0x00000717: return "MSR_UNC_CBO_1_PER_CTR1";
+            case 0x00000718: return "MSR_UNC_CBO_1_PER_CTR2?";
+            case 0x00000719: return "MSR_UNC_CBO_1_PER_CTR3?";
+            case 0x00000720: return "MSR_UNC_CBO_2_PERFEVTSEL0";
+            case 0x00000721: return "MSR_UNC_CBO_2_PERFEVTSEL1";
+            case 0x00000722: return "MSR_UNC_CBO_2_PERFEVTSEL2?";
+            case 0x00000723: return "MSR_UNC_CBO_2_PERFEVTSEL3?";
+            case 0x00000724: return "MSR_UNC_CBO_2_UNK_4";
+            case 0x00000725: return "MSR_UNC_CBO_2_UNK_5";
+            case 0x00000726: return "MSR_UNC_CBO_2_PER_CTR0";
+            case 0x00000727: return "MSR_UNC_CBO_2_PER_CTR1";
+            case 0x00000728: return "MSR_UNC_CBO_2_PER_CTR2?";
+            case 0x00000729: return "MSR_UNC_CBO_2_PER_CTR3?";
+            case 0x00000730: return "MSR_UNC_CBO_3_PERFEVTSEL0";
+            case 0x00000731: return "MSR_UNC_CBO_3_PERFEVTSEL1";
+            case 0x00000732: return "MSR_UNC_CBO_3_PERFEVTSEL2?";
+            case 0x00000733: return "MSR_UNC_CBO_3_PERFEVTSEL3?";
+            case 0x00000734: return "MSR_UNC_CBO_3_UNK_4";
+            case 0x00000735: return "MSR_UNC_CBO_3_UNK_5";
+            case 0x00000736: return "MSR_UNC_CBO_3_PER_CTR0";
+            case 0x00000737: return "MSR_UNC_CBO_3_PER_CTR1";
+            case 0x00000738: return "MSR_UNC_CBO_3_PER_CTR2?";
+            case 0x00000739: return "MSR_UNC_CBO_3_PER_CTR3?";
+            case 0x00000740: return "MSR_UNC_CBO_4_PERFEVTSEL0?";
+            case 0x00000741: return "MSR_UNC_CBO_4_PERFEVTSEL1?";
+            case 0x00000742: return "MSR_UNC_CBO_4_PERFEVTSEL2?";
+            case 0x00000743: return "MSR_UNC_CBO_4_PERFEVTSEL3?";
+            case 0x00000744: return "MSR_UNC_CBO_4_UNK_4";
+            case 0x00000745: return "MSR_UNC_CBO_4_UNK_5";
+            case 0x00000746: return "MSR_UNC_CBO_4_PER_CTR0?";
+            case 0x00000747: return "MSR_UNC_CBO_4_PER_CTR1?";
+            case 0x00000748: return "MSR_UNC_CBO_4_PER_CTR2?";
+            case 0x00000749: return "MSR_UNC_CBO_4_PER_CTR3?";
+
+        }
+
+    /*
      * Bunch of unknown sandy bridge registers.  They might seem like the
      * nehalem based xeon stuff, but the layout doesn't match.  I bet it's the
      * same kind of registes though (i.e. uncore (UNC)).
@@ -1800,11 +1864,13 @@ static const char *getMsrFnName(uint32_t uMsr, bool *pfTakesValue)
                 return NULL; /* TR4 / cache tag on Pentium, but that's for later. */
             return "Ia32MonitorFilterLineSize";
         case 0x00000010: return "Ia32TimestampCounter";
+        case 0x00000017: *pfTakesValue = true; return "Ia32PlatformId";
         case 0x0000001b: return "Ia32ApicBase";
         case 0x0000002a: *pfTakesValue = true; return g_fIntelNetBurst ? "IntelP4EbcHardPowerOn" : "IntelEblCrPowerOn";
         case 0x0000002b: *pfTakesValue = true; return g_fIntelNetBurst ? "IntelP4EbcSoftPowerOn" : NULL;
         case 0x0000002c: *pfTakesValue = true; return g_fIntelNetBurst ? "IntelP4EbcFrequencyId" : NULL;
         //case 0x00000033: return "IntelTestCtl";
+        case 0x00000035: return CPUMMICROARCH_IS_INTEL_CORE7(g_enmMicroarch) ? "IntelI7CoreThreadCount" : NULL;
         case 0x0000003a: return "Ia32FeatureControl";
 
         case 0x00000040:
@@ -1842,11 +1908,8 @@ static const char *getMsrFnName(uint32_t uMsr, bool *pfTakesValue)
                 return "Ia32PmcN";
             return NULL;
 
-        case 0x000000ce: return CPUMMICROARCH_IS_INTEL_CORE7(g_enmMicroarch)
-                              ? (g_enmMicroarch >= kCpumMicroarch_Intel_Core7_SandyBridge
-                                 ? "IntelPlatformInfo100MHz" : "IntelPlatformInfo133MHz")
-                              : NULL;
-
+        case 0x000000cd: *pfTakesValue = true; return "IntelP6FsbFrequency";
+        case 0x000000ce: return CPUMMICROARCH_IS_INTEL_CORE7(g_enmMicroarch)  ? "IntelPlatformInfo" : NULL;
         case 0x000000e2: return "IntelPkgCStConfigControl";
         case 0x000000e3: return "IntelCore2SmmCStMiscInfo";
         case 0x000000e4: return "IntelPmgIoCaptureBase";
@@ -1881,12 +1944,7 @@ static const char *getMsrFnName(uint32_t uMsr, bool *pfTakesValue)
         case 0x00000186: return "Ia32PerfEvtSelN";
         case 0x00000187: return "Ia32PerfEvtSelN";
         case 0x00000193: return /*g_fIntelNetBurst ? NULL :*/ NULL /* Core2_Penryn. */;
-        case 0x00000194:
-            if (g_fIntelNetBurst)
-                break;
-            *pfTakesValue = true;
-            return CPUMMICROARCH_IS_INTEL_CORE7(g_enmMicroarch) && g_enmMicroarch >= kCpumMicroarch_Intel_Core7_SandyBridge
-                 ? "IntelFlexRatio100MHz" : "IntelFlexRatio133MHz";
+        case 0x00000194: if (g_fIntelNetBurst) break;   *pfTakesValue = true; return "IntelFlexRatio";
         case 0x00000198: *pfTakesValue = true; return "Ia32PerfStatus";
         case 0x00000199: *pfTakesValue = true; return "Ia32PerfCtl";
         case 0x0000019a: *pfTakesValue = true; return "Ia32ClockModulation";
@@ -3273,7 +3331,7 @@ static int reportMsr_Ia32MtrrPhysBaseMaskN(VBCPUREPMSR const *paMsrs, uint32_t c
     /* Probing the mask is relatively straight forward. */
     uint64_t fIgnMask = 0;
     uint64_t fGpMask  = 0;
-    rc = msrProberModifyBitChanges(uMsr + iGuineaPig + 1, &fIgnMask, &fGpMask, 0);
+    rc = msrProberModifyBitChanges(uMsr + iGuineaPig + 1, &fIgnMask, &fGpMask, 0x800); /* enabling it may cause trouble */
     if (RT_FAILURE(rc))
         return rc;
     vbCpuRepDebug("fIgnMask=%#llx fGpMask=%#llx\n", fIgnMask, fGpMask);
@@ -3349,7 +3407,11 @@ static int reportMsr_Ia32MtrrFixedOrPat(uint32_t uMsr)
     /* Had a spot of trouble on an old macbook pro with core2 duo T9900 (penryn)
        running 64-bit win81pe. Not giving PAT such a scrutiny fixes it. */
     if (   uMsr != 0x00000277
-        || g_enmMicroarch >= kCpumMicroarch_Intel_Core7_First)
+        || (  g_enmVendor == CPUMCPUVENDOR_INTEL
+            ? g_enmMicroarch >= kCpumMicroarch_Intel_Core7_First
+            : g_enmVendor == CPUMCPUVENDOR_AMD
+            ? g_enmMicroarch != kCpumMicroarch_AMD_K8_90nm_AMDV
+            : true) )
     {
         /* Every 8 bytes is a type, check the type ranges one by one. */
         for (uint32_t iBit = 0; iBit < 64; iBit += 8)
@@ -3372,16 +3434,25 @@ static int reportMsr_Ia32MtrrFixedOrPat(uint32_t uMsr)
  */
 static int reportMsr_Ia32MtrrDefType(uint32_t uMsr)
 {
-    int rc = msrVerifyMtrrTypeGPs(uMsr, 0, 7);
-    if (RT_FAILURE(rc))
-        return rc;
-
     uint64_t fGpMask  = 0;
     uint64_t fIgnMask = 0;
-    rc = msrProberModifyBitChanges(uMsr, &fIgnMask, &fGpMask, 0x7);
-    if (RT_FAILURE(rc))
-        return rc;
-    Assert(!(fGpMask & 7)); Assert(!(fIgnMask & 7));
+    if (g_enmMicroarch == kCpumMicroarch_AMD_K8_90nm_AMDV)
+    {
+        /* Problematic CPU! Fake it for now. */
+        fGpMask = ~(uint64_t)0xc07;
+        fIgnMask = 0;
+    }
+    else
+    {
+        int rc = msrVerifyMtrrTypeGPs(uMsr, 0, 7);
+        if (RT_FAILURE(rc))
+            return rc;
+
+        rc = msrProberModifyBitChanges(uMsr, &fIgnMask, &fGpMask, 0x7);
+        if (RT_FAILURE(rc))
+            return rc;
+        Assert(!(fGpMask & 7)); Assert(!(fIgnMask & 7));
+    }
 
     return printMsrFunctionCpumCpuEx(uMsr, NULL, NULL, NULL, fIgnMask, fGpMask, NULL);
 }
@@ -3624,7 +3695,7 @@ static int reportMsr_AmdK8SysCfg(uint32_t uMsr, uint64_t uValue)
 
     /* Turns out there are more killer bits here, at least on Opteron 2384.
        Skipping all known bits. */
-    if (g_enmMicroarch >= kCpumMicroarch_AMD_K8_65nm /* Not sure when introduced - harmless? */)
+    if (g_enmMicroarch >= kCpumMicroarch_AMD_K8_90nm_AMDV /* Not sure when introduced - harmless? */)
         fSkipMask |= RT_BIT(22); /* Tom2ForceMemTypeWB */
     if (g_enmMicroarch >= kCpumMicroarch_AMD_K8_First)
         fSkipMask |= RT_BIT(21); /* MtrrTom2En */
@@ -3944,9 +4015,9 @@ static int produceMsrReport(VBCPUREPMSR *paMsrs, uint32_t cMsrs)
         uint64_t    uValue     = paMsrs[i].uValue;
         int         rc;
 #if 0
-        if (uMsr < 0x00003170)
-            continue;
-        if (uMsr >= 0x00003170)
+        //if (uMsr < 0x00000000)
+        //    continue;
+        if (uMsr >= 0x00000277)
         {
             vbCpuRepDebug("produceMsrReport: uMsr=%#x (%s)...\n", uMsr, getMsrNameHandled(uMsr));
             RTThreadSleep(1000);
@@ -4096,6 +4167,12 @@ static int produceMsrReport(VBCPUREPMSR *paMsrs, uint32_t cMsrs)
 
         if (RT_FAILURE(rc))
             return rc;
+
+        /*
+         *  A little ugly snooping.
+         */
+        if (uMsr == 0x000000cd && !(fFlags & VBCPUREPMSR_F_WRITE_ONLY))
+            g_uMsrIntelP6FsbFrequency = uValue;
     }
 
     return VINF_SUCCESS;
@@ -4131,13 +4208,10 @@ static int hackingMsrs(void)
     }
 #else
 
-    uint32_t uMsr = 0xc0000080;
+    uint32_t uMsr = 0xc0010010;
     uint64_t uValue = 0;
     msrProberRead(uMsr, &uValue);
-    /* Try for a triple fault... */
-    msrProberWrite(uMsr, uValue ^ MSR_K6_EFER_LME);
-    msrProberRead(uMsr, &uValue);
-    msrProberWrite(uMsr, uValue ^ MSR_K6_EFER_NXE);
+    reportMsr_AmdK8SysCfg(uMsr, uValue);
 #endif
     return VINF_SUCCESS;
 }
@@ -4315,6 +4389,32 @@ static const char *cpuVendorToString(CPUMCPUVENDOR enmCpuVendor)
 }
 
 
+/**
+ * Takes a shot a the bus frequency name (last part).
+ *
+ * @returns Name suffix.
+ */
+static const char *vbCpuRepGuessScalableBusFrequencyName(void)
+{
+    if (CPUMMICROARCH_IS_INTEL_CORE7(g_enmMicroarch))
+        return g_enmMicroarch >= kCpumMicroarch_Intel_Core7_SandyBridge ? "100MHZ" : "133MHZ";
+
+    if (g_uMsrIntelP6FsbFrequency != UINT64_MAX)
+        switch (g_uMsrIntelP6FsbFrequency & 0x7)
+        {
+            case 5: return "100MHZ";
+            case 1: return "133MHZ";
+            case 3: return "167MHZ";
+            case 2: return "200MHZ";
+            case 0: return "267MHZ";
+            case 4: return "333MHZ";
+            case 6: return "400MHZ";
+        }
+
+    return "UNKNOWN";
+}
+
+
 static int produceCpuReport(void)
 {
     /*
@@ -4507,6 +4607,7 @@ static int produceCpuReport(void)
                    "    /*.uModel           = */ %u,\n"
                    "    /*.uStepping        = */ %u,\n"
                    "    /*.enmMicroarch     = */ kCpumMicroarch_%s,\n"
+                   "    /*.uScalableBusFreq = */ CPUM_SBUSFREQ_%s,\n"
                    "    /*.fFlags           = */ 0,\n"
                    "    /*.cMaxPhysAddrWidth= */ %u,\n"
                    "    /*.paCpuIdLeaves    = */ NULL_ALONE(g_aCpuIdLeaves_%s),\n"
@@ -4529,6 +4630,7 @@ static int produceCpuReport(void)
                    ASMGetCpuModel(uEax, enmVendor == CPUMCPUVENDOR_INTEL),
                    ASMGetCpuStepping(uEax),
                    CPUMR3MicroarchName(enmMicroarch),
+                   vbCpuRepGuessScalableBusFrequencyName(),
                    vbCpuRepGetPhysAddrWidth(),
                    szNameC,
                    szNameC,
diff --git a/src/libs/xpcom18a4/python/server/loader.py b/src/libs/xpcom18a4/python/server/loader.py
index b587554..e59155a 100644
--- a/src/libs/xpcom18a4/python/server/loader.py
+++ b/src/libs/xpcom18a4/python/server/loader.py
@@ -57,11 +57,15 @@ def FindCOMComponents(py_module):
     # For now, just run over all classes looking for likely candidates.
     comps = []
     for name, object in py_module.__dict__.items():
-        if type(object)==types.ClassType and \
-           _has_good_attr(object, "_com_interfaces_") and \
-           _has_good_attr(object, "_reg_clsid_") and \
-           _has_good_attr(object, "_reg_contractid_"):
-            comps.append(object)
+        try:
+            if (type(object) == types.ClassType or issubclass(object, object)) and \
+               _has_good_attr(object, "_com_interfaces_") and \
+               _has_good_attr(object, "_reg_clsid_") and \
+               _has_good_attr(object, "_reg_contractid_"):
+                comps.append(object)
+        except TypeError:
+            # The issubclass call raises TypeError when the obj is not a class.
+            pass;
     return comps
 
 def register_self(klass, compMgr, location, registryLocation, componentType):
diff --git a/src/libs/xpcom18a4/python/src/PyGBase.cpp b/src/libs/xpcom18a4/python/src/PyGBase.cpp
index 93fe03f..0a93501 100644
--- a/src/libs/xpcom18a4/python/src/PyGBase.cpp
+++ b/src/libs/xpcom18a4/python/src/PyGBase.cpp
@@ -195,7 +195,8 @@ void *PyG_Base::ThisAsIID( const nsIID &iid )
 PyG_Base::AutoWrapPythonInstance(PyObject *ob, const nsIID &iid, nsISupports **ppret)
 {
 	NS_PRECONDITION(ppret!=NULL, "null pointer when wrapping a Python instance!");
-	NS_PRECONDITION(ob && PyInstance_Check(ob), "AutoWrapPythonInstance is expecting an non-NULL instance!");
+	NS_PRECONDITION(ob && PyObject_HasAttrString(ob, "__class__"),
+			"AutoWrapPythonInstance is expecting an non-NULL instance!");
 	PRBool ok = PR_FALSE;
     // XXX - todo - this static object leaks! (but Python on Windows leaks 2000+ objects as it is ;-)
 	static PyObject *func = NULL; // fetch this once and remember!
diff --git a/src/libs/xpcom18a4/python/src/PyIID.cpp b/src/libs/xpcom18a4/python/src/PyIID.cpp
index 2cdcf5c..783c9c6 100644
--- a/src/libs/xpcom18a4/python/src/PyIID.cpp
+++ b/src/libs/xpcom18a4/python/src/PyIID.cpp
@@ -114,7 +114,7 @@ Py_nsIID::IIDFromPyObject(PyObject *ob, nsIID *pRet) {
 		}
 	} else if (ob->ob_type == &type) {
 		iid = ((Py_nsIID *)ob)->m_iid;
-	} else if (PyInstance_Check(ob)) {
+	} else if (PyObject_HasAttrString(ob, "__class__")) {
 		// Get the _iidobj_ attribute
 		PyObject *use_ob = PyObject_GetAttrString(ob, "_iidobj_");
 		if (use_ob==NULL) {
diff --git a/src/libs/xpcom18a4/python/src/PyISupports.cpp b/src/libs/xpcom18a4/python/src/PyISupports.cpp
index 508eeea..0802eee 100644
--- a/src/libs/xpcom18a4/python/src/PyISupports.cpp
+++ b/src/libs/xpcom18a4/python/src/PyISupports.cpp
@@ -321,7 +321,7 @@ Py_nsISupports::InterfaceFromPyObject(PyObject *ob,
 	// support nsIVariant
 	if (iid.Equals(NS_GET_IID(nsIVariant)) || iid.Equals(NS_GET_IID(nsIWritableVariant))) {
 		// Check it is not already nsIVariant
-		if (PyInstance_Check(ob)) {
+		if (PyObject_HasAttrString(ob, "__class__")) {
 			PyObject *sub_ob = PyObject_GetAttrString(ob, "_comobj_");
 			if (sub_ob==NULL) {
 				PyErr_Clear();
@@ -344,7 +344,7 @@ Py_nsISupports::InterfaceFromPyObject(PyObject *ob,
 	}
 	// end of variant support.
 
-	if (PyInstance_Check(ob)) {
+	if (PyObject_HasAttrString(ob, "__class__")) {
 		// Get the _comobj_ attribute
 		PyObject *use_ob = PyObject_GetAttrString(ob, "_comobj_");
 		if (use_ob==NULL) {

-- 
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