1// SPDX-License-Identifier: GPL-2.0-only
2#include <linux/bpf.h>
3#include <linux/cpu.h>
4#include <linux/device.h>
5
6#include <asm/spectre.h>
7
8static bool _unprivileged_ebpf_enabled(void)
9{
10#ifdef CONFIG_BPF_SYSCALL
11	return !sysctl_unprivileged_bpf_disabled;
12#else
13	return false;
14#endif
15}
16
17ssize_t cpu_show_spectre_v1(struct device *dev, struct device_attribute *attr,
18			    char *buf)
19{
20	return sprintf(buf, "Mitigation: __user pointer sanitization\n");
21}
22
23static unsigned int spectre_v2_state;
24static unsigned int spectre_v2_methods;
25
26void spectre_v2_update_state(unsigned int state, unsigned int method)
27{
28	if (state > spectre_v2_state)
29		spectre_v2_state = state;
30	spectre_v2_methods |= method;
31}
32
33ssize_t cpu_show_spectre_v2(struct device *dev, struct device_attribute *attr,
34			    char *buf)
35{
36	const char *method;
37
38	if (spectre_v2_state == SPECTRE_UNAFFECTED)
39		return sprintf(buf, "%s\n", "Not affected");
40
41	if (spectre_v2_state != SPECTRE_MITIGATED)
42		return sprintf(buf, "%s\n", "Vulnerable");
43
44	if (_unprivileged_ebpf_enabled())
45		return sprintf(buf, "Vulnerable: Unprivileged eBPF enabled\n");
46
47	switch (spectre_v2_methods) {
48	case SPECTRE_V2_METHOD_BPIALL:
49		method = "Branch predictor hardening";
50		break;
51
52	case SPECTRE_V2_METHOD_ICIALLU:
53		method = "I-cache invalidation";
54		break;
55
56	case SPECTRE_V2_METHOD_SMC:
57	case SPECTRE_V2_METHOD_HVC:
58		method = "Firmware call";
59		break;
60
61	case SPECTRE_V2_METHOD_LOOP8:
62		method = "History overwrite";
63		break;
64
65	default:
66		method = "Multiple mitigations";
67		break;
68	}
69
70	return sprintf(buf, "Mitigation: %s\n", method);
71}
72