Index: /trunk/include/VBox/csam.h
===================================================================
--- /trunk/include/VBox/csam.h	(revision 19140)
+++ /trunk/include/VBox/csam.h	(revision 19141)
@@ -259,6 +259,7 @@
  * @returns VBox status code.
  * @param   pVM         The VM to operate on.
- */
-VMMR3DECL(int) CSAMR3DoPendingAction(PVM pVM);
+ * @param   pVCpu       The VMCPU to operate on.
+ */
+VMMR3DECL(int) CSAMR3DoPendingAction(PVM pVM, PVMCPU pVCpu);
 
 /**
Index: /trunk/include/VBox/em.h
===================================================================
--- /trunk/include/VBox/em.h	(revision 19140)
+++ /trunk/include/VBox/em.h	(revision 19141)
@@ -117,6 +117,6 @@
 #define EMIsRawRing0Enabled(pVM) ((pVM)->fRawR0Enabled)
 
-VMMDECL(void)       EMSetInhibitInterruptsPC(PVM pVM, PVMCPU pVCpu, RTGCUINTPTR PC);
-VMMDECL(RTGCUINTPTR) EMGetInhibitInterruptsPC(PVM pVM, PVMCPU pVCpu);
+VMMDECL(void)       EMSetInhibitInterruptsPC(PVMCPU pVCpu, RTGCUINTPTR PC);
+VMMDECL(RTGCUINTPTR) EMGetInhibitInterruptsPC(PVMCPU pVCpu);
 VMMDECL(int)        EMInterpretDisasOne(PVM pVM, PVMCPU pVCpu, PCCPUMCTXCORE pCtxCore, PDISCPUSTATE pCpu, unsigned *pcbInstr);
 VMMDECL(int)        EMInterpretDisasOneEx(PVM pVM, PVMCPU pVCpu, RTGCUINTPTR GCPtrInstr, PCCPUMCTXCORE pCtxCore,
Index: /trunk/include/VBox/pdmapi.h
===================================================================
--- /trunk/include/VBox/pdmapi.h	(revision 19140)
+++ /trunk/include/VBox/pdmapi.h	(revision 19141)
@@ -43,5 +43,5 @@
  */
 
-VMMDECL(int)    PDMGetInterrupt(PVM pVM, uint8_t *pu8Interrupt);
+VMMDECL(int)    PDMGetInterrupt(PVMCPU pVCpu, uint8_t *pu8Interrupt);
 VMMDECL(int)    PDMIsaSetIrq(PVM pVM, uint8_t u8Irq, uint8_t u8Level);
 VMMDECL(int)    PDMIoApicSetIrq(PVM pVM, uint8_t u8Irq, uint8_t u8Level);
Index: /trunk/include/VBox/vm.h
===================================================================
--- /trunk/include/VBox/vm.h	(revision 19140)
+++ /trunk/include/VBox/vm.h	(revision 19141)
@@ -82,5 +82,5 @@
     /** Per CPU forced action.
      * See the VMCPU_FF_* \#defines. Updated atomically. */
-    uint32_t volatile       fForcedActions;
+    uint32_t volatile       fLocalForcedActions;
     /** The CPU state. */
     VMCPUSTATE volatile     enmState;
@@ -187,90 +187,117 @@
  * @{
  */
-/** This action forces the VM to service check and pending interrups on the APIC. */
-#define VM_FF_INTERRUPT_APIC            RT_BIT_32(0)
-/** This action forces the VM to service check and pending interrups on the PIC. */
-#define VM_FF_INTERRUPT_PIC             RT_BIT_32(1)
 /** This action forces the VM to schedule and run pending timer (TM). */
-#define VM_FF_TIMER                     RT_BIT_32(2)
+#define VM_FF_TIMER                         RT_BIT_32(2)
 /** PDM Queues are pending. */
-#define VM_FF_PDM_QUEUES                RT_BIT_32(3)
+#define VM_FF_PDM_QUEUES                    RT_BIT_32(3)
 /** PDM DMA transfers are pending. */
-#define VM_FF_PDM_DMA                   RT_BIT_32(4)
+#define VM_FF_PDM_DMA                       RT_BIT_32(4)
 /** PDM critical section unlocking is pending, process promptly upon return to R3. */
-#define VM_FF_PDM_CRITSECT              RT_BIT_32(5)
-
+#define VM_FF_PDM_CRITSECT                  RT_BIT_32(5)
 /** This action forces the VM to call DBGF so DBGF can service debugger
  * requests in the emulation thread.
  * This action flag stays asserted till DBGF clears it.*/
-#define VM_FF_DBGF                      RT_BIT_32(8)
+#define VM_FF_DBGF                          RT_BIT_32(8)
 /** This action forces the VM to service pending requests from other
  * thread or requests which must be executed in another context. */
-#define VM_FF_REQUEST                   RT_BIT_32(9)
+#define VM_FF_REQUEST                       RT_BIT_32(9)
 /** Terminate the VM immediately. */
-#define VM_FF_TERMINATE                 RT_BIT_32(10)
+#define VM_FF_TERMINATE                     RT_BIT_32(10)
 /** Reset the VM. (postponed) */
-#define VM_FF_RESET                     RT_BIT_32(11)
-
-/** This action forces the VM to resync the page tables before going
- * back to execute guest code. (GLOBAL FLUSH) */
-#define VM_FF_PGM_SYNC_CR3              RT_BIT_32(16)
-/** Same as VM_FF_PGM_SYNC_CR3 except that global pages can be skipped.
- * (NON-GLOBAL FLUSH) */
-#define VM_FF_PGM_SYNC_CR3_NON_GLOBAL   RT_BIT_32(17)
+#define VM_FF_RESET                         RT_BIT_32(11)
 /** PGM needs to allocate handy pages. */
-#define VM_FF_PGM_NEED_HANDY_PAGES      RT_BIT_32(18)
+#define VM_FF_PGM_NEED_HANDY_PAGES          RT_BIT_32(18)
 /** PGM is out of memory.
  * Abandon all loops and code paths which can be resumed and get up to the EM
  * loops. */
-#define VM_FF_PGM_NO_MEMORY             RT_BIT_32(19)
+#define VM_FF_PGM_NO_MEMORY                 RT_BIT_32(19)
+/** REM needs to be informed about handler changes. */
+#define VM_FF_REM_HANDLER_NOTIFY            RT_BIT_32(29)
+/** Suspend the VM - debug only. */
+#define VM_FF_DEBUG_SUSPEND                 RT_BIT_32(31)
+
+
+/** This action forces the VM to service check and pending interrups on the APIC. */
+#define VMCPU_FF_INTERRUPT_APIC             RT_BIT_32(0)
+/** This action forces the VM to service check and pending interrups on the PIC. */
+#define VMCPU_FF_INTERRUPT_PIC              RT_BIT_32(1)
+/** This action forces the VM to schedule and run pending timer (TM). (bogus for now; needed for PATM backwards compatibility) */
+#define VMCPU_FF_TIMER                      RT_BIT_32(2)
+/** This action forces the VM to service pending requests from other
+ * thread or requests which must be executed in another context. */
+#define VMCPU_FF_REQUEST                    RT_BIT_32(9)
+/** This action forces the VM to resync the page tables before going
+ * back to execute guest code. (GLOBAL FLUSH) */
+#define VMCPU_FF_PGM_SYNC_CR3               RT_BIT_32(16)
+/** Same as VM_FF_PGM_SYNC_CR3 except that global pages can be skipped.
+ * (NON-GLOBAL FLUSH) */
+#define VMCPU_FF_PGM_SYNC_CR3_NON_GLOBAL    RT_BIT_32(17)
 /** Check the interupt and trap gates */
-#define VM_FF_TRPM_SYNC_IDT             RT_BIT_32(20)
+#define VMCPU_FF_TRPM_SYNC_IDT              RT_BIT_32(20)
 /** Check Guest's TSS ring 0 stack */
-#define VM_FF_SELM_SYNC_TSS             RT_BIT_32(21)
+#define VMCPU_FF_SELM_SYNC_TSS              RT_BIT_32(21)
 /** Check Guest's GDT table */
-#define VM_FF_SELM_SYNC_GDT             RT_BIT_32(22)
+#define VMCPU_FF_SELM_SYNC_GDT              RT_BIT_32(22)
 /** Check Guest's LDT table */
-#define VM_FF_SELM_SYNC_LDT             RT_BIT_32(23)
+#define VMCPU_FF_SELM_SYNC_LDT              RT_BIT_32(23)
 /** Inhibit interrupts pending. See EMGetInhibitInterruptsPC(). */
-#define VM_FF_INHIBIT_INTERRUPTS        RT_BIT_32(24)
-
+#define VMCPU_FF_INHIBIT_INTERRUPTS         RT_BIT_32(24)
 /** CSAM needs to scan the page that's being executed */
-#define VM_FF_CSAM_SCAN_PAGE            RT_BIT_32(26)
+#define VMCPU_FF_CSAM_SCAN_PAGE             RT_BIT_32(26)
 /** CSAM needs to do some homework. */
-#define VM_FF_CSAM_PENDING_ACTION       RT_BIT_32(27)
-
+#define VMCPU_FF_CSAM_PENDING_ACTION        RT_BIT_32(27)
 /** Force return to Ring-3. */
-#define VM_FF_TO_R3                     RT_BIT_32(28)
-
-/** REM needs to be informed about handler changes. */
-#define VM_FF_REM_HANDLER_NOTIFY        RT_BIT_32(29)
-
-/** Suspend the VM - debug only. */
-#define VM_FF_DEBUG_SUSPEND             RT_BIT_32(31)
-
-/** Externally forced actions. Used to quit the idle/wait loop. */
-#define VM_FF_EXTERNAL_SUSPENDED_MASK   (VM_FF_TERMINATE | VM_FF_DBGF | VM_FF_REQUEST)
-/** Externally forced actions. Used to quit the idle/wait loop. */
-#define VM_FF_EXTERNAL_HALTED_MASK      (VM_FF_TERMINATE | VM_FF_DBGF | VM_FF_TIMER | VM_FF_INTERRUPT_APIC | VM_FF_INTERRUPT_PIC | VM_FF_REQUEST | VM_FF_PDM_QUEUES | VM_FF_PDM_DMA)
-/** High priority pre-execution actions. */
-#define VM_FF_HIGH_PRIORITY_PRE_MASK    (VM_FF_TERMINATE | VM_FF_DBGF | VM_FF_INTERRUPT_APIC | VM_FF_INTERRUPT_PIC | VM_FF_TIMER | VM_FF_DEBUG_SUSPEND \
-                                        | VM_FF_PGM_SYNC_CR3 | VM_FF_PGM_SYNC_CR3_NON_GLOBAL | VM_FF_SELM_SYNC_TSS | VM_FF_TRPM_SYNC_IDT | VM_FF_SELM_SYNC_GDT | VM_FF_SELM_SYNC_LDT | VM_FF_PGM_NEED_HANDY_PAGES | VM_FF_PGM_NO_MEMORY)
-/** High priority pre raw-mode execution mask. */
-#define VM_FF_HIGH_PRIORITY_PRE_RAW_MASK (VM_FF_PGM_SYNC_CR3 | VM_FF_PGM_SYNC_CR3_NON_GLOBAL | VM_FF_SELM_SYNC_TSS | VM_FF_TRPM_SYNC_IDT | VM_FF_SELM_SYNC_GDT | VM_FF_SELM_SYNC_LDT \
-                                         | VM_FF_PGM_NEED_HANDY_PAGES | VM_FF_INHIBIT_INTERRUPTS | VM_FF_PGM_NO_MEMORY)
+#define VMCPU_FF_TO_R3                      RT_BIT_32(28)
+
+/** Externally VM forced actions. Used to quit the idle/wait loop. */
+#define VM_FF_EXTERNAL_SUSPENDED_MASK           (VM_FF_TERMINATE | VM_FF_DBGF | VM_FF_REQUEST)
+/** Externally VMCPU forced actions. Used to quit the idle/wait loop. */
+#define VMCPU_FF_EXTERNAL_SUSPENDED_MASK        (VMCPU_FF_REQUEST)
+
+/** Externally forced VM actions. Used to quit the idle/wait loop. */
+#define VM_FF_EXTERNAL_HALTED_MASK              (VM_FF_TERMINATE | VM_FF_DBGF | VM_FF_TIMER | VM_FF_REQUEST | VM_FF_PDM_QUEUES | VM_FF_PDM_DMA)
+/** Externally forced VMCPU actions. Used to quit the idle/wait loop. */
+#define VMCPU_FF_EXTERNAL_HALTED_MASK           (VMCPU_FF_INTERRUPT_APIC | VMCPU_FF_INTERRUPT_PIC | VMCPU_FF_REQUEST)
+
+/** High priority VM pre-execution actions. */
+#define VM_FF_HIGH_PRIORITY_PRE_MASK            (   VM_FF_TERMINATE | VM_FF_DBGF | VM_FF_TIMER | VM_FF_DEBUG_SUSPEND \
+                                                 |  VM_FF_PGM_NEED_HANDY_PAGES | VM_FF_PGM_NO_MEMORY)
+/** High priority VMCPU pre-execution actions. */
+#define VMCPU_FF_HIGH_PRIORITY_PRE_MASK         (   VMCPU_FF_INTERRUPT_APIC | VMCPU_FF_INTERRUPT_PIC  \
+                                                 |  VMCPU_FF_PGM_SYNC_CR3 | VMCPU_FF_PGM_SYNC_CR3_NON_GLOBAL | VMCPU_FF_SELM_SYNC_TSS | VMCPU_FF_TRPM_SYNC_IDT | VMCPU_FF_SELM_SYNC_GDT | VMCPU_FF_SELM_SYNC_LDT)
+
+/** High priority VM pre raw-mode execution mask. */
+#define VM_FF_HIGH_PRIORITY_PRE_RAW_MASK        (VM_FF_PGM_NEED_HANDY_PAGES | VM_FF_PGM_NO_MEMORY)
+/** High priority VMCPU pre raw-mode execution mask. */
+#define VMCPU_FF_HIGH_PRIORITY_PRE_RAW_MASK     (  VMCPU_FF_PGM_SYNC_CR3 | VMCPU_FF_PGM_SYNC_CR3_NON_GLOBAL | VMCPU_FF_SELM_SYNC_TSS | VMCPU_FF_TRPM_SYNC_IDT | VMCPU_FF_SELM_SYNC_GDT | VMCPU_FF_SELM_SYNC_LDT \
+                                                 | VMCPU_FF_INHIBIT_INTERRUPTS)
+
 /** High priority post-execution actions. */
-#define VM_FF_HIGH_PRIORITY_POST_MASK   (VM_FF_PDM_CRITSECT | VM_FF_CSAM_PENDING_ACTION | VM_FF_PGM_NO_MEMORY)
-/** Normal priority post-execution actions. */
-#define VM_FF_NORMAL_PRIORITY_POST_MASK (VM_FF_TERMINATE | VM_FF_DBGF | VM_FF_RESET | VM_FF_CSAM_SCAN_PAGE | VM_FF_PGM_NO_MEMORY)
+#define VM_FF_HIGH_PRIORITY_POST_MASK           (VM_FF_PDM_CRITSECT | VM_FF_PGM_NO_MEMORY)
+/** High priority post-execution actions. */
+#define VMCPU_FF_HIGH_PRIORITY_POST_MASK        (VMCPU_FF_CSAM_PENDING_ACTION)
+
+/** Normal priority VM post-execution actions. */
+#define VM_FF_NORMAL_PRIORITY_POST_MASK         (VM_FF_TERMINATE | VM_FF_DBGF | VM_FF_RESET | VM_FF_PGM_NO_MEMORY)
+/** Normal priority VMCPU post-execution actions. */
+#define VMCPU_FF_NORMAL_PRIORITY_POST_MASK      (VMCPU_FF_CSAM_SCAN_PAGE)
+
 /** Normal priority actions. */
-#define VM_FF_NORMAL_PRIORITY_MASK      (VM_FF_REQUEST | VM_FF_PDM_QUEUES | VM_FF_PDM_DMA | VM_FF_REM_HANDLER_NOTIFY)
+#define VM_FF_NORMAL_PRIORITY_MASK              (VM_FF_REQUEST | VM_FF_PDM_QUEUES | VM_FF_PDM_DMA | VM_FF_REM_HANDLER_NOTIFY)
+
 /** Flags to clear before resuming guest execution. */
-#define VM_FF_RESUME_GUEST_MASK         (VM_FF_TO_R3)
-/** Flags that causes the HWACCM loops to go back to ring-3. */
-#define VM_FF_HWACCM_TO_R3_MASK         (VM_FF_TO_R3 | VM_FF_TIMER | VM_FF_PGM_NEED_HANDY_PAGES | VM_FF_PGM_NO_MEMORY)
+#define VMCPU_FF_RESUME_GUEST_MASK              (VMCPU_FF_TO_R3)
+
+/** VM Flags that cause the HWACCM loops to go back to ring-3. */
+#define VM_FF_HWACCM_TO_R3_MASK                 (VM_FF_TIMER | VM_FF_PGM_NEED_HANDY_PAGES | VM_FF_PGM_NO_MEMORY)
+/** VMCPU Flags that cause the HWACCM loops to go back to ring-3. */
+#define VMCPU_FF_HWACCM_TO_R3_MASK               (VMCPU_FF_TO_R3)
+
 /** All the forced flags. */
-#define VM_FF_ALL_MASK                  (~0U)
-/** All the forced flags. */
-#define VM_FF_ALL_BUT_RAW_MASK          (~(VM_FF_HIGH_PRIORITY_PRE_RAW_MASK | VM_FF_CSAM_PENDING_ACTION | VM_FF_PDM_CRITSECT) | VM_FF_PGM_NO_MEMORY)
+#define VM_FF_ALL_MASK                          (~0U)
+/** All the forced VM flags. */
+#define VM_FF_ALL_BUT_RAW_MASK                  (~(VM_FF_HIGH_PRIORITY_PRE_RAW_MASK | VM_FF_PDM_CRITSECT) | VM_FF_PGM_NO_MEMORY)
+/** All the forced VMCPU flags. */
+#define VMCPU_FF_ALL_BUT_RAW_MASK               (~(VMCPU_FF_HIGH_PRIORITY_PRE_RAW_MASK | VMCPU_FF_CSAM_PENDING_ACTION))
 
 /** @} */
@@ -283,23 +310,22 @@
  */
 #if 1
-# define VM_FF_SET(pVM, fFlag)              ASMAtomicOrU32(&(pVM)->fForcedActions, (fFlag))
+# define VM_FF_SET(pVM, fFlag)              ASMAtomicOrU32(&(pVM)->fGlobalForcedActions, (fFlag))
 #else
 # define VM_FF_SET(pVM, fFlag) \
