Index: /trunk/Config.kmk
===================================================================
--- /trunk/Config.kmk	(revision 19956)
+++ /trunk/Config.kmk	(revision 19957)
@@ -496,4 +496,11 @@
 ## For experimenting with linking libxml2 into VBoxRT.
 #VBOX_WITH_LIBXML2_IN_VBOXRT = 1
+
+## For experimenting with disabling preemption instead of interrupts
+# when working VT-x/AMD-V in VMMR0.
+## @todo Move to VMM/Makefile.kmk later.
+#if1of ($(KBUILD_TARGET), darwin linux)
+# VBOX_WITH_VMMR0_DISABLE_PREEMPTION=1
+#endif
 
 #
Index: /trunk/src/VBox/HostDrivers/Support/Makefile.kmk
===================================================================
--- /trunk/src/VBox/HostDrivers/Support/Makefile.kmk	(revision 19956)
+++ /trunk/src/VBox/HostDrivers/Support/Makefile.kmk	(revision 19957)
@@ -164,4 +164,7 @@
 VBoxDrv_DEFS          = IN_RT_R0 IN_SUP_R0 SUPDRV_WITH_RELEASE_LOGGER
 VBoxDrv_DEFS.amd64    = RT_WITH_W64_UNWIND_HACK
+ifdef VBOX_WITH_VMMR0_DISABLE_PREEMPTION
+VBoxDrv_DEFS         += VBOX_WITH_VMMR0_DISABLE_PREEMPTION
+endif
 VBoxDrv_SDKS          = W2K3DDK WINPSDKINCS
 VBoxDrv_INCS         := $(PATH_SUB_CURRENT)
Index: /trunk/src/VBox/HostDrivers/Support/win/SUPDrv-win.cpp
===================================================================
--- /trunk/src/VBox/HostDrivers/Support/win/SUPDrv-win.cpp	(revision 19956)
+++ /trunk/src/VBox/HostDrivers/Support/win/SUPDrv-win.cpp	(revision 19957)
@@ -322,5 +322,8 @@
         ||  ulCmd == SUP_IOCTL_FAST_DO_NOP)
     {
-        /* Raise the IRQL to DISPATCH_LEVEl to prevent Windows from rescheduling us to another CPU/core. */
+#ifdef VBOX_WITH_VMMR0_DISABLE_PREEMPTION
+        int rc = supdrvIOCtlFast(ulCmd, (unsigned)(uintptr_t)pIrp->UserBuffer /* VMCPU id */, pDevExt, pSession);
+#else
+        /* Raise the IRQL to DISPATCH_LEVEL to prevent Windows from rescheduling us to another CPU/core. */
         Assert(KeGetCurrentIrql() <= DISPATCH_LEVEL);
         KIRQL oldIrql;
@@ -328,4 +331,5 @@
         int rc = supdrvIOCtlFast(ulCmd, (unsigned)(uintptr_t)pIrp->UserBuffer /* VMCPU id */, pDevExt, pSession);
         KeLowerIrql(oldIrql);
+#endif
 
         /* Complete the I/O request. */
Index: /trunk/src/VBox/VMM/Makefile.kmk
===================================================================
--- /trunk/src/VBox/VMM/Makefile.kmk	(revision 19956)
+++ /trunk/src/VBox/VMM/Makefile.kmk	(revision 19957)
@@ -406,4 +406,7 @@
 VMMR0_DEFS     += VBOX_WITH_R0_LOGGING
 endif
+ifdef VBOX_WITH_VMMR0_DISABLE_PREEMPTION
+VMMR0_DEFS     += VBOX_WITH_VMMR0_DISABLE_PREEMPTION
+endif
 VMMR0_DEFS.darwin.x86 = \
 	VBOX_WITH_2X_4GB_ADDR_SPACE   VBOX_WITH_2X_4GB_ADDR_SPACE_IN_R0 \
Index: /trunk/src/VBox/VMM/VMMR0/HWSVMR0.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR0/HWSVMR0.cpp	(revision 19956)
+++ /trunk/src/VBox/VMM/VMMR0/HWSVMR0.cpp	(revision 19957)
@@ -44,4 +44,7 @@
 #include <iprt/cpuset.h>
 #include <iprt/mp.h>
+#ifdef VBOX_WITH_VMMR0_DISABLE_PREEMPTION
+# include <iprt/thread.h>
+#endif
 #include "HWSVMR0.h"
 
@@ -915,4 +918,16 @@
     }
 
