Skip to content

Commit

Permalink
x86/bugs: KVM: Add support for SRSO_MSR_FIX
Browse files Browse the repository at this point in the history
Add support for

  CPUID Fn8000_0021_EAX[31] (SRSO_MSR_FIX). If this bit is 1, it
  indicates that software may use MSR BP_CFG[BpSpecReduce] to mitigate
  SRSO.

Enable BpSpecReduce to mitigate SRSO across guest/host boundaries.

Switch back to enabling the bit when virtualization is enabled and to
clear the bit when virtualization is disabled because using a MSR slot
would clear the bit when the guest is exited and any training the guest
has done, would potentially influence the host kernel when execution
enters the kernel and hasn't VMRUN the guest yet.

More detail on the public thread in Link below.

Co-developed-by: Sean Christopherson <seanjc@google.com>
Signed-off-by: Sean Christopherson <seanjc@google.com>
Signed-off-by: Borislav Petkov (AMD) <bp@alien8.de>
Link: https://lore.kernel.org/r/20241202120416.6054-1-bp@kernel.org
  • Loading branch information
Borislav Petkov committed Feb 26, 2025
1 parent d082ecb commit 8442df2
Show file tree
Hide file tree
Showing 6 changed files with 46 additions and 4 deletions.
13 changes: 13 additions & 0 deletions Documentation/admin-guide/hw-vuln/srso.rst
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,20 @@ The possible values in this file are:

(spec_rstack_overflow=ibpb-vmexit)

* 'Mitigation: Reduced Speculation':

This mitigation gets automatically enabled when the above one "IBPB on
VMEXIT" has been selected and the CPU supports the BpSpecReduce bit.

It gets automatically enabled on machines which have the
SRSO_USER_KERNEL_NO=1 CPUID bit. In that case, the code logic is to switch
to the above =ibpb-vmexit mitigation because the user/kernel boundary is
not affected anymore and thus "safe RET" is not needed.

After enabling the IBPB on VMEXIT mitigation option, the BpSpecReduce bit
is detected (functionality present on all such machines) and that
practically overrides IBPB on VMEXIT as it has a lot less performance
impact and takes care of the guest->host attack vector too.

In order to exploit vulnerability, an attacker needs to:

Expand Down
4 changes: 4 additions & 0 deletions arch/x86/include/asm/cpufeatures.h
Original file line number Diff line number Diff line change
Expand Up @@ -468,6 +468,10 @@
#define X86_FEATURE_IBPB_BRTYPE (20*32+28) /* MSR_PRED_CMD[IBPB] flushes all branch type predictions */
#define X86_FEATURE_SRSO_NO (20*32+29) /* CPU is not affected by SRSO */
#define X86_FEATURE_SRSO_USER_KERNEL_NO (20*32+30) /* CPU is not affected by SRSO across user/kernel boundaries */
#define X86_FEATURE_SRSO_BP_SPEC_REDUCE (20*32+31) /*
* BP_CFG[BpSpecReduce] can be used to mitigate SRSO for VMs.
* (SRSO_MSR_FIX in the official doc).
*/

/*
* Extended auxiliary flags: Linux defined - for features scattered in various
Expand Down
1 change: 1 addition & 0 deletions arch/x86/include/asm/msr-index.h
Original file line number Diff line number Diff line change
Expand Up @@ -721,6 +721,7 @@

/* Zen4 */
#define MSR_ZEN4_BP_CFG 0xc001102e
#define MSR_ZEN4_BP_CFG_BP_SPEC_REDUCE_BIT 4
#define MSR_ZEN4_BP_CFG_SHARED_BTB_FIX_BIT 5

/* Fam 19h MSRs */
Expand Down
24 changes: 20 additions & 4 deletions arch/x86/kernel/cpu/bugs.c
Original file line number Diff line number Diff line change
Expand Up @@ -2522,6 +2522,7 @@ enum srso_mitigation {
SRSO_MITIGATION_SAFE_RET,
SRSO_MITIGATION_IBPB,
SRSO_MITIGATION_IBPB_ON_VMEXIT,
SRSO_MITIGATION_BP_SPEC_REDUCE,
};

