aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAvi Kivity <avi@qumranet.com>2008-05-26 13:06:35 -0400
committerAvi Kivity <avi@qumranet.com>2008-07-20 05:42:26 -0400
commit9ba075a664dff836fd6fb93f90fcc827f7683d91 (patch)
treea5d939aa61833525a09fa2f346964c16a80f7957
parent81609e3e26508840a1b51414376f2541dd191483 (diff)
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>
-rw-r--r--arch/x86/kvm/x86.c52
-rw-r--r--include/asm-x86/kvm_host.h3
2 files changed, 51 insertions, 4 deletions
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 05b54976c891..5f67a7c54e82 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -611,6 +611,38 @@ static void kvm_write_guest_time(struct kvm_vcpu *v)
611 mark_page_dirty(v->kvm, vcpu->time >> PAGE_SHIFT); 611 mark_page_dirty(v->kvm, vcpu->time >> PAGE_SHIFT);
612} 612}
613 613
614static bool msr_mtrr_valid(unsigned msr)
615{
616 switch (msr) {
617 case 0x200 ... 0x200 + 2 * KVM_NR_VAR_MTRR - 1:
618 case MSR_MTRRfix64K_00000:
619 case MSR_MTRRfix16K_80000:
620 case MSR_MTRRfix16K_A0000:
621 case MSR_MTRRfix4K_C0000:
622 case MSR_MTRRfix4K_C8000:
623 case MSR_MTRRfix4K_D0000:
624 case MSR_MTRRfix4K_D8000:
625 case MSR_MTRRfix4K_E0000:
626 case MSR_MTRRfix4K_E8000:
627 case MSR_MTRRfix4K_F0000:
628 case MSR_MTRRfix4K_F8000:
629 case MSR_MTRRdefType:
630 case MSR_IA32_CR_PAT:
631 return true;
632 case 0x2f8:
633 return true;
634 }
635 return false;
636}
637
638static int set_msr_mtrr(struct kvm_vcpu *vcpu, u32 msr, u64 data)
639{
640 if (!msr_mtrr_valid(msr))
641 return 1;
642
643 vcpu->arch.mtrr[msr - 0x200] = data;
644 return 0;
645}
614 646
615int kvm_set_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 data) 647int kvm_set_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 data)
616{ 648{
@@ -632,8 +664,9 @@ int kvm_set_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 data)
632 break; 664 break;
633 case MSR_IA32_UCODE_REV: 665 case MSR_IA32_UCODE_REV:
634 case MSR_IA32_UCODE_WRITE: 666 case MSR_IA32_UCODE_WRITE:
635 case 0x200 ... 0x2ff: /* MTRRs */
636 break; 667 break;
668 case 0x200 ... 0x2ff:
669 return set_msr_mtrr(vcpu, msr, data);
637 case MSR_IA32_APICBASE: 670 case MSR_IA32_APICBASE:
638 kvm_set_apic_base(vcpu, data); 671 kvm_set_apic_base(vcpu, data);
639 break; 672 break;
@@ -691,6 +724,15 @@ int kvm_get_msr(struct kvm_vcpu *vcpu, u32 msr_index, u64 *pdata)
691 return kvm_x86_ops->get_msr(vcpu, msr_index, pdata); 724 return kvm_x86_ops->get_msr(vcpu, msr_index, pdata);
692} 725}
693 726
727static int get_msr_mtrr(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata)
728{
729 if (!msr_mtrr_valid(msr))
730 return 1;
731
732 *pdata = vcpu->arch.mtrr[msr - 0x200];
733 return 0;
734}
735
694int kvm_get_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata) 736int kvm_get_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata)
695{ 737{
696 u64 data; 738 u64 data;
@@ -712,11 +754,13 @@ int kvm_get_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata)
712 case MSR_IA32_MC0_MISC+16: 754 case MSR_IA32_MC0_MISC+16:
713 case MSR_IA32_UCODE_REV: 755 case MSR_IA32_UCODE_REV:
714 case MSR_IA32_EBL_CR_POWERON: 756 case MSR_IA32_EBL_CR_POWERON:
715 /* MTRR registers */
716 case 0xfe:
717 case 0x200 ... 0x2ff:
718 data = 0; 757 data = 0;
719 break; 758 break;
759 case MSR_MTRRcap:
760 data = 0x500 | KVM_NR_VAR_MTRR;
761 break;
762 case 0x200 ... 0x2ff:
763 return get_msr_mtrr(vcpu, msr, pdata);
720 case 0xcd: /* fsb frequency */ 764 case 0xcd: /* fsb frequency */
721 data = 3; 765 data = 3;
722 break; 766 break;
diff --git a/include/asm-x86/kvm_host.h b/include/asm-x86/kvm_host.h
index 075598b4e3f3..fc72bad878ed 100644
--- a/include/asm-x86/kvm_host.h
+++ b/include/asm-x86/kvm_host.h
@@ -79,6 +79,7 @@
79#define KVM_MIN_FREE_MMU_PAGES 5 79#define KVM_MIN_FREE_MMU_PAGES 5
80#define KVM_REFILL_PAGES 25 80#define KVM_REFILL_PAGES 25
81#define KVM_MAX_CPUID_ENTRIES 40 81#define KVM_MAX_CPUID_ENTRIES 40
82#define KVM_NR_VAR_MTRR 8
82 83
83extern spinlock_t kvm_lock; 84extern spinlock_t kvm_lock;
84extern struct list_head vm_list; 85extern struct list_head vm_list;
@@ -290,6 +291,8 @@ struct kvm_vcpu_arch {
290 struct page *time_page; 291 struct page *time_page;
291 292
292 bool nmi_pending; 293 bool nmi_pending;
294
295 u64 mtrr[0x100];
293}; 296};
294 297
295struct kvm_mem_alias { 298struct kvm_mem_alias {