Index: /trunk/src/VBox/VMM/VMMAll/HMSVMAll.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMAll/HMSVMAll.cpp	(revision 68274)
+++ /trunk/src/VBox/VMM/VMMAll/HMSVMAll.cpp	(revision 68275)
@@ -248,5 +248,5 @@
     {
         /* AMD Seventh and Eighth Generation Processor MSRs. */
-        *pbOffMsrpm += 0x1000;
+        *pbOffMsrpm = 0x1000;
         *puMsrpmBit = (idMsr - 0xc0001000) << 1;
         return VINF_SUCCESS;
Index: /trunk/src/VBox/VMM/VMMR0/HMSVMR0.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR0/HMSVMR0.cpp	(revision 68274)
+++ /trunk/src/VBox/VMM/VMMR0/HMSVMR0.cpp	(revision 68275)
@@ -4223,19 +4223,79 @@
     Assert(pSvmTransient->u64ExitCode <= SVM_EXIT_MAX);
 
+    /*
+     * For all the #VMEXITs here we primarily figure out if the #VMEXIT is expected
+     * by the nested-guest. If it isn't, it should be handled by the (outer) guest.
+     */
     PSVMVMCB            pVmcbNstGst      = pCtx->hwvirt.svm.CTX_SUFF(pVmcb);
+    PSVMVMCBCTRL        pVmcbNstGstCtrl  = &pVmcbNstGst->ctrl;
     PSVMNESTEDVMCBCACHE pVmcbNstGstCache = &pVCpu->hm.s.svm.NstGstVmcbCache;
     switch (pSvmTransient->u64ExitCode)
     {
-        //case SVM_EXIT_NPF:
+#if 0
+        case SVM_EXIT_NPF:
         {
             /** @todo. */
             break;
         }
+#endif
+
+        case SVM_EXIT_CPUID:
+        {
+            if (pVmcbNstGstCache->u64InterceptCtrl & SVM_CTRL_INTERCEPT_CPUID)
+                return hmR0SvmExecVmexit(pVCpu, pCtx);
+            return hmR0SvmExitCpuid(pVCpu, pCtx, pSvmTransient);
+        }
+
+        case SVM_EXIT_RDTSC:
+        {
+            if (pVmcbNstGstCache->u64InterceptCtrl & SVM_CTRL_INTERCEPT_RDTSC)
+                return hmR0SvmExecVmexit(pVCpu, pCtx);
+            return hmR0SvmExitRdtsc(pVCpu, pCtx, pSvmTransient);
+        }
+
+        case SVM_EXIT_RDTSCP:
+        {
+            if (pVmcbNstGstCache->u64InterceptCtrl & SVM_CTRL_INTERCEPT_RDTSCP)
+                return hmR0SvmExecVmexit(pVCpu, pCtx);
+            return hmR0SvmExitRdtscp(pVCpu, pCtx, pSvmTransient);
+        }
+
+        case SVM_EXIT_MSR:
+        {
+            if (pVmcbNstGstCache->u64InterceptCtrl & SVM_CTRL_INTERCEPT_MSR_PROT)
+            {
+                uint32_t const idMsr = pCtx->ecx;
+                uint16_t offMsrpm;
+                uint32_t uMsrpmBit;
+                int rc = HMSvmGetMsrpmOffsetAndBit(idMsr, &offMsrpm, &uMsrpmBit);
+                if (RT_SUCCESS(rc))
+                {
+                    void const *pvMsrBitmap = pCtx->hwvirt.svm.CTX_SUFF(pvMsrBitmap);
+                    bool const fInterceptRd = ASMBitTest(pvMsrBitmap, (offMsrpm << 3) + uMsrpmBit);
+                    bool const fInterceptWr = ASMBitTest(pvMsrBitmap, (offMsrpm << 3) + uMsrpmBit + 1);
+
+                    if (   (pVmcbNstGstCtrl->u64ExitInfo1 == SVM_EXIT1_MSR_WRITE && fInterceptWr)
+                        || (pVmcbNstGstCtrl->u64ExitInfo1 == SVM_EXIT1_MSR_READ  && fInterceptRd))
+                    {
+                        return hmR0SvmExecVmexit(pVCpu, pCtx);
+                    }
+                }
+                else
+                {
+                    /*
+                     * MSRs not covered by the MSRPM automatically cause an #VMEXIT.
+                     * See AMD-V spec. "15.11 MSR Intercepts".
+                     */
+                    Assert(rc == VERR_OUT_OF_RANGE);
+                    return hmR0SvmExecVmexit(pVCpu, pCtx);
+                }
+            }
+            return hmR0SvmExitMsr(pVCpu, pCtx, pSvmTransient);
+        }
 
         case SVM_EXIT_IOIO:
         {
             /*
-             * Figure out if the IO port access is intercepted by the nested-guest. If not,
-             * we pass it to the outer guest.
+             * Figure out if the IO port access is intercepted by the nested-guest.
              */
             if (pVmcbNstGstCache->u64InterceptCtrl & SVM_CTRL_INTERCEPT_IOIO_PROT)
@@ -4251,15 +4311,5 @@
         }
 
-        case SVM_EXIT_RDTSC:
-        {
-            return hmR0SvmExitRdtsc(pVCpu, pCtx, pSvmTransient);
-        }
-
-        case SVM_EXIT_RDTSCP:
-            return hmR0SvmExitRdtscp(pVCpu, pCtx, pSvmTransient);
-
-        case SVM_EXIT_CPUID:
-            return hmR0SvmExitCpuid(pVCpu, pCtx, pSvmTransient);
-
+        /** @todo Exceptions. */
         case SVM_EXIT_EXCEPTION_14:  /* X86_XCPT_PF */
             return hmR0SvmExitXcptPF(pVCpu, pCtx, pSvmTransient);
@@ -4316,7 +4366,4 @@
         case SVM_EXIT_NMI:
             return hmR0SvmExitIntr(pVCpu, pCtx, pSvmTransient);
-
-        case SVM_EXIT_MSR:
-            return hmR0SvmExitMsr(pVCpu, pCtx, pSvmTransient);
 
         case SVM_EXIT_INVLPG:
@@ -4367,5 +4414,5 @@
                      * we want to know about it so log the exit code and bail.
                      */
-                    AssertMsgFailed(("hmR0SvmHandleExit: Unexpected exit %#RX32\n", (uint32_t)pSvmTransient->u64ExitCode));
+                    AssertMsgFailed(("hmR0SvmHandleExitNested: Unexpected exit %#RX32\n", (uint32_t)pSvmTransient->u64ExitCode));
                     pVCpu->hm.s.u32HMError = (uint32_t)pSvmTransient->u64ExitCode;
                     return VERR_SVM_UNEXPECTED_EXIT;
@@ -4452,5 +4499,5 @@
 
                         default:
-                            AssertMsgFailed(("hmR0SvmHandleExit: Unexpected exit caused by exception %#x\n", Event.n.u8Vector));
+                            AssertMsgFailed(("hmR0SvmHandleExitNested: Unexpected exit caused by exception %#x\n", Event.n.u8Vector));
                             pVCpu->hm.s.u32HMError = Event.n.u8Vector;
                             return VERR_SVM_UNEXPECTED_XCPT_EXIT;
@@ -4465,5 +4512,5 @@
                 default:
                 {
-                    AssertMsgFailed(("hmR0SvmHandleExit: Unknown exit code %#x\n", pSvmTransient->u64ExitCode));
+                    AssertMsgFailed(("hmR0SvmHandleExitNested: Unknown exit code %#x\n", pSvmTransient->u64ExitCode));
                     pVCpu->hm.s.u32HMError = pSvmTransient->u64ExitCode;
                     return VERR_SVM_UNKNOWN_EXIT;