-    do { ASMAtomicOrU32(&(pVM)->fForcedActions, (fFlag)); \
-         RTLogPrintf("VM_FF_SET  : %08x %s - %s(%d) %s\n", (pVM)->fForcedActions, #fFlag, __FILE__, __LINE__, __FUNCTION__); \
+    do { ASMAtomicOrU32(&(pVM)->fGlobalForcedActions, (fFlag)); \
+         RTLogPrintf("VM_FF_SET  : %08x %s - %s(%d) %s\n", (pVM)->fGlobalForcedActions, #fFlag, __FILE__, __LINE__, __FUNCTION__); \
     } while (0)
 #endif
 
 /** @def VMCPU_FF_SET
- * Sets a force action flag for given VCPU.
- *
- * @param   pVM     VM Handle.
- * @param   idCpu   Virtual CPU ID.
+ * Sets a force action flag for the given VCPU.
+ *
+ * @param   pVCpu     VMCPU Handle.
  * @param   fFlag   The flag to set.
  */
-#ifdef VBOX_WITH_SMP_GUESTS
-# define VMCPU_FF_SET(pVM, idCpu, fFlag)    ASMAtomicOrU32(&(pVM)->aCpu[idCpu].fForcedActions, (fFlag))
-#else
-# define VMCPU_FF_SET(pVM, idCpu, fFlag)    VM_FF_SET(pVM, fFlag)
+#if 1 //def VBOX_WITH_SMP_GUESTS
+# define VMCPU_FF_SET(pVCpu, fFlag)    ASMAtomicOrU32(&(pVCpu)->fLocalForcedActions, (fFlag))
+#else
+# define VMCPU_FF_SET(pVCpu, fFlag)    ASMAtomicOrU32(&(pVCpu)->CTX_SUFF(pVM)->fGlobalForcedActions, (fFlag))
 #endif
 
@@ -311,23 +337,22 @@
  */
 #if 1
-# define VM_FF_CLEAR(pVM, fFlag)            ASMAtomicAndU32(&(pVM)->fForcedActions, ~(fFlag))
+# define VM_FF_CLEAR(pVM, fFlag)            ASMAtomicAndU32(&(pVM)->fGlobalForcedActions, ~(fFlag))
 #else
 # define VM_FF_CLEAR(pVM, fFlag) \
-    do { ASMAtomicAndU32(&(pVM)->fForcedActions, ~(fFlag)); \
-         RTLogPrintf("VM_FF_CLEAR: %08x %s - %s(%d) %s\n", (pVM)->fForcedActions, #fFlag, __FILE__, __LINE__, __FUNCTION__); \
+    do { ASMAtomicAndU32(&(pVM)->fGlobalForcedActions, ~(fFlag)); \
+         RTLogPrintf("VM_FF_CLEAR: %08x %s - %s(%d) %s\n", (pVM)->fGlobalForcedActions, #fFlag, __FILE__, __LINE__, __FUNCTION__); \
     } while (0)
 #endif
 
 /** @def VMCPU_FF_CLEAR
- * Clears a force action flag for given VCPU.
- *
- * @param   pVM     VM Handle.
- * @param   idCpu   Virtual CPU ID.
+ * Clears a force action flag for the given VCPU.
+ *
+ * @param   pVCpu     VMCPU Handle.
  * @param   fFlag   The flag to clear.
  */
-#ifdef VBOX_WITH_SMP_GUESTS
-# define VMCPU_FF_CLEAR(pVM, idCpu, fFlag)  ASMAtomicAndU32(&(pVM)->aCpu[idCpu].fForcedActions, ~(fFlag))
-#else
-# define VMCPU_FF_CLEAR(pVM, idCpu, fFlag)  VM_FF_CLEAR(pVM, fFlag)
+#if 1 //def VBOX_WITH_SMP_GUESTS
+# define VMCPU_FF_CLEAR(pVCpu, fFlag)  ASMAtomicAndU32(&(pVCpu)->fLocalForcedActions, ~(fFlag))
+#else
+# define VMCPU_FF_CLEAR(pVCpu, fFlag)  ASMAtomicAndU32(&(pVCpu)->CTX_SUFF(pVM)->fGlobalForcedActions, ~(fFlag))
 #endif
 
@@ -338,17 +363,16 @@
  * @param   fFlag   The flag to check.
  */
-#define VM_FF_ISSET(pVM, fFlag)             (((pVM)->fForcedActions & (fFlag)) == (fFlag))
+#define VM_FF_ISSET(pVM, fFlag)             (((pVM)->fGlobalForcedActions & (fFlag)) == (fFlag))
 
 /** @def VMCPU_FF_ISSET
- * Checks if a force action flag is set for given VCPU.
- *
- * @param   pVM     VM Handle.
- * @param   idCpu   Virtual CPU ID.
+ * Checks if a force action flag is set for the given VCPU.
+ *
+ * @param   pVCpu     VMCPU Handle.
  * @param   fFlag   The flag to check.
  */
-#ifdef VBOX_WITH_SMP_GUESTS
-# define VMCPU_FF_ISSET(pVM, idCpu, fFlag)  (((pVM)->aCpu[idCpu].fForcedActions & (fFlag)) == (fFlag))
-#else
-# define VMCPU_FF_ISSET(pVM, idCpu, fFlag)  VM_FF_ISSET(pVM, fFlag)
+#if 1 //def VBOX_WITH_SMP_GUESTS
+# define VMCPU_FF_ISSET(pVCpu, fFlag)  (((pVCpu)->fLocalForcedActions & (fFlag)) == (fFlag))
+#else
+# define VMCPU_FF_ISSET(pVCpu, fFlag)  (((pVCpu)->CTX_SUFF(pVM)->fGlobalForcedActions & (fFlag)) == (fFlag))
 #endif
 
@@ -359,17 +383,16 @@
  * @param   fFlags  The flags to check for.
  */
-#define VM_FF_ISPENDING(pVM, fFlags)        ((pVM)->fForcedActions & (fFlags))
+#define VM_FF_ISPENDING(pVM, fFlags)        ((pVM)->fGlobalForcedActions & (fFlags))
 
 /** @def VMCPU_FF_ISPENDING
- * Checks if one or more force action in the specified set is pending for given VCPU.
- *
- * @param   pVM     VM Handle.
- * @param   idCpu   Virtual CPU ID.
+ * Checks if one or more force action in the specified set is pending for the given VCPU.
+ *
+ * @param   pVCpu     VMCPU Handle.
  * @param   fFlags  The flags to check for.
  */
-#ifdef VBOX_WITH_SMP_GUESTS
-# define VMCPU_FF_ISPENDING(pVM, idCpu, fFlags) ((pVM)->aCpu[idCpu].fForcedActions & (fFlags))
-#else
-# define VMCPU_FF_ISPENDING(pVM, idCpu, fFlags) VM_FF_ISPENDING(pVM, fFlags)
+#if 1 //def VBOX_WITH_SMP_GUESTS
+# define VMCPU_FF_ISPENDING(pVCpu, fFlags) ((pVCpu)->fLocalForcedActions & (fFlags))
+#else
+# define VMCPU_FF_ISPENDING(pVCpu, fFlags) ((pVCpu)->CTX_SUFF(pVM)->fGlobalForcedActions & (fFlags))
 #endif
 
@@ -382,19 +405,18 @@
  * @param   fExcpt  The flags that should not be set.
  */
-#define VM_FF_IS_PENDING_EXCEPT(pVM, fFlags, fExcpt)            ( ((pVM)->fForcedActions & (fFlags)) && !((pVM)->fForcedActions & (fExcpt)) )
+#define VM_FF_IS_PENDING_EXCEPT(pVM, fFlags, fExcpt)            ( ((pVM)->fGlobalForcedActions & (fFlags)) && !((pVM)->fGlobalForcedActions & (fExcpt)) )
 
 /** @def VMCPU_FF_IS_PENDING_EXCEPT
- * Checks if one or more force action in the specified set is pending for given
+ * Checks if one or more force action in the specified set is pending for the given
  * VCPU while one or more other ones are not.
  *
- * @param   pVM     VM Handle.
- * @param   idCpu   Virtual CPU ID.
+ * @param   pVCpu     VMCPU Handle.
  * @param   fFlags  The flags to check for.
  * @param   fExcpt  The flags that should not be set.
  */
-#ifdef VBOX_WITH_SMP_GUESTS
-# define VMCPU_FF_IS_PENDING_EXCEPT(pVM, idCpu, fFlags, fExcpt) ( ((pVM)->aCpu[idCpu].fForcedActions & (fFlags)) && !((pVM)->aCpu[idCpu].fForcedActions & (fExcpt)) )
-#else
-# define VMCPU_FF_IS_PENDING_EXCEPT(pVM, idCpu, fFlags, fExcpt) VM_FF_ISPENDING(pVM, fFlags, fExcpt)
+#if 1 //def VBOX_WITH_SMP_GUESTS
+# define VMCPU_FF_IS_PENDING_EXCEPT(pVCpu, fFlags, fExcpt) ( ((pVCpu)->fLocalForcedActions & (fFlags)) && !((pVCpu)->fLocalForcedActions & (fExcpt)) )
+#else
+# define VMCPU_FF_IS_PENDING_EXCEPT(pVCpu, fFlags, fExcpt) ( ((pVCpu)->CTX_SUFF(pVM)->fGlobalForcedActions & (fFlags)) && !((pVCpu)->CTX_SUFF(pVM)->fGlobalForcedActions & (fExcpt)) )
 #endif
 
@@ -487,5 +509,5 @@
      * See the VM_FF_* \#defines. Updated atomically.
      */
-    volatile uint32_t           fForcedActions;
+    volatile uint32_t           fGlobalForcedActions;
     /** Pointer to the array of page descriptors for the VM structure allocation. */
     R3PTRTYPE(PSUPPAGE)         paVMPagesR3;
Index: /trunk/include/VBox/vm.mac
===================================================================
--- /trunk/include/VBox/vm.mac	(revision 19140)
+++ /trunk/include/VBox/vm.mac	(revision 19141)
@@ -35,12 +35,12 @@
 
 ;/** This action forces the VM to service check and pending interrups on the APIC. */
-%define VM_FF_INTERRUPT_APIC            (1 << 0)
+%define VMCPU_FF_INTERRUPT_APIC            (1 << 0)
 ;/** This action forces the VM to service check and pending interrups on the PIC. */
-%define VM_FF_INTERRUPT_PIC             (1 << 1)
+%define VMCPU_FF_INTERRUPT_PIC             (1 << 1)
 ;/** This action forces the VM to schedule and run pending timer (TM). */
-%define VM_FF_TIMER                     (1 << 2)
+%define VMCPU_FF_TIMER                     (1 << 2)
 ;/** This action forces the VM to service pending requests from other
 ; * thread or requests which must be executed in another context. */
-%define VM_FF_REQUEST                   (1 << 9)
+%define VMCPU_FF_REQUEST                   (1 << 9)
 
 ;;
@@ -48,5 +48,5 @@
 struc VM
     .enmVMState         resd 1
-    .fForcedActions     resd 1
+    .fGlobalForcedActions resd 1
     .paVMPagesR3        RTR3PTR_RES 1
     .pSession           RTR0PTR_RES 1
@@ -105,16 +105,16 @@
 ; This is part of  the VMCPU structure.
 struc VMCPU
-    .fForcedActions     resd 1
-    .enmState           resd 1
-    .pVMR3              RTR3PTR_RES 1
-    .pVMR0              RTR0PTR_RES 1
-    .pVMRC              RTRCPTR_RES 1
-    .idCpu              resd 1
+    .fLocalForcedActions resd 1
+    .enmState            resd 1
+    .pVMR3               RTR3PTR_RES 1
+    .pVMR0               RTR0PTR_RES 1
+    .pVMRC               RTRCPTR_RES 1
+    .idCpu               resd 1
 
-    .hNativeThread      RTR0PTR_RES 1
+    .hNativeThread       RTR0PTR_RES 1
 
     alignb 64
 
-    .cpum               resb 2048
+    .cpum                resb 4096
 endstruc
 
Index: /trunk/include/VBox/vmapi.h
===================================================================
--- /trunk/include/VBox/vmapi.h	(revision 19140)
+++ /trunk/include/VBox/vmapi.h	(revision 19141)
@@ -432,5 +432,5 @@
 VMMR3DECL(void) VMR3NotifyFF(PVM pVM, bool fNotifiedREM);
 VMMR3DECL(void) VMR3NotifyFFU(PUVM pUVM, bool fNotifiedREM);
-VMMR3DECL(int)  VMR3WaitHalted(PVM pVM, bool fIgnoreInterrupts);
+VMMR3DECL(int)  VMR3WaitHalted(PVM pVM, PVMCPU pVCpu, bool fIgnoreInterrupts);
 VMMR3DECL(int)  VMR3WaitU(PUVM pUVM);
 VMMR3DECL(RTCPUID)          VMR3GetVMCPUId(PVM pVM);
Index: /trunk/src/VBox/VMM/DBGF.cpp
===================================================================
--- /trunk/src/VBox/VMM/DBGF.cpp	(revision 19140)
+++ /trunk/src/VBox/VMM/DBGF.cpp	(revision 19141)
@@ -296,5 +296,5 @@
      * Clear the FF DBGF request flag.
      */
-    Assert(pVM->fForcedActions & VM_FF_DBGF);
+    Assert(pVM->fGlobalForcedActions & VM_FF_DBGF);
     VM_FF_CLEAR(pVM, VM_FF_DBGF);
 
Index: /trunk/src/VBox/VMM/EM.cpp
===================================================================
--- /trunk/src/VBox/VMM/EM.cpp	(revision 19140)
+++ /trunk/src/VBox/VMM/EM.cpp	(revision 19141)
@@ -926,5 +926,5 @@
             if (VM_FF_ISPENDING(pVM, VM_FF_REQUEST | VM_FF_TIMER | VM_FF_PDM_QUEUES | VM_FF_DBGF | VM_FF_TERMINATE | VM_FF_RESET))
             {
-                LogFlow(("emR3RemExecute: Skipping run, because FF is set. %#x\n", pVM->fForcedActions));
+                LogFlow(("emR3RemExecute: Skipping run, because FF is set. %#x\n", pVM->fGlobalForcedActions));
                 goto l_REMDoForcedActions;
             }
@@ -943,5 +943,6 @@
          * Deal with high priority post execution FFs before doing anything else.
          */
-        if (VM_FF_ISPENDING(pVM, VM_FF_HIGH_PRIORITY_POST_MASK))
+        if (    VM_FF_ISPENDING(pVM, VM_FF_HIGH_PRIORITY_POST_MASK)
+            ||  VMCPU_FF_ISPENDING(pVCpu, VMCPU_FF_HIGH_PRIORITY_POST_MASK))
             rc = emR3HighPriorityPostForcedActions(pVM, pVCpu, rc);
 
@@ -973,5 +974,6 @@
         TMTimerPoll(pVM);
 #endif
-        if (VM_FF_ISPENDING(pVM, VM_FF_ALL_BUT_RAW_MASK & ~(VM_FF_CSAM_PENDING_ACTION | VM_FF_CSAM_SCAN_PAGE)))
+        if (    VM_FF_ISPENDING(pVM, VM_FF_ALL_BUT_RAW_MASK)
+            ||  VMCPU_FF_ISPENDING(pVCpu, VMCPU_FF_ALL_BUT_RAW_MASK & ~(VMCPU_FF_CSAM_PENDING_ACTION | VMCPU_FF_CSAM_SCAN_PAGE)))
         {
 l_REMDoForcedActions:
@@ -1037,5 +1039,5 @@
     Log(("emR3RawStep: cs:eip=%RTsel:%RGr efl=%RGr - returned from GC with rc=%Rrc\n", pCtx->cs, pCtx->eip, pCtx->eflags, rc));
     rc = CPUMRawLeave(pVCpu, NULL, rc);
-    VM_FF_CLEAR(pVM, VM_FF_RESUME_GUEST_MASK);
+    VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_RESUME_GUEST_MASK);
 
     /*
@@ -1073,5 +1075,6 @@
          * Check vital forced actions, but ignore pending interrupts and timers.
          */
-        if (VM_FF_ISPENDING(pVM, VM_FF_HIGH_PRIORITY_PRE_RAW_MASK))
+        if (    VM_FF_ISPENDING(pVM, VM_FF_HIGH_PRIORITY_PRE_RAW_MASK)
+            ||  VMCPU_FF_ISPENDING(pVCpu, VMCPU_FF_HIGH_PRIORITY_PRE_RAW_MASK))
         {
             rc = emR3RawForcedActions(pVM, pVCpu, pCtx);
@@ -1106,5 +1109,5 @@
              || rc == VINF_EM_RAW_INTERRUPT);
     rc = CPUMRawLeave(pVCpu, NULL, rc);
-    VM_FF_CLEAR(pVM, VM_FF_RESUME_GUEST_MASK);
+    VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_RESUME_GUEST_MASK);
 
     /*
@@ -1142,10 +1145,11 @@
     int         rc;
     PCPUMCTX    pCtx   = pVCpu->em.s.pCtx;
-    VM_FF_CLEAR(pVM, (VM_FF_SELM_SYNC_GDT | VM_FF_SELM_SYNC_LDT | VM_FF_TRPM_SYNC_IDT | VM_FF_SELM_SYNC_TSS));
+    VMCPU_FF_CLEAR(pVCpu, (VMCPU_FF_SELM_SYNC_GDT | VMCPU_FF_SELM_SYNC_LDT | VMCPU_FF_TRPM_SYNC_IDT | VMCPU_FF_SELM_SYNC_TSS));
 
     /*
      * Check vital forced actions, but ignore pending interrupts and timers.
      */
-    if (VM_FF_ISPENDING(pVM, VM_FF_HIGH_PRIORITY_PRE_RAW_MASK))
+    if (    VM_FF_ISPENDING(pVM, VM_FF_HIGH_PRIORITY_PRE_RAW_MASK)
+        ||  VMCPU_FF_ISPENDING(pVCpu, VMCPU_FF_HIGH_PRIORITY_PRE_RAW_MASK))
     {
         rc = emR3RawForcedActions(pVM, pVCpu, pCtx);
@@ -1167,5 +1171,5 @@
     } while (   rc == VINF_SUCCESS
              || rc == VINF_EM_RAW_INTERRUPT);
-    VM_FF_CLEAR(pVM, VM_FF_RESUME_GUEST_MASK);
+    VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_RESUME_GUEST_MASK);
 
     /*
@@ -2113,5 +2117,5 @@
                 case OP_STI:
                     pCtx->eflags.u32 |= X86_EFL_IF;
-                    EMSetInhibitInterruptsPC(pVM, pVCpu, pCtx->rip + Cpu.opsize);
+                    EMSetInhibitInterruptsPC(pVCpu, pCtx->rip + Cpu.opsize);
                     Assert(Cpu.opsize == 1);
                     pCtx->rip += Cpu.opsize;
@@ -2360,6 +2364,6 @@
          */
         case VINF_PGM_SYNC_CR3:
-            AssertMsg(VM_FF_ISPENDING(pVM, VM_FF_PGM_SYNC_CR3 | VM_FF_PGM_SYNC_CR3_NON_GLOBAL),
-                      ("VINF_PGM_SYNC_CR3 and no VM_FF_PGM_SYNC_CR3*!\n"));
+            AssertMsg(VMCPU_FF_ISPENDING(pVCpu, VMCPU_FF_PGM_SYNC_CR3 | VMCPU_FF_PGM_SYNC_CR3_NON_GLOBAL),
+                      ("VINF_PGM_SYNC_CR3 and no VMCPU_FF_PGM_SYNC_CR3*!\n"));
             rc = VINF_SUCCESS;
             break;
@@ -2587,5 +2591,5 @@
      * Sync selector tables.
      */
-    if (VM_FF_ISPENDING(pVM, VM_FF_SELM_SYNC_GDT | VM_FF_SELM_SYNC_LDT))
+    if (VMCPU_FF_ISPENDING(pVCpu, VMCPU_FF_SELM_SYNC_GDT | VMCPU_FF_SELM_SYNC_LDT))
     {
         int rc = SELMR3UpdateFromCPUM(pVM, pVCpu);
@@ -2601,11 +2605,11 @@
      * PGMSyncCR3+pgmPoolClearAll is pending.
      */
-    if (VM_FF_ISPENDING(pVM, VM_FF_TRPM_SYNC_IDT))
-    {
-        if (   VM_FF_ISPENDING(pVM, VM_FF_PGM_SYNC_CR3)
+    if (VMCPU_FF_ISPENDING(pVCpu, VMCPU_FF_TRPM_SYNC_IDT))
+    {
+        if (   VMCPU_FF_ISPENDING(pVCpu, VMCPU_FF_PGM_SYNC_CR3)
             && EMIsRawRing0Enabled(pVM)
             && CSAMIsEnabled(pVM))
         {
-            int rc = PGMSyncCR3(pVCpu, pCtx->cr0, pCtx->cr3, pCtx->cr4, VM_FF_ISSET(pVM, VM_FF_PGM_SYNC_CR3));
+            int rc = PGMSyncCR3(pVCpu, pCtx->cr0, pCtx->cr3, pCtx->cr4, VMCPU_FF_ISSET(pVCpu, VMCPU_FF_PGM_SYNC_CR3));
             if (RT_FAILURE(rc))
                 return rc;
@@ -2620,5 +2624,5 @@
      * Sync TSS.
      */
-    if (VM_FF_ISPENDING(pVM, VM_FF_SELM_SYNC_TSS))
+    if (VMCPU_FF_ISPENDING(pVCpu, VMCPU_FF_SELM_SYNC_TSS))
     {
         int rc = SELMR3SyncTSS(pVM, pVCpu);
@@ -2630,11 +2634,11 @@
      * Sync page directory.
      */
-    if (VM_FF_ISPENDING(pVM, VM_FF_PGM_SYNC_CR3 | VM_FF_PGM_SYNC_CR3_NON_GLOBAL))
-    {
-        int rc = PGMSyncCR3(pVCpu, pCtx->cr0, pCtx->cr3, pCtx->cr4, VM_FF_ISSET(pVM, VM_FF_PGM_SYNC_CR3));
+    if (VMCPU_FF_ISPENDING(pVCpu, VMCPU_FF_PGM_SYNC_CR3 | VMCPU_FF_PGM_SYNC_CR3_NON_GLOBAL))
+    {
+        int rc = PGMSyncCR3(pVCpu, pCtx->cr0, pCtx->cr3, pCtx->cr4, VMCPU_FF_ISSET(pVCpu, VMCPU_FF_PGM_SYNC_CR3));
         if (RT_FAILURE(rc))
             return rc;
 
-        Assert(!VM_FF_ISPENDING(pVM, VM_FF_SELM_SYNC_GDT | VM_FF_SELM_SYNC_LDT));
+        Assert(!VMCPU_FF_ISPENDING(pVCpu, VMCPU_FF_SELM_SYNC_GDT | VMCPU_FF_SELM_SYNC_LDT));
 
         /* Prefetch pages for EIP and ESP. */
@@ -2650,10 +2654,10 @@
                 return rc;
             }
-            rc = PGMSyncCR3(pVCpu, pCtx->cr0, pCtx->cr3, pCtx->cr4, VM_FF_ISSET(pVM, VM_FF_PGM_SYNC_CR3));
+            rc = PGMSyncCR3(pVCpu, pCtx->cr0, pCtx->cr3, pCtx->cr4, VMCPU_FF_ISSET(pVCpu, VMCPU_FF_PGM_SYNC_CR3));
             if (RT_FAILURE(rc))
                 return rc;
         }
         /** @todo maybe prefetch the supervisor stack page as well */
-        Assert(!VM_FF_ISPENDING(pVM, VM_FF_SELM_SYNC_GDT | VM_FF_SELM_SYNC_LDT));
+        Assert(!VMCPU_FF_ISPENDING(pVCpu, VMCPU_FF_SELM_SYNC_GDT | VMCPU_FF_SELM_SYNC_LDT));
     }
 
@@ -2726,5 +2730,5 @@
                   || PATMShouldUseRawMode(pVM, (RTGCPTR)pCtx->eip),
                   ("Tried to execute code with IF at EIP=%08x!\n", pCtx->eip));
-        if (    !VM_FF_ISPENDING(pVM, VM_FF_PGM_SYNC_CR3 | VM_FF_PGM_SYNC_CR3_NON_GLOBAL)
+        if (    !VMCPU_FF_ISPENDING(pVCpu, VMCPU_FF_PGM_SYNC_CR3 | VMCPU_FF_PGM_SYNC_CR3_NON_GLOBAL)
             &&  PGMMapHasConflicts(pVM))
         {
@@ -2738,5 +2742,6 @@
          * Process high priority pre-execution raw-mode FFs.
          */
-        if (VM_FF_ISPENDING(pVM, VM_FF_HIGH_PRIORITY_PRE_RAW_MASK))
+        if (    VM_FF_ISPENDING(pVM, VM_FF_HIGH_PRIORITY_PRE_RAW_MASK)
+            ||  VMCPU_FF_ISPENDING(pVCpu, VMCPU_FF_HIGH_PRIORITY_PRE_RAW_MASK))
         {
             rc = emR3RawForcedActions(pVM, pVCpu, pCtx);
@@ -2767,5 +2772,6 @@
             CSAMR3CheckCodeEx(pVM, CPUMCTX2CORE(pCtx), pCtx->eip);
             STAM_PROFILE_ADV_RESUME(&pVCpu->em.s.StatRAWEntry, b);
-            if (VM_FF_ISPENDING(pVM, VM_FF_HIGH_PRIORITY_PRE_RAW_MASK))
+            if (    VM_FF_ISPENDING(pVM, VM_FF_HIGH_PRIORITY_PRE_RAW_MASK)
+                ||  VMCPU_FF_ISPENDING(pVCpu, VMCPU_FF_HIGH_PRIORITY_PRE_RAW_MASK))
             {
                 rc = emR3RawForcedActions(pVM, pVCpu, pCtx);
@@ -2817,6 +2823,7 @@
          */
         rc = CPUMRawLeave(pVCpu, NULL, rc);
-        VM_FF_CLEAR(pVM, VM_FF_RESUME_GUEST_MASK);
-        if (VM_FF_ISPENDING(pVM, VM_FF_HIGH_PRIORITY_POST_MASK))
+        VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_RESUME_GUEST_MASK);
+        if (    VM_FF_ISPENDING(pVM, VM_FF_HIGH_PRIORITY_POST_MASK)
+            ||  VMCPU_FF_ISPENDING(pVCpu, VMCPU_FF_HIGH_PRIORITY_POST_MASK))
             rc = emR3HighPriorityPostForcedActions(pVM, pVCpu, rc);
 
@@ -2825,5 +2832,5 @@
          * Assert TSS consistency & rc vs patch code.
          */
-        if (   !VM_FF_ISPENDING(pVM, VM_FF_SELM_SYNC_TSS | VM_FF_SELM_SYNC_GDT) /* GDT implies TSS at the moment. */
+        if (   !VMCPU_FF_ISPENDING(pVCpu, VMCPU_FF_SELM_SYNC_TSS | VMCPU_FF_SELM_SYNC_GDT) /* GDT implies TSS at the moment. */
             &&  EMIsRawRing0Enabled(pVM))
             SELMR3CheckTSS(pVM);
@@ -2849,5 +2856,5 @@
          * Let's go paranoid!
          */
-        if (    !VM_FF_ISPENDING(pVM, VM_FF_PGM_SYNC_CR3 | VM_FF_PGM_SYNC_CR3_NON_GLOBAL)
+        if (    !VMCPU_FF_ISPENDING(pVCpu, VMCPU_FF_PGM_SYNC_CR3 | VMCPU_FF_PGM_SYNC_CR3_NON_GLOBAL)
             &&  PGMMapHasConflicts(pVM))
         {
@@ -2884,5 +2891,6 @@
 #endif
         STAM_PROFILE_ADV_STOP(&pVCpu->em.s.StatRAWTail, d);
-        if (VM_FF_ISPENDING(pVM, ~VM_FF_HIGH_PRIORITY_PRE_RAW_MASK | VM_FF_PGM_NO_MEMORY))
+        if (    VM_FF_ISPENDING(pVM, ~VM_FF_HIGH_PRIORITY_PRE_RAW_MASK | VM_FF_PGM_NO_MEMORY)
+            ||  VMCPU_FF_ISPENDING(pVCpu, ~VMCPU_FF_HIGH_PRIORITY_PRE_RAW_MASK))
         {
             Assert(pCtx->eflags.Bits.u1VM || (pCtx->ss & X86_SEL_RPL) != 1);
@@ -2953,6 +2961,7 @@
          * Process high priority pre-execution raw-mode FFs.
          */
-        VM_FF_CLEAR(pVM, (VM_FF_SELM_SYNC_GDT | VM_FF_SELM_SYNC_LDT | VM_FF_TRPM_SYNC_IDT | VM_FF_SELM_SYNC_TSS)); /* not relevant in HWACCM mode; shouldn't be set really. */
-        if (VM_FF_ISPENDING(pVM, VM_FF_HIGH_PRIORITY_PRE_RAW_MASK))
+        VMCPU_FF_CLEAR(pVCpu, (VMCPU_FF_SELM_SYNC_GDT | VMCPU_FF_SELM_SYNC_LDT | VMCPU_FF_TRPM_SYNC_IDT | VMCPU_FF_SELM_SYNC_TSS)); /* not relevant in HWACCM mode; shouldn't be set really. */
+        if (    VM_FF_ISPENDING(pVM, VM_FF_HIGH_PRIORITY_PRE_RAW_MASK)
+            ||  VMCPU_FF_ISPENDING(pVCpu, VMCPU_FF_HIGH_PRIORITY_PRE_RAW_MASK))
         {
             rc = emR3RawForcedActions(pVM, pVCpu, pCtx);
@@ -2990,6 +2999,7 @@
          * Deal with high priority post execution FFs before doing anything else.
          */
-        VM_FF_CLEAR(pVM, VM_FF_RESUME_GUEST_MASK);
-        if (VM_FF_ISPENDING(pVM, VM_FF_HIGH_PRIORITY_POST_MASK))
+        VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_RESUME_GUEST_MASK);
+        if (    VM_FF_ISPENDING(pVM, VM_FF_HIGH_PRIORITY_POST_MASK)
+            ||  VMCPU_FF_ISPENDING(pVCpu, VMCPU_FF_HIGH_PRIORITY_POST_MASK))
             rc = emR3HighPriorityPostForcedActions(pVM, pVCpu, rc);
 
@@ -3194,6 +3204,6 @@
         PDMR3CritSectFF(pVM);
 
-    if (VM_FF_ISPENDING(pVM, VM_FF_CSAM_PENDING_ACTION))
-        CSAMR3DoPendingAction(pVM);
+    if (VMCPU_FF_ISPENDING(pVCpu, VMCPU_FF_CSAM_PENDING_ACTION))
+        CSAMR3DoPendingAction(pVM, pVCpu);
 
     if (VM_FF_ISPENDING(pVM, VM_FF_PGM_NO_MEMORY))
@@ -3246,5 +3256,6 @@
      * Post execution chunk first.
      */
-    if (VM_FF_ISPENDING(pVM, VM_FF_NORMAL_PRIORITY_POST_MASK))
+    if (    VM_FF_ISPENDING(pVM, VM_FF_NORMAL_PRIORITY_POST_MASK)
+        ||  VMCPU_FF_ISPENDING(pVCpu, VMCPU_FF_NORMAL_PRIORITY_POST_MASK))
     {
         /*
@@ -3280,13 +3291,14 @@
          * CSAM page scanning.
          */
-        if (VM_FF_IS_PENDING_EXCEPT(pVM, VM_FF_CSAM_SCAN_PAGE, VM_FF_PGM_NO_MEMORY))
+        if (    !VM_FF_ISPENDING(pVM, VM_FF_PGM_NO_MEMORY)
+            &&  VMCPU_FF_ISPENDING(pVCpu, VMCPU_FF_CSAM_SCAN_PAGE))
         {
             PCPUMCTX pCtx = pVCpu->em.s.pCtx;
 
             /** @todo: check for 16 or 32 bits code! (D bit in the code selector) */
-            Log(("Forced action VM_FF_CSAM_SCAN_PAGE\n"));
+            Log(("Forced action VMCPU_FF_CSAM_SCAN_PAGE\n"));
 
             CSAMR3CheckCodeEx(pVM, CPUMCTX2CORE(pCtx), pCtx->eip);
-            VM_FF_CLEAR(pVM, VM_FF_CSAM_SCAN_PAGE);
+            VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_CSAM_SCAN_PAGE);
         }
 
@@ -3303,5 +3315,6 @@
 
         /* check that we got them all  */
-        Assert(!(VM_FF_NORMAL_PRIORITY_POST_MASK & ~(VM_FF_TERMINATE | VM_FF_DBGF | VM_FF_RESET | VM_FF_CSAM_SCAN_PAGE | VM_FF_PGM_NO_MEMORY)));
+        Assert(!(VM_FF_NORMAL_PRIORITY_POST_MASK & ~(VM_FF_TERMINATE | VM_FF_DBGF | VM_FF_RESET | VM_FF_PGM_NO_MEMORY)));
+        Assert(!(VMCPU_FF_NORMAL_PRIORITY_POST_MASK & ~(VMCPU_FF_CSAM_SCAN_PAGE)));
     }
 
@@ -3351,5 +3364,6 @@
      * (Executed in ascending priority order.)
      */
-    if (VM_FF_ISPENDING(pVM, VM_FF_HIGH_PRIORITY_PRE_MASK))
+    if (    VM_FF_ISPENDING(pVM, VM_FF_HIGH_PRIORITY_PRE_MASK)
+        ||  VMCPU_FF_ISPENDING(pVCpu, VM_FF_HIGH_PRIORITY_PRE_MASK))
     {
         /*
@@ -3362,8 +3376,9 @@
          * The instruction following an emulated STI should *always* be executed!
          */
-        if (VM_FF_IS_PENDING_EXCEPT(pVM, VM_FF_INHIBIT_INTERRUPTS, VM_FF_PGM_NO_MEMORY))
-        {
-            Log(("VM_FF_EMULATED_STI at %RGv successor %RGv\n", (RTGCPTR)CPUMGetGuestRIP(pVCpu), EMGetInhibitInterruptsPC(pVM, pVCpu)));
-            if (CPUMGetGuestEIP(pVCpu) != EMGetInhibitInterruptsPC(pVM, pVCpu))
+        if (    !VM_FF_ISPENDING(pVM, VM_FF_PGM_NO_MEMORY)
+            &&  VMCPU_FF_ISPENDING(pVCpu, VMCPU_FF_INHIBIT_INTERRUPTS))
+        {
+            Log(("VM_FF_EMULATED_STI at %RGv successor %RGv\n", (RTGCPTR)CPUMGetGuestRIP(pVCpu), EMGetInhibitInterruptsPC(pVCpu)));
+            if (CPUMGetGuestEIP(pVCpu) != EMGetInhibitInterruptsPC(pVCpu))
             {
                 /* Note: we intentionally don't clear VM_FF_INHIBIT_INTERRUPTS here if the eip is the same as the inhibited instr address.
@@ -3372,5 +3387,5 @@
                  *  break the guest. Sounds very unlikely, but such timing sensitive problem are not as rare as you might think.
                  */
-                VM_FF_CLEAR(pVM, VM_FF_INHIBIT_INTERRUPTS);
+                VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_INHIBIT_INTERRUPTS);
             }
             if (HWACCMR3IsActive(pVM))
@@ -3385,5 +3400,6 @@
          * Interrupts.
          */
-        if (    !VM_FF_ISPENDING(pVM, VM_FF_INHIBIT_INTERRUPTS | VM_FF_PGM_NO_MEMORY)
+        if (    !VM_FF_ISPENDING(pVM, VM_FF_PGM_NO_MEMORY)
+            &&  !VMCPU_FF_ISPENDING(pVCpu, VMCPU_FF_INHIBIT_INTERRUPTS)
             &&  (!rc || rc >= VINF_EM_RESCHEDULE_HWACC)
             &&  !TRPMHasTrap(pVCpu) /* an interrupt could already be scheduled for dispatching in the recompiler. */
@@ -3391,5 +3407,5 @@
             &&  !HWACCMR3IsEventPending(pVM))
         {
-            if (VM_FF_ISPENDING(pVM, VM_FF_INTERRUPT_APIC | VM_FF_INTERRUPT_PIC))
+            if (VMCPU_FF_ISPENDING(pVCpu, VMCPU_FF_INTERRUPT_APIC | VMCPU_FF_INTERRUPT_PIC))
             {
                 /* Note: it's important to make sure the return code from TRPMR3InjectEvent isn't ignored! */
@@ -3464,5 +3480,6 @@
 #endif
         /* check that we got them all  */
-        Assert(!(VM_FF_HIGH_PRIORITY_PRE_MASK & ~(VM_FF_TIMER | VM_FF_INTERRUPT_APIC | VM_FF_INTERRUPT_PIC | VM_FF_DBGF | VM_FF_PGM_SYNC_CR3 | VM_FF_PGM_SYNC_CR3_NON_GLOBAL | VM_FF_SELM_SYNC_TSS | VM_FF_TRPM_SYNC_IDT | VM_FF_SELM_SYNC_GDT | VM_FF_SELM_SYNC_LDT | VM_FF_TERMINATE | VM_FF_DEBUG_SUSPEND | VM_FF_INHIBIT_INTERRUPTS | VM_FF_PGM_NEED_HANDY_PAGES | VM_FF_PGM_NO_MEMORY)));
+        Assert(!(VM_FF_HIGH_PRIORITY_PRE_MASK & ~(VM_FF_TIMER | VM_FF_DBGF | VM_FF_TERMINATE | VM_FF_DEBUG_SUSPEND | VM_FF_PGM_NEED_HANDY_PAGES | VM_FF_PGM_NO_MEMORY)));
+        Assert(!(VMCPU_FF_HIGH_PRIORITY_PRE_MASK & ~(VMCPU_FF_INTERRUPT_APIC | VMCPU_FF_INTERRUPT_PIC | VMCPU_FF_PGM_SYNC_CR3 | VMCPU_FF_PGM_SYNC_CR3_NON_GLOBAL | VMCPU_FF_SELM_SYNC_TSS | VMCPU_FF_TRPM_SYNC_IDT | VMCPU_FF_SELM_SYNC_GDT | VMCPU_FF_SELM_SYNC_LDT | VMCPU_FF_INHIBIT_INTERRUPTS)));
     }
 
@@ -3796,5 +3813,5 @@
                 {
                     STAM_REL_PROFILE_START(&pVCpu->em.s.StatHalted, y);
-                    rc = VMR3WaitHalted(pVM, !(CPUMGetGuestEFlags(pVCpu) & X86_EFL_IF));
+                    rc = VMR3WaitHalted(pVM, pVCpu, !(CPUMGetGuestEFlags(pVCpu) & X86_EFL_IF));
                     STAM_REL_PROFILE_STOP(&pVCpu->em.s.StatHalted, y);
                     break;
Index: /trunk/src/VBox/VMM/PATM/CSAM.cpp
===================================================================
--- /trunk/src/VBox/VMM/PATM/CSAM.cpp	(revision 19140)
+++ /trunk/src/VBox/VMM/PATM/CSAM.cpp	(revision 19141)
@@ -228,5 +228,6 @@
     pVM->csam.s.fScanningStarted = false;
 
-    VM_FF_CLEAR(pVM, VM_FF_CSAM_PENDING_ACTION);
+    PVMCPU pVCpu = &pVM->aCpus[0];  /* raw mode implies 1 VPCU */
+    VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_CSAM_PENDING_ACTION);
     pVM->csam.s.cDirtyPages = 0;
     /* not necessary */
@@ -2263,11 +2264,12 @@
  * @returns VBox status code.
  * @param   pVM         The VM to operate on.
- */
-VMMR3DECL(int) CSAMR3DoPendingAction(PVM pVM)
+ * @param   pVCpu       The VMCPU to operate on.
+ */
+VMMR3DECL(int) CSAMR3DoPendingAction(PVM pVM, PVMCPU pVCpu)
 {
     csamR3FlushDirtyPages(pVM);
     csamR3FlushCodePages(pVM);
 
-    VM_FF_CLEAR(pVM, VM_FF_CSAM_PENDING_ACTION);
+    VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_CSAM_PENDING_ACTION);
     return VINF_SUCCESS;
 }
Index: /trunk/src/VBox/VMM/PATM/PATM.cpp
===================================================================
--- /trunk/src/VBox/VMM/PATM/PATM.cpp	(revision 19140)
+++ /trunk/src/VBox/VMM/PATM/PATM.cpp	(revision 19141)
@@ -112,6 +112,12 @@
     Log(("PATMR3Init: Patch record size %d\n", sizeof(PATCHINFO)));
 
-    AssertReleaseMsg(PATMInterruptFlag == (VM_FF_INTERRUPT_APIC | VM_FF_INTERRUPT_PIC | VM_FF_TIMER | VM_FF_REQUEST),
-                     ("Interrupt flags out of sync!! PATMInterruptFlag=%#x expected %#x. broken assembler?\n", PATMInterruptFlag, VM_FF_INTERRUPT_APIC | VM_FF_INTERRUPT_PIC | VM_FF_TIMER | VM_FF_REQUEST));
+    /* These values can't change as they are hardcoded in patch code (old saved states!) */
+    AssertCompile(VM_FF_TIMER   == VMCPU_FF_TIMER);
+    AssertCompile(VM_FF_REQUEST == VMCPU_FF_REQUEST);
+    AssertCompile(VMCPU_FF_INTERRUPT_APIC == RT_BIT_32(0));
+    AssertCompile(VMCPU_FF_INTERRUPT_PIC == RT_BIT_32(1));
+
+    AssertReleaseMsg(PATMInterruptFlag == (VMCPU_FF_INTERRUPT_APIC | VMCPU_FF_INTERRUPT_PIC | VMCPU_FF_TIMER | VMCPU_FF_REQUEST),
+                     ("Interrupt flags out of sync!! PATMInterruptFlag=%#x expected %#x. broken assembler?\n", PATMInterruptFlag, VMCPU_FF_INTERRUPT_APIC | VMCPU_FF_INTERRUPT_PIC | VMCPU_FF_TIMER | VMCPU_FF_REQUEST));
 
     /* Allocate patch memory and GC patch state memory. */
@@ -6233,5 +6239,5 @@
         }
 #endif
-        EMSetInhibitInterruptsPC(pVM, pVCpu, pNewEip);
+        EMSetInhibitInterruptsPC(pVCpu, pNewEip);
         pVM->patm.s.pGCStateHC->GCPtrInhibitInterrupts = 0;
     }
Index: /trunk/src/VBox/VMM/PATM/PATMA.asm
===================================================================
--- /trunk/src/VBox/VMM/PATM/PATMA.asm	(revision 19140)
+++ /trunk/src/VBox/VMM/PATM/PATMA.asm	(revision 19141)
@@ -146,5 +146,5 @@
 
     ; if interrupts are pending, then we must go back to the host context to handle them!
-    test    dword [ss:PATM_VM_FORCEDACTIONS], VM_FF_INTERRUPT_APIC | VM_FF_INTERRUPT_PIC | VM_FF_TIMER | VM_FF_REQUEST
+    test    dword [ss:PATM_VM_FORCEDACTIONS], VMCPU_FF_INTERRUPT_APIC | VMCPU_FF_INTERRUPT_PIC | VMCPU_FF_TIMER | VMCPU_FF_REQUEST
     jz      PATMClearInhibitIRQFaultIF0_Continue
 
@@ -221,5 +221,5 @@
 
     ; if interrupts are pending, then we must go back to the host context to handle them!
-    test    dword [ss:PATM_VM_FORCEDACTIONS], VM_FF_INTERRUPT_APIC | VM_FF_INTERRUPT_PIC | VM_FF_TIMER | VM_FF_REQUEST
+    test    dword [ss:PATM_VM_FORCEDACTIONS], VMCPU_FF_INTERRUPT_APIC | VMCPU_FF_INTERRUPT_PIC | VMCPU_FF_TIMER | VMCPU_FF_REQUEST
     jz      PATMClearInhibitIRQContIF0_Continue
 
@@ -744,5 +744,5 @@
 
     ; if interrupts are pending, then we must go back to the host context to handle them!
-    test    dword [ss:PATM_VM_FORCEDACTIONS], VM_FF_INTERRUPT_APIC | VM_FF_INTERRUPT_PIC | VM_FF_TIMER | VM_FF_REQUEST
+    test    dword [ss:PATM_VM_FORCEDACTIONS], VMCPU_FF_INTERRUPT_APIC | VMCPU_FF_INTERRUPT_PIC | VMCPU_FF_TIMER | VMCPU_FF_REQUEST
     jz      PATMPopf32_Continue
 
@@ -834,5 +834,5 @@
 
     ; if interrupts are pending, then we must go back to the host context to handle them!
-    test    dword [ss:PATM_VM_FORCEDACTIONS], VM_FF_INTERRUPT_APIC | VM_FF_INTERRUPT_PIC | VM_FF_TIMER | VM_FF_REQUEST
+    test    dword [ss:PATM_VM_FORCEDACTIONS], VMCPU_FF_INTERRUPT_APIC | VMCPU_FF_INTERRUPT_PIC | VMCPU_FF_TIMER | VMCPU_FF_REQUEST
     jz      PATMPopf32_NoExit_Continue
 
@@ -922,5 +922,5 @@
     ; if interrupts are pending, then we must go back to the host context to handle them!
     ; @note we destroy the flags here, but that should really not matter (PATM_INT3 case)
-    test    dword [ss:PATM_VM_FORCEDACTIONS], VM_FF_INTERRUPT_APIC | VM_FF_INTERRUPT_PIC | VM_FF_TIMER | VM_FF_REQUEST
+    test    dword [ss:PATM_VM_FORCEDACTIONS], VMCPU_FF_INTERRUPT_APIC | VMCPU_FF_INTERRUPT_PIC | VMCPU_FF_TIMER | VMCPU_FF_REQUEST
     jz      PATMPopf16_Continue
     mov     dword [ss:PATM_INTERRUPTFLAG], 1
@@ -987,5 +987,5 @@
     ; if interrupts are pending, then we must go back to the host context to handle them!
     ; @note we destroy the flags here, but that should really not matter (PATM_INT3 case)
-    test    dword [ss:PATM_VM_FORCEDACTIONS], VM_FF_INTERRUPT_APIC | VM_FF_INTERRUPT_PIC | VM_FF_TIMER | VM_FF_REQUEST
+    test    dword [ss:PATM_VM_FORCEDACTIONS], VMCPU_FF_INTERRUPT_APIC | VMCPU_FF_INTERRUPT_PIC | VMCPU_FF_TIMER | VMCPU_FF_REQUEST
     jz      PATMPopf16_Continue_NoExit
     mov     dword [ss:PATM_INTERRUPTFLAG], 1
@@ -1238,5 +1238,5 @@
 ; Note: This is very important as pending pic interrupts can be overriden by apic interrupts if we don't check early enough (Fedora 5 boot)
 ; @@todo fix this properly, so we can dispatch pending interrupts in GC
-    test    dword [ss:PATM_VM_FORCEDACTIONS], VM_FF_INTERRUPT_APIC | VM_FF_INTERRUPT_PIC
+    test    dword [ss:PATM_VM_FORCEDACTIONS], VMCPU_FF_INTERRUPT_APIC | VMCPU_FF_INTERRUPT_PIC
     jz      iret_continue
 
@@ -2582,4 +2582,4 @@
 ; For assertion during init (to make absolutely sure the flags are in sync in vm.mac & vm.h)
 GLOBALNAME PATMInterruptFlag
-    DD      VM_FF_INTERRUPT_APIC | VM_FF_INTERRUPT_PIC | VM_FF_TIMER | VM_FF_REQUEST
-
+    DD      VMCPU_FF_INTERRUPT_APIC | VMCPU_FF_INTERRUPT_PIC | VMCPU_FF_TIMER | VMCPU_FF_REQUEST
+
Index: /trunk/src/VBox/VMM/PATM/PATMInternal.h
===================================================================
--- /trunk/src/VBox/VMM/PATM/PATMInternal.h	(revision 19140)
+++ /trunk/src/VBox/VMM/PATM/PATMInternal.h	(revision 19141)
@@ -41,4 +41,5 @@
 #else
 # define PATM_SSM_VERSION                    54
+# define PATM_SSM_VERSION_FIXUP_HACK         54
 # define PATM_SSM_VERSION_VER16              53
 #endif
@@ -134,4 +135,14 @@
 #define PATM_STAT_MEMSIZE                   (PATM_STAT_MAX_COUNTERS*sizeof(STAMRATIOU32))
 
+/** aCpus[0].fLocalForcedActions fixup (must be uneven to avoid theoretical clashes with valid pointers) */
+#define PATM_FIXUP_CPU_FF_ACTION            0xffffff01
+/** default cpuid pointer fixup */
+#define PATM_FIXUP_CPUID_DEFAULT            0xffffff03
+/** standard cpuid pointer fixup */
+#define PATM_FIXUP_CPUID_STANDARD           0xffffff05
+/** extended cpuid pointer fixup */
+#define PATM_FIXUP_CPUID_EXTENDED           0xffffff07
+/** centaur cpuid pointer fixup */
+#define PATM_FIXUP_CPUID_CENTAUR            0xffffff09
 
 typedef struct
Index: /trunk/src/VBox/VMM/PATM/PATMPatch.cpp
===================================================================
--- /trunk/src/VBox/VMM/PATM/PATMPatch.cpp	(revision 19140)
+++ /trunk/src/VBox/VMM/PATM/PATMPatch.cpp	(revision 19141)
@@ -287,5 +287,5 @@
                 case PATM_VM_FORCEDACTIONS:
                     /* @todo dirty assumptions when correcting this fixup during saved state loading. */
-                    dest = pVM->pVMRC + RT_OFFSETOF(VM, fForcedActions);
+                    dest = pVM->pVMRC + RT_OFFSETOF(VM, aCpus[0].fLocalForcedActions);
                     break;
 
Index: /trunk/src/VBox/VMM/PATM/PATMSSM.cpp
===================================================================
--- /trunk/src/VBox/VMM/PATM/PATMSSM.cpp	(revision 19140)
+++ /trunk/src/VBox/VMM/PATM/PATMSSM.cpp	(revision 19141)
@@ -142,7 +142,28 @@
     PSSMHANDLE          pSSM = pVM->patm.s.savedstate.pSSM;
     RELOCREC            rec  = *(PRELOCREC)pNode;
+    RTRCPTR            *pFixup = (RTRCPTR *)rec.pRelocPos;
 
     Assert(rec.pRelocPos);
+    /* Convert pointer to an offset into patch memory. */
     PATM_SUBTRACT_PTR(rec.pRelocPos, pVM->patm.s.pPatchMemHC);
+
+    if (rec.uType == FIXUP_ABSOLUTE)
+    {
+        /* Core.Key abused to store the fixup type. */
+        if (*pFixup == pVM->pVMRC + RT_OFFSETOF(VM, aCpus[0].fLocalForcedActions))
+            rec.Core.Key = (AVLPVKEY)PATM_FIXUP_CPU_FF_ACTION;
+        else 
+        if (*pFixup == CPUMR3GetGuestCpuIdDefRCPtr(pVM))
+            rec.Core.Key = (AVLPVKEY)PATM_FIXUP_CPUID_DEFAULT;
+        else 
+        if (*pFixup == CPUMR3GetGuestCpuIdStdRCPtr(pVM))
+            rec.Core.Key = (AVLPVKEY)PATM_FIXUP_CPUID_STANDARD;
+        else 
+        if (*pFixup == CPUMR3GetGuestCpuIdExtRCPtr(pVM))
+            rec.Core.Key = (AVLPVKEY)PATM_FIXUP_CPUID_EXTENDED;
+        else 
+        if (*pFixup == CPUMR3GetGuestCpuIdCentaurRCPtr(pVM))
+            rec.Core.Key = (AVLPVKEY)PATM_FIXUP_CPUID_CENTAUR;
+    }
 
     /* Save the lookup record. */
@@ -286,4 +307,5 @@
 
     if (    u32Version != PATM_SSM_VERSION
+        &&  u32Version != PATM_SSM_VERSION_FIXUP_HACK
         &&  u32Version != PATM_SSM_VERSION_VER16
 #ifdef PATM_WITH_NEW_SSM
@@ -874,13 +896,14 @@
         }
         else
-        /* Note: rather assumptive! */
-        if (    *pFixup >= pVM->pVMRC
+        if (    ulSSMVersion <= PATM_SSM_VERSION_FIXUP_HACK
+            &&  *pFixup >= pVM->pVMRC
             &&  *pFixup < pVM->pVMRC + 32)
         {
-            LogFlow(("Changing fForcedActions fixup from %x to %x\n", *pFixup, pVM->pVMRC + RT_OFFSETOF(VM, fForcedActions)));
-            *pFixup = pVM->pVMRC + RT_OFFSETOF(VM, fForcedActions);
+            LogFlow(("Changing fLocalForcedActions fixup from %x to %x\n", *pFixup, pVM->pVMRC + RT_OFFSETOF(VM, aCpus[0].fLocalForcedActions)));
+            *pFixup = pVM->pVMRC + RT_OFFSETOF(VM, aCpus[0].fLocalForcedActions);
         }
         else
-        if (    *pFixup >= pVM->pVMRC
+        if (    ulSSMVersion <= PATM_SSM_VERSION_FIXUP_HACK
+            &&  *pFixup >= pVM->pVMRC
             &&  *pFixup < pVM->pVMRC + 8192)
         {
@@ -909,8 +932,40 @@
         }
         else
-            AssertMsgFailed(("Unexpected fixup value %x\n", *pFixup));
+        if (ulSSMVersion >= PATM_SSM_VERSION)
+        {
+#ifdef LOG_ENABLED
+            RTRCPTR oldFixup = *pFixup;
+#endif
+            /* Core.Key abused to store the type of fixup */
+            switch ((uint32_t)pRec->Core.Key)
+            {
+            case PATM_FIXUP_CPU_FF_ACTION:
+                *pFixup = pVM->pVMRC + RT_OFFSETOF(VM, aCpus[0].fLocalForcedActions);
+                LogFlow(("Changing cpu ff action fixup from %x to %x\n", oldFixup, *pFixup));
+                break;
+            case PATM_FIXUP_CPUID_DEFAULT:
+                *pFixup = CPUMR3GetGuestCpuIdDefRCPtr(pVM);
+                LogFlow(("Changing cpuid def fixup from %x to %x\n", oldFixup, *pFixup));
+                break;
+            case PATM_FIXUP_CPUID_STANDARD:
+                *pFixup = CPUMR3GetGuestCpuIdStdRCPtr(pVM);
+                LogFlow(("Changing cpuid std fixup from %x to %x\n", oldFixup, *pFixup));
+                break;
+            case PATM_FIXUP_CPUID_EXTENDED:
+                *pFixup = CPUMR3GetGuestCpuIdExtRCPtr(pVM);
+                LogFlow(("Changing cpuid ext fixup from %x to %x\n", oldFixup, *pFixup));
+                break;
+            case PATM_FIXUP_CPUID_CENTAUR:
+                *pFixup = CPUMR3GetGuestCpuIdCentaurRCPtr(pVM);
+                LogFlow(("Changing cpuid centaur fixup from %x to %x\n", oldFixup, *pFixup));
+                break;
+            default:
+                AssertMsgFailed(("Unexpected fixup value %x\n", *pFixup));
+                break;
+            }
+        }
 
 #ifdef RT_OS_WINDOWS
-        AssertCompile(RT_OFFSETOF(VM, fForcedActions) < 32);
+        AssertCompile(RT_OFFSETOF(VM, fGlobalForcedActions) < 32);
 #endif
         break;
Index: /trunk/src/VBox/VMM/PATM/VMMAll/CSAMAll.cpp
===================================================================
--- /trunk/src/VBox/VMM/PATM/VMMAll/CSAMAll.cpp	(revision 19140)
+++ /trunk/src/VBox/VMM/PATM/VMMAll/CSAMAll.cpp	(revision 19141)
@@ -37,4 +37,5 @@
 #include "CSAMInternal.h"
 #include <VBox/vm.h>
+#include <VBox/vmm.h>
 #include <VBox/dbg.h>
 #include <VBox/err.h>
@@ -68,5 +69,5 @@
 
     STAM_COUNTER_ADD(&pVM->csam.s.StatNrTraps, 1);
-    VM_FF_SET(pVM, VM_FF_CSAM_SCAN_PAGE);
+    VMCPU_FF_SET(VMMGetCpu0(pVM), VMCPU_FF_CSAM_SCAN_PAGE);
     return VINF_CSAM_PENDING_ACTION;
 }
@@ -205,5 +206,5 @@
     {
         pVM->csam.s.pvPossibleCodePage[pVM->csam.s.cPossibleCodePages++] = (RTRCPTR)GCPtr;
-        VM_FF_SET(pVM, VM_FF_CSAM_PENDING_ACTION);
+        VMCPU_FF_SET(VMMGetCpu0(pVM), VMCPU_FF_CSAM_PENDING_ACTION);
     }
     return;
Index: /trunk/src/VBox/VMM/PATM/VMMAll/PATMAll.cpp
===================================================================
--- /trunk/src/VBox/VMM/PATM/VMMAll/PATMAll.cpp	(revision 19140)
+++ /trunk/src/VBox/VMM/PATM/VMMAll/PATMAll.cpp	(revision 19141)
@@ -191,5 +191,5 @@
         if (CTXSUFF(pVM->patm.s.pGCState)->GCPtrInhibitInterrupts == (RTRCPTR)pCtxCore->eip)
         {
-            EMSetInhibitInterruptsPC(pVM, VMMGetCpu0(pVM), pCtxCore->eip);
+            EMSetInhibitInterruptsPC(VMMGetCpu0(pVM), pCtxCore->eip);
         }
         CTXSUFF(pVM->patm.s.pGCState)->GCPtrInhibitInterrupts = 0;
Index: /trunk/src/VBox/VMM/PATM/VMMGC/CSAMGC.cpp
===================================================================
--- /trunk/src/VBox/VMM/PATM/VMMGC/CSAMGC.cpp	(revision 19140)
+++ /trunk/src/VBox/VMM/PATM/VMMGC/CSAMGC.cpp	(revision 19141)
@@ -117,5 +117,5 @@
     }
 
-    VM_FF_SET(pVM, VM_FF_CSAM_PENDING_ACTION);
+    VMCPU_FF_SET(pVCpu, VMCPU_FF_CSAM_PENDING_ACTION);
 
     /* Note that pvFault might be a different address in case of aliases. So use pvRange + offset instead!. */
Index: /trunk/src/VBox/VMM/PDM.cpp
===================================================================
--- /trunk/src/VBox/VMM/PDM.cpp	(revision 19140)
+++ /trunk/src/VBox/VMM/PDM.cpp	(revision 19141)
@@ -641,6 +641,10 @@
      * Save interrupt and DMA states.
      */
-    SSMR3PutUInt(pSSM, VM_FF_ISSET(pVM, VM_FF_INTERRUPT_APIC));
-    SSMR3PutUInt(pSSM, VM_FF_ISSET(pVM, VM_FF_INTERRUPT_PIC));
+    for (unsigned idCpu=0;idCpu<pVM->cCPUs;idCpu++)
+    {
+        PVMCPU pVCpu = &pVM->aCpus[idCpu];
+        SSMR3PutUInt(pSSM, VMCPU_FF_ISSET(pVCpu, VMCPU_FF_INTERRUPT_APIC));
+        SSMR3PutUInt(pSSM, VMCPU_FF_ISSET(pVCpu, VMCPU_FF_INTERRUPT_PIC));
+    }
     SSMR3PutUInt(pSSM, VM_FF_ISSET(pVM, VM_FF_PDM_DMA));
 
@@ -675,8 +679,16 @@
     LogFlow(("pdmR3LoadPrep: %s%s%s%s\n",
              VM_FF_ISSET(pVM, VM_FF_PDM_QUEUES)     ? " VM_FF_PDM_QUEUES" : "",
-             VM_FF_ISSET(pVM, VM_FF_PDM_DMA)        ? " VM_FF_PDM_DMA" : "",
-             VM_FF_ISSET(pVM, VM_FF_INTERRUPT_APIC) ? " VM_FF_INTERRUPT_APIC" : "",
-             VM_FF_ISSET(pVM, VM_FF_INTERRUPT_PIC)  ? " VM_FF_INTERRUPT_PIC" : ""
+             VM_FF_ISSET(pVM, VM_FF_PDM_DMA)        ? " VM_FF_PDM_DMA" : ""
              ));
+#ifdef LOG_ENABLED
+    for (unsigned idCpu=0;idCpu<pVM->cCPUs;idCpu++)
+    {
+        PVMCPU pVCpu = &pVM->aCpus[idCpu];
+        LogFlow(("pdmR3LoadPrep: VCPU %d %s%s%s%s\n", idCpu, 
+                VMCPU_FF_ISSET(pVCpu, VMCPU_FF_INTERRUPT_APIC) ? " VMCPU_FF_INTERRUPT_APIC" : "",
+                VMCPU_FF_ISSET(pVCpu, VMCPU_FF_INTERRUPT_PIC)  ? " VMCPU_FF_INTERRUPT_PIC" : ""
+                ));
+    }
+#endif
 
     /*
@@ -688,6 +700,10 @@
 
     /* Clear the FFs. */
-    VM_FF_CLEAR(pVM, VM_FF_INTERRUPT_APIC);
-    VM_FF_CLEAR(pVM, VM_FF_INTERRUPT_PIC);
+    for (unsigned idCpu=0;idCpu<pVM->cCPUs;idCpu++)
+    {
+        PVMCPU pVCpu = &pVM->aCpus[idCpu];
+        VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_INTERRUPT_APIC);
+        VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_INTERRUPT_PIC);
+    }
     VM_FF_CLEAR(pVM, VM_FF_PDM_DMA);
 
@@ -706,4 +722,6 @@
 static DECLCALLBACK(int) pdmR3Load(PVM pVM, PSSMHANDLE pSSM, uint32_t u32Version)
 {
+    int rc;
+
     LogFlow(("pdmR3Load:\n"));
 
@@ -720,31 +738,36 @@
      * Load the interrupt and DMA states.
      */
-    /* APIC interrupt */
-    RTUINT fInterruptPending = 0;
-    int rc = SSMR3GetUInt(pSSM, &fInterruptPending);
-    if (RT_FAILURE(rc))
-        return rc;
-    if (fInterruptPending & ~1)
-    {
-        AssertMsgFailed(("fInterruptPending=%#x (APIC)\n", fInterruptPending));
-        return VERR_SSM_DATA_UNIT_FORMAT_CHANGED;
-    }
-    AssertRelease(!VM_FF_ISSET(pVM, VM_FF_INTERRUPT_APIC));
-    if (fInterruptPending)
-        VM_FF_SET(pVM, VM_FF_INTERRUPT_APIC);
-
-    /* PIC interrupt */
-    fInterruptPending = 0;
-    rc = SSMR3GetUInt(pSSM, &fInterruptPending);
-    if (RT_FAILURE(rc))
-        return rc;
-    if (fInterruptPending & ~1)
-    {
-        AssertMsgFailed(("fInterruptPending=%#x (PIC)\n", fInterruptPending));
-        return VERR_SSM_DATA_UNIT_FORMAT_CHANGED;
-    }
-    AssertRelease(!VM_FF_ISSET(pVM, VM_FF_INTERRUPT_PIC));
-    if (fInterruptPending)
-        VM_FF_SET(pVM, VM_FF_INTERRUPT_PIC);
+    for (unsigned idCpu=0;idCpu<pVM->cCPUs;idCpu++)
+    {
+        PVMCPU pVCpu = &pVM->aCpus[idCpu];
+
+        /* APIC interrupt */
+        RTUINT fInterruptPending = 0;
+        rc = SSMR3GetUInt(pSSM, &fInterruptPending);
+        if (RT_FAILURE(rc))
+            return rc;
+        if (fInterruptPending & ~1)
+        {
+            AssertMsgFailed(("fInterruptPending=%#x (APIC)\n", fInterruptPending));
+            return VERR_SSM_DATA_UNIT_FORMAT_CHANGED;
+        }
+        AssertRelease(!VMCPU_FF_ISSET(pVCpu, VMCPU_FF_INTERRUPT_APIC));
+        if (fInterruptPending)
+            VMCPU_FF_SET(pVCpu, VMCPU_FF_INTERRUPT_APIC);
+
+        /* PIC interrupt */
+        fInterruptPending = 0;
+        rc = SSMR3GetUInt(pSSM, &fInterruptPending);
+        if (RT_FAILURE(rc))
+            return rc;
+        if (fInterruptPending & ~1)
+        {
+            AssertMsgFailed(("fInterruptPending=%#x (PIC)\n", fInterruptPending));
+            return VERR_SSM_DATA_UNIT_FORMAT_CHANGED;
+        }
+        AssertRelease(!VMCPU_FF_ISSET(pVCpu, VMCPU_FF_INTERRUPT_PIC));
+        if (fInterruptPending)
+            VMCPU_FF_SET(pVCpu, VMCPU_FF_INTERRUPT_PIC);
+    }
 
     /* DMA pending */
@@ -903,6 +926,10 @@
      * Clear all pending interrupts and DMA operations.
      */
-    VM_FF_CLEAR(pVM, VM_FF_INTERRUPT_APIC);
-    VM_FF_CLEAR(pVM, VM_FF_INTERRUPT_PIC);
+    for (unsigned idCpu=0;idCpu<pVM->cCPUs;idCpu++)
+    {
+        PVMCPU pVCpu = &pVM->aCpus[idCpu];
+        VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_INTERRUPT_APIC);
+        VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_INTERRUPT_PIC);
+    }
     VM_FF_CLEAR(pVM, VM_FF_PDM_DMA);
 
Index: /trunk/src/VBox/VMM/PDMDevMiscHlp.cpp
===================================================================
--- /trunk/src/VBox/VMM/PDMDevMiscHlp.cpp	(revision 19140)
+++ /trunk/src/VBox/VMM/PDMDevMiscHlp.cpp	(revision 19141)
@@ -48,10 +48,11 @@
     PDMDEV_ASSERT_DEVINS(pDevIns);
     PVM pVM = pDevIns->Internal.s.pVMR3;
+    PVMCPU pVCpu = &pVM->aCpus[0];  /* for PIC we always deliver to CPU 0, MP use APIC */
+
     LogFlow(("pdmR3PicHlp_SetInterruptFF: caller='%s'/%d: VM_FF_INTERRUPT_PIC %d -> 1\n",
-             pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VMCPU_FF_ISSET(pVM, 0, VM_FF_INTERRUPT_PIC)));
-
-    /* for PIC we always deliver to CPU 0, MP use APIC */
-    VMCPU_FF_SET(pVM, 0, VM_FF_INTERRUPT_PIC);
-    REMR3NotifyInterruptSet(pVM, VMMGetCpu(pVM));
+             pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VMCPU_FF_ISSET(pVCpu, VMCPU_FF_INTERRUPT_PIC)));
+
+    VMCPU_FF_SET(pVCpu, VMCPU_FF_INTERRUPT_PIC);
+    REMR3NotifyInterruptSet(pVM, pVCpu);
     VMR3NotifyFF(pVM, true); /** @todo SMP: notify the right cpu. */
 }
@@ -62,10 +63,12 @@
 {
     PDMDEV_ASSERT_DEVINS(pDevIns);
+    PVM pVM = pDevIns->Internal.s.pVMR3;
+    PVMCPU pVCpu = &pVM->aCpus[0];  /* for PIC we always deliver to CPU 0, MP use APIC */
+
     LogFlow(("pdmR3PicHlp_ClearInterruptFF: caller='%s'/%d: VM_FF_INTERRUPT_PIC %d -> 0\n",
-             pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VMCPU_FF_ISSET(pDevIns->Internal.s.pVMR3, 0, VM_FF_INTERRUPT_PIC)));
-
-    /* for PIC we always deliver to CPU 0, MP use APIC */
-    VMCPU_FF_CLEAR(pDevIns->Internal.s.pVMR3, 0, VM_FF_INTERRUPT_PIC);
-    REMR3NotifyInterruptClear(pDevIns->Internal.s.pVMR3, VMMGetCpu(pDevIns->Internal.s.pVMR3));
+             pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VMCPU_FF_ISSET(pVCpu, VMCPU_FF_INTERRUPT_PIC)));
+
+    VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_INTERRUPT_PIC);
+    REMR3NotifyInterruptClear(pVM, pVCpu);
 }
 
@@ -146,9 +149,13 @@
     PDMDEV_ASSERT_DEVINS(pDevIns);
     PVM pVM = pDevIns->Internal.s.pVMR3;
+    PVMCPU pVCpu = &pVM->aCpus[idCpu];
+
+    AssertReturnVoid(idCpu < pVM->cCPUs);
+
     LogFlow(("pdmR3ApicHlp_SetInterruptFF: caller='%s'/%d: VM_FF_INTERRUPT(%d) %d -> 1\n",
-             pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, idCpu, VMCPU_FF_ISSET(pVM, idCpu, VM_FF_INTERRUPT_APIC)));
-
-    VMCPU_FF_SET(pVM, idCpu, VM_FF_INTERRUPT_APIC);
-    REMR3NotifyInterruptSet(pVM, VMMGetCpu(pVM));
+             pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, idCpu, VMCPU_FF_ISSET(pVCpu, VMCPU_FF_INTERRUPT_APIC)));
+
+    VMCPU_FF_SET(pVCpu, VMCPU_FF_INTERRUPT_APIC);
+    REMR3NotifyInterruptSet(pVM, pVCpu);
     VMR3NotifyFF(pVM, true);  /** @todo SMP: notify the right cpu. */
 }
@@ -159,9 +166,14 @@
 {
     PDMDEV_ASSERT_DEVINS(pDevIns);
+    PVM pVM = pDevIns->Internal.s.pVMR3;
+    PVMCPU pVCpu = &pVM->aCpus[idCpu];
+
+    AssertReturnVoid(idCpu < pVM->cCPUs);
+
     LogFlow(("pdmR3ApicHlp_ClearInterruptFF: caller='%s'/%d: VM_FF_INTERRUPT(%d) %d -> 0\n",
-             pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, idCpu, VMCPU_FF_ISSET(pDevIns->Internal.s.pVMR3, idCpu, VM_FF_INTERRUPT_APIC)));
-
-    VMCPU_FF_CLEAR(pDevIns->Internal.s.pVMR3, idCpu, VM_FF_INTERRUPT_APIC);
-    REMR3NotifyInterruptClear(pDevIns->Internal.s.pVMR3, VMMGetCpu(pDevIns->Internal.s.pVMR3));
+             pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, idCpu, VMCPU_FF_ISSET(pVCpu, VMCPU_FF_INTERRUPT_APIC)));
+
+    VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_INTERRUPT_APIC);
+    REMR3NotifyInterruptClear(pVM, pVCpu);
 }
 
