|
@@ -611,6 +611,38 @@ static void kvm_write_guest_time(struct kvm_vcpu *v)
|
|
|
mark_page_dirty(v->kvm, vcpu->time >> PAGE_SHIFT);
|
|
|
}
|
|
|
|
|
|
+static bool msr_mtrr_valid(unsigned msr)
|
|
|
+{
|
|
|
+ switch (msr) {
|
|
|
+ case 0x200 ... 0x200 + 2 * KVM_NR_VAR_MTRR - 1:
|
|
|
+ case MSR_MTRRfix64K_00000:
|
|
|
+ case MSR_MTRRfix16K_80000:
|
|
|
+ case MSR_MTRRfix16K_A0000:
|
|
|
+ case MSR_MTRRfix4K_C0000:
|
|
|
+ case MSR_MTRRfix4K_C8000:
|
|
|
+ case MSR_MTRRfix4K_D0000:
|
|
|
+ case MSR_MTRRfix4K_D8000:
|
|
|
+ case MSR_MTRRfix4K_E0000:
|
|
|
+ case MSR_MTRRfix4K_E8000:
|
|
|
+ case MSR_MTRRfix4K_F0000:
|
|
|
+ case MSR_MTRRfix4K_F8000:
|
|
|
+ case MSR_MTRRdefType:
|
|
|
+ case MSR_IA32_CR_PAT:
|
|
|
+ return true;
|
|
|
+ case 0x2f8:
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ return false;
|
|
|
+}
|
|
|
+
|
|
|
+static int set_msr_mtrr(struct kvm_vcpu *vcpu, u32 msr, u64 data)
|
|
|
+{
|
|
|
+ if (!msr_mtrr_valid(msr))
|
|
|
+ return 1;
|
|
|
+
|
|
|
+ vcpu->arch.mtrr[msr - 0x200] = data;
|
|
|
+ return 0;
|
|
|
+}
|
|
|
|
|
|
int kvm_set_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 data)
|
|
|
{
|
|
@@ -632,8 +664,9 @@ int kvm_set_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 data)
|
|
|
break;
|
|
|
case MSR_IA32_UCODE_REV:
|
|
|
case MSR_IA32_UCODE_WRITE:
|
|
|
- case 0x200 ... 0x2ff: /* MTRRs */
|
|
|
break;
|
|
|
+ case 0x200 ... 0x2ff:
|
|
|
+ return set_msr_mtrr(vcpu, msr, data);
|
|
|
case MSR_IA32_APICBASE:
|
|
|
kvm_set_apic_base(vcpu, data);
|
|
|
break;
|
|
@@ -691,6 +724,15 @@ int kvm_get_msr(struct kvm_vcpu *vcpu, u32 msr_index, u64 *pdata)
|
|
|
return kvm_x86_ops->get_msr(vcpu, msr_index, pdata);
|
|
|
}
|
|
|
|
|
|
+static int get_msr_mtrr(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata)
|
|
|
+{
|
|
|
+ if (!msr_mtrr_valid(msr))
|
|
|
+ return 1;
|
|
|
+
|
|
|
+ *pdata = vcpu->arch.mtrr[msr - 0x200];
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
int kvm_get_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata)
|
|
|
{
|
|
|
u64 data;
|
|
@@ -712,11 +754,13 @@ int kvm_get_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata)
|
|
|
case MSR_IA32_MC0_MISC+16:
|
|
|
case MSR_IA32_UCODE_REV:
|
|
|
case MSR_IA32_EBL_CR_POWERON:
|
|
|
- /* MTRR registers */
|
|
|
- case 0xfe:
|
|
|
- case 0x200 ... 0x2ff:
|
|
|
data = 0;
|
|
|
break;
|
|
|
+ case MSR_MTRRcap:
|
|
|
+ data = 0x500 | KVM_NR_VAR_MTRR;
|
|
|
+ break;
|
|
|
+ case 0x200 ... 0x2ff:
|
|
|
+ return get_msr_mtrr(vcpu, msr, pdata);
|
|
|
case 0xcd: /* fsb frequency */
|
|
|
data = 3;
|
|
|
break;
|