From patchwork Wed Jan 17 11:54:39 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Julien Thierry X-Patchwork-Id: 124802 Delivered-To: patch@linaro.org Received: by 10.46.62.1 with SMTP id l1csp11326lja; Wed, 17 Jan 2018 03:55:20 -0800 (PST) X-Google-Smtp-Source: ACJfBouI6YCx+3jo7m4+rl+h07EHonH12nvx9NNEhdUxaYqCdvdNUyjbwheagkCpDmK/22z4JjNp X-Received: by 10.84.228.214 with SMTP id y22mr36947577pli.444.1516190120697; Wed, 17 Jan 2018 03:55:20 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1516190120; cv=none; d=google.com; s=arc-20160816; b=yh7s3qcSAJvoW7NiRyXDVREeEoyUe81dUNMQ77IdBl3mYfmXwRR0MTSKtafY0qxOoN rDRRv71o2/tNoLccRN+N39DXS6qWuWr8BBS0eujnvyUQnWkKxbAZoeupoAbsm7VYR8Zl xnCS7hGZvg8nub8PilcMtzTjKU9TLbzahVuLfgM/6BgTw68lD+coZC1VwveGD715VgEL 2VrK6rUhjtH7y1+VtZlfx/IPtewwf1IUcVNGfbjQ6NhO5Z6gxd6ao1czAqxt4Q95kBJr ePtLduIX4FyTbqn8lScGFemBQAt77RbsswK8qbYApsfvmz2w/CB3bPAnuzoWbTxLJTug +3oQ== 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:arc-authentication-results; bh=S10gRvI67aT4sQTz4nNnVk2Mu87O3vwZf1yv8q0/kL8=; b=W7UKJf+zfu7shQcXuoMJhzLIOgGlwQjqvJhi9SgTelXTupHMrf0DwE4xaZzw/csg5u jwZIVH9bMQrURf1bGm5nnYwbhY+uu8LzlP0BRZ0hOcYC7bsgVGuxZDFv65meQUEK6WIZ NpAiT2YoEwXo/s+LGXuNHALgFT2Z1SUXBwsRb+dkCkXt+HRPa2szDetRMXfTCFXqAyBN T8E5taRSiSy0urmvBfDfxpMkpjCDf0C7FH7gATS7FzLWIlfcZANKAr0jljwoeGGKIwMD jW/wv0vxh/lFTHXax1rrDEQZ9bDPoymsYjIewVctKOshN5rI4QRJ+ZKAqu9psHLw9G18 MhbA== 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 v4si3731573pgf.103.2018.01.17.03.55.20; Wed, 17 Jan 2018 03:55:20 -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 S1753153AbeAQLzQ (ORCPT + 28 others); Wed, 17 Jan 2018 06:55:16 -0500 Received: from foss.arm.com ([217.140.101.70]:39136 "EHLO foss.arm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752664AbeAQLzN (ORCPT ); Wed, 17 Jan 2018 06:55:13 -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 2C68815A2; Wed, 17 Jan 2018 03:55:13 -0800 (PST) Received: from e112298-lin.cambridge.arm.com (usa-sjc-imap-foss1.foss.arm.com [10.72.51.249]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id 83BE93F53D; Wed, 17 Jan 2018 03:55:11 -0800 (PST) From: Julien Thierry To: linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org Cc: mark.rutland@arm.com, marc.zyngier@arm.com, james.morse@arm.com, daniel.thompson@linaro.org, Julien Thierry , Catalin Marinas , Will Deacon , Suzuki K Poulose Subject: [PATCH v2 1/6] arm64: cpufeature: Allow early detect of specific features Date: Wed, 17 Jan 2018 11:54:39 +0000 Message-Id: <1516190084-18978-2-git-send-email-julien.thierry@arm.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1516190084-18978-1-git-send-email-julien.thierry@arm.com> References: <1516190084-18978-1-git-send-email-julien.thierry@arm.com> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Daniel Thompson Currently it is not possible to detect features of the boot CPU until the other CPUs have been brought up. This prevents us from reacting to features of the boot CPU until fairly late in the boot process. To solve this we allow a subset of features (that are likely to be common to all clusters) to be detected based on the boot CPU alone. Signed-off-by: Daniel Thompson [julien.thierry@arm.com: check non-boot cpu missing early features, avoid duplicates between early features and normal features] Signed-off-by: Julien Thierry Cc: Catalin Marinas Cc: Will Deacon Cc: Suzuki K Poulose --- arch/arm64/kernel/cpufeature.c | 69 ++++++++++++++++++++++++++++-------------- 1 file changed, 47 insertions(+), 22 deletions(-) -- 1.9.1 diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c index a73a592..6698404 100644 --- a/arch/arm64/kernel/cpufeature.c +++ b/arch/arm64/kernel/cpufeature.c @@ -52,6 +52,8 @@ DECLARE_BITMAP(cpu_hwcaps, ARM64_NCAPS); EXPORT_SYMBOL(cpu_hwcaps); +static void __init setup_early_feature_capabilities(void); + /* * Flag to indicate if we have computed the system wide * capabilities based on the boot time active CPUs. This @@ -542,6 +544,8 @@ void __init init_cpu_features(struct cpuinfo_arm64 *info) init_cpu_ftr_reg(SYS_ZCR_EL1, info->reg_zcr); sve_init_vq_map(); } + + setup_early_feature_capabilities(); } static void update_cpu_ftr_reg(struct arm64_ftr_reg *reg, u64 new) @@ -846,7 +850,7 @@ static bool has_no_fpsimd(const struct arm64_cpu_capabilities *entry, int __unus ID_AA64PFR0_FP_SHIFT) < 0; } -static const struct arm64_cpu_capabilities arm64_features[] = { +static const struct arm64_cpu_capabilities arm64_early_features[] = { { .desc = "GIC system register CPU interface", .capability = ARM64_HAS_SYSREG_GIC_CPUIF, @@ -857,6 +861,10 @@ static bool has_no_fpsimd(const struct arm64_cpu_capabilities *entry, int __unus .sign = FTR_UNSIGNED, .min_field_value = 1, }, + {} +}; + +static const struct arm64_cpu_capabilities arm64_features[] = { #ifdef CONFIG_ARM64_PAN { .desc = "Privileged Access Never", @@ -1111,6 +1119,29 @@ void __init enable_cpu_capabilities(const struct arm64_cpu_capabilities *caps) } } +/* Returns false on a capability mismatch */ +static bool +verify_local_cpu_features(const struct arm64_cpu_capabilities *caps) +{ + for (; caps->matches; caps++) { + if (!cpus_have_cap(caps->capability)) + continue; + /* + * If the new CPU misses an advertised feature, we cannot + * proceed further, park the cpu. + */ + if (!caps->matches(caps, SCOPE_LOCAL_CPU)) { + pr_crit("CPU%d: missing feature: %s\n", + smp_processor_id(), caps->desc); + return false; + } + if (caps->enable) + caps->enable(NULL); + } + + return true; +} + /* * Check for CPU features that are used in early boot * based on the Boot CPU value. @@ -1119,6 +1150,9 @@ static void check_early_cpu_features(void) { verify_cpu_run_el(); verify_cpu_asid_bits(); + + if (!verify_local_cpu_features(arm64_early_features)) + cpu_panic_kernel(); } static void @@ -1133,26 +1167,6 @@ static void check_early_cpu_features(void) } } -static void -verify_local_cpu_features(const struct arm64_cpu_capabilities *caps) -{ - for (; caps->matches; caps++) { - if (!cpus_have_cap(caps->capability)) - continue; - /* - * If the new CPU misses an advertised feature, we cannot proceed - * further, park the cpu. - */ - if (!caps->matches(caps, SCOPE_LOCAL_CPU)) { - pr_crit("CPU%d: missing feature: %s\n", - smp_processor_id(), caps->desc); - cpu_die_early(); - } - if (caps->enable) - caps->enable(NULL); - } -} - static void verify_sve_features(void) { u64 safe_zcr = read_sanitised_ftr_reg(SYS_ZCR_EL1); @@ -1181,7 +1195,10 @@ static void verify_sve_features(void) static void verify_local_cpu_capabilities(void) { verify_local_cpu_errata_workarounds(); - verify_local_cpu_features(arm64_features); + + if (!verify_local_cpu_features(arm64_features)) + cpu_die_early(); + verify_local_elf_hwcaps(arm64_elf_hwcaps); if (system_supports_32bit_el0()) @@ -1211,6 +1228,13 @@ void check_local_cpu_capabilities(void) verify_local_cpu_capabilities(); } +static void __init setup_early_feature_capabilities(void) +{ + update_cpu_capabilities(arm64_early_features, + "early detected feature:"); + enable_cpu_capabilities(arm64_early_features); +} + static void __init setup_feature_capabilities(void) { update_cpu_capabilities(arm64_features, "detected feature:"); @@ -1249,6 +1273,7 @@ static bool __this_cpu_has_cap(const struct arm64_cpu_capabilities *cap_array, bool this_cpu_has_cap(unsigned int cap) { return (__this_cpu_has_cap(arm64_features, cap) || + __this_cpu_has_cap(arm64_early_features, cap) || __this_cpu_has_cap(arm64_errata, cap)); }