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