Index: /trunk/Config.kmk
===================================================================
--- /trunk/Config.kmk	(revision 33934)
+++ /trunk/Config.kmk	(revision 33935)
@@ -663,4 +663,10 @@
 if1of ($(KBUILD_TARGET), darwin freebsd linux solaris win)
  VBOX_WITH_VMMR0_DISABLE_PREEMPTION = 1
+endif
+# Mask all Local APIC interrupt vectors which are set up to NMI mode when switching
+# to/from the guest in raw mode. Modern Linux kernels use the performance counter
+# to raise an NMI from time to time.
+if1of ($(KBUILD_TARGET), linux)
+ VBOX_WITH_VMMR0_DISABLE_LAPIC_NMI = 1
 endif
 ## For testing deadlock detection and lock order validation.
Index: /trunk/include/VBox/apic.h
===================================================================
--- /trunk/include/VBox/apic.h	(revision 33935)
+++ /trunk/include/VBox/apic.h	(revision 33935)
@@ -0,0 +1,55 @@
+/** @file
+ * X86 (and AMD64) Local APIC registers (VMM,++).
+ *
+ * apic.mac is generated from this file by running 'kmk incs' in the root.
+ */
+
+/*
+ * Copyright (C) 2010 Oracle Corporation.
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+#ifndef ___VBox_apic_h
+#define ___VBox_apic_h
+
+#define APIC_REG_VERSION                        0x0030
+#define   APIC_REG_VERSION_GET_VER(u32)         (u32 & 0xff)
+#define   APIC_REG_VERSION_GET_MAX_LVT(u32)     ((u32 & 0xff0000) >> 16)
+
+/* defines according to Figure 10-8 of the Intel Software Developers Manual Vol 3A */
+#define APIC_REG_LVT_LINT0                      0x0350
+#define APIC_REG_LVT_LINT1                      0x0360
+#define APIC_REG_LVT_ERR                        0x0370
+#define APIC_REG_LVT_PC                         0x0340
+#define APIC_REG_LVT_THMR                       0x0330
+#define   APIC_REG_LVT_MODE_MASK                (RT_BIT(8)|RT_BIT(9)|RT_BIT(10))
+#define   APIC_REG_LVT_MODE_FIXED               0
+#define   APIC_REG_LVT_MODE_NMI                 (RT_BIT(10))
+#define   APIC_REG_LVT_MODE_EXTINT              (RT_BIT(8)|RT_BIT(9)|RT_BIT(10))
+#define   APIC_REG_LVT_PIN_POLARIY              RT_BIT(13)
+#define   APIC_REG_LVT_REMOTE_IRR               RT_BIT(14)
+#define   APIC_REG_LVT_LEVEL_TRIGGER            RT_BIT(15)
+#define   APIC_REG_LVT_MASKED                   RT_BIT(16)
+
+DECLINLINE(uint32_t) ApicRegRead(void *pBase, uint32_t reg)
+{
+    return *(const volatile uint32_t*)((uintptr_t)pBase + reg);
+}
+
+#endif
Index: /trunk/include/VBox/apic.mac
===================================================================
--- /trunk/include/VBox/apic.mac	(revision 33935)
+++ /trunk/include/VBox/apic.mac	(revision 33935)
@@ -0,0 +1,19 @@
+%ifndef ___VBox_apic_h
+%define ___VBox_apic_h
+%define APIC_REG_VERSION                        0x0030
+%define   APIC_REG_VERSION_GET_VER(u32)         (u32 & 0xff)
+%define   APIC_REG_VERSION_GET_MAX_LVT(u32)     ((u32 & 0xff0000) >> 16)
+%define APIC_REG_LVT_LINT0                      0x0350
+%define APIC_REG_LVT_LINT1                      0x0360
+%define APIC_REG_LVT_ERR                        0x0370
+%define APIC_REG_LVT_PC                         0x0340
+%define APIC_REG_LVT_THMR                       0x0330
+%define   APIC_REG_LVT_MODE_MASK                (RT_BIT(8)|RT_BIT(9)|RT_BIT(10))
+%define   APIC_REG_LVT_MODE_FIXED               0
+%define   APIC_REG_LVT_MODE_NMI                 (RT_BIT(10))
+%define   APIC_REG_LVT_MODE_EXTINT              (RT_BIT(8)|RT_BIT(9)|RT_BIT(10))
+%define   APIC_REG_LVT_PIN_POLARIY              RT_BIT(13)
+%define   APIC_REG_LVT_REMOTE_IRR               RT_BIT(14)
+%define   APIC_REG_LVT_LEVEL_TRIGGER            RT_BIT(15)
+%define   APIC_REG_LVT_MASKED                   RT_BIT(16)
+%endif
Index: /trunk/include/VBox/cpum.h
===================================================================
--- /trunk/include/VBox/cpum.h	(revision 33934)
+++ /trunk/include/VBox/cpum.h	(revision 33935)
@@ -461,4 +461,6 @@
  * @{
  */
+VMMR0DECL(int)          CPUMR0ModuleInit();
+VMMR0DECL(int)          CPUMR0ModuleTerm();
 VMMR0DECL(int)          CPUMR0Init(PVM pVM);
 VMMR0DECL(int)          CPUMR0LoadGuestFPU(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx);
@@ -469,4 +471,7 @@
 VMMR0DECL(int)          CPUMR0SaveHostDebugState(PVM pVM, PVMCPU pVCpu);
 VMMR0DECL(int)          CPUMR0LoadHyperDebugState(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx, bool fDR6);
+#ifdef VBOX_WITH_VMMR0_DISABLE_LAPIC_NMI
+VMMR0DECL(void)         CPUMR0SetLApic(PVM pVM, RTCPUID idHostCpu);
+#endif
 
 /** @} */
Index: /trunk/src/VBox/VMM/CPUMInternal.h
===================================================================
--- /trunk/src/VBox/VMM/CPUMInternal.h	(revision 33934)
+++ /trunk/src/VBox/VMM/CPUMInternal.h	(revision 33935)
@@ -313,10 +313,15 @@
 
 #if HC_ARCH_BITS == 32
-    /** Align the next member, and thereby the structure, on a 64-byte boundary. */
     uint8_t                 abPadding2[4];
 #endif
 
+#ifdef VBOX_WITH_VMMR0_DISABLE_LAPIC_NMI
+    RTHCPTR                 pvApicBase;
+    uint32_t                fApicDisVectors;
+    uint8_t                 abPadding3[HC_ARCH_BITS == 32 ? 56 : 52];
+#endif
+
     /**
-     * Guest context on raw mode entry.
+     * Guest context on raw mode entry. 64-byte aligned!
      * This a debug feature, see CPUMR3SaveEntryCtx.
      */
Index: /trunk/src/VBox/VMM/CPUMInternal.mac
===================================================================
--- /trunk/src/VBox/VMM/CPUMInternal.mac	(revision 33934)
+++ /trunk/src/VBox/VMM/CPUMInternal.mac	(revision 33935)
@@ -81,4 +81,18 @@
     .aGuestCpuIdCentaur   resb    16*4
     .GuestCpuIdDef        resb    16
+
+%if HC_ARCH_BITS == 32
+    .abPadding2           resb    4
+%endif
+
+%ifdef VBOX_WITH_VMMR0_DISABLE_LAPIC_NMI
+ %if HC_ARCH_BITS == 32
+    .pvApicBase           resd    1
+    .fApicDisVectors      resd    1
+ %else
+    .pvApicBase           resq    1
+    .fApicDisVectors      resd    1
+ %endif
+%endif
 
     alignb 64
@@ -450,2 +464,10 @@
     sub     %1, dword [%1 + CPUMCPU.offCPUM]
 %endmacro
+
+;;
+; Converts the CPUMCPU pointer to CPUM
+; @param   %1   register name (PVM)
+; @param   %2   register name (CPUMCPU offset)
+%macro CPUM_FROM_CPUMCPU_WITH_OFFSET 2
+    sub     %1, %2
+%endmacro
Index: /trunk/src/VBox/VMM/Makefile.kmk
===================================================================
--- /trunk/src/VBox/VMM/Makefile.kmk	(revision 33934)
+++ /trunk/src/VBox/VMM/Makefile.kmk	(revision 33935)
@@ -38,4 +38,7 @@
 ifdef VBOX_WITH_R0_LOGGING
  VMM_COMMON_DEFS += VBOX_WITH_R0_LOGGING
+endif
+ifdef VBOX_WITH_VMMR0_DISABLE_LAPIC_NMI
+ VMM_COMMON_DEFS += VBOX_WITH_VMMR0_DISABLE_LAPIC_NMI
 endif
 # VMM_COMMON_DEFS += VBOX_WITH_NS_ACCOUNTING_STATS
Index: /trunk/src/VBox/VMM/VMMR0/CPUMR0.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR0/CPUMR0.cpp	(revision 33934)
+++ /trunk/src/VBox/VMM/VMMR0/CPUMR0.cpp	(revision 33935)
@@ -30,5 +30,51 @@
 #include <iprt/assert.h>
 #include <iprt/asm-amd64-x86.h>
-
+#ifdef VBOX_WITH_VMMR0_DISABLE_LAPIC_NMI
+# include <iprt/mem.h>
+# include <iprt/memobj.h>
+# include <VBox/apic.h>
+#endif
+
+
+#ifdef VBOX_WITH_VMMR0_DISABLE_LAPIC_NMI
+/** Local APIC mappings */
+typedef struct
+{
+    bool        fEnabled;
+    uint64_t    PhysBase;
+    RTR0MEMOBJ  hMemObj;
+    RTR0MEMOBJ  hMapObj;
+    void        *pv;
+    uint32_t    fHasThermal;
+} CPUMHOSTLAPIC;
+
+static CPUMHOSTLAPIC g_aLApics[RTCPUSET_MAX_CPUS];
+static int  cpumR0MapLocalApics(void);
+static void cpumR0UnmapLocalApics(void);
+#endif
+
+
+/**
+ * Does the Ring-0 CPU initialization once during module load.
+ * XXX Host-CPU hot-plugging?
+ */
+VMMR0DECL(int) CPUMR0ModuleInit(void)
+{
+#ifdef VBOX_WITH_VMMR0_DISABLE_LAPIC_NMI
+    return cpumR0MapLocalApics();
+#endif
+}
+
+
+/**
+ * Terminate the module.
+ */
+VMMR0DECL(int) CPUMR0ModuleTerm(void)
+{
+#ifdef VBOX_WITH_VMMR0_DISABLE_LAPIC_NMI
+    cpumR0UnmapLocalApics();
+#endif
+    return VINF_SUCCESS;
+}
 
 
@@ -45,4 +91,10 @@
 {
     LogFlow(("CPUMR0Init: %p\n", pVM));
+
+#ifdef VBOX_WITH_VMMR0_DISABLE_LAPIC_NMI
+    for (unsigned i = 0; i < RT_ELEMENTS(g_aLApics); i++)
+        if (g_aLApics[i].pv)
+            SUPR0Printf(" CPU%d: %llx => %llx\n", i, g_aLApics[i].PhysBase, (uint64_t)g_aLApics[i].pv);
+#endif
 
     /*
@@ -590,2 +642,126 @@
 }
 
+
+#ifdef VBOX_WITH_VMMR0_DISABLE_LAPIC_NMI
+/**
+ * Worker for cpumR0MapLocalApics. Check each CPU for a present Local APIC.
+ * Play safe and treat each CPU separate.
+ */
+static void cpumR0MapLocalApicWorker(RTCPUID idCpu, void *pvUser1, void *pvUser2)
+{
+    uint32_t u32MaxIdx;
+    uint32_t u32EBX, u32ECX, u32EDX;
+    int iCpu = RTMpCpuIdToSetIndex(idCpu);
+    Assert(iCpu < RTCPUSET_MAX_CPUS);
+    ASMCpuId(0, &u32MaxIdx, &u32EBX, &u32ECX, &u32EDX);
+    if (   (   (   u32EBX == X86_CPUID_VENDOR_INTEL_EBX
+                && u32ECX == X86_CPUID_VENDOR_INTEL_ECX
+                && u32EDX == X86_CPUID_VENDOR_INTEL_EDX)
+           ||  (   u32EBX == X86_CPUID_VENDOR_AMD_EBX
+                && u32ECX == X86_CPUID_VENDOR_AMD_ECX
+                && u32EDX == X86_CPUID_VENDOR_AMD_EDX))
+        && u32MaxIdx >= 1)
+    {
+        ASMCpuId(1, &u32MaxIdx, &u32EBX, &u32ECX, &u32EDX);
+        if (    (u32EDX & X86_CPUID_FEATURE_EDX_APIC)
+            &&  (u32EDX & X86_CPUID_FEATURE_EDX_MSR))
+        {
+            uint64_t u64ApicBase = ASMRdMsr(MSR_IA32_APICBASE);
+            uint32_t u32MaxExtIdx;
+            /* see Intel Manual: Local APIC Status and Location: MAXPHYADDR default is bit 36 */
+            uint64_t u64Mask = UINT64_C(0x0000000ffffff000);
+            ASMCpuId(0x80000000, &u32MaxExtIdx, &u32EBX, &u32ECX, &u32EDX);
+            if (   u32MaxExtIdx >= 0x80000008
+                && u32MaxExtIdx <  0x8000ffff)
+            {
+                uint32_t u32PhysBits;
+                ASMCpuId(0x80000008, &u32PhysBits, &u32EBX, &u32ECX, &u32EDX);
+                u32PhysBits &= 0xff;
+                u64Mask = ((UINT64_C(1) << u32PhysBits) - 1) & UINT64_C(0xfffffffffffff000);
+            }
+            g_aLApics[iCpu].fEnabled = true;
+            g_aLApics[iCpu].PhysBase = u64ApicBase & u64Mask;
+        }
+    }
+}
+
+
+/**
+ * Map the MMIO page of each local APIC in the system.
+ */
+static int cpumR0MapLocalApics(void)
+{
+    int rc = RTMpOnAll(cpumR0MapLocalApicWorker, NULL, NULL);
+    for (unsigned iCpu = 0; RT_SUCCESS(rc) && iCpu < RT_ELEMENTS(g_aLApics); iCpu++)
+    {
+        if (g_aLApics[iCpu].fEnabled)
+        {
+            rc = RTR0MemObjEnterPhys(&g_aLApics[iCpu].hMemObj, g_aLApics[iCpu].PhysBase,
+                                     PAGE_SIZE, RTMEM_CACHE_POLICY_MMIO);
+            if (RT_SUCCESS(rc))
+                rc = RTR0MemObjMapKernel(&g_aLApics[iCpu].hMapObj, g_aLApics[iCpu].hMemObj, (void*)-1,
+                                         PAGE_SIZE, RTMEM_PROT_READ | RTMEM_PROT_WRITE);
+            if (RT_SUCCESS(rc))
+            {
+                void *pApicBase = RTR0MemObjAddress(g_aLApics[iCpu].hMapObj);
+                uint32_t ApicVersion = ApicRegRead(pApicBase, APIC_REG_VERSION);
+                /*
+                 * 0x0X       82489 external APIC
+                 * 0x1X       Local APIC
+                 * 0x2X..0xFF reserved
+                 */
+                if ((APIC_REG_VERSION_GET_VER(ApicVersion) & 0xF0) != 0x10)
+                {
+                    RTR0MemObjFree(g_aLApics[iCpu].hMapObj, true /* fFreeMappings */);
+                    RTR0MemObjFree(g_aLApics[iCpu].hMemObj, true /* fFreeMappings */);
+                    g_aLApics[iCpu].fEnabled = false;
+                    continue;
+                }
+                g_aLApics[iCpu].fHasThermal = APIC_REG_VERSION_GET_MAX_LVT(ApicVersion) >= 5;
+                g_aLApics[iCpu].pv = pApicBase;
+            }
+        }
+    }
+    if (RT_FAILURE(rc))
+    {
+        cpumR0UnmapLocalApics();
+        return rc;
+    }
+
+    return VINF_SUCCESS;
+}
+
+
+/**
+ * Unmap the Local APIC of all host CPUs.
+ */
+static void cpumR0UnmapLocalApics(void)
+{
+    for (unsigned iCpu = RT_ELEMENTS(g_aLApics); iCpu-- > 0;)
+    {
+        if (g_aLApics[iCpu].pv)
+        {
+            RTR0MemObjFree(g_aLApics[iCpu].hMapObj, true /* fFreeMappings */);
+            RTR0MemObjFree(g_aLApics[iCpu].hMemObj, true /* fFreeMappings */);
+            g_aLApics[iCpu].fEnabled = false;
+            g_aLApics[iCpu].pv = NULL;
+        }
+    }
+}
+
+
+/**
+ * Write the Local APIC mapping address of the current host CPU to CPUM to be
+ * able to access the APIC registers in the raw mode switcher for disabling/
+ * re-enabling the NMI. Must be called with disabled preemption or disabled
+ * interrupts!
+ *
+ * @param   pVM         VM handle.
+ * @param   idHostCpu   The ID of the current host CPU.
+ */
+VMMR0DECL(void) CPUMR0SetLApic(PVM pVM, RTCPUID idHostCpu)
+{
+    pVM->cpum.s.pvApicBase = g_aLApics[RTMpCpuIdToSetIndex(idHostCpu)].pv;
+}
+
+#endif /* VBOX_WITH_VMMR0_DISABLE_LAPIC_NMI */
Index: /trunk/src/VBox/VMM/VMMR0/VMMR0.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR0/VMMR0.cpp	(revision 33934)
+++ /trunk/src/VBox/VMM/VMMR0/VMMR0.cpp	(revision 33935)
@@ -117,6 +117,10 @@
                         if (RT_SUCCESS(rc))
                         {
-                            LogFlow(("ModuleInit: returns success.\n"));
-                            return VINF_SUCCESS;
+                            rc = CPUMR0ModuleInit();
+                            if (RT_SUCCESS(rc))
+                            {
+                                LogFlow(("ModuleInit: returns success.\n"));
+                                return VINF_SUCCESS;
+                            }
                         }
 
@@ -148,4 +152,9 @@
 {
     LogFlow(("ModuleTerm:\n"));
+
+    /*
+     * Terminate the CPUM module (Local APIC cleanup).
+     */
+    CPUMR0ModuleTerm();
 
     /*
@@ -574,5 +583,9 @@
                 RTTHREADPREEMPTSTATE PreemptState = RTTHREADPREEMPTSTATE_INITIALIZER;
                 RTThreadPreemptDisable(&PreemptState);
-                ASMAtomicWriteU32(&pVCpu->idHostCpu, RTMpCpuId());
+                RTCPUID idHostCpu = RTMpCpuId();
+#ifdef VBOX_WITH_VMMR0_DISABLE_LAPIC_NMI
+                CPUMR0SetLApic(pVM, idHostCpu);
+#endif
+                ASMAtomicWriteU32(&pVCpu->idHostCpu, idHostCpu);
                 if (pVM->vmm.s.fUsePeriodicPreemptionTimers)
                     GVMMR0SchedUpdatePeriodicPreemptionTimer(pVM, pVCpu->idHostCpu, TMCalcHostTimerFrequency(pVM, pVCpu));
@@ -887,4 +900,9 @@
             RTCCUINTREG fFlags = ASMIntDisableFlags();
 
+#ifdef VBOX_WITH_VMMR0_DISABLE_LAPIC_NMI
+            RTCPUID idHostCpu = RTMpCpuId();
+            CPUMR0SetLApic(pVM, idHostCpu);
+#endif
+
             /* We might need to disable VT-x if the active switcher turns off paging. */
             rc = HWACCMR0EnterSwitcher(pVM, &fVTxDisabled);
Index: /trunk/src/VBox/VMM/VMMSwitcher/AMD64andLegacy.mac
===================================================================
--- /trunk/src/VBox/VMM/VMMSwitcher/AMD64andLegacy.mac	(revision 33934)
+++ /trunk/src/VBox/VMM/VMMSwitcher/AMD64andLegacy.mac	(revision 33935)
@@ -23,4 +23,5 @@
 ;*******************************************************************************
 %include "VBox/asmdefs.mac"
+%include "VBox/apic.mac"
 %include "VBox/x86.mac"
 %include "VBox/cpum.mac"
@@ -250,4 +251,58 @@
     pop     qword [rdx + r8 + CPUMCPU.Host.rflags]
 
+%ifdef VBOX_WITH_VMMR0_DISABLE_LAPIC_NMI
+    ; Block Local APIC NMI vectors
+    mov     rbx, [rdx + CPUM.pvApicBase]
+    or      rbx, rbx
+    jz      htg_noapic
+    xor     edi, edi
+    mov     eax, [rbx + APIC_REG_LVT_LINT0]
+    mov     ecx, eax
+    and     ecx, (APIC_REG_LVT_MASKED | APIC_REG_LVT_MODE_MASK)
+    cmp     ecx, APIC_REG_LVT_MODE_NMI
+    jne     htg_nolint0
+    or      edi, 0x01
+    or      eax, APIC_REG_LVT_MASKED
+    mov     [rbx + APIC_REG_LVT_LINT0], eax
+    mov     eax, [rbx + APIC_REG_LVT_LINT0] ; write completion
+htg_nolint0:
+    mov     eax, [rbx + APIC_REG_LVT_LINT1]
+    mov     ecx, eax
+    and     ecx, (APIC_REG_LVT_MASKED | APIC_REG_LVT_MODE_MASK)
+    cmp     ecx, APIC_REG_LVT_MODE_NMI
+    jne     htg_nolint1
+    or      edi, 0x02
+    or      eax, APIC_REG_LVT_MASKED
+    mov     [rbx + APIC_REG_LVT_LINT1], eax
+    mov     eax, [rbx + APIC_REG_LVT_LINT1] ; write completion
+htg_nolint1:
+    mov     eax, [rbx + APIC_REG_LVT_PC]
+    mov     ecx, eax
+    and     ecx, (APIC_REG_LVT_MASKED | APIC_REG_LVT_MODE_MASK)
+    cmp     ecx, APIC_REG_LVT_MODE_NMI
+    jne     htg_nopc
+    or      edi, 0x04
+    or      eax, APIC_REG_LVT_MASKED
+    mov     [rbx + APIC_REG_LVT_PC], eax
+    mov     eax, [rbx + APIC_REG_LVT_PC] ; write completion
+htg_nopc:
+    mov     eax, [rbx + APIC_REG_VERSION]
+    shr     eax, 16
+    cmp     al, 5
+    jb      htg_notherm
+    mov     eax, [rbx + APIC_REG_LVT_THMR]
+    mov     ecx, eax
+    and     ecx, (APIC_REG_LVT_MASKED | APIC_REG_LVT_MODE_MASK)
+    cmp     ecx, APIC_REG_LVT_MODE_NMI
+    jne     htg_notherm
+    or      edi, 0x08
+    or      eax, APIC_REG_LVT_MASKED
+    mov     [rbx + APIC_REG_LVT_THMR], eax
+    mov     eax, [rbx + APIC_REG_LVT_THMR] ; write completion
+htg_notherm:
+    mov     [rdx + CPUM.fApicDisVectors], edi
+htg_noapic:
+%endif
+
     FIXUP FIX_NO_SYSENTER_JMP, 0, htg_no_sysenter - NAME(Start) ; this will insert a jmp htg_no_sysenter if host doesn't use sysenter.
     ; save MSR_IA32_SYSENTER_CS register.
@@ -1049,4 +1104,25 @@
     mov     rdx, rbx
 
+%ifdef VBOX_WITH_VMMR0_DISABLE_LAPIC_NMI
+    ;Unblock Local APIC NMI vectors
+    mov     ecx, [rdx + CPUM.fApicDisVectors]
+    mov     rbx, [rdx + CPUM.pvApicBase]
+    shr     ecx, 1
+    jnc     gth_nolint0
+    and     dword [rbx + APIC_REG_LVT_LINT0], ~APIC_REG_LVT_MASKED
+gth_nolint0:
+    shr     ecx, 1
+    jnc     gth_nolint1
+    and     dword [rbx + APIC_REG_LVT_LINT1], ~APIC_REG_LVT_MASKED
+gth_nolint1:
+    shr     ecx, 1
+    jnc     gth_nopc
+    and     dword [rbx + APIC_REG_LVT_PC], ~APIC_REG_LVT_MASKED
+gth_nopc:
+    shr     ecx, 1
+    jnc     gth_notherm
+    and     dword [rbx + APIC_REG_LVT_THMR], ~APIC_REG_LVT_MASKED
+gth_notherm:
+%endif
 
     ; restore general registers.
Index: /trunk/src/VBox/VMM/VMMSwitcher/LegacyandAMD64.mac
===================================================================
--- /trunk/src/VBox/VMM/VMMSwitcher/LegacyandAMD64.mac	(revision 33934)
+++ /trunk/src/VBox/VMM/VMMSwitcher/LegacyandAMD64.mac	(revision 33935)
@@ -26,4 +26,5 @@
 ;*******************************************************************************
 %include "VBox/asmdefs.mac"
+%include "VBox/apic.mac"
 %include "VBox/x86.mac"
 %include "VBox/cpum.mac"
@@ -155,4 +156,58 @@
 %endif
 
+%ifdef VBOX_WITH_VMMR0_DISABLE_LAPIC_NMI
+    CPUM_FROM_CPUMCPU_WITH_OFFSET edx, ebp
+    mov     ebx, [edx + CPUM.pvApicBase]
+    or      ebx, ebx
+    jz      htg_noapic
+    mov     eax, [ebx + APIC_REG_LVT_LINT0]
+    mov     ecx, eax
+    and     ecx, (APIC_REG_LVT_MASKED | APIC_REG_LVT_MODE_MASK)
+    cmp     ecx, APIC_REG_LVT_MODE_NMI
+    jne     htg_nolint0
+    or      edi, 0x01
+    or      eax, APIC_REG_LVT_MASKED
+    mov     [ebx + APIC_REG_LVT_LINT0], eax
+    mov     eax, [ebx + APIC_REG_LVT_LINT0] ; write completion
+htg_nolint0:
+    mov     eax, [ebx + APIC_REG_LVT_LINT1]
+    mov     ecx, eax
+    and     ecx, (APIC_REG_LVT_MASKED | APIC_REG_LVT_MODE_MASK)
+    cmp     ecx, APIC_REG_LVT_MODE_NMI
+    jne     htg_nolint1
+    or      edi, 0x02
+    or      eax, APIC_REG_LVT_MASKED
+    mov     [ebx + APIC_REG_LVT_LINT1], eax
+    mov     eax, [ebx + APIC_REG_LVT_LINT1] ; write completion
+htg_nolint1:
+    mov     eax, [ebx + APIC_REG_LVT_PC]
+    mov     ecx, eax
+    and     ecx, (APIC_REG_LVT_MASKED | APIC_REG_LVT_MODE_MASK)
+    cmp     ecx, APIC_REG_LVT_MODE_NMI
+    jne     htg_nopc
+    or      edi, 0x04
+    or      eax, APIC_REG_LVT_MASKED
+    mov     [ebx + APIC_REG_LVT_PC], eax
+    mov     eax, [ebx + APIC_REG_LVT_PC] ; write completion
+htg_nopc:
+    mov     eax, [ebx + APIC_REG_VERSION]
+    shr     eax, 16
+    cmp     al, 5
+    jb      htg_notherm
+    mov     eax, [ebx + APIC_REG_LVT_THMR]
+    mov     ecx, eax
+    and     ecx, (APIC_REG_LVT_MASKED | APIC_REG_LVT_MODE_MASK)
+    cmp     ecx, APIC_REG_LVT_MODE_NMI
+    jne     htg_notherm
+    or      edi, 0x08
+    or      eax, APIC_REG_LVT_MASKED
+    mov     [ebx + APIC_REG_LVT_THMR], eax
+    mov     eax, [ebx + APIC_REG_LVT_THMR] ; write completion
+htg_notherm:
+    mov     [edx + CPUM.fApicDisVectors], edi
+htg_noapic:
+    CPUMCPU_FROM_CPUM_WITH_OFFSET edx, ebp
+%endif
+
     ; control registers.
     mov     eax, cr0
@@ -287,5 +342,5 @@
     ; Load CPUM pointer into rdx
     mov     rdx, [NAME(pCpumIC) wrt rip]
-    CPUMCPU_FROM_CPUM_WITH_OFFSET    edx, ebp
+    CPUMCPU_FROM_CPUM_WITH_OFFSET edx, ebp
 
     mov     rax, cs
@@ -369,5 +424,5 @@
     ; Load CPUM pointer into rdx
     mov     rdx, [NAME(pCpumIC) wrt rip]
-    CPUMCPU_FROM_CPUM_WITH_OFFSET    edx, ebp
+    CPUMCPU_FROM_CPUM_WITH_OFFSET edx, ebp
 
 %ifdef VBOX_WITH_CRASHDUMP_MAGIC
@@ -516,5 +571,5 @@
     FIXUP FIX_GC_CPUM_OFF, 1, 0
     mov     edx, 0ffffffffh
-    CPUMCPU_FROM_CPUM_WITH_OFFSET    edx, ebp
+    CPUMCPU_FROM_CPUM_WITH_OFFSET edx, ebp
     mov     esi, [edx + CPUMCPU.Host.cr3]
     mov     cr3, esi
@@ -523,5 +578,5 @@
     FIXUP FIX_HC_CPUM_OFF, 1, 0
     mov     edx, 0ffffffffh
-    CPUMCPU_FROM_CPUM_WITH_OFFSET    edx, ebp
+    CPUMCPU_FROM_CPUM_WITH_OFFSET edx, ebp
 
     ; restore the host EFER
@@ -570,4 +625,28 @@
     ;mov     ecx, [edx + CPUMCPU.Host.cr2] ; assumes this is waste of time.
     ;mov     cr2, ecx
+
+%ifdef VBOX_WITH_VMMR0_DISABLE_LAPIC_NMI
+    ; Restore blocked Local APIC NMI vectors
+    CPUM_FROM_CPUMCPU_WITH_OFFSET edx, ebp
+    mov     ebx, [edx + CPUM.pvApicBase]
+    mov     ecx, [edx + CPUM.fApicDisVectors]
+    CPUMCPU_FROM_CPUM_WITH_OFFSET edx, ebp
+    shr     ecx, 1
+    jnc     gth_nolint0
+    and     dword [ebx + APIC_REG_LVT_LINT0], ~APIC_REG_LVT_MASKED
+gth_nolint0:
+    shr     ecx, 1
+    jnc     gth_nolint1
+    and     dword [ebx + APIC_REG_LVT_LINT1], ~APIC_REG_LVT_MASKED
+gth_nolint1:
+    shr     ecx, 1
+    jnc     gth_nopc
+    and     dword [ebx + APIC_REG_LVT_PC], ~APIC_REG_LVT_MASKED
+gth_nopc:
+    shr     ecx, 1
+    jnc     gth_notherm
+    and     dword [ebx + APIC_REG_LVT_THMR], ~APIC_REG_LVT_MASKED
+gth_notherm:
+%endif
 
     ; restore general registers.
Index: /trunk/src/VBox/VMM/VMMSwitcher/PAEand32Bit.mac
===================================================================
--- /trunk/src/VBox/VMM/VMMSwitcher/PAEand32Bit.mac	(revision 33934)
+++ /trunk/src/VBox/VMM/VMMSwitcher/PAEand32Bit.mac	(revision 33935)
@@ -22,4 +22,5 @@
 ;*******************************************************************************
 %include "VBox/asmdefs.mac"
+%include "VBox/apic.mac"
 %include "VBox/x86.mac"
 %include "VBox/cpum.mac"
@@ -136,4 +137,62 @@
     pushfd
     pop     dword [edx + CPUMCPU.Host.eflags]
+
+    ; Block Local APIC NMI vectors
+    xor     edi, edi
+
+%ifdef VBOX_WITH_VMMR0_DISABLE_LAPIC_NMI
+    mov     esi, edx
+    CPUM_FROM_CPUMCPU(edx)
+    mov     ebx, [edx + CPUM.pvApicBase]
+    or      ebx, ebx
+    jz      htg_noapic
+    mov     eax, [ebx + APIC_REG_LVT_LINT0]
+    mov     ecx, eax
+    and     ecx, (APIC_REG_LVT_MASKED | APIC_REG_LVT_MODE_MASK)
+    cmp     ecx, APIC_REG_LVT_MODE_NMI
+    jne     htg_nolint0
+    or      edi, 0x01
+    or      eax, APIC_REG_LVT_MASKED
+    mov     [ebx + APIC_REG_LVT_LINT0], eax
+    mov     eax, [ebx + APIC_REG_LVT_LINT0] ; write completion
+htg_nolint0:
+    mov     eax, [ebx + APIC_REG_LVT_LINT1]
+    mov     ecx, eax
+    and     ecx, (APIC_REG_LVT_MASKED | APIC_REG_LVT_MODE_MASK)
+    cmp     ecx, APIC_REG_LVT_MODE_NMI
+    jne     htg_nolint1
+    or      edi, 0x02
+    or      eax, APIC_REG_LVT_MASKED
+    mov     [ebx + APIC_REG_LVT_LINT1], eax
+    mov     eax, [ebx + APIC_REG_LVT_LINT1] ; write completion
+htg_nolint1:
+    mov     eax, [ebx + APIC_REG_LVT_PC]
+    mov     ecx, eax
+    and     ecx, (APIC_REG_LVT_MASKED | APIC_REG_LVT_MODE_MASK)
+    cmp     ecx, APIC_REG_LVT_MODE_NMI
+    jne     htg_nopc
+    or      edi, 0x04
+    or      eax, APIC_REG_LVT_MASKED
+    mov     [ebx + APIC_REG_LVT_PC], eax
+    mov     eax, [ebx + APIC_REG_LVT_PC] ; write completion
+htg_nopc:
+    mov     eax, [ebx + APIC_REG_VERSION]
+    shr     eax, 16
+    cmp     al, 5
+    jb      htg_notherm
+    mov     eax, [ebx + APIC_REG_LVT_THMR]
+    mov     ecx, eax
+    and     ecx, (APIC_REG_LVT_MASKED | APIC_REG_LVT_MODE_MASK)
+    cmp     ecx, APIC_REG_LVT_MODE_NMI
+    jne     htg_notherm
+    or      edi, 0x08
+    or      eax, APIC_REG_LVT_MASKED
+    mov     [ebx + APIC_REG_LVT_THMR], eax
+    mov     eax, [ebx + APIC_REG_LVT_THMR] ; write completion
+htg_notherm:
+    mov     [edx + CPUM.fApicDisVectors], edi
+htg_noapic:
+    mov     edx, esi
+%endif
 
     FIXUP FIX_NO_SYSENTER_JMP, 0, htg_no_sysenter - NAME(Start) ; this will insert a jmp htg_no_sysenter if host doesn't use sysenter.
@@ -935,4 +994,29 @@
 gth_debug_regs_no:
 
+%ifdef VBOX_WITH_VMMR0_DISABLE_LAPIC_NMI
+    mov     esi, edx
+    CPUM_FROM_CPUMCPU(edx)
+    ; Restore blocked Local APIC NMI vectors
+    mov     ebx, [edx + CPUM.pvApicBase]
+    mov     ecx, [edx + CPUM.fApicDisVectors]
+    mov     edx, esi
+    shr     ecx, 1
+    jnc     gth_nolint0
+    and     dword [ebx + APIC_REG_LVT_LINT0], ~APIC_REG_LVT_MASKED
+gth_nolint0:
+    shr     ecx, 1
+    jnc     gth_nolint1
+    and     dword [ebx + APIC_REG_LVT_LINT1], ~APIC_REG_LVT_MASKED
+gth_nolint1:
+    shr     ecx, 1
+    jnc     gth_nopc
+    and     dword [ebx + APIC_REG_LVT_PC], ~APIC_REG_LVT_MASKED
+gth_nopc:
+    shr     ecx, 1
+    jnc     gth_notherm
+    and     dword [ebx + APIC_REG_LVT_THMR], ~APIC_REG_LVT_MASKED
+gth_notherm:
+%endif
+
     ; restore general registers.
     mov     eax, edi                    ; restore return code. eax = return code !!
Index: /trunk/src/VBox/VMM/testcase/Makefile.kmk
===================================================================
--- /trunk/src/VBox/VMM/testcase/Makefile.kmk	(revision 33934)
+++ /trunk/src/VBox/VMM/testcase/Makefile.kmk	(revision 33935)
@@ -107,4 +107,7 @@
   tstVMStructRC_DEFS    += VBOX_WITH_R0_LOGGING
  endif
+ ifdef VBOX_WITH_VMMR0_DISABLE_LAPIC_NMI
+  tstVMStructRC_DEFS    += VBOX_WITH_VMMR0_DISABLE_LAPIC_NMI
+ endif
  tstVMStructRC_SOURCES   = tstVMStructRC.cpp
  tstVMStructRC_INCS      = $(VBOX_PATH_VMM_SRC) $(VBOX_PATH_VMM_SRC)/PATM
@@ -129,4 +132,7 @@
  tstVMStructSize_DEFS  += VBOX_WITH_R0_LOGGING
 endif
+ifdef VBOX_WITH_VMMR0_DISABLE_LAPIC_NMI
+ tstVMStructSize_DEFS  += VBOX_WITH_VMMR0_DISABLE_LAPIC_NMI
+endif
 
 tstAsmStructs_TEMPLATE  = VBOXR3AUTOTST
@@ -137,4 +143,7 @@
 ifdef VBOX_WITH_R0_LOGGING
  tstAsmStructs_DEFS    += VBOX_WITH_R0_LOGGING
+endif
+ifdef VBOX_WITH_VMMR0_DISABLE_LAPIC_NMI
+ tstAsmStructs_DEFS    += VBOX_WITH_VMMR0_DISABLE_LAPIC_NMI
 endif
 tstAsmStructs_INCS      = $(VBOX_PATH_VMM_SRC) $(VBOX_VMM_TESTCASE_OUT_DIR)
@@ -147,4 +156,7 @@
  ifdef VBOX_WITH_R0_LOGGING
   tstAsmStructsRC_DEFS  += VBOX_WITH_R0_LOGGING
+ endif
+ ifdef VBOX_WITH_VMMR0_DISABLE_LAPIC_NMI
+  tstAsmStructsRC_DEFS  += VBOX_WITH_VMMR0_DISABLE_LAPIC_NMI
  endif
  tstAsmStructsRC_INCS    = $(VBOX_PATH_VMM_SRC) $(VBOX_VMM_TESTCASE_OUT_DIR)
@@ -286,4 +298,5 @@
 			$(DEFS.$(KBUILD_TARGET_ARCH)) \
 			$(DEFS.$(KBUILD_TARGET).$(KBUILD_TARGET_ARCH)) \
+			$(if $(VBOX_WITH_VMMR0_DISABLE_LAPIC_NMI),VBOX_WITH_VMMR0_DISABLE_LAPIC_NMI,) \
 		) \
 		-f $(if $(eq $(KBUILD_TARGET),darwin),macho,elf) \
Index: /trunk/src/VBox/VMM/testcase/tstVMStructSize.cpp
===================================================================
--- /trunk/src/VBox/VMM/testcase/tstVMStructSize.cpp	(revision 33934)
+++ /trunk/src/VBox/VMM/testcase/tstVMStructSize.cpp	(revision 33935)
@@ -260,4 +260,7 @@
     CHECK_MEMBER_ALIGNMENT(VM, aCpus[0].cpum.s.Hyper, 64);
     CHECK_MEMBER_ALIGNMENT(VM, aCpus[1].cpum.s.Hyper, 64);
+#ifdef VBOX_WITH_VMMR0_DISABLE_LAPIC_NMI
+    CHECK_MEMBER_ALIGNMENT(VM, cpum.s.pvApicBase, 8);
+#endif
     CHECK_MEMBER_ALIGNMENT(VM, cpum.s.GuestEntry, 64);
 