Index: /trunk/src/VBox/VMM/PGM.cpp
===================================================================
--- /trunk/src/VBox/VMM/PGM.cpp	(revision 19140)
+++ /trunk/src/VBox/VMM/PGM.cpp	(revision 19141)
@@ -611,4 +611,6 @@
 /** Saved state data unit version for 2.5.x and later. */
 #define PGM_SAVED_STATE_VERSION                 9
+/** Saved state data unit version for 2.2.2 and later. */
+#define PGM_SAVED_STATE_VERSION_2_2_2           8
 /** Saved state data unit version for 2.2.0. */
 #define PGM_SAVED_STATE_VERSION_RR_DESC         7
@@ -2173,6 +2175,6 @@
          * Clear the FFs PGM owns.
          */
-        VM_FF_CLEAR(pVM, VM_FF_PGM_SYNC_CR3);
-        VM_FF_CLEAR(pVM, VM_FF_PGM_SYNC_CR3_NON_GLOBAL);
+        VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_PGM_SYNC_CR3);
+        VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_PGM_SYNC_CR3_NON_GLOBAL);
     }
 
@@ -3009,4 +3011,5 @@
      */
     if (    u32Version != PGM_SAVED_STATE_VERSION
+        &&  u32Version != PGM_SAVED_STATE_VERSION_2_2_2
         &&  u32Version != PGM_SAVED_STATE_VERSION_RR_DESC
         &&  u32Version != PGM_SAVED_STATE_VERSION_OLD_PHYS_CODE)
