Index: /trunk/src/VBox/VMM/VMMR0/HMSVMR0.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR0/HMSVMR0.cpp	(revision 61604)
+++ /trunk/src/VBox/VMM/VMMR0/HMSVMR0.cpp	(revision 61605)
@@ -4235,8 +4235,19 @@
 }
 
-
-/**
- * Advances the guest RIP in the if the NRIP_SAVE feature is supported by the
- * CPU, otherwise advances the RIP by @a cb bytes.
+/**
+ * Updates interrupt shadow for the current RIP.
+ */
+#define HMSVM_UPDATE_INTR_SHADOW(pVCpu, pCtx) \
+    do { \
+        /* Update interrupt shadow. */ \
+        if (   VMCPU_FF_IS_PENDING(pVCpu, VMCPU_FF_INHIBIT_INTERRUPTS) \
+            && pCtx->rip != EMGetInhibitInterruptsPC(pVCpu)) \
+            VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_INHIBIT_INTERRUPTS); \
+    } while (0)
+
+/**
+ * Advances the guest RIP making use of the CPU's NRIP_SAVE feature if
+ * supported, otherwise advances the RIP by the number of bytes specified in
+ * @a cb.
  *
  * @param   pVCpu       The cross context virtual CPU structure.
@@ -4245,11 +4256,13 @@
  *
  * @remarks Use this function only from \#VMEXIT's where the NRIP value is valid
- *          when NRIP_SAVE is supported by the CPU!
- */
-DECLINLINE(void) hmR0SvmUpdateRip(PVMCPU pVCpu, PCPUMCTX pCtx, uint32_t cb)
+ *          when NRIP_SAVE is supported by the CPU, otherwise use
+ *          hmR0SvmAdvanceRipDumb!
+ */
+DECLINLINE(void) hmR0SvmAdvanceRipHwAssist(PVMCPU pVCpu, PCPUMCTX pCtx, uint32_t cb)
 {
     if (pVCpu->CTX_SUFF(pVM)->hm.s.svm.u32Features & AMD_CPUID_SVM_FEATURE_EDX_NRIP_SAVE)
     {
         PSVMVMCB pVmcb = (PSVMVMCB)pVCpu->hm.s.svm.pvVmcb;
+        Assert(pVmcb->ctrl.u64NextRIP);
         Assert(pVmcb->ctrl.u64NextRIP - pCtx->rip == cb);
         pCtx->rip = pVmcb->ctrl.u64NextRIP;
@@ -4258,9 +4271,22 @@
         pCtx->rip += cb;
 
-    /* Update interrupt shadow. */
-    if (   VMCPU_FF_IS_PENDING(pVCpu, VMCPU_FF_INHIBIT_INTERRUPTS)
-        && pCtx->rip != EMGetInhibitInterruptsPC(pVCpu))
-        VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_INHIBIT_INTERRUPTS);
-}
+    HMSVM_UPDATE_INTR_SHADOW(pVCpu, pCtx);
+}
+
+
+/**
+ * Advances the guest RIP by the number of bytes specified in @a cb. This does
+ * not make use of any hardware features to determine the instruction length.
+ *
+ * @param   pVCpu       The cross context virtual CPU structure.
+ * @param   pCtx        Pointer to the guest-CPU context.
+ * @param   cb          RIP increment value in bytes.
+ */
+DECLINLINE(void) hmR0SvmAdvanceRipDumb(PVMCPU pVCpu, PCPUMCTX pCtx, uint32_t cb)
+{
+    pCtx->rip += cb;
+    HMSVM_UPDATE_INTR_SHADOW(pVCpu, pCtx);
+}
+#undef HMSVM_UPDATE_INTR_SHADOW
 
 
@@ -4305,5 +4331,5 @@
     HMSVM_VALIDATE_EXIT_HANDLER_PARAMS();
 
-    hmR0SvmUpdateRip(pVCpu, pCtx, 2);
+    hmR0SvmAdvanceRipHwAssist(pVCpu, pCtx, 2);
     STAM_COUNTER_INC(&pVCpu->hm.s.StatExitWbinvd);
     int rc = VINF_SUCCESS;
@@ -4320,5 +4346,5 @@
     HMSVM_VALIDATE_EXIT_HANDLER_PARAMS();
 
