mirror of https://gitee.com/openkylin/linux.git
KVM: MTRR support
Add emulation for the memory type range registers, needed by VMware esx 3.5, and by pci device assignment. Signed-off-by: Avi Kivity <avi@qumranet.com>
This commit is contained in:
parent
81609e3e26
commit
9ba075a664
|
@ -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;
|
||||
|
|
|
@ -79,6 +79,7 @@
|
|||
#define KVM_MIN_FREE_MMU_PAGES 5
|
||||
#define KVM_REFILL_PAGES 25
|
||||
#define KVM_MAX_CPUID_ENTRIES 40
|
||||
#define KVM_NR_VAR_MTRR 8
|
||||
|
||||
extern spinlock_t kvm_lock;
|
||||
extern struct list_head vm_list;
|
||||
|
@ -290,6 +291,8 @@ struct kvm_vcpu_arch {
|
|||
struct page *time_page;
|
||||
|
||||
bool nmi_pending;
|
||||
|
||||
u64 mtrr[0x100];
|
||||
};
|
||||
|
||||
struct kvm_mem_alias {
|
||||
|
|
Loading…
Reference in New Issue