@@ -3036,6 +3039,6 @@
         {
             PVMCPU pVCpu = &pVM->aCpus[i];
-            VM_FF_SET(pVM, VM_FF_PGM_SYNC_CR3_NON_GLOBAL);
-            VM_FF_SET(pVM, VM_FF_PGM_SYNC_CR3);
+            VMCPU_FF_SET(pVCpu, VMCPU_FF_PGM_SYNC_CR3_NON_GLOBAL);
+            VMCPU_FF_SET(pVCpu, VMCPU_FF_PGM_SYNC_CR3);
 
             pVCpu->pgm.s.fSyncFlags |= PGM_SYNC_UPDATE_PAGE_BIT_VIRTUAL;
@@ -3887,5 +3890,5 @@
      * Always flag the necessary updates
      */
-    VM_FF_SET(pVM, VM_FF_PGM_SYNC_CR3);
+    VMCPU_FF_SET(pVCpu, VMCPU_FF_PGM_SYNC_CR3);
 
     /*
@@ -4086,5 +4089,5 @@
     pVCpu->pgm.s.enmShadowMode = PGMMODE_INVALID;
     int rc = PGMR3ChangeMode(pVM, pVCpu, PGMGetGuestMode(pVCpu));
-    Assert(VM_FF_ISSET(pVM, VM_FF_PGM_SYNC_CR3));
+    Assert(VMCPU_FF_ISSET(pVCpu, VMCPU_FF_PGM_SYNC_CR3));
     AssertRCReturn(rc, rc);
     AssertRCSuccessReturn(rc, VERR_IPE_UNEXPECTED_INFO_STATUS);
@@ -4849,4 +4852,7 @@
 static DECLCALLBACK(int) pgmR3CmdSync(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult)
 {
+    /** @todo SMP support */
+    PVMCPU pVCpu = &pVM->aCpus[0];
+
     /*
      * Validate input.
@@ -4858,5 +4864,5 @@
      * Force page directory sync.
      */
-    VM_FF_SET(pVM, VM_FF_PGM_SYNC_CR3);
+    VMCPU_FF_SET(pVCpu, VMCPU_FF_PGM_SYNC_CR3);
 
     int rc = pCmdHlp->pfnPrintf(pCmdHlp, NULL, "Forcing page directory sync.\n");
@@ -4933,5 +4939,5 @@
     {
         ASMAtomicOrU32(&pVCpu->pgm.s.fSyncFlags, PGM_SYNC_ALWAYS);
-        VM_FF_SET(pVM, VM_FF_PGM_SYNC_CR3);
+        VMCPU_FF_SET(pVCpu, VMCPU_FF_PGM_SYNC_CR3);
         return pCmdHlp->pfnPrintf(pCmdHlp, NULL, "Enabled permanent forced page directory syncing.\n");
     }
Index: /trunk/src/VBox/VMM/PGMBth.h
===================================================================
--- /trunk/src/VBox/VMM/PGMBth.h	(revision 19140)
+++ /trunk/src/VBox/VMM/PGMBth.h	(revision 19141)
@@ -174,5 +174,5 @@
     {
         Log(("Bth-Enter: PGM pool flushed -> signal sync cr3\n"));
-        Assert(VM_FF_ISSET(pVM, VM_FF_PGM_SYNC_CR3));
+        Assert(VMCPU_FF_ISSET(pVCpu, VMCPU_FF_PGM_SYNC_CR3));
         return VINF_PGM_SYNC_CR3;
     }
Index: /trunk/src/VBox/VMM/PGMHandler.cpp
===================================================================
--- /trunk/src/VBox/VMM/PGMHandler.cpp	(revision 19140)
+++ /trunk/src/VBox/VMM/PGMHandler.cpp	(revision 19141)
@@ -394,5 +394,5 @@
 
                 pVCpu->pgm.s.fSyncFlags |= PGM_SYNC_UPDATE_PAGE_BIT_VIRTUAL;
-                VM_FF_SET(pVM, VM_FF_PGM_SYNC_CR3);
+                VMCPU_FF_SET(pVCpu, VMCPU_FF_PGM_SYNC_CR3);
             }
             pVM->pgm.s.fGlobalSyncFlags |= PGM_GLOBAL_SYNC_CLEAR_PGM_POOL;
@@ -480,5 +480,5 @@
 
             pVCpu->pgm.s.fSyncFlags |= PGM_SYNC_UPDATE_PAGE_BIT_VIRTUAL;
-            VM_FF_SET(pVM, VM_FF_PGM_SYNC_CR3);
+            VMCPU_FF_SET(pVCpu, VMCPU_FF_PGM_SYNC_CR3);
         }
         pVM->pgm.s.fGlobalSyncFlags |= PGM_GLOBAL_SYNC_CLEAR_PGM_POOL;
Index: /trunk/src/VBox/VMM/PGMMap.cpp
===================================================================
--- /trunk/src/VBox/VMM/PGMMap.cpp	(revision 19140)
+++ /trunk/src/VBox/VMM/PGMMap.cpp	(revision 19141)
@@ -214,5 +214,9 @@
     }
 
-    VM_FF_SET(pVM, VM_FF_PGM_SYNC_CR3);
+    for (unsigned i=0;i<pVM->cCPUs;i++)
+    {
+        PVMCPU pVCpu = &pVM->aCpus[i];
+        VMCPU_FF_SET(pVCpu, VMCPU_FF_PGM_SYNC_CR3);
+    }
     return VINF_SUCCESS;
 }
@@ -267,5 +271,9 @@
             MMHyperFree(pVM, pCur);
 
-            VM_FF_SET(pVM, VM_FF_PGM_SYNC_CR3);
+            for (unsigned i=0;i<pVM->cCPUs;i++)
+            {
+                PVMCPU pVCpu = &pVM->aCpus[i];
+                VMCPU_FF_SET(pVCpu, VMCPU_FF_PGM_SYNC_CR3);
+            }
             return VINF_SUCCESS;
         }
@@ -649,5 +657,5 @@
         PVMCPU pVCpu = &pVM->aCpus[i];
         pVCpu->pgm.s.fSyncFlags       &= ~PGM_SYNC_MONITOR_CR3;
-        VM_FF_SET(pVM, VM_FF_PGM_SYNC_CR3);
+        VMCPU_FF_SET(pVCpu, VMCPU_FF_PGM_SYNC_CR3);
     }
     return VINF_SUCCESS;
@@ -684,5 +692,5 @@
 
         pVCpu->pgm.s.fSyncFlags       &= ~PGM_SYNC_MONITOR_CR3;
-        VM_FF_SET(pVM, VM_FF_PGM_SYNC_CR3);
+        VMCPU_FF_SET(pVCpu, VMCPU_FF_PGM_SYNC_CR3);
     }
     return VINF_SUCCESS;
@@ -712,5 +720,5 @@
         PVMCPU pVCpu = &pVM->aCpus[i];
 
-        VM_FF_SET(pVM, VM_FF_PGM_SYNC_CR3);
+        VMCPU_FF_SET(pVCpu, VMCPU_FF_PGM_SYNC_CR3);
     }
     return VINF_SUCCESS;
Index: /trunk/src/VBox/VMM/PGMPool.cpp
===================================================================
--- /trunk/src/VBox/VMM/PGMPool.cpp	(revision 19140)
+++ /trunk/src/VBox/VMM/PGMPool.cpp	(revision 19141)
@@ -128,4 +128,6 @@
 int pgmR3PoolInit(PVM pVM)
 {
+    AssertCompile(NIL_PGMPOOL_IDX == 0);
+
     /*
      * Query Pool config.
Index: /trunk/src/VBox/VMM/SELM.cpp
===================================================================
--- /trunk/src/VBox/VMM/SELM.cpp	(revision 19140)
+++ /trunk/src/VBox/VMM/SELM.cpp	(revision 19141)
@@ -223,7 +223,8 @@
      * Default action when entering raw mode for the first time
      */
-    VM_FF_SET(pVM, VM_FF_SELM_SYNC_TSS);
-    VM_FF_SET(pVM, VM_FF_SELM_SYNC_GDT);
-    VM_FF_SET(pVM, VM_FF_SELM_SYNC_LDT);
+    PVMCPU pVCpu = &pVM->aCpus[0];  /* raw mode implies on VCPU */
+    VMCPU_FF_SET(pVCpu, VMCPU_FF_SELM_SYNC_TSS);
+    VMCPU_FF_SET(pVCpu, VMCPU_FF_SELM_SYNC_GDT);
+    VMCPU_FF_SET(pVCpu, VMCPU_FF_SELM_SYNC_LDT);
 
     /*
@@ -579,7 +580,8 @@
      * Default action when entering raw mode for the first time
      */
-    VM_FF_SET(pVM, VM_FF_SELM_SYNC_TSS);
-    VM_FF_SET(pVM, VM_FF_SELM_SYNC_GDT);
-    VM_FF_SET(pVM, VM_FF_SELM_SYNC_LDT);
+    PVMCPU pVCpu = &pVM->aCpus[0];  /* raw mode implies on VCPU */
+    VMCPU_FF_SET(pVCpu, VMCPU_FF_SELM_SYNC_TSS);
+    VMCPU_FF_SET(pVCpu, VMCPU_FF_SELM_SYNC_GDT);
+    VMCPU_FF_SET(pVCpu, VMCPU_FF_SELM_SYNC_LDT);
 }
 
@@ -651,7 +653,8 @@
 #endif
 
-    VM_FF_CLEAR(pVM, VM_FF_SELM_SYNC_TSS);
-    VM_FF_CLEAR(pVM, VM_FF_SELM_SYNC_GDT);
-    VM_FF_CLEAR(pVM, VM_FF_SELM_SYNC_LDT);
+    PVMCPU pVCpu = &pVM->aCpus[0];  /* raw mode implies on VCPU */
+    VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_SELM_SYNC_TSS);
+    VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_SELM_SYNC_GDT);
+    VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_SELM_SYNC_LDT);
 
     pVM->selm.s.fDisableMonitoring = true;
@@ -774,7 +777,7 @@
     if (PGMGetGuestMode(pVCpu) != PGMMODE_REAL)
     {
-        VM_FF_SET(pVM, VM_FF_SELM_SYNC_GDT);
-        VM_FF_SET(pVM, VM_FF_SELM_SYNC_LDT);
-        VM_FF_SET(pVM, VM_FF_SELM_SYNC_TSS);
+        VMCPU_FF_SET(pVCpu, VMCPU_FF_SELM_SYNC_GDT);
+        VMCPU_FF_SET(pVCpu, VMCPU_FF_SELM_SYNC_LDT);
+        VMCPU_FF_SET(pVCpu, VMCPU_FF_SELM_SYNC_TSS);
         SELMR3UpdateFromCPUM(pVM, pVCpu);
     }
@@ -783,7 +786,7 @@
      * Flag everything for resync on next raw mode entry.
      */
-    VM_FF_SET(pVM, VM_FF_SELM_SYNC_GDT);
-    VM_FF_SET(pVM, VM_FF_SELM_SYNC_LDT);
-    VM_FF_SET(pVM, VM_FF_SELM_SYNC_TSS);
+    VMCPU_FF_SET(pVCpu, VMCPU_FF_SELM_SYNC_GDT);
+    VMCPU_FF_SET(pVCpu, VMCPU_FF_SELM_SYNC_LDT);
+    VMCPU_FF_SET(pVCpu, VMCPU_FF_SELM_SYNC_TSS);
 
     return VINF_SUCCESS;
@@ -804,7 +807,7 @@
     if (pVM->selm.s.fDisableMonitoring)
     {
-        VM_FF_CLEAR(pVM, VM_FF_SELM_SYNC_GDT);
-        VM_FF_CLEAR(pVM, VM_FF_SELM_SYNC_LDT);
-        VM_FF_CLEAR(pVM, VM_FF_SELM_SYNC_TSS);
+        VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_SELM_SYNC_GDT);
+        VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_SELM_SYNC_LDT);
+        VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_SELM_SYNC_TSS);
 
         return VINF_SUCCESS;
@@ -816,16 +819,16 @@
      * GDT sync
      */
-    if (VM_FF_ISSET(pVM, VM_FF_SELM_SYNC_GDT))
+    if (VMCPU_FF_ISSET(pVCpu, VMCPU_FF_SELM_SYNC_GDT))
     {
         /*
          * Always assume the best
          */
-        VM_FF_CLEAR(pVM, VM_FF_SELM_SYNC_GDT);
+        VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_SELM_SYNC_GDT);
 
         /* If the GDT was changed, then make sure the LDT is checked too */
         /** @todo only do this if the actual ldtr selector was changed; this is a bit excessive */
-        VM_FF_SET(pVM, VM_FF_SELM_SYNC_LDT);
+        VMCPU_FF_SET(pVCpu, VMCPU_FF_SELM_SYNC_LDT);
         /* Same goes for the TSS selector */
-        VM_FF_SET(pVM, VM_FF_SELM_SYNC_TSS);
+        VMCPU_FF_SET(pVCpu, VMCPU_FF_SELM_SYNC_TSS);
 
         /*
@@ -1074,5 +1077,5 @@
      * TSS sync
      */
-    if (VM_FF_ISSET(pVM, VM_FF_SELM_SYNC_TSS))
+    if (VMCPU_FF_ISSET(pVCpu, VMCPU_FF_SELM_SYNC_TSS))
     {
         SELMR3SyncTSS(pVM, pVCpu);
@@ -1082,10 +1085,10 @@
      * LDT sync
      */
-    if (VM_FF_ISSET(pVM, VM_FF_SELM_SYNC_LDT))
+    if (VMCPU_FF_ISSET(pVCpu, VMCPU_FF_SELM_SYNC_LDT))
     {
         /*
          * Always assume the best
          */
-        VM_FF_CLEAR(pVM, VM_FF_SELM_SYNC_LDT);
+        VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_SELM_SYNC_LDT);
 
         /*
@@ -1368,6 +1371,6 @@
     Assert(enmAccessType == PGMACCESSTYPE_WRITE);
     Log(("selmR3GuestGDTWriteHandler: write to %RGv size %d\n", GCPtr, cbBuf));
-    VM_FF_SET(pVM, VM_FF_SELM_SYNC_GDT);
-
+
+    VMCPU_FF_SET(VMMGetCpu(pVM), VMCPU_FF_SELM_SYNC_GDT);
     return VINF_PGM_HANDLER_DO_DEFAULT;
 }
@@ -1394,5 +1397,5 @@
     Assert(enmAccessType == PGMACCESSTYPE_WRITE);
     Log(("selmR3GuestLDTWriteHandler: write to %RGv size %d\n", GCPtr, cbBuf));
-    VM_FF_SET(pVM, VM_FF_SELM_SYNC_LDT);
+    VMCPU_FF_SET(VMMGetCpu(pVM), VMCPU_FF_SELM_SYNC_LDT);
     return VINF_PGM_HANDLER_DO_DEFAULT;
 }
@@ -1425,5 +1428,5 @@
      *        changes while we're in REM. */
 
-    VM_FF_SET(pVM, VM_FF_SELM_SYNC_TSS);
+    VMCPU_FF_SET(VMMGetCpu(pVM), VMCPU_FF_SELM_SYNC_TSS);
 
     return VINF_PGM_HANDLER_DO_DEFAULT;
@@ -1449,10 +1452,10 @@
     if (pVM->selm.s.fDisableMonitoring)
     {
-        VM_FF_CLEAR(pVM, VM_FF_SELM_SYNC_TSS);
+        VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_SELM_SYNC_TSS);
         return VINF_SUCCESS;
     }
 
     STAM_PROFILE_START(&pVM->selm.s.StatTSSSync, a);
-    Assert(VM_FF_ISSET(pVM, VM_FF_SELM_SYNC_TSS));
+    Assert(VMCPU_FF_ISSET(pVCpu, VMCPU_FF_SELM_SYNC_TSS));
 
     /*
@@ -1632,5 +1635,5 @@
     }
 
-    VM_FF_CLEAR(pVM, VM_FF_SELM_SYNC_TSS);
+    VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_SELM_SYNC_TSS);
 
     STAM_PROFILE_STOP(&pVM->selm.s.StatTSSSync, a);
@@ -1789,5 +1792,5 @@
     PVMCPU pVCpu = VMMGetCpu(pVM);
 
-    if (VM_FF_ISSET(pVM, VM_FF_SELM_SYNC_TSS))
+    if (VMCPU_FF_ISSET(pVCpu, VMCPU_FF_SELM_SYNC_TSS))
         return true;
 
Index: /trunk/src/VBox/VMM/TRPM.cpp
===================================================================
--- /trunk/src/VBox/VMM/TRPM.cpp	(revision 19140)
+++ /trunk/src/VBox/VMM/TRPM.cpp	(revision 19141)
@@ -564,5 +564,6 @@
      * Default action when entering raw mode for the first time
      */
-    VM_FF_SET(pVM, VM_FF_TRPM_SYNC_IDT);
+    PVMCPU pVCpu = &pVM->aCpus[0];  /* raw mode implies on VCPU */
+    VMCPU_FF_SET(pVCpu, VMCPU_FF_TRPM_SYNC_IDT);
     return 0;
 }
@@ -753,5 +754,6 @@
      * Default action when entering raw mode for the first time
      */
-    VM_FF_SET(pVM, VM_FF_TRPM_SYNC_IDT);
+    PVMCPU pVCpu = &pVM->aCpus[0];  /* raw mode implies on VCPU */
+    VMCPU_FF_SET(pVCpu, VMCPU_FF_TRPM_SYNC_IDT);
 }
 
@@ -787,5 +789,6 @@
     }
     SSMR3PutBool(pSSM,      pTrpm->fDisableMonitoring);
