Index: trunk/include/VBox/vmm/cpum.h
===================================================================
--- trunk/include/VBox/vmm/cpum.h	(revision 74647)
+++ trunk/include/VBox/vmm/cpum.h	(revision 74648)
@@ -1268,6 +1268,8 @@
     /** @name VMX Miscellaneous data.
      * @{ */
-    /** VMX: Supports storing EFER.LMA on VM-exits into IA32e-mode guest field. */
-    uint32_t        fVmxExitStoreEferLma : 1;
+    /** VMX: Supports storing EFER.LMA into IA32e-mode guest field on VM-exit. */
+    uint32_t        fVmxExitSaveEferLma : 1;
+    /** VMX: Whether Intel PT (Processor Trace) is supported in VMX mode or not. */
+    uint32_t        fVmxIntelPt : 1;
     /** VMX: Supports VMWRITE to any valid VMCS field incl. read-only fields, otherwise
      *  VMWRITE cannot modify read-only VM-exit information fields. */
@@ -1279,5 +1281,5 @@
 
     /** VMX: Padding / reserved for future features. */
-    uint32_t        fVmxPadding1 : 2;
+    uint32_t        fVmxPadding1 : 1;
     uint32_t        fVmxPadding2;
 } CPUMFEATURES;
Index: trunk/include/VBox/vmm/hm_vmx.h
===================================================================
--- trunk/include/VBox/vmm/hm_vmx.h	(revision 74647)
+++ trunk/include/VBox/vmm/hm_vmx.h	(revision 74648)
@@ -1457,5 +1457,7 @@
  */
 /** Whether VM-exit stores EFER.LMA into the "IA32e mode guest" field. */
-#define VMX_MISC_EXIT_STORE_EFER_LMA                            RT_BIT(5)
+#define VMX_MISC_EXIT_SAVE_EFER_LMA                             RT_BIT(5)
+/** Whether Intel PT is supported in VMX operation. */
+#define VMX_MISC_INTEL_PT                                       RT_BIT(14)
 /** Whether VMWRITE to any valid VMCS field incl. read-only fields, otherwise
  * VMWRITE cannot modify read-only VM-exit information fields. */
@@ -1472,6 +1474,6 @@
 #define VMX_BF_MISC_PREEMPT_TIMER_TSC_MASK                      UINT64_C(0x000000000000001f)
 /** Whether VM-exit stores EFER.LMA into the "IA32e mode guest" field. */
-#define VMX_BF_MISC_EXIT_STORE_EFER_LMA_SHIFT                   5
-#define VMX_BF_MISC_EXIT_STORE_EFER_LMA_MASK                    UINT64_C(0x0000000000000020)
+#define VMX_BF_MISC_EXIT_SAVE_EFER_LMA_SHIFT                    5
+#define VMX_BF_MISC_EXIT_SAVE_EFER_LMA_MASK                     UINT64_C(0x0000000000000020)
 /** Activity states supported by the implementation. */
 #define VMX_BF_MISC_ACTIVITY_STATES_SHIFT                       6
@@ -1481,6 +1483,6 @@
 #define VMX_BF_MISC_RSVD_9_13_MASK                              UINT64_C(0x0000000000003e00)
 /** Whether Intel PT (Processor Trace) can be used in VMX operation.  */
-#define VMX_BF_MISC_PT_SHIFT                                    14
-#define VMX_BF_MISC_PT_MASK                                     UINT64_C(0x0000000000004000)
+#define VMX_BF_MISC_INTEL_PT_SHIFT                              14
+#define VMX_BF_MISC_INTEL_PT_MASK                               UINT64_C(0x0000000000004000)
 /** Whether RDMSR can be used to read IA32_SMBASE MSR in SMM. */
 #define VMX_BF_MISC_SMM_READ_SMBASE_MSR_SHIFT                   15
