lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20251210-profiles-v1-6-315a6ff2ca5a@gmail.com>
Date: Wed, 10 Dec 2025 08:13:43 -0800
From: Charlie Jenkins <charlie@...osinc.com>
To: Paul Walmsley <pjw@...nel.org>, Palmer Dabbelt <palmer@...belt.com>, 
 Alexandre Ghiti <alex@...ti.fr>, Anup Patel <anup@...infault.org>, 
 Atish Patra <atish.patra@...ux.dev>, 
 Samuel Holland <samuel.holland@...ive.com>, 
 Björn Töpel <bjorn@...nel.org>, 
 Luke Nelson <luke.r.nels@...il.com>, Xi Wang <xi.wang@...il.com>, 
 Eric Biggers <ebiggers@...nel.org>, Conor Dooley <conor@...nel.org>
Cc: linux-riscv@...ts.infradead.org, linux-kernel@...r.kernel.org, 
 Charlie Jenkins <thecharlesjenkins@...il.com>
Subject: [PATCH RFC 06/10] riscv: Makefile: Add enabled extensions to
 compiler flags

Build an optimized kernel with all extensions that the hardware is
expected to support. Extensions that might be supported by hardware and
will be detected at runtime will be added to the assembler flags but not
to the compiler flags.

Signed-off-by: Charlie Jenkins <thecharlesjenkins@...il.com>
---
 arch/riscv/Makefile | 135 ++++++++++++++++++++++++++++++++++++++++++++--------
 1 file changed, 116 insertions(+), 19 deletions(-)

diff --git a/arch/riscv/Makefile b/arch/riscv/Makefile
index ef1a7b1bffe8..efe43537e984 100644
--- a/arch/riscv/Makefile
+++ b/arch/riscv/Makefile
@@ -57,37 +57,134 @@ ifeq ($(CONFIG_SHADOW_CALL_STACK),y)
 	KBUILD_LDFLAGS += --no-relax-gp
 endif
 
-# ISA string setting
-riscv-march-y				:= $(CONFIG_ARCH)
-riscv-march-$(CONFIG_FPU)		:= $(riscv-march-y)fd
-riscv-march-$(CONFIG_RISCV_ISA_C)	:= $(riscv-march-y)c
-riscv-march-$(CONFIG_RISCV_ISA_V)	:= $(riscv-march-y)v
+# Handling of riscv extensions
+# There are a couple of considerations when enabling extensions:
+#	1. Does the toolchain support the extension?
+#	2. Is the extension supported by the hardware the kernel will run on?
+#       3. Does the extension have registers that need to be save/restored on
+#          a context switch?
+#       4. Is this extension emitted by the compiler or only by hand-coded
+#          assembly?
+#
+# This section has helpers to support extensions with varying answers to these questions.
+#
+# The compiler will be allowed to emit an extension if all of the following
+# are satisfied:
+#       - The extension is a "stateless" extension (i.e. doesn't introduce additional
+#         registers)
+#	- The extension is supported by the toolchain (selected by CONFIG_TOOLCHAIN_HAS_*)
+#	- The extension is enabled for use in the kernel (selected by CONFIG_RISCV_ISA_*=y)
+#
+# Assembler support for the instruction will be added if the extension is
+# supported by the assembler (selected by CONFIG_TOOLCHAIN_HAS_*).
+
+# Extensions that the compiler is allowed to emit anywhere.
+riscv-march-standard				:= $(CONFIG_ARCH)
+
+# Extensions that the compiler is allowed to emit in FPU contexts.
+# This should riscv-march-standard plus the FPU-specific extensions.
+riscv-march-fpu					:= $(CONFIG_ARCH)
+
+# All extensions supported by the kernel. Some of these extensions require
+# special care so they cannot be arbitrarily emitted by the compiler.
+riscv-march-full				:= $(CONFIG_ARCH)
+
+# Returns the instruction if it is supported, returns the empty string otherwise.
+# An instruction is only "supported" if RISCV_ISA_*!=n.
+# An instruction that is "supported" can be emitted through alternatives, but an instruction that is
+# "enabled" can be emitted arbitrarily by the compiler.
+# Arguments:
+#	$1 - name of extension
+#	$2 - extension delimiter. Should be empty for base extensions and
+#	     underscore otherwise
+extension_supported=$(if $(and $(or $(filter $(CONFIG_RISCV_ISA_$(shell echo $1 | tr a-z A-Z)),m), $(filter $(CONFIG_RISCV_ISA_$(shell echo $1 | tr a-z A-Z)),y)), $(filter $(CONFIG_TOOLCHAIN_HAS_$(shell echo $1 | tr a-z A-Z)),y)),$2$1)
+
+# Returns the instruction if it is enabled, returns the empty string otherwise.
+# An instruction is only "enabled" if RISCV_ISA_*=y.
+# An instruction that is "supported" can be emitted through alternatives, but an instruction that is
+# "enabled" can be emitted arbitrarily by the compiler.
+# Arguments:
+#	$1 - name of extension
+#	$2 - extension delimiter. Should be empty for base extensions and
+#	     underscore otherwise
+extension_enabled=$(if $(and $(filter $(CONFIG_RISCV_ISA_$(shell echo $1 | tr a-z A-Z)),y), $(filter $(CONFIG_TOOLCHAIN_HAS_$(shell echo $1 | tr a-z A-Z)),y)),$2$1)
+
+# Use this macro to add support for an extension that is stateless.
+# A "stateless" extension is one that does not add additional registers.
+#
+# Arguments:
+#	$1 - name of extension
+#	$2 - extension delimiter. Should be empty for base extensions and
+#	     underscore otherwise
+define add_stateless_extension
+$(eval riscv-march-standard=$(riscv-march-standard)$(call extension_enabled,$1,$2))
+$(eval riscv-march-fpu=$(riscv-march-fpu)$(call extension_enabled,$1,$2))
+$(eval riscv-march-full=$(riscv-march-full)$(call extension_supported,$1,$2))
+endef
 
