Index: /trunk/include/VBox/vmm/cpum.h
===================================================================
--- /trunk/include/VBox/vmm/cpum.h	(revision 92514)
+++ /trunk/include/VBox/vmm/cpum.h	(revision 92515)
@@ -2705,4 +2705,5 @@
 VMMR3DECL(int)              CPUMR3CpuIdInsert(PVM pVM, PCPUMCPUIDLEAF pNewLeaf);
 VMMR3DECL(int)              CPUMR3CpuIdGetLeaf(PVM pVM, PCPUMCPUIDLEAF pLeaf, uint32_t uLeaf, uint32_t uSubLeaf);
+VMMR3_INT_DECL(PCCPUMCPUIDLEAF) CPUMR3CpuIdGetPtr(PVM pVM, uint32_t *pcLeaves);
 VMMR3DECL(CPUMMICROARCH)    CPUMR3CpuIdDetermineMicroarchEx(CPUMCPUVENDOR enmVendor, uint8_t bFamily,
                                                             uint8_t bModel, uint8_t bStepping);
Index: /trunk/src/VBox/VMM/VMMR3/CPUMR3CpuId.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR3/CPUMR3CpuId.cpp	(revision 92514)
+++ /trunk/src/VBox/VMM/VMMR3/CPUMR3CpuId.cpp	(revision 92515)
@@ -1238,4 +1238,21 @@
 
 /**
+ * Gets all the leaves.
+ *
+ * This only works after the CPUID leaves have been initialized.  The interface
+ * is intended for NEM and configuring CPUID leaves for the native hypervisor.
+ *
+ * @returns Pointer to the array of leaves.  NULL on failure.
+ * @param   pVM         The cross context VM structure.
+ * @param   pcLeaves    Where to return the number of leaves.
+ */
+VMMR3_INT_DECL(PCCPUMCPUIDLEAF) CPUMR3CpuIdGetPtr(PVM pVM, uint32_t *pcLeaves)
+{
+    *pcLeaves = pVM->cpum.s.GuestInfo.cCpuIdLeaves;
+    return pVM->cpum.s.GuestInfo.paCpuIdLeavesR3;
+}
+
+
+/**
  * Inserts a CPU ID leaf, replacing any existing ones.
  *
@@ -1269,4 +1286,5 @@
     return cpumR3CpuIdInsert(pVM, NULL /* ppaLeaves */, NULL /* pcLeaves */, pNewLeaf);
 }
+
 
 /**
Index: /trunk/src/VBox/VMM/VMMR3/NEMR3Native-linux.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR3/NEMR3Native-linux.cpp	(revision 92514)
+++ /trunk/src/VBox/VMM/VMMR3/NEMR3Native-linux.cpp	(revision 92515)
@@ -30,4 +30,5 @@
 #include <VBox/vmm/vmcc.h>
 
+#include <iprt/alloca.h>
 #include <iprt/string.h>
 #include <iprt/system.h>
@@ -603,7 +604,55 @@
 
 
+/**
+ * Update the CPUID leaves for a VCPU.
+ *
+ * The KVM_SET_CPUID2 call replaces any previous leaves, so we have to redo
+ * everything when there really just are single bit changes.
+ */
+static int nemR3LnxUpdateCpuIdsLeaves(PVM pVM, PVMCPU pVCpu)
+{
+    uint32_t              cLeaves  = 0;
+    PCCPUMCPUIDLEAF const paLeaves = CPUMR3CpuIdGetPtr(pVM, &cLeaves);
+    struct kvm_cpuid2    *pReq = (struct kvm_cpuid2 *)alloca(RT_UOFFSETOF_DYN(struct kvm_cpuid2, entries[cLeaves + 2]));
+
+    pReq->nent    = cLeaves;
+    pReq->padding = 0;
+
+    for (uint32_t i = 0; i < cLeaves; i++)
+    {
+        CPUMGetGuestCpuId(pVCpu, paLeaves[i].uLeaf, paLeaves[i].uSubLeaf,
+                          &pReq->entries[i].eax,
+                          &pReq->entries[i].ebx,
+                          &pReq->entries[i].ecx,
+                          &pReq->entries[i].edx);
+        pReq->entries[i].function   = paLeaves[i].uLeaf;
+        pReq->entries[i].index      = paLeaves[i].uSubLeaf;
+        pReq->entries[i].flags      = !paLeaves[i].fSubLeafMask ? 0 : KVM_CPUID_FLAG_SIGNIFCANT_INDEX;
+        pReq->entries[i].padding[0] = 0;
+        pReq->entries[i].padding[1] = 0;
+        pReq->entries[i].padding[2] = 0;
+    }
+
+    int rcLnx = ioctl(pVCpu->nem.s.fdVCpu, KVM_SET_CPUID2, pReq);
+    AssertLogRelMsgReturn(rcLnx == 0, ("rcLnx=%d errno=%d cLeaves=%#x\n", rcLnx, errno, cLeaves), RTErrConvertFromErrno(errno));
+
+    return VINF_SUCCESS;
+}
+
+
 int nemR3NativeInitCompleted(PVM pVM, VMINITCOMPLETED enmWhat)
 {
-    RT_NOREF(pVM, enmWhat);
+    /*
+     * Configure CPUIDs after ring-3 init has been done.
+     */
+    if (enmWhat == VMINITCOMPLETED_RING3)
+    {
+        for (VMCPUID idCpu = 0; idCpu < pVM->cCpus; idCpu++)
+        {
+            int rc = nemR3LnxUpdateCpuIdsLeaves(pVM, pVM->apCpusR3[idCpu]);
+            AssertRCReturn(rc, rc);
+        }
+    }
+
     return VINF_SUCCESS;
 }