@@ -1511,5 +1513,5 @@
 #define VMX_BF_MISC_MSEG_ID_MASK                                UINT64_C(0xffffffff00000000)
 RT_BF_ASSERT_COMPILE_CHECKS(VMX_BF_MISC_, UINT64_C(0), UINT64_MAX,
-                            (PREEMPT_TIMER_TSC, EXIT_STORE_EFER_LMA, ACTIVITY_STATES, RSVD_9_13, PT, SMM_READ_SMBASE_MSR,
+                            (PREEMPT_TIMER_TSC, EXIT_SAVE_EFER_LMA, ACTIVITY_STATES, RSVD_9_13, INTEL_PT, SMM_READ_SMBASE_MSR,
                              CR3_TARGET, MAX_MSRS, VMXOFF_BLOCK_SMI, VMWRITE_ALL, ENTRY_INJECT_SOFT_INT, RSVD_31, MSEG_ID));
 /** @} */
Index: trunk/include/iprt/x86.h
===================================================================
--- trunk/include/iprt/x86.h	(revision 74647)
+++ trunk/include/iprt/x86.h	(revision 74648)
@@ -1449,4 +1449,6 @@
 #define MSR_IA32_VMX_VMFUNC                 0x491
 
+/** Intel PT - Enable and control for trace packet generation. */
+#define MSR_IA32_RTIT_CTL                   0x570
 
 /** DS Save Area (R/W). */
Index: trunk/src/VBox/VMM/VMMAll/CPUMAllMsrs.cpp
===================================================================
--- trunk/src/VBox/VMM/VMMAll/CPUMAllMsrs.cpp	(revision 74647)
+++ trunk/src/VBox/VMM/VMMAll/CPUMAllMsrs.cpp	(revision 74648)
@@ -1521,8 +1521,8 @@
         uint8_t const cMaxMsrs       = RT_MIN(RT_BF_GET(uHostMsr, VMX_BF_MISC_MAX_MSRS), VMX_V_AUTOMSR_COUNT_MAX);
         uint8_t const fActivityState = RT_BF_GET(uHostMsr, VMX_BF_MISC_ACTIVITY_STATES) & VMX_V_GUEST_ACTIVITY_STATE_MASK;
-        uVmxMsr = RT_BF_MAKE(VMX_BF_MISC_PREEMPT_TIMER_TSC,       VMX_V_PREEMPT_TIMER_SHIFT            )
-                | RT_BF_MAKE(VMX_BF_MISC_EXIT_STORE_EFER_LMA,    pGuestFeatures->fVmxExitStoreEferLma  )
+        uVmxMsr = RT_BF_MAKE(VMX_BF_MISC_PREEMPT_TIMER_TSC,      VMX_V_PREEMPT_TIMER_SHIFT             )
+                | RT_BF_MAKE(VMX_BF_MISC_EXIT_SAVE_EFER_LMA,     pGuestFeatures->fVmxExitSaveEferLma   )
                 | RT_BF_MAKE(VMX_BF_MISC_ACTIVITY_STATES,        fActivityState                        )
-                | RT_BF_MAKE(VMX_BF_MISC_PT,                     0                                     )
+                | RT_BF_MAKE(VMX_BF_MISC_INTEL_PT,               pGuestFeatures->fVmxIntelPt           )
                 | RT_BF_MAKE(VMX_BF_MISC_SMM_READ_SMBASE_MSR,    0                                     )
                 | RT_BF_MAKE(VMX_BF_MISC_CR3_TARGET,             VMX_V_CR3_TARGET_COUNT                )
Index: trunk/src/VBox/VMM/VMMAll/IEMAllCImpl.cpp.h
===================================================================
--- trunk/src/VBox/VMM/VMMAll/IEMAllCImpl.cpp.h	(revision 74647)
+++ trunk/src/VBox/VMM/VMMAll/IEMAllCImpl.cpp.h	(revision 74648)
@@ -6482,7 +6482,9 @@
      */
 #ifdef VBOX_WITH_NESTED_HWVIRT_VMX
-    if (   IEM_VMX_IS_NON_ROOT_MODE(pVCpu)
-        && iemVmxIsRdmsrWrmsrInterceptSet(pVCpu, VMX_EXIT_RDMSR, pVCpu->cpum.GstCtx.ecx))
-        IEM_VMX_VMEXIT_INSTR_RET(pVCpu, VMX_EXIT_RDMSR, cbInstr);
+    if (IEM_VMX_IS_NON_ROOT_MODE(pVCpu))
+    {
+        if (iemVmxIsRdmsrWrmsrInterceptSet(pVCpu, VMX_EXIT_RDMSR, pVCpu->cpum.GstCtx.ecx))
+            IEM_VMX_VMEXIT_INSTR_RET(pVCpu, VMX_EXIT_RDMSR, cbInstr);
+    }
 #endif
 
@@ -6554,11 +6556,61 @@
         return iemRaiseGeneralProtectionFault0(pVCpu);
 
+    RTUINT64U uValue;
+    uValue.s.Lo = pVCpu->cpum.GstCtx.eax;
+    uValue.s.Hi = pVCpu->cpum.GstCtx.edx;
+
+    /** @todo make CPUMAllMsrs.cpp import the necessary MSR state. */
+    IEM_CTX_IMPORT_RET(pVCpu, CPUMCTX_EXTRN_ALL_MSRS);
+
     /*
      * Check nested-guest intercepts.
      */
 #ifdef VBOX_WITH_NESTED_HWVIRT_VMX
-    if (   IEM_VMX_IS_NON_ROOT_MODE(pVCpu)
-        && iemVmxIsRdmsrWrmsrInterceptSet(pVCpu, VMX_EXIT_WRMSR, pVCpu->cpum.GstCtx.ecx))
-        IEM_VMX_VMEXIT_INSTR_RET(pVCpu, VMX_EXIT_WRMSR, cbInstr);
+    if (IEM_VMX_IS_NON_ROOT_MODE(pVCpu))
+    {
+        if (iemVmxIsRdmsrWrmsrInterceptSet(pVCpu, VMX_EXIT_WRMSR, pVCpu->cpum.GstCtx.ecx))
+            IEM_VMX_VMEXIT_INSTR_RET(pVCpu, VMX_EXIT_WRMSR, cbInstr);
+
+        /* Check x2APIC MSRs first. */
+        if (IEM_VMX_IS_PROCCTLS2_SET(pVCpu, VMX_PROC_CTLS2_VIRT_X2APIC_MODE))
+        {
+            switch (pVCpu->cpum.GstCtx.ecx)
+            {
+                case MSR_IA32_X2APIC_TPR:
+                {
+                    if (   !uValue.s.Hi
+                        && !(uValue.s.Lo & UINT32_C(0xffffff00)))
+                    {
+                        uint32_t const uVTpr = (uValue.s.Lo & 0xf) << 4;
+                        iemVmxVirtApicWriteRaw32(pVCpu, uVTpr, XAPIC_OFF_TPR);
+                        VBOXSTRICTRC rcStrict = iemVmxVmexitTprVirtualization(pVCpu, cbInstr);
+                        if (rcStrict != VINF_VMX_INTERCEPT_NOT_ACTIVE)
+                            return rcStrict;
+                        return VINF_SUCCESS;
+                    }
+                    Log(("IEM: Invalid TPR MSR write -> #GP(0)\n", pVCpu->cpum.GstCtx.ecx, uValue.s.Hi, uValue.s.Lo));
+                    return iemRaiseGeneralProtectionFault0(pVCpu);
+                }
+
+                case MSR_IA32_X2APIC_EOI:
+                case MSR_IA32_X2APIC_SELF_IPI:
+                {
+                    /** @todo NSTVMX: EOI and Self-IPI virtualization. */
+                    break;
+                }
+            }
+        }
+        else if (pVCpu->cpum.GstCtx.ecx == MSR_IA32_BIOS_UPDT_TRIG)
+        {
+            /** @todo NSTVMX: We must not allow any microcode updates in VMX non-root mode.
+             *        Since we don't implement this MSR anyway it's currently not a problem.
+             *        If we do, we should probably move this check to the MSR handler.  */
+        }
+        else if (pVCpu->cpum.GstCtx.ecx == MSR_IA32_RTIT_CTL)
+        {
+            /** @todo NSTVMX: We don't support Intel PT yet. When we do, this MSR must #GP
+             *        when IntelPT is not supported in VMX. */
+        }
+    }
 #endif
 
@@ -6580,11 +6632,4 @@
      * Do the job.
      */
-    RTUINT64U uValue;
-    uValue.s.Lo = pVCpu->cpum.GstCtx.eax;
-    uValue.s.Hi = pVCpu->cpum.GstCtx.edx;
-
-    /** @todo make CPUMAllMsrs.cpp import the necessary MSR state. */
-    IEM_CTX_IMPORT_RET(pVCpu, CPUMCTX_EXTRN_ALL_MSRS);
-
     VBOXSTRICTRC rcStrict = CPUMSetGuestMsr(pVCpu, pVCpu->cpum.GstCtx.ecx, uValue.u);
     if (rcStrict == VINF_SUCCESS)
Index: trunk/src/VBox/VMM/VMMR3/CPUM.cpp
===================================================================
--- trunk/src/VBox/VMM/VMMR3/CPUM.cpp	(revision 74647)
+++ trunk/src/VBox/VMM/VMMR3/CPUM.cpp	(revision 74648)
@@ -1184,9 +1184,7 @@
         VMXFEATDUMP("ExitLoadEferMsr - Load IA32_EFER on VM-exit            ", fVmxExitLoadEferMsr);
         VMXFEATDUMP("SavePreemptTimer - Save VMX-preemption timer           ", fVmxSavePreemptTimer);
-        VMXFEATDUMP("ExitStoreEferLma - Store EFER.LMA on VM-exit           ", fVmxExitStoreEferLma);
-        VMXFEATDUMP("VmwriteAll - VMWRITE to any VMCS field                 ", fVmxVmwriteAll);
-        VMXFEATDUMP("EntryInjectSoftInt - Inject softint. with 0-len instr. ", fVmxEntryInjectSoftInt);
         /* Miscellaneous data. */
-        VMXFEATDUMP("ExitStoreEferLma - Inject softint. with 0-len instr.   ", fVmxExitStoreEferLma);
+        VMXFEATDUMP("ExitSaveEferLma - Save EFER.LMA on VM-exit             ", fVmxExitSaveEferLma);
+        VMXFEATDUMP("IntelPt - Intel PT (Processor Trace) in VMX operation  ", fVmxIntelPt);
         VMXFEATDUMP("VmwriteAll - Inject softint. with 0-len instr.         ", fVmxVmwriteAll);
         VMXFEATDUMP("EntryInjectSoftInt - Inject softint. with 0-len instr. ", fVmxEntryInjectSoftInt);
@@ -1297,5 +1295,6 @@
         /* Miscellaneous data. */
         uint32_t const fMiscData = VmxMsrs.u64Misc;
-        pHostFeat->fVmxExitStoreEferLma      = RT_BOOL(fMiscData & VMX_MISC_EXIT_STORE_EFER_LMA);
+        pHostFeat->fVmxExitSaveEferLma       = RT_BOOL(fMiscData & VMX_MISC_EXIT_SAVE_EFER_LMA);
+        pHostFeat->fVmxIntelPt               = RT_BOOL(fMiscData & VMX_MISC_INTEL_PT);
         pHostFeat->fVmxVmwriteAll            = RT_BOOL(fMiscData & VMX_MISC_VMWRITE_ALL);
         pHostFeat->fVmxEntryInjectSoftInt    = RT_BOOL(fMiscData & VMX_MISC_ENTRY_INJECT_SOFT_INT);
@@ -1369,5 +1368,6 @@
     EmuFeat.fVmxExitLoadEferMsr       = 1;
     EmuFeat.fVmxSavePreemptTimer      = 0;
-    EmuFeat.fVmxExitStoreEferLma      = 1;
+    EmuFeat.fVmxExitSaveEferLma       = 1;
+    EmuFeat.fVmxIntelPt               = 0;
     EmuFeat.fVmxVmwriteAll            = 0;
     EmuFeat.fVmxEntryInjectSoftInt    = 0;
@@ -1443,5 +1443,6 @@
     pGuestFeat->fVmxExitLoadEferMsr       = (pBaseFeat->fVmxExitLoadEferMsr       & EmuFeat.fVmxExitLoadEferMsr      );
     pGuestFeat->fVmxSavePreemptTimer      = (pBaseFeat->fVmxSavePreemptTimer      & EmuFeat.fVmxSavePreemptTimer     );
-    pGuestFeat->fVmxExitStoreEferLma      = (pBaseFeat->fVmxExitStoreEferLma      & EmuFeat.fVmxExitStoreEferLma     );
+    pGuestFeat->fVmxExitSaveEferLma       = (pBaseFeat->fVmxExitSaveEferLma       & EmuFeat.fVmxExitSaveEferLma      );
+    pGuestFeat->fVmxIntelPt               = (pBaseFeat->fVmxIntelPt               & EmuFeat.fVmxIntelPt              );
     pGuestFeat->fVmxVmwriteAll            = (pBaseFeat->fVmxVmwriteAll            & EmuFeat.fVmxVmwriteAll           );
     pGuestFeat->fVmxEntryInjectSoftInt    = (pBaseFeat->fVmxEntryInjectSoftInt    & EmuFeat.fVmxEntryInjectSoftInt   );
Index: trunk/src/VBox/VMM/VMMR3/HM.cpp
===================================================================
--- trunk/src/VBox/VMM/VMMR3/HM.cpp	(revision 74647)
+++ trunk/src/VBox/VMM/VMMR3/HM.cpp	(revision 74648)
@@ -1598,8 +1598,8 @@
                 pVM->hm.s.vmx.cPreemptTimerShift));
     }