-    SSMR3PutUInt(pSSM,      VM_FF_ISSET(pVM, VM_FF_TRPM_SYNC_IDT));
+    PVMCPU pVCpu = &pVM->aCpus[0];  /* raw mode implies 1 VCPU */
+    SSMR3PutUInt(pSSM,      VMCPU_FF_ISSET(pVCpu, VMCPU_FF_TRPM_SYNC_IDT));
     SSMR3PutMem(pSSM,       &pTrpm->au32IdtPatched[0], sizeof(pTrpm->au32IdtPatched));
     SSMR3PutU32(pSSM, ~0);              /* separator. */
@@ -886,5 +889,8 @@
     }
     if (fSyncIDT)
-        VM_FF_SET(pVM, VM_FF_TRPM_SYNC_IDT);
+    {
+        PVMCPU pVCpu = &pVM->aCpus[0];  /* raw mode implies 1 VCPU */
+        VMCPU_FF_SET(pVCpu, VMCPU_FF_TRPM_SYNC_IDT);
+    }
     /* else: cleared by reset call above. */
 
@@ -938,5 +944,5 @@
 /**
  * Check if gate handlers were updated
- * (callback for the VM_FF_TRPM_SYNC_IDT forced action).
+ * (callback for the VMCPU_FF_TRPM_SYNC_IDT forced action).
  *
  * @returns VBox status code.
@@ -952,5 +958,5 @@
     if (pVM->trpm.s.fDisableMonitoring)
     {
-        VM_FF_CLEAR(pVM, VM_FF_TRPM_SYNC_IDT);
+        VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_TRPM_SYNC_IDT);
         return VINF_SUCCESS;    /* Nothing to do */
     }
@@ -1040,5 +1046,5 @@
      * Clear the FF and we're done.
      */
-    VM_FF_CLEAR(pVM, VM_FF_TRPM_SYNC_IDT);
+    VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_TRPM_SYNC_IDT);
     STAM_PROFILE_STOP(&pVM->trpm.s.StatSyncIDT, a);
     return VINF_SUCCESS;
@@ -1078,5 +1084,6 @@
 #endif
 
-    VM_FF_CLEAR(pVM, VM_FF_TRPM_SYNC_IDT);
+    PVMCPU pVCpu = &pVM->aCpus[0];  /* raw mode implies on VCPU */
+    VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_TRPM_SYNC_IDT);
 
     pVM->trpm.s.fDisableMonitoring = true;
@@ -1104,5 +1111,5 @@
     Assert(enmAccessType == PGMACCESSTYPE_WRITE);
     Log(("trpmR3GuestIDTWriteHandler: write to %RGv size %d\n", GCPtr, cbBuf));
-    VM_FF_SET(pVM, VM_FF_TRPM_SYNC_IDT);
+    VMCPU_FF_SET(VMMGetCpu(pVM), VMCPU_FF_TRPM_SYNC_IDT);
     return VINF_PGM_HANDLER_DO_DEFAULT;
 }
@@ -1432,5 +1439,5 @@
     pCtx = CPUMQueryGuestCtxPtr(pVCpu);
     Assert(!PATMIsPatchGCAddr(pVM, (RTGCPTR)pCtx->eip));
-    Assert(!VM_FF_ISSET(pVM, VM_FF_INHIBIT_INTERRUPTS));
+    Assert(!VMCPU_FF_ISSET(pVCpu, VMCPU_FF_INHIBIT_INTERRUPTS));
 
     /* Currently only useful for external hardware interrupts. */
@@ -1447,5 +1454,5 @@
 
         uint8_t u8Interrupt;
-        rc = PDMGetInterrupt(pVM, &u8Interrupt);
+        rc = PDMGetInterrupt(pVCpu, &u8Interrupt);
         Log(("TRPMR3InjectEvent: u8Interrupt=%d (%#x) rc=%Rrc\n", u8Interrupt, u8Interrupt, rc));
         if (RT_SUCCESS(rc))
