Index: /trunk/src/VBox/VMM/VMMR0/HMVMXR0.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR0/HMVMXR0.cpp	(revision 79749)
+++ /trunk/src/VBox/VMM/VMMR0/HMVMXR0.cpp	(revision 79750)
@@ -14360,5 +14360,5 @@
 #endif
         pVCpu->hm.s.Event.fPending = false;                  /* In case it's a contributory or vectoring #PF. */
-        if (RT_LIKELY(!pVmxTransient->fVectoringDoublePF))
+        if (!pVmxTransient->fVectoringDoublePF)
         {
             hmR0VmxSetPendingEvent(pVCpu, VMX_ENTRY_INT_INFO_FROM_EXIT_INT_INFO(pVmxTransient->uExitIntInfo), 0 /* cbInstr */,
@@ -14368,4 +14368,5 @@
         {
             /* A guest page-fault occurred during delivery of a page-fault. Inject #DF. */
+            Assert(!pVmxTransient->fIsNestedGuest);
             hmR0VmxSetPendingXcptDF(pVCpu);
             Log4Func(("Pending #DF due to vectoring #PF w/ NestedPaging\n"));
@@ -14374,4 +14375,6 @@
         return rc;
     }
+
+    Assert(!pVmxTransient->fIsNestedGuest);
 
     /* If it's a vectoring #PF, emulate injecting the original event injection as PGMTrap0eHandler() is incapable
@@ -14460,4 +14463,9 @@
     }
 
+    rc  = hmR0VmxReadExitIntInfoVmcs(pVmxTransient);
+    rc |= hmR0VmxReadExitIntErrorCodeVmcs(pVmxTransient);
+    rc |= hmR0VmxReadExitInstrLenVmcs(pVmxTransient);
+    AssertRCReturn(rc, rc);
+
     hmR0VmxSetPendingEvent(pVCpu, VMX_ENTRY_INT_INFO_FROM_EXIT_INT_INFO(pVmxTransient->uExitIntInfo), pVmxTransient->cbInstr,
                            pVmxTransient->uExitIntErrorCode, 0 /* GCPtrFaultAddress */);
@@ -14478,5 +14486,8 @@
 
     PCPUMCTX pCtx = &pVCpu->cpum.GstCtx;
-    rc = DBGFRZTrap03Handler(pVCpu->CTX_SUFF(pVM), pVCpu, CPUMCTX2CORE(pCtx));
+    if (!pVmxTransient->fIsNestedGuest)
+        rc = DBGFRZTrap03Handler(pVCpu->CTX_SUFF(pVM), pVCpu, CPUMCTX2CORE(pCtx));
+    else
+        rc = VINF_EM_RAW_GUEST_TRAP;
     if (rc == VINF_EM_RAW_GUEST_TRAP)
     {
@@ -14496,5 +14507,5 @@
 
 /**
- * VM-exit exception handler for \#AC (alignment check exception).
+ * VM-exit exception handler for \#AC (Alignment-check exception).
  */
 static VBOXSTRICTRC hmR0VmxExitXcptAC(PVMCPU pVCpu, PVMXTRANSIENT pVmxTransient)
@@ -14536,5 +14547,8 @@
 
     PCPUMCTX pCtx = &pVCpu->cpum.GstCtx;
-    rc = DBGFRZTrap01Handler(pVCpu->CTX_SUFF(pVM), pVCpu, CPUMCTX2CORE(pCtx), uDR6, pVCpu->hm.s.fSingleInstruction);
+    if (!pVmxTransient->fIsNestedGuest)
+        rc = DBGFRZTrap01Handler(pVCpu->CTX_SUFF(pVM), pVCpu, CPUMCTX2CORE(pCtx), uDR6, pVCpu->hm.s.fSingleInstruction);
+    else
+        rc = VINF_EM_RAW_GUEST_TRAP;
     Log6Func(("rc=%Rrc\n", rc));
     if (rc == VINF_EM_RAW_GUEST_TRAP)
@@ -14667,8 +14681,7 @@
 }
 
+
 /**
  * VM-exit exception handler for \#GP (General-protection exception).
- *
- * @remarks Requires pVmxTransient->uExitIntInfo to be up-to-date.
  */
 static VBOXSTRICTRC hmR0VmxExitXcptGP(PVMCPU pVCpu, PVMXTRANSIENT pVmxTransient)
@@ -14686,5 +14699,8 @@
         Assert(pVCpu->hm.s.fUsingDebugLoop || pVCpu->hm.s.fTrapXcptGpForLovelyMesaDrv || pVmxTransient->fIsNestedGuest);
 #endif
-        /* If the guest is not in real-mode or we have unrestricted guest execution support, reflect #GP to the guest. */
+        /*
+         * If the guest is not in real-mode or we have unrestricted guest execution support, or if we are
+         * executing a nested-guest, reflect #GP to the guest or nested-guest.
+         */
         int rc  = hmR0VmxReadExitIntInfoVmcs(pVmxTransient);
         rc     |= hmR0VmxReadExitIntErrorCodeVmcs(pVmxTransient);
@@ -14746,10 +14762,11 @@
 
 /**
- * VM-exit exception handler wrapper for generic exceptions.
+ * VM-exit exception handler wrapper for all other exceptions that are not handled
+ * by a specific handler.
  *
  * This simply re-injects the exception back into the VM without any special
  * processing.
  */
-static VBOXSTRICTRC hmR0VmxExitXcptGeneric(PVMCPU pVCpu, PVMXTRANSIENT pVmxTransient)
+static VBOXSTRICTRC hmR0VmxExitXcptOthers(PVMCPU pVCpu, PVMXTRANSIENT pVmxTransient)
 {
     HMVMX_VALIDATE_EXIT_XCPT_HANDLER_PARAMS(pVCpu, pVmxTransient);
@@ -14814,4 +14831,27 @@
     return VINF_SUCCESS;
 }
+
+
+/**
+ * VM-exit exception handler for all exceptions.
+ *
+ * @remarks This may be called for both guests and nested-guests. Take care to not
+ *          make assumptions and avoid doing anything that is not relevant when
+ *          executing a nested-guest (e.g., Mesa driver hacks).
+ */
+DECL_FORCE_INLINE(VBOXSTRICTRC) hmR0VmxExitXcptAll(PVMCPU pVCpu, PVMXTRANSIENT pVmxTransient, uint8_t uVector)
+{
+    switch (uVector)
+    {
+        case X86_XCPT_PF: return hmR0VmxExitXcptPF(pVCpu, pVmxTransient);
+        case X86_XCPT_GP: return hmR0VmxExitXcptGP(pVCpu, pVmxTransient);
+        case X86_XCPT_MF: return hmR0VmxExitXcptMF(pVCpu, pVmxTransient);
+        case X86_XCPT_DB: return hmR0VmxExitXcptDB(pVCpu, pVmxTransient);
+        case X86_XCPT_BP: return hmR0VmxExitXcptBP(pVCpu, pVmxTransient);
+        case X86_XCPT_AC: return hmR0VmxExitXcptAC(pVCpu, pVmxTransient);
+        default:
+            return hmR0VmxExitXcptOthers(pVCpu, pVmxTransient);
+    }
+}
 /** @} */
 
@@ -14912,17 +14952,5 @@
                 break;
             }
