systemd: Support `mitigations=` kernel parameter to disable SMT

This is an alternate way of disabling SMT in the kernel. E. g. Fedora
CoreOS uses `mitigations=auto,nosmt` by default. Recognize this argument
and drop `nosmt` from it when re-enabling SMT.

Continue to always write the explicit `nosmt` argument, though.

Fixes #13138
Closes #13166
This commit is contained in:
Martin Pitt 2019-11-18 17:48:26 +01:00 committed by Martin Pitt
parent d4c500f8b2
commit 835e702e5f
2 changed files with 34 additions and 4 deletions

View File

@ -147,8 +147,13 @@ function availableMitigations() {
const nosmt_enabled = (values[1].indexOf("nosmt") !== -1 && values[1].indexOf("nosmt=") === -1) || values[1].indexOf("nosmt=force") !== -1;
/* available if threads>1 and the cmdline is valid */
const nosmt_available = threads_per_core > 1 && (values[1].indexOf("nosmt=") === -1 || values[1].indexOf("nosmt=force") !== -1);
const mitigations_match = values[1].match(/\bmitigations=(\S*)\b/);
availableMitigations.cachedMitigations = { available: nosmt_available, nosmt_enabled: nosmt_enabled };
availableMitigations.cachedMitigations = {
available: nosmt_available,
nosmt_enabled: nosmt_enabled,
mitigations_arg: mitigations_match ? mitigations_match[1] : undefined,
};
return availableMitigations.cachedMitigations;
});
}
@ -176,10 +181,18 @@ class CPUSecurityMitigationsDialog extends React.Component {
saveAndReboot() {
let options = [];
if (this.state.nosmt)
if (this.state.nosmt) {
options = ['set', 'nosmt'];
else
options = ['remove', 'nosmt'];
} else {
// this may either be an argument of its own, or part of mitigations=
const ma = availableMitigations.cachedMitigations.mitigations_arg;
if (ma && ma.indexOf("nosmt") >= 0) {
const new_args = ma.split(',').filter(opt => opt != 'nosmt');
options = ['set', 'mitigations=' + new_args.join(',')];
} else {
options = ['remove', 'nosmt'];
}
}
cockpit.script(kernelopt_sh, options, { superuser: "require", err: "message" })
.then(() => {

View File

@ -658,6 +658,23 @@ fi
else:
self.assertNotIn('nosmt', m.execute('cat /proc/cmdline'))
# updates mitigations=nosmt when that is present
if m.image != "rhel-8-1-distropkg": # fixed in PR #13166
m.upload(["../pkg/systemd/kernelopt.sh"], "/tmp/")
m.execute("/tmp/kernelopt.sh remove nosmt && /tmp/kernelopt.sh set mitigations=auto,nosmt")
m.spawn("sync && sleep 0.1 && reboot", "reboot")
m.wait_reboot()
self.login_and_go('/system/hwinfo')
b.click('#hwinfo button:contains(Mitigations)')
b.wait_present('#cpu-mitigations-dialog span:contains(nosmt)')
b.wait_present('#cpu-mitigations-dialog #nosmt-switch input:checked')
b.click('#cpu-mitigations-dialog #nosmt-switch input')
b.wait_present('#cpu-mitigations-dialog #nosmt-switch input:not(:checked)')
b.click('#cpu-mitigations-dialog Button:contains(Save and reboot)')
m.wait_reboot()
self.assertNotIn('nosmt', m.execute('cat /proc/cmdline'))
self.assertIn('mitigations=auto', m.execute('cat /proc/cmdline'))
# Behaviour for non-admins
self.login_and_go('/system/hwinfo', authorized=False)
b.wait_present('#hwinfo th:contains(CPU)')