[PATCH] arm64: Generate cpucaps.h
dann frazier
dann.frazier at canonical.com
Tue Sep 21 11:08:11 PDT 2021
On Wed, Apr 28, 2021 at 01:12:31PM +0100, Mark Brown wrote:
> The arm64 code allocates an internal constant to every CPU feature it can
> detect, distinct from the public hwcap numbers we use to expose some
> features to userspace. Currently this is maintained manually which is an
> irritating source of conflicts when working on new features, to avoid this
> replace the header with a simple text file listing the names we've assigned
> and sort it to minimise conflicts.
Thanks for doing this Mark, speaking as someone who has had to
backport a lot of these patches to a distro kernel :)
> As part of doing this we also do the Kbuild hookup required to hook up
> an arch tools directory and to generate header files in there.
>
> This will result in a renumbering and reordering of the existing constants,
> since they are all internal only the values should not be important. The
> reordering will impact the order in which some steps in enumeration handle
> features but the algorithm is not intended to depend on this and I haven't
> seen any issues when testing.
Unfortunately I believe I've hit a regression[*] due to such an
ordering dependency. UNMAP_KERNEL_AT_EL0 currently needs to be
processed after WORKAROUND_CAVIUM_27456. ThunderX systems are
incompatible with KPTI, so unmap_kernel_at_el0() bails if
WORKAROUND_CAVIUM_27456 is set. Because of the sorting,
WORKAROUND_CAVIUM_27456 will not yet have been considered when
unmap_kernel_at_el0() checks for it, so the kernel tries to
run w/ KPTI - and quickly falls over.
I've verified that reordering cpucaps to move WORKAROUND_CAVIUM_27456
just above UNMAP_KERNEL_AT_EL0 restores the old behavior. I'm not sure
of the right way to address this - perhaps unmap_kernel_at_el0() could
check cavium_erratum_27456_cpus[] directly instead of keying on the
ARM64_WORKAROUND_CAVIUM_27456 cap?
-dann
[*] https://bugs.launchpad.net/bugs/1942633
> Due to the UAO cpucap having been removed in
> the past we end up with ARM64_NCAPS being 1 smaller than it was before.
>
> Signed-off-by: Mark Brown <broonie at kernel.org>
> ---
> arch/arm64/Makefile | 3 ++
> arch/arm64/include/asm/Kbuild | 2 +
> arch/arm64/include/asm/cpucaps.h | 74 --------------------------------
> arch/arm64/tools/Makefile | 22 ++++++++++
> arch/arm64/tools/cpucaps | 65 ++++++++++++++++++++++++++++
> arch/arm64/tools/gen-cpucaps.awk | 40 +++++++++++++++++
> 6 files changed, 132 insertions(+), 74 deletions(-)
> delete mode 100644 arch/arm64/include/asm/cpucaps.h
> create mode 100644 arch/arm64/tools/Makefile
> create mode 100644 arch/arm64/tools/cpucaps
> create mode 100755 arch/arm64/tools/gen-cpucaps.awk
>
> diff --git a/arch/arm64/Makefile b/arch/arm64/Makefile
> index 7ef44478560d..b52481f0605d 100644
> --- a/arch/arm64/Makefile
> +++ b/arch/arm64/Makefile
> @@ -175,6 +175,9 @@ vdso_install:
> $(if $(CONFIG_COMPAT_VDSO), \
> $(Q)$(MAKE) $(build)=arch/arm64/kernel/vdso32 $@)
>
> +archprepare:
> + $(Q)$(MAKE) $(build)=arch/arm64/tools kapi
> +
> # We use MRPROPER_FILES and CLEAN_FILES now
> archclean:
> $(Q)$(MAKE) $(clean)=$(boot)
> diff --git a/arch/arm64/include/asm/Kbuild b/arch/arm64/include/asm/Kbuild
> index 73aa25843f65..64202010b700 100644
> --- a/arch/arm64/include/asm/Kbuild
> +++ b/arch/arm64/include/asm/Kbuild
> @@ -4,3 +4,5 @@ generic-y += mcs_spinlock.h
> generic-y += qrwlock.h
> generic-y += qspinlock.h
> generic-y += user.h
> +
> +generated-y += cpucaps.h
> diff --git a/arch/arm64/include/asm/cpucaps.h b/arch/arm64/include/asm/cpucaps.h
> deleted file mode 100644
> index b0c5eda0498f..000000000000
> --- a/arch/arm64/include/asm/cpucaps.h
> +++ /dev/null
> @@ -1,74 +0,0 @@
> -/* SPDX-License-Identifier: GPL-2.0-only */
> -/*
> - * arch/arm64/include/asm/cpucaps.h
> - *
> - * Copyright (C) 2016 ARM Ltd.
> - */
> -#ifndef __ASM_CPUCAPS_H
> -#define __ASM_CPUCAPS_H
> -
> -#define ARM64_WORKAROUND_CLEAN_CACHE 0
> -#define ARM64_WORKAROUND_DEVICE_LOAD_ACQUIRE 1
> -#define ARM64_WORKAROUND_845719 2
> -#define ARM64_HAS_SYSREG_GIC_CPUIF 3
> -#define ARM64_HAS_PAN 4
> -#define ARM64_HAS_LSE_ATOMICS 5
> -#define ARM64_WORKAROUND_CAVIUM_23154 6
> -#define ARM64_WORKAROUND_834220 7
> -#define ARM64_HAS_NO_HW_PREFETCH 8
> -#define ARM64_HAS_VIRT_HOST_EXTN 11
> -#define ARM64_WORKAROUND_CAVIUM_27456 12
> -#define ARM64_HAS_32BIT_EL0 13
> -#define ARM64_SPECTRE_V3A 14
> -#define ARM64_HAS_CNP 15
> -#define ARM64_HAS_NO_FPSIMD 16
> -#define ARM64_WORKAROUND_REPEAT_TLBI 17
> -#define ARM64_WORKAROUND_QCOM_FALKOR_E1003 18
> -#define ARM64_WORKAROUND_858921 19
> -#define ARM64_WORKAROUND_CAVIUM_30115 20
> -#define ARM64_HAS_DCPOP 21
> -#define ARM64_SVE 22
> -#define ARM64_UNMAP_KERNEL_AT_EL0 23
> -#define ARM64_SPECTRE_V2 24
> -#define ARM64_HAS_RAS_EXTN 25
> -#define ARM64_WORKAROUND_843419 26
> -#define ARM64_HAS_CACHE_IDC 27
> -#define ARM64_HAS_CACHE_DIC 28
> -#define ARM64_HW_DBM 29
> -#define ARM64_SPECTRE_V4 30
> -#define ARM64_MISMATCHED_CACHE_TYPE 31
> -#define ARM64_HAS_STAGE2_FWB 32
> -#define ARM64_HAS_CRC32 33
> -#define ARM64_SSBS 34
> -#define ARM64_WORKAROUND_1418040 35
> -#define ARM64_HAS_SB 36
> -#define ARM64_WORKAROUND_SPECULATIVE_AT 37
> -#define ARM64_HAS_ADDRESS_AUTH_ARCH 38
> -#define ARM64_HAS_ADDRESS_AUTH_IMP_DEF 39
> -#define ARM64_HAS_GENERIC_AUTH_ARCH 40
> -#define ARM64_HAS_GENERIC_AUTH_IMP_DEF 41
> -#define ARM64_HAS_IRQ_PRIO_MASKING 42
> -#define ARM64_HAS_DCPODP 43
> -#define ARM64_WORKAROUND_1463225 44
> -#define ARM64_WORKAROUND_CAVIUM_TX2_219_TVM 45
> -#define ARM64_WORKAROUND_CAVIUM_TX2_219_PRFM 46
> -#define ARM64_WORKAROUND_1542419 47
> -#define ARM64_HAS_E0PD 48
> -#define ARM64_HAS_RNG 49
> -#define ARM64_HAS_AMU_EXTN 50
> -#define ARM64_HAS_ADDRESS_AUTH 51
> -#define ARM64_HAS_GENERIC_AUTH 52
> -#define ARM64_HAS_32BIT_EL1 53
> -#define ARM64_BTI 54
> -#define ARM64_HAS_ARMv8_4_TTL 55
> -#define ARM64_HAS_TLB_RANGE 56
> -#define ARM64_MTE 57
> -#define ARM64_WORKAROUND_1508412 58
> -#define ARM64_HAS_LDAPR 59
> -#define ARM64_KVM_PROTECTED_MODE 60
> -#define ARM64_WORKAROUND_NVIDIA_CARMEL_CNP 61
> -#define ARM64_HAS_EPAN 62
> -
> -#define ARM64_NCAPS 63
> -
> -#endif /* __ASM_CPUCAPS_H */
> diff --git a/arch/arm64/tools/Makefile b/arch/arm64/tools/Makefile
> new file mode 100644
> index 000000000000..932b4fe5c768
> --- /dev/null
> +++ b/arch/arm64/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/arm64/tools/cpucaps b/arch/arm64/tools/cpucaps
> new file mode 100644
> index 000000000000..21fbdda7086e
> --- /dev/null
> +++ b/arch/arm64/tools/cpucaps
> @@ -0,0 +1,65 @@
> +# SPDX-License-Identifier: GPL-2.0
> +#
> +# Internal CPU capabilities constants, keep this list sorted
> +
> +BTI
> +HAS_32BIT_EL0
> +HAS_32BIT_EL1
> +HAS_ADDRESS_AUTH
> +HAS_ADDRESS_AUTH_ARCH
> +HAS_ADDRESS_AUTH_IMP_DEF
> +HAS_AMU_EXTN
> +HAS_ARMv8_4_TTL
> +HAS_CACHE_DIC
> +HAS_CACHE_IDC
> +HAS_CNP
> +HAS_CRC32
> +HAS_DCPODP
> +HAS_DCPOP
> +HAS_E0PD
> +HAS_EPAN
> +HAS_GENERIC_AUTH
> +HAS_GENERIC_AUTH_ARCH
> +HAS_GENERIC_AUTH_IMP_DEF
> +HAS_IRQ_PRIO_MASKING
> +HAS_LDAPR
> +HAS_LSE_ATOMICS
> +HAS_NO_FPSIMD
> +HAS_NO_HW_PREFETCH
> +HAS_PAN
> +HAS_RAS_EXTN
> +HAS_RNG
> +HAS_SB
> +HAS_STAGE2_FWB
> +HAS_SYSREG_GIC_CPUIF
> +HAS_TLB_RANGE
> +HAS_VIRT_HOST_EXTN
> +HW_DBM
> +KVM_PROTECTED_MODE
> +MISMATCHED_CACHE_TYPE
> +MTE
> +SPECTRE_V2
> +SPECTRE_V3A
> +SPECTRE_V4
> +SSBS
> +SVE
> +UNMAP_KERNEL_AT_EL0
> +WORKAROUND_834220
> +WORKAROUND_843419
> +WORKAROUND_845719
> +WORKAROUND_858921
> +WORKAROUND_1418040
> +WORKAROUND_1463225
> +WORKAROUND_1508412
> +WORKAROUND_1542419
> +WORKAROUND_CAVIUM_23154
> +WORKAROUND_CAVIUM_27456
> +WORKAROUND_CAVIUM_30115
> +WORKAROUND_CAVIUM_TX2_219_PRFM
> +WORKAROUND_CAVIUM_TX2_219_TVM
> +WORKAROUND_CLEAN_CACHE
> +WORKAROUND_DEVICE_LOAD_ACQUIRE
> +WORKAROUND_NVIDIA_CARMEL_CNP
> +WORKAROUND_QCOM_FALKOR_E1003
> +WORKAROUND_REPEAT_TLBI
> +WORKAROUND_SPECULATIVE_AT
> diff --git a/arch/arm64/tools/gen-cpucaps.awk b/arch/arm64/tools/gen-cpucaps.awk
> new file mode 100755
> index 000000000000..18737a1ce044
> --- /dev/null
> +++ b/arch/arm64/tools/gen-cpucaps.awk
> @@ -0,0 +1,40 @@
> +#!/bin/awk -f
> +# SPDX-License-Identifier: GPL-2.0
> +# gen-cpucaps.awk: arm64 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 ARM64_%-30s\t%d\n", $0, cap_num++)
> + next
> +}
> +
> +END {
> + printf("#define ARM64_NCAPS\t\t\t\t%d\n", cap_num)
> + print ""
> + print "#endif"
> +}
> +
> +# Any lines not handled by previous rules are unexpected
> +{
> + fatal("unhandled statement")
> +}
More information about the linux-arm-kernel
mailing list