@@ -91,6 +91,7 @@ static DEFINE_PER_CPU(struct vmcs *, current_vmcs);
91
91
92
92
static struct page * vmx_io_bitmap_a ;
93
93
static struct page * vmx_io_bitmap_b ;
94
+ static struct page * vmx_msr_bitmap ;
94
95
95
96
static DECLARE_BITMAP (vmx_vpid_bitmap , VMX_NR_VPIDS ) ;
96
97
static DEFINE_SPINLOCK (vmx_vpid_lock );
@@ -185,6 +186,11 @@ static inline int is_external_interrupt(u32 intr_info)
185
186
== (INTR_TYPE_EXT_INTR | INTR_INFO_VALID_MASK );
186
187
}
187
188
189
+ static inline int cpu_has_vmx_msr_bitmap (void )
190
+ {
191
+ return (vmcs_config .cpu_based_exec_ctrl & CPU_BASED_USE_MSR_BITMAPS );
192
+ }
193
+
188
194
static inline int cpu_has_vmx_tpr_shadow (void )
189
195
{
190
196
return (vmcs_config .cpu_based_exec_ctrl & CPU_BASED_TPR_SHADOW );
@@ -1001,6 +1007,7 @@ static __init int setup_vmcs_config(struct vmcs_config *vmcs_conf)
1001
1007
CPU_BASED_MOV_DR_EXITING |
1002
1008
CPU_BASED_USE_TSC_OFFSETING ;
1003
1009
opt = CPU_BASED_TPR_SHADOW |
1010
+ CPU_BASED_USE_MSR_BITMAPS |
1004
1011
CPU_BASED_ACTIVATE_SECONDARY_CONTROLS ;
1005
1012
if (adjust_vmx_controls (min , opt , MSR_IA32_VMX_PROCBASED_CTLS ,
1006
1013
& _cpu_based_exec_control ) < 0 )
@@ -1575,6 +1582,30 @@ static void allocate_vpid(struct vcpu_vmx *vmx)
1575
1582
spin_unlock (& vmx_vpid_lock );
1576
1583
}
1577
1584
1585
+ void vmx_disable_intercept_for_msr (struct page * msr_bitmap , u32 msr )
1586
+ {
1587
+ void * va ;
1588
+
1589
+ if (!cpu_has_vmx_msr_bitmap ())
1590
+ return ;
1591
+
1592
+ /*
1593
+ * See Intel PRM Vol. 3, 20.6.9 (MSR-Bitmap Address). Early manuals
1594
+ * have the write-low and read-high bitmap offsets the wrong way round.
1595
+ * We can control MSRs 0x00000000-0x00001fff and 0xc0000000-0xc0001fff.
1596
+ */
1597
+ va = kmap (msr_bitmap );
1598
+ if (msr <= 0x1fff ) {
1599
+ __clear_bit (msr , va + 0x000 ); /* read-low */
1600
+ __clear_bit (msr , va + 0x800 ); /* write-low */
1601
+ } else if ((msr >= 0xc0000000 ) && (msr <= 0xc0001fff )) {
1602
+ msr &= 0x1fff ;
1603
+ __clear_bit (msr , va + 0x400 ); /* read-high */
1604
+ __clear_bit (msr , va + 0xc00 ); /* write-high */
1605
+ }
1606
+ kunmap (msr_bitmap );
1607
+ }
1608
+
1578
1609
/*
1579
1610
* Sets up the vmcs for emulated real mode.
1580
1611
*/
@@ -1592,6 +1623,9 @@ static int vmx_vcpu_setup(struct vcpu_vmx *vmx)
1592
1623
vmcs_write64 (IO_BITMAP_A , page_to_phys (vmx_io_bitmap_a ));
1593
1624
vmcs_write64 (IO_BITMAP_B , page_to_phys (vmx_io_bitmap_b ));
1594
1625
1626
+ if (cpu_has_vmx_msr_bitmap ())
1627
+ vmcs_write64 (MSR_BITMAP , page_to_phys (vmx_msr_bitmap ));
1628
+
1595
1629
vmcs_write64 (VMCS_LINK_POINTER , -1ull ); /* 22.3.1.5 */
1596
1630
1597
1631
/* Control */
@@ -2728,7 +2762,7 @@ static struct kvm_x86_ops vmx_x86_ops = {
2728
2762
2729
2763
static int __init vmx_init (void )
2730
2764
{
2731
- void * iova ;
2765
+ void * va ;
2732
2766
int r ;
2733
2767
2734
2768
vmx_io_bitmap_a = alloc_page (GFP_KERNEL | __GFP_HIGHMEM );
@@ -2741,30 +2775,48 @@ static int __init vmx_init(void)
2741
2775
goto out ;
2742
2776
}
2743
2777
2778
+ vmx_msr_bitmap = alloc_page (GFP_KERNEL | __GFP_HIGHMEM );
2779
+ if (!vmx_msr_bitmap ) {
2780
+ r = - ENOMEM ;
2781
+ goto out1 ;
2782
+ }
2783
+
2744
2784
/*
2745
2785
* Allow direct access to the PC debug port (it is often used for I/O
2746
2786
* delays, but the vmexits simply slow things down).
2747
2787
*/
2748
- iova = kmap (vmx_io_bitmap_a );
2749
- memset (iova , 0xff , PAGE_SIZE );
2750
- clear_bit (0x80 , iova );
2788
+ va = kmap (vmx_io_bitmap_a );
2789
+ memset (va , 0xff , PAGE_SIZE );
2790
+ clear_bit (0x80 , va );
2751
2791
kunmap (vmx_io_bitmap_a );
2752
2792
2753
- iova = kmap (vmx_io_bitmap_b );
2754
- memset (iova , 0xff , PAGE_SIZE );
2793
+ va = kmap (vmx_io_bitmap_b );
2794
+ memset (va , 0xff , PAGE_SIZE );
2755
2795
kunmap (vmx_io_bitmap_b );
2756
2796
2797
+ va = kmap (vmx_msr_bitmap );
2798
+ memset (va , 0xff , PAGE_SIZE );
2799
+ kunmap (vmx_msr_bitmap );
2800
+
2757
2801
set_bit (0 , vmx_vpid_bitmap ); /* 0 is reserved for host */
2758
2802
2759
2803
r = kvm_init (& vmx_x86_ops , sizeof (struct vcpu_vmx ), THIS_MODULE );
2760
2804
if (r )
2761
- goto out1 ;
2805
+ goto out2 ;
2806
+
2807
+ vmx_disable_intercept_for_msr (vmx_msr_bitmap , MSR_FS_BASE );
2808
+ vmx_disable_intercept_for_msr (vmx_msr_bitmap , MSR_GS_BASE );
2809
+ vmx_disable_intercept_for_msr (vmx_msr_bitmap , MSR_IA32_SYSENTER_CS );
2810
+ vmx_disable_intercept_for_msr (vmx_msr_bitmap , MSR_IA32_SYSENTER_ESP );
2811
+ vmx_disable_intercept_for_msr (vmx_msr_bitmap , MSR_IA32_SYSENTER_EIP );
2762
2812
2763
2813
if (bypass_guest_pf )
2764
2814
kvm_mmu_set_nonpresent_ptes (~0xffeull , 0ull );
2765
2815
2766
2816
return 0 ;
2767
2817
2818
+ out2 :
2819
+ __free_page (vmx_msr_bitmap );
2768
2820
out1 :
2769
2821
__free_page (vmx_io_bitmap_b );
2770
2822
out :
@@ -2774,6 +2826,7 @@ static int __init vmx_init(void)
2774
2826
2775
2827
static void __exit vmx_exit (void )
2776
2828
{
2829
+ __free_page (vmx_msr_bitmap );
2777
2830
__free_page (vmx_io_bitmap_b );
2778
2831
__free_page (vmx_io_bitmap_a );
2779
2832
0 commit comments