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 
_unprivileged_ebpf_enabled(void)8 static 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 
cpu_show_spectre_v1(struct device * dev,struct device_attribute * attr,char * buf)17 ssize_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 
23 static unsigned int spectre_v2_state;
24 static unsigned int spectre_v2_methods;
25 
spectre_v2_update_state(unsigned int state,unsigned int method)26 void 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 
cpu_show_spectre_v2(struct device * dev,struct device_attribute * attr,char * buf)33 ssize_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