| // 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); | |
| } |