Skip to content

Commit e47d860

Browse files
jpoimboesean-jc
authored andcommitted
KVM: x86: Add SBPB support
Add support for the AMD Selective Branch Predictor Barrier (SBPB) by advertising the CPUID bit and handling PRED_CMD writes accordingly. Note, like SRSO_NO and IBPB_BRTYPE before it, advertise support for SBPB even if it's not enumerated by in the raw CPUID. Some CPUs that gained support via a uCode patch don't report SBPB via CPUID (the kernel forces the flag). Signed-off-by: Josh Poimboeuf <[email protected]> Link: https://lore.kernel.org/r/a4ab1e7fe50096d50fde33e739ed2da40b41ea6a.1692919072.git.jpoimboe@kernel.org Co-developed-by: Sean Christopherson <[email protected]> Signed-off-by: Sean Christopherson <[email protected]>
1 parent 6f0f23e commit e47d860

File tree

3 files changed

+27
-6
lines changed

3 files changed

+27
-6
lines changed

arch/x86/kvm/cpuid.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -764,6 +764,7 @@ void kvm_set_cpu_caps(void)
764764
F(NULL_SEL_CLR_BASE) | F(AUTOIBRS) | 0 /* PrefetchCtlMsr */
765765
);
766766

767+
kvm_cpu_cap_check_and_set(X86_FEATURE_SBPB);
767768
kvm_cpu_cap_check_and_set(X86_FEATURE_IBPB_BRTYPE);
768769
kvm_cpu_cap_check_and_set(X86_FEATURE_SRSO_NO);
769770

arch/x86/kvm/cpuid.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,8 @@ static inline bool guest_has_spec_ctrl_msr(struct kvm_vcpu *vcpu)
174174
static inline bool guest_has_pred_cmd_msr(struct kvm_vcpu *vcpu)
175175
{
176176
return (guest_cpuid_has(vcpu, X86_FEATURE_SPEC_CTRL) ||
177-
guest_cpuid_has(vcpu, X86_FEATURE_AMD_IBPB));
177+
guest_cpuid_has(vcpu, X86_FEATURE_AMD_IBPB) ||
178+
guest_cpuid_has(vcpu, X86_FEATURE_SBPB));
178179
}
179180

180181
static inline bool supports_cpuid_fault(struct kvm_vcpu *vcpu)

arch/x86/kvm/x86.c

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3670,17 +3670,36 @@ int kvm_set_msr_common(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
36703670
vcpu->arch.perf_capabilities = data;
36713671
kvm_pmu_refresh(vcpu);
36723672
break;
3673-
case MSR_IA32_PRED_CMD:
3674-
if (!msr_info->host_initiated && !guest_has_pred_cmd_msr(vcpu))
3675-
return 1;
3673+
case MSR_IA32_PRED_CMD: {
3674+
u64 reserved_bits = ~(PRED_CMD_IBPB | PRED_CMD_SBPB);
3675+
3676+
if (!msr_info->host_initiated) {
3677+
if ((!guest_has_pred_cmd_msr(vcpu)))
3678+
return 1;
3679+
3680+
if (!guest_cpuid_has(vcpu, X86_FEATURE_SPEC_CTRL) &&
3681+
!guest_cpuid_has(vcpu, X86_FEATURE_AMD_IBPB))
3682+
reserved_bits |= PRED_CMD_IBPB;
36763683

3677-
if (!boot_cpu_has(X86_FEATURE_IBPB) || (data & ~PRED_CMD_IBPB))
3684+
if (!guest_cpuid_has(vcpu, X86_FEATURE_SBPB))
3685+
reserved_bits |= PRED_CMD_SBPB;
3686+
}
3687+
3688+
if (!boot_cpu_has(X86_FEATURE_IBPB))
3689+
reserved_bits |= PRED_CMD_IBPB;
3690+
3691+
if (!boot_cpu_has(X86_FEATURE_SBPB))
3692+
reserved_bits |= PRED_CMD_SBPB;
3693+
3694+
if (data & reserved_bits)
36783695
return 1;
3696+
36793697
if (!data)
36803698
break;
36813699

3682-
wrmsrl(MSR_IA32_PRED_CMD, PRED_CMD_IBPB);
3700+
wrmsrl(MSR_IA32_PRED_CMD, data);
36833701
break;
3702+
}
36843703
case MSR_IA32_FLUSH_CMD:
36853704
if (!msr_info->host_initiated &&
36863705
!guest_cpuid_has(vcpu, X86_FEATURE_FLUSH_L1D))

0 commit comments

Comments
 (0)