summaryrefslogtreecommitdiff
path: root/arch/arm/kernel/spectre.c
blob: 0dcefc36fb7a08af113ef923af1fe9c826da662d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
// SPDX-License-Identifier: GPL-2.0-only
#include <linux/bpf.h>
#include <linux/cpu.h>
#include <linux/device.h>

#include <asm/spectre.h>

static bool _unprivileged_ebpf_enabled(void)
{
#ifdef CONFIG_BPF_SYSCALL
	return !sysctl_unprivileged_bpf_disabled;
#else
	return false;
#endif
}

ssize_t cpu_show_spectre_v1(struct device *dev, struct device_attribute *attr,
			    char *buf)
{
	return sprintf(buf, "Mitigation: __user pointer sanitization\n");
}

static unsigned int spectre_v2_state;
static unsigned int spectre_v2_methods;

void spectre_v2_update_state(unsigned int state, unsigned int method)
{
	if (state > spectre_v2_state)
		spectre_v2_state = state;
	spectre_v2_methods |= method;
}

ssize_t cpu_show_spectre_v2(struct device *dev, struct device_attribute *attr,
			    char *buf)
{
	const char *method;

	if (spectre_v2_state == SPECTRE_UNAFFECTED)
		return sprintf(buf, "%s\n", "Not affected");

	if (spectre_v2_state != SPECTRE_MITIGATED)
		return sprintf(buf, "%s\n", "Vulnerable");

	if (_unprivileged_ebpf_enabled())
		return sprintf(buf, "Vulnerable: Unprivileged eBPF enabled\n");

	switch (spectre_v2_methods) {
	case SPECTRE_V2_METHOD_BPIALL:
		method = "Branch predictor hardening";
		break;

	case SPECTRE_V2_METHOD_ICIALLU:
		method = "I-cache invalidation";
		break;

	case SPECTRE_V2_METHOD_SMC:
	case SPECTRE_V2_METHOD_HVC:
		method = "Firmware call";
		break;

	case SPECTRE_V2_METHOD_LOOP8:
		method = "History overwrite";
		break;

	default:
		method = "Multiple mitigations";
		break;
	}

	return sprintf(buf, "Mitigation: %s\n", method);
}