From patchwork Wed Oct 11 13:00:57 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Julien Thierry X-Patchwork-Id: 9999599 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id F1B6A6037F for ; Wed, 11 Oct 2017 13:06:15 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id E130D27853 for ; Wed, 11 Oct 2017 13:06:15 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id D5E7228A0D; Wed, 11 Oct 2017 13:06:15 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-4.2 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from bombadil.infradead.org (bombadil.infradead.org [65.50.211.133]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 48E8527853 for ; Wed, 11 Oct 2017 13:06:15 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:MIME-Version:Cc:List-Subscribe: List-Help:List-Post:List-Archive:List-Unsubscribe:List-Id:References: In-Reply-To:Message-Id:Date:Subject:To:From:Reply-To:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Owner; bh=+IFvSSCjKZG25al88aQ2VeE1MUo7QQa3MN0Jvh37ivk=; b=JoE6EpgKdEUDTJyxj0kPVckVBc 5qgQlfLZ/YmsruRx17itAtg5Um6AKU3E7AU2oPvJMQQApX/HGXLPinyPFHhA88PHPJJE8BwQd08Z5 Miir6oKszxX6vvdAyfpk6JQ1SC0uvQMKjI1KdVtTuZOPHDhmJAG68QcxPZ18nICMcSw+713BzDJUb Mf0lqg+SxVZ7BoPSsMAmKcwWxNmFdYO73RszAl08wX5INV6JH1PgG7cLmqUjL6KCRKe3xZUFGqzw/ M3nPpsMB4Y18gNBd892GKEy8X61g1Fh8qZqR8Fm0vjLCkxNZEnMH/mgLROZvuASYiQShEF9LcstGn Wc1F6jaA==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.87 #1 (Red Hat Linux)) id 1e2GiE-0001jZ-Cz; Wed, 11 Oct 2017 13:06:14 +0000 Received: from foss.arm.com ([217.140.101.70]) by bombadil.infradead.org with esmtp (Exim 4.87 #1 (Red Hat Linux)) id 1e2Gdg-0005cF-Ln for linux-arm-kernel@lists.infradead.org; Wed, 11 Oct 2017 13:01:37 +0000 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 0515415AD; Wed, 11 Oct 2017 06:01:17 -0700 (PDT) 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 A24F63F483; Wed, 11 Oct 2017 06:01:15 -0700 (PDT) From: Julien Thierry To: linux-arm-kernel@lists.infradead.org, daniel.thompson@linaro.org, marc.zyngier@arm.com, mark.rutland@arm.com Subject: [RFC 2/7] arm64: cpufeature: Allow early detect of specific features Date: Wed, 11 Oct 2017 14:00:57 +0100 Message-Id: <1507726862-11944-3-git-send-email-julien.thierry@arm.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1507726862-11944-1-git-send-email-julien.thierry@arm.com> References: <1507726862-11944-1-git-send-email-julien.thierry@arm.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20171011_060132_793430_00CB7756 X-CRM114-Status: GOOD ( 15.11 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Catalin Marinas , Suzuki K Poulose , Will Deacon , Julien Thierry MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Virus-Scanned: ClamAV using ClamSMTP 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, do not move init_cpu_features] Signed-off-by: Julien Thierry Cc: Catalin Marinas Cc: Will Deacon Cc: Suzuki K Poulose --- arch/arm64/kernel/cpufeature.c | 67 ++++++++++++++++++++++++++++-------------- 1 file changed, 45 insertions(+), 22 deletions(-) -- 1.9.1 diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c index 21e2c95..0e58cdd 100644 --- a/arch/arm64/kernel/cpufeature.c +++ b/arch/arm64/kernel/cpufeature.c @@ -51,6 +51,8 @@ DECLARE_BITMAP(cpu_hwcaps, ARM64_NCAPS); EXPORT_SYMBOL(cpu_hwcaps); +static void __init setup_early_feature_capabilities(void); + static int dump_cpu_hwcaps(struct notifier_block *self, unsigned long v, void *p) { /* file-wide pr_fmt adds "CPU features: " prefix */ @@ -505,6 +507,7 @@ void __init init_cpu_features(struct cpuinfo_arm64 *info) init_cpu_ftr_reg(SYS_MVFR2_EL1, info->reg_mvfr2); } + setup_early_feature_capabilities(); } static void update_cpu_ftr_reg(struct arm64_ftr_reg *reg, u64 new) @@ -796,7 +799,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, @@ -807,6 +810,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", @@ -1055,6 +1062,29 @@ static inline void set_sys_caps_initialised(void) sys_caps_initialised = true; } +/* 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. @@ -1063,6 +1093,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 @@ -1077,26 +1110,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); - } -} - /* * Run through the enabled system capabilities and enable() it on this CPU. * The capabilities were decided based on the available CPUs at the boot time. @@ -1108,7 +1121,10 @@ static void check_early_cpu_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()) verify_local_elf_hwcaps(compat_elf_hwcaps); @@ -1134,6 +1150,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:");