@@ -1475,5 +1482,5 @@
                     if (rc == VINF_SUCCESS /* Don't use RT_SUCCESS */)
                     {
-                        Assert(!VM_FF_ISPENDING(pVM, VM_FF_SELM_SYNC_GDT | VM_FF_SELM_SYNC_LDT | VM_FF_TRPM_SYNC_IDT | VM_FF_SELM_SYNC_TSS));
+                        Assert(!VMCPU_FF_ISPENDING(pVCpu, VMCPU_FF_SELM_SYNC_GDT | VMCPU_FF_SELM_SYNC_LDT | VMCPU_FF_TRPM_SYNC_IDT | VMCPU_FF_SELM_SYNC_TSS));
 
                         STAM_COUNTER_INC(&pVM->trpm.s.paStatForwardedIRQR3[u8Interrupt]);
@@ -1492,5 +1499,5 @@
         {
             uint8_t u8Interrupt;
-            rc = PDMGetInterrupt(pVM, &u8Interrupt);
+            rc = PDMGetInterrupt(pVCpu, &u8Interrupt);
             Log(("TRPMR3InjectEvent: u8Interrupt=%d (%#x) rc=%Rrc\n", u8Interrupt, u8Interrupt, rc));
             if (RT_SUCCESS(rc))
Index: /trunk/src/VBox/VMM/VM.cpp
===================================================================
--- /trunk/src/VBox/VMM/VM.cpp	(revision 19140)
+++ /trunk/src/VBox/VMM/VM.cpp	(revision 19141)
@@ -1172,5 +1172,5 @@
     }
 
-        /*
+    /*
      * Request the operation in EMT.
      */
@@ -1706,5 +1706,5 @@
      */
     ASMAtomicUoWriteBool(&pVM->pUVM->vm.s.fTerminateEMT, true);
-    ASMAtomicWriteU32(&pVM->fForcedActions, VM_FF_TERMINATE);
+    ASMAtomicWriteU32(&pVM->fGlobalForcedActions, VM_FF_TERMINATE);
     LogFlow(("vmR3Destroy: returning %Rrc\n", VINF_EM_TERMINATE));
     return VINF_EM_TERMINATE;
Index: /trunk/src/VBox/VMM/VMEmt.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMEmt.cpp	(revision 19140)
+++ /trunk/src/VBox/VMM/VMEmt.cpp	(revision 19141)
@@ -344,5 +344,5 @@
  * @param   pUVM            Pointer to the user mode VM structure.
  */
-static DECLCALLBACK(int) vmR3HaltOldDoHalt(PUVM pUVM, const uint32_t fMask, uint64_t /* u64Now*/)
+static DECLCALLBACK(int) vmR3HaltOldDoHalt(PUVM pUVM, PVMCPU pVCpu, const uint32_t fMask, uint64_t /* u64Now*/)
 {
     /*
@@ -363,8 +363,10 @@
         TMR3TimerQueuesDo(pVM);
         STAM_REL_PROFILE_STOP(&pUVM->vm.s.StatHaltTimers, b);
-        if (VM_FF_ISPENDING(pVM, fMask))
+        if (    VM_FF_ISPENDING(pVM, VM_FF_EXTERNAL_HALTED_MASK)
+            ||  VMCPU_FF_ISPENDING(pVCpu, fMask))
             break;
         uint64_t u64NanoTS = TMVirtualToNano(pVM, TMTimerPoll(pVM));
-        if (VM_FF_ISPENDING(pVM, fMask))
+        if (    VM_FF_ISPENDING(pVM, VM_FF_EXTERNAL_HALTED_MASK)
+            ||  VMCPU_FF_ISPENDING(pVCpu, fMask))
             break;
 
@@ -498,5 +500,5 @@
  * the lag has been eliminated.
  */
-static DECLCALLBACK(int) vmR3HaltMethod1Halt(PUVM pUVM, const uint32_t fMask, uint64_t u64Now)
+static DECLCALLBACK(int) vmR3HaltMethod1Halt(PUVM pUVM, PVMCPU pVCpu, const uint32_t fMask, uint64_t u64Now)
 {
     PVM pVM = pUVM->pVM;
@@ -557,5 +559,6 @@
         TMR3TimerQueuesDo(pVM);
         STAM_REL_PROFILE_STOP(&pUVM->vm.s.StatHaltTimers, b);
-        if (VM_FF_ISPENDING(pVM, fMask))
+        if (    VM_FF_ISPENDING(pVM, VM_FF_EXTERNAL_HALTED_MASK)
+            ||  VMCPU_FF_ISPENDING(pVCpu, fMask))
             break;
 
@@ -564,5 +567,6 @@
          */
         uint64_t u64NanoTS = TMVirtualToNano(pVM, TMTimerPoll(pVM));
-        if (VM_FF_ISPENDING(pVM, fMask))
+        if (    VM_FF_ISPENDING(pVM, VM_FF_EXTERNAL_HALTED_MASK)
+            ||  VMCPU_FF_ISPENDING(pVCpu, fMask))
             break;
 
@@ -653,5 +657,5 @@
  * try take care of the global scheduling of EMT threads.
  */
-static DECLCALLBACK(int) vmR3HaltGlobal1Halt(PUVM pUVM, const uint32_t fMask, uint64_t u64Now)
+static DECLCALLBACK(int) vmR3HaltGlobal1Halt(PUVM pUVM, PVMCPU pVCpu, const uint32_t fMask, uint64_t u64Now)
 {
     PVM pVM = pUVM->pVM;
@@ -671,5 +675,6 @@
         TMR3TimerQueuesDo(pVM);
         STAM_REL_PROFILE_STOP(&pUVM->vm.s.StatHaltTimers, b);
-        if (VM_FF_ISPENDING(pVM, fMask))
+        if (    VM_FF_ISPENDING(pVM, VM_FF_EXTERNAL_HALTED_MASK)
+            ||  VMCPU_FF_ISPENDING(pVCpu, fMask))
             break;
 
@@ -679,5 +684,6 @@
         uint64_t u64Delta;
         uint64_t u64GipTime = TMTimerPollGIP(pVM, &u64Delta);
-        if (VM_FF_ISPENDING(pVM, fMask))
+        if (    VM_FF_ISPENDING(pVM, VM_FF_EXTERNAL_HALTED_MASK)
+            ||  VMCPU_FF_ISPENDING(pVCpu, fMask))
             break;
 
@@ -688,6 +694,7 @@
         {
             VMMR3YieldStop(pVM);
-            if (VM_FF_ISPENDING(pVM, fMask))
-                break;
+            if (    VM_FF_ISPENDING(pVM, VM_FF_EXTERNAL_HALTED_MASK)
+                ||  VMCPU_FF_ISPENDING(pVCpu, fMask))
+                    break;
 
             //RTLogRelPrintf("u64NanoTS=%RI64 cLoops=%3d sleep %02dms (%7RU64) ", u64NanoTS, cLoops, cMilliSecs, u64NanoTS);
@@ -734,5 +741,7 @@
     ASMAtomicWriteBool(&pUVM->vm.s.fWait, true);
 
-    PVM pVM = pUVM->pVM;
+    PVM    pVM   = pUVM->pVM;
+    PVMCPU pVCpu = VMMGetCpu(pVM);
+
     int rc = VINF_SUCCESS;
     for (;;)
@@ -741,5 +750,6 @@
          * Check Relevant FFs.
          */
-        if (VM_FF_ISPENDING(pVM, VM_FF_EXTERNAL_SUSPENDED_MASK))
+        if (    VM_FF_ISPENDING(pVM, VM_FF_EXTERNAL_SUSPENDED_MASK)
+            ||  VMCPU_FF_ISPENDING(pVCpu, VMCPU_FF_EXTERNAL_SUSPENDED_MASK))
             break;
 
@@ -804,5 +814,8 @@
             break;
         if (    pUVM->pVM
-            &&  VM_FF_ISPENDING(pUVM->pVM, VM_FF_EXTERNAL_SUSPENDED_MASK))
+            &&  (   VM_FF_ISPENDING(pUVM->pVM, VM_FF_EXTERNAL_SUSPENDED_MASK)
+                 || VMCPU_FF_ISPENDING(VMMGetCpu(pUVM->pVM), VMCPU_FF_EXTERNAL_SUSPENDED_MASK)
+                )
+            )
             break;
         if (pUVM->vm.s.fTerminateEMT)
@@ -859,6 +872,7 @@
     ASMAtomicWriteBool(&pUVM->vm.s.fWait, true);
 
-    PVM pVM = pUVM->pVM;
-    int rc = VINF_SUCCESS;
+    PVM    pVM   = pUVM->pVM;
+    PVMCPU pVCpu = VMMGetCpu(pVM);
+    int    rc    = VINF_SUCCESS;
     for (;;)
     {
@@ -866,5 +880,6 @@
          * Check Relevant FFs.
          */
-        if (VM_FF_ISPENDING(pVM, VM_FF_EXTERNAL_SUSPENDED_MASK))
+        if (    VM_FF_ISPENDING(pVM, VM_FF_EXTERNAL_SUSPENDED_MASK)
+            ||  VMCPU_FF_ISPENDING(pVCpu, VMCPU_FF_EXTERNAL_SUSPENDED_MASK))
             break;
 
@@ -923,5 +938,5 @@
     DECLR3CALLBACKMEMBER(void, pfnTerm,(PUVM pUVM));
     /** The halt function. */
-    DECLR3CALLBACKMEMBER(int,  pfnHalt,(PUVM pUVM, const uint32_t fMask, uint64_t u64Now));
+    DECLR3CALLBACKMEMBER(int,  pfnHalt,(PUVM pUVM, PVMCPU pVCpu, const uint32_t fMask, uint64_t u64Now));
     /** The wait function. */
     DECLR3CALLBACKMEMBER(int,  pfnWait,(PUVM pUVM));
@@ -980,11 +995,10 @@
  *          case an appropriate status code is returned.
  * @param   pVM         VM handle.
+ * @param   pVCpu       VMCPU handle.
  * @param   fIgnoreInterrupts   If set the VM_FF_INTERRUPT flags is ignored.
  * @thread  The emulation thread.
  */
-VMMR3DECL(int) VMR3WaitHalted(PVM pVM, bool fIgnoreInterrupts)
-{
-    PVMCPU pVCpu = VMMGetCpu(pVM);  /* @todo SMP: get rid of this */
-
+VMMR3DECL(int) VMR3WaitHalted(PVM pVM, PVMCPU pVCpu, bool fIgnoreInterrupts)
+{
     LogFlow(("VMR3WaitHalted: fIgnoreInterrupts=%d\n", fIgnoreInterrupts));
 
@@ -993,9 +1007,10 @@
      */
     const uint32_t fMask = !fIgnoreInterrupts
-        ? VM_FF_EXTERNAL_HALTED_MASK
-        : VM_FF_EXTERNAL_HALTED_MASK & ~(VM_FF_INTERRUPT_APIC | VM_FF_INTERRUPT_PIC);
-    if (VM_FF_ISPENDING(pVM, fMask))
-    {
-        LogFlow(("VMR3WaitHalted: returns VINF_SUCCESS (FF %#x)\n", pVM->fForcedActions));
+        ? VMCPU_FF_EXTERNAL_HALTED_MASK
+        : VMCPU_FF_EXTERNAL_HALTED_MASK & ~(VMCPU_FF_INTERRUPT_APIC | VMCPU_FF_INTERRUPT_PIC);
+    if (    VM_FF_ISPENDING(pVM, VM_FF_EXTERNAL_HALTED_MASK)
+        ||  VMCPU_FF_ISPENDING(pVCpu, fMask))
+    {
+        LogFlow(("VMR3WaitHalted: returns VINF_SUCCESS (FF %#x FFCPU %#x)\n", pVM->fGlobalForcedActions, pVCpu->fLocalForcedActions));
         return VINF_SUCCESS;
     }
@@ -1034,5 +1049,5 @@
      * Do the halt.
      */
-    int rc = g_aHaltMethods[pUVM->vm.s.iHaltMethod].pfnHalt(pUVM, fMask, u64Now);
+    int rc = g_aHaltMethods[pUVM->vm.s.iHaltMethod].pfnHalt(pUVM, pVCpu, fMask, u64Now);
 
     /*
@@ -1042,5 +1057,5 @@
     VMMR3YieldResume(pVM);
 
-    LogFlow(("VMR3WaitHalted: returns %Rrc (FF %#x)\n", rc, pVM->fForcedActions));
+    LogFlow(("VMR3WaitHalted: returns %Rrc (FF %#x)\n", rc, pVM->fGlobalForcedActions));
     return rc;
 }
@@ -1064,9 +1079,13 @@
      * Check Relevant FFs.
      */
-    PVM pVM = pUVM->pVM;
+    PVM    pVM   = pUVM->pVM;
+
     if (    pVM
-        &&  VM_FF_ISPENDING(pVM, VM_FF_EXTERNAL_SUSPENDED_MASK))
-    {
-        LogFlow(("VMR3Wait: returns VINF_SUCCESS (FF %#x)\n", pVM->fForcedActions));
+        &&  (   VM_FF_ISPENDING(pVM, VM_FF_EXTERNAL_SUSPENDED_MASK)
+             || VMCPU_FF_ISPENDING(VMMGetCpu(pVM), VMCPU_FF_EXTERNAL_SUSPENDED_MASK)
+            )
+        )
+    {
+        LogFlow(("VMR3Wait: returns VINF_SUCCESS (FF %#x)\n", pVM->fGlobalForcedActions));
         return VINF_SUCCESS;
     }
@@ -1077,5 +1096,5 @@
      */
     int rc = g_aHaltMethods[pUVM->vm.s.iHaltMethod].pfnWait(pUVM);
-    LogFlow(("VMR3WaitU: returns %Rrc (FF %#x)\n", rc, pVM ? pVM->fForcedActions : 0));
+    LogFlow(("VMR3WaitU: returns %Rrc (FF %#x)\n", rc, pVM ? pVM->fGlobalForcedActions : 0));
     return rc;
 }
Index: /trunk/src/VBox/VMM/VMM.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMM.cpp	(revision 19140)
+++ /trunk/src/VBox/VMM/VMM.cpp	(revision 19141)
@@ -1518,11 +1518,17 @@
 static DECLCALLBACK(void) vmmR3InfoFF(PVM pVM, PCDBGFINFOHLP pHlp, const char *pszArgs)
 {
-    const uint32_t fForcedActions = pVM->fForcedActions;
-
-    pHlp->pfnPrintf(pHlp, "Forced action Flags: %#RX32", fForcedActions);
+    const uint32_t fGlobalForcedActions = pVM->fGlobalForcedActions;
+
+    pHlp->pfnPrintf(pHlp, "Forced action Flags: %#RX32", fGlobalForcedActions);
+    for (unsigned i=0;i<pVM->cCPUs;i++)
+    {
+        PVMCPU pVCpu = &pVM->aCpus[i];
+
+        pHlp->pfnPrintf(pHlp, "CPU %d: Forced action Flags: %#RX32", pVCpu->fLocalForcedActions);
+    }
 
     /* show the flag mnemonics  */
     int c = 0;
-    uint32_t f = fForcedActions;
+    uint32_t f = fGlobalForcedActions;
 #define PRINT_FLAG(flag) do { \
         if (f & (flag)) \
@@ -1537,6 +1543,4 @@
         } \
     } while (0)
-    PRINT_FLAG(VM_FF_INTERRUPT_APIC);
-    PRINT_FLAG(VM_FF_INTERRUPT_PIC);
     PRINT_FLAG(VM_FF_TIMER);
     PRINT_FLAG(VM_FF_PDM_QUEUES);
@@ -1547,18 +1551,40 @@
     PRINT_FLAG(VM_FF_TERMINATE);
     PRINT_FLAG(VM_FF_RESET);
-    PRINT_FLAG(VM_FF_PGM_SYNC_CR3);
-    PRINT_FLAG(VM_FF_PGM_SYNC_CR3_NON_GLOBAL);
     PRINT_FLAG(VM_FF_PGM_NEED_HANDY_PAGES);
     PRINT_FLAG(VM_FF_PGM_NO_MEMORY);
-    PRINT_FLAG(VM_FF_TRPM_SYNC_IDT);
-    PRINT_FLAG(VM_FF_SELM_SYNC_TSS);
-    PRINT_FLAG(VM_FF_SELM_SYNC_GDT);
-    PRINT_FLAG(VM_FF_SELM_SYNC_LDT);
-    PRINT_FLAG(VM_FF_INHIBIT_INTERRUPTS);
-    PRINT_FLAG(VM_FF_CSAM_SCAN_PAGE);
-    PRINT_FLAG(VM_FF_CSAM_PENDING_ACTION);
-    PRINT_FLAG(VM_FF_TO_R3);
     PRINT_FLAG(VM_FF_REM_HANDLER_NOTIFY);
     PRINT_FLAG(VM_FF_DEBUG_SUSPEND);
+    for (unsigned i=0;i<pVM->cCPUs;i++)
+    {
+        PVMCPU pVCpu = &pVM->aCpus[i];
+
+        f = pVCpu->fLocalForcedActions;
+#define PRINT_CPU_FLAG(flag) do { \
+        if (f & (flag)) \
+        { \
+            static const char *s_psz = #flag; \
+            if (!(c % 6)) \
+                pHlp->pfnPrintf(pHlp, "CPU %d: %s\n    %s", i, c ? "," : "", s_psz + 6); \
+            else \
+                pHlp->pfnPrintf(pHlp, ", %s", s_psz + 6); \
+            c++; \
+            f &= ~(flag); \
+        } \
+    } while (0)
+
+        PRINT_CPU_FLAG(VMCPU_FF_INTERRUPT_APIC);
+        PRINT_CPU_FLAG(VMCPU_FF_INTERRUPT_PIC);
+        PRINT_CPU_FLAG(VMCPU_FF_PGM_SYNC_CR3);
+        PRINT_CPU_FLAG(VMCPU_FF_PGM_SYNC_CR3_NON_GLOBAL);
+        PRINT_CPU_FLAG(VMCPU_FF_TRPM_SYNC_IDT);
+        PRINT_CPU_FLAG(VMCPU_FF_SELM_SYNC_TSS);
+        PRINT_CPU_FLAG(VMCPU_FF_SELM_SYNC_GDT);
+        PRINT_CPU_FLAG(VMCPU_FF_SELM_SYNC_LDT);
+        PRINT_CPU_FLAG(VMCPU_FF_INHIBIT_INTERRUPTS);
+        PRINT_CPU_FLAG(VMCPU_FF_CSAM_SCAN_PAGE);
+        PRINT_CPU_FLAG(VMCPU_FF_CSAM_PENDING_ACTION);
+        PRINT_CPU_FLAG(VMCPU_FF_TO_R3);
+    }
+
     if (f)
         pHlp->pfnPrintf(pHlp, "%s\n    Unknown bits: %#RX32\n", c ? "," : "", f);
@@ -1566,9 +1592,10 @@
         pHlp->pfnPrintf(pHlp, "\n");
 #undef PRINT_FLAG
+#undef PRINT_CPU_FLAG
 
     /* the groups */
     c = 0;
 #define PRINT_GROUP(grp) do { \
-        if (fForcedActions & (grp)) \
+        if (fGlobalForcedActions & (grp)) \
         { \
             static const char *s_psz = #grp; \
@@ -1587,5 +1614,4 @@
     PRINT_GROUP(VM_FF_NORMAL_PRIORITY_POST_MASK);
     PRINT_GROUP(VM_FF_NORMAL_PRIORITY_MASK);
-    PRINT_GROUP(VM_FF_RESUME_GUEST_MASK);
     PRINT_GROUP(VM_FF_ALL_BUT_RAW_MASK);
     if (c)
Index: /trunk/src/VBox/VMM/VMMAll/EMAll.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMAll/EMAll.cpp	(revision 19140)
+++ /trunk/src/VBox/VMM/VMMAll/EMAll.cpp	(revision 19141)
@@ -2147,9 +2147,9 @@
         {
             Log(("emInterpretMovCRx: CR4: %#RX64->%#RX64 => R3\n", oldval, val));
-            VM_FF_SET(pVM, VM_FF_TO_R3);
+            VMCPU_FF_SET(pVCpu, VMCPU_FF_TO_R3);
         }
 # endif
         if ((val ^ oldval) & X86_CR4_VME)
-            VM_FF_SET(pVM, VM_FF_SELM_SYNC_TSS);
+            VMCPU_FF_SET(pVCpu, VMCPU_FF_SELM_SYNC_TSS);
 
         rc2 = PGMChangeMode(pVCpu, CPUMGetGuestCR0(pVCpu), CPUMGetGuestCR4(pVCpu), CPUMGetGuestEFER(pVCpu));
@@ -2523,5 +2523,5 @@
 
     pVCpu->em.s.GCPtrInhibitInterrupts = pRegFrame->eip + pDISState->opsize;
-    VM_FF_SET(pVM, VM_FF_INHIBIT_INTERRUPTS);
+    VMCPU_FF_SET(pVCpu, VMCPU_FF_INHIBIT_INTERRUPTS);
 
     return VINF_SUCCESS;
@@ -3307,12 +3307,11 @@
  * Sets the PC for which interrupts should be inhibited.
  *
- * @param   pVM         The VM handle.
  * @param   pVCpu       The VMCPU handle.
  * @param   PC          The PC.
  */
-VMMDECL(void) EMSetInhibitInterruptsPC(PVM pVM, PVMCPU pVCpu, RTGCUINTPTR PC)
+VMMDECL(void) EMSetInhibitInterruptsPC(PVMCPU pVCpu, RTGCUINTPTR PC)
 {
     pVCpu->em.s.GCPtrInhibitInterrupts = PC;
-    VM_FF_SET(pVM, VM_FF_INHIBIT_INTERRUPTS);
+    VMCPU_FF_SET(pVCpu, VMCPU_FF_INHIBIT_INTERRUPTS);
 }
 
@@ -3328,9 +3327,8 @@
  *
  * @returns The PC for which interrupts should be inhibited.
- * @param   pVM         VM handle.
  * @param   pVCpu       The VMCPU handle.
  *
  */
-VMMDECL(RTGCUINTPTR) EMGetInhibitInterruptsPC(PVM pVM, PVMCPU pVCpu)
+VMMDECL(RTGCUINTPTR) EMGetInhibitInterruptsPC(PVMCPU pVCpu)
 {
     return pVCpu->em.s.GCPtrInhibitInterrupts;
Index: /trunk/src/VBox/VMM/VMMAll/IOMAllMMIO.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMAll/IOMAllMMIO.cpp	(revision 19140)
+++ /trunk/src/VBox/VMM/VMMAll/IOMAllMMIO.cpp	(revision 19141)
@@ -1868,5 +1868,5 @@
 
 #ifdef VBOX_STRICT
-    if (!VM_FF_ISSET(pVM, VM_FF_PGM_SYNC_CR3))
+    if (!VMCPU_FF_ISSET(pVCpu, VMCPU_FF_PGM_SYNC_CR3))
     {
         uint32_t cb = pRange->cb;
Index: /trunk/src/VBox/VMM/VMMAll/PDMAll.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMAll/PDMAll.cpp	(revision 19140)
+++ /trunk/src/VBox/VMM/VMMAll/PDMAll.cpp	(revision 19141)
@@ -40,9 +40,11 @@
  *
  * @returns VBox status code.
- * @param   pVM             VM handle.
+ * @param   pVCpu           VMCPU handle.
  * @param   pu8Interrupt    Where to store the interrupt on success.
  */
-VMMDECL(int) PDMGetInterrupt(PVM pVM, uint8_t *pu8Interrupt)
-{
+VMMDECL(int) PDMGetInterrupt(PVMCPU pVCpu, uint8_t *pu8Interrupt)
+{
+    PVM pVM = pVCpu->CTX_SUFF(pVM);
+
     pdmLock(pVM);
 
@@ -50,7 +52,7 @@
      * The local APIC has a higer priority than the PIC.
      */
-    if (VM_FF_ISSET(pVM, VM_FF_INTERRUPT_APIC))
-    {
-        VM_FF_CLEAR(pVM, VM_FF_INTERRUPT_APIC);
+    if (VMCPU_FF_ISSET(pVCpu, VMCPU_FF_INTERRUPT_APIC))
+    {
+        VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_INTERRUPT_APIC);
         Assert(pVM->pdm.s.Apic.CTX_SUFF(pDevIns));
         Assert(pVM->pdm.s.Apic.CTX_SUFF(pfnGetInterrupt));
@@ -68,7 +70,7 @@
      * Check the PIC.
      */
-    if (VM_FF_ISSET(pVM, VM_FF_INTERRUPT_PIC))
-    {
-        VM_FF_CLEAR(pVM, VM_FF_INTERRUPT_PIC);
+    if (VMCPU_FF_ISSET(pVCpu, VMCPU_FF_INTERRUPT_PIC))
+    {
+        VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_INTERRUPT_PIC);
         Assert(pVM->pdm.s.Pic.CTX_SUFF(pDevIns));
         Assert(pVM->pdm.s.Pic.CTX_SUFF(pfnGetInterrupt));
Index: /trunk/src/VBox/VMM/VMMAll/PDMAllCritSect.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMAll/PDMAllCritSect.cpp	(revision 19140)
+++ /trunk/src/VBox/VMM/VMMAll/PDMAllCritSect.cpp	(revision 19141)
@@ -203,5 +203,5 @@
     pVM->pdm.s.apQueuedCritSectsLeaves[i] = MMHyperCCToR3(pVM, pCritSect);
     VM_FF_SET(pVM, VM_FF_PDM_CRITSECT);
-    VM_FF_SET(pVM, VM_FF_TO_R3);
+    VMCPU_FF_SET(pVCpu, VMCPU_FF_TO_R3);
     STAM_REL_COUNTER_INC(&pVM->pdm.s.StatQueuedCritSectLeaves);
     STAM_REL_COUNTER_INC(&pCritSect->s.StatContentionRZUnlock);
Index: /trunk/src/VBox/VMM/VMMAll/PDMAllQueue.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMAll/PDMAllQueue.cpp	(revision 19140)
+++ /trunk/src/VBox/VMM/VMMAll/PDMAllQueue.cpp	(revision 19141)
@@ -123,6 +123,6 @@
     else */
     {
-        VM_FF_SET(pVM, VM_FF_TO_R3);
-        Log2(("PDMQueueInsertEx: Setting VM_FF_TO_R3\n"));
+        VMCPU_FF_SET(VMMGetCpu0(pVM), VMCPU_FF_TO_R3);
+        Log2(("PDMQueueInsertEx: Setting VMCPU_FF_TO_R3\n"));
     }
 #endif
Index: /trunk/src/VBox/VMM/VMMAll/PGMAll.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMAll/PGMAll.cpp	(revision 19140)
+++ /trunk/src/VBox/VMM/VMMAll/PGMAll.cpp	(revision 19141)
@@ -710,5 +710,5 @@
         {
             LogFlow(("PGMGCInvalidatePage: Conflict!\n"));
-            VM_FF_SET(pVM, VM_FF_PGM_SYNC_CR3);
+            VMCPU_FF_SET(pVCpu, VMCPU_FF_PGM_SYNC_CR3);
             STAM_COUNTER_INC(&pVM->pgm.s.StatRCInvlPgConflict);
             return VINF_PGM_SYNC_CR3;
@@ -1611,7 +1611,7 @@
      */
     /** @todo optimize this, it shouldn't always be necessary. */
-    VM_FF_SET(pVM, VM_FF_PGM_SYNC_CR3_NON_GLOBAL);
+    VMCPU_FF_SET(pVCpu, VMCPU_FF_PGM_SYNC_CR3_NON_GLOBAL);
     if (fGlobal)
-        VM_FF_SET(pVM, VM_FF_PGM_SYNC_CR3);
+        VMCPU_FF_SET(pVCpu, VMCPU_FF_PGM_SYNC_CR3);
     LogFlow(("PGMFlushTLB: cr3=%RX64 OldCr3=%RX64 fGlobal=%d\n", cr3, pVCpu->pgm.s.GCPhysCR3, fGlobal));
 
@@ -1651,5 +1651,5 @@
         {
             AssertMsg(rc == VINF_PGM_SYNC_CR3, ("%Rrc\n", rc));
-            Assert(VM_FF_ISPENDING(pVM, VM_FF_PGM_SYNC_CR3_NON_GLOBAL | VM_FF_PGM_SYNC_CR3));
+            Assert(VMCPU_FF_ISPENDING(pVCpu, VMCPU_FF_PGM_SYNC_CR3_NON_GLOBAL | VMCPU_FF_PGM_SYNC_CR3));
             pVCpu->pgm.s.GCPhysCR3 = GCPhysOldCR3;
             pVCpu->pgm.s.fSyncFlags |= PGM_SYNC_MAP_CR3;
@@ -1771,6 +1771,6 @@
     {
         Assert((cr0 & (X86_CR0_PG | X86_CR0_PE)) != (X86_CR0_PG | X86_CR0_PE));
-        VM_FF_CLEAR(pVM, VM_FF_PGM_SYNC_CR3);
-        VM_FF_CLEAR(pVM, VM_FF_PGM_SYNC_CR3_NON_GLOBAL);
+        VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_PGM_SYNC_CR3);
+        VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_PGM_SYNC_CR3_NON_GLOBAL);
         return VINF_SUCCESS;
     }
@@ -1780,5 +1780,5 @@
         fGlobal = true;
     LogFlow(("PGMSyncCR3: cr0=%RX64 cr3=%RX64 cr4=%RX64 fGlobal=%d[%d,%d]\n", cr0, cr3, cr4, fGlobal,
-             VM_FF_ISSET(pVM, VM_FF_PGM_SYNC_CR3), VM_FF_ISSET(pVM, VM_FF_PGM_SYNC_CR3_NON_GLOBAL)));
+             VMCPU_FF_ISSET(pVCpu, VMCPU_FF_PGM_SYNC_CR3), VMCPU_FF_ISSET(pVCpu, VMCPU_FF_PGM_SYNC_CR3_NON_GLOBAL)));
 
 #ifdef PGMPOOL_WITH_MONITORING
@@ -1847,6 +1847,6 @@
         if (!(pVCpu->pgm.s.fSyncFlags & PGM_SYNC_ALWAYS))
         {
-            VM_FF_CLEAR(pVM, VM_FF_PGM_SYNC_CR3);
-            VM_FF_CLEAR(pVM, VM_FF_PGM_SYNC_CR3_NON_GLOBAL);
+            VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_PGM_SYNC_CR3);
+            VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_PGM_SYNC_CR3_NON_GLOBAL);
         }
 
Index: /trunk/src/VBox/VMM/VMMAll/PGMAllBth.h
===================================================================
--- /trunk/src/VBox/VMM/VMMAll/PGMAllBth.h	(revision 19140)
+++ /trunk/src/VBox/VMM/VMMAll/PGMAllBth.h	(revision 19141)
@@ -265,5 +265,5 @@
         }
         Log(("SyncPT: %d failed!! rc=%d\n", iPDSrc, rc));
-        VM_FF_SET(pVM, VM_FF_PGM_SYNC_CR3); /** @todo no need to do global sync, right? */
+        VMCPU_FF_SET(pVCpu, VMCPU_FF_PGM_SYNC_CR3); /** @todo no need to do global sync, right? */
         STAM_PROFILE_STOP(&pVCpu->pgm.s.StatRZTrap0eTimeSyncPT, f);
         return VINF_PGM_SYNC_CR3;
@@ -299,5 +299,5 @@
                             STAM_COUNTER_INC(&pVCpu->pgm.s.StatRZTrap0eConflicts);
                             Log(("Trap0e: Detected Conflict %RGv-%RGv\n", pMapping->GCPtr, pMapping->GCPtrLast));
-                            VM_FF_SET(pVM, VM_FF_PGM_SYNC_CR3); /** @todo no need to do global sync,right? */
+                            VMCPU_FF_SET(pVCpu, VMCPU_FF_PGM_SYNC_CR3); /** @todo no need to do global sync,right? */
                             STAM_PROFILE_STOP(&pVCpu->pgm.s.StatRZTrap0eTimeMapping, a);
                             return VINF_PGM_SYNC_CR3;
@@ -973,5 +973,5 @@
         AssertMsg(rc == VERR_PAGE_DIRECTORY_PTR_NOT_PRESENT || rc == VERR_PAGE_MAP_LEVEL4_NOT_PRESENT, ("Unexpected rc=%Rrc\n", rc));
         STAM_COUNTER_INC(&pVCpu->pgm.s.CTX_MID_Z(Stat,InvalidatePageSkipped));
-        if (!VM_FF_ISSET(pVM, VM_FF_PGM_SYNC_CR3))
+        if (!VMCPU_FF_ISSET(pVCpu, VMCPU_FF_PGM_SYNC_CR3))
             PGM_INVL_GUEST_TLBS();
         return VINF_SUCCESS;
@@ -985,5 +985,5 @@
     {
         STAM_COUNTER_INC(&pVCpu->pgm.s.CTX_MID_Z(Stat,InvalidatePageSkipped));
-        if (!VM_FF_ISSET(pVM, VM_FF_PGM_SYNC_CR3))
+        if (!VMCPU_FF_ISSET(pVCpu, VMCPU_FF_PGM_SYNC_CR3))
             PGM_INVL_GUEST_TLBS();
         return VINF_SUCCESS;
@@ -1042,6 +1042,6 @@
      */
 #  ifdef PGM_SKIP_GLOBAL_PAGEDIRS_ON_NONGLOBAL_FLUSH
-    if (    VM_FF_ISSET(pVM, VM_FF_PGM_SYNC_CR3)
-        || (   VM_FF_ISSET(pVM, VM_FF_PGM_SYNC_CR3_NON_GLOBAL)
+    if (    VMCPU_FF_ISSET(pVCpu, VMCPU_FF_PGM_SYNC_CR3)
+        || (   VMCPU_FF_ISSET(pVCpu, VMCPU_FF_PGM_SYNC_CR3_NON_GLOBAL)
             && fIsBigPage
             && PdeSrc.b.u1Global
@@ -2531,5 +2531,5 @@
         else if (rc == VERR_PGM_POOL_FLUSHED)
         {
-            VM_FF_SET(pVM, VM_FF_PGM_SYNC_CR3);
+            VMCPU_FF_SET(pVCpu, VMCPU_FF_PGM_SYNC_CR3);
 # if defined(IN_RC)
             PGMDynUnlockHCPage(pVM, (uint8_t *)pPdeDst);
@@ -3276,5 +3276,5 @@
     PVM pVM = pVCpu->CTX_SUFF(pVM);
 
-    if (VM_FF_ISSET(pVM, VM_FF_PGM_SYNC_CR3))
+    if (VMCPU_FF_ISSET(pVCpu, VMCPU_FF_PGM_SYNC_CR3))
         fGlobal = true; /* Change this CR3 reload to be a global one. */
 
@@ -4298,5 +4298,5 @@
      */
 #   if PGM_WITH_PAGING(PGM_GST_TYPE, PGM_SHW_TYPE)
-    Assert(VM_FF_ISSET(pVM, VM_FF_PGM_SYNC_CR3_NON_GLOBAL) || VM_FF_ISSET(pVM, VM_FF_PGM_SYNC_CR3));
+    Assert(VMCPU_FF_ISSET(pVCpu, VMCPU_FF_PGM_SYNC_CR3_NON_GLOBAL) || VMCPU_FF_ISSET(pVCpu, VMCPU_FF_PGM_SYNC_CR3));
 #   endif
     rc = pgmMapActivateCR3(pVM, pNewShwPageCR3);
Index: /trunk/src/VBox/VMM/VMMAll/PGMAllPhys.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMAll/PGMAllPhys.cpp	(revision 19140)
+++ /trunk/src/VBox/VMM/VMMAll/PGMAllPhys.cpp	(revision 19141)
@@ -291,5 +291,5 @@
                 REMR3NotifyFF(pVM);
 #else
-                VM_FF_SET(pVM, VM_FF_TO_R3); /* paranoia */
+                VMCPU_FF_SET(VMMGetCpu(pVM), VMCPU_FF_TO_R3); /* paranoia */
 #endif
             }
@@ -307,5 +307,5 @@
             {
                 Log(("PGM: VM_FF_TO_R3 - cHandyPages=%u out of %u\n", pVM->pgm.s.cHandyPages, RT_ELEMENTS(pVM->pgm.s.aHandyPages)));
-                VM_FF_SET(pVM, VM_FF_TO_R3);
+                VMCPU_FF_SET(VMMGetCpu(pVM), VMCPU_FF_TO_R3);
             }
 #endif
Index: /trunk/src/VBox/VMM/VMMAll/PGMAllPool.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMAll/PGMAllPool.cpp	(revision 19140)
+++ /trunk/src/VBox/VMM/VMMAll/PGMAllPool.cpp	(revision 19141)
@@ -329,5 +329,5 @@
                         {
                             Assert(pgmMapAreMappingsEnabled(&pVM->pgm.s));
-                            VM_FF_SET(pVM, VM_FF_PGM_SYNC_CR3);
+                            VMCPU_FF_SET(pVCpu, VMCPU_FF_PGM_SYNC_CR3);
                             LogFlow(("pgmPoolMonitorChainChanging: Detected conflict at iShwPdpt=%#x iShw=%#x!\n", iShwPdpt, iShw+i));
                             break;
@@ -357,5 +357,5 @@
                                 {
                                     Assert(pgmMapAreMappingsEnabled(&pVM->pgm.s));
-                                    VM_FF_SET(pVM, VM_FF_PGM_SYNC_CR3);
+                                    VMCPU_FF_SET(pVCpu, VMCPU_FF_PGM_SYNC_CR3);
                                     LogFlow(("pgmPoolMonitorChainChanging: Detected conflict at iShwPdpt=%#x iShw2=%#x!\n", iShwPdpt, iShw2));
                                     break;
@@ -437,5 +437,5 @@
                 {
                     Assert(pgmMapAreMappingsEnabled(&pVM->pgm.s));
-                    VM_FF_SET(pVM, VM_FF_PGM_SYNC_CR3);
+                    VMCPU_FF_SET(pVCpu, VMCPU_FF_PGM_SYNC_CR3);
                     STAM_COUNTER_INC(&(pVCpu->pgm.s.StatRZGuestCR3WriteConflict));
                     LogFlow(("pgmPoolMonitorChainChanging: Detected conflict at iShw=%#x!\n", iShw));
@@ -471,5 +471,5 @@
                             Assert(pgmMapAreMappingsEnabled(&pVM->pgm.s));
                             STAM_COUNTER_INC(&(pVCpu->pgm.s.StatRZGuestCR3WriteConflict));
-                            VM_FF_SET(pVM, VM_FF_PGM_SYNC_CR3);
+                            VMCPU_FF_SET(pVCpu, VMCPU_FF_PGM_SYNC_CR3);
                             LogFlow(("pgmPoolMonitorChainChanging: Detected conflict at iShw2=%#x!\n", iShw2));
                             break;
@@ -494,5 +494,5 @@
 #if 0 /* useful when running PGMAssertCR3(), a bit too troublesome for general use (TLBs). */
                 if (    uShw.pPD->a[iShw].n.u1Present
-                    &&  !VM_FF_ISSET(pVM, VM_FF_PGM_SYNC_CR3))
+                    &&  !VMCPU_FF_ISSET(pVCpu, VMCPU_FF_PGM_SYNC_CR3))
                 {
                     LogFlow(("pgmPoolMonitorChainChanging: iShw=%#x: %RX32 -> freeing it!\n", iShw, uShw.pPD->a[iShw].u));
@@ -515,5 +515,5 @@
                 {
                     Assert(pgmMapAreMappingsEnabled(&pVM->pgm.s));
-                    VM_FF_SET(pVM, VM_FF_PGM_SYNC_CR3);
+                    VMCPU_FF_SET(pVCpu, VMCPU_FF_PGM_SYNC_CR3);
                     STAM_COUNTER_INC(&(pVCpu->pgm.s.StatRZGuestCR3WriteConflict));
                     LogFlow(("pgmPoolMonitorChainChanging: Detected conflict at iShw=%#x!\n", iShw));
@@ -553,5 +553,5 @@
                     {
                         Assert(pgmMapAreMappingsEnabled(&pVM->pgm.s));
-                        VM_FF_SET(pVM, VM_FF_PGM_SYNC_CR3);
+                        VMCPU_FF_SET(pVCpu, VMCPU_FF_PGM_SYNC_CR3);
                         STAM_COUNTER_INC(&(pVCpu->pgm.s.StatRZGuestCR3WriteConflict));
                         LogFlow(("pgmPoolMonitorChainChanging: Detected conflict at iShw2=%#x!\n", iShw2));
@@ -594,5 +594,5 @@
                         Assert(pgmMapAreMappingsEnabled(&pVM->pgm.s));
                         STAM_COUNTER_INC(&(pVCpu->pgm.s.StatRZGuestCR3WriteConflict));
-                        VM_FF_SET(pVM, VM_FF_PGM_SYNC_CR3);
+                        VMCPU_FF_SET(pVCpu, VMCPU_FF_PGM_SYNC_CR3);
                         LogFlow(("pgmPoolMonitorChainChanging: Detected pdpt conflict at iShw=%#x!\n", iShw));
                         break;
@@ -626,5 +626,5 @@
                                 Assert(pgmMapAreMappingsEnabled(&pVM->pgm.s));
                                 STAM_COUNTER_INC(&(pVCpu->pgm.s.StatRZGuestCR3WriteConflict));
-                                VM_FF_SET(pVM, VM_FF_PGM_SYNC_CR3);
+                                VMCPU_FF_SET(pVCpu, VMCPU_FF_PGM_SYNC_CR3);
                                 LogFlow(("pgmPoolMonitorChainChanging: Detected conflict at iShw2=%#x!\n", iShw2));
                                 break;
@@ -692,5 +692,5 @@
                  * - messing with the bits of pd pointers without changing the physical address
                  */
-                if (!VM_FF_ISSET(pVM, VM_FF_PGM_SYNC_CR3))
+                if (!VMCPU_FF_ISSET(pVCpu, VMCPU_FF_PGM_SYNC_CR3))
                 {
                     uShw.pv = PGMPOOL_PAGE_2_LOCKED_PTR(pVM, pPage);
@@ -725,5 +725,5 @@
                  * - messing with the bits of pd pointers without changing the physical address
                  */
-                if (!VM_FF_ISSET(pVM, VM_FF_PGM_SYNC_CR3))
+                if (!VMCPU_FF_ISSET(pVCpu, VMCPU_FF_PGM_SYNC_CR3))
                 {
                     uShw.pv = PGMPOOL_PAGE_2_LOCKED_PTR(pVM, pPage);
@@ -1722,5 +1722,5 @@
          * the heap size should suffice. */
         AssertFatalRC(rc);
-        Assert(!(pVM->pgm.s.fGlobalSyncFlags & PGM_GLOBAL_SYNC_CLEAR_PGM_POOL) || VM_FF_ISSET(pVM, VM_FF_PGM_SYNC_CR3));
+        Assert(!(pVM->pgm.s.fGlobalSyncFlags & PGM_GLOBAL_SYNC_CLEAR_PGM_POOL) || VMCPU_FF_ISSET(VMMGetCpu(pVM), VMCPU_FF_PGM_SYNC_CR3));
     }
     pPage->fMonitored = true;
@@ -1819,6 +1819,6 @@
         rc = PGMHandlerPhysicalDeregister(pVM, pPage->GCPhys & ~(RTGCPHYS)(PAGE_SIZE - 1));
         AssertFatalRC(rc);
-        AssertMsg(!(pVM->pgm.s.fGlobalSyncFlags & PGM_GLOBAL_SYNC_CLEAR_PGM_POOL) || VM_FF_ISSET(pVM, VM_FF_PGM_SYNC_CR3),
-                  ("%#x %#x\n", pVM->pgm.s.fGlobalSyncFlags, pVM->fForcedActions));
+        AssertMsg(!(pVM->pgm.s.fGlobalSyncFlags & PGM_GLOBAL_SYNC_CLEAR_PGM_POOL) || VMCPU_FF_ISSET(VMMGetCpu(pVM), VMCPU_FF_PGM_SYNC_CR3),
+                  ("%#x %#x\n", pVM->pgm.s.fGlobalSyncFlags, pVM->fGlobalForcedActions));
     }
     pPage->fMonitored = false;
@@ -2081,5 +2081,5 @@
 # else  /* !IN_RING3 */
         LogFlow(("SyncCR3: PGM_GLOBAL_SYNC_CLEAR_PGM_POOL is set -> VINF_PGM_SYNC_CR3\n"));
-        VM_FF_SET(pVM, VM_FF_PGM_SYNC_CR3); /** @todo no need to do global sync, right? */
+        VMCPU_FF_SET(VMMGetCpu(pVM), VMCPU_FF_PGM_SYNC_CR3); /** @todo no need to do global sync, right? */
         return VINF_PGM_SYNC_CR3;
 # endif /* !IN_RING3 */
@@ -2713,6 +2713,11 @@
     if (rc == VINF_PGM_GCPHYS_ALIASED)
     {
+        Assert(pVM->cCPUs == 1);    /* @todo check */
         pVM->pgm.s.fGlobalSyncFlags |= PGM_GLOBAL_SYNC_CLEAR_PGM_POOL;
-        VM_FF_SET(pVM, VM_FF_PGM_SYNC_CR3);
+        for (unsigned i=0;i<pVM->cCPUs;i++)
+        {
+            PVMCPU pVCpu = &pVM->aCpus[i];
+            VMCPU_FF_SET(pVCpu, VMCPU_FF_PGM_SYNC_CR3);
+        }
         rc = VINF_PGM_SYNC_CR3;
     }
@@ -3771,24 +3776,4 @@
 #endif /* PGMPOOL_WITH_USER_TRACKING */
 #ifdef IN_RING3
-
-/**
- * Flushes all the special root pages as part of a pgmPoolFlushAllInt operation.
- *
- * @param   pPool       The pool.
- */
-static void pgmPoolFlushAllSpecialRoots(PPGMPOOL pPool)
-{
-    /*
-     * These special pages are all mapped into the indexes 1..PGMPOOL_IDX_FIRST.
-     */
-    Assert(NIL_PGMPOOL_IDX == 0);
-
-    /*
-     * Paranoia (to be removed), flag a global CR3 sync.
-     */
-    VM_FF_SET(pPool->CTX_SUFF(pVM), VM_FF_PGM_SYNC_CR3);
-}
-
-
 /**
  * Flushes the entire cache.
@@ -3823,6 +3808,9 @@
     /** @todo Need to synchronize this across all VCPUs! */
     Assert(pVM->cCPUs == 1);
-    PVMCPU pVCpu = &pVM->aCpus[0];  /* to get it compiled... */
-    pgmR3ExitShadowModeBeforePoolFlush(pVM, pVCpu);
+    for (unsigned i=0;i<pVM->cCPUs;i++)
+    {
+        PVMCPU pVCpu = &pVM->aCpus[i];
+        pgmR3ExitShadowModeBeforePoolFlush(pVM, pVCpu);
+    }
 
     /*
@@ -3929,8 +3917,6 @@
 
     /*
-     * Flush all the special root pages.
      * Reinsert active pages into the hash and ensure monitoring chains are correct.
      */
-    pgmPoolFlushAllSpecialRoots(pPool);
     for (unsigned i = PGMPOOL_IDX_FIRST_SPECIAL; i < PGMPOOL_IDX_FIRST; i++)
     {
@@ -3966,9 +3952,13 @@
     }
 
-    /*
-     * Re-enter the shadowing mode and assert Sync CR3 FF.
-     */
-    pgmR3ReEnterShadowModeAfterPoolFlush(pVM, pVCpu);
-    VM_FF_SET(pVM, VM_FF_PGM_SYNC_CR3);
+    for (unsigned i=0;i<pVM->cCPUs;i++)
+    {
+        PVMCPU pVCpu = &pVM->aCpus[i];
+        /*
+         * Re-enter the shadowing mode and assert Sync CR3 FF.
+         */
+        pgmR3ReEnterShadowModeAfterPoolFlush(pVM, pVCpu);
+        VMCPU_FF_SET(pVCpu, VMCPU_FF_PGM_SYNC_CR3);
+    }
 
     STAM_PROFILE_STOP(&pPool->StatFlushAllInt, a);
Index: /trunk/src/VBox/VMM/VMMAll/TMAllVirtual.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMAll/TMAllVirtual.cpp	(revision 19140)
+++ /trunk/src/VBox/VMM/VMMAll/TMAllVirtual.cpp	(revision 19141)
@@ -96,5 +96,5 @@
     uint64_t u64 = pVM->tm.s.CTX_SUFF(pfnVirtualGetRaw)(&pVM->tm.s.CTX_SUFF(VirtualGetRawData));
     if (cPrevSteps != pVM->tm.s.CTX_SUFF(VirtualGetRawData).c1nsSteps)
-        VM_FF_SET(pVM, VM_FF_TO_R3); /* S10 hack */
+        VMCPU_FF_SET(VMMGetCpu(pVM), VMCPU_FF_TO_R3);
     return u64;
 # endif /* !IN_RING3 */
Index: /trunk/src/VBox/VMM/VMMAll/TRPMAll.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMAll/TRPMAll.cpp	(revision 19140)
+++ /trunk/src/VBox/VMM/VMMAll/TRPMAll.cpp	(revision 19141)
@@ -410,6 +410,6 @@
     eflags.u32 = CPUMRawGetEFlags(pVCpu, pRegFrame);
 
-    /* VM_FF_INHIBIT_INTERRUPTS should be cleared upfront or don't call this function at all for dispatching hardware interrupts. */
-    Assert(enmType != TRPM_HARDWARE_INT || !VM_FF_ISSET(pVM, VM_FF_INHIBIT_INTERRUPTS));
+    /* VMCPU_FF_INHIBIT_INTERRUPTS should be cleared upfront or don't call this function at all for dispatching hardware interrupts. */
+    Assert(enmType != TRPM_HARDWARE_INT || !VMCPU_FF_ISSET(pVCpu, VMCPU_FF_INHIBIT_INTERRUPTS));
 
     /*
@@ -434,5 +434,5 @@
 
         Assert(PATMAreInterruptsEnabledByCtxCore(pVM, pRegFrame));
-        Assert(!VM_FF_ISPENDING(pVM, VM_FF_SELM_SYNC_GDT | VM_FF_SELM_SYNC_LDT | VM_FF_TRPM_SYNC_IDT | VM_FF_SELM_SYNC_TSS));
+        Assert(!VMCPU_FF_ISPENDING(pVCpu, VMCPU_FF_SELM_SYNC_GDT | VMCPU_FF_SELM_SYNC_LDT | VMCPU_FF_TRPM_SYNC_IDT | VMCPU_FF_SELM_SYNC_TSS));
 
         /* Get the current privilege level. */
Index: /trunk/src/VBox/VMM/VMMGC/PDMGCDevice.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMGC/PDMGCDevice.cpp	(revision 19140)
+++ /trunk/src/VBox/VMM/VMMGC/PDMGCDevice.cpp	(revision 19141)
@@ -369,8 +369,11 @@
 {
     PDMDEV_ASSERT_DEVINS(pDevIns);
-    LogFlow(("pdmRCPicHlp_SetInterruptFF: caller=%p/%d: VM_FF_INTERRUPT_PIC %d -> 1\n",
-             pDevIns, pDevIns->iInstance, VMCPU_FF_ISSET(pDevIns->Internal.s.pVMRC, 0, VM_FF_INTERRUPT_PIC)));
-    /* for PIC we always deliver to CPU 0, MP use APIC */
-    VMCPU_FF_SET(pDevIns->Internal.s.pVMRC, 0, VM_FF_INTERRUPT_PIC);
+    PVM pVM = pDevIns->Internal.s.pVMRC;
+    PVMCPU pVCpu = &pVM->aCpus[0];  /* for PIC we always deliver to CPU 0, MP use APIC */
+
+    LogFlow(("pdmRCPicHlp_SetInterruptFF: caller=%p/%d: VMMCPU_FF_INTERRUPT_PIC %d -> 1\n",
+             pDevIns, pDevIns->iInstance, VMCPU_FF_ISSET(pVCpu, VMCPU_FF_INTERRUPT_PIC)));
+
+    VMCPU_FF_SET(pVCpu, VMCPU_FF_INTERRUPT_PIC);
 }
 
@@ -380,8 +383,11 @@
 {
     PDMDEV_ASSERT_DEVINS(pDevIns);
-    LogFlow(("pdmRCPicHlp_ClearInterruptFF: caller=%p/%d: VM_FF_INTERRUPT_PIC %d -> 0\n",
-             pDevIns, pDevIns->iInstance, VMCPU_FF_ISSET(pDevIns->Internal.s.pVMRC, 0, VM_FF_INTERRUPT_PIC)));
-    /* for PIC we always deliver to CPU 0, MP use APIC */
-    VMCPU_FF_CLEAR(pDevIns->Internal.s.pVMRC, 0, VM_FF_INTERRUPT_PIC);
+    PVM pVM = pDevIns->Internal.s.CTX_SUFF(pVM);
+    PVMCPU pVCpu = &pVM->aCpus[0];  /* for PIC we always deliver to CPU 0, MP use APIC */
+
+    LogFlow(("pdmRCPicHlp_ClearInterruptFF: caller=%p/%d: VMCPU_FF_INTERRUPT_PIC %d -> 0\n",
+             pDevIns, pDevIns->iInstance, VMCPU_FF_ISSET(pVCpu, VMCPU_FF_INTERRUPT_PIC)));
+
+    VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_INTERRUPT_PIC);
 }
 
@@ -409,7 +415,12 @@
 {
     PDMDEV_ASSERT_DEVINS(pDevIns);
+    PVM pVM = pDevIns->Internal.s.pVMRC;
+    PVMCPU pVCpu = &pVM->aCpus[idCpu];
+
+    AssertReturnVoid(idCpu < pVM->cCPUs);
+
     LogFlow(("pdmRCApicHlp_SetInterruptFF: caller=%p/%d: VM_FF_INTERRUPT %d -> 1\n",
-             pDevIns, pDevIns->iInstance, VMCPU_FF_ISSET(pDevIns->Internal.s.pVMRC, idCpu, VM_FF_INTERRUPT_APIC)));
-    VMCPU_FF_SET(pDevIns->Internal.s.pVMRC, idCpu, VM_FF_INTERRUPT_APIC);
+             pDevIns, pDevIns->iInstance, VMCPU_FF_ISSET(pVCpu, VMCPU_FF_INTERRUPT_APIC)));
+    VMCPU_FF_SET(pVCpu, VMCPU_FF_INTERRUPT_APIC);
 }
 
@@ -419,7 +430,12 @@
 {
     PDMDEV_ASSERT_DEVINS(pDevIns);
+    PVM pVM = pDevIns->Internal.s.pVMRC;
+    PVMCPU pVCpu = &pVM->aCpus[idCpu];
+
+    AssertReturnVoid(idCpu < pVM->cCPUs);
+
     LogFlow(("pdmRCApicHlp_ClearInterruptFF: caller=%p/%d: VM_FF_INTERRUPT %d -> 0\n",
-             pDevIns, pDevIns->iInstance, VMCPU_FF_ISSET(pDevIns->Internal.s.pVMRC, idCpu, VM_FF_INTERRUPT_APIC)));
-    VMCPU_FF_CLEAR(pDevIns->Internal.s.pVMRC, idCpu, VM_FF_INTERRUPT_APIC);
+             pDevIns, pDevIns->iInstance, VMCPU_FF_ISSET(pVCpu, VMCPU_FF_INTERRUPT_APIC)));
+    VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_INTERRUPT_APIC);
 }
 
Index: /trunk/src/VBox/VMM/VMMGC/SELMGC.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMGC/SELMGC.cpp	(revision 19140)
+++ /trunk/src/VBox/VMM/VMMGC/SELMGC.cpp	(revision 19141)
@@ -139,5 +139,5 @@
     if (Sel == CPUMGetGuestLDTR(pVCpu)) /** @todo this isn't correct in two(+) ways! 1. It shouldn't be done until the LDTR is reloaded. 2. It caused the next instruction to be emulated.  */
     {
-        VM_FF_SET(pVM, VM_FF_SELM_SYNC_LDT);
+        VMCPU_FF_SET(pVCpu, VMCPU_FF_SELM_SYNC_LDT);
         return VINF_EM_RAW_EMULATE_INSTR_LDT_FAULT;
     }
@@ -229,5 +229,5 @@
     {
         /* Not necessary when we need to go back to the host context to sync the LDT or TSS. */
-        VM_FF_SET(pVM, VM_FF_SELM_SYNC_GDT);
+        VMCPU_FF_SET(pVCpu, VMCPU_FF_SELM_SYNC_GDT);
     }
     STAM_COUNTER_INC(&pVM->selm.s.StatRCWriteGuestGDTUnhandled);
@@ -253,5 +253,5 @@
     ////LogCom(("selmRCGuestLDTWriteHandler: eip=%08X pvFault=%RGv pvRange=%RGv\r\n", pRegFrame->eip, pvFault, pvRange));
 
-    VM_FF_SET(pVM, VM_FF_SELM_SYNC_LDT);
+    VMCPU_FF_SET(VMMGetCpu0(pVM), VMCPU_FF_SELM_SYNC_LDT);
     STAM_COUNTER_INC(&pVM->selm.s.StatRCWriteGuestLDT);
     return VINF_EM_RAW_EMULATE_INSTR_LDT_FAULT;
@@ -368,6 +368,6 @@
                 {
                     Log(("TSS offIoBitmap changed: old=%#x new=%#x -> resync in ring-3\n", pVM->selm.s.offGuestIoBitmap, offIoBitmap));
-                    VM_FF_SET(pVM, VM_FF_SELM_SYNC_TSS);
-                    VM_FF_SET(pVM, VM_FF_TO_R3);
+                    VMCPU_FF_SET(pVCpu, VMCPU_FF_SELM_SYNC_TSS);
+                    VMCPU_FF_SET(pVCpu, VMCPU_FF_TO_R3);
                 }
                 else
@@ -401,6 +401,6 @@
         if (rc != VINF_SUCCESS)
         {
-            VM_FF_SET(pVM, VM_FF_SELM_SYNC_TSS);
-            VM_FF_SET(pVM, VM_FF_TO_R3);
+            VMCPU_FF_SET(pVCpu, VMCPU_FF_SELM_SYNC_TSS);
+            VMCPU_FF_SET(pVCpu, VMCPU_FF_TO_R3);
             if (RT_SUCCESS(rc))
                 rc = VINF_SUCCESS;
@@ -412,5 +412,5 @@
     {
         Assert(RT_FAILURE(rc));
-        VM_FF_SET(pVM, VM_FF_SELM_SYNC_TSS);
+        VMCPU_FF_SET(pVCpu, VMCPU_FF_SELM_SYNC_TSS);
         STAM_COUNTER_INC(&pVM->selm.s.StatRCWriteGuestTSSUnhandled);
         if (rc == VERR_EM_INTERPRETER)
Index: /trunk/src/VBox/VMM/VMMGC/TRPMGC.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMGC/TRPMGC.cpp	(revision 19140)
+++ /trunk/src/VBox/VMM/VMMGC/TRPMGC.cpp	(revision 19141)
@@ -150,5 +150,5 @@
 
     /** @todo Check which IDT entry and keep the update cost low in TRPMR3SyncIDT() and CSAMCheckGates(). */
-    VM_FF_SET(pVM, VM_FF_TRPM_SYNC_IDT);
+    VMCPU_FF_SET(pVCpu, VMCPU_FF_TRPM_SYNC_IDT);
 
     STAM_COUNTER_INC(&pVM->trpm.s.StatRCWriteGuestIDTFault);
Index: /trunk/src/VBox/VMM/VMMGC/TRPMGCHandlers.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMGC/TRPMGCHandlers.cpp	(revision 19140)
+++ /trunk/src/VBox/VMM/VMMGC/TRPMGCHandlers.cpp	(revision 19141)
@@ -166,8 +166,8 @@
 
     /* Clear pending inhibit interrupt state if required. (necessary for dispatching interrupts later on) */
-    if (VM_FF_ISSET(pVM, VM_FF_INHIBIT_INTERRUPTS))
-    {
-        Log2(("VM_FF_INHIBIT_INTERRUPTS at %08RX32 successor %RGv\n", pRegFrame->eip, EMGetInhibitInterruptsPC(pVM, pVCpu)));
-        if (pRegFrame->eip != EMGetInhibitInterruptsPC(pVM, pVCpu))
+    if (VMCPU_FF_ISSET(pVCpu, VMCPU_FF_INHIBIT_INTERRUPTS))
+    {
+        Log2(("VM_FF_INHIBIT_INTERRUPTS at %08RX32 successor %RGv\n", pRegFrame->eip, EMGetInhibitInterruptsPC(pVCpu)));
+        if (pRegFrame->eip != EMGetInhibitInterruptsPC(pVCpu))
         {
             /** @note we intentionally don't clear VM_FF_INHIBIT_INTERRUPTS here if the eip is the same as the inhibited instr address.
@@ -176,5 +176,5 @@
              *  break the guest. Sounds very unlikely, but such timing sensitive problem are not as rare as you might think.
              */
-            VM_FF_CLEAR(pVM, VM_FF_INHIBIT_INTERRUPTS);
+            VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_INHIBIT_INTERRUPTS);
         }
     }
@@ -185,6 +185,8 @@
      */
     if (    rc == VINF_SUCCESS
-        &&  VM_FF_ISPENDING(pVM, VM_FF_TO_R3 | VM_FF_TIMER | VM_FF_INTERRUPT_APIC | VM_FF_INTERRUPT_PIC | VM_FF_REQUEST
-                               | VM_FF_PGM_SYNC_CR3 | VM_FF_PGM_SYNC_CR3_NON_GLOBAL | VM_FF_PGM_NO_MEMORY))
+        &&  (   VM_FF_ISPENDING(pVM, VM_FF_TIMER | VM_FF_REQUEST | VM_FF_PGM_NO_MEMORY)
+             || VMCPU_FF_ISPENDING(pVCpu, VMCPU_FF_TO_R3 | VMCPU_FF_INTERRUPT_APIC | VMCPU_FF_INTERRUPT_PIC | VMCPU_FF_REQUEST | VMCPU_FF_PGM_SYNC_CR3 | VMCPU_FF_PGM_SYNC_CR3_NON_GLOBAL)
+            )
+       )
     {
         /* The out of memory condition naturally outrang the others. */
@@ -192,7 +194,7 @@
             rc = VINF_EM_NO_MEMORY;
         /* Pending Ring-3 action. */
-        else if (VM_FF_ISPENDING(pVM, VM_FF_TO_R3))
-        {
-            VM_FF_CLEAR(pVM, VM_FF_TO_R3);
+        else if (VMCPU_FF_ISPENDING(pVCpu, VMCPU_FF_TO_R3))
+        {
+            VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_TO_R3);
             rc = VINF_EM_RAW_TO_R3;
         }
@@ -201,11 +203,11 @@
             rc = VINF_EM_RAW_TIMER_PENDING;
         /* Pending interrupt: dispatch it. */
-        else if (    VM_FF_ISPENDING(pVM, VM_FF_INTERRUPT_APIC | VM_FF_INTERRUPT_PIC)
-                 && !VM_FF_ISSET(pVM, VM_FF_INHIBIT_INTERRUPTS)
+        else if (    VMCPU_FF_ISPENDING(pVCpu, VMCPU_FF_INTERRUPT_APIC | VMCPU_FF_INTERRUPT_PIC)
+                 && !VMCPU_FF_ISSET(pVCpu, VMCPU_FF_INHIBIT_INTERRUPTS)
                  &&  PATMAreInterruptsEnabledByCtxCore(pVM, pRegFrame)
            )
         {
             uint8_t u8Interrupt;
-            rc = PDMGetInterrupt(pVM, &u8Interrupt);
+            rc = PDMGetInterrupt(pVCpu, &u8Interrupt);
             Log(("trpmGCExitTrap: u8Interrupt=%d (%#x) rc=%Rrc\n", u8Interrupt, u8Interrupt, rc));
             AssertFatalMsgRC(rc, ("PDMGetInterrupt failed with %Rrc\n", rc));
@@ -227,12 +229,13 @@
          * Try sync CR3?
          */
-        else if (VM_FF_ISPENDING(pVM, VM_FF_PGM_SYNC_CR3 | VM_FF_PGM_SYNC_CR3_NON_GLOBAL))
+        else if (VMCPU_FF_ISPENDING(pVCpu, VMCPU_FF_PGM_SYNC_CR3 | VMCPU_FF_PGM_SYNC_CR3_NON_GLOBAL))
 #if 1
-            rc = PGMSyncCR3(pVCpu, CPUMGetGuestCR0(pVCpu), CPUMGetGuestCR3(pVCpu), CPUMGetGuestCR4(pVCpu), VM_FF_ISSET(pVM, VM_FF_PGM_SYNC_CR3));
+            rc = PGMSyncCR3(pVCpu, CPUMGetGuestCR0(pVCpu), CPUMGetGuestCR3(pVCpu), CPUMGetGuestCR4(pVCpu), VMCPU_FF_ISSET(pVCpu, VMCPU_FF_PGM_SYNC_CR3));
 #else
             rc = VINF_PGM_SYNC_CR3;
 #endif
         /* Pending request packets might contain actions that need immediate attention, such as pending hardware interrupts. */
-        else if (VM_FF_ISPENDING(pVM, VM_FF_REQUEST))
+        else if (   VM_FF_ISPENDING(pVM, VM_FF_REQUEST)
+                 || VMCPU_FF_ISPENDING(pVCpu, VMCPU_FF_REQUEST))
             rc = VINF_EM_PENDING_REQUEST;
     }
Index: /trunk/src/VBox/VMM/VMMR0/HWACCMR0.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR0/HWACCMR0.cpp	(revision 19140)
+++ /trunk/src/VBox/VMM/VMMR0/HWACCMR0.cpp	(revision 19141)
@@ -1058,5 +1058,5 @@
 #endif
 
-    Assert(!VM_FF_ISPENDING(pVM, VM_FF_PGM_SYNC_CR3 | VM_FF_PGM_SYNC_CR3_NON_GLOBAL));
+    Assert(!VMCPU_FF_ISPENDING(pVCpu, VMCPU_FF_PGM_SYNC_CR3 | VMCPU_FF_PGM_SYNC_CR3_NON_GLOBAL));
     Assert(HWACCMR0Globals.aCpuInfo[idCpu].fConfigured);
     AssertReturn(!ASMAtomicReadBool(&HWACCMR0Globals.fSuspended), VERR_HWACCM_SUSPEND_PENDING);
Index: /trunk/src/VBox/VMM/VMMR0/HWSVMR0.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR0/HWSVMR0.cpp	(revision 19140)
+++ /trunk/src/VBox/VMM/VMMR0/HWSVMR0.cpp	(revision 19141)
@@ -375,5 +375,5 @@
     {
         Log(("INJ-EI: %x at %RGv\n", pEvent->n.u8Vector, (RTGCPTR)pCtx->rip));
-        Assert(!VM_FF_ISSET(pVM, VM_FF_INHIBIT_INTERRUPTS));
+        Assert(!VMCPU_FF_ISSET(VMMGetCpu(pVM), VMCPU_FF_INHIBIT_INTERRUPTS));
         Assert(pCtx->eflags.u32 & X86_EFL_IF);
     }
@@ -428,12 +428,12 @@
     /* When external interrupts are pending, we should exit the VM when IF is set. */
     if (    !TRPMHasTrap(pVCpu)
-        &&  VM_FF_ISPENDING(pVM, (VM_FF_INTERRUPT_APIC|VM_FF_INTERRUPT_PIC)))
+        &&  VMCPU_FF_ISPENDING(pVCpu, (VMCPU_FF_INTERRUPT_APIC|VMCPU_FF_INTERRUPT_PIC)))
     {
         if (    !(pCtx->eflags.u32 & X86_EFL_IF)
-            ||  VM_FF_ISSET(pVM, VM_FF_INHIBIT_INTERRUPTS))
+            ||  VMCPU_FF_ISSET(pVCpu, VMCPU_FF_INHIBIT_INTERRUPTS))
         {
             if (!pVMCB->ctrl.IntCtrl.n.u1VIrqValid)
             {
-                if (!VM_FF_ISSET(pVM, VM_FF_INHIBIT_INTERRUPTS))
+                if (!VMCPU_FF_ISSET(pVCpu, VMCPU_FF_INHIBIT_INTERRUPTS))
                     LogFlow(("Enable irq window exit!\n"));
                 else
@@ -450,5 +450,5 @@
             uint8_t u8Interrupt;
 
-            rc = PDMGetInterrupt(pVM, &u8Interrupt);
+            rc = PDMGetInterrupt(pVCpu, &u8Interrupt);
             Log(("Dispatch interrupt: u8Interrupt=%x (%d) rc=%Rrc\n", u8Interrupt, u8Interrupt, rc));
             if (RT_SUCCESS(rc))
@@ -460,5 +460,5 @@
             {
                 /* Can only happen in rare cases where a pending interrupt is cleared behind our back */
-                Assert(!VM_FF_ISPENDING(pVM, (VM_FF_INTERRUPT_APIC|VM_FF_INTERRUPT_PIC)));
+                Assert(!VMCPU_FF_ISPENDING(pVCpu, (VMCPU_FF_INTERRUPT_APIC|VMCPU_FF_INTERRUPT_PIC)));
                 STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatSwitchGuestIrq);
                 /* Just continue */
@@ -477,5 +477,5 @@
 
     if (    pCtx->eflags.u32 & X86_EFL_IF
-        && (!VM_FF_ISSET(pVM, VM_FF_INHIBIT_INTERRUPTS))
+        && (!VMCPU_FF_ISSET(pVCpu, VMCPU_FF_INHIBIT_INTERRUPTS))
         && TRPMHasTrap(pVCpu)
        )
@@ -678,5 +678,5 @@
         {
             pVMCB->guest.u64CR3             = PGMGetHyperCR3(pVCpu);
-            Assert(pVMCB->guest.u64CR3 || VM_FF_ISPENDING(pVM, VM_FF_PGM_SYNC_CR3 | VM_FF_PGM_SYNC_CR3_NON_GLOBAL));
+            Assert(pVMCB->guest.u64CR3 || VMCPU_FF_ISPENDING(pVCpu, VMCPU_FF_PGM_SYNC_CR3 | VMCPU_FF_PGM_SYNC_CR3_NON_GLOBAL));
         }
     }
@@ -867,8 +867,8 @@
 
     /* Check for irq inhibition due to instruction fusing (sti, mov ss). */
-    if (VM_FF_ISSET(pVM, VM_FF_INHIBIT_INTERRUPTS))
-    {
-        Log(("VM_FF_INHIBIT_INTERRUPTS at %RGv successor %RGv\n", (RTGCPTR)pCtx->rip, EMGetInhibitInterruptsPC(pVM, pVCpu)));
-        if (pCtx->rip != EMGetInhibitInterruptsPC(pVM, pVCpu))
+    if (VMCPU_FF_ISSET(pVCpu, VMCPU_FF_INHIBIT_INTERRUPTS))
+    {
+        Log(("VM_FF_INHIBIT_INTERRUPTS at %RGv successor %RGv\n", (RTGCPTR)pCtx->rip, EMGetInhibitInterruptsPC(pVCpu)));
+        if (pCtx->rip != EMGetInhibitInterruptsPC(pVCpu))
         {
             /* Note: we intentionally don't clear VM_FF_INHIBIT_INTERRUPTS here.
@@ -877,5 +877,5 @@
              * break the guest. Sounds very unlikely, but such timing sensitive problems are not as rare as you might think.
              */
-            VM_FF_CLEAR(pVM, VM_FF_INHIBIT_INTERRUPTS);
+            VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_INHIBIT_INTERRUPTS);
             /* Irq inhibition is no longer active; clear the corresponding SVM state. */
             pVMCB->ctrl.u64IntShadow = 0;
@@ -894,7 +894,8 @@
 #endif
     {
-        if (VM_FF_ISPENDING(pVM, VM_FF_HWACCM_TO_R3_MASK))
-        {
-            VM_FF_CLEAR(pVM, VM_FF_TO_R3);
+        if (    VM_FF_ISPENDING(pVM, VM_FF_HWACCM_TO_R3_MASK)
+            ||  VMCPU_FF_ISPENDING(pVCpu, VMCPU_FF_HWACCM_TO_R3_MASK))
+        {
+            VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_TO_R3);
             STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatSwitchToR3);
             STAM_PROFILE_ADV_STOP(&pVCpu->hwaccm.s.StatEntry, x);
@@ -1245,8 +1246,8 @@
     {
         Log(("uInterruptState %x rip=%RGv\n", pVMCB->ctrl.u64IntShadow, (RTGCPTR)pCtx->rip));
-        EMSetInhibitInterruptsPC(pVM, pVCpu, pCtx->rip);
+        EMSetInhibitInterruptsPC(pVCpu, pCtx->rip);
     }
     else
-        VM_FF_CLEAR(pVM, VM_FF_INHIBIT_INTERRUPTS);
+        VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_INHIBIT_INTERRUPTS);
 
     Log2(("exitCode = %x\n", exitCode));
@@ -1719,7 +1720,7 @@
         /* Check if a sync operation is pending. */
         if (    rc == VINF_SUCCESS /* don't bother if we are going to ring 3 anyway */
-            &&  VM_FF_ISPENDING(pVM, VM_FF_PGM_SYNC_CR3 | VM_FF_PGM_SYNC_CR3_NON_GLOBAL))
-        {
-            rc = PGMSyncCR3(pVCpu, pCtx->cr0, pCtx->cr3, pCtx->cr4, VM_FF_ISSET(pVM, VM_FF_PGM_SYNC_CR3));
+            &&  VMCPU_FF_ISPENDING(pVCpu, VMCPU_FF_PGM_SYNC_CR3 | VMCPU_FF_PGM_SYNC_CR3_NON_GLOBAL))
+        {
+            rc = PGMSyncCR3(pVCpu, pCtx->cr0, pCtx->cr3, pCtx->cr4, VMCPU_FF_ISSET(pVCpu, VMCPU_FF_PGM_SYNC_CR3));
             AssertRC(rc);
 
@@ -2010,5 +2011,5 @@
         pCtx->rip++;    /* skip hlt */
         if (    pCtx->eflags.Bits.u1IF
-            &&  VM_FF_ISPENDING(pVM, (VM_FF_INTERRUPT_APIC|VM_FF_INTERRUPT_PIC)))
+            &&  VMCPU_FF_ISPENDING(pVCpu, (VMCPU_FF_INTERRUPT_APIC|VMCPU_FF_INTERRUPT_PIC)))
             goto ResumeExecution;
 
Index: /trunk/src/VBox/VMM/VMMR0/HWVMXR0.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR0/HWVMXR0.cpp	(revision 19140)
+++ /trunk/src/VBox/VMM/VMMR0/HWVMXR0.cpp	(revision 19141)
@@ -608,5 +608,5 @@
     {
         LogFlow(("INJ-EI: %x at %RGv\n", iGate, (RTGCPTR)pCtx->rip));
-        Assert(VMX_EXIT_INTERRUPTION_INFO_TYPE(intInfo) == VMX_EXIT_INTERRUPTION_INFO_TYPE_SW || !VM_FF_ISSET(pVM, VM_FF_INHIBIT_INTERRUPTS));
+        Assert(VMX_EXIT_INTERRUPTION_INFO_TYPE(intInfo) == VMX_EXIT_INTERRUPTION_INFO_TYPE_SW || !VMCPU_FF_ISSET(pVCpu, VMCPU_FF_INHIBIT_INTERRUPTS));
         Assert(VMX_EXIT_INTERRUPTION_INFO_TYPE(intInfo) == VMX_EXIT_INTERRUPTION_INFO_TYPE_SW || pCtx->eflags.u32 & X86_EFL_IF);
     }
@@ -737,5 +737,5 @@
     /* When external interrupts are pending, we should exit the VM when IF is set. */
     if (    !TRPMHasTrap(pVCpu)
-        &&  VM_FF_ISPENDING(pVM, (VM_FF_INTERRUPT_APIC|VM_FF_INTERRUPT_PIC)))
+        &&  VMCPU_FF_ISPENDING(pVCpu, (VMCPU_FF_INTERRUPT_APIC|VMCPU_FF_INTERRUPT_PIC)))
     {
         if (!(pCtx->eflags.u32 & X86_EFL_IF))
@@ -751,9 +751,9 @@
         }
         else
-        if (!VM_FF_ISSET(pVM, VM_FF_INHIBIT_INTERRUPTS))
+        if (!VMCPU_FF_ISSET(pVCpu, VMCPU_FF_INHIBIT_INTERRUPTS))
         {
             uint8_t u8Interrupt;
 
-            rc = PDMGetInterrupt(pVM, &u8Interrupt);
+            rc = PDMGetInterrupt(pVCpu, &u8Interrupt);
             Log(("Dispatch interrupt: u8Interrupt=%x (%d) rc=%Rrc cs:rip=%04X:%RGv\n", u8Interrupt, u8Interrupt, rc, pCtx->cs, (RTGCPTR)pCtx->rip));
             if (RT_SUCCESS(rc))
@@ -765,5 +765,5 @@
             {
                 /* Can only happen in rare cases where a pending interrupt is cleared behind our back */
-                Assert(!VM_FF_ISPENDING(pVM, (VM_FF_INTERRUPT_APIC|VM_FF_INTERRUPT_PIC)));
+                Assert(!VMCPU_FF_ISPENDING(pVCpu, (VMCPU_FF_INTERRUPT_APIC|VMCPU_FF_INTERRUPT_PIC)));
                 STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatSwitchGuestIrq);
                 /* Just continue */
@@ -784,5 +784,5 @@
 
     if (    pCtx->eflags.u32 & X86_EFL_IF
-        && (!VM_FF_ISSET(pVM, VM_FF_INHIBIT_INTERRUPTS))
+        && (!VMCPU_FF_ISSET(pVCpu, VMCPU_FF_INHIBIT_INTERRUPTS))
         && TRPMHasTrap(pVCpu)
        )
@@ -1526,5 +1526,5 @@
         {
             val = PGMGetHyperCR3(pVCpu);
-            Assert(val || VM_FF_ISPENDING(pVM, VM_FF_PGM_SYNC_CR3 | VM_FF_PGM_SYNC_CR3_NON_GLOBAL));
+            Assert(val || VMCPU_FF_ISPENDING(pVCpu, VMCPU_FF_PGM_SYNC_CR3 | VMCPU_FF_PGM_SYNC_CR3_NON_GLOBAL));
         }
 
@@ -1693,8 +1693,8 @@
         Assert(uInterruptState <= 2);    /* only sti & mov ss */
         Log(("uInterruptState %x eip=%RGv\n", uInterruptState, pCtx->rip));
-        EMSetInhibitInterruptsPC(pVM, pVCpu, pCtx->rip);
+        EMSetInhibitInterruptsPC(pVCpu, pCtx->rip);
     }
     else
-        VM_FF_CLEAR(pVM, VM_FF_INHIBIT_INTERRUPTS);
+        VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_INHIBIT_INTERRUPTS);
 
     /* Control registers. */
@@ -2035,8 +2035,8 @@
 
     /* Check for irq inhibition due to instruction fusing (sti, mov ss). */
-    if (VM_FF_ISSET(pVM, VM_FF_INHIBIT_INTERRUPTS))
-    {
-        Log(("VM_FF_INHIBIT_INTERRUPTS at %RGv successor %RGv\n", (RTGCPTR)pCtx->rip, EMGetInhibitInterruptsPC(pVM, pVCpu)));
-        if (pCtx->rip != EMGetInhibitInterruptsPC(pVM, pVCpu))
+    if (VMCPU_FF_ISSET(pVCpu, VMCPU_FF_INHIBIT_INTERRUPTS))
+    {
+        Log(("VM_FF_INHIBIT_INTERRUPTS at %RGv successor %RGv\n", (RTGCPTR)pCtx->rip, EMGetInhibitInterruptsPC(pVCpu)));
+        if (pCtx->rip != EMGetInhibitInterruptsPC(pVCpu))
         {
             /* Note: we intentionally don't clear VM_FF_INHIBIT_INTERRUPTS here.
@@ -2045,5 +2045,5 @@
              * break the guest. Sounds very unlikely, but such timing sensitive problems are not as rare as you might think.
              */
-            VM_FF_CLEAR(pVM, VM_FF_INHIBIT_INTERRUPTS);
+            VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_INHIBIT_INTERRUPTS);
             /* Irq inhibition is no longer active; clear the corresponding VMX state. */
             rc = VMXWriteVMCS(VMX_VMCS32_GUEST_INTERRUPTIBILITY_STATE,   0);
@@ -2059,7 +2059,8 @@
 
     /* Check for pending actions that force us to go back to ring 3. */
-    if (VM_FF_ISPENDING(pVM, VM_FF_HWACCM_TO_R3_MASK))
-    {
-        VM_FF_CLEAR(pVM, VM_FF_TO_R3);
+    if (    VM_FF_ISPENDING(pVM, VM_FF_HWACCM_TO_R3_MASK)
+        ||  VMCPU_FF_ISPENDING(pVCpu, VMCPU_FF_HWACCM_TO_R3_MASK))
+    {
+        VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_TO_R3);
         STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatSwitchToR3);
         rc = RT_UNLIKELY(VM_FF_ISPENDING(pVM, VM_FF_PGM_NO_MEMORY)) ? VINF_EM_NO_MEMORY : VINF_EM_RAW_TO_R3;
@@ -2890,5 +2891,5 @@
     case VMX_EXIT_IRQ_WINDOW:           /* 7 Interrupt window. */
         /* Clear VM-exit on IF=1 change. */
-        LogFlow(("VMX_EXIT_IRQ_WINDOW %RGv pending=%d IF=%d\n", (RTGCPTR)pCtx->rip, VM_FF_ISPENDING(pVM, (VM_FF_INTERRUPT_APIC|VM_FF_INTERRUPT_PIC)), pCtx->eflags.Bits.u1IF));
+        LogFlow(("VMX_EXIT_IRQ_WINDOW %RGv pending=%d IF=%d\n", (RTGCPTR)pCtx->rip, VMCPU_FF_ISPENDING(pVCpu, (VMCPU_FF_INTERRUPT_APIC|VMCPU_FF_INTERRUPT_PIC)), pCtx->eflags.Bits.u1IF));
         pVCpu->hwaccm.s.vmx.proc_ctls &= ~VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_IRQ_WINDOW_EXIT;
         rc = VMXWriteVMCS(VMX_VMCS_CTRL_PROC_EXEC_CONTROLS, pVCpu->hwaccm.s.vmx.proc_ctls);
@@ -3028,7 +3029,7 @@
             /* Check if a sync operation is pending. */
             if (    rc == VINF_SUCCESS /* don't bother if we are going to ring 3 anyway */
-                &&  VM_FF_ISPENDING(pVM, VM_FF_PGM_SYNC_CR3 | VM_FF_PGM_SYNC_CR3_NON_GLOBAL))
+                &&  VMCPU_FF_ISPENDING(pVCpu, VMCPU_FF_PGM_SYNC_CR3 | VMCPU_FF_PGM_SYNC_CR3_NON_GLOBAL))
             {
-                rc = PGMSyncCR3(pVCpu, pCtx->cr0, pCtx->cr3, pCtx->cr4, VM_FF_ISSET(pVM, VM_FF_PGM_SYNC_CR3));
+                rc = PGMSyncCR3(pVCpu, pCtx->cr0, pCtx->cr3, pCtx->cr4, VMCPU_FF_ISSET(pVCpu, VMCPU_FF_PGM_SYNC_CR3));
                 AssertRC(rc);
             }
@@ -3346,5 +3347,5 @@
         pCtx->rip++;    /* skip hlt */
         if (    pCtx->eflags.Bits.u1IF
-            &&  VM_FF_ISPENDING(pVM, (VM_FF_INTERRUPT_APIC|VM_FF_INTERRUPT_PIC)))
+            &&  VMCPU_FF_ISPENDING(pVCpu, (VMCPU_FF_INTERRUPT_APIC|VMCPU_FF_INTERRUPT_PIC)))
             goto ResumeExecution;
 
Index: /trunk/src/VBox/VMM/VMMR0/PDMR0Device.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR0/PDMR0Device.cpp	(revision 19140)
+++ /trunk/src/VBox/VMM/VMMR0/PDMR0Device.cpp	(revision 19141)
@@ -384,8 +384,11 @@
 {
     PDMDEV_ASSERT_DEVINS(pDevIns);
-    LogFlow(("pdmR0PicHlp_SetInterruptFF: caller=%p/%d: VM_FF_INTERRUPT_PIC %d -> 1\n",
-             pDevIns, pDevIns->iInstance, VMCPU_FF_ISSET(pDevIns->Internal.s.pVMR0, 0, VM_FF_INTERRUPT_PIC)));
-    /* for PIC we always deliver to CPU 0, MP use APIC */
-    VMCPU_FF_SET(pDevIns->Internal.s.pVMR0, 0, VM_FF_INTERRUPT_PIC);
+    PVM    pVM   = pDevIns->Internal.s.pVMR0;
+    PVMCPU pVCpu = &pVM->aCpus[0];      /* for PIC we always deliver to CPU 0, MP use APIC */
+
+    LogFlow(("pdmR0PicHlp_SetInterruptFF: caller=%p/%d: VMCPU_FF_INTERRUPT_PIC %d -> 1\n",
+             pDevIns, pDevIns->iInstance, VMCPU_FF_ISSET(pVCpu, VMCPU_FF_INTERRUPT_PIC)));
+    
+    VMCPU_FF_SET(pVCpu, VMCPU_FF_INTERRUPT_PIC);
 }
 
@@ -395,8 +398,11 @@
 {
     PDMDEV_ASSERT_DEVINS(pDevIns);
-    LogFlow(("pdmR0PicHlp_ClearInterruptFF: caller=%p/%d: VM_FF_INTERRUPT_PIC %d -> 0\n",
-             pDevIns, pDevIns->iInstance, VMCPU_FF_ISSET(pDevIns->Internal.s.pVMR0, 0, VM_FF_INTERRUPT_PIC)));
-    /* for PIC we always deliver to CPU 0, MP use APIC */
-    VMCPU_FF_CLEAR(pDevIns->Internal.s.pVMR0, 0, VM_FF_INTERRUPT_PIC);
+    PVM    pVM   = pDevIns->Internal.s.pVMR0;
+    PVMCPU pVCpu = &pVM->aCpus[0];      /* for PIC we always deliver to CPU 0, MP use APIC */
+
+    LogFlow(("pdmR0PicHlp_ClearInterruptFF: caller=%p/%d: VMCPU_FF_INTERRUPT_PIC %d -> 0\n",
+             pDevIns, pDevIns->iInstance, VMCPU_FF_ISSET(pVCpu, VMCPU_FF_INTERRUPT_PIC)));
+
+    VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_INTERRUPT_PIC);
 }
 
@@ -423,8 +429,12 @@
 {
     PDMDEV_ASSERT_DEVINS(pDevIns);
+    PVM    pVM   = pDevIns->Internal.s.pVMR0;
+    PVMCPU pVCpu = &pVM->aCpus[idCpu];
+
+    AssertReturnVoid(idCpu < pVM->cCPUs);
 
     LogFlow(("pdmR0ApicHlp_SetInterruptFF: caller=%p/%d: VM_FF_INTERRUPT %d -> 1\n",
-             pDevIns, pDevIns->iInstance, VMCPU_FF_ISSET(pDevIns->Internal.s.pVMR0, idCpu, VM_FF_INTERRUPT_APIC)));
-    VMCPU_FF_SET(pDevIns->Internal.s.pVMR0, idCpu, VM_FF_INTERRUPT_APIC);
+             pDevIns, pDevIns->iInstance, VMCPU_FF_ISSET(pVCpu, VMCPU_FF_INTERRUPT_APIC)));
+    VMCPU_FF_SET(pVCpu, VMCPU_FF_INTERRUPT_APIC);
 }
 
@@ -434,8 +444,12 @@
 {
     PDMDEV_ASSERT_DEVINS(pDevIns);
+    PVM    pVM   = pDevIns->Internal.s.pVMR0;
+    PVMCPU pVCpu = &pVM->aCpus[idCpu];
+
+    AssertReturnVoid(idCpu < pVM->cCPUs);
 
     LogFlow(("pdmR0ApicHlp_ClearInterruptFF: caller=%p/%d: VM_FF_INTERRUPT %d -> 0\n",
-             pDevIns, pDevIns->iInstance, VMCPU_FF_ISSET(pDevIns->Internal.s.pVMR0, idCpu, VM_FF_INTERRUPT_APIC)));
-    VMCPU_FF_CLEAR(pDevIns->Internal.s.pVMR0, idCpu, VM_FF_INTERRUPT_APIC);
+             pDevIns, pDevIns->iInstance, VMCPU_FF_ISSET(pVCpu, VMCPU_FF_INTERRUPT_APIC)));
+    VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_INTERRUPT_APIC);
 }
 
Index: /trunk/src/VBox/VMM/VMMTests.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMTests.cpp	(revision 19140)
+++ /trunk/src/VBox/VMM/VMMTests.cpp	(revision 19141)
@@ -391,6 +391,6 @@
          * These forced actions are not necessary for the test and trigger breakpoints too.
          */
-        VM_FF_CLEAR(pVM, VM_FF_TRPM_SYNC_IDT);
-        VM_FF_CLEAR(pVM, VM_FF_SELM_SYNC_TSS);
+        VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_TRPM_SYNC_IDT);
+        VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_SELM_SYNC_TSS);
 
         /*
@@ -485,6 +485,6 @@
      * These forced actions are not necessary for the test and trigger breakpoints too.
      */
-    VM_FF_CLEAR(pVM, VM_FF_TRPM_SYNC_IDT);
-    VM_FF_CLEAR(pVM, VM_FF_SELM_SYNC_TSS);
+    VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_TRPM_SYNC_IDT);
+    VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_SELM_SYNC_TSS);
 
     /* Enable mapping of the hypervisor into the shadow page table. */
@@ -504,5 +504,5 @@
     PGMSyncCR3(pVCpu, pHyperCtx->cr0, CR3Phys, pHyperCtx->cr4, true);
 
-    VM_FF_CLEAR(pVM, VM_FF_TO_R3);
+    VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_TO_R3);
     VM_FF_CLEAR(pVM, VM_FF_TIMER);
     VM_FF_CLEAR(pVM, VM_FF_REQUEST);
@@ -555,5 +555,5 @@
             pGuestCtx->cr3 = CR3Phys;
 
-            VM_FF_CLEAR(pVM, VM_FF_TO_R3);
+            VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_TO_R3);
             VM_FF_CLEAR(pVM, VM_FF_TIMER);
 
Index: /trunk/src/VBox/VMM/VMReq.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMReq.cpp	(revision 19140)
+++ /trunk/src/VBox/VMM/VMReq.cpp	(revision 19141)
@@ -628,4 +628,6 @@
         for (unsigned i=0;i<pUVM->pVM->cCPUs;i++)
         {
+            PVMCPU pVCpu = &pUVM->pVM->aCpus[i];
+
             if (   !pUVMCPU
                 ||  pUVMCPU->idCpu != i)
@@ -646,5 +648,5 @@
                  */
                 if (pUVM->pVM)
-                    VMCPU_FF_SET(pUVM->pVM, VM_FF_REQUEST, i);
+                    VMCPU_FF_SET(pVCpu, VM_FF_REQUEST);
                 /* @todo: VMR3NotifyFFU*/
                 AssertFailed();
@@ -674,4 +676,5 @@
     {
         RTCPUID  idTarget = (RTCPUID)pReq->enmDest;
+        PVMCPU   pVCpu = &pUVM->pVM->aCpus[idTarget];
         unsigned fFlags = ((VMREQ volatile *)pReq)->fFlags;     /* volatile paranoia */
 
@@ -691,5 +694,5 @@
          */
         if (pUVM->pVM)
-            VMCPU_FF_SET(pUVM->pVM, VM_FF_REQUEST, idTarget);
+            VMCPU_FF_SET(pVCpu, VM_FF_REQUEST);
         /* @todo: VMR3NotifyFFU*/
         AssertFailed();
@@ -851,5 +854,9 @@
             ppReqs = (void * volatile *)&pUVM->aCpus[enmDest].vm.s.pReqs;
             if (RT_LIKELY(pUVM->pVM))
-                VMCPU_FF_CLEAR(pUVM->pVM, enmDest, VM_FF_REQUEST);
+            {
+                PVMCPU pVCpu = &pUVM->pVM->aCpus[enmDest];
+
+                VMCPU_FF_CLEAR(pVCpu, VM_FF_REQUEST);
+            }
         }
 
Index: /trunk/src/recompiler_new/VBoxREMWrapper.cpp
===================================================================
--- /trunk/src/recompiler_new/VBoxREMWrapper.cpp	(revision 19140)
+++ /trunk/src/recompiler_new/VBoxREMWrapper.cpp	(revision 19141)
@@ -705,5 +705,5 @@
 static const REMPARMDESC g_aArgsPDMGetInterrupt[] =
 {
-    { REMPARMDESC_FLAGS_INT,        sizeof(PVM), NULL },
+    { REMPARMDESC_FLAGS_INT,        sizeof(PVMCPU), NULL },
     { REMPARMDESC_FLAGS_INT,        sizeof(uint8_t *), NULL }
 };
@@ -1171,8 +1171,8 @@
     { "TMVirtualResume",                        (void *)(uintptr_t)&TMVirtualResume,                &g_aArgsVM[0],                              RT_ELEMENTS(g_aArgsVM),                                REMFNDESC_FLAGS_RET_INT,    sizeof(int),        NULL },
     { "TRPMAssertTrap",                         (void *)(uintptr_t)&TRPMAssertTrap,                 &g_aArgsTRPMAssertTrap[0],                  RT_ELEMENTS(g_aArgsTRPMAssertTrap),                    REMFNDESC_FLAGS_RET_INT,    sizeof(int),        NULL },
-    { "TRPMGetErrorCode",                       (void *)(uintptr_t)&TRPMGetErrorCode,               &g_aArgsVM[0],                              RT_ELEMENTS(g_aArgsVM),                                REMFNDESC_FLAGS_RET_INT,    sizeof(RTGCUINT),   NULL },
-    { "TRPMGetFaultAddress",                    (void *)(uintptr_t)&TRPMGetFaultAddress,            &g_aArgsVM[0],                              RT_ELEMENTS(g_aArgsVM),                                REMFNDESC_FLAGS_RET_INT,    sizeof(RTGCUINTPTR),NULL },
+    { "TRPMGetErrorCode",                       (void *)(uintptr_t)&TRPMGetErrorCode,               &g_aArgsVMCPU[0],                           RT_ELEMENTS(g_aArgsVMCPU),                             REMFNDESC_FLAGS_RET_INT,    sizeof(RTGCUINT),   NULL },
+    { "TRPMGetFaultAddress",                    (void *)(uintptr_t)&TRPMGetFaultAddress,            &g_aArgsVMCPU[0],                           RT_ELEMENTS(g_aArgsVMCPU),                             REMFNDESC_FLAGS_RET_INT,    sizeof(RTGCUINTPTR),NULL },
     { "TRPMQueryTrap",                          (void *)(uintptr_t)&TRPMQueryTrap,                  &g_aArgsTRPMQueryTrap[0],                   RT_ELEMENTS(g_aArgsTRPMQueryTrap),                     REMFNDESC_FLAGS_RET_INT,    sizeof(int),        NULL },
-    { "TRPMResetTrap",                          (void *)(uintptr_t)&TRPMResetTrap,                  &g_aArgsVM[0],                              RT_ELEMENTS(g_aArgsVM),                                REMFNDESC_FLAGS_RET_INT,    sizeof(int),        NULL },
+    { "TRPMResetTrap",                          (void *)(uintptr_t)&TRPMResetTrap,                  &g_aArgsVMCPU[0],                           RT_ELEMENTS(g_aArgsVMCPU),                             REMFNDESC_FLAGS_RET_INT,    sizeof(int),        NULL },
     { "TRPMSetErrorCode",                       (void *)(uintptr_t)&TRPMSetErrorCode,               &g_aArgsTRPMSetErrorCode[0],                RT_ELEMENTS(g_aArgsTRPMSetErrorCode),                  REMFNDESC_FLAGS_RET_VOID,   0,                  NULL },
     { "TRPMSetFaultAddress",                    (void *)(uintptr_t)&TRPMSetFaultAddress,            &g_aArgsTRPMSetFaultAddress[0],             RT_ELEMENTS(g_aArgsTRPMSetFaultAddress),               REMFNDESC_FLAGS_RET_VOID,   0,                  NULL },
Index: /trunk/src/recompiler_new/VBoxRecompiler.c
===================================================================
--- /trunk/src/recompiler_new/VBoxRecompiler.c	(revision 19140)
+++ /trunk/src/recompiler_new/VBoxRecompiler.c	(revision 19141)
@@ -1450,5 +1450,5 @@
     pCtx->cr3 = env->cr[3];
     if ((env->cr[4] ^ pCtx->cr4) & X86_CR4_VME)
-        VM_FF_SET(pVM, VM_FF_SELM_SYNC_TSS);
+        VMCPU_FF_SET(env->pVCpu, VMCPU_FF_SELM_SYNC_TSS);
     pCtx->cr4 = env->cr[4];
 
@@ -1461,5 +1461,5 @@
     {
         AssertMsgFailed(("remR3FlushPage %RGv failed with %d!!\n", GCPtr, rc));
-        VM_FF_SET(pVM, VM_FF_PGM_SYNC_CR3);
+        VMCPU_FF_SET(env->pVCpu, VMCPU_FF_PGM_SYNC_CR3);
     }
     //RAWEx_ProfileStart(env, STATS_QEMU_TOTAL);
@@ -1566,5 +1566,5 @@
     pCtx->cr3 = env->cr[3];
     if ((env->cr[4] ^ pCtx->cr4) & X86_CR4_VME)
-        VM_FF_SET(pVM, VM_FF_SELM_SYNC_TSS);
+        VMCPU_FF_SET(env->pVCpu, VMCPU_FF_SELM_SYNC_TSS);
     pCtx->cr4 = env->cr[4];
 
@@ -1606,5 +1606,5 @@
     pCtx->cr3 = env->cr[3];
     if ((env->cr[4] ^ pCtx->cr4) & X86_CR4_VME)
-        VM_FF_SET(pVM, VM_FF_SELM_SYNC_TSS);
+        VMCPU_FF_SET(env->pVCpu, VMCPU_FF_SELM_SYNC_TSS);
     pCtx->cr4 = env->cr[4];
 
@@ -2188,5 +2188,5 @@
     pVM->rem.s.Env.interrupt_request &= ~(CPU_INTERRUPT_HARD | CPU_INTERRUPT_EXIT | CPU_INTERRUPT_EXITTB | CPU_INTERRUPT_TIMER);
     if (    pVM->rem.s.u32PendingInterrupt != REM_NO_PENDING_IRQ
-        ||  VM_FF_ISPENDING(pVM, VM_FF_INTERRUPT_APIC | VM_FF_INTERRUPT_PIC))
+        ||  VMCPU_FF_ISPENDING(pVCpu, VMCPU_FF_INTERRUPT_APIC | VMCPU_FF_INTERRUPT_PIC))
         pVM->rem.s.Env.interrupt_request |= CPU_INTERRUPT_HARD;
 
@@ -2317,5 +2317,5 @@
     pCtx->cr3           = pVM->rem.s.Env.cr[3];
     if ((pVM->rem.s.Env.cr[4] ^ pCtx->cr4) & X86_CR4_VME)
-        VM_FF_SET(pVM, VM_FF_SELM_SYNC_TSS);
+        VMCPU_FF_SET(pVCpu, VMCPU_FF_SELM_SYNC_TSS);
     pCtx->cr4           = pVM->rem.s.Env.cr[4];
 
@@ -2328,5 +2328,5 @@
         pCtx->gdtr.pGdt = pVM->rem.s.Env.gdt.base;
         STAM_COUNTER_INC(&gStatREMGDTChange);
-        VM_FF_SET(pVM, VM_FF_SELM_SYNC_GDT);
+        VMCPU_FF_SET(pVCpu, VMCPU_FF_SELM_SYNC_GDT);
     }
 
@@ -2336,5 +2336,5 @@
         pCtx->idtr.pIdt = pVM->rem.s.Env.idt.base;
         STAM_COUNTER_INC(&gStatREMIDTChange);
-        VM_FF_SET(pVM, VM_FF_TRPM_SYNC_IDT);
+        VMCPU_FF_SET(pVCpu, VMCPU_FF_TRPM_SYNC_IDT);
     }
 
