diff options
author | Christoph Muellner <christoph.muellner@theobroma-systems.com> | 2018-03-20 11:16:02 +0100 |
---|---|---|
committer | Christoph Muellner <christoph.muellner@theobroma-systems.com> | 2018-04-05 22:33:45 +0200 |
commit | f08166b6816dea1dff2c18785b104af650382e86 (patch) | |
tree | 98edcc6f70442fb4120a01aa296581a9f1ae571a /arch/arm64/kernel/cpu_errata.c | |
parent | 110b33618f3c55f2af17e4d3f7adbab4c2b81c43 (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.c | 64 |
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 |