-ifneq ($(CONFIG_RISCV_ISA_C),y)
-	KBUILD_RUSTFLAGS += -Ctarget-feature=-c
-endif
+# Use this macro to add support for a floating point extension.
+# Floating point extensions are not able to be used in all contexts, so they
+# are kept separate.
+#
+# Arguments:
+#	$1 - name of extension
+#	$2 - extension delimiter. Should be empty for base extensions and
+#	     underscore otherwise
+define add_fpu_extension
+$(eval riscv-march-fpu=$(riscv-march-fpu)$(call extension_enabled,$1,$2))
+$(eval riscv-march-full=$(riscv-march-full)$(call extension_supported,$1,$2))
+endef
+
+# Use this macro to add support for an extension that is stateful.
+# A "stateful" extension is one that adds additional registers, or requires
+# hand-coded assembly (instead of being arbitrarily emitted by the compiler).
+#
+# Arguments:
+#	$1 - name of extension
+#	$2 - extension delimiter. Should be empty for base extensions and
+#	     underscore otherwise
+define add_stateful_extension
+$(eval riscv-march-full=$(riscv-march-full)$(call extension_supported,$1,$2))
+endef
+
+# Extensions must be added in the canonical ISA string order
+
+# Base extensions
+$(call add_fpu_extension,f)
+$(call add_fpu_extension,d)
+$(call add_stateless_extension,c)
+$(call add_stateful_extension,v)
 
 ifdef CONFIG_TOOLCHAIN_NEEDS_OLD_ISA_SPEC
 KBUILD_CFLAGS += -Wa,-misa-spec=2.2
 KBUILD_AFLAGS += -Wa,-misa-spec=2.2
 else
-riscv-march-$(CONFIG_TOOLCHAIN_NEEDS_EXPLICIT_ZICSR_ZIFENCEI) := $(riscv-march-y)_zicsr_zifencei
+$(call add_stateless_extension,zicsr,_)
+$(call add_stateless_extension,zifencei,_)
 endif
 
-# Check if the toolchain supports Zacas
-riscv-march-$(CONFIG_TOOLCHAIN_HAS_ZACAS) := $(riscv-march-y)_zacas
+# Standard extensions
+$(call add_stateless_extension,zabha,_)
+$(call add_stateless_extension,zacas,_)
+$(call add_stateless_extension,zba,_)
+$(call add_stateless_extension,zbb,_)
+$(call add_stateless_extension,zbc,_)
+$(call add_stateless_extension,zbkb,_)
 
-# Check if the toolchain supports Zabha
-riscv-march-$(CONFIG_TOOLCHAIN_HAS_ZABHA) := $(riscv-march-y)_zabha
+ifneq ($(CONFIG_RISCV_ISA_C),y)
+	KBUILD_RUSTFLAGS += -Ctarget-feature=-c
+endif
 
-# Remove F,D,V from isa string for all. Keep extensions between "fd" and "v" by
-# matching non-v and non-multi-letter extensions out with the filter ([^v_]*)
-KBUILD_CFLAGS += -march=$(shell echo $(riscv-march-y) | sed -E 's/(rv32ima|rv64ima)fd([^v_]*)v?/\1\2/')
+# Only include extensions that do not introduce additional state. This
+# "additional state" most often means extra registers.
+KBUILD_CFLAGS += -march=$(riscv-march-standard)
 
-KBUILD_AFLAGS += -march=$(riscv-march-y)
+# Make all instructions available to the assembler
+KBUILD_AFLAGS += -march=$(riscv-march-full)
 
-# For C code built with floating-point support, exclude V but keep F and D.
-CC_FLAGS_FPU  := -march=$(shell echo $(riscv-march-y) | sed -E 's/(rv32ima|rv64ima)([^v_]*)v?/\1\2/')
+# As an extension of the "standard" march string, include any extensions that
+# are able to be used when the FPU is enabled.
+CC_FLAGS_FPU  := -march=$(riscv-march-fpu)
 
 KBUILD_CFLAGS += -mno-save-restore
 

-- 
2.43.0


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