enum srso_mitigation_cmd {
Expand All @@ -2539,7 +2540,8 @@ static const char * const srso_strings[] = {
[SRSO_MITIGATION_MICROCODE] = "Vulnerable: Microcode, no safe RET",
[SRSO_MITIGATION_SAFE_RET] = "Mitigation: Safe RET",
[SRSO_MITIGATION_IBPB] = "Mitigation: IBPB",
[SRSO_MITIGATION_IBPB_ON_VMEXIT] = "Mitigation: IBPB on VMEXIT only"
[SRSO_MITIGATION_IBPB_ON_VMEXIT] = "Mitigation: IBPB on VMEXIT only",
[SRSO_MITIGATION_BP_SPEC_REDUCE] = "Mitigation: Reduced Speculation"
};

static enum srso_mitigation srso_mitigation __ro_after_init = SRSO_MITIGATION_NONE;
Expand Down Expand Up @@ -2578,7 +2580,7 @@ static void __init srso_select_mitigation(void)
srso_cmd == SRSO_CMD_OFF) {
if (boot_cpu_has(X86_FEATURE_SBPB))
x86_pred_cmd = PRED_CMD_SBPB;
return;
goto out;
}

if (has_microcode) {
Expand All @@ -2590,7 +2592,7 @@ static void __init srso_select_mitigation(void)
*/
if (boot_cpu_data.x86 < 0x19 && !cpu_smt_possible()) {
setup_force_cpu_cap(X86_FEATURE_SRSO_NO);
return;
goto out;
}

if (retbleed_mitigation == RETBLEED_MITIGATION_IBPB) {
Expand Down Expand Up @@ -2670,6 +2672,12 @@ static void __init srso_select_mitigation(void)

ibpb_on_vmexit:
case SRSO_CMD_IBPB_ON_VMEXIT:
if (boot_cpu_has(X86_FEATURE_SRSO_BP_SPEC_REDUCE)) {
pr_notice("Reducing speculation to address VM/HV SRSO attack vector.\n");
srso_mitigation = SRSO_MITIGATION_BP_SPEC_REDUCE;
break;
}

if (IS_ENABLED(CONFIG_MITIGATION_IBPB_ENTRY)) {
if (has_microcode) {
setup_force_cpu_cap(X86_FEATURE_IBPB_ON_VMEXIT);
Expand All @@ -2691,7 +2699,15 @@ static void __init srso_select_mitigation(void)
}

out:
pr_info("%s\n", srso_strings[srso_mitigation]);
/*
* Clear the feature flag if this mitigation is not selected as that
* feature flag controls the BpSpecReduce MSR bit toggling in KVM.
*/
if (srso_mitigation != SRSO_MITIGATION_BP_SPEC_REDUCE)
setup_clear_cpu_cap(X86_FEATURE_SRSO_BP_SPEC_REDUCE);

if (srso_mitigation != SRSO_MITIGATION_NONE)
pr_info("%s\n", srso_strings[srso_mitigation]);
}

#undef pr_fmt
Expand Down
6 changes: 6 additions & 0 deletions arch/x86/kvm/svm/svm.c
Original file line number Diff line number Diff line change
Expand Up @@ -607,6 +607,9 @@ static void svm_disable_virtualization_cpu(void)
kvm_cpu_svm_disable();

amd_pmu_disable_virt();

if (cpu_feature_enabled(X86_FEATURE_SRSO_BP_SPEC_REDUCE))
msr_clear_bit(MSR_ZEN4_BP_CFG, MSR_ZEN4_BP_CFG_BP_SPEC_REDUCE_BIT);
}

static int svm_enable_virtualization_cpu(void)
Expand Down Expand Up @@ -684,6 +687,9 @@ static int svm_enable_virtualization_cpu(void)
rdmsr(MSR_TSC_AUX, sev_es_host_save_area(sd)->tsc_aux, msr_hi);
}

if (cpu_feature_enabled(X86_FEATURE_SRSO_BP_SPEC_REDUCE))
msr_set_bit(MSR_ZEN4_BP_CFG, MSR_ZEN4_BP_CFG_BP_SPEC_REDUCE_BIT);

return 0;
}

Expand Down
2 changes: 2 additions & 0 deletions arch/x86/lib/msr.c
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ int msr_set_bit(u32 msr, u8 bit)
{
return __flip_bit(msr, bit, true);
}
EXPORT_SYMBOL_GPL(msr_set_bit);

/**
* msr_clear_bit - Clear @bit in a MSR @msr.
Expand All @@ -118,6 +119,7 @@ int msr_clear_bit(u32 msr, u8 bit)
{
return __flip_bit(msr, bit, false);
}
EXPORT_SYMBOL_GPL(msr_clear_bit);

#ifdef CONFIG_TRACEPOINTS
void do_trace_write_msr(unsigned int msr, u64 val, int failed)
Expand Down

0 comments on commit 8442df2

Please sign in to comment.