2018-03-27 20:01:44 +08:00
|
|
|
// SPDX-License-Identifier: GPL-2.0+
|
|
|
|
//
|
|
|
|
// Security related flags and so on.
|
|
|
|
//
|
|
|
|
// Copyright 2018, Michael Ellerman, IBM Corporation.
|
|
|
|
|
|
|
|
#include <linux/kernel.h>
|
2018-03-27 20:01:48 +08:00
|
|
|
#include <linux/device.h>
|
2018-03-27 20:01:49 +08:00
|
|
|
#include <linux/seq_buf.h>
|
2018-03-27 20:01:48 +08:00
|
|
|
|
2018-03-27 20:01:44 +08:00
|
|
|
#include <asm/security_features.h>
|
2018-04-24 12:15:55 +08:00
|
|
|
#include <asm/setup.h>
|
2018-03-27 20:01:44 +08:00
|
|
|
|
|
|
|
|
2018-03-31 01:28:24 +08:00
|
|
|
unsigned long powerpc_security_features __read_mostly = SEC_FTR_DEFAULT;
|
2018-03-27 20:01:48 +08:00
|
|
|
|
2018-04-24 12:15:55 +08:00
|
|
|
static bool barrier_nospec_enabled;
|
|
|
|
|
|
|
|
static void enable_barrier_nospec(bool enable)
|
|
|
|
{
|
|
|
|
barrier_nospec_enabled = enable;
|
|
|
|
do_barrier_nospec_fixups(enable);
|
|
|
|
}
|
|
|
|
|
2018-03-27 20:01:48 +08:00
|
|
|
ssize_t cpu_show_meltdown(struct device *dev, struct device_attribute *attr, char *buf)
|
|
|
|
{
|
2018-03-27 20:01:49 +08:00
|
|
|
bool thread_priv;
|
|
|
|
|
|
|
|
thread_priv = security_ftr_enabled(SEC_FTR_L1D_THREAD_PRIV);
|
|
|
|
|
|
|
|
if (rfi_flush || thread_priv) {
|
|
|
|
struct seq_buf s;
|
|
|
|
seq_buf_init(&s, buf, PAGE_SIZE - 1);
|
|
|
|
|
|
|
|
seq_buf_printf(&s, "Mitigation: ");
|
|
|
|
|
|
|
|
if (rfi_flush)
|
|
|
|
seq_buf_printf(&s, "RFI Flush");
|
|
|
|
|
|
|
|
if (rfi_flush && thread_priv)
|
|
|
|
seq_buf_printf(&s, ", ");
|
|
|
|
|
|
|
|
if (thread_priv)
|
|
|
|
seq_buf_printf(&s, "L1D private per thread");
|
|
|
|
|
|
|
|
seq_buf_printf(&s, "\n");
|
|
|
|
|
|
|
|
return s.len;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!security_ftr_enabled(SEC_FTR_L1D_FLUSH_HV) &&
|
|
|
|
!security_ftr_enabled(SEC_FTR_L1D_FLUSH_PR))
|
|
|
|
return sprintf(buf, "Not affected\n");
|
2018-03-27 20:01:48 +08:00
|
|
|
|
|
|
|
return sprintf(buf, "Vulnerable\n");
|
|
|
|
}
|
2018-03-27 20:01:52 +08:00
|
|
|
|
|
|
|
ssize_t cpu_show_spectre_v1(struct device *dev, struct device_attribute *attr, char *buf)
|
|
|
|
{
|
|
|
|
if (!security_ftr_enabled(SEC_FTR_BNDS_CHK_SPEC_BAR))
|
|
|
|
return sprintf(buf, "Not affected\n");
|
|
|
|
|
|
|
|
return sprintf(buf, "Vulnerable\n");
|
|
|
|
}
|
2018-03-27 20:01:53 +08:00
|
|
|
|
|
|
|
ssize_t cpu_show_spectre_v2(struct device *dev, struct device_attribute *attr, char *buf)
|
|
|
|
{
|
|
|
|
bool bcs, ccd, ori;
|
|
|
|
struct seq_buf s;
|
|
|
|
|
|
|
|
seq_buf_init(&s, buf, PAGE_SIZE - 1);
|
|
|
|
|
|
|
|
bcs = security_ftr_enabled(SEC_FTR_BCCTRL_SERIALISED);
|
|
|
|
ccd = security_ftr_enabled(SEC_FTR_COUNT_CACHE_DISABLED);
|
|
|
|
ori = security_ftr_enabled(SEC_FTR_SPEC_BAR_ORI31);
|
|
|
|
|
|
|
|
if (bcs || ccd) {
|
|
|
|
seq_buf_printf(&s, "Mitigation: ");
|
|
|
|
|
|
|
|
if (bcs)
|
|
|
|
seq_buf_printf(&s, "Indirect branch serialisation (kernel only)");
|
|
|
|
|
|
|
|
if (bcs && ccd)
|
|
|
|
seq_buf_printf(&s, ", ");
|
|
|
|
|
|
|
|
if (ccd)
|
|
|
|
seq_buf_printf(&s, "Indirect branch cache disabled");
|
|
|
|
} else
|
|
|
|
seq_buf_printf(&s, "Vulnerable");
|
|
|
|
|
|
|
|
if (ori)
|
|
|
|
seq_buf_printf(&s, ", ori31 speculation barrier enabled");
|
|
|
|
|
|
|
|
seq_buf_printf(&s, "\n");
|
|
|
|
|
|
|
|
return s.len;
|
|
|
|
}
|