1455697adSWill Deacon // SPDX-License-Identifier: GPL-2.0-only 2455697adSWill Deacon /* 3455697adSWill Deacon * Handle detection, reporting and mitigation of Spectre v1, v2 and v4, as 4455697adSWill Deacon * detailed at: 5455697adSWill Deacon * 6455697adSWill Deacon * https://developer.arm.com/support/arm-security-updates/speculative-processor-vulnerability 7455697adSWill Deacon * 8455697adSWill Deacon * This code was originally written hastily under an awful lot of stress and so 9455697adSWill Deacon * aspects of it are somewhat hacky. Unfortunately, changing anything in here 10455697adSWill Deacon * instantly makes me feel ill. Thanks, Jann. Thann. 11455697adSWill Deacon * 12455697adSWill Deacon * Copyright (C) 2018 ARM Ltd, All Rights Reserved. 13455697adSWill Deacon * Copyright (C) 2020 Google LLC 14455697adSWill Deacon * 15455697adSWill Deacon * "If there's something strange in your neighbourhood, who you gonna call?" 16455697adSWill Deacon * 17455697adSWill Deacon * Authors: Will Deacon <will@kernel.org> and Marc Zyngier <maz@kernel.org> 18455697adSWill Deacon */ 19455697adSWill Deacon 20d4647f0aSWill Deacon #include <linux/arm-smccc.h> 21d4647f0aSWill Deacon #include <linux/cpu.h> 22455697adSWill Deacon #include <linux/device.h> 239e78b659SWill Deacon #include <linux/nospec.h> 24d4647f0aSWill Deacon #include <linux/prctl.h> 255c8b0cbdSWill Deacon #include <linux/sched/task_stack.h> 26d4647f0aSWill Deacon 27d4647f0aSWill Deacon #include <asm/spectre.h> 28d4647f0aSWill Deacon #include <asm/traps.h> 29d4647f0aSWill Deacon 30d4647f0aSWill Deacon /* 31d4647f0aSWill Deacon * We try to ensure that the mitigation state can never change as the result of 32d4647f0aSWill Deacon * onlining a late CPU. 33d4647f0aSWill Deacon */ 34d4647f0aSWill Deacon static void update_mitigation_state(enum mitigation_state *oldp, 35d4647f0aSWill Deacon enum mitigation_state new) 36d4647f0aSWill Deacon { 37d4647f0aSWill Deacon enum mitigation_state state; 38d4647f0aSWill Deacon 39d4647f0aSWill Deacon do { 40d4647f0aSWill Deacon state = READ_ONCE(*oldp); 41d4647f0aSWill Deacon if (new <= state) 42d4647f0aSWill Deacon break; 43d4647f0aSWill Deacon 44d4647f0aSWill Deacon /* Userspace almost certainly can't deal with this. */ 45d4647f0aSWill Deacon if (WARN_ON(system_capabilities_finalized())) 46d4647f0aSWill Deacon break; 47d4647f0aSWill Deacon } while (cmpxchg_relaxed(oldp, state, new) != state); 48d4647f0aSWill Deacon } 49455697adSWill Deacon 50455697adSWill Deacon /* 51455697adSWill Deacon * Spectre v1. 52455697adSWill Deacon * 53455697adSWill Deacon * The kernel can't protect userspace for this one: it's each person for 54455697adSWill Deacon * themselves. Advertise what we're doing and be done with it. 55455697adSWill Deacon */ 56455697adSWill Deacon ssize_t cpu_show_spectre_v1(struct device *dev, struct device_attribute *attr, 57455697adSWill Deacon char *buf) 58455697adSWill Deacon { 59455697adSWill Deacon return sprintf(buf, "Mitigation: __user pointer sanitization\n"); 60455697adSWill Deacon } 61d4647f0aSWill Deacon 62d4647f0aSWill Deacon /* 63d4647f0aSWill Deacon * Spectre v2. 64d4647f0aSWill Deacon * 65d4647f0aSWill Deacon * This one sucks. A CPU is either: 66d4647f0aSWill Deacon * 67d4647f0aSWill Deacon * - Mitigated in hardware and advertised by ID_AA64PFR0_EL1.CSV2. 68d4647f0aSWill Deacon * - Mitigated in hardware and listed in our "safe list". 69d4647f0aSWill Deacon * - Mitigated in software by firmware. 70d4647f0aSWill Deacon * - Mitigated in software by a CPU-specific dance in the kernel. 71d4647f0aSWill Deacon * - Vulnerable. 72d4647f0aSWill Deacon * 73d4647f0aSWill Deacon * It's not unlikely for different CPUs in a big.LITTLE system to fall into 74d4647f0aSWill Deacon * different camps. 75d4647f0aSWill Deacon */ 76d4647f0aSWill Deacon static enum mitigation_state spectre_v2_state; 77d4647f0aSWill Deacon 78d4647f0aSWill Deacon static bool __read_mostly __nospectre_v2; 79d4647f0aSWill Deacon static int __init parse_spectre_v2_param(char *str) 80d4647f0aSWill Deacon { 81d4647f0aSWill Deacon __nospectre_v2 = true; 82d4647f0aSWill Deacon return 0; 83d4647f0aSWill Deacon } 84d4647f0aSWill Deacon early_param("nospectre_v2", parse_spectre_v2_param); 85d4647f0aSWill Deacon 86d4647f0aSWill Deacon static bool spectre_v2_mitigations_off(void) 87d4647f0aSWill Deacon { 88d4647f0aSWill Deacon bool ret = __nospectre_v2 || cpu_mitigations_off(); 89d4647f0aSWill Deacon 90d4647f0aSWill Deacon if (ret) 91d4647f0aSWill Deacon pr_info_once("spectre-v2 mitigation disabled by command line option\n"); 92d4647f0aSWill Deacon 93d4647f0aSWill Deacon return ret; 94d4647f0aSWill Deacon } 95d4647f0aSWill Deacon 96d4647f0aSWill Deacon ssize_t cpu_show_spectre_v2(struct device *dev, struct device_attribute *attr, 97d4647f0aSWill Deacon char *buf) 98d4647f0aSWill Deacon { 99d4647f0aSWill Deacon switch (spectre_v2_state) { 100d4647f0aSWill Deacon case SPECTRE_UNAFFECTED: 101d4647f0aSWill Deacon return sprintf(buf, "Not affected\n"); 102d4647f0aSWill Deacon case SPECTRE_MITIGATED: 103d4647f0aSWill Deacon return sprintf(buf, "Mitigation: Branch predictor hardening\n"); 104d4647f0aSWill Deacon case SPECTRE_VULNERABLE: 105d4647f0aSWill Deacon fallthrough; 106d4647f0aSWill Deacon default: 107d4647f0aSWill Deacon return sprintf(buf, "Vulnerable\n"); 108d4647f0aSWill Deacon } 109d4647f0aSWill Deacon } 110d4647f0aSWill Deacon 111d4647f0aSWill Deacon static enum mitigation_state spectre_v2_get_cpu_hw_mitigation_state(void) 112d4647f0aSWill Deacon { 113d4647f0aSWill Deacon u64 pfr0; 114d4647f0aSWill Deacon static const struct midr_range spectre_v2_safe_list[] = { 115d4647f0aSWill Deacon MIDR_ALL_VERSIONS(MIDR_CORTEX_A35), 116d4647f0aSWill Deacon MIDR_ALL_VERSIONS(MIDR_CORTEX_A53), 117d4647f0aSWill Deacon MIDR_ALL_VERSIONS(MIDR_CORTEX_A55), 118d4647f0aSWill Deacon MIDR_ALL_VERSIONS(MIDR_BRAHMA_B53), 119d4647f0aSWill Deacon MIDR_ALL_VERSIONS(MIDR_HISI_TSV110), 120d4647f0aSWill Deacon MIDR_ALL_VERSIONS(MIDR_QCOM_KRYO_3XX_SILVER), 121d4647f0aSWill Deacon MIDR_ALL_VERSIONS(MIDR_QCOM_KRYO_4XX_SILVER), 122d4647f0aSWill Deacon { /* sentinel */ } 123d4647f0aSWill Deacon }; 124d4647f0aSWill Deacon 125d4647f0aSWill Deacon /* If the CPU has CSV2 set, we're safe */ 126d4647f0aSWill Deacon pfr0 = read_cpuid(ID_AA64PFR0_EL1); 127d4647f0aSWill Deacon if (cpuid_feature_extract_unsigned_field(pfr0, ID_AA64PFR0_CSV2_SHIFT)) 128d4647f0aSWill Deacon return SPECTRE_UNAFFECTED; 129d4647f0aSWill Deacon 130d4647f0aSWill Deacon /* Alternatively, we have a list of unaffected CPUs */ 131d4647f0aSWill Deacon if (is_midr_in_range_list(read_cpuid_id(), spectre_v2_safe_list)) 132d4647f0aSWill Deacon return SPECTRE_UNAFFECTED; 133d4647f0aSWill Deacon 134d4647f0aSWill Deacon return SPECTRE_VULNERABLE; 135d4647f0aSWill Deacon } 136d4647f0aSWill Deacon 137d4647f0aSWill Deacon #define SMCCC_ARCH_WORKAROUND_RET_UNAFFECTED (1) 138d4647f0aSWill Deacon 139d4647f0aSWill Deacon static enum mitigation_state spectre_v2_get_cpu_fw_mitigation_state(void) 140d4647f0aSWill Deacon { 141d4647f0aSWill Deacon int ret; 142d4647f0aSWill Deacon struct arm_smccc_res res; 143d4647f0aSWill Deacon 144d4647f0aSWill Deacon arm_smccc_1_1_invoke(ARM_SMCCC_ARCH_FEATURES_FUNC_ID, 145d4647f0aSWill Deacon ARM_SMCCC_ARCH_WORKAROUND_1, &res); 146d4647f0aSWill Deacon 147d4647f0aSWill Deacon ret = res.a0; 148d4647f0aSWill Deacon switch (ret) { 149d4647f0aSWill Deacon case SMCCC_RET_SUCCESS: 150d4647f0aSWill Deacon return SPECTRE_MITIGATED; 151d4647f0aSWill Deacon case SMCCC_ARCH_WORKAROUND_RET_UNAFFECTED: 152d4647f0aSWill Deacon return SPECTRE_UNAFFECTED; 153d4647f0aSWill Deacon default: 154d4647f0aSWill Deacon fallthrough; 155d4647f0aSWill Deacon case SMCCC_RET_NOT_SUPPORTED: 156d4647f0aSWill Deacon return SPECTRE_VULNERABLE; 157d4647f0aSWill Deacon } 158d4647f0aSWill Deacon } 159d4647f0aSWill Deacon 160d4647f0aSWill Deacon bool has_spectre_v2(const struct arm64_cpu_capabilities *entry, int scope) 161d4647f0aSWill Deacon { 162d4647f0aSWill Deacon WARN_ON(scope != SCOPE_LOCAL_CPU || preemptible()); 163d4647f0aSWill Deacon 164d4647f0aSWill Deacon if (spectre_v2_get_cpu_hw_mitigation_state() == SPECTRE_UNAFFECTED) 165d4647f0aSWill Deacon return false; 166d4647f0aSWill Deacon 167d4647f0aSWill Deacon if (spectre_v2_get_cpu_fw_mitigation_state() == SPECTRE_UNAFFECTED) 168d4647f0aSWill Deacon return false; 169d4647f0aSWill Deacon 170d4647f0aSWill Deacon return true; 171d4647f0aSWill Deacon } 172d4647f0aSWill Deacon 173d4647f0aSWill Deacon DEFINE_PER_CPU_READ_MOSTLY(struct bp_hardening_data, bp_hardening_data); 174d4647f0aSWill Deacon 175d4647f0aSWill Deacon enum mitigation_state arm64_get_spectre_v2_state(void) 176d4647f0aSWill Deacon { 177d4647f0aSWill Deacon return spectre_v2_state; 178d4647f0aSWill Deacon } 179d4647f0aSWill Deacon 180d4647f0aSWill Deacon #ifdef CONFIG_KVM 181d4647f0aSWill Deacon #include <asm/cacheflush.h> 182d4647f0aSWill Deacon #include <asm/kvm_asm.h> 183d4647f0aSWill Deacon 184d4647f0aSWill Deacon atomic_t arm64_el2_vector_last_slot = ATOMIC_INIT(-1); 185d4647f0aSWill Deacon 186d4647f0aSWill Deacon static void __copy_hyp_vect_bpi(int slot, const char *hyp_vecs_start, 187d4647f0aSWill Deacon const char *hyp_vecs_end) 188d4647f0aSWill Deacon { 189d4647f0aSWill Deacon void *dst = lm_alias(__bp_harden_hyp_vecs + slot * SZ_2K); 190d4647f0aSWill Deacon int i; 191d4647f0aSWill Deacon 192d4647f0aSWill Deacon for (i = 0; i < SZ_2K; i += 0x80) 193d4647f0aSWill Deacon memcpy(dst + i, hyp_vecs_start, hyp_vecs_end - hyp_vecs_start); 194d4647f0aSWill Deacon 195d4647f0aSWill Deacon __flush_icache_range((uintptr_t)dst, (uintptr_t)dst + SZ_2K); 196d4647f0aSWill Deacon } 197d4647f0aSWill Deacon 198d4647f0aSWill Deacon static void install_bp_hardening_cb(bp_hardening_cb_t fn) 199d4647f0aSWill Deacon { 200d4647f0aSWill Deacon static DEFINE_RAW_SPINLOCK(bp_lock); 201d4647f0aSWill Deacon int cpu, slot = -1; 202d4647f0aSWill Deacon const char *hyp_vecs_start = __smccc_workaround_1_smc; 203d4647f0aSWill Deacon const char *hyp_vecs_end = __smccc_workaround_1_smc + 204d4647f0aSWill Deacon __SMCCC_WORKAROUND_1_SMC_SZ; 205d4647f0aSWill Deacon 206d4647f0aSWill Deacon /* 207d4647f0aSWill Deacon * detect_harden_bp_fw() passes NULL for the hyp_vecs start/end if 208d4647f0aSWill Deacon * we're a guest. Skip the hyp-vectors work. 209d4647f0aSWill Deacon */ 210d4647f0aSWill Deacon if (!is_hyp_mode_available()) { 211d4647f0aSWill Deacon __this_cpu_write(bp_hardening_data.fn, fn); 212d4647f0aSWill Deacon return; 213d4647f0aSWill Deacon } 214d4647f0aSWill Deacon 215d4647f0aSWill Deacon raw_spin_lock(&bp_lock); 216d4647f0aSWill Deacon for_each_possible_cpu(cpu) { 217d4647f0aSWill Deacon if (per_cpu(bp_hardening_data.fn, cpu) == fn) { 218d4647f0aSWill Deacon slot = per_cpu(bp_hardening_data.hyp_vectors_slot, cpu); 219d4647f0aSWill Deacon break; 220d4647f0aSWill Deacon } 221d4647f0aSWill Deacon } 222d4647f0aSWill Deacon 223d4647f0aSWill Deacon if (slot == -1) { 224d4647f0aSWill Deacon slot = atomic_inc_return(&arm64_el2_vector_last_slot); 225d4647f0aSWill Deacon BUG_ON(slot >= BP_HARDEN_EL2_SLOTS); 226d4647f0aSWill Deacon __copy_hyp_vect_bpi(slot, hyp_vecs_start, hyp_vecs_end); 227d4647f0aSWill Deacon } 228d4647f0aSWill Deacon 229d4647f0aSWill Deacon __this_cpu_write(bp_hardening_data.hyp_vectors_slot, slot); 230d4647f0aSWill Deacon __this_cpu_write(bp_hardening_data.fn, fn); 231d4647f0aSWill Deacon raw_spin_unlock(&bp_lock); 232d4647f0aSWill Deacon } 233d4647f0aSWill Deacon #else 234d4647f0aSWill Deacon static void install_bp_hardening_cb(bp_hardening_cb_t fn) 235d4647f0aSWill Deacon { 236d4647f0aSWill Deacon __this_cpu_write(bp_hardening_data.fn, fn); 237d4647f0aSWill Deacon } 238d4647f0aSWill Deacon #endif /* CONFIG_KVM */ 239d4647f0aSWill Deacon 240d4647f0aSWill Deacon static void call_smc_arch_workaround_1(void) 241d4647f0aSWill Deacon { 242d4647f0aSWill Deacon arm_smccc_1_1_smc(ARM_SMCCC_ARCH_WORKAROUND_1, NULL); 243d4647f0aSWill Deacon } 244d4647f0aSWill Deacon 245d4647f0aSWill Deacon static void call_hvc_arch_workaround_1(void) 246d4647f0aSWill Deacon { 247d4647f0aSWill Deacon arm_smccc_1_1_hvc(ARM_SMCCC_ARCH_WORKAROUND_1, NULL); 248d4647f0aSWill Deacon } 249d4647f0aSWill Deacon 250d4647f0aSWill Deacon static void qcom_link_stack_sanitisation(void) 251d4647f0aSWill Deacon { 252d4647f0aSWill Deacon u64 tmp; 253d4647f0aSWill Deacon 254d4647f0aSWill Deacon asm volatile("mov %0, x30 \n" 255d4647f0aSWill Deacon ".rept 16 \n" 256d4647f0aSWill Deacon "bl . + 4 \n" 257d4647f0aSWill Deacon ".endr \n" 258d4647f0aSWill Deacon "mov x30, %0 \n" 259d4647f0aSWill Deacon : "=&r" (tmp)); 260d4647f0aSWill Deacon } 261d4647f0aSWill Deacon 262d4647f0aSWill Deacon static enum mitigation_state spectre_v2_enable_fw_mitigation(void) 263d4647f0aSWill Deacon { 264d4647f0aSWill Deacon bp_hardening_cb_t cb; 265d4647f0aSWill Deacon enum mitigation_state state; 266d4647f0aSWill Deacon 267d4647f0aSWill Deacon state = spectre_v2_get_cpu_fw_mitigation_state(); 268d4647f0aSWill Deacon if (state != SPECTRE_MITIGATED) 269d4647f0aSWill Deacon return state; 270d4647f0aSWill Deacon 271d4647f0aSWill Deacon if (spectre_v2_mitigations_off()) 272d4647f0aSWill Deacon return SPECTRE_VULNERABLE; 273d4647f0aSWill Deacon 274d4647f0aSWill Deacon switch (arm_smccc_1_1_get_conduit()) { 275d4647f0aSWill Deacon case SMCCC_CONDUIT_HVC: 276d4647f0aSWill Deacon cb = call_hvc_arch_workaround_1; 277d4647f0aSWill Deacon break; 278d4647f0aSWill Deacon 279d4647f0aSWill Deacon case SMCCC_CONDUIT_SMC: 280d4647f0aSWill Deacon cb = call_smc_arch_workaround_1; 281d4647f0aSWill Deacon break; 282d4647f0aSWill Deacon 283d4647f0aSWill Deacon default: 284d4647f0aSWill Deacon return SPECTRE_VULNERABLE; 285d4647f0aSWill Deacon } 286d4647f0aSWill Deacon 287d4647f0aSWill Deacon install_bp_hardening_cb(cb); 288d4647f0aSWill Deacon return SPECTRE_MITIGATED; 289d4647f0aSWill Deacon } 290d4647f0aSWill Deacon 291d4647f0aSWill Deacon static enum mitigation_state spectre_v2_enable_sw_mitigation(void) 292d4647f0aSWill Deacon { 293d4647f0aSWill Deacon u32 midr; 294d4647f0aSWill Deacon 295d4647f0aSWill Deacon if (spectre_v2_mitigations_off()) 296d4647f0aSWill Deacon return SPECTRE_VULNERABLE; 297d4647f0aSWill Deacon 298d4647f0aSWill Deacon midr = read_cpuid_id(); 299d4647f0aSWill Deacon if (((midr & MIDR_CPU_MODEL_MASK) != MIDR_QCOM_FALKOR) && 300d4647f0aSWill Deacon ((midr & MIDR_CPU_MODEL_MASK) != MIDR_QCOM_FALKOR_V1)) 301d4647f0aSWill Deacon return SPECTRE_VULNERABLE; 302d4647f0aSWill Deacon 303d4647f0aSWill Deacon install_bp_hardening_cb(qcom_link_stack_sanitisation); 304d4647f0aSWill Deacon return SPECTRE_MITIGATED; 305d4647f0aSWill Deacon } 306d4647f0aSWill Deacon 307d4647f0aSWill Deacon void spectre_v2_enable_mitigation(const struct arm64_cpu_capabilities *__unused) 308d4647f0aSWill Deacon { 309d4647f0aSWill Deacon enum mitigation_state state; 310d4647f0aSWill Deacon 311d4647f0aSWill Deacon WARN_ON(preemptible()); 312d4647f0aSWill Deacon 313d4647f0aSWill Deacon state = spectre_v2_get_cpu_hw_mitigation_state(); 314d4647f0aSWill Deacon if (state == SPECTRE_VULNERABLE) 315d4647f0aSWill Deacon state = spectre_v2_enable_fw_mitigation(); 316d4647f0aSWill Deacon if (state == SPECTRE_VULNERABLE) 317d4647f0aSWill Deacon state = spectre_v2_enable_sw_mitigation(); 318d4647f0aSWill Deacon 319d4647f0aSWill Deacon update_mitigation_state(&spectre_v2_state, state); 320d4647f0aSWill Deacon } 3219e78b659SWill Deacon 322c2876207SWill Deacon /* 323c2876207SWill Deacon * Spectre v4. 324c2876207SWill Deacon * 325c2876207SWill Deacon * If you thought Spectre v2 was nasty, wait until you see this mess. A CPU is 326c2876207SWill Deacon * either: 327c2876207SWill Deacon * 328c2876207SWill Deacon * - Mitigated in hardware and listed in our "safe list". 329c2876207SWill Deacon * - Mitigated in hardware via PSTATE.SSBS. 330c2876207SWill Deacon * - Mitigated in software by firmware (sometimes referred to as SSBD). 331c2876207SWill Deacon * 332c2876207SWill Deacon * Wait, that doesn't sound so bad, does it? Keep reading... 333c2876207SWill Deacon * 334c2876207SWill Deacon * A major source of headaches is that the software mitigation is enabled both 335c2876207SWill Deacon * on a per-task basis, but can also be forced on for the kernel, necessitating 336c2876207SWill Deacon * both context-switch *and* entry/exit hooks. To make it even worse, some CPUs 337c2876207SWill Deacon * allow EL0 to toggle SSBS directly, which can end up with the prctl() state 338c2876207SWill Deacon * being stale when re-entering the kernel. The usual big.LITTLE caveats apply, 339c2876207SWill Deacon * so you can have systems that have both firmware and SSBS mitigations. This 340c2876207SWill Deacon * means we actually have to reject late onlining of CPUs with mitigations if 341c2876207SWill Deacon * all of the currently onlined CPUs are safelisted, as the mitigation tends to 342c2876207SWill Deacon * be opt-in for userspace. Yes, really, the cure is worse than the disease. 343c2876207SWill Deacon * 344c2876207SWill Deacon * The only good part is that if the firmware mitigation is present, then it is 345c2876207SWill Deacon * present for all CPUs, meaning we don't have to worry about late onlining of a 346c2876207SWill Deacon * vulnerable CPU if one of the boot CPUs is using the firmware mitigation. 347c2876207SWill Deacon * 348c2876207SWill Deacon * Give me a VAX-11/780 any day of the week... 349c2876207SWill Deacon */ 350c2876207SWill Deacon static enum mitigation_state spectre_v4_state; 3519e78b659SWill Deacon 352c2876207SWill Deacon /* This is the per-cpu state tracking whether we need to talk to firmware */ 353c2876207SWill Deacon DEFINE_PER_CPU_READ_MOSTLY(u64, arm64_ssbd_callback_required); 354c2876207SWill Deacon 355c2876207SWill Deacon enum spectre_v4_policy { 356c2876207SWill Deacon SPECTRE_V4_POLICY_MITIGATION_DYNAMIC, 357c2876207SWill Deacon SPECTRE_V4_POLICY_MITIGATION_ENABLED, 358c2876207SWill Deacon SPECTRE_V4_POLICY_MITIGATION_DISABLED, 359c2876207SWill Deacon }; 360c2876207SWill Deacon 361c2876207SWill Deacon static enum spectre_v4_policy __read_mostly __spectre_v4_policy; 362c2876207SWill Deacon 363c2876207SWill Deacon static const struct spectre_v4_param { 364c2876207SWill Deacon const char *str; 365c2876207SWill Deacon enum spectre_v4_policy policy; 366c2876207SWill Deacon } spectre_v4_params[] = { 367c2876207SWill Deacon { "force-on", SPECTRE_V4_POLICY_MITIGATION_ENABLED, }, 368c2876207SWill Deacon { "force-off", SPECTRE_V4_POLICY_MITIGATION_DISABLED, }, 369c2876207SWill Deacon { "kernel", SPECTRE_V4_POLICY_MITIGATION_DYNAMIC, }, 370c2876207SWill Deacon }; 371c2876207SWill Deacon static int __init parse_spectre_v4_param(char *str) 372c2876207SWill Deacon { 373c2876207SWill Deacon int i; 374c2876207SWill Deacon 375c2876207SWill Deacon if (!str || !str[0]) 376c2876207SWill Deacon return -EINVAL; 377c2876207SWill Deacon 378c2876207SWill Deacon for (i = 0; i < ARRAY_SIZE(spectre_v4_params); i++) { 379c2876207SWill Deacon const struct spectre_v4_param *param = &spectre_v4_params[i]; 380c2876207SWill Deacon 381c2876207SWill Deacon if (strncmp(str, param->str, strlen(param->str))) 382c2876207SWill Deacon continue; 383c2876207SWill Deacon 384c2876207SWill Deacon __spectre_v4_policy = param->policy; 385c2876207SWill Deacon return 0; 3869e78b659SWill Deacon } 3879e78b659SWill Deacon 388c2876207SWill Deacon return -EINVAL; 389c2876207SWill Deacon } 390c2876207SWill Deacon early_param("ssbd", parse_spectre_v4_param); 3919e78b659SWill Deacon 392c2876207SWill Deacon /* 393c2876207SWill Deacon * Because this was all written in a rush by people working in different silos, 394c2876207SWill Deacon * we've ended up with multiple command line options to control the same thing. 395c2876207SWill Deacon * Wrap these up in some helpers, which prefer disabling the mitigation if faced 396c2876207SWill Deacon * with contradictory parameters. The mitigation is always either "off", 397c2876207SWill Deacon * "dynamic" or "on". 398c2876207SWill Deacon */ 399c2876207SWill Deacon static bool spectre_v4_mitigations_off(void) 400c2876207SWill Deacon { 401c2876207SWill Deacon bool ret = cpu_mitigations_off() || 402c2876207SWill Deacon __spectre_v4_policy == SPECTRE_V4_POLICY_MITIGATION_DISABLED; 403c2876207SWill Deacon 404c2876207SWill Deacon if (ret) 405c2876207SWill Deacon pr_info_once("spectre-v4 mitigation disabled by command-line option\n"); 406c2876207SWill Deacon 407c2876207SWill Deacon return ret; 408c2876207SWill Deacon } 409c2876207SWill Deacon 410c2876207SWill Deacon /* Do we need to toggle the mitigation state on entry to/exit from the kernel? */ 411c2876207SWill Deacon static bool spectre_v4_mitigations_dynamic(void) 412c2876207SWill Deacon { 413c2876207SWill Deacon return !spectre_v4_mitigations_off() && 414c2876207SWill Deacon __spectre_v4_policy == SPECTRE_V4_POLICY_MITIGATION_DYNAMIC; 415c2876207SWill Deacon } 416c2876207SWill Deacon 417c2876207SWill Deacon static bool spectre_v4_mitigations_on(void) 418c2876207SWill Deacon { 419c2876207SWill Deacon return !spectre_v4_mitigations_off() && 420c2876207SWill Deacon __spectre_v4_policy == SPECTRE_V4_POLICY_MITIGATION_ENABLED; 421c2876207SWill Deacon } 422c2876207SWill Deacon 423c2876207SWill Deacon ssize_t cpu_show_spec_store_bypass(struct device *dev, 424c2876207SWill Deacon struct device_attribute *attr, char *buf) 425c2876207SWill Deacon { 426c2876207SWill Deacon switch (spectre_v4_state) { 427c2876207SWill Deacon case SPECTRE_UNAFFECTED: 428c2876207SWill Deacon return sprintf(buf, "Not affected\n"); 429c2876207SWill Deacon case SPECTRE_MITIGATED: 430c2876207SWill Deacon return sprintf(buf, "Mitigation: Speculative Store Bypass disabled via prctl\n"); 431c2876207SWill Deacon case SPECTRE_VULNERABLE: 432c2876207SWill Deacon fallthrough; 433c2876207SWill Deacon default: 434c2876207SWill Deacon return sprintf(buf, "Vulnerable\n"); 435c2876207SWill Deacon } 436c2876207SWill Deacon } 437c2876207SWill Deacon 438c2876207SWill Deacon enum mitigation_state arm64_get_spectre_v4_state(void) 439c2876207SWill Deacon { 440c2876207SWill Deacon return spectre_v4_state; 441c2876207SWill Deacon } 442c2876207SWill Deacon 443c2876207SWill Deacon static enum mitigation_state spectre_v4_get_cpu_hw_mitigation_state(void) 444c2876207SWill Deacon { 445c2876207SWill Deacon static const struct midr_range spectre_v4_safe_list[] = { 446c2876207SWill Deacon MIDR_ALL_VERSIONS(MIDR_CORTEX_A35), 447c2876207SWill Deacon MIDR_ALL_VERSIONS(MIDR_CORTEX_A53), 448c2876207SWill Deacon MIDR_ALL_VERSIONS(MIDR_CORTEX_A55), 449c2876207SWill Deacon MIDR_ALL_VERSIONS(MIDR_BRAHMA_B53), 450c2876207SWill Deacon MIDR_ALL_VERSIONS(MIDR_QCOM_KRYO_3XX_SILVER), 451c2876207SWill Deacon MIDR_ALL_VERSIONS(MIDR_QCOM_KRYO_4XX_SILVER), 452c2876207SWill Deacon { /* sentinel */ }, 453c2876207SWill Deacon }; 454c2876207SWill Deacon 455c2876207SWill Deacon if (is_midr_in_range_list(read_cpuid_id(), spectre_v4_safe_list)) 456c2876207SWill Deacon return SPECTRE_UNAFFECTED; 457c2876207SWill Deacon 458c2876207SWill Deacon /* CPU features are detected first */ 459c2876207SWill Deacon if (this_cpu_has_cap(ARM64_SSBS)) 460c2876207SWill Deacon return SPECTRE_MITIGATED; 461c2876207SWill Deacon 462c2876207SWill Deacon return SPECTRE_VULNERABLE; 463c2876207SWill Deacon } 464c2876207SWill Deacon 465c2876207SWill Deacon static enum mitigation_state spectre_v4_get_cpu_fw_mitigation_state(void) 466c2876207SWill Deacon { 467c2876207SWill Deacon int ret; 468c2876207SWill Deacon struct arm_smccc_res res; 469c2876207SWill Deacon 470c2876207SWill Deacon arm_smccc_1_1_invoke(ARM_SMCCC_ARCH_FEATURES_FUNC_ID, 471c2876207SWill Deacon ARM_SMCCC_ARCH_WORKAROUND_2, &res); 472c2876207SWill Deacon 473c2876207SWill Deacon ret = res.a0; 474c2876207SWill Deacon switch (ret) { 475c2876207SWill Deacon case SMCCC_RET_SUCCESS: 476c2876207SWill Deacon return SPECTRE_MITIGATED; 477c2876207SWill Deacon case SMCCC_ARCH_WORKAROUND_RET_UNAFFECTED: 478c2876207SWill Deacon fallthrough; 479c2876207SWill Deacon case SMCCC_RET_NOT_REQUIRED: 480c2876207SWill Deacon return SPECTRE_UNAFFECTED; 481c2876207SWill Deacon default: 482c2876207SWill Deacon fallthrough; 483c2876207SWill Deacon case SMCCC_RET_NOT_SUPPORTED: 484c2876207SWill Deacon return SPECTRE_VULNERABLE; 485c2876207SWill Deacon } 486c2876207SWill Deacon } 487c2876207SWill Deacon 488c2876207SWill Deacon bool has_spectre_v4(const struct arm64_cpu_capabilities *cap, int scope) 489c2876207SWill Deacon { 490c2876207SWill Deacon enum mitigation_state state; 491c2876207SWill Deacon 492c2876207SWill Deacon WARN_ON(scope != SCOPE_LOCAL_CPU || preemptible()); 493c2876207SWill Deacon 494c2876207SWill Deacon state = spectre_v4_get_cpu_hw_mitigation_state(); 495c2876207SWill Deacon if (state == SPECTRE_VULNERABLE) 496c2876207SWill Deacon state = spectre_v4_get_cpu_fw_mitigation_state(); 497c2876207SWill Deacon 498c2876207SWill Deacon return state != SPECTRE_UNAFFECTED; 499c2876207SWill Deacon } 500c2876207SWill Deacon 501c2876207SWill Deacon static int ssbs_emulation_handler(struct pt_regs *regs, u32 instr) 502c2876207SWill Deacon { 503c2876207SWill Deacon if (user_mode(regs)) 504c2876207SWill Deacon return 1; 505c2876207SWill Deacon 506c2876207SWill Deacon if (instr & BIT(PSTATE_Imm_shift)) 507c2876207SWill Deacon regs->pstate |= PSR_SSBS_BIT; 508c2876207SWill Deacon else 509c2876207SWill Deacon regs->pstate &= ~PSR_SSBS_BIT; 510c2876207SWill Deacon 511c2876207SWill Deacon arm64_skip_faulting_instruction(regs, 4); 512c2876207SWill Deacon return 0; 513c2876207SWill Deacon } 514c2876207SWill Deacon 515c2876207SWill Deacon static struct undef_hook ssbs_emulation_hook = { 516c2876207SWill Deacon .instr_mask = ~(1U << PSTATE_Imm_shift), 517c2876207SWill Deacon .instr_val = 0xd500401f | PSTATE_SSBS, 518c2876207SWill Deacon .fn = ssbs_emulation_handler, 519c2876207SWill Deacon }; 520c2876207SWill Deacon 521c2876207SWill Deacon static enum mitigation_state spectre_v4_enable_hw_mitigation(void) 522c2876207SWill Deacon { 523c2876207SWill Deacon static bool undef_hook_registered = false; 524c2876207SWill Deacon static DEFINE_RAW_SPINLOCK(hook_lock); 525c2876207SWill Deacon enum mitigation_state state; 526c2876207SWill Deacon 527c2876207SWill Deacon /* 528c2876207SWill Deacon * If the system is mitigated but this CPU doesn't have SSBS, then 529c2876207SWill Deacon * we must be on the safelist and there's nothing more to do. 530c2876207SWill Deacon */ 531c2876207SWill Deacon state = spectre_v4_get_cpu_hw_mitigation_state(); 532c2876207SWill Deacon if (state != SPECTRE_MITIGATED || !this_cpu_has_cap(ARM64_SSBS)) 533c2876207SWill Deacon return state; 534c2876207SWill Deacon 535c2876207SWill Deacon raw_spin_lock(&hook_lock); 536c2876207SWill Deacon if (!undef_hook_registered) { 537c2876207SWill Deacon register_undef_hook(&ssbs_emulation_hook); 538c2876207SWill Deacon undef_hook_registered = true; 539c2876207SWill Deacon } 540c2876207SWill Deacon raw_spin_unlock(&hook_lock); 541c2876207SWill Deacon 542c2876207SWill Deacon if (spectre_v4_mitigations_off()) { 543c2876207SWill Deacon sysreg_clear_set(sctlr_el1, 0, SCTLR_ELx_DSSBS); 544c2876207SWill Deacon asm volatile(SET_PSTATE_SSBS(1)); 545c2876207SWill Deacon return SPECTRE_VULNERABLE; 546c2876207SWill Deacon } 547c2876207SWill Deacon 548c2876207SWill Deacon /* SCTLR_EL1.DSSBS was initialised to 0 during boot */ 549c2876207SWill Deacon asm volatile(SET_PSTATE_SSBS(0)); 550c2876207SWill Deacon return SPECTRE_MITIGATED; 5519e78b659SWill Deacon } 5529e78b659SWill Deacon 5539e78b659SWill Deacon /* 554c2876207SWill Deacon * Patch a branch over the Spectre-v4 mitigation code with a NOP so that 555c2876207SWill Deacon * we fallthrough and check whether firmware needs to be called on this CPU. 556c2876207SWill Deacon */ 557c2876207SWill Deacon void __init spectre_v4_patch_fw_mitigation_enable(struct alt_instr *alt, 558c2876207SWill Deacon __le32 *origptr, 559c2876207SWill Deacon __le32 *updptr, int nr_inst) 560c2876207SWill Deacon { 561c2876207SWill Deacon BUG_ON(nr_inst != 1); /* Branch -> NOP */ 562c2876207SWill Deacon 563c2876207SWill Deacon if (spectre_v4_mitigations_off()) 564c2876207SWill Deacon return; 565c2876207SWill Deacon 566c2876207SWill Deacon if (cpus_have_final_cap(ARM64_SSBS)) 567c2876207SWill Deacon return; 568c2876207SWill Deacon 569c2876207SWill Deacon if (spectre_v4_mitigations_dynamic()) 570c2876207SWill Deacon *updptr = cpu_to_le32(aarch64_insn_gen_nop()); 571c2876207SWill Deacon } 572c2876207SWill Deacon 573c2876207SWill Deacon /* 574c2876207SWill Deacon * Patch a NOP in the Spectre-v4 mitigation code with an SMC/HVC instruction 575c2876207SWill Deacon * to call into firmware to adjust the mitigation state. 576c2876207SWill Deacon */ 577c2876207SWill Deacon void __init spectre_v4_patch_fw_mitigation_conduit(struct alt_instr *alt, 578c2876207SWill Deacon __le32 *origptr, 579c2876207SWill Deacon __le32 *updptr, int nr_inst) 580c2876207SWill Deacon { 581c2876207SWill Deacon u32 insn; 582c2876207SWill Deacon 583c2876207SWill Deacon BUG_ON(nr_inst != 1); /* NOP -> HVC/SMC */ 584c2876207SWill Deacon 585c2876207SWill Deacon switch (arm_smccc_1_1_get_conduit()) { 586c2876207SWill Deacon case SMCCC_CONDUIT_HVC: 587c2876207SWill Deacon insn = aarch64_insn_get_hvc_value(); 588c2876207SWill Deacon break; 589c2876207SWill Deacon case SMCCC_CONDUIT_SMC: 590c2876207SWill Deacon insn = aarch64_insn_get_smc_value(); 591c2876207SWill Deacon break; 592c2876207SWill Deacon default: 593c2876207SWill Deacon return; 594c2876207SWill Deacon } 595c2876207SWill Deacon 596c2876207SWill Deacon *updptr = cpu_to_le32(insn); 597c2876207SWill Deacon } 598c2876207SWill Deacon 599c2876207SWill Deacon static enum mitigation_state spectre_v4_enable_fw_mitigation(void) 600c2876207SWill Deacon { 601c2876207SWill Deacon enum mitigation_state state; 602c2876207SWill Deacon 603c2876207SWill Deacon state = spectre_v4_get_cpu_fw_mitigation_state(); 604c2876207SWill Deacon if (state != SPECTRE_MITIGATED) 605c2876207SWill Deacon return state; 606c2876207SWill Deacon 607c2876207SWill Deacon if (spectre_v4_mitigations_off()) { 608c2876207SWill Deacon arm_smccc_1_1_invoke(ARM_SMCCC_ARCH_WORKAROUND_2, false, NULL); 609c2876207SWill Deacon return SPECTRE_VULNERABLE; 610c2876207SWill Deacon } 611c2876207SWill Deacon 612c2876207SWill Deacon arm_smccc_1_1_invoke(ARM_SMCCC_ARCH_WORKAROUND_2, true, NULL); 613c2876207SWill Deacon 614c2876207SWill Deacon if (spectre_v4_mitigations_dynamic()) 615c2876207SWill Deacon __this_cpu_write(arm64_ssbd_callback_required, 1); 616c2876207SWill Deacon 617c2876207SWill Deacon return SPECTRE_MITIGATED; 618c2876207SWill Deacon } 619c2876207SWill Deacon 620c2876207SWill Deacon void spectre_v4_enable_mitigation(const struct arm64_cpu_capabilities *__unused) 621c2876207SWill Deacon { 622c2876207SWill Deacon enum mitigation_state state; 623c2876207SWill Deacon 624c2876207SWill Deacon WARN_ON(preemptible()); 625c2876207SWill Deacon 626c2876207SWill Deacon state = spectre_v4_enable_hw_mitigation(); 627c2876207SWill Deacon if (state == SPECTRE_VULNERABLE) 628c2876207SWill Deacon state = spectre_v4_enable_fw_mitigation(); 629c2876207SWill Deacon 630c2876207SWill Deacon update_mitigation_state(&spectre_v4_state, state); 631c2876207SWill Deacon } 632c2876207SWill Deacon 633c2876207SWill Deacon static void __update_pstate_ssbs(struct pt_regs *regs, bool state) 634c2876207SWill Deacon { 635c2876207SWill Deacon u64 bit = compat_user_mode(regs) ? PSR_AA32_SSBS_BIT : PSR_SSBS_BIT; 636c2876207SWill Deacon 637c2876207SWill Deacon if (state) 638c2876207SWill Deacon regs->pstate |= bit; 639c2876207SWill Deacon else 640c2876207SWill Deacon regs->pstate &= ~bit; 641c2876207SWill Deacon } 642c2876207SWill Deacon 643c2876207SWill Deacon void spectre_v4_enable_task_mitigation(struct task_struct *tsk) 644c2876207SWill Deacon { 645c2876207SWill Deacon struct pt_regs *regs = task_pt_regs(tsk); 646c2876207SWill Deacon bool ssbs = false, kthread = tsk->flags & PF_KTHREAD; 647c2876207SWill Deacon 648c2876207SWill Deacon if (spectre_v4_mitigations_off()) 649c2876207SWill Deacon ssbs = true; 650c2876207SWill Deacon else if (spectre_v4_mitigations_dynamic() && !kthread) 651c2876207SWill Deacon ssbs = !test_tsk_thread_flag(tsk, TIF_SSBD); 652c2876207SWill Deacon 653c2876207SWill Deacon __update_pstate_ssbs(regs, ssbs); 654c2876207SWill Deacon } 655c2876207SWill Deacon 656c2876207SWill Deacon /* 657c2876207SWill Deacon * The Spectre-v4 mitigation can be controlled via a prctl() from userspace. 658c2876207SWill Deacon * This is interesting because the "speculation disabled" behaviour can be 659c2876207SWill Deacon * configured so that it is preserved across exec(), which means that the 660c2876207SWill Deacon * prctl() may be necessary even when PSTATE.SSBS can be toggled directly 661c2876207SWill Deacon * from userspace. 6629e78b659SWill Deacon */ 663780c083aSWill Deacon static void ssbd_prctl_enable_mitigation(struct task_struct *task) 664780c083aSWill Deacon { 665780c083aSWill Deacon task_clear_spec_ssb_noexec(task); 666780c083aSWill Deacon task_set_spec_ssb_disable(task); 667780c083aSWill Deacon set_tsk_thread_flag(task, TIF_SSBD); 668780c083aSWill Deacon } 669780c083aSWill Deacon 670780c083aSWill Deacon static void ssbd_prctl_disable_mitigation(struct task_struct *task) 671780c083aSWill Deacon { 672780c083aSWill Deacon task_clear_spec_ssb_noexec(task); 673780c083aSWill Deacon task_clear_spec_ssb_disable(task); 674780c083aSWill Deacon clear_tsk_thread_flag(task, TIF_SSBD); 675780c083aSWill Deacon } 676780c083aSWill Deacon 6779e78b659SWill Deacon static int ssbd_prctl_set(struct task_struct *task, unsigned long ctrl) 6789e78b659SWill Deacon { 6799e78b659SWill Deacon switch (ctrl) { 6809e78b659SWill Deacon case PR_SPEC_ENABLE: 681c2876207SWill Deacon /* Enable speculation: disable mitigation */ 682c2876207SWill Deacon /* 683c2876207SWill Deacon * Force disabled speculation prevents it from being 684c2876207SWill Deacon * re-enabled. 685c2876207SWill Deacon */ 686c2876207SWill Deacon if (task_spec_ssb_force_disable(task)) 6879e78b659SWill Deacon return -EPERM; 6889e78b659SWill Deacon 6899e78b659SWill Deacon /* 690c2876207SWill Deacon * If the mitigation is forced on, then speculation is forced 691c2876207SWill Deacon * off and we again prevent it from being re-enabled. 6929e78b659SWill Deacon */ 693c2876207SWill Deacon if (spectre_v4_mitigations_on()) 6949e78b659SWill Deacon return -EPERM; 695c2876207SWill Deacon 696780c083aSWill Deacon ssbd_prctl_disable_mitigation(task); 6979e78b659SWill Deacon break; 6989e78b659SWill Deacon case PR_SPEC_FORCE_DISABLE: 699c2876207SWill Deacon /* Force disable speculation: force enable mitigation */ 700c2876207SWill Deacon /* 701c2876207SWill Deacon * If the mitigation is forced off, then speculation is forced 702c2876207SWill Deacon * on and we prevent it from being disabled. 703c2876207SWill Deacon */ 704c2876207SWill Deacon if (spectre_v4_mitigations_off()) 7059e78b659SWill Deacon return -EPERM; 706c2876207SWill Deacon 7079e78b659SWill Deacon task_set_spec_ssb_force_disable(task); 708c2876207SWill Deacon fallthrough; 709c2876207SWill Deacon case PR_SPEC_DISABLE: 710c2876207SWill Deacon /* Disable speculation: enable mitigation */ 711c2876207SWill Deacon /* Same as PR_SPEC_FORCE_DISABLE */ 712c2876207SWill Deacon if (spectre_v4_mitigations_off()) 713c2876207SWill Deacon return -EPERM; 714c2876207SWill Deacon 715780c083aSWill Deacon ssbd_prctl_enable_mitigation(task); 716780c083aSWill Deacon break; 717780c083aSWill Deacon case PR_SPEC_DISABLE_NOEXEC: 718780c083aSWill Deacon /* Disable speculation until execve(): enable mitigation */ 719780c083aSWill Deacon /* 720780c083aSWill Deacon * If the mitigation state is forced one way or the other, then 721780c083aSWill Deacon * we must fail now before we try to toggle it on execve(). 722780c083aSWill Deacon */ 723780c083aSWill Deacon if (task_spec_ssb_force_disable(task) || 724780c083aSWill Deacon spectre_v4_mitigations_off() || 725780c083aSWill Deacon spectre_v4_mitigations_on()) { 726780c083aSWill Deacon return -EPERM; 727780c083aSWill Deacon } 728780c083aSWill Deacon 729780c083aSWill Deacon ssbd_prctl_enable_mitigation(task); 730780c083aSWill Deacon task_set_spec_ssb_noexec(task); 7319e78b659SWill Deacon break; 7329e78b659SWill Deacon default: 7339e78b659SWill Deacon return -ERANGE; 7349e78b659SWill Deacon } 7359e78b659SWill Deacon 736c2876207SWill Deacon spectre_v4_enable_task_mitigation(task); 7379e78b659SWill Deacon return 0; 7389e78b659SWill Deacon } 7399e78b659SWill Deacon 7409e78b659SWill Deacon int arch_prctl_spec_ctrl_set(struct task_struct *task, unsigned long which, 7419e78b659SWill Deacon unsigned long ctrl) 7429e78b659SWill Deacon { 7439e78b659SWill Deacon switch (which) { 7449e78b659SWill Deacon case PR_SPEC_STORE_BYPASS: 7459e78b659SWill Deacon return ssbd_prctl_set(task, ctrl); 7469e78b659SWill Deacon default: 7479e78b659SWill Deacon return -ENODEV; 7489e78b659SWill Deacon } 7499e78b659SWill Deacon } 7509e78b659SWill Deacon 7519e78b659SWill Deacon static int ssbd_prctl_get(struct task_struct *task) 7529e78b659SWill Deacon { 753c2876207SWill Deacon switch (spectre_v4_state) { 754c2876207SWill Deacon case SPECTRE_UNAFFECTED: 755c2876207SWill Deacon return PR_SPEC_NOT_AFFECTED; 756c2876207SWill Deacon case SPECTRE_MITIGATED: 757c2876207SWill Deacon if (spectre_v4_mitigations_on()) 758c2876207SWill Deacon return PR_SPEC_NOT_AFFECTED; 759c2876207SWill Deacon 760c2876207SWill Deacon if (spectre_v4_mitigations_dynamic()) 761c2876207SWill Deacon break; 762c2876207SWill Deacon 763c2876207SWill Deacon /* Mitigations are disabled, so we're vulnerable. */ 764c2876207SWill Deacon fallthrough; 765c2876207SWill Deacon case SPECTRE_VULNERABLE: 766c2876207SWill Deacon fallthrough; 767c2876207SWill Deacon default: 768c2876207SWill Deacon return PR_SPEC_ENABLE; 769c2876207SWill Deacon } 770c2876207SWill Deacon 771c2876207SWill Deacon /* Check the mitigation state for this task */ 7729e78b659SWill Deacon if (task_spec_ssb_force_disable(task)) 7739e78b659SWill Deacon return PR_SPEC_PRCTL | PR_SPEC_FORCE_DISABLE; 774c2876207SWill Deacon 775780c083aSWill Deacon if (task_spec_ssb_noexec(task)) 776780c083aSWill Deacon return PR_SPEC_PRCTL | PR_SPEC_DISABLE_NOEXEC; 777780c083aSWill Deacon 7789e78b659SWill Deacon if (task_spec_ssb_disable(task)) 7799e78b659SWill Deacon return PR_SPEC_PRCTL | PR_SPEC_DISABLE; 780c2876207SWill Deacon 7819e78b659SWill Deacon return PR_SPEC_PRCTL | PR_SPEC_ENABLE; 7829e78b659SWill Deacon } 7839e78b659SWill Deacon 7849e78b659SWill Deacon int arch_prctl_spec_ctrl_get(struct task_struct *task, unsigned long which) 7859e78b659SWill Deacon { 7869e78b659SWill Deacon switch (which) { 7879e78b659SWill Deacon case PR_SPEC_STORE_BYPASS: 7889e78b659SWill Deacon return ssbd_prctl_get(task); 7899e78b659SWill Deacon default: 7909e78b659SWill Deacon return -ENODEV; 7919e78b659SWill Deacon } 7929e78b659SWill Deacon } 793