From patchwork Thu Oct 24 12:48:26 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ard Biesheuvel X-Patchwork-Id: 177462 Delivered-To: patch@linaro.org Received: by 2002:a92:409a:0:0:0:0:0 with SMTP id d26csp2143087ill; Thu, 24 Oct 2019 05:49:56 -0700 (PDT) X-Google-Smtp-Source: APXvYqzu7vjwS6A2PefcfHhTYqr8HD9V1xxxhqWOw/rmpwlfBVe6Kz/ELzPHPd2JOPs9vZihJ3RS X-Received: by 2002:a17:906:f42:: with SMTP id h2mr37555536ejj.39.1571921396237; Thu, 24 Oct 2019 05:49:56 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1571921396; cv=none; d=google.com; s=arc-20160816; b=TiFIQqNgc1GJSYasazuqs3B6kWWZfMjcaBsxa1F2bcoKN1MExAkhpCcPqGHYEE6Dsp +yWAjKJhtYIjHJfhQVvO3BBZgEG6hgdtqCWovK8VRc9kL4Z32I+dt8uzeoxrr+p5wLt6 8huHdEgqhkU6E5oWqpxqbEpviLN/w3mL5rmbgsqxsYefglDJascs5k0d7V0lO8dQqoaM RiQtJ9QwPMLd8z/EPpz3/PF9HOlBzvaYkEjRSQhn3URZviOu55rH9EhBBMIhY/tiXQPq 7g1wy/0M5rcL3AHH5DuuN4MD+4ON809lbsgaA6E5uGn0VXNF2Z9qbMUylpZMkItYhuIk Nxkw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=UmmJ2QSgDR/QepaR+/lUkSjbzhjl6vcl9iGibzO6BKE=; b=aq0fPKNi0AEqJeEb966El4prYoeosd1UWUCCcIQOPmlgEiTMpUoIV8U90IFqoSCnXj +6Gfyj7+j8TQOkFY2i5RHXuOC1NNGNvKNGnAuupARHjS5HbvVU8zogg0sHOuEcJ88Agd 866Zg5/ylN340B/P5TZrFIH81n7qXyHeKoeSDs5pBrRyat+SEeXJ1FiH17KrU4NFcXpL bl41vqmd4Blpd62fGhI7pw7og16TCqsViJpSs/oSunLbq8HzZInpwxcTJLdkRvenk43b t9baJrSCzfRx1Ewa8NIMB8NPkNgEiVk0b8eC5oFX5P2gpBCROxKrd9Hsaf4+MowXbm2s 2U7g== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=vlI0uBOG; spf=pass (google.com: best guess record for domain of stable-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=stable-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id y71si17602216ede.135.2019.10.24.05.49.56; Thu, 24 Oct 2019 05:49:56 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of stable-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=vlI0uBOG; spf=pass (google.com: best guess record for domain of stable-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=stable-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2502137AbfJXMtz (ORCPT + 14 others); Thu, 24 Oct 2019 08:49:55 -0400 Received: from mail-wm1-f65.google.com ([209.85.128.65]:34615 "EHLO mail-wm1-f65.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2502139AbfJXMtz (ORCPT ); Thu, 24 Oct 2019 08:49:55 -0400 Received: by mail-wm1-f65.google.com with SMTP id v3so1933510wmh.1 for ; Thu, 24 Oct 2019 05:49:53 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=UmmJ2QSgDR/QepaR+/lUkSjbzhjl6vcl9iGibzO6BKE=; b=vlI0uBOGkpEtdBhANWziFtkgYmZZklblTxLlxmxdSL1+Frgqpz2NtOsPcnvam8Ve8z hM+8X0c5bRjXuZ42EOJtVPV9lF/Gr5LJYTFhqNa4Aptf5osrHu/gvgxPLzMiotz+0Ix9 QgbkzpajA7UVV9qF4uZpZM19RcCfIUHJ/Wdl2XAcJBVjURRTYWnQzpXaIYvh3EmtoIHW 1D5l/HN8XYLjayfhbM+Q1wtw0BkUD1dUFcxcs/KLSo+za1+cd1DdYET6N4xiBnKYUKr0 wRUghunkAWsJ9CGXX9FwiMYIJsCkmLp2c/yh6au4Q6sHV65Q4D0oCTR7fefPYslyMJ+9 QTcw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=UmmJ2QSgDR/QepaR+/lUkSjbzhjl6vcl9iGibzO6BKE=; b=UY6Wh6Ybx5qRgYJTU9cJAsJMCIYeCsSXOXG0CVo/H5NQBsMXwGmfA+oE/xcZFl58rz Ow9VN4dPSZsoHJoK7Pn/1OLl8ehOzAEFQ/qNLD9zQchl7HCIhdkGxOokVZUgJWhd7Gy+ ysojC9hocFFWFTGfSmbW2EqOLx1x/Bj5dAifyZxzbSeh5td2uI4J1b70XIwC9k4305EM jpPSzs2XtG74qRKnTuuH+b34yHtq5itrVi/ixhgev35iYHXetShAfgCuGMKYYDWqq1TC MOBMg5bZvUgjnddOJw69+N4gioFByLtwWrjZuqEdrfH3QHa6Tj/LxwQq8NKDdfYu7VtM qQLQ== X-Gm-Message-State: APjAAAXtloPR5xKvULuDLPYLDSZgbtSa2tBsV/VYCkMiKNaJ+s7jjbAi rciWdPqeD5mGysUw2nk8nG+FxYzwYWi1QLTn X-Received: by 2002:a1c:7c13:: with SMTP id x19mr4806528wmc.80.1571921392755; Thu, 24 Oct 2019 05:49:52 -0700 (PDT) Received: from localhost.localdomain (aaubervilliers-681-1-126-126.w90-88.abo.wanadoo.fr. [90.88.7.126]) by smtp.gmail.com with ESMTPSA id j22sm29111038wrd.41.2019.10.24.05.49.51 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 24 Oct 2019 05:49:51 -0700 (PDT) From: Ard Biesheuvel To: stable@vger.kernel.org Cc: Ard Biesheuvel , Will Deacon , Catalin Marinas , Marc Zyngier , Mark Rutland , Suzuki K Poulose , Jeremy Linton , Andre Przywara , Alexandru Elisei , Marc Zyngier , Stefan Wahren , Will Deacon Subject: [PATCH for-stable-4.14 41/48] arm64: Advertise mitigation of Spectre-v2, or lack thereof Date: Thu, 24 Oct 2019 14:48:26 +0200 Message-Id: <20191024124833.4158-42-ard.biesheuvel@linaro.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20191024124833.4158-1-ard.biesheuvel@linaro.org> References: <20191024124833.4158-1-ard.biesheuvel@linaro.org> MIME-Version: 1.0 Sender: stable-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: stable@vger.kernel.org From: Marc Zyngier [ Upstream commit 73f38166095947f3b86b02fbed6bd592223a7ac8 ] We currently have a list of CPUs affected by Spectre-v2, for which we check that the firmware implements ARCH_WORKAROUND_1. It turns out that not all firmwares do implement the required mitigation, and that we fail to let the user know about it. Instead, let's slightly revamp our checks, and rely on a whitelist of cores that are known to be non-vulnerable, and let the user know the status of the mitigation in the kernel log. Signed-off-by: Marc Zyngier Signed-off-by: Jeremy Linton Reviewed-by: Andre Przywara Reviewed-by: Suzuki K Poulose Reviewed-by: Catalin Marinas Tested-by: Stefan Wahren Signed-off-by: Will Deacon Signed-off-by: Ard Biesheuvel --- arch/arm64/kernel/cpu_errata.c | 108 ++++++++++---------- 1 file changed, 56 insertions(+), 52 deletions(-) -- 2.20.1 diff --git a/arch/arm64/kernel/cpu_errata.c b/arch/arm64/kernel/cpu_errata.c index 5c3f8c712aae..bf6d8aa9b45a 100644 --- a/arch/arm64/kernel/cpu_errata.c +++ b/arch/arm64/kernel/cpu_errata.c @@ -98,9 +98,9 @@ static void __copy_hyp_vect_bpi(int slot, const char *hyp_vecs_start, flush_icache_range((uintptr_t)dst, (uintptr_t)dst + SZ_2K); } -static void __install_bp_hardening_cb(bp_hardening_cb_t fn, - const char *hyp_vecs_start, - const char *hyp_vecs_end) +static void install_bp_hardening_cb(bp_hardening_cb_t fn, + const char *hyp_vecs_start, + const char *hyp_vecs_end) { static int last_slot = -1; static DEFINE_SPINLOCK(bp_lock); @@ -130,7 +130,7 @@ static void __install_bp_hardening_cb(bp_hardening_cb_t fn, #define __smccc_workaround_1_smc_start NULL #define __smccc_workaround_1_smc_end NULL -static void __install_bp_hardening_cb(bp_hardening_cb_t fn, +static void install_bp_hardening_cb(bp_hardening_cb_t fn, const char *hyp_vecs_start, const char *hyp_vecs_end) { @@ -138,23 +138,6 @@ static void __install_bp_hardening_cb(bp_hardening_cb_t fn, } #endif /* CONFIG_KVM */ -static void install_bp_hardening_cb(const struct arm64_cpu_capabilities *entry, - bp_hardening_cb_t fn, - const char *hyp_vecs_start, - const char *hyp_vecs_end) -{ - u64 pfr0; - - if (!entry->matches(entry, SCOPE_LOCAL_CPU)) - return; - - pfr0 = read_cpuid(ID_AA64PFR0_EL1); - if (cpuid_feature_extract_unsigned_field(pfr0, ID_AA64PFR0_CSV2_SHIFT)) - return; - - __install_bp_hardening_cb(fn, hyp_vecs_start, hyp_vecs_end); -} - #include #include #include @@ -189,31 +172,27 @@ static int __init parse_nospectre_v2(char *str) } early_param("nospectre_v2", parse_nospectre_v2); -static void -enable_smccc_arch_workaround_1(const struct arm64_cpu_capabilities *entry) +/* + * -1: No workaround + * 0: No workaround required + * 1: Workaround installed + */ +static int detect_harden_bp_fw(void) { bp_hardening_cb_t cb; void *smccc_start, *smccc_end; struct arm_smccc_res res; u32 midr = read_cpuid_id(); - if (!entry->matches(entry, SCOPE_LOCAL_CPU)) - return; - - if (__nospectre_v2) { - pr_info_once("spectrev2 mitigation disabled by command line option\n"); - return; - } - if (psci_ops.smccc_version == SMCCC_VERSION_1_0) - return; + return -1; switch (psci_ops.conduit) { case PSCI_CONDUIT_HVC: arm_smccc_1_1_hvc(ARM_SMCCC_ARCH_FEATURES_FUNC_ID, ARM_SMCCC_ARCH_WORKAROUND_1, &res); if ((int)res.a0 < 0) - return; + return -1; cb = call_hvc_arch_workaround_1; /* This is a guest, no need to patch KVM vectors */ smccc_start = NULL; @@ -224,23 +203,23 @@ enable_smccc_arch_workaround_1(const struct arm64_cpu_capabilities *entry) arm_smccc_1_1_smc(ARM_SMCCC_ARCH_FEATURES_FUNC_ID, ARM_SMCCC_ARCH_WORKAROUND_1, &res); if ((int)res.a0 < 0) - return; + return -1; cb = call_smc_arch_workaround_1; smccc_start = __smccc_workaround_1_smc_start; smccc_end = __smccc_workaround_1_smc_end; break; default: - return; + return -1; } if (((midr & MIDR_CPU_MODEL_MASK) == MIDR_QCOM_FALKOR) || ((midr & MIDR_CPU_MODEL_MASK) == MIDR_QCOM_FALKOR_V1)) cb = qcom_link_stack_sanitization; - install_bp_hardening_cb(entry, cb, smccc_start, smccc_end); + install_bp_hardening_cb(cb, smccc_start, smccc_end); - return; + return 1; } #endif /* CONFIG_HARDEN_BRANCH_PREDICTOR */ @@ -479,23 +458,48 @@ static bool has_ssbd_mitigation(const struct arm64_cpu_capabilities *entry, CAP_MIDR_RANGE_LIST(midr_list) #ifdef CONFIG_HARDEN_BRANCH_PREDICTOR - /* - * List of CPUs where we need to issue a psci call to - * harden the branch predictor. + * List of CPUs that do not need any Spectre-v2 mitigation at all. */ -static const struct midr_range arm64_bp_harden_smccc_cpus[] = { - MIDR_ALL_VERSIONS(MIDR_CORTEX_A57), - MIDR_ALL_VERSIONS(MIDR_CORTEX_A72), - MIDR_ALL_VERSIONS(MIDR_CORTEX_A73), - MIDR_ALL_VERSIONS(MIDR_CORTEX_A75), - MIDR_ALL_VERSIONS(MIDR_BRCM_VULCAN), - MIDR_ALL_VERSIONS(MIDR_CAVIUM_THUNDERX2), - MIDR_ALL_VERSIONS(MIDR_QCOM_FALKOR_V1), - MIDR_ALL_VERSIONS(MIDR_QCOM_FALKOR), - {}, +static const struct midr_range spectre_v2_safe_list[] = { + MIDR_ALL_VERSIONS(MIDR_CORTEX_A35), + MIDR_ALL_VERSIONS(MIDR_CORTEX_A53), + MIDR_ALL_VERSIONS(MIDR_CORTEX_A55), + { /* sentinel */ } }; +static bool __maybe_unused +check_branch_predictor(const struct arm64_cpu_capabilities *entry, int scope) +{ + int need_wa; + + WARN_ON(scope != SCOPE_LOCAL_CPU || preemptible()); + + /* If the CPU has CSV2 set, we're safe */ + if (cpuid_feature_extract_unsigned_field(read_cpuid(ID_AA64PFR0_EL1), + ID_AA64PFR0_CSV2_SHIFT)) + return false; + + /* Alternatively, we have a list of unaffected CPUs */ + if (is_midr_in_range_list(read_cpuid_id(), spectre_v2_safe_list)) + return false; + + /* Fallback to firmware detection */ + need_wa = detect_harden_bp_fw(); + if (!need_wa) + return false; + + /* forced off */ + if (__nospectre_v2) { + pr_info_once("spectrev2 mitigation disabled by command line option\n"); + return false; + } + + if (need_wa < 0) + pr_warn_once("ARM_SMCCC_ARCH_WORKAROUND_1 missing from firmware\n"); + + return (need_wa > 0); +} #endif const struct arm64_cpu_capabilities arm64_errata[] = { @@ -639,8 +643,8 @@ const struct arm64_cpu_capabilities arm64_errata[] = { #ifdef CONFIG_HARDEN_BRANCH_PREDICTOR { .capability = ARM64_HARDEN_BRANCH_PREDICTOR, - ERRATA_MIDR_RANGE_LIST(arm64_bp_harden_smccc_cpus), - .cpu_enable = enable_smccc_arch_workaround_1, + .type = ARM64_CPUCAP_LOCAL_CPU_ERRATUM, + .matches = check_branch_predictor, }, #endif {