-
-            switch (uVector)
-            {
-                case X86_XCPT_PF: rcStrict = hmR0VmxExitXcptPF(pVCpu, pVmxTransient);   break;
-                case X86_XCPT_GP: rcStrict = hmR0VmxExitXcptGP(pVCpu, pVmxTransient);   break;
-                case X86_XCPT_MF: rcStrict = hmR0VmxExitXcptMF(pVCpu, pVmxTransient);   break;
-                case X86_XCPT_DB: rcStrict = hmR0VmxExitXcptDB(pVCpu, pVmxTransient);   break;
-                case X86_XCPT_BP: rcStrict = hmR0VmxExitXcptBP(pVCpu, pVmxTransient);   break;
-                case X86_XCPT_AC: rcStrict = hmR0VmxExitXcptAC(pVCpu, pVmxTransient);   break;
-                default:
-                    rcStrict = hmR0VmxExitXcptGeneric(pVCpu, pVmxTransient);
-                    break;
-            }
+            rcStrict = hmR0VmxExitXcptAll(pVCpu, pVmxTransient, uVector);
             break;
         }
@@ -17066,7 +17094,5 @@
              */
             pVCpu->hm.s.Event.fPending = false;
-            hmR0VmxSetPendingEvent(pVCpu, VMX_ENTRY_INT_INFO_FROM_EXIT_INT_INFO(uExitIntInfo), pVmxTransient->cbInstr,
-                                   pVmxTransient->uExitIntErrorCode, pVmxTransient->uExitQual);
-            return VINF_SUCCESS;
+            return hmR0VmxExitXcptAll(pVCpu, pVmxTransient, uVector);
         }
 