@@ -1221,19 +1270,9 @@
         if (fWhat & (CPUMCTX_EXTRN_X87 | CPUMCTX_EXTRN_SSE_AVX | CPUMCTX_EXTRN_OTHER_XSAVE))
         {
-            /* Partial state is annoying as we have to do merging - is this possible at all? */
-            struct kvm_xsave XSave;
-            int rc = ioctl(pVCpu->nem.s.fdVCpu, KVM_GET_XSAVE, &XSave);
+            fWhat |= CPUMCTX_EXTRN_X87 | CPUMCTX_EXTRN_SSE_AVX | CPUMCTX_EXTRN_OTHER_XSAVE; /* we do all or nothing at all */
+
+            AssertCompile(sizeof(pCtx->XState) >= sizeof(struct kvm_xsave));
+            int rc = ioctl(pVCpu->nem.s.fdVCpu, KVM_GET_XSAVE, &pCtx->XState);
             AssertMsgReturn(rc == 0, ("rc=%d errno=%d\n", rc, errno), VERR_NEM_IPE_3);
-
-            if (fWhat & CPUMCTX_EXTRN_X87)
-                memcpy(&pCtx->XState.x87, &XSave, sizeof(pCtx->XState.x87));
-            if (fWhat & CPUMCTX_EXTRN_SSE_AVX)
-            {
-                /** @todo    */
-            }
-            if (fWhat & CPUMCTX_EXTRN_OTHER_XSAVE)
-            {
-                /** @todo   */
-            }
         }
 
@@ -1612,24 +1651,9 @@
         if (fExtrn & (CPUMCTX_EXTRN_X87 | CPUMCTX_EXTRN_SSE_AVX | CPUMCTX_EXTRN_OTHER_XSAVE))
         {
-            if (   (fExtrn & (CPUMCTX_EXTRN_X87 | CPUMCTX_EXTRN_SSE_AVX | CPUMCTX_EXTRN_OTHER_XSAVE))
-                !=           (CPUMCTX_EXTRN_X87 | CPUMCTX_EXTRN_SSE_AVX | CPUMCTX_EXTRN_OTHER_XSAVE))
-            {
-                /* Partial state is annoying as we have to do merging - is this possible at all? */
-                struct kvm_xsave XSave;
-                int rc = ioctl(pVCpu->nem.s.fdVCpu, KVM_GET_XSAVE, &XSave);
-                AssertMsgReturn(rc == 0, ("rc=%d errno=%d\n", rc, errno), VERR_NEM_IPE_3);
-
-                if (fExtrn & CPUMCTX_EXTRN_X87)
-                    memcpy(&pCtx->XState.x87, &XSave, sizeof(pCtx->XState.x87));
-                if (fExtrn & CPUMCTX_EXTRN_SSE_AVX)
-                {
-                    /** @todo    */
-                }
-                if (fExtrn & CPUMCTX_EXTRN_OTHER_XSAVE)
-                {
-                    /** @todo   */
-                }
-            }
-
+            /** @todo could IEM just grab state partial control in some situations? */
+            Assert(   (fExtrn & (CPUMCTX_EXTRN_X87 | CPUMCTX_EXTRN_SSE_AVX | CPUMCTX_EXTRN_OTHER_XSAVE))
+                   ==           (CPUMCTX_EXTRN_X87 | CPUMCTX_EXTRN_SSE_AVX | CPUMCTX_EXTRN_OTHER_XSAVE)); /* no partial states */
+
+            AssertCompile(sizeof(pCtx->XState) >= sizeof(struct kvm_xsave));
             int rc = ioctl(pVCpu->nem.s.fdVCpu, KVM_SET_XSAVE, &pCtx->XState);
             AssertMsgReturn(rc == 0, ("rc=%d errno=%d\n", rc, errno), VERR_NEM_IPE_3);
@@ -2129,4 +2153,6 @@
 
         case KVM_EXIT_IRQ_WINDOW_OPEN:
+            EMHistoryAddExit(pVCpu, EMEXIT_MAKE_FT(EMEXIT_F_KIND_NEM, KVM_EXIT_IRQ_WINDOW_OPEN),
+                             pRun->s.regs.regs.rip + pRun->s.regs.sregs.cs.base, ASMReadTSC());
             STAM_REL_COUNTER_INC(&pVCpu->nem.s.StatExitIrqWindowOpen);
             Log5(("IrqWinOpen/%u: %d\n", pVCpu->idCpu, pRun->request_interrupt_window));
@@ -2155,4 +2181,6 @@
 
         case KVM_EXIT_HLT:
+            EMHistoryAddExit(pVCpu, EMEXIT_MAKE_FT(EMEXIT_F_KIND_NEM, KVM_EXIT_HLT),
+                             pRun->s.regs.regs.rip + pRun->s.regs.sregs.cs.base, ASMReadTSC());
             STAM_REL_COUNTER_INC(&pVCpu->nem.s.StatExitHalt);
             Log5(("Halt/%u\n", pVCpu->idCpu));
@@ -2160,4 +2188,6 @@
 
         case KVM_EXIT_INTR: /* EINTR */
+            EMHistoryAddExit(pVCpu, EMEXIT_MAKE_FT(EMEXIT_F_KIND_NEM, KVM_EXIT_INTR),
+                             pRun->s.regs.regs.rip + pRun->s.regs.sregs.cs.base, ASMReadTSC());
             STAM_REL_COUNTER_INC(&pVCpu->nem.s.StatExitIntr);
             Log5(("Intr/%u\n", pVCpu->idCpu));
