KVM: x86: handle guest access to BBL_CR_CTL3 MSR
authorjohn cooper <john.cooper@redhat.com>
Fri, 21 Jan 2011 05:21:00 +0000 (00:21 -0500)
committerMarcelo Tosatti <mtosatti@redhat.com>
Thu, 17 Mar 2011 16:08:27 +0000 (13:08 -0300)
A correction to Intel cpu model CPUID data (patch queued)
caused winxp to BSOD when booted with a Penryn model.
This was traced to the CPUID "model" field correction from
6 -> 23 (as is proper for a Penryn class of cpu).  Only in
this case does the problem surface.

The cause for this failure is winxp accessing the BBL_CR_CTL3
MSR which is unsupported by current kvm, appears to be a
legacy MSR not fully characterized yet existing in current
silicon, and is apparently carried forward in MSR space to
accommodate vintage code as here.  It is not yet conclusive
whether this MSR implements any of its legacy functionality
or is just an ornamental dud for compatibility.  While I
found no silicon version specific documentation link to
this MSR, a general description exists in Intel's developer's
reference which agrees with the functional behavior of
other bootloader/kernel code I've examined accessing
BBL_CR_CTL3.  Regrettably winxp appears to be setting bit #19
called out as "reserved" in the above document.

So to minimally accommodate this MSR, kvm msr get will provide
the equivalent mock data and kvm msr write will simply toss the
guest passed data without interpretation.  While this treatment
of BBL_CR_CTL3 addresses the immediate problem, the approach may
be modified pending clarification from Intel.

Signed-off-by: john cooper <john.cooper@redhat.com>
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
arch/x86/include/asm/msr-index.h
arch/x86/kvm/x86.c

index 823d482234008790894f75fe384f0b677d2b701c..fd5a1f365c95105ebe095c33df1dfbf91e1715a1 100644 (file)
@@ -43,6 +43,7 @@
 
 #define MSR_MTRRcap                    0x000000fe
 #define MSR_IA32_BBL_CR_CTL            0x00000119
+#define MSR_IA32_BBL_CR_CTL3           0x0000011e
 
 #define MSR_IA32_SYSENTER_CS           0x00000174
 #define MSR_IA32_SYSENTER_ESP          0x00000175
index a7f65aa6eef6a860dcde9e13d90ce4c387f6754f..7faf262ab2021294e722d615dc864bbec3fe6121 100644 (file)
@@ -1592,6 +1592,12 @@ int kvm_set_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 data)
                } else
                        return set_msr_hyperv(vcpu, msr, data);
                break;
+       case MSR_IA32_BBL_CR_CTL3:
+               /* Drop writes to this legacy MSR -- see rdmsr
+                * counterpart for further detail.
+                */
+               pr_unimpl(vcpu, "ignored wrmsr: 0x%x data %llx\n", msr, data);
+               break;
        default:
                if (msr && (msr == vcpu->kvm->arch.xen_hvm_config.msr))
                        return xen_hvm_config(vcpu, data);
@@ -1846,6 +1852,19 @@ int kvm_get_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata)
                } else
                        return get_msr_hyperv(vcpu, msr, pdata);
                break;
+       case MSR_IA32_BBL_CR_CTL3:
+               /* This legacy MSR exists but isn't fully documented in current
+                * silicon.  It is however accessed by winxp in very narrow
+                * scenarios where it sets bit #19, itself documented as
+                * a "reserved" bit.  Best effort attempt to source coherent
+                * read data here should the balance of the register be
+                * interpreted by the guest:
+                *
+                * L2 cache control register 3: 64GB range, 256KB size,
+                * enabled, latency 0x1, configured
+                */
+               data = 0xbe702111;
+               break;
        default:
                if (!ignore_msrs) {
                        pr_unimpl(vcpu, "unhandled rdmsr: 0x%x\n", msr);