From patchwork Tue Jan 25 16:50:34 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jisheng Zhang X-Patchwork-Id: 12724042 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 26254C433F5 for ; Tue, 25 Jan 2022 16:58:28 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-Id:Date:Subject:Cc:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=L/+5Qm+a34cxE7L2Imc2V5FD7rTIe6SQGjt0nwDXyRk=; b=xDZWV/3eJmKWQL yl1Zf0LjBxIto+xcfbQsvpV/SHrlucPoGaaTQp5uy7jleE11Z7b+cBr2grk1k3kuB0I09KZUst4ui jpdoG+MomGDn8OC5fo9HIQxQHIRq0Ss9QD4DS0gWDELTFDENlIRNUSNvl6SnQdL6J06DyReLUAbHi 7/Ob3bfZicFZMYt44Kv64kkSWMcVIq75usrimlRkWnTNThq8scyuEXPrbL6y+NUrwjGFCoO1AhpAj TYTvApvVQGwov9KZxNE5BE4+h5RRv+e6ygbERTdqS0iquuNu5z6AJuu2WwT74p0SNx4gFpWFCWLy5 scM9ZmCvIe8vGAZKKXjg==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1nCP9B-008oln-5M; Tue, 25 Jan 2022 16:58:21 +0000 Received: from ams.source.kernel.org ([2604:1380:4601:e00::1]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1nCP96-008ojk-Qi for linux-riscv@lists.infradead.org; Tue, 25 Jan 2022 16:58:18 +0000 Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ams.source.kernel.org (Postfix) with ESMTPS id 5A4D1B81912; Tue, 25 Jan 2022 16:58:15 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 942B9C340E0; Tue, 25 Jan 2022 16:58:11 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1643129894; bh=I+ef37gDpw0j39EXTaSOMc1BVOQf5hfN3THc7cxFln4=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=fNch9TQEHH/tkZsu3oImGUVpi5zTGrQuB98uq8baxAzs5rnN9gpXoLpPbrzc0+fD5 rDrkMSNvpYO7pF3Bz8B3FttaIRxkLLJXcKv6AlXE0rR9W39fksYPrBfWlbDoqwEtFO TT1Q1CwbWX6aPx7ujSHkR+1DuvlFry5AuwywBzHILMAS4mV+xyXD2rjl6ATni7xkIG adoTUQtxiQg7oSmaU3ZB/sRFfJH6CqEIo6GkDeSsk5JiHirXKb8ZZmeae8BTDHSGF7 QKxDjm8m3Bahe9kYNO+jGZbEUbkFsmD7YD0w6Rsssx62FRk5fsL1LMKDiJ0sH1AzLY OubmcVw9t+nyg== From: Jisheng Zhang To: Paul Walmsley , Palmer Dabbelt , Albert Ou , Andrey Ryabinin , Alexander Potapenko , Andrey Konovalov , Dmitry Vyukov , Alexandre Ghiti Cc: linux-riscv@lists.infradead.org, linux-kernel@vger.kernel.org, kasan-dev@googlegroups.com Subject: [PATCH 1/3] riscv: introduce unified static key mechanism for CPU features Date: Wed, 26 Jan 2022 00:50:34 +0800 Message-Id: <20220125165036.987-2-jszhang@kernel.org> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220125165036.987-1-jszhang@kernel.org> References: <20220125165036.987-1-jszhang@kernel.org> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20220125_085817_196288_E364DFFE X-CRM114-Status: GOOD ( 26.06 ) X-BeenThere: linux-riscv@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-riscv" Errors-To: linux-riscv-bounces+linux-riscv=archiver.kernel.org@lists.infradead.org Currently, riscv has several features why may not be supported on all riscv platforms, for example, FPU, SV48 and so on. To support unified kernel Image style, we need to check whether the feature is suportted or not. If the check sits at hot code path, then performance will be impacted a lot. static key can be used to solve the issue. In the past FPU support has been converted to use static key mechanism. I believe we will have similar cases in the future. Similar as arm64 does(in fact, some code is borrowed from arm64), this patch tries to add an unified mechanism to use static keys for all the cpu features by implementing an array of default-false static keys and enabling them when detected. The cpus_have_*_cap() check uses the static keys if riscv_const_caps_ready is finalized, otherwise the compiler generates the bitmap test. Signed-off-by: Jisheng Zhang --- arch/riscv/Makefile | 3 + arch/riscv/include/asm/cpufeature.h | 94 +++++++++++++++++++++++++++++ arch/riscv/kernel/cpufeature.c | 23 +++++++ arch/riscv/tools/Makefile | 22 +++++++ arch/riscv/tools/cpucaps | 5 ++ arch/riscv/tools/gen-cpucaps.awk | 40 ++++++++++++ 6 files changed, 187 insertions(+) create mode 100644 arch/riscv/include/asm/cpufeature.h create mode 100644 arch/riscv/tools/Makefile create mode 100644 arch/riscv/tools/cpucaps create mode 100755 arch/riscv/tools/gen-cpucaps.awk diff --git a/arch/riscv/Makefile b/arch/riscv/Makefile index 8a107ed18b0d..65c63023c8a8 100644 --- a/arch/riscv/Makefile +++ b/arch/riscv/Makefile @@ -148,3 +148,6 @@ PHONY += rv64_randconfig rv64_randconfig: $(Q)$(MAKE) KCONFIG_ALLCONFIG=$(srctree)/arch/riscv/configs/64-bit.config \ -f $(srctree)/Makefile randconfig + +archprepare: + $(Q)$(MAKE) $(build)=arch/riscv/tools kapi diff --git a/arch/riscv/include/asm/cpufeature.h b/arch/riscv/include/asm/cpufeature.h new file mode 100644 index 000000000000..d80ddd2f3b49 --- /dev/null +++ b/arch/riscv/include/asm/cpufeature.h @@ -0,0 +1,94 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (C) 2014 Linaro Ltd. + * Copyright (C) 2022 Jisheng Zhang + */ + +#ifndef __ASM_CPUFEATURE_H +#define __ASM_CPUFEATURE_H + +#include + +#include +#include +#include + +extern DECLARE_BITMAP(cpu_hwcaps, RISCV_NCAPS); +extern struct static_key_false cpu_hwcap_keys[RISCV_NCAPS]; +extern struct static_key_false riscv_const_caps_ready; + +static __always_inline bool system_capabilities_finalized(void) +{ + return static_branch_likely(&riscv_const_caps_ready); +} + +/* + * Test for a capability with a runtime check. + * + * Before the capability is detected, this returns false. + */ +static inline bool cpus_have_cap(unsigned int num) +{ + if (num >= RISCV_NCAPS) + return false; + return test_bit(num, cpu_hwcaps); +} + +/* + * Test for a capability without a runtime check. + * + * Before capabilities are finalized, this returns false. + * After capabilities are finalized, this is patched to avoid a runtime check. + * + * @num must be a compile-time constant. + */ +static __always_inline bool __cpus_have_const_cap(int num) +{ + if (num >= RISCV_NCAPS) + return false; + return static_branch_unlikely(&cpu_hwcap_keys[num]); +} + +/* + * Test for a capability without a runtime check. + * + * Before capabilities are finalized, this will BUG(). + * After capabilities are finalized, this is patched to avoid a runtime check. + * + * @num must be a compile-time constant. + */ +static __always_inline bool cpus_have_final_cap(int num) +{ + if (system_capabilities_finalized()) + return __cpus_have_const_cap(num); + else + BUG(); +} + +/* + * Test for a capability, possibly with a runtime check. + * + * Before capabilities are finalized, this behaves as cpus_have_cap(). + * After capabilities are finalized, this is patched to avoid a runtime check. + * + * @num must be a compile-time constant. + */ +static __always_inline bool cpus_have_const_cap(int num) +{ + if (system_capabilities_finalized()) + return __cpus_have_const_cap(num); + else + return cpus_have_cap(num); +} + +static inline void cpus_set_cap(unsigned int num) +{ + if (num >= RISCV_NCAPS) { + pr_warn("Attempt to set an illegal CPU capability (%d >= %d)\n", + num, RISCV_NCAPS); + } else { + __set_bit(num, cpu_hwcaps); + } +} + +#endif diff --git a/arch/riscv/kernel/cpufeature.c b/arch/riscv/kernel/cpufeature.c index d959d207a40d..09331abfa70c 100644 --- a/arch/riscv/kernel/cpufeature.c +++ b/arch/riscv/kernel/cpufeature.c @@ -8,6 +8,7 @@ #include #include +#include #include #include #include @@ -22,6 +23,15 @@ static DECLARE_BITMAP(riscv_isa, RISCV_ISA_EXT_MAX) __read_mostly; __ro_after_init DEFINE_STATIC_KEY_FALSE(cpu_hwcap_fpu); #endif +DECLARE_BITMAP(cpu_hwcaps, RISCV_NCAPS); +EXPORT_SYMBOL(cpu_hwcaps); + +DEFINE_STATIC_KEY_ARRAY_FALSE(cpu_hwcap_keys, RISCV_NCAPS); +EXPORT_SYMBOL(cpu_hwcap_keys); + +DEFINE_STATIC_KEY_FALSE(riscv_const_caps_ready); +EXPORT_SYMBOL(riscv_const_caps_ready); + /** * riscv_isa_extension_base() - Get base extension word * @@ -59,6 +69,17 @@ bool __riscv_isa_extension_available(const unsigned long *isa_bitmap, int bit) } EXPORT_SYMBOL_GPL(__riscv_isa_extension_available); +static void __init enable_cpu_capabilities(void) +{ + int i; + + for (i = 0; i < RISCV_NCAPS; i++) { + if (!cpus_have_cap(i)) + continue; + static_branch_enable(&cpu_hwcap_keys[i]); + } +} + void __init riscv_fill_hwcap(void) { struct device_node *node; @@ -148,4 +169,6 @@ void __init riscv_fill_hwcap(void) if (elf_hwcap & (COMPAT_HWCAP_ISA_F | COMPAT_HWCAP_ISA_D)) static_branch_enable(&cpu_hwcap_fpu); #endif + enable_cpu_capabilities(); + static_branch_enable(&riscv_const_caps_ready); } diff --git a/arch/riscv/tools/Makefile b/arch/riscv/tools/Makefile new file mode 100644 index 000000000000..932b4fe5c768 --- /dev/null +++ b/arch/riscv/tools/Makefile @@ -0,0 +1,22 @@ +# SPDX-License-Identifier: GPL-2.0 + +gen := arch/$(ARCH)/include/generated +kapi := $(gen)/asm + +kapi-hdrs-y := $(kapi)/cpucaps.h + +targets += $(addprefix ../../../,$(gen-y) $(kapi-hdrs-y)) + +PHONY += kapi + +kapi: $(kapi-hdrs-y) $(gen-y) + +# Create output directory if not already present +_dummy := $(shell [ -d '$(kapi)' ] || mkdir -p '$(kapi)') + +quiet_cmd_gen_cpucaps = GEN $@ + cmd_gen_cpucaps = mkdir -p $(dir $@) && \ + $(AWK) -f $(filter-out $(PHONY),$^) > $@ + +$(kapi)/cpucaps.h: $(src)/gen-cpucaps.awk $(src)/cpucaps FORCE + $(call if_changed,gen_cpucaps) diff --git a/arch/riscv/tools/cpucaps b/arch/riscv/tools/cpucaps new file mode 100644 index 000000000000..cb1ff2747859 --- /dev/null +++ b/arch/riscv/tools/cpucaps @@ -0,0 +1,5 @@ +# SPDX-License-Identifier: GPL-2.0 +# +# Internal CPU capabilities constants, keep this list sorted + +HAS_NO_FPU diff --git a/arch/riscv/tools/gen-cpucaps.awk b/arch/riscv/tools/gen-cpucaps.awk new file mode 100755 index 000000000000..52a1e1b064ad --- /dev/null +++ b/arch/riscv/tools/gen-cpucaps.awk @@ -0,0 +1,40 @@ +#!/bin/awk -f +# SPDX-License-Identifier: GPL-2.0 +# gen-cpucaps.awk: riscv cpucaps header generator +# +# Usage: awk -f gen-cpucaps.awk cpucaps.txt + +# Log an error and terminate +function fatal(msg) { + print "Error at line " NR ": " msg > "/dev/stderr" + exit 1 +} + +# skip blank lines and comment lines +/^$/ { next } +/^#/ { next } + +BEGIN { + print "#ifndef __ASM_CPUCAPS_H" + print "#define __ASM_CPUCAPS_H" + print "" + print "/* Generated file - do not edit */" + cap_num = 0 + print "" +} + +/^[vA-Z0-9_]+$/ { + printf("#define RISCV_%-30s\t%d\n", $0, cap_num++) + next +} + +END { + printf("#define RISCV_NCAPS\t\t\t\t%d\n", cap_num) + print "" + print "#endif /* __ASM_CPUCAPS_H */" +} + +# Any lines not handled by previous rules are unexpected +{ + fatal("unhandled statement") +} From patchwork Tue Jan 25 16:50:35 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jisheng Zhang X-Patchwork-Id: 12724043 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 1BDBDC433EF for ; Tue, 25 Jan 2022 16:58:30 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-Id:Date:Subject:Cc:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=0Aei8QrUBKLXnjzuqCCUL9YPpqJfdhAEqCBrq0akq50=; b=CvOioEETbdmKiD m5ICX9jpA7VaWbJvYsL5sWjchmz0cWJD5tOVUEEDSUDH3j1sk3tIAui/X/klAW5j7/zXNtrx0k0lb wFx1JfN/vcLkHEJhcOy0g+phlKUHnZeKmn26gPnN1F+EF1hBB53iCohMFD96cbpCK9e+ZKKGFzLv3 Z74BTIqfB09RtpKhB/j7Uyig7x8bB5ciOVMtfQrkYzxQTUSsT/3XNcY3/0ch/WQshl3RnxNyOkSKq P/YXcRiM/spCa0QNNhevRIZPKacAJrcp4JKiWZfPGYucQ6wSYH/DMpo4ZLwUjciUxCP7fbq/XQR8l Jjoqcucwn7ABH8Wm3RUg==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1nCP9D-008onH-Ec; Tue, 25 Jan 2022 16:58:23 +0000 Received: from dfw.source.kernel.org ([139.178.84.217]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1nCP98-008okk-Uv for linux-riscv@lists.infradead.org; Tue, 25 Jan 2022 16:58:20 +0000 Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id 8779960F03; Tue, 25 Jan 2022 16:58:18 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 03D8AC340E8; Tue, 25 Jan 2022 16:58:14 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1643129898; bh=eY/S0q2iP6uSlBdAmwwfuaur78GUJEQH/qQszn/QL90=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=fimlBcBb0INWmijAXC6G0YQW6HSIKLghDMKJGXvd3VfcousVxXBgw/5HboIJw37mf ekrNyxSPPBK7Zs2oMLvYGC+7hndb5m6LN6KtbQWbmaMvlXqaUIUn7i/Aq9mTkuj0KS g4V2J46TBjO68DhBLPumEZhptMlYbDsH1vV3p0ruhVSQLeIVaJlEnlw1ZGis8nUWqa Bk5cta/utC00d8vyGs0hu/LrQE6NK0+/RPOVgD/YvEK5chBDUesAA9PCud2sx9ExQ9 WMIUJbAzuENeqSDIbhVasTnv+8PrK2kBzxr3F1/P9EKmLns/rurwdUVy3O5hsk2A/q cXEgRkRmiqHzw== From: Jisheng Zhang To: Paul Walmsley , Palmer Dabbelt , Albert Ou , Andrey Ryabinin , Alexander Potapenko , Andrey Konovalov , Dmitry Vyukov , Alexandre Ghiti Cc: linux-riscv@lists.infradead.org, linux-kernel@vger.kernel.org, kasan-dev@googlegroups.com Subject: [PATCH 2/3] riscv: replace has_fpu() with system_supports_fpu() Date: Wed, 26 Jan 2022 00:50:35 +0800 Message-Id: <20220125165036.987-3-jszhang@kernel.org> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220125165036.987-1-jszhang@kernel.org> References: <20220125165036.987-1-jszhang@kernel.org> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20220125_085819_121009_04C2B76B X-CRM114-Status: GOOD ( 17.14 ) X-BeenThere: linux-riscv@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-riscv" Errors-To: linux-riscv-bounces+linux-riscv=archiver.kernel.org@lists.infradead.org This is to use the unified cpus_have_{final|const}_cap() instead of putting static key related here and there. Signed-off-by: Jisheng Zhang --- arch/riscv/include/asm/cpufeature.h | 5 +++++ arch/riscv/include/asm/switch_to.h | 9 ++------- arch/riscv/kernel/cpufeature.c | 8 ++------ arch/riscv/kernel/process.c | 2 +- arch/riscv/kernel/signal.c | 4 ++-- 5 files changed, 12 insertions(+), 16 deletions(-) diff --git a/arch/riscv/include/asm/cpufeature.h b/arch/riscv/include/asm/cpufeature.h index d80ddd2f3b49..634a653c7fa2 100644 --- a/arch/riscv/include/asm/cpufeature.h +++ b/arch/riscv/include/asm/cpufeature.h @@ -91,4 +91,9 @@ static inline void cpus_set_cap(unsigned int num) } } +static inline bool system_supports_fpu(void) +{ + return IS_ENABLED(CONFIG_FPU) && !cpus_have_final_cap(RISCV_HAS_NO_FPU); +} + #endif diff --git a/arch/riscv/include/asm/switch_to.h b/arch/riscv/include/asm/switch_to.h index 0a3f4f95c555..362cb18d12d5 100644 --- a/arch/riscv/include/asm/switch_to.h +++ b/arch/riscv/include/asm/switch_to.h @@ -8,6 +8,7 @@ #include #include +#include #include #include #include @@ -56,13 +57,7 @@ static inline void __switch_to_aux(struct task_struct *prev, fstate_restore(next, task_pt_regs(next)); } -extern struct static_key_false cpu_hwcap_fpu; -static __always_inline bool has_fpu(void) -{ - return static_branch_likely(&cpu_hwcap_fpu); -} #else -static __always_inline bool has_fpu(void) { return false; } #define fstate_save(task, regs) do { } while (0) #define fstate_restore(task, regs) do { } while (0) #define __switch_to_aux(__prev, __next) do { } while (0) @@ -75,7 +70,7 @@ extern struct task_struct *__switch_to(struct task_struct *, do { \ struct task_struct *__prev = (prev); \ struct task_struct *__next = (next); \ - if (has_fpu()) \ + if (system_supports_fpu()) \ __switch_to_aux(__prev, __next); \ ((last) = __switch_to(__prev, __next)); \ } while (0) diff --git a/arch/riscv/kernel/cpufeature.c b/arch/riscv/kernel/cpufeature.c index 09331abfa70c..da272b399af6 100644 --- a/arch/riscv/kernel/cpufeature.c +++ b/arch/riscv/kernel/cpufeature.c @@ -19,10 +19,6 @@ unsigned long elf_hwcap __read_mostly; /* Host ISA bitmap */ static DECLARE_BITMAP(riscv_isa, RISCV_ISA_EXT_MAX) __read_mostly; -#ifdef CONFIG_FPU -__ro_after_init DEFINE_STATIC_KEY_FALSE(cpu_hwcap_fpu); -#endif - DECLARE_BITMAP(cpu_hwcaps, RISCV_NCAPS); EXPORT_SYMBOL(cpu_hwcaps); @@ -166,8 +162,8 @@ void __init riscv_fill_hwcap(void) pr_info("riscv: ELF capabilities %s\n", print_str); #ifdef CONFIG_FPU - if (elf_hwcap & (COMPAT_HWCAP_ISA_F | COMPAT_HWCAP_ISA_D)) - static_branch_enable(&cpu_hwcap_fpu); + if (!(elf_hwcap & (COMPAT_HWCAP_ISA_F | COMPAT_HWCAP_ISA_D))) + cpus_set_cap(RISCV_HAS_NO_FPU); #endif enable_cpu_capabilities(); static_branch_enable(&riscv_const_caps_ready); diff --git a/arch/riscv/kernel/process.c b/arch/riscv/kernel/process.c index 03ac3aa611f5..ece62392b79f 100644 --- a/arch/riscv/kernel/process.c +++ b/arch/riscv/kernel/process.c @@ -87,7 +87,7 @@ void start_thread(struct pt_regs *regs, unsigned long pc, unsigned long sp) { regs->status = SR_PIE; - if (has_fpu()) { + if (system_supports_fpu()) { regs->status |= SR_FS_INITIAL; /* * Restore the initial value to the FP register diff --git a/arch/riscv/kernel/signal.c b/arch/riscv/kernel/signal.c index c2d5ecbe5526..c236eb777fbc 100644 --- a/arch/riscv/kernel/signal.c +++ b/arch/riscv/kernel/signal.c @@ -90,7 +90,7 @@ static long restore_sigcontext(struct pt_regs *regs, /* sc_regs is structured the same as the start of pt_regs */ err = __copy_from_user(regs, &sc->sc_regs, sizeof(sc->sc_regs)); /* Restore the floating-point state. */ - if (has_fpu()) + if (system_supports_fpu()) err |= restore_fp_state(regs, &sc->sc_fpregs); return err; } @@ -143,7 +143,7 @@ static long setup_sigcontext(struct rt_sigframe __user *frame, /* sc_regs is structured the same as the start of pt_regs */ err = __copy_to_user(&sc->sc_regs, regs, sizeof(sc->sc_regs)); /* Save the floating-point state. */ - if (has_fpu()) + if (system_supports_fpu()) err |= save_fp_state(regs, &sc->sc_fpregs); return err; } From patchwork Tue Jan 25 16:50:36 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jisheng Zhang X-Patchwork-Id: 12724044 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 80F49C433F5 for ; Tue, 25 Jan 2022 16:58:36 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-Id:Date:Subject:Cc:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=XzG6vJkv3VhGRDAfBEQXF5GL32w+wEm/NYL7jUu1hVg=; b=MqaAeJrgcQqpbM 78jnKsUPKgrFZbt+MvdrcKqHxUjDKnVEpXh8YyJgoVCuCedX1aSq/6j4VnI+z3WL2K6YnmOYCRk7/ OknbG4pEFLDpPS05phg6FbD9VKpD9PMLd3MtQgRvxuYJQ3Uw/gmdx0w5Uxy90gk7BAq3RampYf1aB rRTpDJkRwnlGcbEBmX/MUfwujXLATt1QmMwe7pn7EYh24R1C5cL548F9KUE62Rs4TU9/b+hcLMocj RboF42kpkWY/qCe5UO96u2ZYGjKKI14xBGtvOkreytyueRapmHozc7kNj6kvH1AptEfPEKKuV0+hv /wHa2zDT5Y+XZT9HH86g==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1nCP9I-008oqn-VB; Tue, 25 Jan 2022 16:58:28 +0000 Received: from ams.source.kernel.org ([2604:1380:4601:e00::1]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1nCP9D-008onE-TE for linux-riscv@lists.infradead.org; Tue, 25 Jan 2022 16:58:26 +0000 Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ams.source.kernel.org (Postfix) with ESMTPS id 7D9C7B81912; Tue, 25 Jan 2022 16:58:22 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 7B036C340E0; Tue, 25 Jan 2022 16:58:18 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1643129901; bh=0JTUTncS+D5Fiykm7xtb+/SFyenCaQLIIFOpuGzk77s=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=H2CXBtZxryn9upBAGxtAnZPq9VGZynL7tpYv7bQCAkedpYJkwi6FNUervs7m81fL+ 9UUU8w1yBH0dne6DUsmAxjN6vhV2YL+dyxc3nS3QWCwlx/3/jJOC7DNJ2z41pO2jxc Gh8LbdXnSCokuBjP5Si+LhZuJc9w+/oU8TkijUH/ZyK5BMWoLqTz2HOA8z69VaSAd5 Z9u7CNrBnwN/TBI6sjvEEbFjaaGh9SKtxIl9pZnHhYdPGKnTcdCLI3lXi08rJehcog RKonLlinMIDFyGIqpZGnLNeanl/qxcLVH7HoQQpQ0LLrGm4VXL8cpZu8oEmsf9/thR hSEZGnEex43kw== From: Jisheng Zhang To: Paul Walmsley , Palmer Dabbelt , Albert Ou , Andrey Ryabinin , Alexander Potapenko , Andrey Konovalov , Dmitry Vyukov , Alexandre Ghiti Cc: linux-riscv@lists.infradead.org, linux-kernel@vger.kernel.org, kasan-dev@googlegroups.com Subject: [PATCH 3/3] riscv: convert pgtable_l4_enabled to static key Date: Wed, 26 Jan 2022 00:50:36 +0800 Message-Id: <20220125165036.987-4-jszhang@kernel.org> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220125165036.987-1-jszhang@kernel.org> References: <20220125165036.987-1-jszhang@kernel.org> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20220125_085824_261875_BC85B8C8 X-CRM114-Status: GOOD ( 20.15 ) X-BeenThere: linux-riscv@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-riscv" Errors-To: linux-riscv-bounces+linux-riscv=archiver.kernel.org@lists.infradead.org On a specific HW platform, pgtable_l4_enabled won't change after boot, and the check sits at hot code path, this characteristic make it suitable for optimization with static key. Signed-off-by: Jisheng Zhang Reported-by: kernel test robot Reported-by: kernel test robot --- arch/riscv/include/asm/cpufeature.h | 6 ++++++ arch/riscv/include/asm/pgalloc.h | 8 ++++---- arch/riscv/include/asm/pgtable-64.h | 21 ++++++++++----------- arch/riscv/include/asm/pgtable.h | 3 +-- arch/riscv/kernel/cpu.c | 2 +- arch/riscv/mm/init.c | 23 ++++++++++------------- arch/riscv/mm/kasan_init.c | 6 +++--- arch/riscv/tools/cpucaps | 1 + 8 files changed, 36 insertions(+), 34 deletions(-) diff --git a/arch/riscv/include/asm/cpufeature.h b/arch/riscv/include/asm/cpufeature.h index 634a653c7fa2..10af83d6fb2a 100644 --- a/arch/riscv/include/asm/cpufeature.h +++ b/arch/riscv/include/asm/cpufeature.h @@ -96,4 +96,10 @@ static inline bool system_supports_fpu(void) return IS_ENABLED(CONFIG_FPU) && !cpus_have_final_cap(RISCV_HAS_NO_FPU); } +static inline bool system_supports_sv48(void) +{ + return IS_ENABLED(CONFIG_64BIT) && !IS_ENABLED(CONFIG_XIP_KERNEL) && + !cpus_have_const_cap(RISCV_HAS_NO_SV48); +} + #endif diff --git a/arch/riscv/include/asm/pgalloc.h b/arch/riscv/include/asm/pgalloc.h index 11823004b87a..cd37f3777ff1 100644 --- a/arch/riscv/include/asm/pgalloc.h +++ b/arch/riscv/include/asm/pgalloc.h @@ -41,7 +41,7 @@ static inline void pud_populate(struct mm_struct *mm, pud_t *pud, pmd_t *pmd) static inline void p4d_populate(struct mm_struct *mm, p4d_t *p4d, pud_t *pud) { - if (pgtable_l4_enabled) { + if (system_supports_sv48()) { unsigned long pfn = virt_to_pfn(pud); set_p4d(p4d, __p4d((pfn << _PAGE_PFN_SHIFT) | _PAGE_TABLE)); @@ -51,7 +51,7 @@ static inline void p4d_populate(struct mm_struct *mm, p4d_t *p4d, pud_t *pud) static inline void p4d_populate_safe(struct mm_struct *mm, p4d_t *p4d, pud_t *pud) { - if (pgtable_l4_enabled) { + if (system_supports_sv48()) { unsigned long pfn = virt_to_pfn(pud); set_p4d_safe(p4d, @@ -62,7 +62,7 @@ static inline void p4d_populate_safe(struct mm_struct *mm, p4d_t *p4d, #define pud_alloc_one pud_alloc_one static inline pud_t *pud_alloc_one(struct mm_struct *mm, unsigned long addr) { - if (pgtable_l4_enabled) + if (system_supports_sv48()) return __pud_alloc_one(mm, addr); return NULL; @@ -71,7 +71,7 @@ static inline pud_t *pud_alloc_one(struct mm_struct *mm, unsigned long addr) #define pud_free pud_free static inline void pud_free(struct mm_struct *mm, pud_t *pud) { - if (pgtable_l4_enabled) + if (system_supports_sv48()) __pud_free(mm, pud); } diff --git a/arch/riscv/include/asm/pgtable-64.h b/arch/riscv/include/asm/pgtable-64.h index bbbdd66e5e2f..5ad4311f9c6e 100644 --- a/arch/riscv/include/asm/pgtable-64.h +++ b/arch/riscv/include/asm/pgtable-64.h @@ -7,14 +7,13 @@ #define _ASM_RISCV_PGTABLE_64_H #include - -extern bool pgtable_l4_enabled; +#include #define PGDIR_SHIFT_L3 30 #define PGDIR_SHIFT_L4 39 #define PGDIR_SIZE_L3 (_AC(1, UL) << PGDIR_SHIFT_L3) -#define PGDIR_SHIFT (pgtable_l4_enabled ? PGDIR_SHIFT_L4 : PGDIR_SHIFT_L3) +#define PGDIR_SHIFT (system_supports_sv48() ? PGDIR_SHIFT_L4 : PGDIR_SHIFT_L3) /* Size of region mapped by a page global directory */ #define PGDIR_SIZE (_AC(1, UL) << PGDIR_SHIFT) #define PGDIR_MASK (~(PGDIR_SIZE - 1)) @@ -102,7 +101,7 @@ static inline struct page *pud_page(pud_t pud) #define mm_pud_folded mm_pud_folded static inline bool mm_pud_folded(struct mm_struct *mm) { - if (pgtable_l4_enabled) + if (system_supports_sv48()) return false; return true; @@ -130,7 +129,7 @@ static inline unsigned long _pmd_pfn(pmd_t pmd) static inline void set_p4d(p4d_t *p4dp, p4d_t p4d) { - if (pgtable_l4_enabled) + if (system_supports_sv48()) *p4dp = p4d; else set_pud((pud_t *)p4dp, (pud_t){ p4d_val(p4d) }); @@ -138,7 +137,7 @@ static inline void set_p4d(p4d_t *p4dp, p4d_t p4d) static inline int p4d_none(p4d_t p4d) { - if (pgtable_l4_enabled) + if (system_supports_sv48()) return (p4d_val(p4d) == 0); return 0; @@ -146,7 +145,7 @@ static inline int p4d_none(p4d_t p4d) static inline int p4d_present(p4d_t p4d) { - if (pgtable_l4_enabled) + if (system_supports_sv48()) return (p4d_val(p4d) & _PAGE_PRESENT); return 1; @@ -154,7 +153,7 @@ static inline int p4d_present(p4d_t p4d) static inline int p4d_bad(p4d_t p4d) { - if (pgtable_l4_enabled) + if (system_supports_sv48()) return !p4d_present(p4d); return 0; @@ -162,13 +161,13 @@ static inline int p4d_bad(p4d_t p4d) static inline void p4d_clear(p4d_t *p4d) { - if (pgtable_l4_enabled) + if (system_supports_sv48()) set_p4d(p4d, __p4d(0)); } static inline pud_t *p4d_pgtable(p4d_t p4d) { - if (pgtable_l4_enabled) + if (system_supports_sv48()) return (pud_t *)pfn_to_virt(p4d_val(p4d) >> _PAGE_PFN_SHIFT); return (pud_t *)pud_pgtable((pud_t) { p4d_val(p4d) }); @@ -184,7 +183,7 @@ static inline struct page *p4d_page(p4d_t p4d) #define pud_offset pud_offset static inline pud_t *pud_offset(p4d_t *p4d, unsigned long address) { - if (pgtable_l4_enabled) + if (system_supports_sv48()) return p4d_pgtable(*p4d) + pud_index(address); return (pud_t *)p4d; diff --git a/arch/riscv/include/asm/pgtable.h b/arch/riscv/include/asm/pgtable.h index 7e949f25c933..40d999950e5b 100644 --- a/arch/riscv/include/asm/pgtable.h +++ b/arch/riscv/include/asm/pgtable.h @@ -62,7 +62,7 @@ * position vmemmap directly below the VMALLOC region. */ #ifdef CONFIG_64BIT -#define VA_BITS (pgtable_l4_enabled ? 48 : 39) +#define VA_BITS (system_supports_sv48() ? 48 : 39) #else #define VA_BITS 32 #endif @@ -735,7 +735,6 @@ extern uintptr_t _dtb_early_pa; #define dtb_early_pa _dtb_early_pa #endif /* CONFIG_XIP_KERNEL */ extern u64 satp_mode; -extern bool pgtable_l4_enabled; void paging_init(void); void misc_mem_init(void); diff --git a/arch/riscv/kernel/cpu.c b/arch/riscv/kernel/cpu.c index ad0a7e9f828b..ce38319232ec 100644 --- a/arch/riscv/kernel/cpu.c +++ b/arch/riscv/kernel/cpu.c @@ -79,7 +79,7 @@ static void print_mmu(struct seq_file *f) #if defined(CONFIG_32BIT) strncpy(sv_type, "sv32", 5); #elif defined(CONFIG_64BIT) - if (pgtable_l4_enabled) + if (system_supports_sv48()) strncpy(sv_type, "sv48", 5); else strncpy(sv_type, "sv39", 5); diff --git a/arch/riscv/mm/init.c b/arch/riscv/mm/init.c index 35586688a1b6..8a84606f99f0 100644 --- a/arch/riscv/mm/init.c +++ b/arch/riscv/mm/init.c @@ -44,9 +44,6 @@ u64 satp_mode __ro_after_init = SATP_MODE_32; #endif EXPORT_SYMBOL(satp_mode); -bool pgtable_l4_enabled = IS_ENABLED(CONFIG_64BIT) && !IS_ENABLED(CONFIG_XIP_KERNEL); -EXPORT_SYMBOL(pgtable_l4_enabled); - phys_addr_t phys_ram_base __ro_after_init; EXPORT_SYMBOL(phys_ram_base); @@ -459,19 +456,19 @@ static void __init create_pud_mapping(pud_t *pudp, } #define pgd_next_t pud_t -#define alloc_pgd_next(__va) (pgtable_l4_enabled ? \ +#define alloc_pgd_next(__va) (system_supports_sv48() ? \ pt_ops.alloc_pud(__va) : pt_ops.alloc_pmd(__va)) -#define get_pgd_next_virt(__pa) (pgtable_l4_enabled ? \ +#define get_pgd_next_virt(__pa) (system_supports_sv48() ? \ pt_ops.get_pud_virt(__pa) : (pgd_next_t *)pt_ops.get_pmd_virt(__pa)) #define create_pgd_next_mapping(__nextp, __va, __pa, __sz, __prot) \ - (pgtable_l4_enabled ? \ + (system_supports_sv48() ? \ create_pud_mapping(__nextp, __va, __pa, __sz, __prot) : \ create_pmd_mapping((pmd_t *)__nextp, __va, __pa, __sz, __prot)) -#define fixmap_pgd_next (pgtable_l4_enabled ? \ +#define fixmap_pgd_next (system_supports_sv48() ? \ (uintptr_t)fixmap_pud : (uintptr_t)fixmap_pmd) -#define trampoline_pgd_next (pgtable_l4_enabled ? \ +#define trampoline_pgd_next (system_supports_sv48() ? \ (uintptr_t)trampoline_pud : (uintptr_t)trampoline_pmd) -#define early_dtb_pgd_next (pgtable_l4_enabled ? \ +#define early_dtb_pgd_next (system_supports_sv48() ? \ (uintptr_t)early_dtb_pud : (uintptr_t)early_dtb_pmd) #else #define pgd_next_t pte_t @@ -575,7 +572,7 @@ static __init pgprot_t pgprot_from_va(uintptr_t va) #ifdef CONFIG_64BIT static void __init disable_pgtable_l4(void) { - pgtable_l4_enabled = false; + cpus_set_cap(RISCV_HAS_NO_SV48); kernel_map.page_offset = PAGE_OFFSET_L3; satp_mode = SATP_MODE_39; } @@ -691,7 +688,7 @@ static void __init create_fdt_early_page_table(pgd_t *pgdir, uintptr_t dtb_pa) PGDIR_SIZE, IS_ENABLED(CONFIG_64BIT) ? PAGE_TABLE : PAGE_KERNEL); - if (pgtable_l4_enabled) { + if (system_supports_sv48()) { create_pud_mapping(early_dtb_pud, DTB_EARLY_BASE_VA, (uintptr_t)early_dtb_pmd, PUD_SIZE, PAGE_TABLE); } @@ -819,7 +816,7 @@ asmlinkage void __init setup_vm(uintptr_t dtb_pa) #ifndef __PAGETABLE_PMD_FOLDED /* Setup fixmap PUD and PMD */ - if (pgtable_l4_enabled) + if (system_supports_sv48()) create_pud_mapping(fixmap_pud, FIXADDR_START, (uintptr_t)fixmap_pmd, PUD_SIZE, PAGE_TABLE); create_pmd_mapping(fixmap_pmd, FIXADDR_START, @@ -827,7 +824,7 @@ asmlinkage void __init setup_vm(uintptr_t dtb_pa) /* Setup trampoline PGD and PMD */ create_pgd_mapping(trampoline_pg_dir, kernel_map.virt_addr, trampoline_pgd_next, PGDIR_SIZE, PAGE_TABLE); - if (pgtable_l4_enabled) + if (system_supports_sv48()) create_pud_mapping(trampoline_pud, kernel_map.virt_addr, (uintptr_t)trampoline_pmd, PUD_SIZE, PAGE_TABLE); #ifdef CONFIG_XIP_KERNEL diff --git a/arch/riscv/mm/kasan_init.c b/arch/riscv/mm/kasan_init.c index f61f7ca6fe0f..3d456c5b55c8 100644 --- a/arch/riscv/mm/kasan_init.c +++ b/arch/riscv/mm/kasan_init.c @@ -149,11 +149,11 @@ static void __init kasan_populate_pud(pgd_t *pgd, set_pgd(pgd, pfn_pgd(PFN_DOWN(__pa(base_pud)), PAGE_TABLE)); } -#define kasan_early_shadow_pgd_next (pgtable_l4_enabled ? \ +#define kasan_early_shadow_pgd_next (system_supports_sv48() ? \ (uintptr_t)kasan_early_shadow_pud : \ (uintptr_t)kasan_early_shadow_pmd) #define kasan_populate_pgd_next(pgdp, vaddr, next, early) \ - (pgtable_l4_enabled ? \ + (system_supports_sv48() ? \ kasan_populate_pud(pgdp, vaddr, next, early) : \ kasan_populate_pmd((pud_t *)pgdp, vaddr, next)) @@ -211,7 +211,7 @@ asmlinkage void __init kasan_early_init(void) (__pa((uintptr_t)kasan_early_shadow_pte)), PAGE_TABLE)); - if (pgtable_l4_enabled) { + if (system_supports_sv48()) { for (i = 0; i < PTRS_PER_PUD; ++i) set_pud(kasan_early_shadow_pud + i, pfn_pud(PFN_DOWN diff --git a/arch/riscv/tools/cpucaps b/arch/riscv/tools/cpucaps index cb1ff2747859..1aea959f225d 100644 --- a/arch/riscv/tools/cpucaps +++ b/arch/riscv/tools/cpucaps @@ -3,3 +3,4 @@ # Internal CPU capabilities constants, keep this list sorted HAS_NO_FPU +HAS_NO_SV48