aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorHe, Qing <qing.he@intel.com>2007-04-30 02:45:24 -0400
committerAvi Kivity <avi@qumranet.com>2007-07-16 05:05:37 -0400
commitfdef3ad1b38660d74a29abc990940b5dbaaf3fc9 (patch)
tree374039f92105e432f68ec233bce7b92a049c5a7c /drivers
parent8f41958bdd577731f7411c9605cfaa9db6766809 (diff)
KVM: VMX: Enable io bitmaps to avoid IO port 0x80 VMEXITs
This patch enables IO bitmaps control on vmx and unmask the 0x80 port to avoid VMEXITs caused by accessing port 0x80. 0x80 is used as delays (see include/asm/io.h), and handling VMEXITs on its access is unnecessary but slows things down. This patch improves kernel build test at around 3%~5%. Because every VM uses the same io bitmap, it is shared between all VMs rather than a per-VM data structure. Signed-off-by: Qing He <qing.he@intel.com> Signed-off-by: Avi Kivity <avi@qumranet.com>
Diffstat (limited to 'drivers')
-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