aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86
diff options
context:
space:
mode:
authorAvi Kivity <avi@redhat.com>2009-02-24 14:46:19 -0500
committerAvi Kivity <avi@redhat.com>2009-06-10 04:48:21 -0400
commit3e7c73e9b15eab73e9cf72daf3931925da8afcff (patch)
treeab78f31bfc210c5966f7e93dcfbb8d1f0d1503d9 /arch/x86
parent07a2039b8eb0af4ff464efd3dfd95de5c02648c6 (diff)
KVM: VMX: Don't use highmem pages for the msr and pio bitmaps
Highmem pages are a pain, and saving three lowmem pages on i386 isn't worth the extra code. Signed-off-by: Avi Kivity <avi@redhat.com>
Diffstat (limited to 'arch/x86')
-rw-r--r--arch/x86/kvm/vmx.c59
1 files changed, 25 insertions, 34 deletions
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
index bb481330716f..b20c9e47e925 100644
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -111,9 +111,9 @@ static DEFINE_PER_CPU(struct vmcs *, vmxarea);
111static DEFINE_PER_CPU(struct vmcs *, current_vmcs); 111static DEFINE_PER_CPU(struct vmcs *, current_vmcs);
112static DEFINE_PER_CPU(struct list_head, vcpus_on_cpu); 112static DEFINE_PER_CPU(struct list_head, vcpus_on_cpu);
113 113
114static struct page *vmx_io_bitmap_a; 114static unsigned long *vmx_io_bitmap_a;
115static struct page *vmx_io_bitmap_b; 115static unsigned long *vmx_io_bitmap_b;
116static struct page *vmx_msr_bitmap; 116static unsigned long *vmx_msr_bitmap;
117 117
118static DECLARE_BITMAP(vmx_vpid_bitmap, VMX_NR_VPIDS); 118static DECLARE_BITMAP(vmx_vpid_bitmap, VMX_NR_VPIDS);
119static DEFINE_SPINLOCK(vmx_vpid_lock); 119static DEFINE_SPINLOCK(vmx_vpid_lock);
@@ -2082,9 +2082,9 @@ static void allocate_vpid(struct vcpu_vmx *vmx)
2082 spin_unlock(&vmx_vpid_lock); 2082 spin_unlock(&vmx_vpid_lock);
2083} 2083}
2084 2084
2085static void vmx_disable_intercept_for_msr(struct page *msr_bitmap, u32 msr) 2085static void vmx_disable_intercept_for_msr(unsigned long *msr_bitmap, u32 msr)
2086{ 2086{
2087 void *va; 2087 int f = sizeof(unsigned long);
2088 2088
2089 if (!cpu_has_vmx_msr_bitmap()) 2089 if (!cpu_has_vmx_msr_bitmap())
2090 return; 2090 return;
@@ -2094,16 +2094,14 @@ static void vmx_disable_intercept_for_msr(struct page *msr_bitmap, u32 msr)
2094 * have the write-low and read-high bitmap offsets the wrong way round. 2094 * have the write-low and read-high bitmap offsets the wrong way round.
2095 * We can control MSRs 0x00000000-0x00001fff and 0xc0000000-0xc0001fff. 2095 * We can control MSRs 0x00000000-0x00001fff and 0xc0000000-0xc0001fff.
2096 */ 2096 */
2097 va = kmap(msr_bitmap);
2098 if (msr <= 0x1fff) { 2097 if (msr <= 0x1fff) {
2099 __clear_bit(msr, va + 0x000); /* read-low */ 2098 __clear_bit(msr, msr_bitmap + 0x000 / f); /* read-low */
2100 __clear_bit(msr, va + 0x800); /* write-low */ 2099 __clear_bit(msr, msr_bitmap + 0x800 / f); /* write-low */
2101 } else if ((msr >= 0xc0000000) && (msr <= 0xc0001fff)) { 2100 } else if ((msr >= 0xc0000000) && (msr <= 0xc0001fff)) {
2102 msr &= 0x1fff; 2101 msr &= 0x1fff;
2103 __clear_bit(msr, va + 0x400); /* read-high */ 2102 __clear_bit(msr, msr_bitmap + 0x400 / f); /* read-high */
2104 __clear_bit(msr, va + 0xc00); /* write-high */ 2103 __clear_bit(msr, msr_bitmap + 0xc00 / f); /* write-high */
2105 } 2104 }
2106 kunmap(msr_bitmap);
2107} 2105}
2108 2106
2109/* 2107/*
@@ -2121,11 +2119,11 @@ static int vmx_vcpu_setup(struct vcpu_vmx *vmx)
2121 u32 exec_control; 2119 u32 exec_control;
2122 2120
2123 /* I/O */ 2121 /* I/O */
2124 vmcs_write64(IO_BITMAP_A, page_to_phys(vmx_io_bitmap_a)); 2122 vmcs_write64(IO_BITMAP_A, __pa(vmx_io_bitmap_a));
2125 vmcs_write64(IO_BITMAP_B, page_to_phys(vmx_io_bitmap_b)); 2123 vmcs_write64(IO_BITMAP_B, __pa(vmx_io_bitmap_b));
2126 2124
2127 if (cpu_has_vmx_msr_bitmap()) 2125 if (cpu_has_vmx_msr_bitmap())
2128 vmcs_write64(MSR_BITMAP, page_to_phys(vmx_msr_bitmap)); 2126 vmcs_write64(MSR_BITMAP, __pa(vmx_msr_bitmap));
2129 2127
2130 vmcs_write64(VMCS_LINK_POINTER, -1ull); /* 22.3.1.5 */ 2128 vmcs_write64(VMCS_LINK_POINTER, -1ull); /* 22.3.1.5 */
2131 2129
@@ -3695,20 +3693,19 @@ static struct kvm_x86_ops vmx_x86_ops = {
3695 3693
3696static int __init vmx_init(void) 3694static int __init vmx_init(void)
3697{ 3695{
3698 void *va;
3699 int r; 3696 int r;
3700 3697
3701 vmx_io_bitmap_a = alloc_page(GFP_KERNEL | __GFP_HIGHMEM); 3698 vmx_io_bitmap_a = (unsigned long *)__get_free_page(GFP_KERNEL);
3702 if (!vmx_io_bitmap_a) 3699 if (!vmx_io_bitmap_a)
3703 return -ENOMEM; 3700 return -ENOMEM;
3704 3701
3705 vmx_io_bitmap_b = alloc_page(GFP_KERNEL | __GFP_HIGHMEM); 3702 vmx_io_bitmap_b = (unsigned long *)__get_free_page(GFP_KERNEL);
3706 if (!vmx_io_bitmap_b) { 3703 if (!vmx_io_bitmap_b) {
3707 r = -ENOMEM; 3704 r = -ENOMEM;
3708 goto out; 3705 goto out;
3709 } 3706 }
3710 3707
3711 vmx_msr_bitmap = alloc_page(GFP_KERNEL | __GFP_HIGHMEM); 3708 vmx_msr_bitmap = (unsigned long *)__get_free_page(GFP_KERNEL);
3712 if (!vmx_msr_bitmap) { 3709 if (!vmx_msr_bitmap) {
3713 r = -ENOMEM; 3710 r = -ENOMEM;
3714 goto out1; 3711 goto out1;
@@ -3718,18 +3715,12 @@ static int __init vmx_init(void)
3718 * Allow direct access to the PC debug port (it is often used for I/O 3715 * Allow direct access to the PC debug port (it is often used for I/O
3719 * delays, but the vmexits simply slow things down). 3716 * delays, but the vmexits simply slow things down).
3720 */ 3717 */
3721 va = kmap(vmx_io_bitmap_a); 3718 memset(vmx_io_bitmap_a, 0xff, PAGE_SIZE);
3722 memset(va, 0xff, PAGE_SIZE); 3719 clear_bit(0x80, vmx_io_bitmap_a);
3723 clear_bit(0x80, va);
3724 kunmap(vmx_io_bitmap_a);
3725 3720
3726 va = kmap(vmx_io_bitmap_b); 3721 memset(vmx_io_bitmap_b, 0xff, PAGE_SIZE);
3727 memset(va, 0xff, PAGE_SIZE);
3728 kunmap(vmx_io_bitmap_b);
3729 3722
3730 va = kmap(vmx_msr_bitmap); 3723 memset(vmx_msr_bitmap, 0xff, PAGE_SIZE);
3731 memset(va, 0xff, PAGE_SIZE);
3732 kunmap(vmx_msr_bitmap);
3733 3724
3734 set_bit(0, vmx_vpid_bitmap); /* 0 is reserved for host */ 3725 set_bit(0, vmx_vpid_bitmap); /* 0 is reserved for host */
3735 3726
@@ -3762,19 +3753,19 @@ static int __init vmx_init(void)
3762 return 0; 3753 return 0;
3763 3754
3764out2: 3755out2:
3765 __free_page(vmx_msr_bitmap); 3756 free_page((unsigned long)vmx_msr_bitmap);
3766out1: 3757out1:
3767 __free_page(vmx_io_bitmap_b); 3758 free_page((unsigned long)vmx_io_bitmap_b);
3768out: 3759out:
3769 __free_page(vmx_io_bitmap_a); 3760 free_page((unsigned long)vmx_io_bitmap_a);
3770 return r; 3761 return r;
3771} 3762}
3772 3763
3773static void __exit vmx_exit(void) 3764static void __exit vmx_exit(void)
3774{ 3765{
3775 __free_page(vmx_msr_bitmap); 3766 free_page((unsigned long)vmx_msr_bitmap);
3776 __free_page(vmx_io_bitmap_b); 3767 free_page((unsigned long)vmx_io_bitmap_b);
3777 __free_page(vmx_io_bitmap_a); 3768 free_page((unsigned long)vmx_io_bitmap_a);
3778 3769
3779 kvm_exit(); 3770 kvm_exit();
3780} 3771}