-    hmR0SvmUpdateRip(pVCpu, pCtx, 2);
+    hmR0SvmAdvanceRipHwAssist(pVCpu, pCtx, 2);
     STAM_COUNTER_INC(&pVCpu->hm.s.StatExitInvd);
     int rc = VINF_SUCCESS;
@@ -4338,5 +4364,5 @@
     if (RT_LIKELY(rc == VINF_SUCCESS))
     {
-        hmR0SvmUpdateRip(pVCpu, pCtx, 2);
+        hmR0SvmAdvanceRipHwAssist(pVCpu, pCtx, 2);
         HMSVM_CHECK_SINGLE_STEP(pVCpu, rc);
     }
@@ -4361,5 +4387,5 @@
     if (RT_LIKELY(rc == VINF_SUCCESS))
     {
-        hmR0SvmUpdateRip(pVCpu, pCtx, 2);
+        hmR0SvmAdvanceRipHwAssist(pVCpu, pCtx, 2);
         pSvmTransient->fUpdateTscOffsetting = true;
 
@@ -4386,5 +4412,5 @@
     if (RT_LIKELY(rc == VINF_SUCCESS))
     {
-        hmR0SvmUpdateRip(pVCpu, pCtx, 3);
+        hmR0SvmAdvanceRipHwAssist(pVCpu, pCtx, 3);
         pSvmTransient->fUpdateTscOffsetting = true;
         HMSVM_CHECK_SINGLE_STEP(pVCpu, rc);
@@ -4409,5 +4435,5 @@
     if (RT_LIKELY(rc == VINF_SUCCESS))
     {
-        hmR0SvmUpdateRip(pVCpu, pCtx, 2);
+        hmR0SvmAdvanceRipHwAssist(pVCpu, pCtx, 2);
         HMSVM_CHECK_SINGLE_STEP(pVCpu, rc);
     }
@@ -4447,5 +4473,5 @@
     HMSVM_VALIDATE_EXIT_HANDLER_PARAMS();
 
-    hmR0SvmUpdateRip(pVCpu, pCtx, 1);
+    hmR0SvmAdvanceRipHwAssist(pVCpu, pCtx, 1);
     int rc = EMShouldContinueAfterHalt(pVCpu, pCtx) ? VINF_SUCCESS : VINF_EM_HALT;
     HMSVM_CHECK_SINGLE_STEP(pVCpu, rc);
@@ -4466,5 +4492,5 @@
     if (RT_LIKELY(rc == VINF_SUCCESS))
     {
-        hmR0SvmUpdateRip(pVCpu, pCtx, 3);
+        hmR0SvmAdvanceRipHwAssist(pVCpu, pCtx, 3);
         HMSVM_CHECK_SINGLE_STEP(pVCpu, rc);
     }
@@ -4490,5 +4516,5 @@
         ||  rc == VINF_SUCCESS)
     {
-        hmR0SvmUpdateRip(pVCpu, pCtx, 3);
+        hmR0SvmAdvanceRipHwAssist(pVCpu, pCtx, 3);
 
         if (   rc == VINF_EM_HALT
@@ -4629,5 +4655,5 @@
                 HMCPU_CF_SET(pVCpu, HM_CHANGED_SVM_GUEST_APIC_STATE);
             }
-            hmR0SvmUpdateRip(pVCpu, pCtx, 2);
+            hmR0SvmAdvanceRipHwAssist(pVCpu, pCtx, 2);
             rc = VINF_SUCCESS;
             HMSVM_CHECK_SINGLE_STEP(pVCpu, rc);
@@ -5207,5 +5233,5 @@
             {
                 if (rcStrict == VINF_SUCCESS)
-                    hmR0SvmUpdateRip(pVCpu, pCtx, 3 /* cbInstr */);
+                    hmR0SvmAdvanceRipHwAssist(pVCpu, pCtx, 3 /* cbInstr */);
                 else
                     Assert(   rcStrict == VINF_GIM_HYPERCALL_CONTINUING
@@ -5451,5 +5477,6 @@
         if (rcStrict == VINF_SUCCESS)
         {
-            hmR0SvmUpdateRip(pVCpu, pCtx, cbInstr);
+            /* #UD #VMEXIT does not have valid NRIP information, manually advance RIP. See @bugref{7270#c170}. */
+            hmR0SvmAdvanceRipDumb(pVCpu, pCtx, cbInstr);
             rc = VINF_SUCCESS;
         }