@@ -2349,5 +2349,5 @@
         pCtx->ldtrHid.Attr.u    = (pVM->rem.s.Env.ldt.flags >> 8) & 0xF0FF;
         STAM_COUNTER_INC(&gStatREMLDTRChange);
-        VM_FF_SET(pVM, VM_FF_SELM_SYNC_LDT);
+        VMCPU_FF_SET(pVCpu, VMCPU_FF_SELM_SYNC_LDT);
     }
 
@@ -2371,5 +2371,5 @@
             pCtx->trHid.Attr.u |= DESC_TSS_BUSY_MASK >> 8;
         STAM_COUNTER_INC(&gStatREMTRChange);
-        VM_FF_SET(pVM, VM_FF_SELM_SYNC_TSS);
+        VMCPU_FF_SET(pVCpu, VMCPU_FF_SELM_SYNC_TSS);
     }
 
@@ -2533,5 +2533,5 @@
     pCtx->cr3           = pVM->rem.s.Env.cr[3];
     if ((pVM->rem.s.Env.cr[4] ^ pCtx->cr4) & X86_CR4_VME)
-        VM_FF_SET(pVM, VM_FF_SELM_SYNC_TSS);
+        VMCPU_FF_SET(pVCpu, VMCPU_FF_SELM_SYNC_TSS);
     pCtx->cr4           = pVM->rem.s.Env.cr[4];
 
