diff options
-rw-r--r-- | drivers/kvm/vmx.c | 50 |
1 files changed, 46 insertions, 4 deletions
diff --git a/drivers/kvm/vmx.c b/drivers/kvm/vmx.c index c1ac106ace8c..52bd5f079df1 100644 --- a/drivers/kvm/vmx.c +++ b/drivers/kvm/vmx.c | |||
@@ -34,6 +34,9 @@ MODULE_LICENSE("GPL"); | |||
34 | static DEFINE_PER_CPU(struct vmcs *, vmxarea); | 34 | static DEFINE_PER_CPU(struct vmcs *, vmxarea); |
35 | static DEFINE_PER_CPU(struct vmcs *, current_vmcs); | 35 | static DEFINE_PER_CPU(struct vmcs *, current_vmcs); |
36 | 36 | ||
37 | static struct page *vmx_io_bitmap_a; | ||
38 | static struct page *vmx_io_bitmap_b; | ||
39 | |||
37 | #ifdef CONFIG_X86_64 | 40 | #ifdef CONFIG_X86_64 |
38 | #define HOST_IS_64 1 | 41 | #define HOST_IS_64 1 |
39 | #else | 42 | #else |
@@ -1129,8 +1132,8 @@ static int vmx_vcpu_setup(struct kvm_vcpu *vcpu) | |||
1129 | vmcs_write32(GUEST_PENDING_DBG_EXCEPTIONS, 0); | 1132 | vmcs_write32(GUEST_PENDING_DBG_EXCEPTIONS, 0); |
1130 | 1133 | ||
1131 | /* I/O */ | 1134 | /* I/O */ |
1132 | vmcs_write64(IO_BITMAP_A, 0); | 1135 | vmcs_write64(IO_BITMAP_A, page_to_phys(vmx_io_bitmap_a)); |
1133 | vmcs_write64(IO_BITMAP_B, 0); | 1136 | vmcs_write64(IO_BITMAP_B, page_to_phys(vmx_io_bitmap_b)); |
1134 | 1137 | ||
1135 | guest_write_tsc(0); | 1138 | guest_write_tsc(0); |
1136 | 1139 | ||
@@ -1150,7 +1153,7 @@ static int vmx_vcpu_setup(struct kvm_vcpu *vcpu) | |||
1150 | CPU_BASED_HLT_EXITING /* 20.6.2 */ | 1153 | CPU_BASED_HLT_EXITING /* 20.6.2 */ |
1151 | | CPU_BASED_CR8_LOAD_EXITING /* 20.6.2 */ | 1154 | | CPU_BASED_CR8_LOAD_EXITING /* 20.6.2 */ |
1152 | | CPU_BASED_CR8_STORE_EXITING /* 20.6.2 */ | 1155 | | CPU_BASED_CR8_STORE_EXITING /* 20.6.2 */ |
1153 | | CPU_BASED_UNCOND_IO_EXITING /* 20.6.2 */ | 1156 | | CPU_BASED_ACTIVATE_IO_BITMAP /* 20.6.2 */ |
1154 | | CPU_BASED_MOV_DR_EXITING | 1157 | | CPU_BASED_MOV_DR_EXITING |
1155 | | CPU_BASED_USE_TSC_OFFSETING /* 21.3 */ | 1158 | | CPU_BASED_USE_TSC_OFFSETING /* 21.3 */ |
1156 | ); | 1159 | ); |
@@ -2188,11 +2191,50 @@ static struct kvm_arch_ops vmx_arch_ops = { | |||
2188 | 2191 | ||
2189 | static int __init vmx_init(void) | 2192 | static int __init vmx_init(void) |
2190 | { | 2193 | { |
2191 | return kvm_init_arch(&vmx_arch_ops, THIS_MODULE); | 2194 | void *iova; |
2195 | int r; | ||
2196 | |||
2197 | vmx_io_bitmap_a = alloc_page(GFP_KERNEL | __GFP_HIGHMEM); | ||
2198 | if (!vmx_io_bitmap_a) | ||
2199 | return -ENOMEM; | ||
2200 | |||
2201 | vmx_io_bitmap_b = alloc_page(GFP_KERNEL | __GFP_HIGHMEM); | ||
2202 | if (!vmx_io_bitmap_b) { | ||
2203 | r = -ENOMEM; | ||
2204 | goto out; | ||
2205 | } | ||
2206 | |||
2207 | /* | ||
2208 | * Allow direct access to the PC debug port (it is often used for I/O | ||
2209 | * delays, but the vmexits simply slow things down). | ||
2210 | */ | ||
2211 | iova = kmap(vmx_io_bitmap_a); | ||
2212 | memset(iova, 0xff, PAGE_SIZE); | ||
2213 | clear_bit(0x80, iova); | ||
2214 | kunmap(iova); | ||
2215 | |||
2216 | iova = kmap(vmx_io_bitmap_b); | ||
2217 | memset(iova, 0xff, PAGE_SIZE); | ||
2218 | kunmap(iova); | ||
2219 | |||
2220 | r = kvm_init_arch(&vmx_arch_ops, THIS_MODULE); | ||
2221 | if (r) | ||
2222 | goto out1; | ||
2223 | |||
2224 | return 0; | ||
2225 | |||
2226 | out1: | ||
2227 | __free_page(vmx_io_bitmap_b); | ||
2228 | out: | ||
2229 | __free_page(vmx_io_bitmap_a); | ||
2230 | return r; | ||
2192 | } | 2231 | } |
2193 | 2232 | ||
2194 | static void __exit vmx_exit(void) | 2233 | static void __exit vmx_exit(void) |
2195 | { | 2234 | { |
2235 | __free_page(vmx_io_bitmap_b); | ||
2236 | __free_page(vmx_io_bitmap_a); | ||
2237 | |||
2196 | kvm_exit_arch(); | 2238 | kvm_exit_arch(); |
2197 | } | 2239 | } |
2198 | 2240 | ||