summaryrefslogtreecommitdiff
path: root/arch/arm64/kernel/cpu_errata.c
diff options
context:
space:
mode:
authorChristoph Muellner <christoph.muellner@theobroma-systems.com>2018-03-20 11:16:02 +0100
committerChristoph Muellner <christoph.muellner@theobroma-systems.com>2018-04-05 22:33:45 +0200
commitf08166b6816dea1dff2c18785b104af650382e86 (patch)
tree98edcc6f70442fb4120a01aa296581a9f1ae571a /arch/arm64/kernel/cpu_errata.c
parent110b33618f3c55f2af17e4d3f7adbab4c2b81c43 (diff)
arm64: Introduce retpoline for aarch64/arm64.
This patch adds retpoline support for aarch64. This includes: * Kconfig flag CONFIG_RETPOLINE to enable it * testing for required compiler support * generation of external retpoline thunk functions * patches for the arm64 specific assembly code * Enable /sys/devices/system/cpu/vulnerabilities * Add thunk prototypes to asm/asm-prototypes.h Signed-off-by: Christoph Muellner <christoph.muellner@theobroma-systems.com>
Diffstat (limited to 'arch/arm64/kernel/cpu_errata.c')
-rw-r--r--arch/arm64/kernel/cpu_errata.c64
1 files changed, 64 insertions, 0 deletions
diff --git a/arch/arm64/kernel/cpu_errata.c b/arch/arm64/kernel/cpu_errata.c
index 52f15cd896e1..a0b66529f331 100644
--- a/arch/arm64/kernel/cpu_errata.c
+++ b/arch/arm64/kernel/cpu_errata.c
@@ -462,3 +462,67 @@ void __init enable_errata_workarounds(void)
{
enable_cpu_capabilities(arm64_errata);
}
+
+static inline bool retp_compiler(void)
+{
+ return __is_defined(RETPOLINE);
+}
+
+/* The Spectre V2 mitigation variants */
+enum spectre_v2_mitigation {
+ SPECTRE_V2_NONE,
+ SPECTRE_V2_RETPOLINE_MINIMAL,
+ SPECTRE_V2_RETPOLINE_GENERIC,
+};
+
+static const char *spectre_v2_strings[] = {
+ [SPECTRE_V2_NONE] = "Vulnerable",
+ [SPECTRE_V2_RETPOLINE_MINIMAL] = "Vulnerable: Minimal generic ASM retpoline",
+ [SPECTRE_V2_RETPOLINE_GENERIC] = "Mitigation: Full generic retpoline",
+};
+
+enum spectre_v2_mitigation get_spectre_v2_mitigation(void)
+{
+ enum spectre_v2_mitigation mode;
+
+#ifndef RETPOLINE
+ return SPECTRE_V2_NONE;
+#endif
+
+ mode = retp_compiler() ? SPECTRE_V2_RETPOLINE_GENERIC :
+ SPECTRE_V2_RETPOLINE_MINIMAL;
+
+ return mode;
+}
+
+#ifdef RETPOLINE
+static bool spectre_v2_bad_module;
+
+bool retpoline_module_ok(bool has_retpoline)
+{
+ if (has_retpoline)
+ return true;
+
+ pr_err("System may be vulnerable to spectre v2\n");
+ spectre_v2_bad_module = true;
+ return false;
+}
+
+static inline const char *spectre_v2_module_string(void)
+{
+ return spectre_v2_bad_module ? " - vulnerable module loaded" : "";
+}
+#else
+static inline const char *spectre_v2_module_string(void) { return ""; }
+#endif
+
+#ifdef CONFIG_SYSFS
+ssize_t cpu_show_spectre_v2(struct device *dev, struct device_attribute *attr, char *buf)
+{
+ enum spectre_v2_mitigation mode;
+
+ mode = get_spectre_v2_mitigation();
+ return sprintf(buf, "%s%s\n", spectre_v2_strings[mode],
+ spectre_v2_module_string());
+}
+#endif