@@ -958,6 +958,7 @@ static struct vmcs_config {
958
958
u32 cpu_based_2nd_exec_ctrl ;
959
959
u32 vmexit_ctrl ;
960
960
u32 vmentry_ctrl ;
961
+ struct nested_vmx_msrs nested ;
961
962
} vmcs_config ;
962
963
963
964
static struct vmx_capability {
@@ -2689,6 +2690,11 @@ static inline bool nested_vmx_allowed(struct kvm_vcpu *vcpu)
2689
2690
*/
2690
2691
static void nested_vmx_setup_ctls_msrs (struct nested_vmx_msrs * msrs , bool apicv )
2691
2692
{
2693
+ if (!nested ) {
2694
+ memset (msrs , 0 , sizeof (* msrs ));
2695
+ return ;
2696
+ }
2697
+
2692
2698
/*
2693
2699
* Note that as a general rule, the high half of the MSRs (bits in
2694
2700
* the control fields which may be 1) should be initialized by the
@@ -2713,13 +2719,11 @@ static void nested_vmx_setup_ctls_msrs(struct nested_vmx_msrs *msrs, bool apicv)
2713
2719
msrs -> pinbased_ctls_high &=
2714
2720
PIN_BASED_EXT_INTR_MASK |
2715
2721
PIN_BASED_NMI_EXITING |
2716
- PIN_BASED_VIRTUAL_NMIS ;
2722
+ PIN_BASED_VIRTUAL_NMIS |
2723
+ (apicv ? PIN_BASED_POSTED_INTR : 0 );
2717
2724
msrs -> pinbased_ctls_high |=
2718
2725
PIN_BASED_ALWAYSON_WITHOUT_TRUE_MSR |
2719
2726
PIN_BASED_VMX_PREEMPTION_TIMER ;
2720
- if (apicv )
2721
- msrs -> pinbased_ctls_high |=
2722
- PIN_BASED_POSTED_INTR ;
2723
2727
2724
2728
/* exit controls */
2725
2729
rdmsr (MSR_IA32_VMX_EXIT_CTLS ,
@@ -3231,7 +3235,16 @@ static inline bool vmx_feature_control_msr_valid(struct kvm_vcpu *vcpu,
3231
3235
3232
3236
static int vmx_get_msr_feature (struct kvm_msr_entry * msr )
3233
3237
{
3234
- return 1 ;
3238
+ switch (msr -> index ) {
3239
+ case MSR_IA32_VMX_BASIC ... MSR_IA32_VMX_VMFUNC :
3240
+ if (!nested )
3241
+ return 1 ;
3242
+ return vmx_get_vmx_msr (& vmcs_config .nested , msr -> index , & msr -> data );
3243
+ default :
3244
+ return 1 ;
3245
+ }
3246
+
3247
+ return 0 ;
3235
3248
}
3236
3249
3237
3250
/*
@@ -3697,6 +3710,7 @@ static __init int setup_vmcs_config(struct vmcs_config *vmcs_conf)
3697
3710
u32 _vmexit_control = 0 ;
3698
3711
u32 _vmentry_control = 0 ;
3699
3712
3713
+ memset (vmcs_conf , 0 , sizeof (* vmcs_conf ));
3700
3714
min = CPU_BASED_HLT_EXITING |
3701
3715
#ifdef CONFIG_X86_64
3702
3716
CPU_BASED_CR8_LOAD_EXITING |
@@ -7091,6 +7105,7 @@ static __init int hardware_setup(void)
7091
7105
init_vmcs_shadow_fields ();
7092
7106
7093
7107
kvm_set_posted_intr_wakeup_handler (wakeup_handler );
7108
+ nested_vmx_setup_ctls_msrs (& vmcs_config .nested , enable_apicv );
7094
7109
7095
7110
kvm_mce_cap_supported |= MCG_LMCE_P ;
7096
7111
@@ -9822,6 +9837,7 @@ static void __init vmx_check_processor_compat(void *rtn)
9822
9837
* (int * )rtn = 0 ;
9823
9838
if (setup_vmcs_config (& vmcs_conf ) < 0 )
9824
9839
* (int * )rtn = - EIO ;
9840
+ nested_vmx_setup_ctls_msrs (& vmcs_conf .nested , enable_apicv );
9825
9841
if (memcmp (& vmcs_config , & vmcs_conf , sizeof (struct vmcs_config )) != 0 ) {
9826
9842
printk (KERN_ERR "kvm: CPU %d feature inconsistency!\n" ,
9827
9843
smp_processor_id ());
0 commit comments