From patchwork Fri Jan 25 18:07:07 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jeremy Linton X-Patchwork-Id: 156623 Delivered-To: patch@linaro.org Received: by 2002:a02:48:0:0:0:0:0 with SMTP id 69csp652386jaa; Fri, 25 Jan 2019 10:07:35 -0800 (PST) X-Google-Smtp-Source: ALg8bN7IbQrkSfcU7FjqbTxrO0X9tuPMuIkSqJaDq8Zj4DZyFPDJ1szOwqWtd3y+k+JaTffNGaR1 X-Received: by 2002:a63:e445:: with SMTP id i5mr10850381pgk.307.1548439655045; Fri, 25 Jan 2019 10:07:35 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1548439655; cv=none; d=google.com; s=arc-20160816; b=qChFqUaJLsUWj8kibrWapDAdEPnqXFSDWAPSfNmOpAjv+FqclT7RyXbjjMhPGe3God tDWLTGIY06ge5rXiYnqq2+BrcacvZrYwZ3S4eAe/Zl3MeBfqcswfySiXR1qnl0pghopG 2cCsSKZ2E/W4Vl62P7L9x8mTx864+UGQVIGsLRI9VAgPy+I2njJLnEvZrlaLcEBZGoIs Mus0HStXRXcpfzzp1G49e3m49Ox8agImJknSBmqHIkD5nt6XxOl1qavE9F+r1fzPlLZK /9MPZhTcWiz3eh5Vecgkdi61rvUfc4ad5k6NH8cCMubAM7506gdZ4NtWRIL06HwoILmt 7HYw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from; bh=pHDYbyepUCwz6eu1LhGvFQ5jeKIGxTMMNmFw/c1IAFE=; b=L2weRBksxFFUYf3YMfgRynYkjF02A1q5u2WwzHP+V+Iy6D5sjZX7fGBu3eUPYqLx/O fjpAf7kvo70K2oOgTFzCSEnOHTvkdVdfsXVFiIvXeja3qnEhfysvEd+//1VWhMcNRemJ i8BPiwxBZ0LaD2zaPrY8cKNkta3P4a2kSFdXhpznXACBCNiJ0hVFWR8Qfz/pj9xF9/H4 lbXvGDhLuWvZVbfF1ASyq7VHR2svyRkyrwsgAwVZHHSHlijxSf2S43V2k1sxOqBV2CYl YcudZbU9dQGNnPtEzEiM7WBmw+PBZ2q+hVQBZXrLBn8UNONIQ6wnQU4djn5gW8RX/E6M opfw== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id b3si26104567pld.282.2019.01.25.10.07.34; Fri, 25 Jan 2019 10:07:35 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729396AbfAYSHd (ORCPT + 31 others); Fri, 25 Jan 2019 13:07:33 -0500 Received: from usa-sjc-mx-foss1.foss.arm.com ([217.140.101.70]:51852 "EHLO foss.arm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729364AbfAYSHa (ORCPT ); Fri, 25 Jan 2019 13:07:30 -0500 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.72.51.249]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 37BC7169E; Fri, 25 Jan 2019 10:07:30 -0800 (PST) Received: from beelzebub.austin.arm.com (beelzebub.austin.arm.com [10.118.12.119]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id 90AF73F5AF; Fri, 25 Jan 2019 10:07:29 -0800 (PST) From: Jeremy Linton To: linux-arm-kernel@lists.infradead.org Cc: catalin.marinas@arm.com, will.deacon@arm.com, marc.zyngier@arm.com, suzuki.poulose@arm.com, dave.martin@arm.com, shankerd@codeaurora.org, linux-kernel@vger.kernel.org, ykaukab@suse.de, julien.thierry@arm.com, mlangsdo@redhat.com, steven.price@arm.com, stefan.wahren@i2se.com, Jeremy Linton Subject: [PATCH v4 08/12] arm64: Advertise mitigation of Spectre-v2, or lack thereof Date: Fri, 25 Jan 2019 12:07:07 -0600 Message-Id: <20190125180711.1970973-9-jeremy.linton@arm.com> X-Mailer: git-send-email 2.17.2 In-Reply-To: <20190125180711.1970973-1-jeremy.linton@arm.com> References: <20190125180711.1970973-1-jeremy.linton@arm.com> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Marc Zyngier 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 [This makes more sense in front of the sysfs patch] [Pick pieces of that patch into this and move it earlier] Signed-off-by: Jeremy Linton --- arch/arm64/kernel/cpu_errata.c | 104 +++++++++++++++++---------------- 1 file changed, 54 insertions(+), 50 deletions(-) -- 2.17.2 Reviewed-by: Andre Przywara diff --git a/arch/arm64/kernel/cpu_errata.c b/arch/arm64/kernel/cpu_errata.c index ef636acf5604..4d23b4d4cfa8 100644 --- a/arch/arm64/kernel/cpu_errata.c +++ b/arch/arm64/kernel/cpu_errata.c @@ -129,9 +129,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 DEFINE_RAW_SPINLOCK(bp_lock); int cpu, slot = -1; @@ -164,23 +164,6 @@ static void __install_bp_hardening_cb(bp_hardening_cb_t fn, raw_spin_unlock(&bp_lock); } -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 @@ -215,29 +198,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) - 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; @@ -248,23 +229,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; } DEFINE_PER_CPU_READ_MOSTLY(u64, arm64_ssbd_callback_required); @@ -502,24 +483,47 @@ cpu_enable_cache_maint_trap(const struct arm64_cpu_capabilities *__unused) .type = ARM64_CPUCAP_LOCAL_CPU_ERRATUM, \ CAP_MIDR_RANGE_LIST(midr_list) - /* - * 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), - MIDR_ALL_VERSIONS(MIDR_NVIDIA_DENVER), - {}, +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; + + if (need_wa < 0) + pr_warn_once("ARM_SMCCC_ARCH_WORKAROUND_1 missing from firmware\n"); + + /* forced off */ + if (__nospectre_v2) + return false; + + return (need_wa > 0); +} + #ifdef CONFIG_HARDEN_EL2_VECTORS static const struct midr_range arm64_harden_el2_vectors[] = { @@ -695,8 +699,8 @@ const struct arm64_cpu_capabilities arm64_errata[] = { #endif { .capability = ARM64_HARDEN_BRANCH_PREDICTOR, - .cpu_enable = enable_smccc_arch_workaround_1, - ERRATA_MIDR_RANGE_LIST(arm64_bp_harden_smccc_cpus), + .type = ARM64_CPUCAP_LOCAL_CPU_ERRATUM, + .matches = check_branch_predictor, }, #ifdef CONFIG_HARDEN_EL2_VECTORS {