@@ -595,6 +595,7 @@ struct vcpu_vmx {
595
595
#endif
596
596
597
597
u64 arch_capabilities ;
598
+ u64 spec_ctrl ;
598
599
599
600
u32 vm_entry_controls_shadow ;
600
601
u32 vm_exit_controls_shadow ;
@@ -1910,6 +1911,29 @@ static void update_exception_bitmap(struct kvm_vcpu *vcpu)
1910
1911
vmcs_write32 (EXCEPTION_BITMAP , eb );
1911
1912
}
1912
1913
1914
+ /*
1915
+ * Check if MSR is intercepted for currently loaded MSR bitmap.
1916
+ */
1917
+ static bool msr_write_intercepted (struct kvm_vcpu * vcpu , u32 msr )
1918
+ {
1919
+ unsigned long * msr_bitmap ;
1920
+ int f = sizeof (unsigned long );
1921
+
1922
+ if (!cpu_has_vmx_msr_bitmap ())
1923
+ return true;
1924
+
1925
+ msr_bitmap = to_vmx (vcpu )-> loaded_vmcs -> msr_bitmap ;
1926
+
1927
+ if (msr <= 0x1fff ) {
1928
+ return !!test_bit (msr , msr_bitmap + 0x800 / f );
1929
+ } else if ((msr >= 0xc0000000 ) && (msr <= 0xc0001fff )) {
1930
+ msr &= 0x1fff ;
1931
+ return !!test_bit (msr , msr_bitmap + 0xc00 / f );
1932
+ }
1933
+
1934
+ return true;
1935
+ }
1936
+
1913
1937
/*
1914
1938
* Check if MSR is intercepted for L01 MSR bitmap.
1915
1939
*/
@@ -3262,6 +3286,14 @@ static int vmx_get_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
3262
3286
case MSR_IA32_TSC :
3263
3287
msr_info -> data = guest_read_tsc (vcpu );
3264
3288
break ;
3289
+ case MSR_IA32_SPEC_CTRL :
3290
+ if (!msr_info -> host_initiated &&
3291
+ !guest_cpuid_has (vcpu , X86_FEATURE_IBRS ) &&
3292
+ !guest_cpuid_has (vcpu , X86_FEATURE_SPEC_CTRL ))
3293
+ return 1 ;
3294
+
3295
+ msr_info -> data = to_vmx (vcpu )-> spec_ctrl ;
3296
+ break ;
3265
3297
case MSR_IA32_ARCH_CAPABILITIES :
3266
3298
if (!msr_info -> host_initiated &&
3267
3299
!guest_cpuid_has (vcpu , X86_FEATURE_ARCH_CAPABILITIES ))
@@ -3375,6 +3407,37 @@ static int vmx_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
3375
3407
case MSR_IA32_TSC :
3376
3408
kvm_write_tsc (vcpu , msr_info );
3377
3409
break ;
3410
+ case MSR_IA32_SPEC_CTRL :
3411
+ if (!msr_info -> host_initiated &&
3412
+ !guest_cpuid_has (vcpu , X86_FEATURE_IBRS ) &&
3413
+ !guest_cpuid_has (vcpu , X86_FEATURE_SPEC_CTRL ))
3414
+ return 1 ;
3415
+
3416
+ /* The STIBP bit doesn't fault even if it's not advertised */
3417
+ if (data & ~(SPEC_CTRL_IBRS | SPEC_CTRL_STIBP ))
3418
+ return 1 ;
3419
+
3420
+ vmx -> spec_ctrl = data ;
3421
+
3422
+ if (!data )
3423
+ break ;
3424
+
3425
+ /*
3426
+ * For non-nested:
3427
+ * When it's written (to non-zero) for the first time, pass
3428
+ * it through.
3429
+ *
3430
+ * For nested:
3431
+ * The handling of the MSR bitmap for L2 guests is done in
3432
+ * nested_vmx_merge_msr_bitmap. We should not touch the
3433
+ * vmcs02.msr_bitmap here since it gets completely overwritten
3434
+ * in the merging. We update the vmcs01 here for L1 as well
3435
+ * since it will end up touching the MSR anyway now.
3436
+ */
3437
+ vmx_disable_intercept_for_msr (vmx -> vmcs01 .msr_bitmap ,
3438
+ MSR_IA32_SPEC_CTRL ,
3439
+ MSR_TYPE_RW );
3440
+ break ;
3378
3441
case MSR_IA32_PRED_CMD :
3379
3442
if (!msr_info -> host_initiated &&
3380
3443
!guest_cpuid_has (vcpu , X86_FEATURE_IBPB ) &&
@@ -5700,6 +5763,7 @@ static void vmx_vcpu_reset(struct kvm_vcpu *vcpu, bool init_event)
5700
5763
u64 cr0 ;
5701
5764
5702
5765
vmx -> rmode .vm86_active = 0 ;
5766
+ vmx -> spec_ctrl = 0 ;
5703
5767
5704
5768
vmx -> vcpu .arch .regs [VCPU_REGS_RDX ] = get_rdx_init_val ();
5705
5769
kvm_set_cr8 (vcpu , 0 );
@@ -9371,6 +9435,15 @@ static void __noclone vmx_vcpu_run(struct kvm_vcpu *vcpu)
9371
9435
9372
9436
vmx_arm_hv_timer (vcpu );
9373
9437
9438
+ /*
9439
+ * If this vCPU has touched SPEC_CTRL, restore the guest's value if
9440
+ * it's non-zero. Since vmentry is serialising on affected CPUs, there
9441
+ * is no need to worry about the conditional branch over the wrmsr
9442
+ * being speculatively taken.
9443
+ */
9444
+ if (vmx -> spec_ctrl )
9445
+ wrmsrl (MSR_IA32_SPEC_CTRL , vmx -> spec_ctrl );
9446
+
9374
9447
vmx -> __launched = vmx -> loaded_vmcs -> launched ;
9375
9448
asm(
9376
9449
/* Store host registers */
@@ -9489,6 +9562,27 @@ static void __noclone vmx_vcpu_run(struct kvm_vcpu *vcpu)
9489
9562
#endif
9490
9563
);
9491
9564
9565
+ /*
9566
+ * We do not use IBRS in the kernel. If this vCPU has used the
9567
+ * SPEC_CTRL MSR it may have left it on; save the value and
9568
+ * turn it off. This is much more efficient than blindly adding
9569
+ * it to the atomic save/restore list. Especially as the former
9570
+ * (Saving guest MSRs on vmexit) doesn't even exist in KVM.
9571
+ *
9572
+ * For non-nested case:
9573
+ * If the L01 MSR bitmap does not intercept the MSR, then we need to
9574
+ * save it.
9575
+ *
9576
+ * For nested case:
9577
+ * If the L02 MSR bitmap does not intercept the MSR, then we need to
9578
+ * save it.
9579
+ */
9580
+ if (!msr_write_intercepted (vcpu , MSR_IA32_SPEC_CTRL ))
9581
+ rdmsrl (MSR_IA32_SPEC_CTRL , vmx -> spec_ctrl );
9582
+
9583
+ if (vmx -> spec_ctrl )
9584
+ wrmsrl (MSR_IA32_SPEC_CTRL , 0 );
9585
+
9492
9586
/* Eliminate branch target predictions from guest mode */
9493
9587
vmexit_fill_RSB ();
9494
9588
@@ -10113,7 +10207,7 @@ static inline bool nested_vmx_merge_msr_bitmap(struct kvm_vcpu *vcpu,
10113
10207
unsigned long * msr_bitmap_l1 ;
10114
10208
unsigned long * msr_bitmap_l0 = to_vmx (vcpu )-> nested .vmcs02 .msr_bitmap ;
10115
10209
/*
10116
- * pred_cmd is trying to verify two things:
10210
+ * pred_cmd & spec_ctrl are trying to verify two things:
10117
10211
*
10118
10212
* 1. L0 gave a permission to L1 to actually passthrough the MSR. This
10119
10213
* ensures that we do not accidentally generate an L02 MSR bitmap
@@ -10126,9 +10220,10 @@ static inline bool nested_vmx_merge_msr_bitmap(struct kvm_vcpu *vcpu,
10126
10220
* the MSR.
10127
10221
*/
10128
10222
bool pred_cmd = msr_write_intercepted_l01 (vcpu , MSR_IA32_PRED_CMD );
10223
+ bool spec_ctrl = msr_write_intercepted_l01 (vcpu , MSR_IA32_SPEC_CTRL );
10129
10224
10130
10225
if (!nested_cpu_has_virt_x2apic_mode (vmcs12 ) &&
10131
- !pred_cmd )
10226
+ !pred_cmd && ! spec_ctrl )
10132
10227
return false;
10133
10228
10134
10229
page = kvm_vcpu_gpa_to_page (vcpu , vmcs12 -> msr_bitmap );
@@ -10162,6 +10257,12 @@ static inline bool nested_vmx_merge_msr_bitmap(struct kvm_vcpu *vcpu,
10162
10257
}
10163
10258
}
10164
10259
10260
+ if (spec_ctrl )
10261
+ nested_vmx_disable_intercept_for_msr (
10262
+ msr_bitmap_l1 , msr_bitmap_l0 ,
10263
+ MSR_IA32_SPEC_CTRL ,
10264
+ MSR_TYPE_R | MSR_TYPE_W );
10265
+
10165
10266
if (pred_cmd )
10166
10267
nested_vmx_disable_intercept_for_msr (
10167
10268
msr_bitmap_l1 , msr_bitmap_l0 ,
0 commit comments