Add MSR Bitmap support in VMX so that some execution of RDMSR or WRMSR won't cause a VM exit.
Signed-off-by: Sheng Yang <[EMAIL PROTECTED]>
Signed-off-by: Qing He <[EMAIL PROTECTED]>
---
drivers/kvm/vmx.c | 44 +++++++++++++++++++++++++++++++++++++++++++-
drivers/kvm/vmx.h | 3 +++
2 files changed, 46 insertions(+), 1 deletions(-)
diff --git a/drivers/kvm/vmx.c b/drivers/kvm/vmx.c
index 3b901fe..bebe0d4 100644
--- a/drivers/kvm/vmx.c
+++ b/drivers/kvm/vmx.c
@@ -71,6 +71,7 @@ static DEFINE_PER_CPU(struct vmcs *, current_vmcs);
static struct page *vmx_io_bitmap_a;
static struct page *vmx_io_bitmap_b;
+static struct page *vmx_msr_bitmap;
#define EFER_SAVE_RESTORE_BITS ((u64)EFER_SCE)
@@ -867,7 +868,7 @@ static __init int setup_vmcs_config(struct
vmcs_config *vmcs_conf)
CPU_BASED_USE_IO_BITMAPS |
CPU_BASED_MOV_DR_EXITING |
CPU_BASED_USE_TSC_OFFSETING;
- opt = 0;
+ opt = CPU_BASED_USE_MSR_BITMAPS;
if (adjust_vmx_controls(min, opt, MSR_IA32_VMX_PROCBASED_CTLS,
&_cpu_based_exec_control) < 0)
return -EIO;
@@ -1426,6 +1427,10 @@ static int vmx_vcpu_setup(struct vcpu_vmx *vmx)
vmcs_write64(IO_BITMAP_A, page_to_phys(vmx_io_bitmap_a));
vmcs_write64(IO_BITMAP_B, page_to_phys(vmx_io_bitmap_b));
+ /* MSR bitmap */
+ if (cpu_has_vmx_msr_bitmap)
+ vmcs_write64(MSR_BITMAP, page_to_phys(vmx_msr_bitmap));
+
guest_write_tsc(0);
vmcs_write64(VMCS_LINK_POINTER, -1ull); /* 22.3.1.5 */
@@ -2424,6 +2429,19 @@ static void __init
vmx_check_processor_compat(void *rtn)
}
}
+static void __init disable_intercept_for_msr(u32 msr, void
*msr_bitmap_va)
+{
+ /* See Intel PRM Vol. 3, 20.6.9 (MSR-Bitmap Address). */
+ if (msr <= 0x1fff) { /* read and write bitmaps for low MSRs */
+ __clear_bit(msr, msr_bitmap_va + 0x000);
+ __clear_bit(msr, msr_bitmap_va + 0x800);
+ } else if ((msr >= 0xc0000000) && (msr <= 0xc0001fff)) {
+ msr &= 0x1fff; /* read and write bitmaps for high MSRs
*/
+ __clear_bit(msr, msr_bitmap_va + 0x400);
+ __clear_bit(msr, msr_bitmap_va + 0xc00);
+ }
+}
+
static struct kvm_arch_ops vmx_arch_ops = {
.cpu_has_kvm_support = cpu_has_kvm_support,
.disabled_by_bios = vmx_disabled_by_bios,
@@ -2505,6 +2523,28 @@ static int __init vmx_init(void)
if (r)
goto out1;
+ if (cpu_has_vmx_msr_bitmap) {
+ vmx_msr_bitmap = alloc_page(GFP_KERNEL | __GFP_HIGHMEM);
+ if (!vmx_msr_bitmap) {
+ r = -ENOMEM;
+ goto out1;
+ }
+
+ printk(KERN_INFO "kvm: Enable MSR bitmap support.\n");
+
+ va = kmap(vmx_msr_bitmap);
+ memset(va, 0xff, PAGE_SIZE);
+
+ disable_intercept_for_msr(MSR_FS_BASE, va);
+ disable_intercept_for_msr(MSR_GS_BASE, va);
+
+ disable_intercept_for_msr(MSR_IA32_SYSENTER_CS, va);
+ disable_intercept_for_msr(MSR_IA32_SYSENTER_ESP, va);
+ disable_intercept_for_msr(MSR_IA32_SYSENTER_EIP, va);
+
+ kunmap(vmx_msr_bitmap);
+ }
+
return 0;
out1:
@@ -2516,6 +2556,8 @@ out:
static void __exit vmx_exit(void)
{
+ if (cpu_has_vmx_msr_bitmap)
+ __free_page(vmx_msr_bitmap);
__free_page(vmx_io_bitmap_b);
__free_page(vmx_io_bitmap_a);
diff --git a/drivers/kvm/vmx.h b/drivers/kvm/vmx.h
index 7e4dc12..b61c7f3 100644
--- a/drivers/kvm/vmx.h
+++ b/drivers/kvm/vmx.h
@@ -309,4 +309,7 @@ enum vmcs_field {
#define MSR_IA32_FEATURE_CONTROL_LOCKED 0x1
#define MSR_IA32_FEATURE_CONTROL_VMXON_ENABLED 0x4
+#define cpu_has_vmx_msr_bitmap \
+ (vmcs_config.cpu_based_exec_ctrl & CPU_BASED_USE_MSR_BITMAPS)
+
#endif
--
1.5.2
Add-MSR-Bitmap-support-for-VMX.patch
Description: Add-MSR-Bitmap-support-for-VMX.patch
------------------------------------------------------------------------- This SF.net email is sponsored by: Splunk Inc. Still grepping through log files to find problems? Stop. Now Search log events and configuration files using AJAX and a browser. Download your FREE copy of Splunk now >> http://get.splunk.com/
_______________________________________________ kvm-devel mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/kvm-devel
