@@ -576,6 +576,8 @@ struct vcpu_vmx {
576
576
#endif
577
577
u32 vm_entry_controls_shadow ;
578
578
u32 vm_exit_controls_shadow ;
579
+ u32 secondary_exec_control ;
580
+
579
581
/*
580
582
* loaded_vmcs points to the VMCS currently used in this vcpu. For a
581
583
* non-nested (L1) guest, it always points to vmcs01. For a nested
@@ -2807,15 +2809,17 @@ static void nested_vmx_setup_ctls_msrs(struct vcpu_vmx *vmx)
2807
2809
vmx -> nested .nested_vmx_procbased_ctls_low &=
2808
2810
~(CPU_BASED_CR3_LOAD_EXITING | CPU_BASED_CR3_STORE_EXITING );
2809
2811
2810
- /* secondary cpu-based controls */
2812
+ /*
2813
+ * secondary cpu-based controls. Do not include those that
2814
+ * depend on CPUID bits, they are added later by vmx_cpuid_update.
2815
+ */
2811
2816
rdmsr (MSR_IA32_VMX_PROCBASED_CTLS2 ,
2812
2817
vmx -> nested .nested_vmx_secondary_ctls_low ,
2813
2818
vmx -> nested .nested_vmx_secondary_ctls_high );
2814
2819
vmx -> nested .nested_vmx_secondary_ctls_low = 0 ;
2815
2820
vmx -> nested .nested_vmx_secondary_ctls_high &=
2816
2821
SECONDARY_EXEC_RDRAND | SECONDARY_EXEC_RDSEED |
2817
2822
SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES |
2818
- SECONDARY_EXEC_RDTSCP |
2819
2823
SECONDARY_EXEC_DESC |
2820
2824
SECONDARY_EXEC_VIRTUALIZE_X2APIC_MODE |
2821
2825
SECONDARY_EXEC_APIC_REGISTER_VIRT |
@@ -5269,10 +5273,12 @@ static u32 vmx_exec_control(struct vcpu_vmx *vmx)
5269
5273
return exec_control ;
5270
5274
}
5271
5275
5272
- static u32 vmx_secondary_exec_control (struct vcpu_vmx * vmx )
5276
+ static void vmx_compute_secondary_exec_control (struct vcpu_vmx * vmx )
5273
5277
{
5278
+ struct kvm_vcpu * vcpu = & vmx -> vcpu ;
5279
+
5274
5280
u32 exec_control = vmcs_config .cpu_based_2nd_exec_ctrl ;
5275
- if (!cpu_need_virtualize_apic_accesses (& vmx -> vcpu ))
5281
+ if (!cpu_need_virtualize_apic_accesses (vcpu ))
5276
5282
exec_control &= ~SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES ;
5277
5283
if (vmx -> vpid == 0 )
5278
5284
exec_control &= ~SECONDARY_EXEC_ENABLE_VPID ;
@@ -5286,7 +5292,7 @@ static u32 vmx_secondary_exec_control(struct vcpu_vmx *vmx)
5286
5292
exec_control &= ~SECONDARY_EXEC_UNRESTRICTED_GUEST ;
5287
5293
if (!ple_gap )
5288
5294
exec_control &= ~SECONDARY_EXEC_PAUSE_LOOP_EXITING ;
5289
- if (!kvm_vcpu_apicv_active (& vmx -> vcpu ))
5295
+ if (!kvm_vcpu_apicv_active (vcpu ))
5290
5296
exec_control &= ~(SECONDARY_EXEC_APIC_REGISTER_VIRT |
5291
5297
SECONDARY_EXEC_VIRTUAL_INTR_DELIVERY );
5292
5298
exec_control &= ~SECONDARY_EXEC_VIRTUALIZE_X2APIC_MODE ;
@@ -5300,7 +5306,43 @@ static u32 vmx_secondary_exec_control(struct vcpu_vmx *vmx)
5300
5306
if (!enable_pml )
5301
5307
exec_control &= ~SECONDARY_EXEC_ENABLE_PML ;
5302
5308
5303
- return exec_control ;
5309
+ if (vmx_rdtscp_supported ()) {
5310
+ bool rdtscp_enabled = guest_cpuid_has (vcpu , X86_FEATURE_RDTSCP );
5311
+ if (!rdtscp_enabled )
5312
+ exec_control &= ~SECONDARY_EXEC_RDTSCP ;
5313
+
5314
+ if (nested ) {
5315
+ if (rdtscp_enabled )
5316
+ vmx -> nested .nested_vmx_secondary_ctls_high |=
5317
+ SECONDARY_EXEC_RDTSCP ;
5318
+ else
5319
+ vmx -> nested .nested_vmx_secondary_ctls_high &=
5320
+ ~SECONDARY_EXEC_RDTSCP ;
5321
+ }
5322
+ }
5323
+
5324
+ if (vmx_invpcid_supported ()) {
5325
+ /* Exposing INVPCID only when PCID is exposed */
5326
+ bool invpcid_enabled =
5327
+ guest_cpuid_has (vcpu , X86_FEATURE_INVPCID ) &&
5328
+ guest_cpuid_has (vcpu , X86_FEATURE_PCID );
5329
+
5330
+ if (!invpcid_enabled ) {
5331
+ exec_control &= ~SECONDARY_EXEC_ENABLE_INVPCID ;
5332
+ guest_cpuid_clear (vcpu , X86_FEATURE_INVPCID );
5333
+ }
5334
+
5335
+ if (nested ) {
5336
+ if (invpcid_enabled )
5337
+ vmx -> nested .nested_vmx_secondary_ctls_high |=
5338
+ SECONDARY_EXEC_ENABLE_INVPCID ;
5339
+ else
5340
+ vmx -> nested .nested_vmx_secondary_ctls_high &=
5341
+ ~SECONDARY_EXEC_ENABLE_INVPCID ;
5342
+ }
5343
+ }
5344
+
5345
+ vmx -> secondary_exec_control = exec_control ;
5304
5346
}
5305
5347
5306
5348
static void ept_set_mmio_spte_mask (void )
@@ -5344,8 +5386,9 @@ static int vmx_vcpu_setup(struct vcpu_vmx *vmx)
5344
5386
vmcs_write32 (CPU_BASED_VM_EXEC_CONTROL , vmx_exec_control (vmx ));
5345
5387
5346
5388
if (cpu_has_secondary_exec_ctrls ()) {
5389
+ vmx_compute_secondary_exec_control (vmx );
5347
5390
vmcs_write32 (SECONDARY_VM_EXEC_CONTROL ,
5348
- vmx_secondary_exec_control ( vmx ) );
5391
+ vmx -> secondary_exec_control );
5349
5392
}
5350
5393
5351
5394
if (kvm_vcpu_apicv_active (& vmx -> vcpu )) {
@@ -9623,47 +9666,12 @@ static void nested_vmx_cr_fixed1_bits_update(struct kvm_vcpu *vcpu)
9623
9666
static void vmx_cpuid_update (struct kvm_vcpu * vcpu )
9624
9667
{
9625
9668
struct vcpu_vmx * vmx = to_vmx (vcpu );
9626
- u32 secondary_exec_ctl = vmx_secondary_exec_control (vmx );
9627
-
9628
- if (vmx_rdtscp_supported ()) {
9629
- bool rdtscp_enabled = guest_cpuid_has (vcpu , X86_FEATURE_RDTSCP );
9630
- if (!rdtscp_enabled )
9631
- secondary_exec_ctl &= ~SECONDARY_EXEC_RDTSCP ;
9632
-
9633
- if (nested ) {
9634
- if (rdtscp_enabled )
9635
- vmx -> nested .nested_vmx_secondary_ctls_high |=
9636
- SECONDARY_EXEC_RDTSCP ;
9637
- else
9638
- vmx -> nested .nested_vmx_secondary_ctls_high &=
9639
- ~SECONDARY_EXEC_RDTSCP ;
9640
- }
9641
- }
9642
-
9643
- if (vmx_invpcid_supported ()) {
9644
- /* Exposing INVPCID only when PCID is exposed */
9645
- bool invpcid_enabled =
9646
- guest_cpuid_has (vcpu , X86_FEATURE_INVPCID ) &&
9647
- guest_cpuid_has (vcpu , X86_FEATURE_PCID );
9648
-
9649
- if (!invpcid_enabled ) {
9650
- secondary_exec_ctl &= ~SECONDARY_EXEC_ENABLE_INVPCID ;
9651
- guest_cpuid_clear (vcpu , X86_FEATURE_INVPCID );
9652
- }
9653
9669
9654
- if (nested ) {
9655
- if (invpcid_enabled )
9656
- vmx -> nested .nested_vmx_secondary_ctls_high |=
9657
- SECONDARY_EXEC_ENABLE_INVPCID ;
9658
- else
9659
- vmx -> nested .nested_vmx_secondary_ctls_high &=
9660
- ~SECONDARY_EXEC_ENABLE_INVPCID ;
9661
- }
9670
+ if (cpu_has_secondary_exec_ctrls ()) {
9671
+ vmx_compute_secondary_exec_control (vmx );
9672
+ vmcs_set_secondary_exec_control (vmx -> secondary_exec_control );
9662
9673
}
9663
9674
9664
- if (cpu_has_secondary_exec_ctrls ())
9665
- vmcs_set_secondary_exec_control (secondary_exec_ctl );
9666
-
9667
9675
if (nested_vmx_allowed (vcpu ))
9668
9676
to_vmx (vcpu )-> msr_ia32_feature_control_valid_bits |=
9669
9677
FEATURE_CONTROL_VMXON_ENABLED_OUTSIDE_SMX ;
@@ -10356,7 +10364,7 @@ static int prepare_vmcs02(struct kvm_vcpu *vcpu, struct vmcs12 *vmcs12,
10356
10364
enable_ept ? vmcs12 -> page_fault_error_code_match : 0 );
10357
10365
10358
10366
if (cpu_has_secondary_exec_ctrls ()) {
10359
- exec_control = vmx_secondary_exec_control ( vmx ) ;
10367
+ exec_control = vmx -> secondary_exec_control ;
10360
10368
10361
10369
/* Take the following fields only from vmcs12 */
10362
10370
exec_control &= ~(SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES |
0 commit comments