@@ -2544,5 +2544,5 @@
         pCtx->gdtr.pGdt     = (RTGCPTR)pVM->rem.s.Env.gdt.base;
         STAM_COUNTER_INC(&gStatREMGDTChange);
-        VM_FF_SET(pVM, VM_FF_SELM_SYNC_GDT);
+        VMCPU_FF_SET(pVCpu, VMCPU_FF_SELM_SYNC_GDT);
     }
 
@@ -2552,5 +2552,5 @@
         pCtx->idtr.pIdt     = (RTGCPTR)pVM->rem.s.Env.idt.base;
         STAM_COUNTER_INC(&gStatREMIDTChange);
-        VM_FF_SET(pVM, VM_FF_TRPM_SYNC_IDT);
+        VMCPU_FF_SET(pVCpu, VMCPU_FF_TRPM_SYNC_IDT);
     }
 
@@ -2565,5 +2565,5 @@
         pCtx->ldtrHid.Attr.u    = (pVM->rem.s.Env.ldt.flags >> 8) & 0xFFFF;
         STAM_COUNTER_INC(&gStatREMLDTRChange);
-        VM_FF_SET(pVM, VM_FF_SELM_SYNC_LDT);
+        VMCPU_FF_SET(pVCpu, VMCPU_FF_SELM_SYNC_LDT);
     }
 
@@ -2587,5 +2587,5 @@
             pCtx->trHid.Attr.u |= DESC_TSS_BUSY_MASK >> 8;
         STAM_COUNTER_INC(&gStatREMTRChange);
-        VM_FF_SET(pVM, VM_FF_SELM_SYNC_TSS);
+        VMCPU_FF_SET(pVCpu, VMCPU_FF_SELM_SYNC_TSS);
     }
 
@@ -4030,10 +4030,10 @@
     }
     else
-        rc = PDMGetInterrupt(env->pVM, &u8Interrupt);
+        rc = PDMGetInterrupt(env->pVCpu, &u8Interrupt);
 
     LogFlow(("cpu_get_pic_interrupt: u8Interrupt=%d rc=%Rrc\n", u8Interrupt, rc));
     if (RT_SUCCESS(rc))
     {
-        if (VM_FF_ISPENDING(env->pVM, VM_FF_INTERRUPT_APIC | VM_FF_INTERRUPT_PIC))
+        if (VMCPU_FF_ISPENDING(env->pVCpu, VMCPU_FF_INTERRUPT_APIC | VMCPU_FF_INTERRUPT_PIC))
             env->interrupt_request |= CPU_INTERRUPT_HARD;
         return u8Interrupt;
