mirror of
https://github.com/torvalds/linux
synced 2024-11-05 18:23:50 +00:00
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
2 changed files with 51 additions and 4 deletions
|
@ -611,6 +611,38 @@ static void kvm_write_guest_time(struct kvm_vcpu *v)
|
||||||
mark_page_dirty(v->kvm, vcpu->time >> PAGE_SHIFT);
|
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)
|
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;
|
break;
|
||||||
case MSR_IA32_UCODE_REV:
|
case MSR_IA32_UCODE_REV:
|
||||||
case MSR_IA32_UCODE_WRITE:
|
case MSR_IA32_UCODE_WRITE:
|
||||||
case 0x200 ... 0x2ff: /* MTRRs */
|
|
||||||
break;
|
break;
|
||||||
|
case 0x200 ... 0x2ff:
|
||||||
|
return set_msr_mtrr(vcpu, msr, data);
|
||||||
case MSR_IA32_APICBASE:
|
case MSR_IA32_APICBASE:
|
||||||
kvm_set_apic_base(vcpu, data);
|
kvm_set_apic_base(vcpu, data);
|
||||||
break;
|
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);
|
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)
|
int kvm_get_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata)
|
||||||
{
|
{
|
||||||
u64 data;
|
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_MC0_MISC+16:
|
||||||
case MSR_IA32_UCODE_REV:
|
case MSR_IA32_UCODE_REV:
|
||||||
case MSR_IA32_EBL_CR_POWERON:
|
case MSR_IA32_EBL_CR_POWERON:
|
||||||
/* MTRR registers */
|
|
||||||
case 0xfe:
|
|
||||||
case 0x200 ... 0x2ff:
|
|
||||||
data = 0;
|
data = 0;
|
||||||
break;
|
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 */
|
case 0xcd: /* fsb frequency */
|
||||||
data = 3;
|
data = 3;
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -79,6 +79,7 @@
|
||||||
#define KVM_MIN_FREE_MMU_PAGES 5
|
#define KVM_MIN_FREE_MMU_PAGES 5
|
||||||
#define KVM_REFILL_PAGES 25
|
#define KVM_REFILL_PAGES 25
|
||||||
#define KVM_MAX_CPUID_ENTRIES 40
|
#define KVM_MAX_CPUID_ENTRIES 40
|
||||||
|
#define KVM_NR_VAR_MTRR 8
|
||||||
|
|
||||||
extern spinlock_t kvm_lock;
|
extern spinlock_t kvm_lock;
|
||||||
extern struct list_head vm_list;
|
extern struct list_head vm_list;
|
||||||
|
@ -290,6 +291,8 @@ struct kvm_vcpu_arch {
|
||||||
struct page *time_page;
|
struct page *time_page;
|
||||||
|
|
||||||
bool nmi_pending;
|
bool nmi_pending;
|
||||||
|
|
||||||
|
u64 mtrr[0x100];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct kvm_mem_alias {
|
struct kvm_mem_alias {
|
||||||
|
|
Loading…
Reference in a new issue