+#ifdef VBOX_WITH_VMMR0_DISABLE_PREEMPTION
+    /** @todo This must be repeated (or moved down) after we've disabled interrupts
+     *        below because a rescheduling request (IPI) might arrive before we get
+     *        there and we end up exceeding our timeslice. (Putting it here for
+     *        now because I don't want to mess up anything.) */
+    if (RTThreadPreemptIsPending(NIL_RTTHREAD))
+    {
+        rc = VINF_EM_RAW_INTERRUPT_HYPER;
+        goto end;
+    }
+#endif
+
     /* When external interrupts are pending, we should exit the VM when IF is set. */
     /* Note! *After* VM_FF_INHIBIT_INTERRUPTS check!!! */
@@ -989,5 +1004,5 @@
     }
 
-    /* Disable interrupts to make sure a poke will interrupt execution. 
+    /* Disable interrupts to make sure a poke will interrupt execution.
      * This must be done *before* we check for TLB flushes; TLB shootdowns rely on this.
      */
Index: /trunk/src/VBox/VMM/VMMR0/HWVMXR0.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR0/HWVMXR0.cpp	(revision 19956)
+++ /trunk/src/VBox/VMM/VMMR0/HWVMXR0.cpp	(revision 19957)
@@ -36,8 +36,11 @@
 #include <VBox/iom.h>
 #include <VBox/rem.h>
+#include <iprt/asm.h>
+#include <iprt/assert.h>
 #include <iprt/param.h>
-#include <iprt/assert.h>
-#include <iprt/asm.h>
 #include <iprt/string.h>
+#ifdef VBOX_WITH_VMMR0_DISABLE_PREEMPTION
+# include <iprt/thread.h>
+#endif
 #include "HWVMXR0.h"
 
@@ -2111,4 +2114,16 @@
     }
 
+#ifdef VBOX_WITH_VMMR0_DISABLE_PREEMPTION
+    /** @todo This must be repeated (or moved down) after we've disabled interrupts
+     *        below because a rescheduling request (IPI) might arrive before we get
+     *        there and we end up exceeding our timeslice. (Putting it here for
+     *        now because I don't want to mess up anything.) */
+    if (RTThreadPreemptIsPending(NIL_RTTHREAD))
+    {
+        rc = VINF_EM_RAW_INTERRUPT_HYPER;
+        goto end;
+    }
+#endif
+
     /* When external interrupts are pending, we should exit the VM when IF is set. */
     /* Note! *After* VM_FF_INHIBIT_INTERRUPTS check!!! */
@@ -2196,5 +2211,5 @@
         goto end;
 
-    /* Disable interrupts to make sure a poke will interrupt execution. 
+    /* Disable interrupts to make sure a poke will interrupt execution.
      * This must be done *before* we check for TLB flushes; TLB shootdowns rely on this.
      */
Index: /trunk/src/VBox/VMM/VMMR0/VMMR0.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR0/VMMR0.cpp	(revision 19956)
+++ /trunk/src/VBox/VMM/VMMR0/VMMR0.cpp	(revision 19957)
@@ -33,4 +33,5 @@
 #include "VMMInternal.h"
 #include <VBox/vm.h>
+
 #include <VBox/gvmm.h>
 #include <VBox/gmm.h>
@@ -38,12 +39,15 @@
 #include <VBox/hwaccm.h>
 #include <VBox/param.h>
-
 #include <VBox/err.h>
 #include <VBox/version.h>
 #include <VBox/log.h>
+
 #include <iprt/assert.h>
+#include <iprt/mp.h>
 #include <iprt/stdarg.h>
-#include <iprt/mp.h>
 #include <iprt/string.h>
+#ifdef VBOX_WITH_VMMR0_DISABLE_PREEMPTION
+# include <iprt/thread.h>
+#endif
 
 #if defined(_MSC_VER) && defined(RT_ARCH_AMD64) /** @todo check this with with VC7! */
@@ -624,5 +628,8 @@
             STAM_COUNTER_INC(&pVM->vmm.s.StatRunRC);
 
-#if !defined(RT_OS_WINDOWS) /** @todo check other hosts */
+#ifdef VBOX_WITH_VMMR0_DISABLE_PREEMPTION
+            RTTHREADPREEMPTSTATE PreemptState = RTTHREADPREEMPTSTATE_INITIALIZER;
+            RTThreadPreemptDisable(&PreemptState);
+#elif !defined(RT_OS_WINDOWS)
             RTCCUINTREG uFlags = ASMIntDisableFlags();
 #endif
@@ -660,5 +667,7 @@
 
             ASMAtomicWriteU32(&pVCpu->idHostCpu, NIL_RTCPUID);
-#if !defined(RT_OS_WINDOWS) /** @todo check other hosts */
+#ifdef VBOX_WITH_VMMR0_DISABLE_PREEMPTION
+            RTThreadPreemptRestore(&PreemptState);
+#else !defined(RT_OS_WINDOWS)
             ASMSetFlags(uFlags);
 #endif
