aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/kvm/vmx.c50
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");
34static DEFINE_PER_CPU(struct vmcs *, vmxarea); 34static DEFINE_PER_CPU(struct vmcs *, vmxarea);
35static DEFINE_PER_CPU(struct vmcs *, current_vmcs); 35static DEFINE_PER_CPU(struct vmcs *, current_vmcs);
36 36
37static struct page *vmx_io_bitmap_a;
38static 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
2189static int __init vmx_init(void) 2192static 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
2226out1:
2227 __free_page(vmx_io_bitmap_b);
2228out:
2229 __free_page(vmx_io_bitmap_a);
2230 return r;
2192} 2231}
2193 2232
2194static void __exit vmx_exit(void) 2233static 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