Index: /trunk/src/VBox/VMM/VMMR0/HMVMXR0.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR0/HMVMXR0.cpp	(revision 81205)
+++ /trunk/src/VBox/VMM/VMMR0/HMVMXR0.cpp	(revision 81206)
@@ -4849,5 +4849,4 @@
  * Exports the guest APIC TPR state into the VMCS.
  *
- * @returns VBox status code.
  * @param   pVCpu           The cross context virtual CPU structure.
  * @param   pVmxTransient   The VMX-transient structure.
@@ -4855,5 +4854,5 @@
  * @remarks No-long-jump zone!!!
  */
-static int hmR0VmxExportGuestApicTpr(PVMCPUCC pVCpu, PVMXTRANSIENT pVmxTransient)
+static void hmR0VmxExportGuestApicTpr(PVMCPUCC pVCpu, PVMXTRANSIENT pVmxTransient)
 {
     if (ASMAtomicUoReadU64(&pVCpu->hm.s.fCtxChanged) & HM_CHANGED_GUEST_APIC_TPR)
@@ -4876,5 +4875,5 @@
                     uint8_t u8PendingIntr = 0;
                     int rc = APICGetTpr(pVCpu, &u8Tpr, &fPendingIntr, &u8PendingIntr);
-                    AssertRCReturn(rc, rc);
+                    AssertRC(rc);
 
                     /*
@@ -4903,5 +4902,4 @@
         ASMAtomicUoAndU64(&pVCpu->hm.s.fCtxChanged, ~HM_CHANGED_GUEST_APIC_TPR);
     }
-    return VINF_SUCCESS;
 }
 
@@ -4967,5 +4965,4 @@
  * Exports the exception intercepts required for guest execution in the VMCS.
  *
- * @returns VBox status code.
  * @param   pVCpu           The cross context virtual CPU structure.
  * @param   pVmxTransient   The VMX-transient structure.
@@ -4973,5 +4970,5 @@
  * @remarks No-long-jump zone!!!
  */
-static int hmR0VmxExportGuestXcptIntercepts(PVMCPUCC pVCpu, PVMXTRANSIENT pVmxTransient)
+static void hmR0VmxExportGuestXcptIntercepts(PVMCPUCC pVCpu, PVMXTRANSIENT pVmxTransient)
 {
     if (ASMAtomicUoReadU64(&pVCpu->hm.s.fCtxChanged) & HM_CHANGED_VMX_XCPT_INTERCEPTS)
@@ -4987,5 +4984,4 @@
         ASMAtomicUoAndU64(&pVCpu->hm.s.fCtxChanged, ~HM_CHANGED_VMX_XCPT_INTERCEPTS);
     }
-    return VINF_SUCCESS;
 }
 
@@ -4994,10 +4990,9 @@
  * Exports the guest's RIP into the guest-state area in the VMCS.
  *
- * @returns VBox status code.
  * @param   pVCpu   The cross context virtual CPU structure.
  *
  * @remarks No-long-jump zone!!!
  */
-static int hmR0VmxExportGuestRip(PVMCPUCC pVCpu)
+static void hmR0VmxExportGuestRip(PVMCPUCC pVCpu)
 {
     if (ASMAtomicUoReadU64(&pVCpu->hm.s.fCtxChanged) & HM_CHANGED_GUEST_RIP)
@@ -5011,5 +5006,4 @@
         Log4Func(("rip=%#RX64\n", pVCpu->cpum.GstCtx.rip));
     }
-    return VINF_SUCCESS;
 }
 
@@ -5018,10 +5012,9 @@
  * Exports the guest's RSP into the guest-state area in the VMCS.
  *
- * @returns VBox status code.
  * @param   pVCpu   The cross context virtual CPU structure.
  *
  * @remarks No-long-jump zone!!!
  */
-static int hmR0VmxExportGuestRsp(PVMCPUCC pVCpu)
+static void hmR0VmxExportGuestRsp(PVMCPUCC pVCpu)
 {
     if (ASMAtomicUoReadU64(&pVCpu->hm.s.fCtxChanged) & HM_CHANGED_GUEST_RSP)
@@ -5035,5 +5028,4 @@
         Log4Func(("rsp=%#RX64\n", pVCpu->cpum.GstCtx.rsp));
     }
-    return VINF_SUCCESS;
 }
 
@@ -5042,5 +5034,4 @@
  * Exports the guest's RFLAGS into the guest-state area in the VMCS.
  *
- * @returns VBox status code.
  * @param   pVCpu           The cross context virtual CPU structure.
  * @param   pVmxTransient   The VMX-transient structure.
@@ -5048,5 +5039,5 @@
  * @remarks No-long-jump zone!!!
  */
-static int hmR0VmxExportGuestRflags(PVMCPUCC pVCpu, PVMXTRANSIENT pVmxTransient)
+static void hmR0VmxExportGuestRflags(PVMCPUCC pVCpu, PVMXTRANSIENT pVmxTransient)
 {
     if (ASMAtomicUoReadU64(&pVCpu->hm.s.fCtxChanged) & HM_CHANGED_GUEST_RFLAGS)
@@ -5100,5 +5091,4 @@
         Log4Func(("eflags=%#RX32\n", fEFlags.u32));
     }
-    return VINF_SUCCESS;
 }
 
@@ -9087,14 +9077,9 @@
     AssertLogRelMsgRCReturn(rc, ("rc=%Rrc\n", rc), rc);
 
