Skip to contentSkip to conversation

Limit MCG Cap

PATCH New Ben Guthro 1 participant 1 message Aug 27, 2007

lore
Share & tools
lore

Ben Guthro

author
#0 lore raw

PATCH 1/1 Limit MCG Cap

Intercept guest reads of MSR_IA32_MCG_CAP and limit the number of memory banks reported to one. This prevents us from trying to read status of non-existent banks when migrated to a machine with fewer banks.

Signed-off-by Ben Guthro
xen/arch/x86/hvm/svm/svm.c +13 -1
diff -r 4eea7c9b3bf2 xen/arch/x86/hvm/svm/svm.c
@@ -2162,7 +2162,19 @@ static void svm_do_msr_access(
             /* No point in letting the guest see real MCEs */
             msr_content = 0;
             break;
-
+        case MSR_IA32_MCG_CAP:
+            if ( rdmsr_safe(ecx, regs->eax, regs->edx) == 0 ) {
+                /*
+                 * Report at most one memory bank so migration to a machine with
+                 * fewer banks doesn't cause guest GPFs when the guest tries to read the
+                 * (now, after migration) non-existent banks' MSRs.
+                 */
+                regs->eax = (regs->eax & ~0xFF) | !!(regs->eax & 0xFF);
+                goto done;
+            }
+            gdprintk(XENLOG_ERR, "%s: rdmsr_safe(MCG_CAP) failed!\n", __FUNCTION__);
+            svm_inject_exception(v, TRAP_gp_fault, 1, 0);
+            return;
         default:
             if ( rdmsr_hypervisor_regs(ecx, &eax, &edx) ||
                  rdmsr_safe(ecx, eax, edx) == 0 )
xen/arch/x86/hvm/vmx/vmx.c +13 -0
diff -r 4eea7c9b3bf2 xen/arch/x86/hvm/vmx/vmx.c
@@ -2754,6 +2754,19 @@ static int vmx_do_msr_read(struct cpu_us
         /* No point in letting the guest see real MCEs */
         msr_content = 0;
         break;
+    case MSR_IA32_MCG_CAP:
+        if ( rdmsr_safe(ecx, regs->eax, regs->edx) == 0 ) {
+            /*
+             * Report only a single memory bank so migration to a machine with
+             * fewer banks doesn't cause guest GPFs when the guest tries to read the
+             * (now, after migration) non-existent banks' MSRs.
+             */
+            regs->eax = (regs->eax & ~0xFF) | !!(regs->eax & 0xFF);
+            goto done;
+        }
+        gdprintk(XENLOG_ERR, "%s: rdmsr_safe(MCG_CAP) failed!\n", __FUNCTION__);
+        vmx_inject_hw_exception(v, TRAP_gp_fault, 0);
+        return 0;
     default:
         switch ( long_mode_do_msr_read(regs) )
         {

_______________________________________________
Xen-devel mailing list
[email protected]
http://lists.xensource.com/xen-devel