diff options
author | Avi Kivity <avi@redhat.com> | 2009-02-24 14:46:19 -0500 |
---|---|---|
committer | Avi Kivity <avi@redhat.com> | 2009-06-10 04:48:21 -0400 |
commit | 3e7c73e9b15eab73e9cf72daf3931925da8afcff (patch) | |
tree | ab78f31bfc210c5966f7e93dcfbb8d1f0d1503d9 /arch/x86 | |
parent | 07a2039b8eb0af4ff464efd3dfd95de5c02648c6 (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.c | 59 |
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); | |||
111 | static DEFINE_PER_CPU(struct vmcs *, current_vmcs); | 111 | static DEFINE_PER_CPU(struct vmcs *, current_vmcs); |
112 | static DEFINE_PER_CPU(struct list_head, vcpus_on_cpu); | 112 | static DEFINE_PER_CPU(struct list_head, vcpus_on_cpu); |
113 | 113 | ||
114 | static struct page *vmx_io_bitmap_a; | 114 | static unsigned long *vmx_io_bitmap_a; |
115 | static struct page *vmx_io_bitmap_b; | 115 | static unsigned long *vmx_io_bitmap_b; |
116 | static struct page *vmx_msr_bitmap; | 116 | static unsigned long *vmx_msr_bitmap; |
117 | 117 | ||
118 | static DECLARE_BITMAP(vmx_vpid_bitmap, VMX_NR_VPIDS); | 118 | static DECLARE_BITMAP(vmx_vpid_bitmap, VMX_NR_VPIDS); |
119 | static DEFINE_SPINLOCK(vmx_vpid_lock); | 119 | static 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 | ||
2085 | static void vmx_disable_intercept_for_msr(struct page *msr_bitmap, u32 msr) | 2085 | static 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 | ||
3696 | static int __init vmx_init(void) | 3694 | static 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 | ||
3764 | out2: | 3755 | out2: |
3765 | __free_page(vmx_msr_bitmap); | 3756 | free_page((unsigned long)vmx_msr_bitmap); |
3766 | out1: | 3757 | out1: |
3767 | __free_page(vmx_io_bitmap_b); | 3758 | free_page((unsigned long)vmx_io_bitmap_b); |
3768 | out: | 3759 | out: |
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 | ||
3773 | static void __exit vmx_exit(void) | 3764 | static 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 | } |