-    rc = hmR0VmxExportGuestApicTpr(pVCpu, pVmxTransient);
-    AssertLogRelMsgRCReturn(rc, ("rc=%Rrc\n", rc), rc);
-
-    rc = hmR0VmxExportGuestXcptIntercepts(pVCpu, pVmxTransient);
-    AssertLogRelMsgRCReturn(rc, ("rc=%Rrc\n", rc), rc);
-
-    rc  = hmR0VmxExportGuestRip(pVCpu);
-    rc |= hmR0VmxExportGuestRsp(pVCpu);
-    rc |= hmR0VmxExportGuestRflags(pVCpu, pVmxTransient);
-    AssertLogRelMsgRCReturn(rc, ("rc=%Rrc\n", rc), rc);
+    hmR0VmxExportGuestApicTpr(pVCpu, pVmxTransient);
+    hmR0VmxExportGuestXcptIntercepts(pVCpu, pVmxTransient);
+    hmR0VmxExportGuestRip(pVCpu);
+    hmR0VmxExportGuestRsp(pVCpu);
+    hmR0VmxExportGuestRflags(pVCpu, pVmxTransient);
 
     rc = hmR0VmxExportGuestHwvirtState(pVCpu, pVmxTransient);
@@ -9141,8 +9126,5 @@
         /* Loading shared debug bits might have changed eflags.TF bit for debugging purposes. */
         if (pVCpu->hm.s.fCtxChanged & HM_CHANGED_GUEST_RFLAGS)
-        {
-            rc = hmR0VmxExportGuestRflags(pVCpu, pVmxTransient);
-            AssertRC(rc);
-        }
+            hmR0VmxExportGuestRflags(pVCpu, pVmxTransient);
     }
 
@@ -9182,20 +9164,24 @@
 
     /*
-     * For many exits it's only RIP that changes and hence try to export it first
+     * For many exits it's only RIP/RSP/RFLAGS that changes and hence try to export it first
      * without going through a lot of change flag checks.
      */
-    VBOXSTRICTRC rcStrict;
-    uint64_t     fCtxChanged = ASMAtomicUoReadU64(&pVCpu->hm.s.fCtxChanged);
-    RT_UNTRUSTED_NONVOLATILE_COPY_FENCE();
-    if ((fCtxChanged & (HM_CHANGED_ALL_GUEST & ~HM_CHANGED_VMX_HOST_GUEST_SHARED_STATE)) == HM_CHANGED_GUEST_RIP)
-    {
-        rcStrict = hmR0VmxExportGuestRip(pVCpu);
-        if (RT_LIKELY(rcStrict == VINF_SUCCESS))
-        { /* likely */}
-        else
-            AssertMsgFailedReturn(("Failed to export guest RIP! rc=%Rrc\n", VBOXSTRICTRC_VAL(rcStrict)), rcStrict);
+    VBOXSTRICTRC   rcStrict;
+    uint64_t const fCtxMask     = HM_CHANGED_ALL_GUEST & ~HM_CHANGED_VMX_HOST_GUEST_SHARED_STATE;
+    uint64_t const fMinimalMask = HM_CHANGED_GUEST_RIP | HM_CHANGED_GUEST_RSP | HM_CHANGED_GUEST_RFLAGS | HM_CHANGED_GUEST_HWVIRT;
+    uint64_t const fCtxChanged  = ASMAtomicUoReadU64(&pVCpu->hm.s.fCtxChanged);
+
+    /* If only RIP/RSP/RFLAGS/HWVIRT changed, export only those (quicker, happens more often).*/
+    if (    (fCtxChanged & fMinimalMask)
+        && !(fCtxChanged & (fCtxMask & ~fMinimalMask)))
+    {
+        hmR0VmxExportGuestRip(pVCpu);
+        hmR0VmxExportGuestRsp(pVCpu);
+        hmR0VmxExportGuestRflags(pVCpu, pVmxTransient);
+        rcStrict = hmR0VmxExportGuestHwvirtState(pVCpu, pVmxTransient);
         STAM_COUNTER_INC(&pVCpu->hm.s.StatExportMinimal);
     }
-    else if (fCtxChanged & (HM_CHANGED_ALL_GUEST & ~HM_CHANGED_VMX_HOST_GUEST_SHARED_STATE))
+    /* If anything else also changed, go through the full export routine and export as required. */
+    else if (fCtxChanged & fCtxMask)
     {
         rcStrict = hmR0VmxExportGuestState(pVCpu, pVmxTransient);
@@ -9211,11 +9197,9 @@
         STAM_COUNTER_INC(&pVCpu->hm.s.StatExportFull);
     }
-    else
-        rcStrict = VINF_SUCCESS;
+    /* else: Nothing changed, nothing to load here. */
 
 #ifdef VBOX_STRICT
     /* All the guest state bits should be loaded except maybe the host context and/or the shared host/guest bits. */
     fCtxChanged = ASMAtomicUoReadU64(&pVCpu->hm.s.fCtxChanged);
-    RT_UNTRUSTED_NONVOLATILE_COPY_FENCE();
     AssertMsg(!(fCtxChanged & (HM_CHANGED_ALL_GUEST & ~HM_CHANGED_VMX_HOST_GUEST_SHARED_STATE)),
               ("fCtxChanged=%#RX64\n", fCtxChanged));
@@ -14842,6 +14826,5 @@
     STAM_COUNTER_INC(&pVCpu->hm.s.StatExitRdmsr);
     if (rcStrict == VINF_SUCCESS)
-        ASMAtomicUoOrU64(&pVCpu->hm.s.fCtxChanged, HM_CHANGED_GUEST_RIP | HM_CHANGED_GUEST_RFLAGS
-                                                 | HM_CHANGED_GUEST_RAX | HM_CHANGED_GUEST_RDX);
+        ASMAtomicUoOrU64(&pVCpu->hm.s.fCtxChanged, HM_CHANGED_GUEST_RIP | HM_CHANGED_GUEST_RFLAGS);
     else if (rcStrict == VINF_IEM_RAISED_XCPT)
     {
