1
0
mirror of https://git.FreeBSD.org/src.git synced 2024-11-28 08:02:54 +00:00

x86: AMD Zen2: Zenbleed chicken bit mitigation

Applies only to bare-metal Zen2 processors.  The system currently
automatically applies it to all of them.

Tunable/sysctl 'machdep.mitigations.zenbleed.enable' can be used to
forcibly enable or disable the mitigation at boot or run-time.  Possible
values are:

    0: Mitigation disabled
    1: Mitigation enabled
    2: Run the automatic determination.

Currently, value 2 is the default and has identical effect as value 1.
This might change in the future if we choose to take into account
microcode revisions in the automatic determination process.

The tunable/sysctl value is simply ignored on non-applicable CPU models,
which is useful to apply the same configuration on a set of machines
that do not all have Zen2 processors.  Trying to set it to any integer
value not listed above is silently equivalent to setting it to value 2
(automatic determination).

The current mitigation state can be queried through sysctl
'machdep.mitigations.zenbleed.state', which returns "Not applicable",
"Mitigation enabled" or "Mitigation disabled".  Note that this state is
not guaranteed to be accurate in case of intervening modifications of
the corresponding chicken bit directly via cpuctl(4) (this includes the
cpucontrol(8) utility).  Resetting the desired policy through
'machdep.mitigations.zenbleed.enable' (possibly to its current value)
will reset the hardware state and ensure that the reported state is
again coherent with it.

Reviewed by:	kib
Sponsored by:   The FreeBSD Foundation
Differential Revision:	https://reviews.freebsd.org/D41817
This commit is contained in:
Olivier Certner 2023-09-11 16:18:30 +02:00 committed by Ed Maste
parent c6cc06d465
commit ebaea1bcd2
7 changed files with 136 additions and 0 deletions

View File

@ -306,6 +306,7 @@ acpi_wakeup_machdep(struct acpi_softc *sc, int state, int sleep_result,
amd64_syscall_ret_flush_l1d_recalc();
hw_ssb_recalculate(true);
x86_rngds_mitg_recalculate(true);
zenbleed_check_and_apply(true);
AcpiSetFirmwareWakingVector(0, 0);
} else {

View File

@ -193,6 +193,9 @@ init_amd(void)
hw_lower_amd64_sharedpage = 1;
}
}
/* Zenbleed. See the comments in 'cpu_machdep.c'. */
zenbleed_check_and_apply(false);
}
/*

View File

@ -1495,6 +1495,10 @@ hammer_time(u_int64_t modulep, u_int64_t physfree)
TUNABLE_INT_FETCH("machdep.mitigations.rndgs.enable",
&x86_rngds_mitg_enable);
TUNABLE_INT_FETCH("machdep.mitigations.zenbleed.enable",
&zenbleed_enable);
zenbleed_sanitize_enable();
finishidentcpu(); /* Final stage of CPU initialization */
/*

View File

@ -546,6 +546,7 @@ cpuctl_do_eval_cpu_features(int cpu, struct thread *td)
hw_mds_recalculate();
x86_taa_recalculate();
x86_rngds_mitg_recalculate(true);
zenbleed_check_and_apply(true);
printcpuinfo();
return (0);
}

View File

@ -1172,6 +1172,7 @@
/* MSR_DE_CFG */
#define DE_CFG_10H_12H_STACK_POINTER_JUMP_FIX_BIT 0x1
#define DE_CFG_ZEN_LOAD_STALE_DATA_FIX_BIT 0x2000
#define DE_CFG_ZEN2_FP_BACKUP_FIX_BIT 0x200
/* VIA ACE crypto featureset: for via_feature_rng */
#define VIA_HAS_RNG 1 /* cpu has RNG */

View File

@ -90,6 +90,7 @@ extern int hw_ssb_active;
extern int x86_taa_enable;
extern int cpu_flush_rsb_ctxsw;
extern int x86_rngds_mitg_enable;
extern int zenbleed_enable;
extern int cpu_amdc1e_bug;
extern char bootmethod[16];
@ -140,6 +141,8 @@ void hw_mds_recalculate(void);
void hw_ssb_recalculate(bool all_cpus);
void x86_taa_recalculate(void);
void x86_rngds_mitg_recalculate(bool all_cpus);
void zenbleed_sanitize_enable(void);
void zenbleed_check_and_apply(bool all_cpus);
void nmi_call_kdb(u_int cpu, u_int type, struct trapframe *frame);
void nmi_call_kdb_smp(u_int type, struct trapframe *frame);
void nmi_handle_intr(u_int type, struct trapframe *frame);

View File