-    LogRel(("HM:   EXIT_STORE_EFER_LMA               = %RTbool\n",    RT_BF_GET(fMisc, VMX_BF_MISC_EXIT_STORE_EFER_LMA)));
+    LogRel(("HM:   EXIT_SAVE_EFER_LMA                = %RTbool\n",    RT_BF_GET(fMisc, VMX_BF_MISC_EXIT_SAVE_EFER_LMA)));
     LogRel(("HM:   ACTIVITY_STATES                   = %#x%s\n",      RT_BF_GET(fMisc, VMX_BF_MISC_ACTIVITY_STATES),
                                                                       hmR3VmxGetActivityStateAllDesc(fMisc)));
-    LogRel(("HM:   PT                                = %RTbool\n",    RT_BF_GET(fMisc, VMX_BF_MISC_PT)));
+    LogRel(("HM:   INTEL_PT                          = %RTbool\n",    RT_BF_GET(fMisc, VMX_BF_MISC_INTEL_PT)));
     LogRel(("HM:   SMM_READ_SMBASE_MSR               = %RTbool\n",    RT_BF_GET(fMisc, VMX_BF_MISC_SMM_READ_SMBASE_MSR)));
     LogRel(("HM:   CR3_TARGET                        = %#x\n",        RT_BF_GET(fMisc, VMX_BF_MISC_CR3_TARGET)));
