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:
parent
c6cc06d465
commit
ebaea1bcd2
@ -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 {
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -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 */
|
||||
|
||||
/*
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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 */
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user