@ -1477,6 +1477,129 @@ SYSCTL_PROC(_machdep_mitigations_rngds, OID_AUTO, state,
sysctl_rngds_state_handler, "A",
"MCU Optimization state");
/*
* Zenbleed.
*
* No corresponding errata is publicly listed. AMD has issued a security
* bulletin (AMD-SB-7008), entitled "Cross-Process Information Leak". This
* document lists (as of August 2023) platform firmware's availability target
* dates, with most being November/December 2023. It will then be up to
* motherboard manufacturers to produce corresponding BIOS updates, which will
* happen with an inevitable lag. Additionally, for a variety of reasons,
* operators might not be able to apply them everywhere due. On the side of
* standalone CPU microcodes, no plans for availability have been published so
* far. However, a developer appearing to be an AMD employee has hardcoded in
* Linux revision numbers of future microcodes that are presumed to fix the
* vulnerability.
*
* Given the stability issues encountered with early microcode releases for Rome
* (the only microcode publicly released so far) and the absence of official
* communication on standalone CPU microcodes, we have opted instead for
* matching by default all AMD Zen2 processors which, according to the
* vulnerability's discoverer, are all affected (see
* https://lock.cmpxchg8b.com/zenbleed.html). This policy, also adopted by
* OpenBSD, may be overriden using the tunable/sysctl
* 'machdep.mitigations.zenbleed.enable'. We might revise it later depending on
* official statements, microcode updates' public availability and community
* assessment that they actually fix the vulnerability without any instability
* side effects.
*/
SYSCTL_NODE(_machdep_mitigations, OID_AUTO, zenbleed,
CTLFLAG_RW | CTLFLAG_MPSAFE, 0,
"Zenbleed OS-triggered prevention (via chicken bit)");
/* 2 is auto, see below. */
int zenbleed_enable = 2;
void
zenbleed_sanitize_enable(void)
{
/* Default to auto (2). */
if (zenbleed_enable < 0 || zenbleed_enable > 2)
zenbleed_enable = 2;
}
static bool
zenbleed_chicken_bit_applicable(void)
{
/* Concerns only bare-metal AMD Zen2 processors. */
return (cpu_vendor_id == CPU_VENDOR_AMD &&
CPUID_TO_FAMILY(cpu_id) == 0x17 &&
CPUID_TO_MODEL(cpu_id) >= 0x30 &&
vm_guest == VM_GUEST_NO);
}
static bool
zenbleed_chicken_bit_should_enable(void)
{
/*
* Obey tunable/sysctl.
*
* As explained above, currently, the automatic setting (2) and the "on"
* one (1) have the same effect. In the future, we might additionally
* check for specific microcode revisions as part of the automatic
* determination.
*/
return (zenbleed_enable != 0);
}
void
zenbleed_check_and_apply(bool all_cpus)
{
bool set;
if (!zenbleed_chicken_bit_applicable())
return;
set = zenbleed_chicken_bit_should_enable();
x86_msr_op(MSR_DE_CFG,
(set ? MSR_OP_OR : MSR_OP_ANDNOT) |
(all_cpus ? MSR_OP_RENDEZVOUS_ALL : MSR_OP_LOCAL),
DE_CFG_ZEN2_FP_BACKUP_FIX_BIT, NULL);
}
static int
sysctl_zenbleed_enable_handler(SYSCTL_HANDLER_ARGS)
{
int error, val;
val = zenbleed_enable;
error = sysctl_handle_int(oidp, &val, 0, req);
if (error != 0 || req->newptr == NULL)
return (error);
zenbleed_enable = val;
zenbleed_sanitize_enable();
zenbleed_check_and_apply(true);
return (0);
}
SYSCTL_PROC(_machdep_mitigations_zenbleed, OID_AUTO, enable, CTLTYPE_INT |
CTLFLAG_RWTUN | CTLFLAG_NOFETCH | CTLFLAG_MPSAFE, NULL, 0,
sysctl_zenbleed_enable_handler, "I",
"Enable Zenbleed OS-triggered mitigation (chicken bit) "
"(0: Force disable, 1: Force enable, 2: Automatic determination)");
static int
sysctl_zenbleed_state_handler(SYSCTL_HANDLER_ARGS)
{
const char *state;
if (!zenbleed_chicken_bit_applicable())
state = "Not applicable";
else if (zenbleed_chicken_bit_should_enable())
state = "Mitigation enabled";
else
state = "Mitigation disabled";
return (SYSCTL_OUT(req, state, strlen(state)));
}
SYSCTL_PROC(_machdep_mitigations_zenbleed, OID_AUTO, state,
CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_MPSAFE, NULL, 0,
sysctl_zenbleed_state_handler, "A",
"Zenbleed OS-triggered mitigation (chicken bit) state");
/*
* Enable and restore kernel text write permissions.
* Callers must ensure that disable_wp()/restore_wp() are executed