Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge tag 'arm64-upstream' of git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux

Pull arm64 updates from Catalin Marinas:

- Support for arm64 SME 2 and 2.1. SME2 introduces a new 512-bit
architectural register (ZT0, for the look-up table feature) that
Linux needs to save/restore

- Include TPIDR2 in the signal context and add the corresponding
kselftests

- Perf updates: Arm SPEv1.2 support, HiSilicon uncore PMU updates, ACPI
support to the Marvell DDR and TAD PMU drivers, reset DTM_PMU_CONFIG
(ARM CMN) at probe time

- Support for DYNAMIC_FTRACE_WITH_CALL_OPS on arm64

- Permit EFI boot with MMU and caches on. Instead of cleaning the
entire loaded kernel image to the PoC and disabling the MMU and
caches before branching to the kernel bare metal entry point, leave
the MMU and caches enabled and rely on EFI's cacheable 1:1 mapping of
all of system RAM to populate the initial page tables

- Expose the AArch32 (compat) ELF_HWCAP features to user in an arm64
kernel (the arm32 kernel only defines the values)

- Harden the arm64 shadow call stack pointer handling: stash the shadow
stack pointer in the task struct on interrupt, load it directly from
this structure

- Signal handling cleanups to remove redundant validation of size
information and avoid reading the same data from userspace twice

- Refactor the hwcap macros to make use of the automatically generated
ID registers. It should make new hwcaps writing less error prone

- Further arm64 sysreg conversion and some fixes

- arm64 kselftest fixes and improvements

- Pointer authentication cleanups: don't sign leaf functions, unify
asm-arch manipulation

- Pseudo-NMI code generation optimisations

- Minor fixes for SME and TPIDR2 handling

- Miscellaneous updates: ARCH_FORCE_MAX_ORDER is now selectable,
replace strtobool() to kstrtobool() in the cpufeature.c code, apply
dynamic shadow call stack in two passes, intercept pfn changes in
set_pte_at() without the required break-before-make sequence, attempt
to dump all instructions on unhandled kernel faults

* tag 'arm64-upstream' of git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux: (130 commits)
arm64: fix .idmap.text assertion for large kernels
kselftest/arm64: Don't require FA64 for streaming SVE+ZA tests
kselftest/arm64: Copy whole EXTRA context
arm64: kprobes: Drop ID map text from kprobes blacklist
perf: arm_spe: Print the version of SPE detected
perf: arm_spe: Add support for SPEv1.2 inverted event filtering
perf: Add perf_event_attr::config3
arm64/sme: Fix __finalise_el2 SMEver check
drivers/perf: fsl_imx8_ddr_perf: Remove set-but-not-used variable
arm64/signal: Only read new data when parsing the ZT context
arm64/signal: Only read new data when parsing the ZA context
arm64/signal: Only read new data when parsing the SVE context
arm64/signal: Avoid rereading context frame sizes
arm64/signal: Make interface for restore_fpsimd_context() consistent
arm64/signal: Remove redundant size validation from parse_user_sigframe()
arm64/signal: Don't redundantly verify FPSIMD magic
arm64/cpufeature: Use helper macros to specify hwcaps
arm64/cpufeature: Always use symbolic name for feature value in hwcaps
arm64/sysreg: Initial unsigned annotations for ID registers
arm64/sysreg: Initial annotation of signed ID registers
...

+3643 -1062
+11 -1
Documentation/arm64/booting.rst
··· 223 223 For systems with a GICv3 interrupt controller to be used in v3 mode: 224 224 - If EL3 is present: 225 225 226 - - ICC_SRE_EL3.Enable (bit 3) must be initialiased to 0b1. 226 + - ICC_SRE_EL3.Enable (bit 3) must be initialised to 0b1. 227 227 - ICC_SRE_EL3.SRE (bit 0) must be initialised to 0b1. 228 228 - ICC_CTLR_EL3.PMHE (bit 6) must be set to the same value across 229 229 all CPUs the kernel is executing on, and must stay constant ··· 368 368 - If the kernel is entered at EL1 and EL2 is present: 369 369 370 370 - HCR_EL2.ATA (bit 56) must be initialised to 0b1. 371 + 372 + For CPUs with the Scalable Matrix Extension version 2 (FEAT_SME2): 373 + 374 + - If EL3 is present: 375 + 376 + - SMCR_EL3.EZT0 (bit 30) must be initialised to 0b1. 377 + 378 + - If the kernel is entered at EL1 and EL2 is present: 379 + 380 + - SMCR_EL2.EZT0 (bit 30) must be initialised to 0b1. 371 381 372 382 The requirements described above for CPU mode, caches, MMUs, architected 373 383 timers, coherency and system registers apply to all CPUs. All CPUs must
+19 -1
Documentation/arm64/elf_hwcaps.rst
··· 14 14 implementations, and/or with certain kernel configurations, but have no 15 15 architected discovery mechanism available to userspace code at EL0. The 16 16 kernel exposes the presence of these features to userspace through a set 17 - of flags called hwcaps, exposed in the auxilliary vector. 17 + of flags called hwcaps, exposed in the auxiliary vector. 18 18 19 19 Userspace software can test for features by acquiring the AT_HWCAP or 20 20 AT_HWCAP2 entry of the auxiliary vector, and testing whether the relevant ··· 283 283 284 284 HWCAP2_SVE2P1 285 285 Functionality implied by ID_AA64ZFR0_EL1.SVEver == 0b0010. 286 + 287 + HWCAP2_SME2 288 + Functionality implied by ID_AA64SMFR0_EL1.SMEver == 0b0001. 289 + 290 + HWCAP2_SME2P1 291 + Functionality implied by ID_AA64SMFR0_EL1.SMEver == 0b0010. 292 + 293 + HWCAP2_SMEI16I32 294 + Functionality implied by ID_AA64SMFR0_EL1.I16I32 == 0b0101 295 + 296 + HWCAP2_SMEBI32I32 297 + Functionality implied by ID_AA64SMFR0_EL1.BI32I32 == 0b1 298 + 299 + HWCAP2_SMEB16B16 300 + Functionality implied by ID_AA64SMFR0_EL1.B16B16 == 0b1 301 + 302 + HWCAP2_SMEF16F16 303 + Functionality implied by ID_AA64SMFR0_EL1.F16F16 == 0b1 286 304 287 305 4. Unused AT_HWCAP bits 288 306 -----------------------
+46 -9
Documentation/arm64/sme.rst
··· 18 18 1. General 19 19 ----------- 20 20 21 - * PSTATE.SM, PSTATE.ZA, the streaming mode vector length, the ZA 22 - register state and TPIDR2_EL0 are tracked per thread. 21 + * PSTATE.SM, PSTATE.ZA, the streaming mode vector length, the ZA and (when 22 + present) ZTn register state and TPIDR2_EL0 are tracked per thread. 23 23 24 24 * The presence of SME is reported to userspace via HWCAP2_SME in the aux vector 25 25 AT_HWCAP2 entry. Presence of this flag implies the presence of the SME 26 26 instructions and registers, and the Linux-specific system interfaces 27 27 described in this document. SME is reported in /proc/cpuinfo as "sme". 28 + 29 + * The presence of SME2 is reported to userspace via HWCAP2_SME2 in the 30 + aux vector AT_HWCAP2 entry. Presence of this flag implies the presence of 31 + the SME2 instructions and ZT0, and the Linux-specific system interfaces 32 + described in this document. SME2 is reported in /proc/cpuinfo as "sme2". 28 33 29 34 * Support for the execution of SME instructions in userspace can also be 30 35 detected by reading the CPU ID register ID_AA64PFR1_EL1 using an MRS ··· 49 44 HWCAP2_SME_B16F32 50 45 HWCAP2_SME_F32F32 51 46 HWCAP2_SME_FA64 47 + HWCAP2_SME2 52 48 53 49 This list may be extended over time as the SME architecture evolves. 54 50 ··· 58 52 cpu-feature-registers.txt for details. 59 53 60 54 * Debuggers should restrict themselves to interacting with the target via the 61 - NT_ARM_SVE, NT_ARM_SSVE and NT_ARM_ZA regsets. The recommended way 62 - of detecting support for these regsets is to connect to a target process 55 + NT_ARM_SVE, NT_ARM_SSVE, NT_ARM_ZA and NT_ARM_ZT regsets. The recommended 56 + way of detecting support for these regsets is to connect to a target process 63 57 first and then attempt a 64 58 65 59 ptrace(PTRACE_GETREGSET, pid, NT_ARM_<regset>, &iov). ··· 95 89 ------------------------- 96 90 97 91 * On syscall PSTATE.ZA is preserved, if PSTATE.ZA==1 then the contents of the 98 - ZA matrix are preserved. 92 + ZA matrix and ZTn (if present) are preserved. 99 93 100 94 * On syscall PSTATE.SM will be cleared and the SVE registers will be handled 101 95 as per the standard SVE ABI. 102 96 103 - * Neither the SVE registers nor ZA are used to pass arguments to or receive 104 - results from any syscall. 97 + * None of the SVE registers, ZA or ZTn are used to pass arguments to 98 + or receive results from any syscall. 105 99 106 100 * On process creation (eg, clone()) the newly created process will have 107 101 PSTATE.SM cleared. ··· 116 110 ------------------- 117 111 118 112 * Signal handlers are invoked with streaming mode and ZA disabled. 113 + 114 + * A new signal frame record TPIDR2_MAGIC is added formatted as a struct 115 + tpidr2_context to allow access to TPIDR2_EL0 from signal handlers. 119 116 120 117 * A new signal frame record za_context encodes the ZA register contents on 121 118 signal delivery. [1] ··· 143 134 __reserved[] referencing this space. za_context is then written in the 144 135 extra space. Refer to [1] for further details about this mechanism. 145 136 137 + * If ZTn is supported and PSTATE.ZA==1 then a signal frame record for ZTn will 138 + be generated. 139 + 140 + * The signal record for ZTn has magic ZT_MAGIC (0x5a544e01) and consists of a 141 + standard signal frame header followed by a struct zt_context specifying 142 + the number of ZTn registers supported by the system, then zt_context.nregs 143 + blocks of 64 bytes of data per register. 144 + 146 145 147 146 5. Signal return 148 147 ----------------- ··· 167 150 * The vector length cannot be changed via signal return. If za_context.vl in 168 151 the signal frame does not match the current vector length, the signal return 169 152 attempt is treated as illegal, resulting in a forced SIGSEGV. 153 + 154 + * If ZTn is not supported or PSTATE.ZA==0 then it is illegal to have a 155 + signal frame record for ZTn, resulting in a forced SIGSEGV. 170 156 171 157 172 158 6. prctl extensions ··· 234 214 vector length that will be applied at the next execve() by the calling 235 215 thread. 236 216 237 - * Changing the vector length causes all of ZA, P0..P15, FFR and all bits of 238 - Z0..Z31 except for Z0 bits [127:0] .. Z31 bits [127:0] to become 217 + * Changing the vector length causes all of ZA, ZTn, P0..P15, FFR and all 218 + bits of Z0..Z31 except for Z0 bits [127:0] .. Z31 bits [127:0] to become 239 219 unspecified, including both streaming and non-streaming SVE state. 240 220 Calling PR_SME_SET_VL with vl equal to the thread's current vector 241 221 length, or calling PR_SME_SET_VL with the PR_SVE_SET_VL_ONEXEC flag, ··· 337 317 338 318 * The effect of writing a partial, incomplete payload is unspecified. 339 319 320 + * A new regset NT_ARM_ZT is defined for access to ZTn state via 321 + PTRACE_GETREGSET and PTRACE_SETREGSET. 322 + 323 + * The NT_ARM_ZT regset consists of a single 512 bit register. 324 + 325 + * When PSTATE.ZA==0 reads of NT_ARM_ZT will report all bits of ZTn as 0. 326 + 327 + * Writes to NT_ARM_ZT will set PSTATE.ZA to 1. 328 + 340 329 341 330 8. ELF coredump extensions 342 331 --------------------------- ··· 358 329 * A NT_ARM_ZA note will be added to each coredump for each thread of the 359 330 dumped process. The contents will be equivalent to the data that would have 360 331 been read if a PTRACE_GETREGSET of NT_ARM_ZA were executed for each thread 332 + when the coredump was generated. 333 + 334 + * A NT_ARM_ZT note will be added to each coredump for each thread of the 335 + dumped process. The contents will be equivalent to the data that would have 336 + been read if a PTRACE_GETREGSET of NT_ARM_ZT were executed for each thread 361 337 when the coredump was generated. 362 338 363 339 * The NT_ARM_TLS note will be extended to two registers, the second register ··· 439 405 440 406 For best system performance it is strongly encouraged for software to enable 441 407 ZA only when it is actively being used. 408 + 409 + * A new ZT0 register is introduced when SME2 is present. This is a 512 bit 410 + register which is accessible when PSTATE.ZA is set, as ZA itself is. 442 411 443 412 * Two new 1 bit fields in PSTATE which may be controlled via the SMSTART and 444 413 SMSTOP instructions or by access to the SVCR system register:
+2 -2
Documentation/arm64/sve.rst
··· 175 175 When returning from a signal handler: 176 176 177 177 * If there is no sve_context record in the signal frame, or if the record is 178 - present but contains no register data as desribed in the previous section, 178 + present but contains no register data as described in the previous section, 179 179 then the SVE registers/bits become non-live and take unspecified values. 180 180 181 181 * If sve_context is present in the signal frame and contains full register ··· 223 223 Defer the requested vector length change until the next execve() 224 224 performed by this thread. 225 225 226 - The effect is equivalent to implicit exceution of the following 226 + The effect is equivalent to implicit execution of the following 227 227 call immediately after the next execve() (if any) by the thread: 228 228 229 229 prctl(PR_SVE_SET_VL, arg & ~PR_SVE_SET_VL_ONEXEC)
+5
arch/arm/include/asm/arch_gicv3.h
··· 252 252 WARN_ON_ONCE(true); 253 253 } 254 254 255 + static inline bool gic_has_relaxed_pmr_sync(void) 256 + { 257 + return false; 258 + } 259 + 255 260 #endif /* !__ASSEMBLY__ */ 256 261 #endif /* !__ASM_ARCH_GICV3_H */
+21 -4
arch/arm64/Kconfig
··· 123 123 select DMA_DIRECT_REMAP 124 124 select EDAC_SUPPORT 125 125 select FRAME_POINTER 126 + select FUNCTION_ALIGNMENT_4B 127 + select FUNCTION_ALIGNMENT_8B if DYNAMIC_FTRACE_WITH_CALL_OPS 126 128 select GENERIC_ALLOCATOR 127 129 select GENERIC_ARCH_TOPOLOGY 128 130 select GENERIC_CLOCKEVENTS_BROADCAST ··· 186 184 select HAVE_DEBUG_KMEMLEAK 187 185 select HAVE_DMA_CONTIGUOUS 188 186 select HAVE_DYNAMIC_FTRACE 187 + select HAVE_DYNAMIC_FTRACE_WITH_CALL_OPS \ 188 + if (DYNAMIC_FTRACE_WITH_ARGS && !CFI_CLANG) 189 189 select FTRACE_MCOUNT_USE_PATCHABLE_FUNCTION_ENTRY \ 190 190 if DYNAMIC_FTRACE_WITH_ARGS 191 191 select HAVE_EFFICIENT_UNALIGNED_ACCESS ··· 1474 1470 help 1475 1471 Say Y if you want to run Linux in a Virtual Machine on Xen on ARM64. 1476 1472 1473 + # include/linux/mmzone.h requires the following to be true: 1474 + # 1475 + # MAX_ORDER - 1 + PAGE_SHIFT <= SECTION_SIZE_BITS 1476 + # 1477 + # so the maximum value of MAX_ORDER is SECTION_SIZE_BITS + 1 - PAGE_SHIFT: 1478 + # 1479 + # | SECTION_SIZE_BITS | PAGE_SHIFT | max MAX_ORDER | default MAX_ORDER | 1480 + # ----+-------------------+--------------+-----------------+--------------------+ 1481 + # 4K | 27 | 12 | 16 | 11 | 1482 + # 16K | 27 | 14 | 14 | 12 | 1483 + # 64K | 29 | 16 | 14 | 14 | 1477 1484 config ARCH_FORCE_MAX_ORDER 1478 - int 1485 + int "Maximum zone order" if ARM64_4K_PAGES || ARM64_16K_PAGES 1479 1486 default "14" if ARM64_64K_PAGES 1487 + range 12 14 if ARM64_16K_PAGES 1480 1488 default "12" if ARM64_16K_PAGES 1489 + range 11 16 if ARM64_4K_PAGES 1481 1490 default "11" 1482 1491 help 1483 1492 The kernel memory allocator divides physically contiguous memory ··· 1503 1486 This config option is actually maximum order plus one. For example, 1504 1487 a value of 11 means that the largest free memory block is 2^10 pages. 1505 1488 1506 - We make sure that we can allocate upto a HugePage size for each configuration. 1489 + We make sure that we can allocate up to a HugePage size for each configuration. 1507 1490 Hence we have : 1508 1491 MAX_ORDER = (PMD_SHIFT - PAGE_SHIFT) + 1 => PAGE_SHIFT - 2 1509 1492 ··· 1849 1832 bool "Use pointer authentication for kernel" 1850 1833 default y 1851 1834 depends on ARM64_PTR_AUTH 1852 - depends on (CC_HAS_SIGN_RETURN_ADDRESS || CC_HAS_BRANCH_PROT_PAC_RET) && AS_HAS_PAC 1835 + depends on (CC_HAS_SIGN_RETURN_ADDRESS || CC_HAS_BRANCH_PROT_PAC_RET) && AS_HAS_ARMV8_3 1853 1836 # Modern compilers insert a .note.gnu.property section note for PAC 1854 1837 # which is only understood by binutils starting with version 2.33.1. 1855 1838 depends on LD_IS_LLD || LD_VERSION >= 23301 || (CC_IS_GCC && GCC_VERSION < 90100) ··· 1874 1857 # GCC 7, 8 1875 1858 def_bool $(cc-option,-msign-return-address=all) 1876 1859 1877 - config AS_HAS_PAC 1860 + config AS_HAS_ARMV8_3 1878 1861 def_bool $(cc-option,-Wa$(comma)-march=armv8.3-a) 1879 1862 1880 1863 config AS_HAS_CFI_NEGATE_RA_STATE
+1 -1
arch/arm64/Kconfig.platforms
··· 187 187 select PINCTRL_ARMADA_CP110 188 188 select PINCTRL_AC5 189 189 help 190 - This enables support for Marvell EBU familly, including: 190 + This enables support for Marvell EBU family, including: 191 191 - Armada 3700 SoC Family 192 192 - Armada 7K SoC Family 193 193 - Armada 8K SoC Family
+30 -40
arch/arm64/Makefile
··· 63 63 include/generated/asm-offsets.h)) 64 64 endif 65 65 66 - ifeq ($(CONFIG_AS_HAS_ARMV8_2), y) 67 - # make sure to pass the newest target architecture to -march. 68 - asm-arch := armv8.2-a 69 - endif 70 - 71 - # Ensure that if the compiler supports branch protection we default it 72 - # off, this will be overridden if we are using branch protection. 73 - branch-prot-flags-y += $(call cc-option,-mbranch-protection=none) 74 - 75 - ifeq ($(CONFIG_ARM64_PTR_AUTH_KERNEL),y) 76 - branch-prot-flags-$(CONFIG_CC_HAS_SIGN_RETURN_ADDRESS) := -msign-return-address=all 77 - # We enable additional protection for leaf functions as there is some 78 - # narrow potential for ROP protection benefits and no substantial 79 - # performance impact has been observed. 80 - PACRET-y := pac-ret+leaf 81 - 82 - # Using a shadow call stack in leaf functions is too costly, so avoid PAC there 83 - # as well when we may be patching PAC into SCS 84 - PACRET-$(CONFIG_UNWIND_PATCH_PAC_INTO_SCS) := pac-ret 85 - 86 66 ifeq ($(CONFIG_ARM64_BTI_KERNEL),y) 87 - branch-prot-flags-$(CONFIG_CC_HAS_BRANCH_PROT_PAC_RET_BTI) := -mbranch-protection=$(PACRET-y)+bti 67 + KBUILD_CFLAGS += -mbranch-protection=pac-ret+bti 68 + else ifeq ($(CONFIG_ARM64_PTR_AUTH_KERNEL),y) 69 + ifeq ($(CONFIG_CC_HAS_BRANCH_PROT_PAC_RET),y) 70 + KBUILD_CFLAGS += -mbranch-protection=pac-ret 71 + else 72 + KBUILD_CFLAGS += -msign-return-address=non-leaf 73 + endif 88 74 else 89 - branch-prot-flags-$(CONFIG_CC_HAS_BRANCH_PROT_PAC_RET) := -mbranch-protection=$(PACRET-y) 90 - endif 91 - # -march=armv8.3-a enables the non-nops instructions for PAC, to avoid the 92 - # compiler to generate them and consequently to break the single image contract 93 - # we pass it only to the assembler. This option is utilized only in case of non 94 - # integrated assemblers. 95 - ifeq ($(CONFIG_AS_HAS_PAC), y) 96 - asm-arch := armv8.3-a 97 - endif 75 + KBUILD_CFLAGS += $(call cc-option,-mbranch-protection=none) 98 76 endif 99 77 100 - KBUILD_CFLAGS += $(branch-prot-flags-y) 101 - 102 - ifeq ($(CONFIG_AS_HAS_ARMV8_4), y) 103 - # make sure to pass the newest target architecture to -march. 104 - asm-arch := armv8.4-a 105 - endif 106 - 78 + # Tell the assembler to support instructions from the latest target 79 + # architecture. 80 + # 81 + # For non-integrated assemblers we'll pass this on the command line, and for 82 + # integrated assemblers we'll define ARM64_ASM_ARCH and ARM64_ASM_PREAMBLE for 83 + # inline usage. 84 + # 85 + # We cannot pass the same arch flag to the compiler as this would allow it to 86 + # freely generate instructions which are not supported by earlier architecture 87 + # versions, which would prevent a single kernel image from working on earlier 88 + # hardware. 107 89 ifeq ($(CONFIG_AS_HAS_ARMV8_5), y) 108 - # make sure to pass the newest target architecture to -march. 109 - asm-arch := armv8.5-a 90 + asm-arch := armv8.5-a 91 + else ifeq ($(CONFIG_AS_HAS_ARMV8_4), y) 92 + asm-arch := armv8.4-a 93 + else ifeq ($(CONFIG_AS_HAS_ARMV8_3), y) 94 + asm-arch := armv8.3-a 95 + else ifeq ($(CONFIG_AS_HAS_ARMV8_2), y) 96 + asm-arch := armv8.2-a 110 97 endif 111 98 112 99 ifdef asm-arch ··· 126 139 127 140 CHECKFLAGS += -D__aarch64__ 128 141 129 - ifeq ($(CONFIG_DYNAMIC_FTRACE_WITH_ARGS),y) 142 + ifeq ($(CONFIG_DYNAMIC_FTRACE_WITH_CALL_OPS),y) 143 + KBUILD_CPPFLAGS += -DCC_USING_PATCHABLE_FUNCTION_ENTRY 144 + CC_FLAGS_FTRACE := -fpatchable-function-entry=4,2 145 + else ifeq ($(CONFIG_DYNAMIC_FTRACE_WITH_ARGS),y) 130 146 KBUILD_CPPFLAGS += -DCC_USING_PATCHABLE_FUNCTION_ENTRY 131 147 CC_FLAGS_FTRACE := -fpatchable-function-entry=2 132 148 endif
+5
arch/arm64/include/asm/arch_gicv3.h
··· 190 190 asm volatile ("msr daifclr, #3" : : : "memory"); 191 191 } 192 192 193 + static inline bool gic_has_relaxed_pmr_sync(void) 194 + { 195 + return cpus_have_cap(ARM64_HAS_GIC_PRIO_RELAXED_SYNC); 196 + } 197 + 193 198 #endif /* __ASSEMBLY__ */ 194 199 #endif /* __ASM_ARCH_GICV3_H */
+7 -4
arch/arm64/include/asm/barrier.h
··· 11 11 12 12 #include <linux/kasan-checks.h> 13 13 14 + #include <asm/alternative-macros.h> 15 + 14 16 #define __nops(n) ".rept " #n "\nnop\n.endr\n" 15 17 #define nops(n) asm volatile(__nops(n)) 16 18 ··· 43 41 #ifdef CONFIG_ARM64_PSEUDO_NMI 44 42 #define pmr_sync() \ 45 43 do { \ 46 - extern struct static_key_false gic_pmr_sync; \ 47 - \ 48 - if (static_branch_unlikely(&gic_pmr_sync)) \ 49 - dsb(sy); \ 44 + asm volatile( \ 45 + ALTERNATIVE_CB("dsb sy", \ 46 + ARM64_HAS_GIC_PRIO_RELAXED_SYNC, \ 47 + alt_cb_patch_nops) \ 48 + ); \ 50 49 } while(0) 51 50 #else 52 51 #define pmr_sync() do {} while (0)
+12 -2
arch/arm64/include/asm/cpufeature.h
··· 769 769 cpus_have_const_cap(ARM64_SME); 770 770 } 771 771 772 + static __always_inline bool system_supports_sme2(void) 773 + { 774 + return IS_ENABLED(CONFIG_ARM64_SME) && 775 + cpus_have_const_cap(ARM64_SME2); 776 + } 777 + 772 778 static __always_inline bool system_supports_fa64(void) 773 779 { 774 780 return IS_ENABLED(CONFIG_ARM64_SME) && ··· 812 806 static __always_inline bool system_uses_irq_prio_masking(void) 813 807 { 814 808 return IS_ENABLED(CONFIG_ARM64_PSEUDO_NMI) && 815 - cpus_have_const_cap(ARM64_HAS_IRQ_PRIO_MASKING); 809 + cpus_have_const_cap(ARM64_HAS_GIC_PRIO_MASKING); 816 810 } 817 811 818 812 static inline bool system_supports_mte(void) ··· 870 864 if (!IS_ENABLED(CONFIG_ARM64_HW_AFDBM)) 871 865 return false; 872 866 873 - mmfr1 = read_cpuid(ID_AA64MMFR1_EL1); 867 + /* 868 + * Use cached version to avoid emulated msr operation on KVM 869 + * guests. 870 + */ 871 + mmfr1 = read_sanitised_ftr_reg(SYS_ID_AA64MMFR1_EL1); 874 872 return cpuid_feature_extract_unsigned_field(mmfr1, 875 873 ID_AA64MMFR1_EL1_HAFDBS_SHIFT); 876 874 }
+2
arch/arm64/include/asm/efi.h
··· 114 114 #define EFI_ALLOC_ALIGN SZ_64K 115 115 #define EFI_ALLOC_LIMIT ((1UL << 48) - 1) 116 116 117 + extern unsigned long primary_entry_offset(void); 118 + 117 119 /* 118 120 * On ARM systems, virtually remapped UEFI runtime services are set up in two 119 121 * distinct stages:
+4 -4
arch/arm64/include/asm/el2_setup.h
··· 53 53 cbz x0, .Lskip_spe_\@ // Skip if SPE not present 54 54 55 55 mrs_s x0, SYS_PMBIDR_EL1 // If SPE available at EL2, 56 - and x0, x0, #(1 << SYS_PMBIDR_EL1_P_SHIFT) 56 + and x0, x0, #(1 << PMBIDR_EL1_P_SHIFT) 57 57 cbnz x0, .Lskip_spe_el2_\@ // then permit sampling of physical 58 - mov x0, #(1 << SYS_PMSCR_EL2_PCT_SHIFT | \ 59 - 1 << SYS_PMSCR_EL2_PA_SHIFT) 58 + mov x0, #(1 << PMSCR_EL2_PCT_SHIFT | \ 59 + 1 << PMSCR_EL2_PA_SHIFT) 60 60 msr_s SYS_PMSCR_EL2, x0 // addresses and physical counter 61 61 .Lskip_spe_el2_\@: 62 62 mov x0, #(MDCR_EL2_E2PB_MASK << MDCR_EL2_E2PB_SHIFT) ··· 177 177 /** 178 178 * Initialize EL2 registers to sane values. This should be called early on all 179 179 * cores that were booted in EL2. Note that everything gets initialised as 180 - * if VHE was not evailable. The kernel context will be upgraded to VHE 180 + * if VHE was not available. The kernel context will be upgraded to VHE 181 181 * if possible later on in the boot process 182 182 * 183 183 * Regs: x0, x1 and x2 are clobbered.
+1
arch/arm64/include/asm/esr.h
··· 350 350 #define ESR_ELx_SME_ISS_ILL 1 351 351 #define ESR_ELx_SME_ISS_SM_DISABLED 2 352 352 #define ESR_ELx_SME_ISS_ZA_DISABLED 3 353 + #define ESR_ELx_SME_ISS_ZT_DISABLED 4 353 354 354 355 #ifndef __ASSEMBLY__ 355 356 #include <asm/types.h>
+22 -8
arch/arm64/include/asm/fpsimd.h
··· 61 61 struct cpu_fp_state { 62 62 struct user_fpsimd_state *st; 63 63 void *sve_state; 64 - void *za_state; 64 + void *sme_state; 65 65 u64 *svcr; 66 66 unsigned int sve_vl; 67 67 unsigned int sme_vl; ··· 105 105 return (char *)thread->sve_state + sve_ffr_offset(vl); 106 106 } 107 107 108 + static inline void *thread_zt_state(struct thread_struct *thread) 109 + { 110 + /* The ZT register state is stored immediately after the ZA state */ 111 + unsigned int sme_vq = sve_vq_from_vl(thread_get_sme_vl(thread)); 112 + return thread->sme_state + ZA_SIG_REGS_SIZE(sme_vq); 113 + } 114 + 108 115 extern void sve_save_state(void *state, u32 *pfpsr, int save_ffr); 109 116 extern void sve_load_state(void const *state, u32 const *pfpsr, 110 117 int restore_ffr); ··· 119 112 extern unsigned int sve_get_vl(void); 120 113 extern void sve_set_vq(unsigned long vq_minus_1); 121 114 extern void sme_set_vq(unsigned long vq_minus_1); 122 - extern void za_save_state(void *state); 123 - extern void za_load_state(void const *state); 115 + extern void sme_save_state(void *state, int zt); 116 + extern void sme_load_state(void const *state, int zt); 124 117 125 118 struct arm64_cpu_capabilities; 126 119 extern void sve_kernel_enable(const struct arm64_cpu_capabilities *__unused); 127 120 extern void sme_kernel_enable(const struct arm64_cpu_capabilities *__unused); 121 + extern void sme2_kernel_enable(const struct arm64_cpu_capabilities *__unused); 128 122 extern void fa64_kernel_enable(const struct arm64_cpu_capabilities *__unused); 129 123 130 124 extern u64 read_zcr_features(void); ··· 363 355 364 356 /* 365 357 * Return how many bytes of memory are required to store the full SME 366 - * specific state (currently just ZA) for task, given task's currently 367 - * configured vector length. 358 + * specific state for task, given task's currently configured vector 359 + * length. 368 360 */ 369 - static inline size_t za_state_size(struct task_struct const *task) 361 + static inline size_t sme_state_size(struct task_struct const *task) 370 362 { 371 363 unsigned int vl = task_get_sme_vl(task); 364 + size_t size; 372 365 373 - return ZA_SIG_REGS_SIZE(sve_vq_from_vl(vl)); 366 + size = ZA_SIG_REGS_SIZE(sve_vq_from_vl(vl)); 367 + 368 + if (system_supports_sme2()) 369 + size += ZT_SIG_REG_SIZE; 370 + 371 + return size; 374 372 } 375 373 376 374 #else ··· 396 382 static inline int sme_set_current_vl(unsigned long arg) { return -EINVAL; } 397 383 static inline int sme_get_current_vl(void) { return -EINVAL; } 398 384 399 - static inline size_t za_state_size(struct task_struct const *task) 385 + static inline size_t sme_state_size(struct task_struct const *task) 400 386 { 401 387 return 0; 402 388 }
+22
arch/arm64/include/asm/fpsimdmacros.h
··· 221 221 .endm 222 222 223 223 /* 224 + * LDR (ZT0) 225 + * 226 + * LDR ZT0, nx 227 + */ 228 + .macro _ldr_zt nx 229 + _check_general_reg \nx 230 + .inst 0xe11f8000 \ 231 + | (\nx << 5) 232 + .endm 233 + 234 + /* 235 + * STR (ZT0) 236 + * 237 + * STR ZT0, nx 238 + */ 239 + .macro _str_zt nx 240 + _check_general_reg \nx 241 + .inst 0xe13f8000 \ 242 + | (\nx << 5) 243 + .endm 244 + 245 + /* 224 246 * Zero the entire ZA array 225 247 * ZERO ZA 226 248 */
+1 -14
arch/arm64/include/asm/ftrace.h
··· 62 62 63 63 extern void return_to_handler(void); 64 64 65 - static inline unsigned long ftrace_call_adjust(unsigned long addr) 66 - { 67 - /* 68 - * Adjust addr to point at the BL in the callsite. 69 - * See ftrace_init_nop() for the callsite sequence. 70 - */ 71 - if (IS_ENABLED(CONFIG_DYNAMIC_FTRACE_WITH_ARGS)) 72 - return addr + AARCH64_INSN_SIZE; 73 - /* 74 - * addr is the address of the mcount call instruction. 75 - * recordmcount does the necessary offset calculation. 76 - */ 77 - return addr; 78 - } 65 + unsigned long ftrace_call_adjust(unsigned long addr); 79 66 80 67 #ifdef CONFIG_DYNAMIC_FTRACE_WITH_ARGS 81 68 struct dyn_ftrace;
+14
arch/arm64/include/asm/hwcap.h
··· 31 31 #define COMPAT_HWCAP_VFPD32 (1 << 19) 32 32 #define COMPAT_HWCAP_LPAE (1 << 20) 33 33 #define COMPAT_HWCAP_EVTSTRM (1 << 21) 34 + #define COMPAT_HWCAP_FPHP (1 << 22) 35 + #define COMPAT_HWCAP_ASIMDHP (1 << 23) 36 + #define COMPAT_HWCAP_ASIMDDP (1 << 24) 37 + #define COMPAT_HWCAP_ASIMDFHM (1 << 25) 38 + #define COMPAT_HWCAP_ASIMDBF16 (1 << 26) 39 + #define COMPAT_HWCAP_I8MM (1 << 27) 34 40 35 41 #define COMPAT_HWCAP2_AES (1 << 0) 36 42 #define COMPAT_HWCAP2_PMULL (1 << 1) 37 43 #define COMPAT_HWCAP2_SHA1 (1 << 2) 38 44 #define COMPAT_HWCAP2_SHA2 (1 << 3) 39 45 #define COMPAT_HWCAP2_CRC32 (1 << 4) 46 + #define COMPAT_HWCAP2_SB (1 << 5) 47 + #define COMPAT_HWCAP2_SSBS (1 << 6) 40 48 41 49 #ifndef __ASSEMBLY__ 42 50 #include <linux/log2.h> ··· 131 123 #define KERNEL_HWCAP_CSSC __khwcap2_feature(CSSC) 132 124 #define KERNEL_HWCAP_RPRFM __khwcap2_feature(RPRFM) 133 125 #define KERNEL_HWCAP_SVE2P1 __khwcap2_feature(SVE2P1) 126 + #define KERNEL_HWCAP_SME2 __khwcap2_feature(SME2) 127 + #define KERNEL_HWCAP_SME2P1 __khwcap2_feature(SME2P1) 128 + #define KERNEL_HWCAP_SME_I16I32 __khwcap2_feature(SME_I16I32) 129 + #define KERNEL_HWCAP_SME_BI32I32 __khwcap2_feature(SME_BI32I32) 130 + #define KERNEL_HWCAP_SME_B16B16 __khwcap2_feature(SME_B16B16) 131 + #define KERNEL_HWCAP_SME_F16F16 __khwcap2_feature(SME_F16F16) 134 132 135 133 /* 136 134 * This yields a mask that user programs can use to figure out what
+1
arch/arm64/include/asm/insn.h
··· 420 420 __AARCH64_INSN_FUNCS(clrex, 0xFFFFF0FF, 0xD503305F) 421 421 __AARCH64_INSN_FUNCS(ssbb, 0xFFFFFFFF, 0xD503309F) 422 422 __AARCH64_INSN_FUNCS(pssbb, 0xFFFFFFFF, 0xD503349F) 423 + __AARCH64_INSN_FUNCS(bti, 0xFFFFFF3F, 0xD503241f) 423 424 424 425 #undef __AARCH64_INSN_FUNCS 425 426
+141 -68
arch/arm64/include/asm/irqflags.h
··· 21 21 * exceptions should be unmasked. 22 22 */ 23 23 24 - /* 25 - * CPU interrupt mask handling. 26 - */ 27 - static inline void arch_local_irq_enable(void) 24 + static __always_inline bool __irqflags_uses_pmr(void) 28 25 { 29 - if (system_has_prio_mask_debugging()) { 30 - u32 pmr = read_sysreg_s(SYS_ICC_PMR_EL1); 26 + return IS_ENABLED(CONFIG_ARM64_PSEUDO_NMI) && 27 + alternative_has_feature_unlikely(ARM64_HAS_GIC_PRIO_MASKING); 28 + } 31 29 30 + static __always_inline void __daif_local_irq_enable(void) 31 + { 32 + barrier(); 33 + asm volatile("msr daifclr, #3"); 34 + barrier(); 35 + } 36 + 37 + static __always_inline void __pmr_local_irq_enable(void) 38 + { 39 + if (IS_ENABLED(CONFIG_ARM64_DEBUG_PRIORITY_MASKING)) { 40 + u32 pmr = read_sysreg_s(SYS_ICC_PMR_EL1); 32 41 WARN_ON_ONCE(pmr != GIC_PRIO_IRQON && pmr != GIC_PRIO_IRQOFF); 33 42 } 34 43 35 - asm volatile(ALTERNATIVE( 36 - "msr daifclr, #3 // arch_local_irq_enable", 37 - __msr_s(SYS_ICC_PMR_EL1, "%0"), 38 - ARM64_HAS_IRQ_PRIO_MASKING) 39 - : 40 - : "r" ((unsigned long) GIC_PRIO_IRQON) 41 - : "memory"); 42 - 44 + barrier(); 45 + write_sysreg_s(GIC_PRIO_IRQON, SYS_ICC_PMR_EL1); 43 46 pmr_sync(); 47 + barrier(); 48 + } 49 + 50 + static inline void arch_local_irq_enable(void) 51 + { 52 + if (__irqflags_uses_pmr()) { 53 + __pmr_local_irq_enable(); 54 + } else { 55 + __daif_local_irq_enable(); 56 + } 57 + } 58 + 59 + static __always_inline void __daif_local_irq_disable(void) 60 + { 61 + barrier(); 62 + asm volatile("msr daifset, #3"); 63 + barrier(); 64 + } 65 + 66 + static __always_inline void __pmr_local_irq_disable(void) 67 + { 68 + if (IS_ENABLED(CONFIG_ARM64_DEBUG_PRIORITY_MASKING)) { 69 + u32 pmr = read_sysreg_s(SYS_ICC_PMR_EL1); 70 + WARN_ON_ONCE(pmr != GIC_PRIO_IRQON && pmr != GIC_PRIO_IRQOFF); 71 + } 72 + 73 + barrier(); 74 + write_sysreg_s(GIC_PRIO_IRQOFF, SYS_ICC_PMR_EL1); 75 + barrier(); 44 76 } 45 77 46 78 static inline void arch_local_irq_disable(void) 47 79 { 48 - if (system_has_prio_mask_debugging()) { 49 - u32 pmr = read_sysreg_s(SYS_ICC_PMR_EL1); 50 - 51 - WARN_ON_ONCE(pmr != GIC_PRIO_IRQON && pmr != GIC_PRIO_IRQOFF); 80 + if (__irqflags_uses_pmr()) { 81 + __pmr_local_irq_disable(); 82 + } else { 83 + __daif_local_irq_disable(); 52 84 } 85 + } 53 86 54 - asm volatile(ALTERNATIVE( 55 - "msr daifset, #3 // arch_local_irq_disable", 56 - __msr_s(SYS_ICC_PMR_EL1, "%0"), 57 - ARM64_HAS_IRQ_PRIO_MASKING) 58 - : 59 - : "r" ((unsigned long) GIC_PRIO_IRQOFF) 60 - : "memory"); 87 + static __always_inline unsigned long __daif_local_save_flags(void) 88 + { 89 + return read_sysreg(daif); 90 + } 91 + 92 + static __always_inline unsigned long __pmr_local_save_flags(void) 93 + { 94 + return read_sysreg_s(SYS_ICC_PMR_EL1); 61 95 } 62 96 63 97 /* ··· 99 65 */ 100 66 static inline unsigned long arch_local_save_flags(void) 101 67 { 102 - unsigned long flags; 68 + if (__irqflags_uses_pmr()) { 69 + return __pmr_local_save_flags(); 70 + } else { 71 + return __daif_local_save_flags(); 72 + } 73 + } 103 74 104 - asm volatile(ALTERNATIVE( 105 - "mrs %0, daif", 106 - __mrs_s("%0", SYS_ICC_PMR_EL1), 107 - ARM64_HAS_IRQ_PRIO_MASKING) 108 - : "=&r" (flags) 109 - : 110 - : "memory"); 75 + static __always_inline bool __daif_irqs_disabled_flags(unsigned long flags) 76 + { 77 + return flags & PSR_I_BIT; 78 + } 79 + 80 + static __always_inline bool __pmr_irqs_disabled_flags(unsigned long flags) 81 + { 82 + return flags != GIC_PRIO_IRQON; 83 + } 84 + 85 + static inline bool arch_irqs_disabled_flags(unsigned long flags) 86 + { 87 + if (__irqflags_uses_pmr()) { 88 + return __pmr_irqs_disabled_flags(flags); 89 + } else { 90 + return __daif_irqs_disabled_flags(flags); 91 + } 92 + } 93 + 94 + static __always_inline bool __daif_irqs_disabled(void) 95 + { 96 + return __daif_irqs_disabled_flags(__daif_local_save_flags()); 97 + } 98 + 99 + static __always_inline bool __pmr_irqs_disabled(void) 100 + { 101 + return __pmr_irqs_disabled_flags(__pmr_local_save_flags()); 102 + } 103 + 104 + static inline bool arch_irqs_disabled(void) 105 + { 106 + if (__irqflags_uses_pmr()) { 107 + return __pmr_irqs_disabled(); 108 + } else { 109 + return __daif_irqs_disabled(); 110 + } 111 + } 112 + 113 + static __always_inline unsigned long __daif_local_irq_save(void) 114 + { 115 + unsigned long flags = __daif_local_save_flags(); 116 + 117 + __daif_local_irq_disable(); 111 118 112 119 return flags; 113 120 } 114 121 115 - static inline int arch_irqs_disabled_flags(unsigned long flags) 122 + static __always_inline unsigned long __pmr_local_irq_save(void) 116 123 { 117 - int res; 118 - 119 - asm volatile(ALTERNATIVE( 120 - "and %w0, %w1, #" __stringify(PSR_I_BIT), 121 - "eor %w0, %w1, #" __stringify(GIC_PRIO_IRQON), 122 - ARM64_HAS_IRQ_PRIO_MASKING) 123 - : "=&r" (res) 124 - : "r" ((int) flags) 125 - : "memory"); 126 - 127 - return res; 128 - } 129 - 130 - static inline int arch_irqs_disabled(void) 131 - { 132 - return arch_irqs_disabled_flags(arch_local_save_flags()); 133 - } 134 - 135 - static inline unsigned long arch_local_irq_save(void) 136 - { 137 - unsigned long flags; 138 - 139 - flags = arch_local_save_flags(); 124 + unsigned long flags = __pmr_local_save_flags(); 140 125 141 126 /* 142 127 * There are too many states with IRQs disabled, just keep the current 143 128 * state if interrupts are already disabled/masked. 144 129 */ 145 - if (!arch_irqs_disabled_flags(flags)) 146 - arch_local_irq_disable(); 130 + if (!__pmr_irqs_disabled_flags(flags)) 131 + __pmr_local_irq_disable(); 147 132 148 133 return flags; 134 + } 135 + 136 + static inline unsigned long arch_local_irq_save(void) 137 + { 138 + if (__irqflags_uses_pmr()) { 139 + return __pmr_local_irq_save(); 140 + } else { 141 + return __daif_local_irq_save(); 142 + } 143 + } 144 + 145 + static __always_inline void __daif_local_irq_restore(unsigned long flags) 146 + { 147 + barrier(); 148 + write_sysreg(flags, daif); 149 + barrier(); 150 + } 151 + 152 + static __always_inline void __pmr_local_irq_restore(unsigned long flags) 153 + { 154 + barrier(); 155 + write_sysreg_s(flags, SYS_ICC_PMR_EL1); 156 + pmr_sync(); 157 + barrier(); 149 158 } 150 159 151 160 /* ··· 196 119 */ 197 120 static inline void arch_local_irq_restore(unsigned long flags) 198 121 { 199 - asm volatile(ALTERNATIVE( 200 - "msr daif, %0", 201 - __msr_s(SYS_ICC_PMR_EL1, "%0"), 202 - ARM64_HAS_IRQ_PRIO_MASKING) 203 - : 204 - : "r" (flags) 205 - : "memory"); 206 - 207 - pmr_sync(); 122 + if (__irqflags_uses_pmr()) { 123 + __pmr_local_irq_restore(flags); 124 + } else { 125 + __daif_local_irq_restore(flags); 126 + } 208 127 } 209 128 210 129 #endif /* __ASM_IRQFLAGS_H */
+2 -2
arch/arm64/include/asm/linkage.h
··· 5 5 #include <asm/assembler.h> 6 6 #endif 7 7 8 - #define __ALIGN .align 2 9 - #define __ALIGN_STR ".align 2" 8 + #define __ALIGN .balign CONFIG_FUNCTION_ALIGNMENT 9 + #define __ALIGN_STR ".balign " #CONFIG_FUNCTION_ALIGNMENT 10 10 11 11 /* 12 12 * When using in-kernel BTI we need to ensure that PCS-conformant
+2
arch/arm64/include/asm/patching.h
··· 7 7 int aarch64_insn_read(void *addr, u32 *insnp); 8 8 int aarch64_insn_write(void *addr, u32 insn); 9 9 10 + int aarch64_insn_write_literal_u64(void *addr, u64 val); 11 + 10 12 int aarch64_insn_patch_text_nosync(void *addr, u32 insn); 11 13 int aarch64_insn_patch_text(void *addrs[], u32 insns[], int cnt); 12 14
+6 -2
arch/arm64/include/asm/pgtable.h
··· 275 275 } 276 276 277 277 extern void __sync_icache_dcache(pte_t pteval); 278 + bool pgattr_change_is_safe(u64 old, u64 new); 278 279 279 280 /* 280 281 * PTE bits configuration in the presence of hardware Dirty Bit Management ··· 293 292 * PTE_DIRTY || (PTE_WRITE && !PTE_RDONLY) 294 293 */ 295 294 296 - static inline void __check_racy_pte_update(struct mm_struct *mm, pte_t *ptep, 295 + static inline void __check_safe_pte_update(struct mm_struct *mm, pte_t *ptep, 297 296 pte_t pte) 298 297 { 299 298 pte_t old_pte; ··· 318 317 __func__, pte_val(old_pte), pte_val(pte)); 319 318 VM_WARN_ONCE(pte_write(old_pte) && !pte_dirty(pte), 320 319 "%s: racy dirty state clearing: 0x%016llx -> 0x%016llx", 320 + __func__, pte_val(old_pte), pte_val(pte)); 321 + VM_WARN_ONCE(!pgattr_change_is_safe(pte_val(old_pte), pte_val(pte)), 322 + "%s: unsafe attribute change: 0x%016llx -> 0x%016llx", 321 323 __func__, pte_val(old_pte), pte_val(pte)); 322 324 } 323 325 ··· 350 346 mte_sync_tags(old_pte, pte); 351 347 } 352 348 353 - __check_racy_pte_update(mm, ptep, pte); 349 + __check_safe_pte_update(mm, ptep, pte); 354 350 355 351 set_pte(ptep, pte); 356 352 }
+1 -1
arch/arm64/include/asm/processor.h
··· 161 161 enum fp_type fp_type; /* registers FPSIMD or SVE? */ 162 162 unsigned int fpsimd_cpu; 163 163 void *sve_state; /* SVE registers, if any */ 164 - void *za_state; /* ZA register, if any */ 164 + void *sme_state; /* ZA and ZT state, if any */ 165 165 unsigned int vl[ARM64_VEC_MAX]; /* vector length */ 166 166 unsigned int vl_onexec[ARM64_VEC_MAX]; /* vl after next exec */ 167 167 unsigned long fault_address; /* fault info */
+1 -1
arch/arm64/include/asm/ptrace.h
··· 194 194 u32 unused2; 195 195 #endif 196 196 u64 sdei_ttbr1; 197 - /* Only valid when ARM64_HAS_IRQ_PRIO_MASKING is enabled. */ 197 + /* Only valid when ARM64_HAS_GIC_PRIO_MASKING is enabled. */ 198 198 u64 pmr_save; 199 199 u64 stackframe[2]; 200 200
+4 -3
arch/arm64/include/asm/scs.h
··· 10 10 #ifdef CONFIG_SHADOW_CALL_STACK 11 11 scs_sp .req x18 12 12 13 - .macro scs_load tsk 14 - ldr scs_sp, [\tsk, #TSK_TI_SCS_SP] 13 + .macro scs_load_current 14 + get_current_task scs_sp 15 + ldr scs_sp, [scs_sp, #TSK_TI_SCS_SP] 15 16 .endm 16 17 17 18 .macro scs_save tsk 18 19 str scs_sp, [\tsk, #TSK_TI_SCS_SP] 19 20 .endm 20 21 #else 21 - .macro scs_load tsk 22 + .macro scs_load_current 22 23 .endm 23 24 24 25 .macro scs_save tsk
+14 -92
arch/arm64/include/asm/sysreg.h
··· 216 216 #define SYS_PAR_EL1_FST GENMASK(6, 1) 217 217 218 218 /*** Statistical Profiling Extension ***/ 219 - /* ID registers */ 220 - #define SYS_PMSIDR_EL1 sys_reg(3, 0, 9, 9, 7) 221 - #define SYS_PMSIDR_EL1_FE_SHIFT 0 222 - #define SYS_PMSIDR_EL1_FT_SHIFT 1 223 - #define SYS_PMSIDR_EL1_FL_SHIFT 2 224 - #define SYS_PMSIDR_EL1_ARCHINST_SHIFT 3 225 - #define SYS_PMSIDR_EL1_LDS_SHIFT 4 226 - #define SYS_PMSIDR_EL1_ERND_SHIFT 5 227 - #define SYS_PMSIDR_EL1_INTERVAL_SHIFT 8 228 - #define SYS_PMSIDR_EL1_INTERVAL_MASK 0xfUL 229 - #define SYS_PMSIDR_EL1_MAXSIZE_SHIFT 12 230 - #define SYS_PMSIDR_EL1_MAXSIZE_MASK 0xfUL 231 - #define SYS_PMSIDR_EL1_COUNTSIZE_SHIFT 16 232 - #define SYS_PMSIDR_EL1_COUNTSIZE_MASK 0xfUL 233 - 234 - #define SYS_PMBIDR_EL1 sys_reg(3, 0, 9, 10, 7) 235 - #define SYS_PMBIDR_EL1_ALIGN_SHIFT 0 236 - #define SYS_PMBIDR_EL1_ALIGN_MASK 0xfU 237 - #define SYS_PMBIDR_EL1_P_SHIFT 4 238 - #define SYS_PMBIDR_EL1_F_SHIFT 5 239 - 240 - /* Sampling controls */ 241 - #define SYS_PMSCR_EL1 sys_reg(3, 0, 9, 9, 0) 242 - #define SYS_PMSCR_EL1_E0SPE_SHIFT 0 243 - #define SYS_PMSCR_EL1_E1SPE_SHIFT 1 244 - #define SYS_PMSCR_EL1_CX_SHIFT 3 245 - #define SYS_PMSCR_EL1_PA_SHIFT 4 246 - #define SYS_PMSCR_EL1_TS_SHIFT 5 247 - #define SYS_PMSCR_EL1_PCT_SHIFT 6 248 - 249 - #define SYS_PMSCR_EL2 sys_reg(3, 4, 9, 9, 0) 250 - #define SYS_PMSCR_EL2_E0HSPE_SHIFT 0 251 - #define SYS_PMSCR_EL2_E2SPE_SHIFT 1 252 - #define SYS_PMSCR_EL2_CX_SHIFT 3 253 - #define SYS_PMSCR_EL2_PA_SHIFT 4 254 - #define SYS_PMSCR_EL2_TS_SHIFT 5 255 - #define SYS_PMSCR_EL2_PCT_SHIFT 6 256 - 257 - #define SYS_PMSICR_EL1 sys_reg(3, 0, 9, 9, 2) 258 - 259 - #define SYS_PMSIRR_EL1 sys_reg(3, 0, 9, 9, 3) 260 - #define SYS_PMSIRR_EL1_RND_SHIFT 0 261 - #define SYS_PMSIRR_EL1_INTERVAL_SHIFT 8 262 - #define SYS_PMSIRR_EL1_INTERVAL_MASK 0xffffffUL 263 - 264 - /* Filtering controls */ 265 - #define SYS_PMSNEVFR_EL1 sys_reg(3, 0, 9, 9, 1) 266 - 267 - #define SYS_PMSFCR_EL1 sys_reg(3, 0, 9, 9, 4) 268 - #define SYS_PMSFCR_EL1_FE_SHIFT 0 269 - #define SYS_PMSFCR_EL1_FT_SHIFT 1 270 - #define SYS_PMSFCR_EL1_FL_SHIFT 2 271 - #define SYS_PMSFCR_EL1_B_SHIFT 16 272 - #define SYS_PMSFCR_EL1_LD_SHIFT 17 273 - #define SYS_PMSFCR_EL1_ST_SHIFT 18 274 - 275 - #define SYS_PMSEVFR_EL1 sys_reg(3, 0, 9, 9, 5) 276 - #define SYS_PMSEVFR_EL1_RES0_8_2 \ 219 + #define PMSEVFR_EL1_RES0_IMP \ 277 220 (GENMASK_ULL(47, 32) | GENMASK_ULL(23, 16) | GENMASK_ULL(11, 8) |\ 278 221 BIT_ULL(6) | BIT_ULL(4) | BIT_ULL(2) | BIT_ULL(0)) 279 - #define SYS_PMSEVFR_EL1_RES0_8_3 \ 280 - (SYS_PMSEVFR_EL1_RES0_8_2 & ~(BIT_ULL(18) | BIT_ULL(17) | BIT_ULL(11))) 281 - 282 - #define SYS_PMSLATFR_EL1 sys_reg(3, 0, 9, 9, 6) 283 - #define SYS_PMSLATFR_EL1_MINLAT_SHIFT 0 284 - 285 - /* Buffer controls */ 286 - #define SYS_PMBLIMITR_EL1 sys_reg(3, 0, 9, 10, 0) 287 - #define SYS_PMBLIMITR_EL1_E_SHIFT 0 288 - #define SYS_PMBLIMITR_EL1_FM_SHIFT 1 289 - #define SYS_PMBLIMITR_EL1_FM_MASK 0x3UL 290 - #define SYS_PMBLIMITR_EL1_FM_STOP_IRQ (0 << SYS_PMBLIMITR_EL1_FM_SHIFT) 291 - 292 - #define SYS_PMBPTR_EL1 sys_reg(3, 0, 9, 10, 1) 222 + #define PMSEVFR_EL1_RES0_V1P1 \ 223 + (PMSEVFR_EL1_RES0_IMP & ~(BIT_ULL(18) | BIT_ULL(17) | BIT_ULL(11))) 224 + #define PMSEVFR_EL1_RES0_V1P2 \ 225 + (PMSEVFR_EL1_RES0_V1P1 & ~BIT_ULL(6)) 293 226 294 227 /* Buffer error reporting */ 295 - #define SYS_PMBSR_EL1 sys_reg(3, 0, 9, 10, 3) 296 - #define SYS_PMBSR_EL1_COLL_SHIFT 16 297 - #define SYS_PMBSR_EL1_S_SHIFT 17 298 - #define SYS_PMBSR_EL1_EA_SHIFT 18 299 - #define SYS_PMBSR_EL1_DL_SHIFT 19 300 - #define SYS_PMBSR_EL1_EC_SHIFT 26 301 - #define SYS_PMBSR_EL1_EC_MASK 0x3fUL 228 + #define PMBSR_EL1_FAULT_FSC_SHIFT PMBSR_EL1_MSS_SHIFT 229 + #define PMBSR_EL1_FAULT_FSC_MASK PMBSR_EL1_MSS_MASK 302 230 303 - #define SYS_PMBSR_EL1_EC_BUF (0x0UL << SYS_PMBSR_EL1_EC_SHIFT) 304 - #define SYS_PMBSR_EL1_EC_FAULT_S1 (0x24UL << SYS_PMBSR_EL1_EC_SHIFT) 305 - #define SYS_PMBSR_EL1_EC_FAULT_S2 (0x25UL << SYS_PMBSR_EL1_EC_SHIFT) 231 + #define PMBSR_EL1_BUF_BSC_SHIFT PMBSR_EL1_MSS_SHIFT 232 + #define PMBSR_EL1_BUF_BSC_MASK PMBSR_EL1_MSS_MASK 306 233 307 - #define SYS_PMBSR_EL1_FAULT_FSC_SHIFT 0 308 - #define SYS_PMBSR_EL1_FAULT_FSC_MASK 0x3fUL 309 - 310 - #define SYS_PMBSR_EL1_BUF_BSC_SHIFT 0 311 - #define SYS_PMBSR_EL1_BUF_BSC_MASK 0x3fUL 312 - 313 - #define SYS_PMBSR_EL1_BUF_BSC_FULL (0x1UL << SYS_PMBSR_EL1_BUF_BSC_SHIFT) 234 + #define PMBSR_EL1_BUF_BSC_FULL 0x1UL 314 235 315 236 /*** End of Statistical Profiling Extension ***/ 316 237 ··· 496 575 #define SCTLR_ELx_DSSBS (BIT(44)) 497 576 #define SCTLR_ELx_ATA (BIT(43)) 498 577 578 + #define SCTLR_ELx_EE_SHIFT 25 499 579 #define SCTLR_ELx_ENIA_SHIFT 31 500 580 501 581 #define SCTLR_ELx_ITFSB (BIT(37)) ··· 505 583 #define SCTLR_ELx_LSMAOE (BIT(29)) 506 584 #define SCTLR_ELx_nTLSMD (BIT(28)) 507 585 #define SCTLR_ELx_ENDA (BIT(27)) 508 - #define SCTLR_ELx_EE (BIT(25)) 586 + #define SCTLR_ELx_EE (BIT(SCTLR_ELx_EE_SHIFT)) 509 587 #define SCTLR_ELx_EIS (BIT(22)) 510 588 #define SCTLR_ELx_IESB (BIT(21)) 511 589 #define SCTLR_ELx_TSCXT (BIT(20)) ··· 731 809 732 810 #define ARM64_FEATURE_FIELD_BITS 4 733 811 734 - /* Create a mask for the feature bits of the specified feature. */ 735 - #define ARM64_FEATURE_MASK(x) (GENMASK_ULL(x##_SHIFT + ARM64_FEATURE_FIELD_BITS - 1, x##_SHIFT)) 812 + /* Defined for compatibility only, do not add new users. */ 813 + #define ARM64_FEATURE_MASK(x) (x##_MASK) 736 814 737 815 #ifdef __ASSEMBLY__ 738 816
+6
arch/arm64/include/uapi/asm/hwcap.h
··· 96 96 #define HWCAP2_CSSC (1UL << 34) 97 97 #define HWCAP2_RPRFM (1UL << 35) 98 98 #define HWCAP2_SVE2P1 (1UL << 36) 99 + #define HWCAP2_SME2 (1UL << 37) 100 + #define HWCAP2_SME2P1 (1UL << 38) 101 + #define HWCAP2_SME_I16I32 (1UL << 39) 102 + #define HWCAP2_SME_BI32I32 (1UL << 40) 103 + #define HWCAP2_SME_B16B16 (1UL << 41) 104 + #define HWCAP2_SME_F16F16 (1UL << 42) 99 105 100 106 #endif /* _UAPI__ASM_HWCAP_H */
+27
arch/arm64/include/uapi/asm/sigcontext.h
··· 144 144 145 145 #define SVE_SIG_FLAG_SM 0x1 /* Context describes streaming mode */ 146 146 147 + /* TPIDR2_EL0 context */ 148 + #define TPIDR2_MAGIC 0x54504902 149 + 150 + struct tpidr2_context { 151 + struct _aarch64_ctx head; 152 + __u64 tpidr2; 153 + }; 154 + 147 155 #define ZA_MAGIC 0x54366345 148 156 149 157 struct za_context { 150 158 struct _aarch64_ctx head; 151 159 __u16 vl; 160 + __u16 __reserved[3]; 161 + }; 162 + 163 + #define ZT_MAGIC 0x5a544e01 164 + 165 + struct zt_context { 166 + struct _aarch64_ctx head; 167 + __u16 nregs; 152 168 __u16 __reserved[3]; 153 169 }; 154 170 ··· 319 303 320 304 #define ZA_SIG_CONTEXT_SIZE(vq) \ 321 305 (ZA_SIG_REGS_OFFSET + ZA_SIG_REGS_SIZE(vq)) 306 + 307 + #define ZT_SIG_REG_SIZE 512 308 + 309 + #define ZT_SIG_REG_BYTES (ZT_SIG_REG_SIZE / 8) 310 + 311 + #define ZT_SIG_REGS_OFFSET sizeof(struct zt_context) 312 + 313 + #define ZT_SIG_REGS_SIZE(n) (ZT_SIG_REG_BYTES * n) 314 + 315 + #define ZT_SIG_CONTEXT_SIZE(n) \ 316 + (sizeof(struct zt_context) + ZT_SIG_REGS_SIZE(n)) 322 317 323 318 #endif /* _UAPI__ASM_SIGCONTEXT_H */
+4
arch/arm64/kernel/asm-offsets.c
··· 9 9 10 10 #include <linux/arm_sdei.h> 11 11 #include <linux/sched.h> 12 + #include <linux/ftrace.h> 12 13 #include <linux/kexec.h> 13 14 #include <linux/mm.h> 14 15 #include <linux/dma-mapping.h> ··· 194 193 DEFINE(KIMAGE_HEAD, offsetof(struct kimage, head)); 195 194 DEFINE(KIMAGE_START, offsetof(struct kimage, start)); 196 195 BLANK(); 196 + #endif 197 + #ifdef CONFIG_FUNCTION_TRACER 198 + DEFINE(FTRACE_OPS_FUNC, offsetof(struct ftrace_ops, func)); 197 199 #endif 198 200 return 0; 199 201 }
+181 -112
arch/arm64/kernel/cpufeature.c
··· 65 65 #include <linux/bsearch.h> 66 66 #include <linux/cpumask.h> 67 67 #include <linux/crash_dump.h> 68 + #include <linux/kstrtox.h> 68 69 #include <linux/sort.h> 69 70 #include <linux/stop_machine.h> 70 71 #include <linux/sysfs.h> ··· 284 283 ARM64_FTR_BITS(FTR_VISIBLE_IF_IS_ENABLED(CONFIG_ARM64_SME), 285 284 FTR_STRICT, FTR_EXACT, ID_AA64SMFR0_EL1_FA64_SHIFT, 1, 0), 286 285 ARM64_FTR_BITS(FTR_VISIBLE_IF_IS_ENABLED(CONFIG_ARM64_SME), 286 + FTR_STRICT, FTR_EXACT, ID_AA64SMFR0_EL1_SMEver_SHIFT, 4, 0), 287 + ARM64_FTR_BITS(FTR_VISIBLE_IF_IS_ENABLED(CONFIG_ARM64_SME), 287 288 FTR_STRICT, FTR_EXACT, ID_AA64SMFR0_EL1_I16I64_SHIFT, 4, 0), 288 289 ARM64_FTR_BITS(FTR_VISIBLE_IF_IS_ENABLED(CONFIG_ARM64_SME), 289 290 FTR_STRICT, FTR_EXACT, ID_AA64SMFR0_EL1_F64F64_SHIFT, 1, 0), 291 + ARM64_FTR_BITS(FTR_VISIBLE_IF_IS_ENABLED(CONFIG_ARM64_SME), 292 + FTR_STRICT, FTR_EXACT, ID_AA64SMFR0_EL1_I16I32_SHIFT, 4, 0), 293 + ARM64_FTR_BITS(FTR_VISIBLE_IF_IS_ENABLED(CONFIG_ARM64_SME), 294 + FTR_STRICT, FTR_EXACT, ID_AA64SMFR0_EL1_B16B16_SHIFT, 1, 0), 295 + ARM64_FTR_BITS(FTR_VISIBLE_IF_IS_ENABLED(CONFIG_ARM64_SME), 296 + FTR_STRICT, FTR_EXACT, ID_AA64SMFR0_EL1_F16F16_SHIFT, 1, 0), 290 297 ARM64_FTR_BITS(FTR_VISIBLE_IF_IS_ENABLED(CONFIG_ARM64_SME), 291 298 FTR_STRICT, FTR_EXACT, ID_AA64SMFR0_EL1_I8I32_SHIFT, 4, 0), 292 299 ARM64_FTR_BITS(FTR_VISIBLE_IF_IS_ENABLED(CONFIG_ARM64_SME), 293 300 FTR_STRICT, FTR_EXACT, ID_AA64SMFR0_EL1_F16F32_SHIFT, 1, 0), 294 301 ARM64_FTR_BITS(FTR_VISIBLE_IF_IS_ENABLED(CONFIG_ARM64_SME), 295 302 FTR_STRICT, FTR_EXACT, ID_AA64SMFR0_EL1_B16F32_SHIFT, 1, 0), 303 + ARM64_FTR_BITS(FTR_VISIBLE_IF_IS_ENABLED(CONFIG_ARM64_SME), 304 + FTR_STRICT, FTR_EXACT, ID_AA64SMFR0_EL1_BI32I32_SHIFT, 1, 0), 296 305 ARM64_FTR_BITS(FTR_VISIBLE_IF_IS_ENABLED(CONFIG_ARM64_SME), 297 306 FTR_STRICT, FTR_EXACT, ID_AA64SMFR0_EL1_F32F32_SHIFT, 1, 0), 298 307 ARM64_FTR_END, ··· 455 444 456 445 static const struct arm64_ftr_bits ftr_mvfr1[] = { 457 446 ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_LOWER_SAFE, MVFR1_EL1_SIMDFMAC_SHIFT, 4, 0), 458 - ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, MVFR1_EL1_FPHP_SHIFT, 4, 0), 459 - ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, MVFR1_EL1_SIMDHP_SHIFT, 4, 0), 447 + ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_LOWER_SAFE, MVFR1_EL1_FPHP_SHIFT, 4, 0), 448 + ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_LOWER_SAFE, MVFR1_EL1_SIMDHP_SHIFT, 4, 0), 460 449 ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_LOWER_SAFE, MVFR1_EL1_SIMDSP_SHIFT, 4, 0), 461 450 ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_LOWER_SAFE, MVFR1_EL1_SIMDInt_SHIFT, 4, 0), 462 451 ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_LOWER_SAFE, MVFR1_EL1_SIMDLS_SHIFT, 4, 0), ··· 540 529 }; 541 530 542 531 static const struct arm64_ftr_bits ftr_id_isar6[] = { 543 - ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_ISAR6_EL1_I8MM_SHIFT, 4, 0), 544 - ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_ISAR6_EL1_BF16_SHIFT, 4, 0), 532 + ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_LOWER_SAFE, ID_ISAR6_EL1_I8MM_SHIFT, 4, 0), 533 + ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_LOWER_SAFE, ID_ISAR6_EL1_BF16_SHIFT, 4, 0), 545 534 ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_ISAR6_EL1_SPECRES_SHIFT, 4, 0), 546 - ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_ISAR6_EL1_SB_SHIFT, 4, 0), 547 - ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_ISAR6_EL1_FHM_SHIFT, 4, 0), 548 - ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_ISAR6_EL1_DP_SHIFT, 4, 0), 535 + ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_LOWER_SAFE, ID_ISAR6_EL1_SB_SHIFT, 4, 0), 536 + ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_LOWER_SAFE, ID_ISAR6_EL1_FHM_SHIFT, 4, 0), 537 + ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_LOWER_SAFE, ID_ISAR6_EL1_DP_SHIFT, 4, 0), 549 538 ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_ISAR6_EL1_JSCVT_SHIFT, 4, 0), 550 539 ARM64_FTR_END, 551 540 }; ··· 573 562 }; 574 563 575 564 static const struct arm64_ftr_bits ftr_id_pfr2[] = { 576 - ARM64_FTR_BITS(FTR_HIDDEN, FTR_NONSTRICT, FTR_LOWER_SAFE, ID_PFR2_EL1_SSBS_SHIFT, 4, 0), 565 + ARM64_FTR_BITS(FTR_VISIBLE, FTR_NONSTRICT, FTR_LOWER_SAFE, ID_PFR2_EL1_SSBS_SHIFT, 4, 0), 577 566 ARM64_FTR_BITS(FTR_HIDDEN, FTR_NONSTRICT, FTR_LOWER_SAFE, ID_PFR2_EL1_CSV3_SHIFT, 4, 0), 578 567 ARM64_FTR_END, 579 568 }; ··· 1806 1795 static int __init parse_kpti(char *str) 1807 1796 { 1808 1797 bool enabled; 1809 - int ret = strtobool(str, &enabled); 1798 + int ret = kstrtobool(str, &enabled); 1810 1799 1811 1800 if (ret) 1812 1801 return ret; ··· 2050 2039 2051 2040 static int __init early_enable_pseudo_nmi(char *p) 2052 2041 { 2053 - return strtobool(p, &enable_pseudo_nmi); 2042 + return kstrtobool(p, &enable_pseudo_nmi); 2054 2043 } 2055 2044 early_param("irqchip.gicv3_pseudo_nmi", early_enable_pseudo_nmi); 2056 2045 2057 2046 static bool can_use_gic_priorities(const struct arm64_cpu_capabilities *entry, 2058 2047 int scope) 2059 2048 { 2060 - return enable_pseudo_nmi && has_useable_gicv3_cpuif(entry, scope); 2049 + /* 2050 + * ARM64_HAS_GIC_CPUIF_SYSREGS has a lower index, and is a boot CPU 2051 + * feature, so will be detected earlier. 2052 + */ 2053 + BUILD_BUG_ON(ARM64_HAS_GIC_PRIO_MASKING <= ARM64_HAS_GIC_CPUIF_SYSREGS); 2054 + if (!cpus_have_cap(ARM64_HAS_GIC_CPUIF_SYSREGS)) 2055 + return false; 2056 + 2057 + return enable_pseudo_nmi; 2058 + } 2059 + 2060 + static bool has_gic_prio_relaxed_sync(const struct arm64_cpu_capabilities *entry, 2061 + int scope) 2062 + { 2063 + /* 2064 + * If we're not using priority masking then we won't be poking PMR_EL1, 2065 + * and there's no need to relax synchronization of writes to it, and 2066 + * ICC_CTLR_EL1 might not be accessible and we must avoid reads from 2067 + * that. 2068 + * 2069 + * ARM64_HAS_GIC_PRIO_MASKING has a lower index, and is a boot CPU 2070 + * feature, so will be detected earlier. 2071 + */ 2072 + BUILD_BUG_ON(ARM64_HAS_GIC_PRIO_RELAXED_SYNC <= ARM64_HAS_GIC_PRIO_MASKING); 2073 + if (!cpus_have_cap(ARM64_HAS_GIC_PRIO_MASKING)) 2074 + return false; 2075 + 2076 + /* 2077 + * When Priority Mask Hint Enable (PMHE) == 0b0, PMR is not used as a 2078 + * hint for interrupt distribution, a DSB is not necessary when 2079 + * unmasking IRQs via PMR, and we can relax the barrier to a NOP. 2080 + * 2081 + * Linux itself doesn't use 1:N distribution, so has no need to 2082 + * set PMHE. The only reason to have it set is if EL3 requires it 2083 + * (and we can't change it). 2084 + */ 2085 + return (gic_read_ctlr() & ICC_CTLR_EL1_PMHE_MASK) == 0; 2061 2086 } 2062 2087 #endif 2063 2088 ··· 2189 2142 }, 2190 2143 { 2191 2144 .desc = "GIC system register CPU interface", 2192 - .capability = ARM64_HAS_SYSREG_GIC_CPUIF, 2145 + .capability = ARM64_HAS_GIC_CPUIF_SYSREGS, 2193 2146 .type = ARM64_CPUCAP_STRICT_BOOT_CPU_FEATURE, 2194 2147 .matches = has_useable_gicv3_cpuif, 2195 2148 .sys_reg = SYS_ID_AA64PFR0_EL1, ··· 2581 2534 * Depends on having GICv3 2582 2535 */ 2583 2536 .desc = "IRQ priority masking", 2584 - .capability = ARM64_HAS_IRQ_PRIO_MASKING, 2537 + .capability = ARM64_HAS_GIC_PRIO_MASKING, 2585 2538 .type = ARM64_CPUCAP_STRICT_BOOT_CPU_FEATURE, 2586 2539 .matches = can_use_gic_priorities, 2587 - .sys_reg = SYS_ID_AA64PFR0_EL1, 2588 - .field_pos = ID_AA64PFR0_EL1_GIC_SHIFT, 2589 - .field_width = 4, 2590 - .sign = FTR_UNSIGNED, 2591 - .min_field_value = 1, 2540 + }, 2541 + { 2542 + /* 2543 + * Depends on ARM64_HAS_GIC_PRIO_MASKING 2544 + */ 2545 + .capability = ARM64_HAS_GIC_PRIO_RELAXED_SYNC, 2546 + .type = ARM64_CPUCAP_STRICT_BOOT_CPU_FEATURE, 2547 + .matches = has_gic_prio_relaxed_sync, 2592 2548 }, 2593 2549 #endif 2594 2550 #ifdef CONFIG_ARM64_E0PD ··· 2699 2649 .matches = has_cpuid_feature, 2700 2650 .cpu_enable = fa64_kernel_enable, 2701 2651 }, 2652 + { 2653 + .desc = "SME2", 2654 + .type = ARM64_CPUCAP_SYSTEM_FEATURE, 2655 + .capability = ARM64_SME2, 2656 + .sys_reg = SYS_ID_AA64PFR1_EL1, 2657 + .sign = FTR_UNSIGNED, 2658 + .field_pos = ID_AA64PFR1_EL1_SME_SHIFT, 2659 + .field_width = ID_AA64PFR1_EL1_SME_WIDTH, 2660 + .min_field_value = ID_AA64PFR1_EL1_SME_SME2, 2661 + .matches = has_cpuid_feature, 2662 + .cpu_enable = sme2_kernel_enable, 2663 + }, 2702 2664 #endif /* CONFIG_ARM64_SME */ 2703 2665 { 2704 2666 .desc = "WFx with timeout", ··· 2750 2688 {}, 2751 2689 }; 2752 2690 2753 - #define HWCAP_CPUID_MATCH(reg, field, width, s, min_value) \ 2691 + #define HWCAP_CPUID_MATCH(reg, field, min_value) \ 2754 2692 .matches = has_user_cpuid_feature, \ 2755 - .sys_reg = reg, \ 2756 - .field_pos = field, \ 2757 - .field_width = width, \ 2758 - .sign = s, \ 2759 - .min_field_value = min_value, 2693 + .sys_reg = SYS_##reg, \ 2694 + .field_pos = reg##_##field##_SHIFT, \ 2695 + .field_width = reg##_##field##_WIDTH, \ 2696 + .sign = reg##_##field##_SIGNED, \ 2697 + .min_field_value = reg##_##field##_##min_value, 2760 2698 2761 2699 #define __HWCAP_CAP(name, cap_type, cap) \ 2762 2700 .desc = name, \ ··· 2764 2702 .hwcap_type = cap_type, \ 2765 2703 .hwcap = cap, \ 2766 2704 2767 - #define HWCAP_CAP(reg, field, width, s, min_value, cap_type, cap) \ 2705 + #define HWCAP_CAP(reg, field, min_value, cap_type, cap) \ 2768 2706 { \ 2769 2707 __HWCAP_CAP(#cap, cap_type, cap) \ 2770 - HWCAP_CPUID_MATCH(reg, field, width, s, min_value) \ 2708 + HWCAP_CPUID_MATCH(reg, field, min_value) \ 2771 2709 } 2772 2710 2773 2711 #define HWCAP_MULTI_CAP(list, cap_type, cap) \ ··· 2786 2724 #ifdef CONFIG_ARM64_PTR_AUTH 2787 2725 static const struct arm64_cpu_capabilities ptr_auth_hwcap_addr_matches[] = { 2788 2726 { 2789 - HWCAP_CPUID_MATCH(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_EL1_APA_SHIFT, 2790 - 4, FTR_UNSIGNED, 2791 - ID_AA64ISAR1_EL1_APA_PAuth) 2727 + HWCAP_CPUID_MATCH(ID_AA64ISAR1_EL1, APA, PAuth) 2792 2728 }, 2793 2729 { 2794 - HWCAP_CPUID_MATCH(SYS_ID_AA64ISAR2_EL1, ID_AA64ISAR2_EL1_APA3_SHIFT, 2795 - 4, FTR_UNSIGNED, ID_AA64ISAR2_EL1_APA3_PAuth) 2730 + HWCAP_CPUID_MATCH(ID_AA64ISAR2_EL1, APA3, PAuth) 2796 2731 }, 2797 2732 { 2798 - HWCAP_CPUID_MATCH(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_EL1_API_SHIFT, 2799 - 4, FTR_UNSIGNED, ID_AA64ISAR1_EL1_API_PAuth) 2733 + HWCAP_CPUID_MATCH(ID_AA64ISAR1_EL1, API, PAuth) 2800 2734 }, 2801 2735 {}, 2802 2736 }; 2803 2737 2804 2738 static const struct arm64_cpu_capabilities ptr_auth_hwcap_gen_matches[] = { 2805 2739 { 2806 - HWCAP_CPUID_MATCH(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_EL1_GPA_SHIFT, 2807 - 4, FTR_UNSIGNED, ID_AA64ISAR1_EL1_GPA_IMP) 2740 + HWCAP_CPUID_MATCH(ID_AA64ISAR1_EL1, GPA, IMP) 2808 2741 }, 2809 2742 { 2810 - HWCAP_CPUID_MATCH(SYS_ID_AA64ISAR2_EL1, ID_AA64ISAR2_EL1_GPA3_SHIFT, 2811 - 4, FTR_UNSIGNED, ID_AA64ISAR2_EL1_GPA3_IMP) 2743 + HWCAP_CPUID_MATCH(ID_AA64ISAR2_EL1, GPA3, IMP) 2812 2744 }, 2813 2745 { 2814 - HWCAP_CPUID_MATCH(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_EL1_GPI_SHIFT, 2815 - 4, FTR_UNSIGNED, ID_AA64ISAR1_EL1_GPI_IMP) 2746 + HWCAP_CPUID_MATCH(ID_AA64ISAR1_EL1, GPI, IMP) 2816 2747 }, 2817 2748 {}, 2818 2749 }; 2819 2750 #endif 2820 2751 2821 2752 static const struct arm64_cpu_capabilities arm64_elf_hwcaps[] = { 2822 - HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_EL1_AES_SHIFT, 4, FTR_UNSIGNED, 2, CAP_HWCAP, KERNEL_HWCAP_PMULL), 2823 - HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_EL1_AES_SHIFT, 4, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_AES), 2824 - HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_EL1_SHA1_SHIFT, 4, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_SHA1), 2825 - HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_EL1_SHA2_SHIFT, 4, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_SHA2), 2826 - HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_EL1_SHA2_SHIFT, 4, FTR_UNSIGNED, 2, CAP_HWCAP, KERNEL_HWCAP_SHA512), 2827 - HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_EL1_CRC32_SHIFT, 4, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_CRC32), 2828 - HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_EL1_ATOMIC_SHIFT, 4, FTR_UNSIGNED, 2, CAP_HWCAP, KERNEL_HWCAP_ATOMICS), 2829 - HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_EL1_RDM_SHIFT, 4, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_ASIMDRDM), 2830 - HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_EL1_SHA3_SHIFT, 4, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_SHA3), 2831 - HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_EL1_SM3_SHIFT, 4, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_SM3), 2832 - HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_EL1_SM4_SHIFT, 4, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_SM4), 2833 - HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_EL1_DP_SHIFT, 4, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_ASIMDDP), 2834 - HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_EL1_FHM_SHIFT, 4, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_ASIMDFHM), 2835 - HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_EL1_TS_SHIFT, 4, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_FLAGM), 2836 - HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_EL1_TS_SHIFT, 4, FTR_UNSIGNED, 2, CAP_HWCAP, KERNEL_HWCAP_FLAGM2), 2837 - HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_EL1_RNDR_SHIFT, 4, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_RNG), 2838 - HWCAP_CAP(SYS_ID_AA64PFR0_EL1, ID_AA64PFR0_EL1_FP_SHIFT, 4, FTR_SIGNED, 0, CAP_HWCAP, KERNEL_HWCAP_FP), 2839 - HWCAP_CAP(SYS_ID_AA64PFR0_EL1, ID_AA64PFR0_EL1_FP_SHIFT, 4, FTR_SIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_FPHP), 2840 - HWCAP_CAP(SYS_ID_AA64PFR0_EL1, ID_AA64PFR0_EL1_AdvSIMD_SHIFT, 4, FTR_SIGNED, 0, CAP_HWCAP, KERNEL_HWCAP_ASIMD), 2841 - HWCAP_CAP(SYS_ID_AA64PFR0_EL1, ID_AA64PFR0_EL1_AdvSIMD_SHIFT, 4, FTR_SIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_ASIMDHP), 2842 - HWCAP_CAP(SYS_ID_AA64PFR0_EL1, ID_AA64PFR0_EL1_DIT_SHIFT, 4, FTR_SIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_DIT), 2843 - HWCAP_CAP(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_EL1_DPB_SHIFT, 4, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_DCPOP), 2844 - HWCAP_CAP(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_EL1_DPB_SHIFT, 4, FTR_UNSIGNED, 2, CAP_HWCAP, KERNEL_HWCAP_DCPODP), 2845 - HWCAP_CAP(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_EL1_JSCVT_SHIFT, 4, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_JSCVT), 2846 - HWCAP_CAP(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_EL1_FCMA_SHIFT, 4, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_FCMA), 2847 - HWCAP_CAP(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_EL1_LRCPC_SHIFT, 4, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_LRCPC), 2848 - HWCAP_CAP(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_EL1_LRCPC_SHIFT, 4, FTR_UNSIGNED, 2, CAP_HWCAP, KERNEL_HWCAP_ILRCPC), 2849 - HWCAP_CAP(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_EL1_FRINTTS_SHIFT, 4, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_FRINT), 2850 - HWCAP_CAP(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_EL1_SB_SHIFT, 4, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_SB), 2851 - HWCAP_CAP(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_EL1_BF16_SHIFT, 4, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_BF16), 2852 - HWCAP_CAP(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_EL1_BF16_SHIFT, 4, FTR_UNSIGNED, 2, CAP_HWCAP, KERNEL_HWCAP_EBF16), 2853 - HWCAP_CAP(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_EL1_DGH_SHIFT, 4, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_DGH), 2854 - HWCAP_CAP(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_EL1_I8MM_SHIFT, 4, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_I8MM), 2855 - HWCAP_CAP(SYS_ID_AA64MMFR2_EL1, ID_AA64MMFR2_EL1_AT_SHIFT, 4, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_USCAT), 2753 + HWCAP_CAP(ID_AA64ISAR0_EL1, AES, PMULL, CAP_HWCAP, KERNEL_HWCAP_PMULL), 2754 + HWCAP_CAP(ID_AA64ISAR0_EL1, AES, AES, CAP_HWCAP, KERNEL_HWCAP_AES), 2755 + HWCAP_CAP(ID_AA64ISAR0_EL1, SHA1, IMP, CAP_HWCAP, KERNEL_HWCAP_SHA1), 2756 + HWCAP_CAP(ID_AA64ISAR0_EL1, SHA2, SHA256, CAP_HWCAP, KERNEL_HWCAP_SHA2), 2757 + HWCAP_CAP(ID_AA64ISAR0_EL1, SHA2, SHA512, CAP_HWCAP, KERNEL_HWCAP_SHA512), 2758 + HWCAP_CAP(ID_AA64ISAR0_EL1, CRC32, IMP, CAP_HWCAP, KERNEL_HWCAP_CRC32), 2759 + HWCAP_CAP(ID_AA64ISAR0_EL1, ATOMIC, IMP, CAP_HWCAP, KERNEL_HWCAP_ATOMICS), 2760 + HWCAP_CAP(ID_AA64ISAR0_EL1, RDM, IMP, CAP_HWCAP, KERNEL_HWCAP_ASIMDRDM), 2761 + HWCAP_CAP(ID_AA64ISAR0_EL1, SHA3, IMP, CAP_HWCAP, KERNEL_HWCAP_SHA3), 2762 + HWCAP_CAP(ID_AA64ISAR0_EL1, SM3, IMP, CAP_HWCAP, KERNEL_HWCAP_SM3), 2763 + HWCAP_CAP(ID_AA64ISAR0_EL1, SM4, IMP, CAP_HWCAP, KERNEL_HWCAP_SM4), 2764 + HWCAP_CAP(ID_AA64ISAR0_EL1, DP, IMP, CAP_HWCAP, KERNEL_HWCAP_ASIMDDP), 2765 + HWCAP_CAP(ID_AA64ISAR0_EL1, FHM, IMP, CAP_HWCAP, KERNEL_HWCAP_ASIMDFHM), 2766 + HWCAP_CAP(ID_AA64ISAR0_EL1, TS, FLAGM, CAP_HWCAP, KERNEL_HWCAP_FLAGM), 2767 + HWCAP_CAP(ID_AA64ISAR0_EL1, TS, FLAGM2, CAP_HWCAP, KERNEL_HWCAP_FLAGM2), 2768 + HWCAP_CAP(ID_AA64ISAR0_EL1, RNDR, IMP, CAP_HWCAP, KERNEL_HWCAP_RNG), 2769 + HWCAP_CAP(ID_AA64PFR0_EL1, FP, IMP, CAP_HWCAP, KERNEL_HWCAP_FP), 2770 + HWCAP_CAP(ID_AA64PFR0_EL1, FP, FP16, CAP_HWCAP, KERNEL_HWCAP_FPHP), 2771 + HWCAP_CAP(ID_AA64PFR0_EL1, AdvSIMD, IMP, CAP_HWCAP, KERNEL_HWCAP_ASIMD), 2772 + HWCAP_CAP(ID_AA64PFR0_EL1, AdvSIMD, FP16, CAP_HWCAP, KERNEL_HWCAP_ASIMDHP), 2773 + HWCAP_CAP(ID_AA64PFR0_EL1, DIT, IMP, CAP_HWCAP, KERNEL_HWCAP_DIT), 2774 + HWCAP_CAP(ID_AA64ISAR1_EL1, DPB, IMP, CAP_HWCAP, KERNEL_HWCAP_DCPOP), 2775 + HWCAP_CAP(ID_AA64ISAR1_EL1, DPB, DPB2, CAP_HWCAP, KERNEL_HWCAP_DCPODP), 2776 + HWCAP_CAP(ID_AA64ISAR1_EL1, JSCVT, IMP, CAP_HWCAP, KERNEL_HWCAP_JSCVT), 2777 + HWCAP_CAP(ID_AA64ISAR1_EL1, FCMA, IMP, CAP_HWCAP, KERNEL_HWCAP_FCMA), 2778 + HWCAP_CAP(ID_AA64ISAR1_EL1, LRCPC, IMP, CAP_HWCAP, KERNEL_HWCAP_LRCPC), 2779 + HWCAP_CAP(ID_AA64ISAR1_EL1, LRCPC, LRCPC2, CAP_HWCAP, KERNEL_HWCAP_ILRCPC), 2780 + HWCAP_CAP(ID_AA64ISAR1_EL1, FRINTTS, IMP, CAP_HWCAP, KERNEL_HWCAP_FRINT), 2781 + HWCAP_CAP(ID_AA64ISAR1_EL1, SB, IMP, CAP_HWCAP, KERNEL_HWCAP_SB), 2782 + HWCAP_CAP(ID_AA64ISAR1_EL1, BF16, IMP, CAP_HWCAP, KERNEL_HWCAP_BF16), 2783 + HWCAP_CAP(ID_AA64ISAR1_EL1, BF16, EBF16, CAP_HWCAP, KERNEL_HWCAP_EBF16), 2784 + HWCAP_CAP(ID_AA64ISAR1_EL1, DGH, IMP, CAP_HWCAP, KERNEL_HWCAP_DGH), 2785 + HWCAP_CAP(ID_AA64ISAR1_EL1, I8MM, IMP, CAP_HWCAP, KERNEL_HWCAP_I8MM), 2786 + HWCAP_CAP(ID_AA64MMFR2_EL1, AT, IMP, CAP_HWCAP, KERNEL_HWCAP_USCAT), 2856 2787 #ifdef CONFIG_ARM64_SVE 2857 - HWCAP_CAP(SYS_ID_AA64PFR0_EL1, ID_AA64PFR0_EL1_SVE_SHIFT, 4, FTR_UNSIGNED, ID_AA64PFR0_EL1_SVE_IMP, CAP_HWCAP, KERNEL_HWCAP_SVE), 2858 - HWCAP_CAP(SYS_ID_AA64ZFR0_EL1, ID_AA64ZFR0_EL1_SVEver_SHIFT, 4, FTR_UNSIGNED, ID_AA64ZFR0_EL1_SVEver_SVE2p1, CAP_HWCAP, KERNEL_HWCAP_SVE2P1), 2859 - HWCAP_CAP(SYS_ID_AA64ZFR0_EL1, ID_AA64ZFR0_EL1_SVEver_SHIFT, 4, FTR_UNSIGNED, ID_AA64ZFR0_EL1_SVEver_SVE2, CAP_HWCAP, KERNEL_HWCAP_SVE2), 2860 - HWCAP_CAP(SYS_ID_AA64ZFR0_EL1, ID_AA64ZFR0_EL1_AES_SHIFT, 4, FTR_UNSIGNED, ID_AA64ZFR0_EL1_AES_IMP, CAP_HWCAP, KERNEL_HWCAP_SVEAES), 2861 - HWCAP_CAP(SYS_ID_AA64ZFR0_EL1, ID_AA64ZFR0_EL1_AES_SHIFT, 4, FTR_UNSIGNED, ID_AA64ZFR0_EL1_AES_PMULL128, CAP_HWCAP, KERNEL_HWCAP_SVEPMULL), 2862 - HWCAP_CAP(SYS_ID_AA64ZFR0_EL1, ID_AA64ZFR0_EL1_BitPerm_SHIFT, 4, FTR_UNSIGNED, ID_AA64ZFR0_EL1_BitPerm_IMP, CAP_HWCAP, KERNEL_HWCAP_SVEBITPERM), 2863 - HWCAP_CAP(SYS_ID_AA64ZFR0_EL1, ID_AA64ZFR0_EL1_BF16_SHIFT, 4, FTR_UNSIGNED, ID_AA64ZFR0_EL1_BF16_IMP, CAP_HWCAP, KERNEL_HWCAP_SVEBF16), 2864 - HWCAP_CAP(SYS_ID_AA64ZFR0_EL1, ID_AA64ZFR0_EL1_BF16_SHIFT, 4, FTR_UNSIGNED, ID_AA64ZFR0_EL1_BF16_EBF16, CAP_HWCAP, KERNEL_HWCAP_SVE_EBF16), 2865 - HWCAP_CAP(SYS_ID_AA64ZFR0_EL1, ID_AA64ZFR0_EL1_SHA3_SHIFT, 4, FTR_UNSIGNED, ID_AA64ZFR0_EL1_SHA3_IMP, CAP_HWCAP, KERNEL_HWCAP_SVESHA3), 2866 - HWCAP_CAP(SYS_ID_AA64ZFR0_EL1, ID_AA64ZFR0_EL1_SM4_SHIFT, 4, FTR_UNSIGNED, ID_AA64ZFR0_EL1_SM4_IMP, CAP_HWCAP, KERNEL_HWCAP_SVESM4), 2867 - HWCAP_CAP(SYS_ID_AA64ZFR0_EL1, ID_AA64ZFR0_EL1_I8MM_SHIFT, 4, FTR_UNSIGNED, ID_AA64ZFR0_EL1_I8MM_IMP, CAP_HWCAP, KERNEL_HWCAP_SVEI8MM), 2868 - HWCAP_CAP(SYS_ID_AA64ZFR0_EL1, ID_AA64ZFR0_EL1_F32MM_SHIFT, 4, FTR_UNSIGNED, ID_AA64ZFR0_EL1_F32MM_IMP, CAP_HWCAP, KERNEL_HWCAP_SVEF32MM), 2869 - HWCAP_CAP(SYS_ID_AA64ZFR0_EL1, ID_AA64ZFR0_EL1_F64MM_SHIFT, 4, FTR_UNSIGNED, ID_AA64ZFR0_EL1_F64MM_IMP, CAP_HWCAP, KERNEL_HWCAP_SVEF64MM), 2788 + HWCAP_CAP(ID_AA64PFR0_EL1, SVE, IMP, CAP_HWCAP, KERNEL_HWCAP_SVE), 2789 + HWCAP_CAP(ID_AA64ZFR0_EL1, SVEver, SVE2p1, CAP_HWCAP, KERNEL_HWCAP_SVE2P1), 2790 + HWCAP_CAP(ID_AA64ZFR0_EL1, SVEver, SVE2, CAP_HWCAP, KERNEL_HWCAP_SVE2), 2791 + HWCAP_CAP(ID_AA64ZFR0_EL1, AES, IMP, CAP_HWCAP, KERNEL_HWCAP_SVEAES), 2792 + HWCAP_CAP(ID_AA64ZFR0_EL1, AES, PMULL128, CAP_HWCAP, KERNEL_HWCAP_SVEPMULL), 2793 + HWCAP_CAP(ID_AA64ZFR0_EL1, BitPerm, IMP, CAP_HWCAP, KERNEL_HWCAP_SVEBITPERM), 2794 + HWCAP_CAP(ID_AA64ZFR0_EL1, BF16, IMP, CAP_HWCAP, KERNEL_HWCAP_SVEBF16), 2795 + HWCAP_CAP(ID_AA64ZFR0_EL1, BF16, EBF16, CAP_HWCAP, KERNEL_HWCAP_SVE_EBF16), 2796 + HWCAP_CAP(ID_AA64ZFR0_EL1, SHA3, IMP, CAP_HWCAP, KERNEL_HWCAP_SVESHA3), 2797 + HWCAP_CAP(ID_AA64ZFR0_EL1, SM4, IMP, CAP_HWCAP, KERNEL_HWCAP_SVESM4), 2798 + HWCAP_CAP(ID_AA64ZFR0_EL1, I8MM, IMP, CAP_HWCAP, KERNEL_HWCAP_SVEI8MM), 2799 + HWCAP_CAP(ID_AA64ZFR0_EL1, F32MM, IMP, CAP_HWCAP, KERNEL_HWCAP_SVEF32MM), 2800 + HWCAP_CAP(ID_AA64ZFR0_EL1, F64MM, IMP, CAP_HWCAP, KERNEL_HWCAP_SVEF64MM), 2870 2801 #endif 2871 - HWCAP_CAP(SYS_ID_AA64PFR1_EL1, ID_AA64PFR1_EL1_SSBS_SHIFT, 4, FTR_UNSIGNED, ID_AA64PFR1_EL1_SSBS_SSBS2, CAP_HWCAP, KERNEL_HWCAP_SSBS), 2802 + HWCAP_CAP(ID_AA64PFR1_EL1, SSBS, SSBS2, CAP_HWCAP, KERNEL_HWCAP_SSBS), 2872 2803 #ifdef CONFIG_ARM64_BTI 2873 - HWCAP_CAP(SYS_ID_AA64PFR1_EL1, ID_AA64PFR1_EL1_BT_SHIFT, 4, FTR_UNSIGNED, ID_AA64PFR1_EL1_BT_IMP, CAP_HWCAP, KERNEL_HWCAP_BTI), 2804 + HWCAP_CAP(ID_AA64PFR1_EL1, BT, IMP, CAP_HWCAP, KERNEL_HWCAP_BTI), 2874 2805 #endif 2875 2806 #ifdef CONFIG_ARM64_PTR_AUTH 2876 2807 HWCAP_MULTI_CAP(ptr_auth_hwcap_addr_matches, CAP_HWCAP, KERNEL_HWCAP_PACA), 2877 2808 HWCAP_MULTI_CAP(ptr_auth_hwcap_gen_matches, CAP_HWCAP, KERNEL_HWCAP_PACG), 2878 2809 #endif 2879 2810 #ifdef CONFIG_ARM64_MTE 2880 - HWCAP_CAP(SYS_ID_AA64PFR1_EL1, ID_AA64PFR1_EL1_MTE_SHIFT, 4, FTR_UNSIGNED, ID_AA64PFR1_EL1_MTE_MTE2, CAP_HWCAP, KERNEL_HWCAP_MTE), 2881 - HWCAP_CAP(SYS_ID_AA64PFR1_EL1, ID_AA64PFR1_EL1_MTE_SHIFT, 4, FTR_UNSIGNED, ID_AA64PFR1_EL1_MTE_MTE3, CAP_HWCAP, KERNEL_HWCAP_MTE3), 2811 + HWCAP_CAP(ID_AA64PFR1_EL1, MTE, MTE2, CAP_HWCAP, KERNEL_HWCAP_MTE), 2812 + HWCAP_CAP(ID_AA64PFR1_EL1, MTE, MTE3, CAP_HWCAP, KERNEL_HWCAP_MTE3), 2882 2813 #endif /* CONFIG_ARM64_MTE */ 2883 - HWCAP_CAP(SYS_ID_AA64MMFR0_EL1, ID_AA64MMFR0_EL1_ECV_SHIFT, 4, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_ECV), 2884 - HWCAP_CAP(SYS_ID_AA64MMFR1_EL1, ID_AA64MMFR1_EL1_AFP_SHIFT, 4, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_AFP), 2885 - HWCAP_CAP(SYS_ID_AA64ISAR2_EL1, ID_AA64ISAR2_EL1_CSSC_SHIFT, 4, FTR_UNSIGNED, ID_AA64ISAR2_EL1_CSSC_IMP, CAP_HWCAP, KERNEL_HWCAP_CSSC), 2886 - HWCAP_CAP(SYS_ID_AA64ISAR2_EL1, ID_AA64ISAR2_EL1_RPRFM_SHIFT, 4, FTR_UNSIGNED, ID_AA64ISAR2_EL1_RPRFM_IMP, CAP_HWCAP, KERNEL_HWCAP_RPRFM), 2887 - HWCAP_CAP(SYS_ID_AA64ISAR2_EL1, ID_AA64ISAR2_EL1_RPRES_SHIFT, 4, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_RPRES), 2888 - HWCAP_CAP(SYS_ID_AA64ISAR2_EL1, ID_AA64ISAR2_EL1_WFxT_SHIFT, 4, FTR_UNSIGNED, ID_AA64ISAR2_EL1_WFxT_IMP, CAP_HWCAP, KERNEL_HWCAP_WFXT), 2814 + HWCAP_CAP(ID_AA64MMFR0_EL1, ECV, IMP, CAP_HWCAP, KERNEL_HWCAP_ECV), 2815 + HWCAP_CAP(ID_AA64MMFR1_EL1, AFP, IMP, CAP_HWCAP, KERNEL_HWCAP_AFP), 2816 + HWCAP_CAP(ID_AA64ISAR2_EL1, CSSC, IMP, CAP_HWCAP, KERNEL_HWCAP_CSSC), 2817 + HWCAP_CAP(ID_AA64ISAR2_EL1, RPRFM, IMP, CAP_HWCAP, KERNEL_HWCAP_RPRFM), 2818 + HWCAP_CAP(ID_AA64ISAR2_EL1, RPRES, IMP, CAP_HWCAP, KERNEL_HWCAP_RPRES), 2819 + HWCAP_CAP(ID_AA64ISAR2_EL1, WFxT, IMP, CAP_HWCAP, KERNEL_HWCAP_WFXT), 2889 2820 #ifdef CONFIG_ARM64_SME 2890 - HWCAP_CAP(SYS_ID_AA64PFR1_EL1, ID_AA64PFR1_EL1_SME_SHIFT, 4, FTR_UNSIGNED, ID_AA64PFR1_EL1_SME_IMP, CAP_HWCAP, KERNEL_HWCAP_SME), 2891 - HWCAP_CAP(SYS_ID_AA64SMFR0_EL1, ID_AA64SMFR0_EL1_FA64_SHIFT, 1, FTR_UNSIGNED, ID_AA64SMFR0_EL1_FA64_IMP, CAP_HWCAP, KERNEL_HWCAP_SME_FA64), 2892 - HWCAP_CAP(SYS_ID_AA64SMFR0_EL1, ID_AA64SMFR0_EL1_I16I64_SHIFT, 4, FTR_UNSIGNED, ID_AA64SMFR0_EL1_I16I64_IMP, CAP_HWCAP, KERNEL_HWCAP_SME_I16I64), 2893 - HWCAP_CAP(SYS_ID_AA64SMFR0_EL1, ID_AA64SMFR0_EL1_F64F64_SHIFT, 1, FTR_UNSIGNED, ID_AA64SMFR0_EL1_F64F64_IMP, CAP_HWCAP, KERNEL_HWCAP_SME_F64F64), 2894 - HWCAP_CAP(SYS_ID_AA64SMFR0_EL1, ID_AA64SMFR0_EL1_I8I32_SHIFT, 4, FTR_UNSIGNED, ID_AA64SMFR0_EL1_I8I32_IMP, CAP_HWCAP, KERNEL_HWCAP_SME_I8I32), 2895 - HWCAP_CAP(SYS_ID_AA64SMFR0_EL1, ID_AA64SMFR0_EL1_F16F32_SHIFT, 1, FTR_UNSIGNED, ID_AA64SMFR0_EL1_F16F32_IMP, CAP_HWCAP, KERNEL_HWCAP_SME_F16F32), 2896 - HWCAP_CAP(SYS_ID_AA64SMFR0_EL1, ID_AA64SMFR0_EL1_B16F32_SHIFT, 1, FTR_UNSIGNED, ID_AA64SMFR0_EL1_B16F32_IMP, CAP_HWCAP, KERNEL_HWCAP_SME_B16F32), 2897 - HWCAP_CAP(SYS_ID_AA64SMFR0_EL1, ID_AA64SMFR0_EL1_F32F32_SHIFT, 1, FTR_UNSIGNED, ID_AA64SMFR0_EL1_F32F32_IMP, CAP_HWCAP, KERNEL_HWCAP_SME_F32F32), 2821 + HWCAP_CAP(ID_AA64PFR1_EL1, SME, IMP, CAP_HWCAP, KERNEL_HWCAP_SME), 2822 + HWCAP_CAP(ID_AA64SMFR0_EL1, FA64, IMP, CAP_HWCAP, KERNEL_HWCAP_SME_FA64), 2823 + HWCAP_CAP(ID_AA64SMFR0_EL1, SMEver, SME2p1, CAP_HWCAP, KERNEL_HWCAP_SME2P1), 2824 + HWCAP_CAP(ID_AA64SMFR0_EL1, SMEver, SME2, CAP_HWCAP, KERNEL_HWCAP_SME2), 2825 + HWCAP_CAP(ID_AA64SMFR0_EL1, I16I64, IMP, CAP_HWCAP, KERNEL_HWCAP_SME_I16I64), 2826 + HWCAP_CAP(ID_AA64SMFR0_EL1, F64F64, IMP, CAP_HWCAP, KERNEL_HWCAP_SME_F64F64), 2827 + HWCAP_CAP(ID_AA64SMFR0_EL1, I16I32, IMP, CAP_HWCAP, KERNEL_HWCAP_SME_I16I32), 2828 + HWCAP_CAP(ID_AA64SMFR0_EL1, B16B16, IMP, CAP_HWCAP, KERNEL_HWCAP_SME_B16B16), 2829 + HWCAP_CAP(ID_AA64SMFR0_EL1, F16F16, IMP, CAP_HWCAP, KERNEL_HWCAP_SME_F16F16), 2830 + HWCAP_CAP(ID_AA64SMFR0_EL1, I8I32, IMP, CAP_HWCAP, KERNEL_HWCAP_SME_I8I32), 2831 + HWCAP_CAP(ID_AA64SMFR0_EL1, F16F32, IMP, CAP_HWCAP, KERNEL_HWCAP_SME_F16F32), 2832 + HWCAP_CAP(ID_AA64SMFR0_EL1, B16F32, IMP, CAP_HWCAP, KERNEL_HWCAP_SME_B16F32), 2833 + HWCAP_CAP(ID_AA64SMFR0_EL1, BI32I32, IMP, CAP_HWCAP, KERNEL_HWCAP_SME_BI32I32), 2834 + HWCAP_CAP(ID_AA64SMFR0_EL1, F32F32, IMP, CAP_HWCAP, KERNEL_HWCAP_SME_F32F32), 2898 2835 #endif /* CONFIG_ARM64_SME */ 2899 2836 {}, 2900 2837 }; ··· 2923 2862 static const struct arm64_cpu_capabilities compat_elf_hwcaps[] = { 2924 2863 #ifdef CONFIG_COMPAT 2925 2864 HWCAP_CAP_MATCH(compat_has_neon, CAP_COMPAT_HWCAP, COMPAT_HWCAP_NEON), 2926 - HWCAP_CAP(SYS_MVFR1_EL1, MVFR1_EL1_SIMDFMAC_SHIFT, 4, FTR_UNSIGNED, 1, CAP_COMPAT_HWCAP, COMPAT_HWCAP_VFPv4), 2865 + HWCAP_CAP(MVFR1_EL1, SIMDFMAC, IMP, CAP_COMPAT_HWCAP, COMPAT_HWCAP_VFPv4), 2927 2866 /* Arm v8 mandates MVFR0.FPDP == {0, 2}. So, piggy back on this for the presence of VFP support */ 2928 - HWCAP_CAP(SYS_MVFR0_EL1, MVFR0_EL1_FPDP_SHIFT, 4, FTR_UNSIGNED, 2, CAP_COMPAT_HWCAP, COMPAT_HWCAP_VFP), 2929 - HWCAP_CAP(SYS_MVFR0_EL1, MVFR0_EL1_FPDP_SHIFT, 4, FTR_UNSIGNED, 2, CAP_COMPAT_HWCAP, COMPAT_HWCAP_VFPv3), 2930 - HWCAP_CAP(SYS_ID_ISAR5_EL1, ID_ISAR5_EL1_AES_SHIFT, 4, FTR_UNSIGNED, 2, CAP_COMPAT_HWCAP2, COMPAT_HWCAP2_PMULL), 2931 - HWCAP_CAP(SYS_ID_ISAR5_EL1, ID_ISAR5_EL1_AES_SHIFT, 4, FTR_UNSIGNED, 1, CAP_COMPAT_HWCAP2, COMPAT_HWCAP2_AES), 2932 - HWCAP_CAP(SYS_ID_ISAR5_EL1, ID_ISAR5_EL1_SHA1_SHIFT, 4, FTR_UNSIGNED, 1, CAP_COMPAT_HWCAP2, COMPAT_HWCAP2_SHA1), 2933 - HWCAP_CAP(SYS_ID_ISAR5_EL1, ID_ISAR5_EL1_SHA2_SHIFT, 4, FTR_UNSIGNED, 1, CAP_COMPAT_HWCAP2, COMPAT_HWCAP2_SHA2), 2934 - HWCAP_CAP(SYS_ID_ISAR5_EL1, ID_ISAR5_EL1_CRC32_SHIFT, 4, FTR_UNSIGNED, 1, CAP_COMPAT_HWCAP2, COMPAT_HWCAP2_CRC32), 2867 + HWCAP_CAP(MVFR0_EL1, FPDP, VFPv3, CAP_COMPAT_HWCAP, COMPAT_HWCAP_VFP), 2868 + HWCAP_CAP(MVFR0_EL1, FPDP, VFPv3, CAP_COMPAT_HWCAP, COMPAT_HWCAP_VFPv3), 2869 + HWCAP_CAP(MVFR1_EL1, FPHP, FP16, CAP_COMPAT_HWCAP, COMPAT_HWCAP_FPHP), 2870 + HWCAP_CAP(MVFR1_EL1, SIMDHP, SIMDHP_FLOAT, CAP_COMPAT_HWCAP, COMPAT_HWCAP_ASIMDHP), 2871 + HWCAP_CAP(ID_ISAR5_EL1, AES, VMULL, CAP_COMPAT_HWCAP2, COMPAT_HWCAP2_PMULL), 2872 + HWCAP_CAP(ID_ISAR5_EL1, AES, IMP, CAP_COMPAT_HWCAP2, COMPAT_HWCAP2_AES), 2873 + HWCAP_CAP(ID_ISAR5_EL1, SHA1, IMP, CAP_COMPAT_HWCAP2, COMPAT_HWCAP2_SHA1), 2874 + HWCAP_CAP(ID_ISAR5_EL1, SHA2, IMP, CAP_COMPAT_HWCAP2, COMPAT_HWCAP2_SHA2), 2875 + HWCAP_CAP(ID_ISAR5_EL1, CRC32, IMP, CAP_COMPAT_HWCAP2, COMPAT_HWCAP2_CRC32), 2876 + HWCAP_CAP(ID_ISAR6_EL1, DP, IMP, CAP_COMPAT_HWCAP, COMPAT_HWCAP_ASIMDDP), 2877 + HWCAP_CAP(ID_ISAR6_EL1, FHM, IMP, CAP_COMPAT_HWCAP, COMPAT_HWCAP_ASIMDFHM), 2878 + HWCAP_CAP(ID_ISAR6_EL1, SB, IMP, CAP_COMPAT_HWCAP2, COMPAT_HWCAP2_SB), 2879 + HWCAP_CAP(ID_ISAR6_EL1, BF16, IMP, CAP_COMPAT_HWCAP, COMPAT_HWCAP_ASIMDBF16), 2880 + HWCAP_CAP(ID_ISAR6_EL1, I8MM, IMP, CAP_COMPAT_HWCAP, COMPAT_HWCAP_I8MM), 2881 + HWCAP_CAP(ID_PFR2_EL1, SSBS, IMP, CAP_COMPAT_HWCAP2, COMPAT_HWCAP2_SSBS), 2935 2882 #endif 2936 2883 {}, 2937 2884 };
+14
arch/arm64/kernel/cpuinfo.c
··· 119 119 [KERNEL_HWCAP_CSSC] = "cssc", 120 120 [KERNEL_HWCAP_RPRFM] = "rprfm", 121 121 [KERNEL_HWCAP_SVE2P1] = "sve2p1", 122 + [KERNEL_HWCAP_SME2] = "sme2", 123 + [KERNEL_HWCAP_SME2P1] = "sme2p1", 124 + [KERNEL_HWCAP_SME_I16I32] = "smei16i32", 125 + [KERNEL_HWCAP_SME_BI32I32] = "smebi32i32", 126 + [KERNEL_HWCAP_SME_B16B16] = "smeb16b16", 127 + [KERNEL_HWCAP_SME_F16F16] = "smef16f16", 122 128 }; 123 129 124 130 #ifdef CONFIG_COMPAT ··· 152 146 [COMPAT_KERNEL_HWCAP(VFPD32)] = NULL, /* Not possible on arm64 */ 153 147 [COMPAT_KERNEL_HWCAP(LPAE)] = "lpae", 154 148 [COMPAT_KERNEL_HWCAP(EVTSTRM)] = "evtstrm", 149 + [COMPAT_KERNEL_HWCAP(FPHP)] = "fphp", 150 + [COMPAT_KERNEL_HWCAP(ASIMDHP)] = "asimdhp", 151 + [COMPAT_KERNEL_HWCAP(ASIMDDP)] = "asimddp", 152 + [COMPAT_KERNEL_HWCAP(ASIMDFHM)] = "asimdfhm", 153 + [COMPAT_KERNEL_HWCAP(ASIMDBF16)] = "asimdbf16", 154 + [COMPAT_KERNEL_HWCAP(I8MM)] = "i8mm", 155 155 }; 156 156 157 157 #define COMPAT_KERNEL_HWCAP2(x) const_ilog2(COMPAT_HWCAP2_ ## x) ··· 167 155 [COMPAT_KERNEL_HWCAP2(SHA1)] = "sha1", 168 156 [COMPAT_KERNEL_HWCAP2(SHA2)] = "sha2", 169 157 [COMPAT_KERNEL_HWCAP2(CRC32)] = "crc32", 158 + [COMPAT_KERNEL_HWCAP2(SB)] = "sb", 159 + [COMPAT_KERNEL_HWCAP2(SSBS)] = "ssbs", 170 160 }; 171 161 #endif /* CONFIG_COMPAT */ 172 162
+20 -10
arch/arm64/kernel/entry-fpsimd.S
··· 100 100 SYM_FUNC_END(sme_set_vq) 101 101 102 102 /* 103 - * Save the SME state 103 + * Save the ZA and ZT state 104 104 * 105 105 * x0 - pointer to buffer for state 106 + * x1 - number of ZT registers to save 106 107 */ 107 - SYM_FUNC_START(za_save_state) 108 - _sme_rdsvl 1, 1 // x1 = VL/8 109 - sme_save_za 0, x1, 12 108 + SYM_FUNC_START(sme_save_state) 109 + _sme_rdsvl 2, 1 // x2 = VL/8 110 + sme_save_za 0, x2, 12 // Leaves x0 pointing to the end of ZA 111 + 112 + cbz x1, 1f 113 + _str_zt 0 114 + 1: 110 115 ret 111 - SYM_FUNC_END(za_save_state) 116 + SYM_FUNC_END(sme_save_state) 112 117 113 118 /* 114 - * Load the SME state 119 + * Load the ZA and ZT state 115 120 * 116 121 * x0 - pointer to buffer for state 122 + * x1 - number of ZT registers to save 117 123 */ 118 - SYM_FUNC_START(za_load_state) 119 - _sme_rdsvl 1, 1 // x1 = VL/8 120 - sme_load_za 0, x1, 12 124 + SYM_FUNC_START(sme_load_state) 125 + _sme_rdsvl 2, 1 // x2 = VL/8 126 + sme_load_za 0, x2, 12 // Leaves x0 pointing to the end of ZA 127 + 128 + cbz x1, 1f 129 + _ldr_zt 0 130 + 1: 121 131 ret 122 - SYM_FUNC_END(za_load_state) 132 + SYM_FUNC_END(sme_load_state) 123 133 124 134 #endif /* CONFIG_ARM64_SME */
+27 -5
arch/arm64/kernel/entry-ftrace.S
··· 65 65 stp x29, x30, [sp, #FREGS_SIZE] 66 66 add x29, sp, #FREGS_SIZE 67 67 68 - sub x0, x30, #AARCH64_INSN_SIZE // ip (callsite's BL insn) 69 - mov x1, x9 // parent_ip (callsite's LR) 70 - ldr_l x2, function_trace_op // op 71 - mov x3, sp // regs 68 + /* Prepare arguments for the the tracer func */ 69 + sub x0, x30, #AARCH64_INSN_SIZE // ip (callsite's BL insn) 70 + mov x1, x9 // parent_ip (callsite's LR) 71 + mov x3, sp // regs 72 + 73 + #ifdef CONFIG_DYNAMIC_FTRACE_WITH_CALL_OPS 74 + /* 75 + * The literal pointer to the ops is at an 8-byte aligned boundary 76 + * which is either 12 or 16 bytes before the BL instruction in the call 77 + * site. See ftrace_call_adjust() for details. 78 + * 79 + * Therefore here the LR points at `literal + 16` or `literal + 20`, 80 + * and we can find the address of the literal in either case by 81 + * aligning to an 8-byte boundary and subtracting 16. We do the 82 + * alignment first as this allows us to fold the subtraction into the 83 + * LDR. 84 + */ 85 + bic x2, x30, 0x7 86 + ldr x2, [x2, #-16] // op 87 + 88 + ldr x4, [x2, #FTRACE_OPS_FUNC] // op->func 89 + blr x4 // op->func(ip, parent_ip, op, regs) 90 + 91 + #else 92 + ldr_l x2, function_trace_op // op 72 93 73 94 SYM_INNER_LABEL(ftrace_call, SYM_L_GLOBAL) 74 - bl ftrace_stub 95 + bl ftrace_stub // func(ip, parent_ip, op, regs) 96 + #endif 75 97 76 98 /* 77 99 * At the callsite x0-x8 and x19-x30 were live. Any C code will have preserved
+23 -18
arch/arm64/kernel/entry.S
··· 275 275 alternative_else_nop_endif 276 276 1: 277 277 278 - scs_load tsk 278 + scs_load_current 279 279 .else 280 280 add x21, sp, #PT_REGS_SIZE 281 281 get_current_task tsk ··· 311 311 .endif 312 312 313 313 #ifdef CONFIG_ARM64_PSEUDO_NMI 314 - /* Save pmr */ 315 - alternative_if ARM64_HAS_IRQ_PRIO_MASKING 314 + alternative_if_not ARM64_HAS_GIC_PRIO_MASKING 315 + b .Lskip_pmr_save\@ 316 + alternative_else_nop_endif 317 + 316 318 mrs_s x20, SYS_ICC_PMR_EL1 317 319 str x20, [sp, #S_PMR_SAVE] 318 320 mov x20, #GIC_PRIO_IRQON | GIC_PRIO_PSR_I_SET 319 321 msr_s SYS_ICC_PMR_EL1, x20 320 - alternative_else_nop_endif 322 + 323 + .Lskip_pmr_save\@: 321 324 #endif 322 325 323 326 /* ··· 339 336 .endif 340 337 341 338 #ifdef CONFIG_ARM64_PSEUDO_NMI 342 - /* Restore pmr */ 343 - alternative_if ARM64_HAS_IRQ_PRIO_MASKING 339 + alternative_if_not ARM64_HAS_GIC_PRIO_MASKING 340 + b .Lskip_pmr_restore\@ 341 + alternative_else_nop_endif 342 + 344 343 ldr x20, [sp, #S_PMR_SAVE] 345 344 msr_s SYS_ICC_PMR_EL1, x20 346 - mrs_s x21, SYS_ICC_CTLR_EL1 347 - tbz x21, #6, .L__skip_pmr_sync\@ // Check for ICC_CTLR_EL1.PMHE 348 - dsb sy // Ensure priority change is seen by redistributor 349 - .L__skip_pmr_sync\@: 345 + 346 + /* Ensure priority change is seen by redistributor */ 347 + alternative_if_not ARM64_HAS_GIC_PRIO_RELAXED_SYNC 348 + dsb sy 350 349 alternative_else_nop_endif 350 + 351 + .Lskip_pmr_restore\@: 351 352 #endif 352 353 353 354 ldp x21, x22, [sp, #S_PC] // load ELR, SPSR ··· 855 848 msr sp_el0, x1 856 849 ptrauth_keys_install_kernel x1, x8, x9, x10 857 850 scs_save x0 858 - scs_load x1 851 + scs_load_current 859 852 ret 860 853 SYM_FUNC_END(cpu_switch_to) 861 854 NOKPROBE(cpu_switch_to) ··· 883 876 */ 884 877 SYM_FUNC_START(call_on_irq_stack) 885 878 #ifdef CONFIG_SHADOW_CALL_STACK 886 - stp scs_sp, xzr, [sp, #-16]! 879 + get_current_task x16 880 + scs_save x16 887 881 ldr_this_cpu scs_sp, irq_shadow_call_stack_ptr, x17 888 882 #endif 883 + 889 884 /* Create a frame record to save our LR and SP (implicit in FP) */ 890 885 stp x29, x30, [sp, #-16]! 891 886 mov x29, sp 892 887 893 888 ldr_this_cpu x16, irq_stack_ptr, x17 894 - mov x15, #IRQ_STACK_SIZE 895 - add x16, x16, x15 896 889 897 890 /* Move to the new stack and call the function there */ 898 - mov sp, x16 891 + add sp, x16, #IRQ_STACK_SIZE 899 892 blr x1 900 893 901 894 /* ··· 904 897 */ 905 898 mov sp, x29 906 899 ldp x29, x30, [sp], #16 907 - #ifdef CONFIG_SHADOW_CALL_STACK 908 - ldp scs_sp, xzr, [sp], #16 909 - #endif 900 + scs_load_current 910 901 ret 911 902 SYM_FUNC_END(call_on_irq_stack) 912 903 NOKPROBE(call_on_irq_stack)
+31 -21
arch/arm64/kernel/fpsimd.c
··· 299 299 /* 300 300 * TIF_SME controls whether a task can use SME without trapping while 301 301 * in userspace, when TIF_SME is set then we must have storage 302 - * alocated in sve_state and za_state to store the contents of both ZA 302 + * alocated in sve_state and sme_state to store the contents of both ZA 303 303 * and the SVE registers for both streaming and non-streaming modes. 304 304 * 305 305 * If both SVCR.ZA and SVCR.SM are disabled then at any point we ··· 429 429 write_sysreg_s(current->thread.svcr, SYS_SVCR); 430 430 431 431 if (thread_za_enabled(&current->thread)) 432 - za_load_state(current->thread.za_state); 432 + sme_load_state(current->thread.sme_state, 433 + system_supports_sme2()); 433 434 434 435 if (thread_sm_enabled(&current->thread)) 435 436 restore_ffr = system_supports_fa64(); ··· 491 490 *svcr = read_sysreg_s(SYS_SVCR); 492 491 493 492 if (*svcr & SVCR_ZA_MASK) 494 - za_save_state(last->za_state); 493 + sme_save_state(last->sme_state, 494 + system_supports_sme2()); 495 495 496 496 /* If we are in streaming mode override regular SVE. */ 497 497 if (*svcr & SVCR_SM_MASK) { ··· 1259 1257 #ifdef CONFIG_ARM64_SME 1260 1258 1261 1259 /* 1262 - * Ensure that task->thread.za_state is allocated and sufficiently large. 1260 + * Ensure that task->thread.sme_state is allocated and sufficiently large. 1263 1261 * 1264 1262 * This function should be used only in preparation for replacing 1265 - * task->thread.za_state with new data. The memory is always zeroed 1263 + * task->thread.sme_state with new data. The memory is always zeroed 1266 1264 * here to prevent stale data from showing through: this is done in 1267 1265 * the interest of testability and predictability, the architecture 1268 1266 * guarantees that when ZA is enabled it will be zeroed. 1269 1267 */ 1270 1268 void sme_alloc(struct task_struct *task) 1271 1269 { 1272 - if (task->thread.za_state) { 1273 - memset(task->thread.za_state, 0, za_state_size(task)); 1270 + if (task->thread.sme_state) { 1271 + memset(task->thread.sme_state, 0, sme_state_size(task)); 1274 1272 return; 1275 1273 } 1276 1274 1277 1275 /* This could potentially be up to 64K. */ 1278 - task->thread.za_state = 1279 - kzalloc(za_state_size(task), GFP_KERNEL); 1276 + task->thread.sme_state = 1277 + kzalloc(sme_state_size(task), GFP_KERNEL); 1280 1278 } 1281 1279 1282 1280 static void sme_free(struct task_struct *task) 1283 1281 { 1284 - kfree(task->thread.za_state); 1285 - task->thread.za_state = NULL; 1282 + kfree(task->thread.sme_state); 1283 + task->thread.sme_state = NULL; 1286 1284 } 1287 1285 1288 1286 void sme_kernel_enable(const struct arm64_cpu_capabilities *__always_unused p) ··· 1298 1296 /* Allow EL0 to access TPIDR2 */ 1299 1297 write_sysreg(read_sysreg(SCTLR_EL1) | SCTLR_ELx_ENTP2, SCTLR_EL1); 1300 1298 isb(); 1299 + } 1300 + 1301 + /* 1302 + * This must be called after sme_kernel_enable(), we rely on the 1303 + * feature table being sorted to ensure this. 1304 + */ 1305 + void sme2_kernel_enable(const struct arm64_cpu_capabilities *__always_unused p) 1306 + { 1307 + /* Allow use of ZT0 */ 1308 + write_sysreg_s(read_sysreg_s(SYS_SMCR_EL1) | SMCR_ELx_EZT0_MASK, 1309 + SYS_SMCR_EL1); 1301 1310 } 1302 1311 1303 1312 /* ··· 1335 1322 unsigned int vq_max; 1336 1323 1337 1324 sme_kernel_enable(NULL); 1338 - sme_smstart_sm(); 1339 1325 1340 1326 /* 1341 1327 * Set the maximum possible VL. ··· 1344 1332 1345 1333 smcr = read_sysreg_s(SYS_SMCR_EL1); 1346 1334 smcr &= ~(u64)SMCR_ELx_LEN_MASK; /* Only the LEN field */ 1347 - vq_max = sve_vq_from_vl(sve_get_vl()); 1335 + vq_max = sve_vq_from_vl(sme_get_vl()); 1348 1336 smcr |= vq_max - 1; /* set LEN field to maximum effective value */ 1349 - 1350 - sme_smstop_sm(); 1351 1337 1352 1338 return smcr; 1353 1339 } ··· 1498 1488 1499 1489 sve_alloc(current, false); 1500 1490 sme_alloc(current); 1501 - if (!current->thread.sve_state || !current->thread.za_state) { 1491 + if (!current->thread.sve_state || !current->thread.sme_state) { 1502 1492 force_sig(SIGKILL); 1503 1493 return; 1504 1494 } ··· 1619 1609 void fpsimd_flush_thread(void) 1620 1610 { 1621 1611 void *sve_state = NULL; 1622 - void *za_state = NULL; 1612 + void *sme_state = NULL; 1623 1613 1624 1614 if (!system_supports_fpsimd()) 1625 1615 return; ··· 1644 1634 clear_thread_flag(TIF_SME); 1645 1635 1646 1636 /* Defer kfree() while in atomic context */ 1647 - za_state = current->thread.za_state; 1648 - current->thread.za_state = NULL; 1637 + sme_state = current->thread.sme_state; 1638 + current->thread.sme_state = NULL; 1649 1639 1650 1640 fpsimd_flush_thread_vl(ARM64_VEC_SME); 1651 1641 current->thread.svcr = 0; ··· 1655 1645 1656 1646 put_cpu_fpsimd_context(); 1657 1647 kfree(sve_state); 1658 - kfree(za_state); 1648 + kfree(sme_state); 1659 1649 } 1660 1650 1661 1651 /* ··· 1721 1711 WARN_ON(!system_supports_fpsimd()); 1722 1712 last->st = &current->thread.uw.fpsimd_state; 1723 1713 last->sve_state = current->thread.sve_state; 1724 - last->za_state = current->thread.za_state; 1714 + last->sme_state = current->thread.sme_state; 1725 1715 last->sve_vl = task_get_sve_vl(current); 1726 1716 last->sme_vl = task_get_sme_vl(current); 1727 1717 last->svcr = &current->thread.svcr;
+157 -1
arch/arm64/kernel/ftrace.c
··· 60 60 } 61 61 #endif 62 62 63 + unsigned long ftrace_call_adjust(unsigned long addr) 64 + { 65 + /* 66 + * When using mcount, addr is the address of the mcount call 67 + * instruction, and no adjustment is necessary. 68 + */ 69 + if (!IS_ENABLED(CONFIG_DYNAMIC_FTRACE_WITH_ARGS)) 70 + return addr; 71 + 72 + /* 73 + * When using patchable-function-entry without pre-function NOPS, addr 74 + * is the address of the first NOP after the function entry point. 75 + * 76 + * The compiler has either generated: 77 + * 78 + * addr+00: func: NOP // To be patched to MOV X9, LR 79 + * addr+04: NOP // To be patched to BL <caller> 80 + * 81 + * Or: 82 + * 83 + * addr-04: BTI C 84 + * addr+00: func: NOP // To be patched to MOV X9, LR 85 + * addr+04: NOP // To be patched to BL <caller> 86 + * 87 + * We must adjust addr to the address of the NOP which will be patched 88 + * to `BL <caller>`, which is at `addr + 4` bytes in either case. 89 + * 90 + */ 91 + if (!IS_ENABLED(CONFIG_DYNAMIC_FTRACE_WITH_CALL_OPS)) 92 + return addr + AARCH64_INSN_SIZE; 93 + 94 + /* 95 + * When using patchable-function-entry with pre-function NOPs, addr is 96 + * the address of the first pre-function NOP. 97 + * 98 + * Starting from an 8-byte aligned base, the compiler has either 99 + * generated: 100 + * 101 + * addr+00: NOP // Literal (first 32 bits) 102 + * addr+04: NOP // Literal (last 32 bits) 103 + * addr+08: func: NOP // To be patched to MOV X9, LR 104 + * addr+12: NOP // To be patched to BL <caller> 105 + * 106 + * Or: 107 + * 108 + * addr+00: NOP // Literal (first 32 bits) 109 + * addr+04: NOP // Literal (last 32 bits) 110 + * addr+08: func: BTI C 111 + * addr+12: NOP // To be patched to MOV X9, LR 112 + * addr+16: NOP // To be patched to BL <caller> 113 + * 114 + * We must adjust addr to the address of the NOP which will be patched 115 + * to `BL <caller>`, which is at either addr+12 or addr+16 depending on 116 + * whether there is a BTI. 117 + */ 118 + 119 + if (!IS_ALIGNED(addr, sizeof(unsigned long))) { 120 + WARN_RATELIMIT(1, "Misaligned patch-site %pS\n", 121 + (void *)(addr + 8)); 122 + return 0; 123 + } 124 + 125 + /* Skip the NOPs placed before the function entry point */ 126 + addr += 2 * AARCH64_INSN_SIZE; 127 + 128 + /* Skip any BTI */ 129 + if (IS_ENABLED(CONFIG_ARM64_BTI_KERNEL)) { 130 + u32 insn = le32_to_cpu(*(__le32 *)addr); 131 + 132 + if (aarch64_insn_is_bti(insn)) { 133 + addr += AARCH64_INSN_SIZE; 134 + } else if (insn != aarch64_insn_gen_nop()) { 135 + WARN_RATELIMIT(1, "unexpected insn in patch-site %pS: 0x%08x\n", 136 + (void *)addr, insn); 137 + } 138 + } 139 + 140 + /* Skip the first NOP after function entry */ 141 + addr += AARCH64_INSN_SIZE; 142 + 143 + return addr; 144 + } 145 + 63 146 /* 64 147 * Replace a single instruction, which may be a branch or NOP. 65 148 * If @validate == true, a replaced instruction is checked against 'old'. ··· 180 97 { 181 98 unsigned long pc; 182 99 u32 new; 100 + 101 + /* 102 + * When using CALL_OPS, the function to call is associated with the 103 + * call site, and we don't have a global function pointer to update. 104 + */ 105 + if (IS_ENABLED(CONFIG_DYNAMIC_FTRACE_WITH_CALL_OPS)) 106 + return 0; 183 107 184 108 pc = (unsigned long)ftrace_call; 185 109 new = aarch64_insn_gen_branch_imm(pc, (unsigned long)func, ··· 266 176 return true; 267 177 } 268 178 179 + #ifdef CONFIG_DYNAMIC_FTRACE_WITH_CALL_OPS 180 + static const struct ftrace_ops *arm64_rec_get_ops(struct dyn_ftrace *rec) 181 + { 182 + const struct ftrace_ops *ops = NULL; 183 + 184 + if (rec->flags & FTRACE_FL_CALL_OPS_EN) { 185 + ops = ftrace_find_unique_ops(rec); 186 + WARN_ON_ONCE(!ops); 187 + } 188 + 189 + if (!ops) 190 + ops = &ftrace_list_ops; 191 + 192 + return ops; 193 + } 194 + 195 + static int ftrace_rec_set_ops(const struct dyn_ftrace *rec, 196 + const struct ftrace_ops *ops) 197 + { 198 + unsigned long literal = ALIGN_DOWN(rec->ip - 12, 8); 199 + return aarch64_insn_write_literal_u64((void *)literal, 200 + (unsigned long)ops); 201 + } 202 + 203 + static int ftrace_rec_set_nop_ops(struct dyn_ftrace *rec) 204 + { 205 + return ftrace_rec_set_ops(rec, &ftrace_nop_ops); 206 + } 207 + 208 + static int ftrace_rec_update_ops(struct dyn_ftrace *rec) 209 + { 210 + return ftrace_rec_set_ops(rec, arm64_rec_get_ops(rec)); 211 + } 212 + #else 213 + static int ftrace_rec_set_nop_ops(struct dyn_ftrace *rec) { return 0; } 214 + static int ftrace_rec_update_ops(struct dyn_ftrace *rec) { return 0; } 215 + #endif 216 + 269 217 /* 270 218 * Turn on the call to ftrace_caller() in instrumented function 271 219 */ ··· 311 183 { 312 184 unsigned long pc = rec->ip; 313 185 u32 old, new; 186 + int ret; 187 + 188 + ret = ftrace_rec_update_ops(rec); 189 + if (ret) 190 + return ret; 314 191 315 192 if (!ftrace_find_callable_addr(rec, NULL, &addr)) 316 193 return -EINVAL; ··· 325 192 326 193 return ftrace_modify_code(pc, old, new, true); 327 194 } 195 + 196 + #ifdef CONFIG_DYNAMIC_FTRACE_WITH_CALL_OPS 197 + int ftrace_modify_call(struct dyn_ftrace *rec, unsigned long old_addr, 198 + unsigned long addr) 199 + { 200 + if (WARN_ON_ONCE(old_addr != (unsigned long)ftrace_caller)) 201 + return -EINVAL; 202 + if (WARN_ON_ONCE(addr != (unsigned long)ftrace_caller)) 203 + return -EINVAL; 204 + 205 + return ftrace_rec_update_ops(rec); 206 + } 207 + #endif 328 208 329 209 #ifdef CONFIG_DYNAMIC_FTRACE_WITH_ARGS 330 210 /* ··· 355 209 * | NOP | MOV X9, LR | MOV X9, LR | 356 210 * | NOP | NOP | BL <entry> | 357 211 * 358 - * The LR value will be recovered by ftrace_regs_entry, and restored into LR 212 + * The LR value will be recovered by ftrace_caller, and restored into LR 359 213 * before returning to the regular function prologue. When a function is not 360 214 * being traced, the MOV is not harmful given x9 is not live per the AAPCS. 361 215 * ··· 366 220 { 367 221 unsigned long pc = rec->ip - AARCH64_INSN_SIZE; 368 222 u32 old, new; 223 + int ret; 224 + 225 + ret = ftrace_rec_set_nop_ops(rec); 226 + if (ret) 227 + return ret; 369 228 370 229 old = aarch64_insn_gen_nop(); 371 230 new = aarch64_insn_gen_move_reg(AARCH64_INSN_REG_9, ··· 388 237 { 389 238 unsigned long pc = rec->ip; 390 239 u32 old = 0, new; 240 + int ret; 391 241 392 242 new = aarch64_insn_gen_nop(); 243 + 244 + ret = ftrace_rec_set_nop_ops(rec); 245 + if (ret) 246 + return ret; 393 247 394 248 /* 395 249 * When using mcount, callsites in modules may have been initalized to
+94 -22
arch/arm64/kernel/head.S
··· 70 70 71 71 __EFI_PE_HEADER 72 72 73 - __INIT 73 + .section ".idmap.text","a" 74 74 75 75 /* 76 76 * The following callee saved general purpose registers are used on the 77 77 * primary lowlevel boot path: 78 78 * 79 79 * Register Scope Purpose 80 + * x19 primary_entry() .. start_kernel() whether we entered with the MMU on 80 81 * x20 primary_entry() .. __primary_switch() CPU boot mode 81 82 * x21 primary_entry() .. start_kernel() FDT pointer passed at boot in x0 82 83 * x22 create_idmap() .. start_kernel() ID map VA of the DT blob ··· 87 86 * x28 create_idmap() callee preserved temp register 88 87 */ 89 88 SYM_CODE_START(primary_entry) 89 + bl record_mmu_state 90 90 bl preserve_boot_args 91 + bl create_idmap 92 + 93 + /* 94 + * If we entered with the MMU and caches on, clean the ID mapped part 95 + * of the primary boot code to the PoC so we can safely execute it with 96 + * the MMU off. 97 + */ 98 + cbz x19, 0f 99 + adrp x0, __idmap_text_start 100 + adr_l x1, __idmap_text_end 101 + adr_l x2, dcache_clean_poc 102 + blr x2 103 + 0: mov x0, x19 91 104 bl init_kernel_el // w0=cpu_boot_mode 92 105 mov x20, x0 93 - bl create_idmap 94 106 95 107 /* 96 108 * The following calls CPU setup code, see arch/arm64/mm/proc.S for ··· 123 109 b __primary_switch 124 110 SYM_CODE_END(primary_entry) 125 111 112 + __INIT 113 + SYM_CODE_START_LOCAL(record_mmu_state) 114 + mrs x19, CurrentEL 115 + cmp x19, #CurrentEL_EL2 116 + mrs x19, sctlr_el1 117 + b.ne 0f 118 + mrs x19, sctlr_el2 119 + 0: 120 + CPU_LE( tbnz x19, #SCTLR_ELx_EE_SHIFT, 1f ) 121 + CPU_BE( tbz x19, #SCTLR_ELx_EE_SHIFT, 1f ) 122 + tst x19, #SCTLR_ELx_C // Z := (C == 0) 123 + and x19, x19, #SCTLR_ELx_M // isolate M bit 124 + csel x19, xzr, x19, eq // clear x19 if Z 125 + ret 126 + 127 + /* 128 + * Set the correct endianness early so all memory accesses issued 129 + * before init_kernel_el() occur in the correct byte order. Note that 130 + * this means the MMU must be disabled, or the active ID map will end 131 + * up getting interpreted with the wrong byte order. 132 + */ 133 + 1: eor x19, x19, #SCTLR_ELx_EE 134 + bic x19, x19, #SCTLR_ELx_M 135 + b.ne 2f 136 + pre_disable_mmu_workaround 137 + msr sctlr_el2, x19 138 + b 3f 139 + pre_disable_mmu_workaround 140 + 2: msr sctlr_el1, x19 141 + 3: isb 142 + mov x19, xzr 143 + ret 144 + SYM_CODE_END(record_mmu_state) 145 + 126 146 /* 127 147 * Preserve the arguments passed by the bootloader in x0 .. x3 128 148 */ ··· 167 119 stp x21, x1, [x0] // x0 .. x3 at kernel entry 168 120 stp x2, x3, [x0, #16] 169 121 122 + cbnz x19, 0f // skip cache invalidation if MMU is on 170 123 dmb sy // needed before dc ivac with 171 124 // MMU off 172 125 173 126 add x1, x0, #0x20 // 4 x 8 bytes 174 127 b dcache_inval_poc // tail call 128 + 0: str_l x19, mmu_enabled_at_boot, x0 129 + ret 175 130 SYM_CODE_END(preserve_boot_args) 176 131 177 132 SYM_FUNC_START_LOCAL(clear_page_tables) ··· 411 360 * accesses (MMU disabled), invalidate those tables again to 412 361 * remove any speculatively loaded cache lines. 413 362 */ 363 + cbnz x19, 0f // skip cache invalidation if MMU is on 414 364 dmb sy 415 365 416 366 adrp x0, init_idmap_pg_dir 417 367 adrp x1, init_idmap_pg_end 418 368 bl dcache_inval_poc 419 - ret x28 369 + 0: ret x28 420 370 SYM_FUNC_END(create_idmap) 421 371 422 372 SYM_FUNC_START_LOCAL(create_kernel_mapping) ··· 456 404 stp xzr, xzr, [sp, #S_STACKFRAME] 457 405 add x29, sp, #S_STACKFRAME 458 406 459 - scs_load \tsk 407 + scs_load_current 460 408 461 409 adr_l \tmp1, __per_cpu_offset 462 410 ldr w\tmp2, [\tsk, #TSK_TI_CPU] ··· 528 476 * end early head section, begin head code that is also used for 529 477 * hotplug and needs to have the same protections as the text region 530 478 */ 531 - .section ".idmap.text","awx" 479 + .section ".idmap.text","a" 532 480 533 481 /* 534 482 * Starting from EL2 or EL1, configure the CPU to execute at the highest ··· 541 489 * Returns either BOOT_CPU_MODE_EL1 or BOOT_CPU_MODE_EL2 in x0 if 542 490 * booted in EL1 or EL2 respectively, with the top 32 bits containing 543 491 * potential context flags. These flags are *not* stored in __boot_cpu_mode. 492 + * 493 + * x0: whether we are being called from the primary boot path with the MMU on 544 494 */ 545 495 SYM_FUNC_START(init_kernel_el) 546 - mrs x0, CurrentEL 547 - cmp x0, #CurrentEL_EL2 496 + mrs x1, CurrentEL 497 + cmp x1, #CurrentEL_EL2 548 498 b.eq init_el2 549 499 550 500 SYM_INNER_LABEL(init_el1, SYM_L_LOCAL) 551 501 mov_q x0, INIT_SCTLR_EL1_MMU_OFF 502 + pre_disable_mmu_workaround 552 503 msr sctlr_el1, x0 553 504 isb 554 505 mov_q x0, INIT_PSTATE_EL1 ··· 561 506 eret 562 507 563 508 SYM_INNER_LABEL(init_el2, SYM_L_LOCAL) 509 + msr elr_el2, lr 510 + 511 + // clean all HYP code to the PoC if we booted at EL2 with the MMU on 512 + cbz x0, 0f 513 + adrp x0, __hyp_idmap_text_start 514 + adr_l x1, __hyp_text_end 515 + adr_l x2, dcache_clean_poc 516 + blr x2 517 + 0: 564 518 mov_q x0, HCR_HOST_NVHE_FLAGS 565 519 msr hcr_el2, x0 566 520 isb ··· 593 529 cbz x0, 1f 594 530 595 531 /* Set a sane SCTLR_EL1, the VHE way */ 532 + pre_disable_mmu_workaround 596 533 msr_s SYS_SCTLR_EL12, x1 597 534 mov x2, #BOOT_CPU_FLAG_E2H 598 535 b 2f 599 536 600 537 1: 538 + pre_disable_mmu_workaround 601 539 msr sctlr_el1, x1 602 540 mov x2, xzr 603 541 2: 604 - msr elr_el2, lr 605 542 mov w0, #BOOT_CPU_MODE_EL2 606 543 orr x0, x0, x2 607 544 eret 608 545 SYM_FUNC_END(init_kernel_el) 609 - 610 - /* 611 - * Sets the __boot_cpu_mode flag depending on the CPU boot mode passed 612 - * in w0. See arch/arm64/include/asm/virt.h for more info. 613 - */ 614 - SYM_FUNC_START_LOCAL(set_cpu_boot_mode_flag) 615 - adr_l x1, __boot_cpu_mode 616 - cmp w0, #BOOT_CPU_MODE_EL2 617 - b.ne 1f 618 - add x1, x1, #4 619 - 1: str w0, [x1] // Save CPU boot mode 620 - ret 621 - SYM_FUNC_END(set_cpu_boot_mode_flag) 622 546 623 547 /* 624 548 * This provides a "holding pen" for platforms to hold all secondary 625 549 * cores are held until we're ready for them to initialise. 626 550 */ 627 551 SYM_FUNC_START(secondary_holding_pen) 552 + mov x0, xzr 628 553 bl init_kernel_el // w0=cpu_boot_mode 629 554 mrs x2, mpidr_el1 630 555 mov_q x1, MPIDR_HWID_BITMASK ··· 631 578 * be used where CPUs are brought online dynamically by the kernel. 632 579 */ 633 580 SYM_FUNC_START(secondary_entry) 581 + mov x0, xzr 634 582 bl init_kernel_el // w0=cpu_boot_mode 635 583 b secondary_startup 636 584 SYM_FUNC_END(secondary_entry) ··· 641 587 * Common entry point for secondary CPUs. 642 588 */ 643 589 mov x20, x0 // preserve boot mode 644 - bl finalise_el2 645 590 bl __cpu_secondary_check52bitva 646 591 #if VA_BITS > 48 647 592 ldr_l x0, vabits_actual ··· 653 600 br x8 654 601 SYM_FUNC_END(secondary_startup) 655 602 603 + .text 656 604 SYM_FUNC_START_LOCAL(__secondary_switched) 657 605 mov x0, x20 658 606 bl set_cpu_boot_mode_flag 607 + 608 + mov x0, x20 609 + bl finalise_el2 610 + 659 611 str_l xzr, __early_cpu_boot_status, x3 660 612 adr_l x5, vectors 661 613 msr vbar_el1, x5 ··· 685 627 wfi 686 628 b __secondary_too_slow 687 629 SYM_FUNC_END(__secondary_too_slow) 630 + 631 + /* 632 + * Sets the __boot_cpu_mode flag depending on the CPU boot mode passed 633 + * in w0. See arch/arm64/include/asm/virt.h for more info. 634 + */ 635 + SYM_FUNC_START_LOCAL(set_cpu_boot_mode_flag) 636 + adr_l x1, __boot_cpu_mode 637 + cmp w0, #BOOT_CPU_MODE_EL2 638 + b.ne 1f 639 + add x1, x1, #4 640 + 1: str w0, [x1] // Save CPU boot mode 641 + ret 642 + SYM_FUNC_END(set_cpu_boot_mode_flag) 688 643 689 644 /* 690 645 * The booting CPU updates the failed status @__early_cpu_boot_status, ··· 730 659 * Checks if the selected granule size is supported by the CPU. 731 660 * If it isn't, park the CPU 732 661 */ 662 + .section ".idmap.text","a" 733 663 SYM_FUNC_START(__enable_mmu) 734 664 mrs x3, ID_AA64MMFR0_EL1 735 665 ubfx x3, x3, #ID_AA64MMFR0_EL1_TGRAN_SHIFT, 4
+7
arch/arm64/kernel/hyp-stub.S
··· 132 132 orr x0, x0, SMCR_ELx_FA64_MASK 133 133 .Lskip_sme_fa64: 134 134 135 + // ZT0 available? 136 + mrs_s x1, SYS_ID_AA64SMFR0_EL1 137 + __check_override id_aa64smfr0 ID_AA64SMFR0_EL1_SMEver_SHIFT 4 .Linit_sme_zt0 .Lskip_sme_zt0 138 + .Linit_sme_zt0: 139 + orr x0, x0, SMCR_ELx_EZT0_MASK 140 + .Lskip_sme_zt0: 141 + 135 142 orr x0, x0, #SMCR_ELx_LEN_MASK // Enable full SME vector 136 143 msr_s SYS_SMCR_EL2, x0 // length for EL1. 137 144
+1
arch/arm64/kernel/idreg-override.c
··· 131 131 .name = "id_aa64smfr0", 132 132 .override = &id_aa64smfr0_override, 133 133 .fields = { 134 + FIELD("smever", ID_AA64SMFR0_EL1_SMEver_SHIFT, NULL), 134 135 /* FA64 is a one bit field... :-/ */ 135 136 { "fa64", ID_AA64SMFR0_EL1_FA64_SHIFT, 1, }, 136 137 {}
+3 -4
arch/arm64/kernel/image-vars.h
··· 10 10 #error This file should only be included in vmlinux.lds.S 11 11 #endif 12 12 13 - PROVIDE(__efistub_primary_entry_offset = primary_entry - _text); 13 + PROVIDE(__efistub_primary_entry = primary_entry); 14 14 15 15 /* 16 16 * The EFI stub has its own symbol namespace prefixed by __efistub_, to ··· 21 21 * linked at. The routines below are all implemented in assembler in a 22 22 * position independent manner 23 23 */ 24 - PROVIDE(__efistub_dcache_clean_poc = __pi_dcache_clean_poc); 24 + PROVIDE(__efistub_caches_clean_inval_pou = __pi_caches_clean_inval_pou); 25 25 26 26 PROVIDE(__efistub__text = _text); 27 27 PROVIDE(__efistub__end = _end); 28 + PROVIDE(__efistub___inittext_end = __inittext_end); 28 29 PROVIDE(__efistub__edata = _edata); 29 30 PROVIDE(__efistub_screen_info = screen_info); 30 31 PROVIDE(__efistub__ctype = _ctype); ··· 68 67 KVM_NVHE_ALIAS(vgic_v2_cpuif_trap); 69 68 KVM_NVHE_ALIAS(vgic_v3_cpuif_trap); 70 69 71 - /* Static key checked in pmr_sync(). */ 72 70 #ifdef CONFIG_ARM64_PSEUDO_NMI 73 - KVM_NVHE_ALIAS(gic_pmr_sync); 74 71 /* Static key checked in GIC_PRIO_IRQOFF. */ 75 72 KVM_NVHE_ALIAS(gic_nonsecure_priorities); 76 73 #endif
+8 -3
arch/arm64/kernel/patch-scs.c
··· 130 130 131 131 static int noinstr scs_handle_fde_frame(const struct eh_frame *frame, 132 132 bool fde_has_augmentation_data, 133 - int code_alignment_factor) 133 + int code_alignment_factor, 134 + bool dry_run) 134 135 { 135 136 int size = frame->size - offsetof(struct eh_frame, opcodes) + 4; 136 137 u64 loc = (u64)offset_to_ptr(&frame->initial_loc); ··· 185 184 break; 186 185 187 186 case DW_CFA_negate_ra_state: 188 - scs_patch_loc(loc - 4); 187 + if (!dry_run) 188 + scs_patch_loc(loc - 4); 189 189 break; 190 190 191 191 case 0x40 ... 0x7f: ··· 237 235 } else { 238 236 ret = scs_handle_fde_frame(frame, 239 237 fde_has_augmentation_data, 240 - code_alignment_factor); 238 + code_alignment_factor, 239 + true); 241 240 if (ret) 242 241 return ret; 242 + scs_handle_fde_frame(frame, fde_has_augmentation_data, 243 + code_alignment_factor, false); 243 244 } 244 245 245 246 p += sizeof(frame->size) + frame->size;
+17
arch/arm64/kernel/patching.c
··· 88 88 return __aarch64_insn_write(addr, cpu_to_le32(insn)); 89 89 } 90 90 91 + noinstr int aarch64_insn_write_literal_u64(void *addr, u64 val) 92 + { 93 + u64 *waddr; 94 + unsigned long flags; 95 + int ret; 96 + 97 + raw_spin_lock_irqsave(&patch_lock, flags); 98 + waddr = patch_map(addr, FIX_TEXT_POKE0); 99 + 100 + ret = copy_to_kernel_nofault(waddr, &val, sizeof(val)); 101 + 102 + patch_unmap(FIX_TEXT_POKE0); 103 + raw_spin_unlock_irqrestore(&patch_lock, flags); 104 + 105 + return ret; 106 + } 107 + 91 108 int __kprobes aarch64_insn_patch_text_nosync(void *addr, u32 insn) 92 109 { 93 110 u32 *tp = addr;
-4
arch/arm64/kernel/probes/kprobes.c
··· 387 387 (unsigned long)__irqentry_text_end); 388 388 if (ret) 389 389 return ret; 390 - ret = kprobe_add_area_blacklist((unsigned long)__idmap_text_start, 391 - (unsigned long)__idmap_text_end); 392 - if (ret) 393 - return ret; 394 390 ret = kprobe_add_area_blacklist((unsigned long)__hyp_text_start, 395 391 (unsigned long)__hyp_text_end); 396 392 if (ret || is_kernel_in_hyp_mode())
+11 -10
arch/arm64/kernel/process.c
··· 307 307 308 308 /* 309 309 * In the unlikely event that we create a new thread with ZA 310 - * enabled we should retain the ZA state so duplicate it here. 311 - * This may be shortly freed if we exec() or if CLONE_SETTLS 312 - * but it's simpler to do it here. To avoid confusing the rest 313 - * of the code ensure that we have a sve_state allocated 314 - * whenever za_state is allocated. 310 + * enabled we should retain the ZA and ZT state so duplicate 311 + * it here. This may be shortly freed if we exec() or if 312 + * CLONE_SETTLS but it's simpler to do it here. To avoid 313 + * confusing the rest of the code ensure that we have a 314 + * sve_state allocated whenever sme_state is allocated. 315 315 */ 316 316 if (thread_za_enabled(&src->thread)) { 317 317 dst->thread.sve_state = kzalloc(sve_state_size(src), 318 318 GFP_KERNEL); 319 319 if (!dst->thread.sve_state) 320 320 return -ENOMEM; 321 - dst->thread.za_state = kmemdup(src->thread.za_state, 322 - za_state_size(src), 323 - GFP_KERNEL); 324 - if (!dst->thread.za_state) { 321 + 322 + dst->thread.sme_state = kmemdup(src->thread.sme_state, 323 + sme_state_size(src), 324 + GFP_KERNEL); 325 + if (!dst->thread.sme_state) { 325 326 kfree(dst->thread.sve_state); 326 327 dst->thread.sve_state = NULL; 327 328 return -ENOMEM; 328 329 } 329 330 } else { 330 - dst->thread.za_state = NULL; 331 + dst->thread.sme_state = NULL; 331 332 clear_tsk_thread_flag(dst, TIF_SME); 332 333 } 333 334
+59 -5
arch/arm64/kernel/ptrace.c
··· 683 683 unsigned long tls[2]; 684 684 685 685 tls[0] = target->thread.uw.tp_value; 686 - if (system_supports_sme()) 686 + if (system_supports_tpidr2()) 687 687 tls[1] = target->thread.tpidr2_el0; 688 688 689 689 ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, tls, 0, count); ··· 691 691 return ret; 692 692 693 693 target->thread.uw.tp_value = tls[0]; 694 - if (system_supports_sme()) 694 + if (system_supports_tpidr2()) 695 695 target->thread.tpidr2_el0 = tls[1]; 696 696 697 697 return ret; ··· 1045 1045 if (thread_za_enabled(&target->thread)) { 1046 1046 start = end; 1047 1047 end = ZA_PT_SIZE(vq); 1048 - membuf_write(&to, target->thread.za_state, end - start); 1048 + membuf_write(&to, target->thread.sme_state, end - start); 1049 1049 } 1050 1050 1051 1051 /* Zero any trailing padding */ ··· 1099 1099 1100 1100 /* Allocate/reinit ZA storage */ 1101 1101 sme_alloc(target); 1102 - if (!target->thread.za_state) { 1102 + if (!target->thread.sme_state) { 1103 1103 ret = -ENOMEM; 1104 1104 goto out; 1105 1105 } ··· 1124 1124 start = ZA_PT_ZA_OFFSET; 1125 1125 end = ZA_PT_SIZE(vq); 1126 1126 ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, 1127 - target->thread.za_state, 1127 + target->thread.sme_state, 1128 1128 start, end); 1129 1129 if (ret) 1130 1130 goto out; ··· 1135 1135 1136 1136 out: 1137 1137 fpsimd_flush_task_state(target); 1138 + return ret; 1139 + } 1140 + 1141 + static int zt_get(struct task_struct *target, 1142 + const struct user_regset *regset, 1143 + struct membuf to) 1144 + { 1145 + if (!system_supports_sme2()) 1146 + return -EINVAL; 1147 + 1148 + /* 1149 + * If PSTATE.ZA is not set then ZT will be zeroed when it is 1150 + * enabled so report the current register value as zero. 1151 + */ 1152 + if (thread_za_enabled(&target->thread)) 1153 + membuf_write(&to, thread_zt_state(&target->thread), 1154 + ZT_SIG_REG_BYTES); 1155 + else 1156 + membuf_zero(&to, ZT_SIG_REG_BYTES); 1157 + 1158 + return 0; 1159 + } 1160 + 1161 + static int zt_set(struct task_struct *target, 1162 + const struct user_regset *regset, 1163 + unsigned int pos, unsigned int count, 1164 + const void *kbuf, const void __user *ubuf) 1165 + { 1166 + int ret; 1167 + 1168 + if (!system_supports_sme2()) 1169 + return -EINVAL; 1170 + 1171 + if (!thread_za_enabled(&target->thread)) { 1172 + sme_alloc(target); 1173 + if (!target->thread.sme_state) 1174 + return -ENOMEM; 1175 + } 1176 + 1177 + ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, 1178 + thread_zt_state(&target->thread), 1179 + 0, ZT_SIG_REG_BYTES); 1180 + if (ret == 0) 1181 + target->thread.svcr |= SVCR_ZA_MASK; 1182 + 1138 1183 return ret; 1139 1184 } 1140 1185 ··· 1405 1360 #ifdef CONFIG_ARM64_SME 1406 1361 REGSET_SSVE, 1407 1362 REGSET_ZA, 1363 + REGSET_ZT, 1408 1364 #endif 1409 1365 #ifdef CONFIG_ARM64_PTR_AUTH 1410 1366 REGSET_PAC_MASK, ··· 1512 1466 .align = SVE_VQ_BYTES, 1513 1467 .regset_get = za_get, 1514 1468 .set = za_set, 1469 + }, 1470 + [REGSET_ZT] = { /* SME ZT */ 1471 + .core_note_type = NT_ARM_ZT, 1472 + .n = 1, 1473 + .size = ZT_SIG_REG_BYTES, 1474 + .align = sizeof(u64), 1475 + .regset_get = zt_get, 1476 + .set = zt_set, 1515 1477 }, 1516 1478 #endif 1517 1479 #ifdef CONFIG_ARM64_PTR_AUTH
+15 -2
arch/arm64/kernel/setup.c
··· 58 58 static struct resource *standard_resources; 59 59 60 60 phys_addr_t __fdt_pointer __initdata; 61 + u64 mmu_enabled_at_boot __initdata; 61 62 62 63 /* 63 64 * Standard memory resources ··· 333 332 xen_early_init(); 334 333 efi_init(); 335 334 336 - if (!efi_enabled(EFI_BOOT) && ((u64)_text % MIN_KIMG_ALIGN) != 0) 337 - pr_warn(FW_BUG "Kernel image misaligned at boot, please fix your bootloader!"); 335 + if (!efi_enabled(EFI_BOOT)) { 336 + if ((u64)_text % MIN_KIMG_ALIGN) 337 + pr_warn(FW_BUG "Kernel image misaligned at boot, please fix your bootloader!"); 338 + WARN_TAINT(mmu_enabled_at_boot, TAINT_FIRMWARE_WORKAROUND, 339 + FW_BUG "Booted with MMU enabled!"); 340 + } 338 341 339 342 arm64_memblock_init(); 340 343 ··· 447 442 return 0; 448 443 } 449 444 device_initcall(register_arm64_panic_block); 445 + 446 + static int __init check_mmu_enabled_at_boot(void) 447 + { 448 + if (!efi_enabled(EFI_BOOT) && mmu_enabled_at_boot) 449 + panic("Non-EFI boot detected with MMU and caches enabled"); 450 + return 0; 451 + } 452 + device_initcall_sync(check_mmu_enabled_at_boot);
+213 -48
arch/arm64/kernel/signal.c
··· 56 56 unsigned long fpsimd_offset; 57 57 unsigned long esr_offset; 58 58 unsigned long sve_offset; 59 + unsigned long tpidr2_offset; 59 60 unsigned long za_offset; 61 + unsigned long zt_offset; 60 62 unsigned long extra_offset; 61 63 unsigned long end_offset; 62 64 }; ··· 170 168 return base + offset; 171 169 } 172 170 171 + struct user_ctxs { 172 + struct fpsimd_context __user *fpsimd; 173 + u32 fpsimd_size; 174 + struct sve_context __user *sve; 175 + u32 sve_size; 176 + struct tpidr2_context __user *tpidr2; 177 + u32 tpidr2_size; 178 + struct za_context __user *za; 179 + u32 za_size; 180 + struct zt_context __user *zt; 181 + u32 zt_size; 182 + }; 183 + 173 184 static int preserve_fpsimd_context(struct fpsimd_context __user *ctx) 174 185 { 175 186 struct user_fpsimd_state const *fpsimd = ··· 201 186 return err ? -EFAULT : 0; 202 187 } 203 188 204 - static int restore_fpsimd_context(struct fpsimd_context __user *ctx) 189 + static int restore_fpsimd_context(struct user_ctxs *user) 205 190 { 206 191 struct user_fpsimd_state fpsimd; 207 - __u32 magic, size; 208 192 int err = 0; 209 193 210 - /* check the magic/size information */ 211 - __get_user_error(magic, &ctx->head.magic, err); 212 - __get_user_error(size, &ctx->head.size, err); 213 - if (err) 214 - return -EFAULT; 215 - if (magic != FPSIMD_MAGIC || size != sizeof(struct fpsimd_context)) 194 + /* check the size information */ 195 + if (user->fpsimd_size != sizeof(struct fpsimd_context)) 216 196 return -EINVAL; 217 197 218 198 /* copy the FP and status/control registers */ 219 - err = __copy_from_user(fpsimd.vregs, ctx->vregs, 199 + err = __copy_from_user(fpsimd.vregs, &(user->fpsimd->vregs), 220 200 sizeof(fpsimd.vregs)); 221 - __get_user_error(fpsimd.fpsr, &ctx->fpsr, err); 222 - __get_user_error(fpsimd.fpcr, &ctx->fpcr, err); 201 + __get_user_error(fpsimd.fpsr, &(user->fpsimd->fpsr), err); 202 + __get_user_error(fpsimd.fpcr, &(user->fpsimd->fpcr), err); 223 203 224 204 clear_thread_flag(TIF_SVE); 225 205 current->thread.fp_type = FP_STATE_FPSIMD; ··· 226 216 return err ? -EFAULT : 0; 227 217 } 228 218 229 - 230 - struct user_ctxs { 231 - struct fpsimd_context __user *fpsimd; 232 - struct sve_context __user *sve; 233 - struct za_context __user *za; 234 - }; 235 219 236 220 #ifdef CONFIG_ARM64_SVE 237 221 ··· 271 267 272 268 static int restore_sve_fpsimd_context(struct user_ctxs *user) 273 269 { 274 - int err; 270 + int err = 0; 275 271 unsigned int vl, vq; 276 272 struct user_fpsimd_state fpsimd; 277 - struct sve_context sve; 273 + u16 user_vl, flags; 278 274 279 - if (__copy_from_user(&sve, user->sve, sizeof(sve))) 280 - return -EFAULT; 275 + if (user->sve_size < sizeof(*user->sve)) 276 + return -EINVAL; 281 277 282 - if (sve.flags & SVE_SIG_FLAG_SM) { 278 + __get_user_error(user_vl, &(user->sve->vl), err); 279 + __get_user_error(flags, &(user->sve->flags), err); 280 + if (err) 281 + return err; 282 + 283 + if (flags & SVE_SIG_FLAG_SM) { 283 284 if (!system_supports_sme()) 284 285 return -EINVAL; 285 286 ··· 301 292 vl = task_get_sve_vl(current); 302 293 } 303 294 304 - if (sve.vl != vl) 295 + if (user_vl != vl) 305 296 return -EINVAL; 306 297 307 - if (sve.head.size <= sizeof(*user->sve)) { 298 + if (user->sve_size == sizeof(*user->sve)) { 308 299 clear_thread_flag(TIF_SVE); 309 300 current->thread.svcr &= ~SVCR_SM_MASK; 310 301 current->thread.fp_type = FP_STATE_FPSIMD; 311 302 goto fpsimd_only; 312 303 } 313 304 314 - vq = sve_vq_from_vl(sve.vl); 305 + vq = sve_vq_from_vl(vl); 315 306 316 - if (sve.head.size < SVE_SIG_CONTEXT_SIZE(vq)) 307 + if (user->sve_size < SVE_SIG_CONTEXT_SIZE(vq)) 317 308 return -EINVAL; 318 309 319 310 /* ··· 339 330 if (err) 340 331 return -EFAULT; 341 332 342 - if (sve.flags & SVE_SIG_FLAG_SM) 333 + if (flags & SVE_SIG_FLAG_SM) 343 334 current->thread.svcr |= SVCR_SM_MASK; 344 335 else 345 336 set_thread_flag(TIF_SVE); ··· 375 366 376 367 #ifdef CONFIG_ARM64_SME 377 368 369 + static int preserve_tpidr2_context(struct tpidr2_context __user *ctx) 370 + { 371 + int err = 0; 372 + 373 + current->thread.tpidr2_el0 = read_sysreg_s(SYS_TPIDR2_EL0); 374 + 375 + __put_user_error(TPIDR2_MAGIC, &ctx->head.magic, err); 376 + __put_user_error(sizeof(*ctx), &ctx->head.size, err); 377 + __put_user_error(current->thread.tpidr2_el0, &ctx->tpidr2, err); 378 + 379 + return err; 380 + } 381 + 382 + static int restore_tpidr2_context(struct user_ctxs *user) 383 + { 384 + u64 tpidr2_el0; 385 + int err = 0; 386 + 387 + if (user->tpidr2_size != sizeof(*user->tpidr2)) 388 + return -EINVAL; 389 + 390 + __get_user_error(tpidr2_el0, &user->tpidr2->tpidr2, err); 391 + if (!err) 392 + current->thread.tpidr2_el0 = tpidr2_el0; 393 + 394 + return err; 395 + } 396 + 378 397 static int preserve_za_context(struct za_context __user *ctx) 379 398 { 380 399 int err = 0; ··· 431 394 * fpsimd_signal_preserve_current_state(). 432 395 */ 433 396 err |= __copy_to_user((char __user *)ctx + ZA_SIG_REGS_OFFSET, 434 - current->thread.za_state, 397 + current->thread.sme_state, 435 398 ZA_SIG_REGS_SIZE(vq)); 436 399 } 437 400 ··· 440 403 441 404 static int restore_za_context(struct user_ctxs *user) 442 405 { 443 - int err; 406 + int err = 0; 444 407 unsigned int vq; 445 - struct za_context za; 408 + u16 user_vl; 446 409 447 - if (__copy_from_user(&za, user->za, sizeof(za))) 448 - return -EFAULT; 449 - 450 - if (za.vl != task_get_sme_vl(current)) 410 + if (user->za_size < sizeof(*user->za)) 451 411 return -EINVAL; 452 412 453 - if (za.head.size <= sizeof(*user->za)) { 413 + __get_user_error(user_vl, &(user->za->vl), err); 414 + if (err) 415 + return err; 416 + 417 + if (user_vl != task_get_sme_vl(current)) 418 + return -EINVAL; 419 + 420 + if (user->za_size == sizeof(*user->za)) { 454 421 current->thread.svcr &= ~SVCR_ZA_MASK; 455 422 return 0; 456 423 } 457 424 458 - vq = sve_vq_from_vl(za.vl); 425 + vq = sve_vq_from_vl(user_vl); 459 426 460 - if (za.head.size < ZA_SIG_CONTEXT_SIZE(vq)) 427 + if (user->za_size < ZA_SIG_CONTEXT_SIZE(vq)) 461 428 return -EINVAL; 462 429 463 430 /* 464 431 * Careful: we are about __copy_from_user() directly into 465 - * thread.za_state with preemption enabled, so protection is 432 + * thread.sme_state with preemption enabled, so protection is 466 433 * needed to prevent a racing context switch from writing stale 467 434 * registers back over the new data. 468 435 */ ··· 475 434 /* From now, fpsimd_thread_switch() won't touch thread.sve_state */ 476 435 477 436 sme_alloc(current); 478 - if (!current->thread.za_state) { 437 + if (!current->thread.sme_state) { 479 438 current->thread.svcr &= ~SVCR_ZA_MASK; 480 439 clear_thread_flag(TIF_SME); 481 440 return -ENOMEM; 482 441 } 483 442 484 - err = __copy_from_user(current->thread.za_state, 443 + err = __copy_from_user(current->thread.sme_state, 485 444 (char __user const *)user->za + 486 445 ZA_SIG_REGS_OFFSET, 487 446 ZA_SIG_REGS_SIZE(vq)); ··· 493 452 494 453 return 0; 495 454 } 455 + 456 + static int preserve_zt_context(struct zt_context __user *ctx) 457 + { 458 + int err = 0; 459 + u16 reserved[ARRAY_SIZE(ctx->__reserved)]; 460 + 461 + if (WARN_ON(!thread_za_enabled(&current->thread))) 462 + return -EINVAL; 463 + 464 + memset(reserved, 0, sizeof(reserved)); 465 + 466 + __put_user_error(ZT_MAGIC, &ctx->head.magic, err); 467 + __put_user_error(round_up(ZT_SIG_CONTEXT_SIZE(1), 16), 468 + &ctx->head.size, err); 469 + __put_user_error(1, &ctx->nregs, err); 470 + BUILD_BUG_ON(sizeof(ctx->__reserved) != sizeof(reserved)); 471 + err |= __copy_to_user(&ctx->__reserved, reserved, sizeof(reserved)); 472 + 473 + /* 474 + * This assumes that the ZT state has already been saved to 475 + * the task struct by calling the function 476 + * fpsimd_signal_preserve_current_state(). 477 + */ 478 + err |= __copy_to_user((char __user *)ctx + ZT_SIG_REGS_OFFSET, 479 + thread_zt_state(&current->thread), 480 + ZT_SIG_REGS_SIZE(1)); 481 + 482 + return err ? -EFAULT : 0; 483 + } 484 + 485 + static int restore_zt_context(struct user_ctxs *user) 486 + { 487 + int err; 488 + u16 nregs; 489 + 490 + /* ZA must be restored first for this check to be valid */ 491 + if (!thread_za_enabled(&current->thread)) 492 + return -EINVAL; 493 + 494 + if (user->zt_size != ZT_SIG_CONTEXT_SIZE(1)) 495 + return -EINVAL; 496 + 497 + if (__copy_from_user(&nregs, &(user->zt->nregs), sizeof(nregs))) 498 + return -EFAULT; 499 + 500 + if (nregs != 1) 501 + return -EINVAL; 502 + 503 + /* 504 + * Careful: we are about __copy_from_user() directly into 505 + * thread.zt_state with preemption enabled, so protection is 506 + * needed to prevent a racing context switch from writing stale 507 + * registers back over the new data. 508 + */ 509 + 510 + fpsimd_flush_task_state(current); 511 + /* From now, fpsimd_thread_switch() won't touch ZT in thread state */ 512 + 513 + err = __copy_from_user(thread_zt_state(&current->thread), 514 + (char __user const *)user->zt + 515 + ZT_SIG_REGS_OFFSET, 516 + ZT_SIG_REGS_SIZE(1)); 517 + if (err) 518 + return -EFAULT; 519 + 520 + return 0; 521 + } 522 + 496 523 #else /* ! CONFIG_ARM64_SME */ 497 524 498 525 /* Turn any non-optimised out attempts to use these into a link error: */ 526 + extern int preserve_tpidr2_context(void __user *ctx); 527 + extern int restore_tpidr2_context(struct user_ctxs *user); 499 528 extern int preserve_za_context(void __user *ctx); 500 529 extern int restore_za_context(struct user_ctxs *user); 530 + extern int preserve_zt_context(void __user *ctx); 531 + extern int restore_zt_context(struct user_ctxs *user); 501 532 502 533 #endif /* ! CONFIG_ARM64_SME */ 503 534 ··· 586 473 587 474 user->fpsimd = NULL; 588 475 user->sve = NULL; 476 + user->tpidr2 = NULL; 589 477 user->za = NULL; 478 + user->zt = NULL; 590 479 591 480 if (!IS_ALIGNED((unsigned long)base, 16)) 592 481 goto invalid; ··· 631 516 if (user->fpsimd) 632 517 goto invalid; 633 518 634 - if (size < sizeof(*user->fpsimd)) 635 - goto invalid; 636 - 637 519 user->fpsimd = (struct fpsimd_context __user *)head; 520 + user->fpsimd_size = size; 638 521 break; 639 522 640 523 case ESR_MAGIC: ··· 646 533 if (user->sve) 647 534 goto invalid; 648 535 649 - if (size < sizeof(*user->sve)) 536 + user->sve = (struct sve_context __user *)head; 537 + user->sve_size = size; 538 + break; 539 + 540 + case TPIDR2_MAGIC: 541 + if (!system_supports_sme()) 650 542 goto invalid; 651 543 652 - user->sve = (struct sve_context __user *)head; 544 + if (user->tpidr2) 545 + goto invalid; 546 + 547 + user->tpidr2 = (struct tpidr2_context __user *)head; 548 + user->tpidr2_size = size; 653 549 break; 654 550 655 551 case ZA_MAGIC: ··· 668 546 if (user->za) 669 547 goto invalid; 670 548 671 - if (size < sizeof(*user->za)) 549 + user->za = (struct za_context __user *)head; 550 + user->za_size = size; 551 + break; 552 + 553 + case ZT_MAGIC: 554 + if (!system_supports_sme2()) 672 555 goto invalid; 673 556 674 - user->za = (struct za_context __user *)head; 557 + if (user->zt) 558 + goto invalid; 559 + 560 + user->zt = (struct zt_context __user *)head; 561 + user->zt_size = size; 675 562 break; 676 563 677 564 case EXTRA_MAGIC: ··· 799 668 if (user.sve) 800 669 err = restore_sve_fpsimd_context(&user); 801 670 else 802 - err = restore_fpsimd_context(user.fpsimd); 671 + err = restore_fpsimd_context(&user); 803 672 } 673 + 674 + if (err == 0 && system_supports_sme() && user.tpidr2) 675 + err = restore_tpidr2_context(&user); 804 676 805 677 if (err == 0 && system_supports_sme() && user.za) 806 678 err = restore_za_context(&user); 679 + 680 + if (err == 0 && system_supports_sme2() && user.zt) 681 + err = restore_zt_context(&user); 807 682 808 683 return err; 809 684 } ··· 902 765 else 903 766 vl = task_get_sme_vl(current); 904 767 768 + err = sigframe_alloc(user, &user->tpidr2_offset, 769 + sizeof(struct tpidr2_context)); 770 + if (err) 771 + return err; 772 + 905 773 if (thread_za_enabled(&current->thread)) 906 774 vq = sve_vq_from_vl(vl); 907 775 ··· 914 772 ZA_SIG_CONTEXT_SIZE(vq)); 915 773 if (err) 916 774 return err; 775 + } 776 + 777 + if (system_supports_sme2()) { 778 + if (add_all || thread_za_enabled(&current->thread)) { 779 + err = sigframe_alloc(user, &user->zt_offset, 780 + ZT_SIG_CONTEXT_SIZE(1)); 781 + if (err) 782 + return err; 783 + } 917 784 } 918 785 919 786 return sigframe_alloc_end(user); ··· 973 822 err |= preserve_sve_context(sve_ctx); 974 823 } 975 824 825 + /* TPIDR2 if supported */ 826 + if (system_supports_sme() && err == 0) { 827 + struct tpidr2_context __user *tpidr2_ctx = 828 + apply_user_offset(user, user->tpidr2_offset); 829 + err |= preserve_tpidr2_context(tpidr2_ctx); 830 + } 831 + 976 832 /* ZA state if present */ 977 833 if (system_supports_sme() && err == 0 && user->za_offset) { 978 834 struct za_context __user *za_ctx = 979 835 apply_user_offset(user, user->za_offset); 980 836 err |= preserve_za_context(za_ctx); 837 + } 838 + 839 + /* ZT state if present */ 840 + if (system_supports_sme2() && err == 0 && user->zt_offset) { 841 + struct zt_context __user *zt_ctx = 842 + apply_user_offset(user, user->zt_offset); 843 + err |= preserve_zt_context(zt_ctx); 981 844 } 982 845 983 846 if (err == 0 && user->extra_offset) {
+5 -1
arch/arm64/kernel/sleep.S
··· 99 99 100 100 .pushsection ".idmap.text", "awx" 101 101 SYM_CODE_START(cpu_resume) 102 + mov x0, xzr 102 103 bl init_kernel_el 103 - bl finalise_el2 104 + mov x19, x0 // preserve boot mode 104 105 #if VA_BITS > 48 105 106 ldr_l x0, vabits_actual 106 107 #endif ··· 117 116 .popsection 118 117 119 118 SYM_FUNC_START(_cpu_resume) 119 + mov x0, x19 120 + bl finalise_el2 121 + 120 122 mrs x1, mpidr_el1 121 123 adr_l x8, mpidr_hash // x8 = struct mpidr_hash virt address 122 124
+2 -6
arch/arm64/kernel/syscall.c
··· 173 173 * register state to track, if this changes the KVM code will 174 174 * need updating. 175 175 */ 176 - if (system_supports_sme() && test_thread_flag(TIF_SME)) { 177 - u64 svcr = read_sysreg_s(SYS_SVCR); 178 - 179 - if (svcr & SVCR_SM_MASK) 180 - sme_smstop_sm(); 181 - } 176 + if (system_supports_sme()) 177 + sme_smstop_sm(); 182 178 183 179 if (!system_supports_sve()) 184 180 return;
+2 -4
arch/arm64/kernel/traps.c
··· 163 163 164 164 if (!bad) 165 165 p += sprintf(p, i == 0 ? "(%08x) " : "%08x ", val); 166 - else { 167 - p += sprintf(p, "bad PC value"); 168 - break; 169 - } 166 + else 167 + p += sprintf(p, i == 0 ? "(????????) " : "???????? "); 170 168 } 171 169 172 170 printk("%sCode: %s\n", lvl, str);
+7 -1
arch/arm64/kernel/vmlinux.lds.S
··· 93 93 94 94 #ifdef CONFIG_HIBERNATION 95 95 #define HIBERNATE_TEXT \ 96 + ALIGN_FUNCTION(); \ 96 97 __hibernate_exit_text_start = .; \ 97 98 *(.hibernate_exit.text) \ 98 99 __hibernate_exit_text_end = .; ··· 103 102 104 103 #ifdef CONFIG_KEXEC_CORE 105 104 #define KEXEC_TEXT \ 105 + ALIGN_FUNCTION(); \ 106 106 __relocate_new_kernel_start = .; \ 107 107 *(.kexec_relocate.text) \ 108 108 __relocate_new_kernel_end = .; ··· 180 178 LOCK_TEXT 181 179 KPROBES_TEXT 182 180 HYPERVISOR_TEXT 183 - IDMAP_TEXT 184 181 *(.gnu.warning) 185 182 . = ALIGN(16); 186 183 *(.got) /* Global offset table */ ··· 206 205 TRAMP_TEXT 207 206 HIBERNATE_TEXT 208 207 KEXEC_TEXT 208 + IDMAP_TEXT 209 209 . = ALIGN(PAGE_SIZE); 210 210 } 211 211 ··· 356 354 #ifdef CONFIG_HIBERNATION 357 355 ASSERT(__hibernate_exit_text_end - __hibernate_exit_text_start <= SZ_4K, 358 356 "Hibernate exit text is bigger than 4 KiB") 357 + ASSERT(__hibernate_exit_text_start == swsusp_arch_suspend_exit, 358 + "Hibernate exit text does not start with swsusp_arch_suspend_exit") 359 359 #endif 360 360 #ifdef CONFIG_UNMAP_KERNEL_AT_EL0 361 361 ASSERT((__entry_tramp_text_end - __entry_tramp_text_start) <= 3*PAGE_SIZE, ··· 384 380 ASSERT(__relocate_new_kernel_end - __relocate_new_kernel_start <= SZ_4K, 385 381 "kexec relocation code is bigger than 4 KiB") 386 382 ASSERT(KEXEC_CONTROL_PAGE_SIZE >= SZ_4K, "KEXEC_CONTROL_PAGE_SIZE is broken") 383 + ASSERT(__relocate_new_kernel_start == arm64_relocate_new_kernel, 384 + "kexec control page does not start with arm64_relocate_new_kernel") 387 385 #endif
+1 -1
arch/arm64/kvm/debug.c
··· 328 328 * we may need to check if the host state needs to be saved. 329 329 */ 330 330 if (cpuid_feature_extract_unsigned_field(dfr0, ID_AA64DFR0_EL1_PMSVer_SHIFT) && 331 - !(read_sysreg_s(SYS_PMBIDR_EL1) & BIT(SYS_PMBIDR_EL1_P_SHIFT))) 331 + !(read_sysreg_s(SYS_PMBIDR_EL1) & BIT(PMBIDR_EL1_P_SHIFT))) 332 332 vcpu_set_flag(vcpu, DEBUG_STATE_SAVE_SPE); 333 333 334 334 /* Check if we have TRBE implemented and available at the host */
+1 -1
arch/arm64/kvm/fpsimd.c
··· 143 143 fp_state.st = &vcpu->arch.ctxt.fp_regs; 144 144 fp_state.sve_state = vcpu->arch.sve_state; 145 145 fp_state.sve_vl = vcpu->arch.sve_max_vl; 146 - fp_state.za_state = NULL; 146 + fp_state.sme_state = NULL; 147 147 fp_state.svcr = &vcpu->arch.svcr; 148 148 fp_state.fp_type = &vcpu->arch.fp_type; 149 149
+1 -1
arch/arm64/kvm/hyp/entry.S
··· 171 171 dsb sy // Synchronize against in-flight ld/st 172 172 isb // Prevent an early read of side-effect free ISR 173 173 mrs x2, isr_el1 174 - tbnz x2, #8, 2f // ISR_EL1.A 174 + tbnz x2, #ISR_EL1_A_SHIFT, 2f 175 175 ret 176 176 nop 177 177 2:
+1 -1
arch/arm64/kvm/hyp/nvhe/debug-sr.c
··· 27 27 * Check if the host is actually using it ? 28 28 */ 29 29 reg = read_sysreg_s(SYS_PMBLIMITR_EL1); 30 - if (!(reg & BIT(SYS_PMBLIMITR_EL1_E_SHIFT))) 30 + if (!(reg & BIT(PMBLIMITR_EL1_E_SHIFT))) 31 31 return; 32 32 33 33 /* Yes; save the control register and disable data generation */
+1
arch/arm64/mm/cache.S
··· 56 56 caches_clean_inval_pou_macro 57 57 ret 58 58 SYM_FUNC_END(caches_clean_inval_pou) 59 + SYM_FUNC_ALIAS(__pi_caches_clean_inval_pou, caches_clean_inval_pou) 59 60 60 61 /* 61 62 * caches_clean_inval_user_pou(start,end)
+6 -2
arch/arm64/mm/mmu.c
··· 133 133 return phys; 134 134 } 135 135 136 - static bool pgattr_change_is_safe(u64 old, u64 new) 136 + bool pgattr_change_is_safe(u64 old, u64 new) 137 137 { 138 138 /* 139 139 * The following mapping attributes may be updated in live ··· 142 142 pteval_t mask = PTE_PXN | PTE_RDONLY | PTE_WRITE | PTE_NG; 143 143 144 144 /* creating or taking down mappings is always safe */ 145 - if (old == 0 || new == 0) 145 + if (!pte_valid(__pte(old)) || !pte_valid(__pte(new))) 146 146 return true; 147 + 148 + /* A live entry's pfn should not change */ 149 + if (pte_pfn(__pte(old)) != pte_pfn(__pte(new))) 150 + return false; 147 151 148 152 /* live contiguous mappings may not be manipulated at all */ 149 153 if ((old | new) & PTE_CONT)
-2
arch/arm64/mm/proc.S
··· 110 110 * 111 111 * x0: Address of context pointer 112 112 */ 113 - .pushsection ".idmap.text", "awx" 114 113 SYM_FUNC_START(cpu_do_resume) 115 114 ldp x2, x3, [x0] 116 115 ldp x4, x5, [x0, #16] ··· 165 166 isb 166 167 ret 167 168 SYM_FUNC_END(cpu_do_resume) 168 - .popsection 169 169 #endif 170 170 171 171 .pushsection ".idmap.text", "awx"
+4 -2
arch/arm64/tools/cpucaps
··· 28 28 HAS_GENERIC_AUTH_ARCH_QARMA3 29 29 HAS_GENERIC_AUTH_ARCH_QARMA5 30 30 HAS_GENERIC_AUTH_IMP_DEF 31 - HAS_IRQ_PRIO_MASKING 31 + HAS_GIC_CPUIF_SYSREGS 32 + HAS_GIC_PRIO_MASKING 33 + HAS_GIC_PRIO_RELAXED_SYNC 32 34 HAS_LDAPR 33 35 HAS_LSE_ATOMICS 34 36 HAS_NO_FPSIMD ··· 40 38 HAS_RNG 41 39 HAS_SB 42 40 HAS_STAGE2_FWB 43 - HAS_SYSREG_GIC_CPUIF 44 41 HAS_TIDCP1 45 42 HAS_TLB_RANGE 46 43 HAS_VIRT_HOST_EXTN ··· 51 50 MTE_ASYMM 52 51 SME 53 52 SME_FA64 53 + SME2 54 54 SPECTRE_V2 55 55 SPECTRE_V3A 56 56 SPECTRE_V4
+29
arch/arm64/tools/gen-sysreg.awk
··· 44 44 define(reg "_" field "_WIDTH", msb - lsb + 1) 45 45 } 46 46 47 + # Print a field _SIGNED definition for a field 48 + function define_field_sign(reg, field, sign) { 49 + define(reg "_" field "_SIGNED", sign) 50 + } 51 + 47 52 # Parse a "<msb>[:<lsb>]" string into the global variables @msb and @lsb 48 53 function parse_bitdef(reg, field, bitdef, _bits) 49 54 { ··· 234 229 /^Raz/ && (block == "Sysreg" || block == "SysregFields") { 235 230 expect_fields(2) 236 231 parse_bitdef(reg, field, $2) 232 + 233 + next 234 + } 235 + 236 + /^SignedEnum/ { 237 + change_block("Enum<", "Sysreg", "Enum") 238 + expect_fields(3) 239 + field = $3 240 + parse_bitdef(reg, field, $2) 241 + 242 + define_field(reg, field, msb, lsb) 243 + define_field_sign(reg, field, "true") 244 + 245 + next 246 + } 247 + 248 + /^UnsignedEnum/ { 249 + change_block("Enum<", "Sysreg", "Enum") 250 + expect_fields(3) 251 + field = $3 252 + parse_bitdef(reg, field, $2) 253 + 254 + define_field(reg, field, msb, lsb) 255 + define_field_sign(reg, field, "false") 237 256 238 257 next 239 258 }
+367 -193
arch/arm64/tools/sysreg
··· 48 48 49 49 Sysreg ID_PFR0_EL1 3 0 0 1 0 50 50 Res0 63:32 51 - Enum 31:28 RAS 51 + UnsignedEnum 31:28 RAS 52 52 0b0000 NI 53 53 0b0001 RAS 54 54 0b0010 RASv1p1 55 55 EndEnum 56 - Enum 27:24 DIT 56 + UnsignedEnum 27:24 DIT 57 57 0b0000 NI 58 58 0b0001 IMP 59 59 EndEnum 60 - Enum 23:20 AMU 60 + UnsignedEnum 23:20 AMU 61 61 0b0000 NI 62 62 0b0001 AMUv1 63 63 0b0010 AMUv1p1 64 64 EndEnum 65 - Enum 19:16 CSV2 65 + UnsignedEnum 19:16 CSV2 66 66 0b0000 UNDISCLOSED 67 67 0b0001 IMP 68 68 0b0010 CSV2p1 69 69 EndEnum 70 - Enum 15:12 State3 70 + UnsignedEnum 15:12 State3 71 71 0b0000 NI 72 72 0b0001 IMP 73 73 EndEnum ··· 76 76 0b0001 NO_CV 77 77 0b0010 CV 78 78 EndEnum 79 - Enum 7:4 State1 79 + UnsignedEnum 7:4 State1 80 80 0b0000 NI 81 81 0b0001 THUMB 82 82 0b0010 THUMB2 83 83 EndEnum 84 - Enum 3:0 State0 84 + UnsignedEnum 3:0 State0 85 85 0b0000 NI 86 86 0b0001 IMP 87 87 EndEnum ··· 89 89 90 90 Sysreg ID_PFR1_EL1 3 0 0 1 1 91 91 Res0 63:32 92 - Enum 31:28 GIC 92 + UnsignedEnum 31:28 GIC 93 93 0b0000 NI 94 94 0b0001 GICv3 95 95 0b0010 GICv4p1 96 96 EndEnum 97 - Enum 27:24 Virt_frac 97 + UnsignedEnum 27:24 Virt_frac 98 98 0b0000 NI 99 99 0b0001 IMP 100 100 EndEnum ··· 103 103 0b0001 WALK_DISABLE 104 104 0b0010 SECURE_MEMORY 105 105 EndEnum 106 - Enum 19:16 GenTimer 106 + UnsignedEnum 19:16 GenTimer 107 107 0b0000 NI 108 108 0b0001 IMP 109 109 0b0010 ECV 110 110 EndEnum 111 - Enum 15:12 Virtualization 111 + UnsignedEnum 15:12 Virtualization 112 112 0b0000 NI 113 113 0b0001 IMP 114 114 EndEnum 115 - Enum 11:8 MProgMod 115 + UnsignedEnum 11:8 MProgMod 116 116 0b0000 NI 117 117 0b0001 IMP 118 118 EndEnum ··· 121 121 0b0001 EL3 122 122 0b0001 NSACR_RFR 123 123 EndEnum 124 - Enum 3:0 ProgMod 124 + UnsignedEnum 3:0 ProgMod 125 125 0b0000 NI 126 126 0b0001 IMP 127 127 EndEnum ··· 129 129 130 130 Sysreg ID_DFR0_EL1 3 0 0 1 2 131 131 Res0 63:32 132 - Enum 31:28 TraceFilt 132 + UnsignedEnum 31:28 TraceFilt 133 133 0b0000 NI 134 134 0b0001 IMP 135 135 EndEnum 136 - Enum 27:24 PerfMon 136 + UnsignedEnum 27:24 PerfMon 137 137 0b0000 NI 138 138 0b0001 PMUv1 139 139 0b0010 PMUv2 ··· 192 192 0b0001 HW 193 193 0b1111 IGNORED 194 194 EndEnum 195 - Enum 27:24 FCSE 195 + UnsignedEnum 27:24 FCSE 196 196 0b0000 NI 197 197 0b0001 IMP 198 198 EndEnum ··· 369 369 0b0001 xDIV_T32 370 370 0b0010 xDIV_A32 371 371 EndEnum 372 - Enum 23:20 Debug 372 + UnsignedEnum 23:20 Debug 373 373 0b0000 NI 374 374 0b0001 IMP 375 375 EndEnum ··· 380 380 0b0011 MRRC 381 381 0b0100 MRRC2 382 382 EndEnum 383 - Enum 15:12 CmpBranch 383 + UnsignedEnum 15:12 CmpBranch 384 384 0b0000 NI 385 385 0b0001 IMP 386 386 EndEnum 387 - Enum 11:8 BitField 387 + UnsignedEnum 11:8 BitField 388 388 0b0000 NI 389 389 0b0001 IMP 390 390 EndEnum 391 - Enum 7:4 BitCount 391 + UnsignedEnum 7:4 BitCount 392 392 0b0000 NI 393 393 0b0001 IMP 394 394 EndEnum 395 - Enum 3:0 Swap 395 + UnsignedEnum 3:0 Swap 396 396 0b0000 NI 397 397 0b0001 IMP 398 398 EndEnum ··· 562 562 563 563 Sysreg ID_ISAR5_EL1 3 0 0 2 5 564 564 Res0 63:32 565 - Enum 31:28 VCMA 565 + UnsignedEnum 31:28 VCMA 566 566 0b0000 NI 567 567 0b0001 IMP 568 568 EndEnum 569 - Enum 27:24 RDM 569 + UnsignedEnum 27:24 RDM 570 570 0b0000 NI 571 571 0b0001 IMP 572 572 EndEnum 573 573 Res0 23:20 574 - Enum 19:16 CRC32 574 + UnsignedEnum 19:16 CRC32 575 575 0b0000 NI 576 576 0b0001 IMP 577 577 EndEnum 578 - Enum 15:12 SHA2 578 + UnsignedEnum 15:12 SHA2 579 579 0b0000 NI 580 580 0b0001 IMP 581 581 EndEnum 582 - Enum 11:8 SHA1 582 + UnsignedEnum 11:8 SHA1 583 583 0b0000 NI 584 584 0b0001 IMP 585 585 EndEnum 586 - Enum 7:4 AES 586 + UnsignedEnum 7:4 AES 587 587 0b0000 NI 588 588 0b0001 IMP 589 589 0b0010 VMULL 590 590 EndEnum 591 - Enum 3:0 SEVL 591 + UnsignedEnum 3:0 SEVL 592 592 0b0000 NI 593 593 0b0001 IMP 594 594 EndEnum ··· 596 596 597 597 Sysreg ID_ISAR6_EL1 3 0 0 2 7 598 598 Res0 63:28 599 - Enum 27:24 I8MM 599 + UnsignedEnum 27:24 I8MM 600 600 0b0000 NI 601 601 0b0001 IMP 602 602 EndEnum 603 - Enum 23:20 BF16 603 + UnsignedEnum 23:20 BF16 604 604 0b0000 NI 605 605 0b0001 IMP 606 606 EndEnum 607 - Enum 19:16 SPECRES 607 + UnsignedEnum 19:16 SPECRES 608 608 0b0000 NI 609 609 0b0001 IMP 610 610 EndEnum 611 - Enum 15:12 SB 611 + UnsignedEnum 15:12 SB 612 612 0b0000 NI 613 613 0b0001 IMP 614 614 EndEnum 615 - Enum 11:8 FHM 615 + UnsignedEnum 11:8 FHM 616 616 0b0000 NI 617 617 0b0001 IMP 618 618 EndEnum 619 - Enum 7:4 DP 619 + UnsignedEnum 7:4 DP 620 620 0b0000 NI 621 621 0b0001 IMP 622 622 EndEnum 623 - Enum 3:0 JSCVT 623 + UnsignedEnum 3:0 JSCVT 624 624 0b0000 NI 625 625 0b0001 IMP 626 626 EndEnum ··· 628 628 629 629 Sysreg ID_MMFR4_EL1 3 0 0 2 6 630 630 Res0 63:32 631 - Enum 31:28 EVT 631 + UnsignedEnum 31:28 EVT 632 632 0b0000 NI 633 633 0b0001 NO_TLBIS 634 634 0b0010 TLBIS 635 635 EndEnum 636 - Enum 27:24 CCIDX 636 + UnsignedEnum 27:24 CCIDX 637 637 0b0000 NI 638 638 0b0001 IMP 639 639 EndEnum 640 - Enum 23:20 LSM 640 + UnsignedEnum 23:20 LSM 641 641 0b0000 NI 642 642 0b0001 IMP 643 643 EndEnum 644 - Enum 19:16 HPDS 644 + UnsignedEnum 19:16 HPDS 645 645 0b0000 NI 646 646 0b0001 AA32HPD 647 647 0b0010 HPDS2 648 648 EndEnum 649 - Enum 15:12 CnP 649 + UnsignedEnum 15:12 CnP 650 650 0b0000 NI 651 651 0b0001 IMP 652 652 EndEnum 653 - Enum 11:8 XNX 653 + UnsignedEnum 11:8 XNX 654 654 0b0000 NI 655 655 0b0001 IMP 656 656 EndEnum 657 - Enum 7:4 AC2 657 + UnsignedEnum 7:4 AC2 658 658 0b0000 NI 659 659 0b0001 IMP 660 660 EndEnum 661 - Enum 3:0 SpecSEI 661 + UnsignedEnum 3:0 SpecSEI 662 662 0b0000 NI 663 663 0b0001 IMP 664 664 EndEnum ··· 666 666 667 667 Sysreg MVFR0_EL1 3 0 0 3 0 668 668 Res0 63:32 669 - Enum 31:28 FPRound 669 + UnsignedEnum 31:28 FPRound 670 670 0b0000 NI 671 671 0b0001 IMP 672 672 EndEnum 673 - Enum 27:24 FPShVec 673 + UnsignedEnum 27:24 FPShVec 674 674 0b0000 NI 675 675 0b0001 IMP 676 676 EndEnum 677 - Enum 23:20 FPSqrt 677 + UnsignedEnum 23:20 FPSqrt 678 678 0b0000 NI 679 679 0b0001 IMP 680 680 EndEnum 681 - Enum 19:16 FPDivide 681 + UnsignedEnum 19:16 FPDivide 682 682 0b0000 NI 683 683 0b0001 IMP 684 684 EndEnum 685 - Enum 15:12 FPTrap 685 + UnsignedEnum 15:12 FPTrap 686 686 0b0000 NI 687 687 0b0001 IMP 688 688 EndEnum 689 - Enum 11:8 FPDP 689 + UnsignedEnum 11:8 FPDP 690 690 0b0000 NI 691 691 0b0001 VFPv2 692 - 0b0001 VFPv3 692 + 0b0010 VFPv3 693 693 EndEnum 694 - Enum 7:4 FPSP 694 + UnsignedEnum 7:4 FPSP 695 695 0b0000 NI 696 696 0b0001 VFPv2 697 - 0b0001 VFPv3 697 + 0b0010 VFPv3 698 698 EndEnum 699 699 Enum 3:0 SIMDReg 700 700 0b0000 NI 701 701 0b0001 IMP_16x64 702 - 0b0001 IMP_32x64 702 + 0b0010 IMP_32x64 703 703 EndEnum 704 704 EndSysreg 705 705 706 706 Sysreg MVFR1_EL1 3 0 0 3 1 707 707 Res0 63:32 708 - Enum 31:28 SIMDFMAC 708 + UnsignedEnum 31:28 SIMDFMAC 709 709 0b0000 NI 710 710 0b0001 IMP 711 711 EndEnum 712 - Enum 27:24 FPHP 712 + UnsignedEnum 27:24 FPHP 713 713 0b0000 NI 714 714 0b0001 FPHP 715 715 0b0010 FPHP_CONV 716 716 0b0011 FP16 717 717 EndEnum 718 - Enum 23:20 SIMDHP 718 + UnsignedEnum 23:20 SIMDHP 719 719 0b0000 NI 720 720 0b0001 SIMDHP 721 - 0b0001 SIMDHP_FLOAT 721 + 0b0010 SIMDHP_FLOAT 722 722 EndEnum 723 - Enum 19:16 SIMDSP 723 + UnsignedEnum 19:16 SIMDSP 724 724 0b0000 NI 725 725 0b0001 IMP 726 726 EndEnum 727 - Enum 15:12 SIMDInt 727 + UnsignedEnum 15:12 SIMDInt 728 728 0b0000 NI 729 729 0b0001 IMP 730 730 EndEnum 731 - Enum 11:8 SIMDLS 731 + UnsignedEnum 11:8 SIMDLS 732 732 0b0000 NI 733 733 0b0001 IMP 734 734 EndEnum 735 - Enum 7:4 FPDNaN 735 + UnsignedEnum 7:4 FPDNaN 736 736 0b0000 NI 737 737 0b0001 IMP 738 738 EndEnum 739 - Enum 3:0 FPFtZ 739 + UnsignedEnum 3:0 FPFtZ 740 740 0b0000 NI 741 741 0b0001 IMP 742 742 EndEnum ··· 761 761 762 762 Sysreg ID_PFR2_EL1 3 0 0 3 4 763 763 Res0 63:12 764 - Enum 11:8 RAS_frac 764 + UnsignedEnum 11:8 RAS_frac 765 765 0b0000 NI 766 766 0b0001 RASv1p1 767 767 EndEnum 768 - Enum 7:4 SSBS 768 + UnsignedEnum 7:4 SSBS 769 769 0b0000 NI 770 770 0b0001 IMP 771 771 EndEnum 772 - Enum 3:0 CSV3 772 + UnsignedEnum 3:0 CSV3 773 773 0b0000 NI 774 774 0b0001 IMP 775 775 EndEnum ··· 777 777 778 778 Sysreg ID_DFR1_EL1 3 0 0 3 5 779 779 Res0 63:8 780 - Enum 7:4 HPMN0 780 + UnsignedEnum 7:4 HPMN0 781 781 0b0000 NI 782 782 0b0001 IMP 783 783 EndEnum ··· 790 790 791 791 Sysreg ID_MMFR5_EL1 3 0 0 3 6 792 792 Res0 63:8 793 - Enum 7:4 nTLBPA 793 + UnsignedEnum 7:4 nTLBPA 794 794 0b0000 NI 795 795 0b0001 IMP 796 796 EndEnum 797 - Enum 3:0 ETS 797 + UnsignedEnum 3:0 ETS 798 798 0b0000 NI 799 799 0b0001 IMP 800 800 EndEnum 801 801 EndSysreg 802 802 803 803 Sysreg ID_AA64PFR0_EL1 3 0 0 4 0 804 - Enum 63:60 CSV3 804 + UnsignedEnum 63:60 CSV3 805 805 0b0000 NI 806 806 0b0001 IMP 807 807 EndEnum 808 - Enum 59:56 CSV2 808 + UnsignedEnum 59:56 CSV2 809 809 0b0000 NI 810 810 0b0001 IMP 811 811 0b0010 CSV2_2 812 812 0b0011 CSV2_3 813 813 EndEnum 814 - Enum 55:52 RME 814 + UnsignedEnum 55:52 RME 815 815 0b0000 NI 816 816 0b0001 IMP 817 817 EndEnum 818 - Enum 51:48 DIT 818 + UnsignedEnum 51:48 DIT 819 819 0b0000 NI 820 820 0b0001 IMP 821 821 EndEnum 822 - Enum 47:44 AMU 822 + UnsignedEnum 47:44 AMU 823 823 0b0000 NI 824 824 0b0001 IMP 825 825 0b0010 V1P1 826 826 EndEnum 827 - Enum 43:40 MPAM 827 + UnsignedEnum 43:40 MPAM 828 828 0b0000 0 829 829 0b0001 1 830 830 EndEnum 831 - Enum 39:36 SEL2 831 + UnsignedEnum 39:36 SEL2 832 832 0b0000 NI 833 833 0b0001 IMP 834 834 EndEnum 835 - Enum 35:32 SVE 835 + UnsignedEnum 35:32 SVE 836 836 0b0000 NI 837 837 0b0001 IMP 838 838 EndEnum 839 - Enum 31:28 RAS 839 + UnsignedEnum 31:28 RAS 840 840 0b0000 NI 841 841 0b0001 IMP 842 842 0b0010 V1P1 843 843 EndEnum 844 - Enum 27:24 GIC 844 + UnsignedEnum 27:24 GIC 845 845 0b0000 NI 846 846 0b0001 IMP 847 847 0b0010 V4P1 848 848 EndEnum 849 - Enum 23:20 AdvSIMD 849 + SignedEnum 23:20 AdvSIMD 850 850 0b0000 IMP 851 851 0b0001 FP16 852 852 0b1111 NI 853 853 EndEnum 854 - Enum 19:16 FP 854 + SignedEnum 19:16 FP 855 855 0b0000 IMP 856 856 0b0001 FP16 857 857 0b1111 NI 858 858 EndEnum 859 - Enum 15:12 EL3 859 + UnsignedEnum 15:12 EL3 860 860 0b0000 NI 861 861 0b0001 IMP 862 862 0b0010 AARCH32 863 863 EndEnum 864 - Enum 11:8 EL2 864 + UnsignedEnum 11:8 EL2 865 865 0b0000 NI 866 866 0b0001 IMP 867 867 0b0010 AARCH32 868 868 EndEnum 869 - Enum 7:4 EL1 869 + UnsignedEnum 7:4 EL1 870 870 0b0001 IMP 871 871 0b0010 AARCH32 872 872 EndEnum 873 - Enum 3:0 EL0 873 + UnsignedEnum 3:0 EL0 874 874 0b0001 IMP 875 875 0b0010 AARCH32 876 876 EndEnum ··· 878 878 879 879 Sysreg ID_AA64PFR1_EL1 3 0 0 4 1 880 880 Res0 63:40 881 - Enum 39:36 NMI 881 + UnsignedEnum 39:36 NMI 882 882 0b0000 NI 883 883 0b0001 IMP 884 884 EndEnum 885 - Enum 35:32 CSV2_frac 885 + UnsignedEnum 35:32 CSV2_frac 886 886 0b0000 NI 887 887 0b0001 CSV2_1p1 888 888 0b0010 CSV2_1p2 889 889 EndEnum 890 - Enum 31:28 RNDR_trap 890 + UnsignedEnum 31:28 RNDR_trap 891 891 0b0000 NI 892 892 0b0001 IMP 893 893 EndEnum 894 - Enum 27:24 SME 894 + UnsignedEnum 27:24 SME 895 895 0b0000 NI 896 896 0b0001 IMP 897 + 0b0010 SME2 897 898 EndEnum 898 899 Res0 23:20 899 - Enum 19:16 MPAM_frac 900 + UnsignedEnum 19:16 MPAM_frac 900 901 0b0000 MINOR_0 901 902 0b0001 MINOR_1 902 903 EndEnum 903 - Enum 15:12 RAS_frac 904 + UnsignedEnum 15:12 RAS_frac 904 905 0b0000 NI 905 906 0b0001 RASv1p1 906 907 EndEnum 907 - Enum 11:8 MTE 908 + UnsignedEnum 11:8 MTE 908 909 0b0000 NI 909 910 0b0001 IMP 910 911 0b0010 MTE2 911 912 0b0011 MTE3 912 913 EndEnum 913 - Enum 7:4 SSBS 914 + UnsignedEnum 7:4 SSBS 914 915 0b0000 NI 915 916 0b0001 IMP 916 917 0b0010 SSBS2 917 918 EndEnum 918 - Enum 3:0 BT 919 + UnsignedEnum 3:0 BT 919 920 0b0000 NI 920 921 0b0001 IMP 921 922 EndEnum ··· 924 923 925 924 Sysreg ID_AA64ZFR0_EL1 3 0 0 4 4 926 925 Res0 63:60 927 - Enum 59:56 F64MM 926 + UnsignedEnum 59:56 F64MM 928 927 0b0000 NI 929 928 0b0001 IMP 930 929 EndEnum 931 - Enum 55:52 F32MM 930 + UnsignedEnum 55:52 F32MM 932 931 0b0000 NI 933 932 0b0001 IMP 934 933 EndEnum 935 934 Res0 51:48 936 - Enum 47:44 I8MM 935 + UnsignedEnum 47:44 I8MM 937 936 0b0000 NI 938 937 0b0001 IMP 939 938 EndEnum 940 - Enum 43:40 SM4 939 + UnsignedEnum 43:40 SM4 941 940 0b0000 NI 942 941 0b0001 IMP 943 942 EndEnum 944 943 Res0 39:36 945 - Enum 35:32 SHA3 944 + UnsignedEnum 35:32 SHA3 946 945 0b0000 NI 947 946 0b0001 IMP 948 947 EndEnum 949 948 Res0 31:24 950 - Enum 23:20 BF16 949 + UnsignedEnum 23:20 BF16 951 950 0b0000 NI 952 951 0b0001 IMP 953 952 0b0010 EBF16 954 953 EndEnum 955 - Enum 19:16 BitPerm 954 + UnsignedEnum 19:16 BitPerm 956 955 0b0000 NI 957 956 0b0001 IMP 958 957 EndEnum 959 958 Res0 15:8 960 - Enum 7:4 AES 959 + UnsignedEnum 7:4 AES 961 960 0b0000 NI 962 961 0b0001 IMP 963 962 0b0010 PMULL128 964 963 EndEnum 965 - Enum 3:0 SVEver 964 + UnsignedEnum 3:0 SVEver 966 965 0b0000 IMP 967 966 0b0001 SVE2 968 967 0b0010 SVE2p1 ··· 970 969 EndSysreg 971 970 972 971 Sysreg ID_AA64SMFR0_EL1 3 0 0 4 5 973 - Enum 63 FA64 972 + UnsignedEnum 63 FA64 974 973 0b0 NI 975 974 0b1 IMP 976 975 EndEnum 977 976 Res0 62:60 978 - Enum 59:56 SMEver 977 + UnsignedEnum 59:56 SMEver 978 + 0b0000 SME 979 + 0b0001 SME2 980 + 0b0010 SME2p1 979 981 0b0000 IMP 980 982 EndEnum 981 - Enum 55:52 I16I64 983 + UnsignedEnum 55:52 I16I64 982 984 0b0000 NI 983 985 0b1111 IMP 984 986 EndEnum 985 987 Res0 51:49 986 - Enum 48 F64F64 988 + UnsignedEnum 48 F64F64 987 989 0b0 NI 988 990 0b1 IMP 989 991 EndEnum 990 - Res0 47:40 991 - Enum 39:36 I8I32 992 + UnsignedEnum 47:44 I16I32 993 + 0b0000 NI 994 + 0b0101 IMP 995 + EndEnum 996 + UnsignedEnum 43 B16B16 997 + 0b0 NI 998 + 0b1 IMP 999 + EndEnum 1000 + UnsignedEnum 42 F16F16 1001 + 0b0 NI 1002 + 0b1 IMP 1003 + EndEnum 1004 + Res0 41:40 1005 + UnsignedEnum 39:36 I8I32 992 1006 0b0000 NI 993 1007 0b1111 IMP 994 1008 EndEnum 995 - Enum 35 F16F32 1009 + UnsignedEnum 35 F16F32 996 1010 0b0 NI 997 1011 0b1 IMP 998 1012 EndEnum 999 - Enum 34 B16F32 1013 + UnsignedEnum 34 B16F32 1000 1014 0b0 NI 1001 1015 0b1 IMP 1002 1016 EndEnum 1003 - Res0 33 1004 - Enum 32 F32F32 1017 + UnsignedEnum 33 BI32I32 1018 + 0b0 NI 1019 + 0b1 IMP 1020 + EndEnum 1021 + UnsignedEnum 32 F32F32 1005 1022 0b0 NI 1006 1023 0b1 IMP 1007 1024 EndEnum ··· 1032 1013 0b0001 DEF 1033 1014 EndEnum 1034 1015 Res0 59:56 1035 - Enum 55:52 BRBE 1016 + UnsignedEnum 55:52 BRBE 1036 1017 0b0000 NI 1037 1018 0b0001 IMP 1038 1019 0b0010 BRBE_V1P1 ··· 1042 1023 0b0001 IMP 1043 1024 0b1111 NI 1044 1025 EndEnum 1045 - Enum 47:44 TraceBuffer 1026 + UnsignedEnum 47:44 TraceBuffer 1046 1027 0b0000 NI 1047 1028 0b0001 IMP 1048 1029 EndEnum 1049 - Enum 43:40 TraceFilt 1030 + UnsignedEnum 43:40 TraceFilt 1050 1031 0b0000 NI 1051 1032 0b0001 IMP 1052 1033 EndEnum 1053 - Enum 39:36 DoubleLock 1034 + UnsignedEnum 39:36 DoubleLock 1054 1035 0b0000 IMP 1055 1036 0b1111 NI 1056 1037 EndEnum 1057 - Enum 35:32 PMSVer 1038 + UnsignedEnum 35:32 PMSVer 1058 1039 0b0000 NI 1059 1040 0b0001 IMP 1060 1041 0b0010 V1P1 ··· 1066 1047 Field 23:20 WRPs 1067 1048 Res0 19:16 1068 1049 Field 15:12 BRPs 1069 - Enum 11:8 PMUVer 1050 + UnsignedEnum 11:8 PMUVer 1070 1051 0b0000 NI 1071 1052 0b0001 IMP 1072 1053 0b0100 V3P1 ··· 1076 1057 0b1000 V3P8 1077 1058 0b1111 IMP_DEF 1078 1059 EndEnum 1079 - Enum 7:4 TraceVer 1060 + UnsignedEnum 7:4 TraceVer 1080 1061 0b0000 NI 1081 1062 0b0001 IMP 1082 1063 EndEnum 1083 - Enum 3:0 DebugVer 1064 + UnsignedEnum 3:0 DebugVer 1084 1065 0b0110 IMP 1085 1066 0b0111 VHE 1086 1067 0b1000 V8P2 ··· 1110 1091 EndSysreg 1111 1092 1112 1093 Sysreg ID_AA64ISAR0_EL1 3 0 0 6 0 1113 - Enum 63:60 RNDR 1094 + UnsignedEnum 63:60 RNDR 1114 1095 0b0000 NI 1115 1096 0b0001 IMP 1116 1097 EndEnum 1117 - Enum 59:56 TLB 1098 + UnsignedEnum 59:56 TLB 1118 1099 0b0000 NI 1119 1100 0b0001 OS 1120 1101 0b0010 RANGE 1121 1102 EndEnum 1122 - Enum 55:52 TS 1103 + UnsignedEnum 55:52 TS 1123 1104 0b0000 NI 1124 1105 0b0001 FLAGM 1125 1106 0b0010 FLAGM2 1126 1107 EndEnum 1127 - Enum 51:48 FHM 1108 + UnsignedEnum 51:48 FHM 1128 1109 0b0000 NI 1129 1110 0b0001 IMP 1130 1111 EndEnum 1131 - Enum 47:44 DP 1112 + UnsignedEnum 47:44 DP 1132 1113 0b0000 NI 1133 1114 0b0001 IMP 1134 1115 EndEnum 1135 - Enum 43:40 SM4 1116 + UnsignedEnum 43:40 SM4 1136 1117 0b0000 NI 1137 1118 0b0001 IMP 1138 1119 EndEnum 1139 - Enum 39:36 SM3 1120 + UnsignedEnum 39:36 SM3 1140 1121 0b0000 NI 1141 1122 0b0001 IMP 1142 1123 EndEnum 1143 - Enum 35:32 SHA3 1124 + UnsignedEnum 35:32 SHA3 1144 1125 0b0000 NI 1145 1126 0b0001 IMP 1146 1127 EndEnum 1147 - Enum 31:28 RDM 1128 + UnsignedEnum 31:28 RDM 1148 1129 0b0000 NI 1149 1130 0b0001 IMP 1150 1131 EndEnum 1151 - Enum 27:24 TME 1132 + UnsignedEnum 27:24 TME 1152 1133 0b0000 NI 1153 1134 0b0001 IMP 1154 1135 EndEnum 1155 - Enum 23:20 ATOMIC 1136 + UnsignedEnum 23:20 ATOMIC 1156 1137 0b0000 NI 1157 1138 0b0010 IMP 1158 1139 EndEnum 1159 - Enum 19:16 CRC32 1140 + UnsignedEnum 19:16 CRC32 1160 1141 0b0000 NI 1161 1142 0b0001 IMP 1162 1143 EndEnum 1163 - Enum 15:12 SHA2 1144 + UnsignedEnum 15:12 SHA2 1164 1145 0b0000 NI 1165 1146 0b0001 SHA256 1166 1147 0b0010 SHA512 1167 1148 EndEnum 1168 - Enum 11:8 SHA1 1149 + UnsignedEnum 11:8 SHA1 1169 1150 0b0000 NI 1170 1151 0b0001 IMP 1171 1152 EndEnum 1172 - Enum 7:4 AES 1153 + UnsignedEnum 7:4 AES 1173 1154 0b0000 NI 1174 1155 0b0001 AES 1175 1156 0b0010 PMULL ··· 1178 1159 EndSysreg 1179 1160 1180 1161 Sysreg ID_AA64ISAR1_EL1 3 0 0 6 1 1181 - Enum 63:60 LS64 1162 + UnsignedEnum 63:60 LS64 1182 1163 0b0000 NI 1183 1164 0b0001 LS64 1184 1165 0b0010 LS64_V 1185 1166 0b0011 LS64_ACCDATA 1186 1167 EndEnum 1187 - Enum 59:56 XS 1168 + UnsignedEnum 59:56 XS 1188 1169 0b0000 NI 1189 1170 0b0001 IMP 1190 1171 EndEnum 1191 - Enum 55:52 I8MM 1172 + UnsignedEnum 55:52 I8MM 1192 1173 0b0000 NI 1193 1174 0b0001 IMP 1194 1175 EndEnum 1195 - Enum 51:48 DGH 1176 + UnsignedEnum 51:48 DGH 1196 1177 0b0000 NI 1197 1178 0b0001 IMP 1198 1179 EndEnum 1199 - Enum 47:44 BF16 1180 + UnsignedEnum 47:44 BF16 1200 1181 0b0000 NI 1201 1182 0b0001 IMP 1202 1183 0b0010 EBF16 1203 1184 EndEnum 1204 - Enum 43:40 SPECRES 1185 + UnsignedEnum 43:40 SPECRES 1205 1186 0b0000 NI 1206 1187 0b0001 IMP 1207 1188 EndEnum 1208 - Enum 39:36 SB 1189 + UnsignedEnum 39:36 SB 1209 1190 0b0000 NI 1210 1191 0b0001 IMP 1211 1192 EndEnum 1212 - Enum 35:32 FRINTTS 1193 + UnsignedEnum 35:32 FRINTTS 1213 1194 0b0000 NI 1214 1195 0b0001 IMP 1215 1196 EndEnum 1216 - Enum 31:28 GPI 1197 + UnsignedEnum 31:28 GPI 1217 1198 0b0000 NI 1218 1199 0b0001 IMP 1219 1200 EndEnum 1220 - Enum 27:24 GPA 1201 + UnsignedEnum 27:24 GPA 1221 1202 0b0000 NI 1222 1203 0b0001 IMP 1223 1204 EndEnum 1224 - Enum 23:20 LRCPC 1205 + UnsignedEnum 23:20 LRCPC 1225 1206 0b0000 NI 1226 1207 0b0001 IMP 1227 1208 0b0010 LRCPC2 1228 1209 EndEnum 1229 - Enum 19:16 FCMA 1210 + UnsignedEnum 19:16 FCMA 1230 1211 0b0000 NI 1231 1212 0b0001 IMP 1232 1213 EndEnum 1233 - Enum 15:12 JSCVT 1214 + UnsignedEnum 15:12 JSCVT 1234 1215 0b0000 NI 1235 1216 0b0001 IMP 1236 1217 EndEnum 1237 - Enum 11:8 API 1218 + UnsignedEnum 11:8 API 1238 1219 0b0000 NI 1239 1220 0b0001 PAuth 1240 1221 0b0010 EPAC ··· 1242 1223 0b0100 FPAC 1243 1224 0b0101 FPACCOMBINE 1244 1225 EndEnum 1245 - Enum 7:4 APA 1226 + UnsignedEnum 7:4 APA 1246 1227 0b0000 NI 1247 1228 0b0001 PAuth 1248 1229 0b0010 EPAC ··· 1250 1231 0b0100 FPAC 1251 1232 0b0101 FPACCOMBINE 1252 1233 EndEnum 1253 - Enum 3:0 DPB 1234 + UnsignedEnum 3:0 DPB 1254 1235 0b0000 NI 1255 1236 0b0001 IMP 1256 1237 0b0010 DPB2 ··· 1259 1240 1260 1241 Sysreg ID_AA64ISAR2_EL1 3 0 0 6 2 1261 1242 Res0 63:56 1262 - Enum 55:52 CSSC 1243 + UnsignedEnum 55:52 CSSC 1263 1244 0b0000 NI 1264 1245 0b0001 IMP 1265 1246 EndEnum 1266 - Enum 51:48 RPRFM 1247 + UnsignedEnum 51:48 RPRFM 1267 1248 0b0000 NI 1268 1249 0b0001 IMP 1269 1250 EndEnum 1270 1251 Res0 47:28 1271 - Enum 27:24 PAC_frac 1252 + UnsignedEnum 27:24 PAC_frac 1272 1253 0b0000 NI 1273 1254 0b0001 IMP 1274 1255 EndEnum 1275 - Enum 23:20 BC 1256 + UnsignedEnum 23:20 BC 1276 1257 0b0000 NI 1277 1258 0b0001 IMP 1278 1259 EndEnum 1279 - Enum 19:16 MOPS 1260 + UnsignedEnum 19:16 MOPS 1280 1261 0b0000 NI 1281 1262 0b0001 IMP 1282 1263 EndEnum 1283 - Enum 15:12 APA3 1264 + UnsignedEnum 15:12 APA3 1284 1265 0b0000 NI 1285 1266 0b0001 PAuth 1286 1267 0b0010 EPAC ··· 1288 1269 0b0100 FPAC 1289 1270 0b0101 FPACCOMBINE 1290 1271 EndEnum 1291 - Enum 11:8 GPA3 1272 + UnsignedEnum 11:8 GPA3 1292 1273 0b0000 NI 1293 1274 0b0001 IMP 1294 1275 EndEnum 1295 - Enum 7:4 RPRES 1276 + UnsignedEnum 7:4 RPRES 1296 1277 0b0000 NI 1297 1278 0b0001 IMP 1298 1279 EndEnum 1299 - Enum 3:0 WFxT 1280 + UnsignedEnum 3:0 WFxT 1300 1281 0b0000 NI 1301 1282 0b0010 IMP 1302 1283 EndEnum 1303 1284 EndSysreg 1304 1285 1305 1286 Sysreg ID_AA64MMFR0_EL1 3 0 0 7 0 1306 - Enum 63:60 ECV 1287 + UnsignedEnum 63:60 ECV 1307 1288 0b0000 NI 1308 1289 0b0001 IMP 1309 1290 0b0010 CNTPOFF 1310 1291 EndEnum 1311 - Enum 59:56 FGT 1292 + UnsignedEnum 59:56 FGT 1312 1293 0b0000 NI 1313 1294 0b0001 IMP 1314 1295 EndEnum 1315 1296 Res0 55:48 1316 - Enum 47:44 EXS 1297 + UnsignedEnum 47:44 EXS 1317 1298 0b0000 NI 1318 1299 0b0001 IMP 1319 1300 EndEnum ··· 1348 1329 0b0001 IMP 1349 1330 0b0010 52_BIT 1350 1331 EndEnum 1351 - Enum 19:16 BIGENDEL0 1332 + UnsignedEnum 19:16 BIGENDEL0 1352 1333 0b0000 NI 1353 1334 0b0001 IMP 1354 1335 EndEnum 1355 - Enum 15:12 SNSMEM 1336 + UnsignedEnum 15:12 SNSMEM 1356 1337 0b0000 NI 1357 1338 0b0001 IMP 1358 1339 EndEnum 1359 - Enum 11:8 BIGEND 1340 + UnsignedEnum 11:8 BIGEND 1360 1341 0b0000 NI 1361 1342 0b0001 IMP 1362 1343 EndEnum ··· 1376 1357 EndSysreg 1377 1358 1378 1359 Sysreg ID_AA64MMFR1_EL1 3 0 0 7 1 1379 - Enum 63:60 ECBHB 1360 + UnsignedEnum 63:60 ECBHB 1380 1361 0b0000 NI 1381 1362 0b0001 IMP 1382 1363 EndEnum 1383 - Enum 59:56 CMOW 1364 + UnsignedEnum 59:56 CMOW 1384 1365 0b0000 NI 1385 1366 0b0001 IMP 1386 1367 EndEnum 1387 - Enum 55:52 TIDCP1 1368 + UnsignedEnum 55:52 TIDCP1 1388 1369 0b0000 NI 1389 1370 0b0001 IMP 1390 1371 EndEnum 1391 - Enum 51:48 nTLBPA 1372 + UnsignedEnum 51:48 nTLBPA 1392 1373 0b0000 NI 1393 1374 0b0001 IMP 1394 1375 EndEnum 1395 - Enum 47:44 AFP 1376 + UnsignedEnum 47:44 AFP 1396 1377 0b0000 NI 1397 1378 0b0001 IMP 1398 1379 EndEnum 1399 - Enum 43:40 HCX 1380 + UnsignedEnum 43:40 HCX 1400 1381 0b0000 NI 1401 1382 0b0001 IMP 1402 1383 EndEnum 1403 - Enum 39:36 ETS 1384 + UnsignedEnum 39:36 ETS 1404 1385 0b0000 NI 1405 1386 0b0001 IMP 1406 1387 EndEnum 1407 - Enum 35:32 TWED 1388 + UnsignedEnum 35:32 TWED 1408 1389 0b0000 NI 1409 1390 0b0001 IMP 1410 1391 EndEnum 1411 - Enum 31:28 XNX 1392 + UnsignedEnum 31:28 XNX 1412 1393 0b0000 NI 1413 1394 0b0001 IMP 1414 1395 EndEnum 1415 - Enum 27:24 SpecSEI 1396 + UnsignedEnum 27:24 SpecSEI 1416 1397 0b0000 NI 1417 1398 0b0001 IMP 1418 1399 EndEnum 1419 - Enum 23:20 PAN 1400 + UnsignedEnum 23:20 PAN 1420 1401 0b0000 NI 1421 1402 0b0001 IMP 1422 1403 0b0010 PAN2 1423 1404 0b0011 PAN3 1424 1405 EndEnum 1425 - Enum 19:16 LO 1406 + UnsignedEnum 19:16 LO 1426 1407 0b0000 NI 1427 1408 0b0001 IMP 1428 1409 EndEnum 1429 - Enum 15:12 HPDS 1410 + UnsignedEnum 15:12 HPDS 1430 1411 0b0000 NI 1431 1412 0b0001 IMP 1432 1413 0b0010 HPDS2 1433 1414 EndEnum 1434 - Enum 11:8 VH 1415 + UnsignedEnum 11:8 VH 1435 1416 0b0000 NI 1436 1417 0b0001 IMP 1437 1418 EndEnum ··· 1439 1420 0b0000 8 1440 1421 0b0010 16 1441 1422 EndEnum 1442 - Enum 3:0 HAFDBS 1423 + UnsignedEnum 3:0 HAFDBS 1443 1424 0b0000 NI 1444 1425 0b0001 AF 1445 1426 0b0010 DBM ··· 1447 1428 EndSysreg 1448 1429 1449 1430 Sysreg ID_AA64MMFR2_EL1 3 0 0 7 2 1450 - Enum 63:60 E0PD 1431 + UnsignedEnum 63:60 E0PD 1451 1432 0b0000 NI 1452 1433 0b0001 IMP 1453 1434 EndEnum 1454 - Enum 59:56 EVT 1435 + UnsignedEnum 59:56 EVT 1455 1436 0b0000 NI 1456 1437 0b0001 IMP 1457 1438 0b0010 TTLBxS 1458 1439 EndEnum 1459 - Enum 55:52 BBM 1440 + UnsignedEnum 55:52 BBM 1460 1441 0b0000 0 1461 1442 0b0001 1 1462 1443 0b0010 2 1463 1444 EndEnum 1464 - Enum 51:48 TTL 1445 + UnsignedEnum 51:48 TTL 1465 1446 0b0000 NI 1466 1447 0b0001 IMP 1467 1448 EndEnum 1468 1449 Res0 47:44 1469 - Enum 43:40 FWB 1450 + UnsignedEnum 43:40 FWB 1470 1451 0b0000 NI 1471 1452 0b0001 IMP 1472 1453 EndEnum ··· 1474 1455 0b0000 0x0 1475 1456 0b0001 0x18 1476 1457 EndEnum 1477 - Enum 35:32 AT 1458 + UnsignedEnum 35:32 AT 1478 1459 0b0000 NI 1479 1460 0b0001 IMP 1480 1461 EndEnum ··· 1482 1463 0b0000 39 1483 1464 0b0001 48_47 1484 1465 EndEnum 1485 - Enum 27:24 NV 1466 + UnsignedEnum 27:24 NV 1486 1467 0b0000 NI 1487 1468 0b0001 IMP 1488 1469 0b0010 NV2 ··· 1495 1476 0b0000 48 1496 1477 0b0001 52 1497 1478 EndEnum 1498 - Enum 15:12 IESB 1479 + UnsignedEnum 15:12 IESB 1499 1480 0b0000 NI 1500 1481 0b0001 IMP 1501 1482 EndEnum 1502 - Enum 11:8 LSM 1483 + UnsignedEnum 11:8 LSM 1503 1484 0b0000 NI 1504 1485 0b0001 IMP 1505 1486 EndEnum 1506 - Enum 7:4 UAO 1487 + UnsignedEnum 7:4 UAO 1507 1488 0b0000 NI 1508 1489 0b0001 IMP 1509 1490 EndEnum 1510 - Enum 3:0 CnP 1491 + UnsignedEnum 3:0 CnP 1511 1492 0b0000 NI 1512 1493 0b0001 IMP 1513 1494 EndEnum ··· 1618 1599 SysregFields SMCR_ELx 1619 1600 Res0 63:32 1620 1601 Field 31 FA64 1621 - Res0 30:9 1602 + Field 30 EZT0 1603 + Res0 29:9 1622 1604 Raz 8:4 1623 1605 Field 3:0 LEN 1624 1606 EndSysregFields ··· 1636 1616 1637 1617 Sysreg FAR_EL1 3 0 6 0 0 1638 1618 Field 63:0 ADDR 1619 + EndSysreg 1620 + 1621 + Sysreg PMSCR_EL1 3 0 9 9 0 1622 + Res0 63:8 1623 + Field 7:6 PCT 1624 + Field 5 TS 1625 + Field 4 PA 1626 + Field 3 CX 1627 + Res0 2 1628 + Field 1 E1SPE 1629 + Field 0 E0SPE 1630 + EndSysreg 1631 + 1632 + Sysreg PMSNEVFR_EL1 3 0 9 9 1 1633 + Field 63:0 E 1634 + EndSysreg 1635 + 1636 + Sysreg PMSICR_EL1 3 0 9 9 2 1637 + Field 63:56 ECOUNT 1638 + Res0 55:32 1639 + Field 31:0 COUNT 1640 + EndSysreg 1641 + 1642 + Sysreg PMSIRR_EL1 3 0 9 9 3 1643 + Res0 63:32 1644 + Field 31:8 INTERVAL 1645 + Res0 7:1 1646 + Field 0 RND 1647 + EndSysreg 1648 + 1649 + Sysreg PMSFCR_EL1 3 0 9 9 4 1650 + Res0 63:19 1651 + Field 18 ST 1652 + Field 17 LD 1653 + Field 16 B 1654 + Res0 15:4 1655 + Field 3 FnE 1656 + Field 2 FL 1657 + Field 1 FT 1658 + Field 0 FE 1659 + EndSysreg 1660 + 1661 + Sysreg PMSEVFR_EL1 3 0 9 9 5 1662 + Field 63:0 E 1663 + EndSysreg 1664 + 1665 + Sysreg PMSLATFR_EL1 3 0 9 9 6 1666 + Res0 63:16 1667 + Field 15:0 MINLAT 1668 + EndSysreg 1669 + 1670 + Sysreg PMSIDR_EL1 3 0 9 9 7 1671 + Res0 63:25 1672 + Field 24 PBT 1673 + Field 23:20 FORMAT 1674 + Enum 19:16 COUNTSIZE 1675 + 0b0010 12_BIT_SAT 1676 + 0b0011 16_BIT_SAT 1677 + EndEnum 1678 + Field 15:12 MAXSIZE 1679 + Enum 11:8 INTERVAL 1680 + 0b0000 256 1681 + 0b0010 512 1682 + 0b0011 768 1683 + 0b0100 1024 1684 + 0b0101 1536 1685 + 0b0110 2048 1686 + 0b0111 3072 1687 + 0b1000 4096 1688 + EndEnum 1689 + Res0 7 1690 + Field 6 FnE 1691 + Field 5 ERND 1692 + Field 4 LDS 1693 + Field 3 ARCHINST 1694 + Field 2 FL 1695 + Field 1 FT 1696 + Field 0 FE 1697 + EndSysreg 1698 + 1699 + Sysreg PMBLIMITR_EL1 3 0 9 10 0 1700 + Field 63:12 LIMIT 1701 + Res0 11:6 1702 + Field 5 PMFZ 1703 + Res0 4:3 1704 + Enum 2:1 FM 1705 + 0b00 FILL 1706 + 0b10 DISCARD 1707 + EndEnum 1708 + Field 0 E 1709 + EndSysreg 1710 + 1711 + Sysreg PMBPTR_EL1 3 0 9 10 1 1712 + Field 63:0 PTR 1713 + EndSysreg 1714 + 1715 + Sysreg PMBSR_EL1 3 0 9 10 3 1716 + Res0 63:32 1717 + Enum 31:26 EC 1718 + 0b000000 BUF 1719 + 0b100100 FAULT_S1 1720 + 0b100101 FAULT_S2 1721 + 0b011110 FAULT_GPC 1722 + 0b011111 IMP_DEF 1723 + EndEnum 1724 + Res0 25:20 1725 + Field 19 DL 1726 + Field 18 EA 1727 + Field 17 S 1728 + Field 16 COLL 1729 + Field 15:0 MSS 1730 + EndSysreg 1731 + 1732 + Sysreg PMBIDR_EL1 3 0 9 10 7 1733 + Res0 63:12 1734 + Enum 11:8 EA 1735 + 0b0000 NotDescribed 1736 + 0b0001 Ignored 1737 + 0b0010 SError 1738 + EndEnum 1739 + Res0 7:6 1740 + Field 5 F 1741 + Field 4 P 1742 + Field 3:0 ALIGN 1639 1743 EndSysreg 1640 1744 1641 1745 SysregFields CONTEXTIDR_ELx ··· 1916 1772 Field 63:0 ADDR 1917 1773 EndSysreg 1918 1774 1775 + Sysreg PMSCR_EL2 3 4 9 9 0 1776 + Res0 63:8 1777 + Enum 7:6 PCT 1778 + 0b00 VIRT 1779 + 0b01 PHYS 1780 + 0b11 GUEST 1781 + EndEnum 1782 + Field 5 TS 1783 + Field 4 PA 1784 + Field 3 CX 1785 + Res0 2 1786 + Field 1 E2SPE 1787 + Field 0 E0HSPE 1788 + EndSysreg 1789 + 1919 1790 Sysreg CONTEXTIDR_EL2 3 4 13 0 1 1920 1791 Fields CONTEXTIDR_ELx 1921 1792 EndSysreg ··· 2000 1841 Field 23:16 LD 2001 1842 Res0 15:8 2002 1843 Field 7:0 LR 1844 + EndSysreg 1845 + 1846 + Sysreg ISR_EL1 3 0 12 1 0 1847 + Res0 63:11 1848 + Field 10 IS 1849 + Field 9 FS 1850 + Field 8 A 1851 + Field 7 I 1852 + Field 6 F 1853 + Res0 5:0 1854 + EndSysreg 1855 + 1856 + Sysreg ICC_NMIAR1_EL1 3 0 12 9 5 1857 + Res0 63:24 1858 + Field 23:0 INTID 2003 1859 EndSysreg
+1 -1
drivers/acpi/acpica/Makefile
··· 3 3 # Makefile for ACPICA Core interpreter 4 4 # 5 5 6 - ccflags-y := -Os -D_LINUX -DBUILDING_ACPICA 6 + ccflags-y := -D_LINUX -DBUILDING_ACPICA 7 7 ccflags-$(CONFIG_ACPI_DEBUG) += -DACPI_DEBUG_OUTPUT 8 8 9 9 # use acpi.o to put all files here into acpi.o modparam namespace
+2 -2
drivers/firmware/efi/libstub/Makefile
··· 87 87 screen_info.o efi-stub-entry.o 88 88 89 89 lib-$(CONFIG_ARM) += arm32-stub.o 90 - lib-$(CONFIG_ARM64) += arm64.o arm64-stub.o arm64-entry.o smbios.o 90 + lib-$(CONFIG_ARM64) += arm64.o arm64-stub.o smbios.o 91 91 lib-$(CONFIG_X86) += x86-stub.o 92 92 lib-$(CONFIG_RISCV) += riscv.o riscv-stub.o 93 93 lib-$(CONFIG_LOONGARCH) += loongarch.o loongarch-stub.o ··· 141 141 # 142 142 STUBCOPY_FLAGS-$(CONFIG_ARM64) += --prefix-alloc-sections=.init \ 143 143 --prefix-symbols=__efistub_ 144 - STUBCOPY_RELOC-$(CONFIG_ARM64) := R_AARCH64_ABS64 144 + STUBCOPY_RELOC-$(CONFIG_ARM64) := R_AARCH64_ABS 145 145 146 146 # For RISC-V, we don't need anything special other than arm64. Keep all the 147 147 # symbols in .init section and make sure that no absolute symbols references
-67
drivers/firmware/efi/libstub/arm64-entry.S
··· 1 - /* SPDX-License-Identifier: GPL-2.0-only */ 2 - /* 3 - * EFI entry point. 4 - * 5 - * Copyright (C) 2013, 2014 Red Hat, Inc. 6 - * Author: Mark Salter <msalter@redhat.com> 7 - */ 8 - #include <linux/linkage.h> 9 - #include <asm/assembler.h> 10 - 11 - /* 12 - * The entrypoint of a arm64 bare metal image is at offset #0 of the 13 - * image, so this is a reasonable default for primary_entry_offset. 14 - * Only when the EFI stub is integrated into the core kernel, it is not 15 - * guaranteed that the PE/COFF header has been copied to memory too, so 16 - * in this case, primary_entry_offset should be overridden by the 17 - * linker and point to primary_entry() directly. 18 - */ 19 - .weak primary_entry_offset 20 - 21 - SYM_CODE_START(efi_enter_kernel) 22 - /* 23 - * efi_pe_entry() will have copied the kernel image if necessary and we 24 - * end up here with device tree address in x1 and the kernel entry 25 - * point stored in x0. Save those values in registers which are 26 - * callee preserved. 27 - */ 28 - ldr w2, =primary_entry_offset 29 - add x19, x0, x2 // relocated Image entrypoint 30 - 31 - mov x0, x1 // DTB address 32 - mov x1, xzr 33 - mov x2, xzr 34 - mov x3, xzr 35 - 36 - /* 37 - * Clean the remainder of this routine to the PoC 38 - * so that we can safely disable the MMU and caches. 39 - */ 40 - adr x4, 1f 41 - dc civac, x4 42 - dsb sy 43 - 44 - /* Turn off Dcache and MMU */ 45 - mrs x4, CurrentEL 46 - cmp x4, #CurrentEL_EL2 47 - mrs x4, sctlr_el1 48 - b.ne 0f 49 - mrs x4, sctlr_el2 50 - 0: bic x4, x4, #SCTLR_ELx_M 51 - bic x4, x4, #SCTLR_ELx_C 52 - b.eq 1f 53 - b 2f 54 - 55 - .balign 32 56 - 1: pre_disable_mmu_workaround 57 - msr sctlr_el2, x4 58 - isb 59 - br x19 // jump to kernel entrypoint 60 - 61 - 2: pre_disable_mmu_workaround 62 - msr sctlr_el1, x4 63 - isb 64 - br x19 // jump to kernel entrypoint 65 - 66 - .org 1b + 32 67 - SYM_CODE_END(efi_enter_kernel)
+18 -10
drivers/firmware/efi/libstub/arm64-stub.c
··· 58 58 efi_handle_t image_handle) 59 59 { 60 60 efi_status_t status; 61 - unsigned long kernel_size, kernel_memsize = 0; 61 + unsigned long kernel_size, kernel_codesize, kernel_memsize; 62 62 u32 phys_seed = 0; 63 63 u64 min_kimg_align = efi_get_kimg_min_align(); 64 64 ··· 93 93 SEGMENT_ALIGN >> 10); 94 94 95 95 kernel_size = _edata - _text; 96 + kernel_codesize = __inittext_end - _text; 96 97 kernel_memsize = kernel_size + (_end - _edata); 97 98 *reserve_size = kernel_memsize; 98 99 ··· 122 121 */ 123 122 *image_addr = (u64)_text; 124 123 *reserve_size = 0; 125 - goto clean_image_to_poc; 124 + return EFI_SUCCESS; 126 125 } 127 126 128 127 status = efi_allocate_pages_aligned(*reserve_size, reserve_addr, ··· 138 137 139 138 *image_addr = *reserve_addr; 140 139 memcpy((void *)*image_addr, _text, kernel_size); 141 - 142 - clean_image_to_poc: 143 - /* 144 - * Clean the copied Image to the PoC, and ensure it is not shadowed by 145 - * stale icache entries from before relocation. 146 - */ 147 - dcache_clean_poc(*image_addr, *image_addr + kernel_size); 148 - asm("ic ialluis"); 140 + caches_clean_inval_pou(*image_addr, *image_addr + kernel_codesize); 149 141 150 142 return EFI_SUCCESS; 143 + } 144 + 145 + asmlinkage void primary_entry(void); 146 + 147 + unsigned long primary_entry_offset(void) 148 + { 149 + /* 150 + * When built as part of the kernel, the EFI stub cannot branch to the 151 + * kernel proper via the image header, as the PE/COFF header is 152 + * strictly not part of the in-memory presentation of the image, only 153 + * of the file representation. So instead, we need to jump to the 154 + * actual entrypoint in the .text region of the image. 155 + */ 156 + return (char *)primary_entry - _text; 151 157 }
+36 -5
drivers/firmware/efi/libstub/arm64.c
··· 59 59 return EFI_SUCCESS; 60 60 } 61 61 62 + #ifdef CONFIG_ARM64_WORKAROUND_CLEAN_CACHE 63 + #define DCTYPE "civac" 64 + #else 65 + #define DCTYPE "cvau" 66 + #endif 67 + 62 68 void efi_cache_sync_image(unsigned long image_base, 63 69 unsigned long alloc_size, 64 70 unsigned long code_size) ··· 73 67 u64 lsize = 4 << cpuid_feature_extract_unsigned_field(ctr, 74 68 CTR_EL0_DminLine_SHIFT); 75 69 76 - do { 77 - asm("dc civac, %0" :: "r"(image_base)); 78 - image_base += lsize; 79 - alloc_size -= lsize; 80 - } while (alloc_size >= lsize); 70 + /* only perform the cache maintenance if needed for I/D coherency */ 71 + if (!(ctr & BIT(CTR_EL0_IDC_SHIFT))) { 72 + do { 73 + asm("dc " DCTYPE ", %0" :: "r"(image_base)); 74 + image_base += lsize; 75 + code_size -= lsize; 76 + } while (code_size >= lsize); 77 + } 81 78 82 79 asm("ic ialluis"); 83 80 dsb(ish); 84 81 isb(); 82 + } 83 + 84 + unsigned long __weak primary_entry_offset(void) 85 + { 86 + /* 87 + * By default, we can invoke the kernel via the branch instruction in 88 + * the image header, so offset #0. This will be overridden by the EFI 89 + * stub build that is linked into the core kernel, as in that case, the 90 + * image header may not have been loaded into memory, or may be mapped 91 + * with non-executable permissions. 92 + */ 93 + return 0; 94 + } 95 + 96 + void __noreturn efi_enter_kernel(unsigned long entrypoint, 97 + unsigned long fdt_addr, 98 + unsigned long fdt_size) 99 + { 100 + void (* __noreturn enter_kernel)(u64, u64, u64, u64); 101 + 102 + enter_kernel = (void *)entrypoint + primary_entry_offset(); 103 + enter_kernel(fdt_addr, 0, 0, 0); 85 104 }
+1 -18
drivers/irqchip/irq-gic-v3.c
··· 89 89 */ 90 90 static DEFINE_STATIC_KEY_FALSE(supports_pseudo_nmis); 91 91 92 - /* 93 - * Global static key controlling whether an update to PMR allowing more 94 - * interrupts requires to be propagated to the redistributor (DSB SY). 95 - * And this needs to be exported for modules to be able to enable 96 - * interrupts... 97 - */ 98 - DEFINE_STATIC_KEY_FALSE(gic_pmr_sync); 99 - EXPORT_SYMBOL(gic_pmr_sync); 100 - 101 92 DEFINE_STATIC_KEY_FALSE(gic_nonsecure_priorities); 102 93 EXPORT_SYMBOL(gic_nonsecure_priorities); 103 94 ··· 1757 1766 for (i = 0; i < gic_data.ppi_nr; i++) 1758 1767 refcount_set(&ppi_nmi_refs[i], 0); 1759 1768 1760 - /* 1761 - * Linux itself doesn't use 1:N distribution, so has no need to 1762 - * set PMHE. The only reason to have it set is if EL3 requires it 1763 - * (and we can't change it). 1764 - */ 1765 - if (gic_read_ctlr() & ICC_CTLR_EL1_PMHE_MASK) 1766 - static_branch_enable(&gic_pmr_sync); 1767 - 1768 1769 pr_info("Pseudo-NMIs enabled using %s ICC_PMR_EL1 synchronisation\n", 1769 - static_branch_unlikely(&gic_pmr_sync) ? "forced" : "relaxed"); 1770 + gic_has_relaxed_pmr_sync() ? "relaxed" : "forced"); 1770 1771 1771 1772 /* 1772 1773 * How priority values are used by the GIC depends on two things:
+1 -1
drivers/irqchip/irq-gic.c
··· 54 54 55 55 static void gic_check_cpu_features(void) 56 56 { 57 - WARN_TAINT_ONCE(this_cpu_has_cap(ARM64_HAS_SYSREG_GIC_CPUIF), 57 + WARN_TAINT_ONCE(this_cpu_has_cap(ARM64_HAS_GIC_CPUIF_SYSREGS), 58 58 TAINT_CPU_OUT_OF_SPEC, 59 59 "GICv3 system registers enabled, broken firmware!\n"); 60 60 }
+1
drivers/perf/arm-cmn.c
··· 1870 1870 1871 1871 dtm->base = xp->pmu_base + CMN_DTM_OFFSET(idx); 1872 1872 dtm->pmu_config_low = CMN_DTM_PMU_CONFIG_PMU_EN; 1873 + writeq_relaxed(dtm->pmu_config_low, dtm->base + CMN_DTM_PMU_CONFIG); 1873 1874 for (i = 0; i < 4; i++) { 1874 1875 dtm->wp_event[i] = -1; 1875 1876 writeq_relaxed(0, dtm->base + CMN_DTM_WPn_MASK(i));
+102 -58
drivers/perf/arm_spe_pmu.c
··· 12 12 #define DRVNAME PMUNAME "_pmu" 13 13 #define pr_fmt(fmt) DRVNAME ": " fmt 14 14 15 + #include <linux/bitfield.h> 15 16 #include <linux/bitops.h> 16 17 #include <linux/bug.h> 17 18 #include <linux/capability.h> ··· 85 84 #define SPE_PMU_FEAT_ARCH_INST (1UL << 3) 86 85 #define SPE_PMU_FEAT_LDS (1UL << 4) 87 86 #define SPE_PMU_FEAT_ERND (1UL << 5) 87 + #define SPE_PMU_FEAT_INV_FILT_EVT (1UL << 6) 88 88 #define SPE_PMU_FEAT_DEV_PROBED (1UL << 63) 89 89 u64 features; 90 90 ··· 203 201 #define ATTR_CFG_FLD_min_latency_LO 0 204 202 #define ATTR_CFG_FLD_min_latency_HI 11 205 203 204 + #define ATTR_CFG_FLD_inv_event_filter_CFG config3 /* PMSNEVFR_EL1 */ 205 + #define ATTR_CFG_FLD_inv_event_filter_LO 0 206 + #define ATTR_CFG_FLD_inv_event_filter_HI 63 207 + 206 208 /* Why does everything I do descend into this? */ 207 209 #define __GEN_PMU_FORMAT_ATTR(cfg, lo, hi) \ 208 210 (lo) == (hi) ? #cfg ":" #lo "\n" : #cfg ":" #lo "-" #hi ··· 237 231 GEN_PMU_FORMAT_ATTR(load_filter); 238 232 GEN_PMU_FORMAT_ATTR(store_filter); 239 233 GEN_PMU_FORMAT_ATTR(event_filter); 234 + GEN_PMU_FORMAT_ATTR(inv_event_filter); 240 235 GEN_PMU_FORMAT_ATTR(min_latency); 241 236 242 237 static struct attribute *arm_spe_pmu_formats_attr[] = { ··· 249 242 &format_attr_load_filter.attr, 250 243 &format_attr_store_filter.attr, 251 244 &format_attr_event_filter.attr, 245 + &format_attr_inv_event_filter.attr, 252 246 &format_attr_min_latency.attr, 253 247 NULL, 254 248 }; 255 249 250 + static umode_t arm_spe_pmu_format_attr_is_visible(struct kobject *kobj, 251 + struct attribute *attr, 252 + int unused) 253 + { 254 + struct device *dev = kobj_to_dev(kobj); 255 + struct arm_spe_pmu *spe_pmu = dev_get_drvdata(dev); 256 + 257 + if (attr == &format_attr_inv_event_filter.attr && !(spe_pmu->features & SPE_PMU_FEAT_INV_FILT_EVT)) 258 + return 0; 259 + 260 + return attr->mode; 261 + } 262 + 256 263 static const struct attribute_group arm_spe_pmu_format_group = { 257 264 .name = "format", 265 + .is_visible = arm_spe_pmu_format_attr_is_visible, 258 266 .attrs = arm_spe_pmu_formats_attr, 259 267 }; 260 268 ··· 304 282 struct perf_event_attr *attr = &event->attr; 305 283 u64 reg = 0; 306 284 307 - reg |= ATTR_CFG_GET_FLD(attr, ts_enable) << SYS_PMSCR_EL1_TS_SHIFT; 308 - reg |= ATTR_CFG_GET_FLD(attr, pa_enable) << SYS_PMSCR_EL1_PA_SHIFT; 309 - reg |= ATTR_CFG_GET_FLD(attr, pct_enable) << SYS_PMSCR_EL1_PCT_SHIFT; 285 + reg |= FIELD_PREP(PMSCR_EL1_TS, ATTR_CFG_GET_FLD(attr, ts_enable)); 286 + reg |= FIELD_PREP(PMSCR_EL1_PA, ATTR_CFG_GET_FLD(attr, pa_enable)); 287 + reg |= FIELD_PREP(PMSCR_EL1_PCT, ATTR_CFG_GET_FLD(attr, pct_enable)); 310 288 311 289 if (!attr->exclude_user) 312 - reg |= BIT(SYS_PMSCR_EL1_E0SPE_SHIFT); 290 + reg |= PMSCR_EL1_E0SPE; 313 291 314 292 if (!attr->exclude_kernel) 315 - reg |= BIT(SYS_PMSCR_EL1_E1SPE_SHIFT); 293 + reg |= PMSCR_EL1_E1SPE; 316 294 317 295 if (get_spe_event_has_cx(event)) 318 - reg |= BIT(SYS_PMSCR_EL1_CX_SHIFT); 296 + reg |= PMSCR_EL1_CX; 319 297 320 298 return reg; 321 299 } ··· 324 302 { 325 303 struct arm_spe_pmu *spe_pmu = to_spe_pmu(event->pmu); 326 304 u64 period = event->hw.sample_period; 327 - u64 max_period = SYS_PMSIRR_EL1_INTERVAL_MASK 328 - << SYS_PMSIRR_EL1_INTERVAL_SHIFT; 305 + u64 max_period = PMSIRR_EL1_INTERVAL_MASK; 329 306 330 307 if (period < spe_pmu->min_period) 331 308 period = spe_pmu->min_period; ··· 343 322 344 323 arm_spe_event_sanitise_period(event); 345 324 346 - reg |= ATTR_CFG_GET_FLD(attr, jitter) << SYS_PMSIRR_EL1_RND_SHIFT; 325 + reg |= FIELD_PREP(PMSIRR_EL1_RND, ATTR_CFG_GET_FLD(attr, jitter)); 347 326 reg |= event->hw.sample_period; 348 327 349 328 return reg; ··· 354 333 struct perf_event_attr *attr = &event->attr; 355 334 u64 reg = 0; 356 335 357 - reg |= ATTR_CFG_GET_FLD(attr, load_filter) << SYS_PMSFCR_EL1_LD_SHIFT; 358 - reg |= ATTR_CFG_GET_FLD(attr, store_filter) << SYS_PMSFCR_EL1_ST_SHIFT; 359 - reg |= ATTR_CFG_GET_FLD(attr, branch_filter) << SYS_PMSFCR_EL1_B_SHIFT; 336 + reg |= FIELD_PREP(PMSFCR_EL1_LD, ATTR_CFG_GET_FLD(attr, load_filter)); 337 + reg |= FIELD_PREP(PMSFCR_EL1_ST, ATTR_CFG_GET_FLD(attr, store_filter)); 338 + reg |= FIELD_PREP(PMSFCR_EL1_B, ATTR_CFG_GET_FLD(attr, branch_filter)); 360 339 361 340 if (reg) 362 - reg |= BIT(SYS_PMSFCR_EL1_FT_SHIFT); 341 + reg |= PMSFCR_EL1_FT; 363 342 364 343 if (ATTR_CFG_GET_FLD(attr, event_filter)) 365 - reg |= BIT(SYS_PMSFCR_EL1_FE_SHIFT); 344 + reg |= PMSFCR_EL1_FE; 345 + 346 + if (ATTR_CFG_GET_FLD(attr, inv_event_filter)) 347 + reg |= PMSFCR_EL1_FnE; 366 348 367 349 if (ATTR_CFG_GET_FLD(attr, min_latency)) 368 - reg |= BIT(SYS_PMSFCR_EL1_FL_SHIFT); 350 + reg |= PMSFCR_EL1_FL; 369 351 370 352 return reg; 371 353 } ··· 379 355 return ATTR_CFG_GET_FLD(attr, event_filter); 380 356 } 381 357 358 + static u64 arm_spe_event_to_pmsnevfr(struct perf_event *event) 359 + { 360 + struct perf_event_attr *attr = &event->attr; 361 + return ATTR_CFG_GET_FLD(attr, inv_event_filter); 362 + } 363 + 382 364 static u64 arm_spe_event_to_pmslatfr(struct perf_event *event) 383 365 { 384 366 struct perf_event_attr *attr = &event->attr; 385 - return ATTR_CFG_GET_FLD(attr, min_latency) 386 - << SYS_PMSLATFR_EL1_MINLAT_SHIFT; 367 + return FIELD_PREP(PMSLATFR_EL1_MINLAT, ATTR_CFG_GET_FLD(attr, min_latency)); 387 368 } 388 369 389 370 static void arm_spe_pmu_pad_buf(struct perf_output_handle *handle, int len) ··· 540 511 limit = buf->snapshot ? arm_spe_pmu_next_snapshot_off(handle) 541 512 : arm_spe_pmu_next_off(handle); 542 513 if (limit) 543 - limit |= BIT(SYS_PMBLIMITR_EL1_E_SHIFT); 514 + limit |= PMBLIMITR_EL1_E; 544 515 545 516 limit += (u64)buf->base; 546 517 base = (u64)buf->base + PERF_IDX2OFF(handle->head, buf); ··· 599 570 600 571 /* Service required? */ 601 572 pmbsr = read_sysreg_s(SYS_PMBSR_EL1); 602 - if (!(pmbsr & BIT(SYS_PMBSR_EL1_S_SHIFT))) 573 + if (!FIELD_GET(PMBSR_EL1_S, pmbsr)) 603 574 return SPE_PMU_BUF_FAULT_ACT_SPURIOUS; 604 575 605 576 /* 606 577 * If we've lost data, disable profiling and also set the PARTIAL 607 578 * flag to indicate that the last record is corrupted. 608 579 */ 609 - if (pmbsr & BIT(SYS_PMBSR_EL1_DL_SHIFT)) 580 + if (FIELD_GET(PMBSR_EL1_DL, pmbsr)) 610 581 perf_aux_output_flag(handle, PERF_AUX_FLAG_TRUNCATED | 611 582 PERF_AUX_FLAG_PARTIAL); 612 583 613 584 /* Report collisions to userspace so that it can up the period */ 614 - if (pmbsr & BIT(SYS_PMBSR_EL1_COLL_SHIFT)) 585 + if (FIELD_GET(PMBSR_EL1_COLL, pmbsr)) 615 586 perf_aux_output_flag(handle, PERF_AUX_FLAG_COLLISION); 616 587 617 588 /* We only expect buffer management events */ 618 - switch (pmbsr & (SYS_PMBSR_EL1_EC_MASK << SYS_PMBSR_EL1_EC_SHIFT)) { 619 - case SYS_PMBSR_EL1_EC_BUF: 589 + switch (FIELD_GET(PMBSR_EL1_EC, pmbsr)) { 590 + case PMBSR_EL1_EC_BUF: 620 591 /* Handled below */ 621 592 break; 622 - case SYS_PMBSR_EL1_EC_FAULT_S1: 623 - case SYS_PMBSR_EL1_EC_FAULT_S2: 593 + case PMBSR_EL1_EC_FAULT_S1: 594 + case PMBSR_EL1_EC_FAULT_S2: 624 595 err_str = "Unexpected buffer fault"; 625 596 goto out_err; 626 597 default: ··· 629 600 } 630 601 631 602 /* Buffer management event */ 632 - switch (pmbsr & 633 - (SYS_PMBSR_EL1_BUF_BSC_MASK << SYS_PMBSR_EL1_BUF_BSC_SHIFT)) { 634 - case SYS_PMBSR_EL1_BUF_BSC_FULL: 603 + switch (FIELD_GET(PMBSR_EL1_BUF_BSC_MASK, pmbsr)) { 604 + case PMBSR_EL1_BUF_BSC_FULL: 635 605 ret = SPE_PMU_BUF_FAULT_ACT_OK; 636 606 goto out_stop; 637 607 default: ··· 705 677 { 706 678 switch (pmsver) { 707 679 case ID_AA64DFR0_EL1_PMSVer_IMP: 708 - return SYS_PMSEVFR_EL1_RES0_8_2; 680 + return PMSEVFR_EL1_RES0_IMP; 709 681 case ID_AA64DFR0_EL1_PMSVer_V1P1: 682 + return PMSEVFR_EL1_RES0_V1P1; 683 + case ID_AA64DFR0_EL1_PMSVer_V1P2: 710 684 /* Return the highest version we support in default */ 711 685 default: 712 - return SYS_PMSEVFR_EL1_RES0_8_3; 686 + return PMSEVFR_EL1_RES0_V1P2; 713 687 } 714 688 } 715 689 ··· 733 703 if (arm_spe_event_to_pmsevfr(event) & arm_spe_pmsevfr_res0(spe_pmu->pmsver)) 734 704 return -EOPNOTSUPP; 735 705 706 + if (arm_spe_event_to_pmsnevfr(event) & arm_spe_pmsevfr_res0(spe_pmu->pmsver)) 707 + return -EOPNOTSUPP; 708 + 736 709 if (attr->exclude_idle) 737 710 return -EOPNOTSUPP; 738 711 ··· 750 717 return -EINVAL; 751 718 752 719 reg = arm_spe_event_to_pmsfcr(event); 753 - if ((reg & BIT(SYS_PMSFCR_EL1_FE_SHIFT)) && 720 + if ((FIELD_GET(PMSFCR_EL1_FE, reg)) && 754 721 !(spe_pmu->features & SPE_PMU_FEAT_FILT_EVT)) 755 722 return -EOPNOTSUPP; 756 723 757 - if ((reg & BIT(SYS_PMSFCR_EL1_FT_SHIFT)) && 724 + if ((FIELD_GET(PMSFCR_EL1_FnE, reg)) && 725 + !(spe_pmu->features & SPE_PMU_FEAT_INV_FILT_EVT)) 726 + return -EOPNOTSUPP; 727 + 728 + if ((FIELD_GET(PMSFCR_EL1_FT, reg)) && 758 729 !(spe_pmu->features & SPE_PMU_FEAT_FILT_TYP)) 759 730 return -EOPNOTSUPP; 760 731 761 - if ((reg & BIT(SYS_PMSFCR_EL1_FL_SHIFT)) && 732 + if ((FIELD_GET(PMSFCR_EL1_FL, reg)) && 762 733 !(spe_pmu->features & SPE_PMU_FEAT_FILT_LAT)) 763 734 return -EOPNOTSUPP; 764 735 765 736 set_spe_event_has_cx(event); 766 737 reg = arm_spe_event_to_pmscr(event); 767 738 if (!perfmon_capable() && 768 - (reg & (BIT(SYS_PMSCR_EL1_PA_SHIFT) | 769 - BIT(SYS_PMSCR_EL1_PCT_SHIFT)))) 739 + (reg & (PMSCR_EL1_PA | PMSCR_EL1_PCT))) 770 740 return -EACCES; 771 741 772 742 return 0; ··· 792 756 793 757 reg = arm_spe_event_to_pmsevfr(event); 794 758 write_sysreg_s(reg, SYS_PMSEVFR_EL1); 759 + 760 + if (spe_pmu->features & SPE_PMU_FEAT_INV_FILT_EVT) { 761 + reg = arm_spe_event_to_pmsnevfr(event); 762 + write_sysreg_s(reg, SYS_PMSNEVFR_EL1); 763 + } 795 764 796 765 reg = arm_spe_event_to_pmslatfr(event); 797 766 write_sysreg_s(reg, SYS_PMSLATFR_EL1); ··· 1012 971 1013 972 /* Read PMBIDR first to determine whether or not we have access */ 1014 973 reg = read_sysreg_s(SYS_PMBIDR_EL1); 1015 - if (reg & BIT(SYS_PMBIDR_EL1_P_SHIFT)) { 974 + if (FIELD_GET(PMBIDR_EL1_P, reg)) { 1016 975 dev_err(dev, 1017 976 "profiling buffer owned by higher exception level\n"); 1018 977 return; 1019 978 } 1020 979 1021 980 /* Minimum alignment. If it's out-of-range, then fail the probe */ 1022 - fld = reg >> SYS_PMBIDR_EL1_ALIGN_SHIFT & SYS_PMBIDR_EL1_ALIGN_MASK; 981 + fld = FIELD_GET(PMBIDR_EL1_ALIGN, reg); 1023 982 spe_pmu->align = 1 << fld; 1024 983 if (spe_pmu->align > SZ_2K) { 1025 984 dev_err(dev, "unsupported PMBIDR.Align [%d] on CPU %d\n", ··· 1029 988 1030 989 /* It's now safe to read PMSIDR and figure out what we've got */ 1031 990 reg = read_sysreg_s(SYS_PMSIDR_EL1); 1032 - if (reg & BIT(SYS_PMSIDR_EL1_FE_SHIFT)) 991 + if (FIELD_GET(PMSIDR_EL1_FE, reg)) 1033 992 spe_pmu->features |= SPE_PMU_FEAT_FILT_EVT; 1034 993 1035 - if (reg & BIT(SYS_PMSIDR_EL1_FT_SHIFT)) 994 + if (FIELD_GET(PMSIDR_EL1_FnE, reg)) 995 + spe_pmu->features |= SPE_PMU_FEAT_INV_FILT_EVT; 996 + 997 + if (FIELD_GET(PMSIDR_EL1_FT, reg)) 1036 998 spe_pmu->features |= SPE_PMU_FEAT_FILT_TYP; 1037 999 1038 - if (reg & BIT(SYS_PMSIDR_EL1_FL_SHIFT)) 1000 + if (FIELD_GET(PMSIDR_EL1_FL, reg)) 1039 1001 spe_pmu->features |= SPE_PMU_FEAT_FILT_LAT; 1040 1002 1041 - if (reg & BIT(SYS_PMSIDR_EL1_ARCHINST_SHIFT)) 1003 + if (FIELD_GET(PMSIDR_EL1_ARCHINST, reg)) 1042 1004 spe_pmu->features |= SPE_PMU_FEAT_ARCH_INST; 1043 1005 1044 - if (reg & BIT(SYS_PMSIDR_EL1_LDS_SHIFT)) 1006 + if (FIELD_GET(PMSIDR_EL1_LDS, reg)) 1045 1007 spe_pmu->features |= SPE_PMU_FEAT_LDS; 1046 1008 1047 - if (reg & BIT(SYS_PMSIDR_EL1_ERND_SHIFT)) 1009 + if (FIELD_GET(PMSIDR_EL1_ERND, reg)) 1048 1010 spe_pmu->features |= SPE_PMU_FEAT_ERND; 1049 1011 1050 1012 /* This field has a spaced out encoding, so just use a look-up */ 1051 - fld = reg >> SYS_PMSIDR_EL1_INTERVAL_SHIFT & SYS_PMSIDR_EL1_INTERVAL_MASK; 1013 + fld = FIELD_GET(PMSIDR_EL1_INTERVAL, reg); 1052 1014 switch (fld) { 1053 - case 0: 1015 + case PMSIDR_EL1_INTERVAL_256: 1054 1016 spe_pmu->min_period = 256; 1055 1017 break; 1056 - case 2: 1018 + case PMSIDR_EL1_INTERVAL_512: 1057 1019 spe_pmu->min_period = 512; 1058 1020 break; 1059 - case 3: 1021 + case PMSIDR_EL1_INTERVAL_768: 1060 1022 spe_pmu->min_period = 768; 1061 1023 break; 1062 - case 4: 1024 + case PMSIDR_EL1_INTERVAL_1024: 1063 1025 spe_pmu->min_period = 1024; 1064 1026 break; 1065 - case 5: 1027 + case PMSIDR_EL1_INTERVAL_1536: 1066 1028 spe_pmu->min_period = 1536; 1067 1029 break; 1068 - case 6: 1030 + case PMSIDR_EL1_INTERVAL_2048: 1069 1031 spe_pmu->min_period = 2048; 1070 1032 break; 1071 - case 7: 1033 + case PMSIDR_EL1_INTERVAL_3072: 1072 1034 spe_pmu->min_period = 3072; 1073 1035 break; 1074 1036 default: 1075 1037 dev_warn(dev, "unknown PMSIDR_EL1.Interval [%d]; assuming 8\n", 1076 1038 fld); 1077 1039 fallthrough; 1078 - case 8: 1040 + case PMSIDR_EL1_INTERVAL_4096: 1079 1041 spe_pmu->min_period = 4096; 1080 1042 } 1081 1043 1082 1044 /* Maximum record size. If it's out-of-range, then fail the probe */ 1083 - fld = reg >> SYS_PMSIDR_EL1_MAXSIZE_SHIFT & SYS_PMSIDR_EL1_MAXSIZE_MASK; 1045 + fld = FIELD_GET(PMSIDR_EL1_MAXSIZE, reg); 1084 1046 spe_pmu->max_record_sz = 1 << fld; 1085 1047 if (spe_pmu->max_record_sz > SZ_2K || spe_pmu->max_record_sz < 16) { 1086 1048 dev_err(dev, "unsupported PMSIDR_EL1.MaxSize [%d] on CPU %d\n", ··· 1091 1047 return; 1092 1048 } 1093 1049 1094 - fld = reg >> SYS_PMSIDR_EL1_COUNTSIZE_SHIFT & SYS_PMSIDR_EL1_COUNTSIZE_MASK; 1050 + fld = FIELD_GET(PMSIDR_EL1_COUNTSIZE, reg); 1095 1051 switch (fld) { 1096 1052 default: 1097 1053 dev_warn(dev, "unknown PMSIDR_EL1.CountSize [%d]; assuming 2\n", 1098 1054 fld); 1099 1055 fallthrough; 1100 - case 2: 1056 + case PMSIDR_EL1_COUNTSIZE_12_BIT_SAT: 1101 1057 spe_pmu->counter_sz = 12; 1102 1058 break; 1103 - case 3: 1059 + case PMSIDR_EL1_COUNTSIZE_16_BIT_SAT: 1104 1060 spe_pmu->counter_sz = 16; 1105 1061 } 1106 1062 1107 1063 dev_info(dev, 1108 - "probed for CPUs %*pbl [max_record_sz %u, align %u, features 0x%llx]\n", 1109 - cpumask_pr_args(&spe_pmu->supported_cpus), 1064 + "probed SPEv1.%d for CPUs %*pbl [max_record_sz %u, align %u, features 0x%llx]\n", 1065 + spe_pmu->pmsver - 1, cpumask_pr_args(&spe_pmu->supported_cpus), 1110 1066 spe_pmu->max_record_sz, spe_pmu->align, spe_pmu->features); 1111 1067 1112 1068 spe_pmu->features |= SPE_PMU_FEAT_DEV_PROBED;
-3
drivers/perf/fsl_imx8_ddr_perf.c
··· 97 97 struct hlist_node node; 98 98 struct device *dev; 99 99 struct perf_event *events[NUM_COUNTERS]; 100 - int active_events; 101 100 enum cpuhp_state cpuhp_state; 102 101 const struct fsl_ddr_devtype_data *devtype_data; 103 102 int irq; ··· 529 530 } 530 531 531 532 pmu->events[counter] = event; 532 - pmu->active_events++; 533 533 hwc->idx = counter; 534 534 535 535 hwc->state |= PERF_HES_STOPPED; ··· 560 562 ddr_perf_event_stop(event, PERF_EF_UPDATE); 561 563 562 564 ddr_perf_free_counter(pmu, counter); 563 - pmu->active_events--; 564 565 hwc->idx = -1; 565 566 } 566 567
+1 -15
drivers/perf/hisilicon/hisi_uncore_cpa_pmu.c
··· 316 316 if (!name) 317 317 return -ENOMEM; 318 318 319 - cpa_pmu->pmu = (struct pmu) { 320 - .name = name, 321 - .module = THIS_MODULE, 322 - .task_ctx_nr = perf_invalid_context, 323 - .event_init = hisi_uncore_pmu_event_init, 324 - .pmu_enable = hisi_uncore_pmu_enable, 325 - .pmu_disable = hisi_uncore_pmu_disable, 326 - .add = hisi_uncore_pmu_add, 327 - .del = hisi_uncore_pmu_del, 328 - .start = hisi_uncore_pmu_start, 329 - .stop = hisi_uncore_pmu_stop, 330 - .read = hisi_uncore_pmu_read, 331 - .attr_groups = cpa_pmu->pmu_events.attr_groups, 332 - .capabilities = PERF_PMU_CAP_NO_EXCLUDE, 333 - }; 319 + hisi_pmu_init(cpa_pmu, name, THIS_MODULE); 334 320 335 321 /* Power Management should be disabled before using CPA PMU. */ 336 322 hisi_cpa_pmu_disable_pm(cpa_pmu);
+1 -1
drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c
··· 516 516 "hisi_sccl%u_ddrc%u", ddrc_pmu->sccl_id, 517 517 ddrc_pmu->index_id); 518 518 519 - hisi_pmu_init(&ddrc_pmu->pmu, name, ddrc_pmu->pmu_events.attr_groups, THIS_MODULE); 519 + hisi_pmu_init(ddrc_pmu, name, THIS_MODULE); 520 520 521 521 ret = perf_pmu_register(&ddrc_pmu->pmu, name, -1); 522 522 if (ret) {
+1 -1
drivers/perf/hisilicon/hisi_uncore_hha_pmu.c
··· 519 519 520 520 name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "hisi_sccl%u_hha%u", 521 521 hha_pmu->sccl_id, hha_pmu->index_id); 522 - hisi_pmu_init(&hha_pmu->pmu, name, hha_pmu->pmu_events.attr_groups, THIS_MODULE); 522 + hisi_pmu_init(hha_pmu, name, THIS_MODULE); 523 523 524 524 ret = perf_pmu_register(&hha_pmu->pmu, name, -1); 525 525 if (ret) {
+1 -1
drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c
··· 557 557 */ 558 558 name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "hisi_sccl%u_l3c%u", 559 559 l3c_pmu->sccl_id, l3c_pmu->ccl_id); 560 - hisi_pmu_init(&l3c_pmu->pmu, name, l3c_pmu->pmu_events.attr_groups, THIS_MODULE); 560 + hisi_pmu_init(l3c_pmu, name, THIS_MODULE); 561 561 562 562 ret = perf_pmu_register(&l3c_pmu->pmu, name, -1); 563 563 if (ret) {
+1 -1
drivers/perf/hisilicon/hisi_uncore_pa_pmu.c
··· 412 412 return ret; 413 413 } 414 414 415 - hisi_pmu_init(&pa_pmu->pmu, name, pa_pmu->pmu_events.attr_groups, THIS_MODULE); 415 + hisi_pmu_init(pa_pmu, name, THIS_MODULE); 416 416 ret = perf_pmu_register(&pa_pmu->pmu, name, -1); 417 417 if (ret) { 418 418 dev_err(pa_pmu->dev, "PMU register failed, ret = %d\n", ret);
+6 -3
drivers/perf/hisilicon/hisi_uncore_pmu.c
··· 531 531 } 532 532 EXPORT_SYMBOL_GPL(hisi_uncore_pmu_offline_cpu); 533 533 534 - void hisi_pmu_init(struct pmu *pmu, const char *name, 535 - const struct attribute_group **attr_groups, struct module *module) 534 + void hisi_pmu_init(struct hisi_pmu *hisi_pmu, const char *name, 535 + struct module *module) 536 536 { 537 + struct pmu *pmu = &hisi_pmu->pmu; 538 + 537 539 pmu->name = name; 538 540 pmu->module = module; 539 541 pmu->task_ctx_nr = perf_invalid_context; ··· 547 545 pmu->start = hisi_uncore_pmu_start; 548 546 pmu->stop = hisi_uncore_pmu_stop; 549 547 pmu->read = hisi_uncore_pmu_read; 550 - pmu->attr_groups = attr_groups; 548 + pmu->attr_groups = hisi_pmu->pmu_events.attr_groups; 549 + pmu->capabilities = PERF_PMU_CAP_NO_EXCLUDE; 551 550 } 552 551 EXPORT_SYMBOL_GPL(hisi_pmu_init); 553 552
+2 -2
drivers/perf/hisilicon/hisi_uncore_pmu.h
··· 121 121 int hisi_uncore_pmu_init_irq(struct hisi_pmu *hisi_pmu, 122 122 struct platform_device *pdev); 123 123 124 - void hisi_pmu_init(struct pmu *pmu, const char *name, 125 - const struct attribute_group **attr_groups, struct module *module); 124 + void hisi_pmu_init(struct hisi_pmu *hisi_pmu, const char *name, 125 + struct module *module); 126 126 #endif /* __HISI_UNCORE_PMU_H__ */
+1 -1
drivers/perf/hisilicon/hisi_uncore_sllc_pmu.c
··· 445 445 return ret; 446 446 } 447 447 448 - hisi_pmu_init(&sllc_pmu->pmu, name, sllc_pmu->pmu_events.attr_groups, THIS_MODULE); 448 + hisi_pmu_init(sllc_pmu, name, THIS_MODULE); 449 449 450 450 ret = perf_pmu_register(&sllc_pmu->pmu, name, -1); 451 451 if (ret) {
+10
drivers/perf/marvell_cn10k_ddr_pmu.c
··· 12 12 #include <linux/of_device.h> 13 13 #include <linux/perf_event.h> 14 14 #include <linux/hrtimer.h> 15 + #include <linux/acpi.h> 15 16 16 17 /* Performance Counters Operating Mode Control Registers */ 17 18 #define DDRC_PERF_CNT_OP_MODE_CTRL 0x8020 ··· 718 717 MODULE_DEVICE_TABLE(of, cn10k_ddr_pmu_of_match); 719 718 #endif 720 719 720 + #ifdef CONFIG_ACPI 721 + static const struct acpi_device_id cn10k_ddr_pmu_acpi_match[] = { 722 + {"MRVL000A", 0}, 723 + {}, 724 + }; 725 + MODULE_DEVICE_TABLE(acpi, cn10k_ddr_pmu_acpi_match); 726 + #endif 727 + 721 728 static struct platform_driver cn10k_ddr_pmu_driver = { 722 729 .driver = { 723 730 .name = "cn10k-ddr-pmu", 724 731 .of_match_table = of_match_ptr(cn10k_ddr_pmu_of_match), 732 + .acpi_match_table = ACPI_PTR(cn10k_ddr_pmu_acpi_match), 725 733 .suppress_bind_attrs = true, 726 734 }, 727 735 .probe = cn10k_ddr_perf_probe,
+16 -6
drivers/perf/marvell_cn10k_tad_pmu.c
··· 13 13 #include <linux/cpuhotplug.h> 14 14 #include <linux/perf_event.h> 15 15 #include <linux/platform_device.h> 16 + #include <linux/acpi.h> 16 17 17 18 #define TAD_PFC_OFFSET 0x800 18 19 #define TAD_PFC(counter) (TAD_PFC_OFFSET | (counter << 3)) ··· 255 254 256 255 static int tad_pmu_probe(struct platform_device *pdev) 257 256 { 258 - struct device_node *node = pdev->dev.of_node; 257 + struct device *dev = &pdev->dev; 259 258 struct tad_region *regions; 260 259 struct tad_pmu *tad_pmu; 261 260 struct resource *res; ··· 277 276 return -ENODEV; 278 277 } 279 278 280 - ret = of_property_read_u32(node, "marvell,tad-page-size", 281 - &tad_page_size); 279 + ret = device_property_read_u32(dev, "marvell,tad-page-size", 280 + &tad_page_size); 282 281 if (ret) { 283 282 dev_err(&pdev->dev, "Can't find tad-page-size property\n"); 284 283 return ret; 285 284 } 286 285 287 - ret = of_property_read_u32(node, "marvell,tad-pmu-page-size", 288 - &tad_pmu_page_size); 286 + ret = device_property_read_u32(dev, "marvell,tad-pmu-page-size", 287 + &tad_pmu_page_size); 289 288 if (ret) { 290 289 dev_err(&pdev->dev, "Can't find tad-pmu-page-size property\n"); 291 290 return ret; 292 291 } 293 292 294 - ret = of_property_read_u32(node, "marvell,tad-cnt", &tad_cnt); 293 + ret = device_property_read_u32(dev, "marvell,tad-cnt", &tad_cnt); 295 294 if (ret) { 296 295 dev_err(&pdev->dev, "Can't find tad-cnt property\n"); 297 296 return ret; ··· 370 369 }; 371 370 #endif 372 371 372 + #ifdef CONFIG_ACPI 373 + static const struct acpi_device_id tad_pmu_acpi_match[] = { 374 + {"MRVL000B", 0}, 375 + {}, 376 + }; 377 + MODULE_DEVICE_TABLE(acpi, tad_pmu_acpi_match); 378 + #endif 379 + 373 380 static struct platform_driver tad_pmu_driver = { 374 381 .driver = { 375 382 .name = "cn10k_tad_pmu", 376 383 .of_match_table = of_match_ptr(tad_pmu_of_match), 384 + .acpi_match_table = ACPI_PTR(tad_pmu_acpi_match), 377 385 .suppress_bind_attrs = true, 378 386 }, 379 387 .probe = tad_pmu_probe,
-6
include/linux/compiler_attributes.h
··· 76 76 #endif 77 77 78 78 /* 79 - * gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-cold-function-attribute 80 - * gcc: https://gcc.gnu.org/onlinedocs/gcc/Label-Attributes.html#index-cold-label-attribute 81 - */ 82 - #define __cold __attribute__((__cold__)) 83 - 84 - /* 85 79 * Note the long name. 86 80 * 87 81 * gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-const-function-attribute
+27
include/linux/compiler_types.h
··· 79 79 /* Attributes */ 80 80 #include <linux/compiler_attributes.h> 81 81 82 + #if CONFIG_FUNCTION_ALIGNMENT > 0 83 + #define __function_aligned __aligned(CONFIG_FUNCTION_ALIGNMENT) 84 + #else 85 + #define __function_aligned 86 + #endif 87 + 88 + /* 89 + * gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-cold-function-attribute 90 + * gcc: https://gcc.gnu.org/onlinedocs/gcc/Label-Attributes.html#index-cold-label-attribute 91 + * 92 + * When -falign-functions=N is in use, we must avoid the cold attribute as 93 + * contemporary versions of GCC drop the alignment for cold functions. Worse, 94 + * GCC can implicitly mark callees of cold functions as cold themselves, so 95 + * it's not sufficient to add __function_aligned here as that will not ensure 96 + * that callees are correctly aligned. 97 + * 98 + * See: 99 + * 100 + * https://lore.kernel.org/lkml/Y77%2FqVgvaJidFpYt@FVFF77S0Q05N 101 + * https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88345#c9 102 + */ 103 + #if !defined(CONFIG_CC_IS_GCC) || (CONFIG_FUNCTION_ALIGNMENT == 0) 104 + #define __cold __attribute__((__cold__)) 105 + #else 106 + #define __cold 107 + #endif 108 + 82 109 /* Builtins */ 83 110 84 111 /*
+14 -4
include/linux/ftrace.h
··· 39 39 40 40 struct ftrace_ops; 41 41 struct ftrace_regs; 42 + struct dyn_ftrace; 42 43 43 44 #ifdef CONFIG_FUNCTION_TRACER 44 45 /* ··· 58 57 void arch_ftrace_ops_list_func(unsigned long ip, unsigned long parent_ip, 59 58 struct ftrace_ops *op, struct ftrace_regs *fregs); 60 59 #endif 60 + extern const struct ftrace_ops ftrace_nop_ops; 61 + extern const struct ftrace_ops ftrace_list_ops; 62 + struct ftrace_ops *ftrace_find_unique_ops(struct dyn_ftrace *rec); 61 63 #endif /* CONFIG_FUNCTION_TRACER */ 62 64 63 65 /* Main tracing buffer and events set up */ ··· 395 391 unsigned long direct; /* for direct lookup only */ 396 392 }; 397 393 398 - struct dyn_ftrace; 399 - 400 394 #ifdef CONFIG_DYNAMIC_FTRACE_WITH_DIRECT_CALLS 401 395 extern int ftrace_direct_func_count; 402 396 int register_ftrace_direct(unsigned long ip, unsigned long addr); ··· 565 563 * IPMODIFY - the record allows for the IP address to be changed. 566 564 * DISABLED - the record is not ready to be touched yet 567 565 * DIRECT - there is a direct function to call 566 + * CALL_OPS - the record can use callsite-specific ops 567 + * CALL_OPS_EN - the function is set up to use callsite-specific ops 568 568 * 569 569 * When a new ftrace_ops is registered and wants a function to save 570 570 * pt_regs, the rec->flags REGS is set. When the function has been ··· 584 580 FTRACE_FL_DISABLED = (1UL << 25), 585 581 FTRACE_FL_DIRECT = (1UL << 24), 586 582 FTRACE_FL_DIRECT_EN = (1UL << 23), 583 + FTRACE_FL_CALL_OPS = (1UL << 22), 584 + FTRACE_FL_CALL_OPS_EN = (1UL << 21), 587 585 }; 588 586 589 - #define FTRACE_REF_MAX_SHIFT 23 587 + #define FTRACE_REF_MAX_SHIFT 21 590 588 #define FTRACE_REF_MAX ((1UL << FTRACE_REF_MAX_SHIFT) - 1) 591 589 592 590 #define ftrace_rec_count(rec) ((rec)->flags & FTRACE_REF_MAX) ··· 826 820 */ 827 821 extern int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr); 828 822 829 - #ifdef CONFIG_DYNAMIC_FTRACE_WITH_REGS 823 + #if defined(CONFIG_DYNAMIC_FTRACE_WITH_REGS) || \ 824 + defined(CONFIG_DYNAMIC_FTRACE_WITH_CALL_OPS) 830 825 /** 831 826 * ftrace_modify_call - convert from one addr to another (no nop) 832 827 * @rec: the call site record (e.g. mcount/fentry) ··· 839 832 * read the location, check to see if what is read is indeed 840 833 * what we expect it to be, and then on success of the compare, 841 834 * it should write to the location. 835 + * 836 + * When using call ops, this is called when the associated ops change, even 837 + * when (addr == old_addr). 842 838 * 843 839 * The code segment at @rec->ip should be a caller to @old_addr 844 840 *
+1
include/uapi/linux/elf.h
··· 434 434 #define NT_ARM_PAC_ENABLED_KEYS 0x40a /* arm64 ptr auth enabled keys (prctl()) */ 435 435 #define NT_ARM_SSVE 0x40b /* ARM Streaming SVE registers */ 436 436 #define NT_ARM_ZA 0x40c /* ARM SME ZA registers */ 437 + #define NT_ARM_ZT 0x40d /* ARM SME ZT registers */ 437 438 #define NT_ARC_V2 0x600 /* ARCv2 accumulator/extra registers */ 438 439 #define NT_VMCOREDD 0x700 /* Vmcore Device Dump Note */ 439 440 #define NT_MIPS_DSP 0x800 /* MIPS DSP ASE registers */
+3
include/uapi/linux/perf_event.h
··· 374 374 #define PERF_ATTR_SIZE_VER5 112 /* add: aux_watermark */ 375 375 #define PERF_ATTR_SIZE_VER6 120 /* add: aux_sample_size */ 376 376 #define PERF_ATTR_SIZE_VER7 128 /* add: sig_data */ 377 + #define PERF_ATTR_SIZE_VER8 136 /* add: config3 */ 377 378 378 379 /* 379 380 * Hardware event_id to monitor via a performance monitoring event: ··· 516 515 * truncated accordingly on 32 bit architectures. 517 516 */ 518 517 __u64 sig_data; 518 + 519 + __u64 config3; /* extension of config2 */ 519 520 }; 520 521 521 522 /*
+8 -1
kernel/exit.c
··· 1905 1905 } 1906 1906 EXPORT_SYMBOL(thread_group_exited); 1907 1907 1908 - __weak void abort(void) 1908 + /* 1909 + * This needs to be __function_aligned as GCC implicitly makes any 1910 + * implementation of abort() cold and drops alignment specified by 1911 + * -falign-functions=N. 1912 + * 1913 + * See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88345#c11 1914 + */ 1915 + __weak __function_aligned void abort(void) 1909 1916 { 1910 1917 BUG(); 1911 1918
+7
kernel/trace/Kconfig
··· 42 42 config HAVE_DYNAMIC_FTRACE_WITH_DIRECT_CALLS 43 43 bool 44 44 45 + config HAVE_DYNAMIC_FTRACE_WITH_CALL_OPS 46 + bool 47 + 45 48 config HAVE_DYNAMIC_FTRACE_WITH_ARGS 46 49 bool 47 50 help ··· 259 256 def_bool y 260 257 depends on DYNAMIC_FTRACE_WITH_REGS 261 258 depends on HAVE_DYNAMIC_FTRACE_WITH_DIRECT_CALLS 259 + 260 + config DYNAMIC_FTRACE_WITH_CALL_OPS 261 + def_bool y 262 + depends on HAVE_DYNAMIC_FTRACE_WITH_CALL_OPS 262 263 263 264 config DYNAMIC_FTRACE_WITH_ARGS 264 265 def_bool y
+104 -5
kernel/trace/ftrace.c
··· 125 125 void ftrace_ops_list_func(unsigned long ip, unsigned long parent_ip, 126 126 struct ftrace_ops *op, struct ftrace_regs *fregs); 127 127 128 + #ifdef CONFIG_DYNAMIC_FTRACE_WITH_CALL_OPS 129 + /* 130 + * Stub used to invoke the list ops without requiring a separate trampoline. 131 + */ 132 + const struct ftrace_ops ftrace_list_ops = { 133 + .func = ftrace_ops_list_func, 134 + .flags = FTRACE_OPS_FL_STUB, 135 + }; 136 + 137 + static void ftrace_ops_nop_func(unsigned long ip, unsigned long parent_ip, 138 + struct ftrace_ops *op, 139 + struct ftrace_regs *fregs) 140 + { 141 + /* do nothing */ 142 + } 143 + 144 + /* 145 + * Stub used when a call site is disabled. May be called transiently by threads 146 + * which have made it into ftrace_caller but haven't yet recovered the ops at 147 + * the point the call site is disabled. 148 + */ 149 + const struct ftrace_ops ftrace_nop_ops = { 150 + .func = ftrace_ops_nop_func, 151 + .flags = FTRACE_OPS_FL_STUB, 152 + }; 153 + #endif 154 + 128 155 static inline void ftrace_ops_init(struct ftrace_ops *ops) 129 156 { 130 157 #ifdef CONFIG_DYNAMIC_FTRACE ··· 1846 1819 * if rec count is zero. 1847 1820 */ 1848 1821 } 1822 + 1823 + /* 1824 + * If the rec has a single associated ops, and ops->func can be 1825 + * called directly, allow the call site to call via the ops. 1826 + */ 1827 + if (IS_ENABLED(CONFIG_DYNAMIC_FTRACE_WITH_CALL_OPS) && 1828 + ftrace_rec_count(rec) == 1 && 1829 + ftrace_ops_get_func(ops) == ops->func) 1830 + rec->flags |= FTRACE_FL_CALL_OPS; 1831 + else 1832 + rec->flags &= ~FTRACE_FL_CALL_OPS; 1833 + 1849 1834 count++; 1850 1835 1851 1836 /* Must match FTRACE_UPDATE_CALLS in ftrace_modify_all_code() */ ··· 2152 2113 struct ftrace_ops *ops = NULL; 2153 2114 2154 2115 pr_info("ftrace record flags: %lx\n", rec->flags); 2155 - pr_cont(" (%ld)%s", ftrace_rec_count(rec), 2156 - rec->flags & FTRACE_FL_REGS ? " R" : " "); 2116 + pr_cont(" (%ld)%s%s", ftrace_rec_count(rec), 2117 + rec->flags & FTRACE_FL_REGS ? " R" : " ", 2118 + rec->flags & FTRACE_FL_CALL_OPS ? " O" : " "); 2157 2119 if (rec->flags & FTRACE_FL_TRAMP_EN) { 2158 2120 ops = ftrace_find_tramp_ops_any(rec); 2159 2121 if (ops) { ··· 2222 2182 * want the direct enabled (it will be done via the 2223 2183 * direct helper). But if DIRECT_EN is set, and 2224 2184 * the count is not one, we need to clear it. 2185 + * 2225 2186 */ 2226 2187 if (ftrace_rec_count(rec) == 1) { 2227 2188 if (!(rec->flags & FTRACE_FL_DIRECT) != ··· 2230 2189 flag |= FTRACE_FL_DIRECT; 2231 2190 } else if (rec->flags & FTRACE_FL_DIRECT_EN) { 2232 2191 flag |= FTRACE_FL_DIRECT; 2192 + } 2193 + 2194 + /* 2195 + * Ops calls are special, as count matters. 2196 + * As with direct calls, they must only be enabled when count 2197 + * is one, otherwise they'll be handled via the list ops. 2198 + */ 2199 + if (ftrace_rec_count(rec) == 1) { 2200 + if (!(rec->flags & FTRACE_FL_CALL_OPS) != 2201 + !(rec->flags & FTRACE_FL_CALL_OPS_EN)) 2202 + flag |= FTRACE_FL_CALL_OPS; 2203 + } else if (rec->flags & FTRACE_FL_CALL_OPS_EN) { 2204 + flag |= FTRACE_FL_CALL_OPS; 2233 2205 } 2234 2206 } 2235 2207 ··· 2288 2234 rec->flags &= ~FTRACE_FL_DIRECT_EN; 2289 2235 } 2290 2236 } 2237 + 2238 + if (flag & FTRACE_FL_CALL_OPS) { 2239 + if (ftrace_rec_count(rec) == 1) { 2240 + if (rec->flags & FTRACE_FL_CALL_OPS) 2241 + rec->flags |= FTRACE_FL_CALL_OPS_EN; 2242 + else 2243 + rec->flags &= ~FTRACE_FL_CALL_OPS_EN; 2244 + } else { 2245 + /* 2246 + * Can only call directly if there's 2247 + * only one set of associated ops. 2248 + */ 2249 + rec->flags &= ~FTRACE_FL_CALL_OPS_EN; 2250 + } 2251 + } 2291 2252 } 2292 2253 2293 2254 /* ··· 2332 2263 * and REGS states. The _EN flags must be disabled though. 2333 2264 */ 2334 2265 rec->flags &= ~(FTRACE_FL_ENABLED | FTRACE_FL_TRAMP_EN | 2335 - FTRACE_FL_REGS_EN | FTRACE_FL_DIRECT_EN); 2266 + FTRACE_FL_REGS_EN | FTRACE_FL_DIRECT_EN | 2267 + FTRACE_FL_CALL_OPS_EN); 2336 2268 } 2337 2269 2338 2270 ftrace_bug_type = FTRACE_BUG_NOP; ··· 2504 2434 } while_for_each_ftrace_op(op); 2505 2435 2506 2436 return NULL; 2437 + } 2438 + 2439 + struct ftrace_ops * 2440 + ftrace_find_unique_ops(struct dyn_ftrace *rec) 2441 + { 2442 + struct ftrace_ops *op, *found = NULL; 2443 + unsigned long ip = rec->ip; 2444 + 2445 + do_for_each_ftrace_op(op, ftrace_ops_list) { 2446 + 2447 + if (hash_contains_ip(ip, op->func_hash)) { 2448 + if (found) 2449 + return NULL; 2450 + found = op; 2451 + } 2452 + 2453 + } while_for_each_ftrace_op(op); 2454 + 2455 + return found; 2507 2456 } 2508 2457 2509 2458 #ifdef CONFIG_DYNAMIC_FTRACE_WITH_DIRECT_CALLS ··· 3874 3785 if (iter->flags & FTRACE_ITER_ENABLED) { 3875 3786 struct ftrace_ops *ops; 3876 3787 3877 - seq_printf(m, " (%ld)%s%s%s", 3788 + seq_printf(m, " (%ld)%s%s%s%s", 3878 3789 ftrace_rec_count(rec), 3879 3790 rec->flags & FTRACE_FL_REGS ? " R" : " ", 3880 3791 rec->flags & FTRACE_FL_IPMODIFY ? " I" : " ", 3881 - rec->flags & FTRACE_FL_DIRECT ? " D" : " "); 3792 + rec->flags & FTRACE_FL_DIRECT ? " D" : " ", 3793 + rec->flags & FTRACE_FL_CALL_OPS ? " O" : " "); 3882 3794 if (rec->flags & FTRACE_FL_TRAMP_EN) { 3883 3795 ops = ftrace_find_tramp_ops_any(rec); 3884 3796 if (ops) { ··· 3894 3804 seq_puts(m, "\ttramp: ERROR!"); 3895 3805 } else { 3896 3806 add_trampoline_func(m, NULL, rec); 3807 + } 3808 + if (rec->flags & FTRACE_FL_CALL_OPS_EN) { 3809 + ops = ftrace_find_unique_ops(rec); 3810 + if (ops) { 3811 + seq_printf(m, "\tops: %pS (%pS)", 3812 + ops, ops->func); 3813 + } else { 3814 + seq_puts(m, "\tops: ERROR!"); 3815 + } 3897 3816 } 3898 3817 if (rec->flags & FTRACE_FL_DIRECT) { 3899 3818 unsigned long direct;
+115
tools/testing/selftests/arm64/abi/hwcap.c
··· 50 50 asm volatile(".inst 0x04bf5800" : : : "x0"); 51 51 } 52 52 53 + static void sme2_sigill(void) 54 + { 55 + /* SMSTART ZA */ 56 + asm volatile("msr S0_3_C4_C5_3, xzr" : : : ); 57 + 58 + /* ZERO ZT0 */ 59 + asm volatile(".inst 0xc0480001" : : : ); 60 + 61 + /* SMSTOP */ 62 + asm volatile("msr S0_3_C4_C6_3, xzr" : : : ); 63 + } 64 + 65 + static void sme2p1_sigill(void) 66 + { 67 + /* SMSTART SM */ 68 + asm volatile("msr S0_3_C4_C3_3, xzr" : : : ); 69 + 70 + /* BFCLAMP { Z0.H - Z1.H }, Z0.H, Z0.H */ 71 + asm volatile(".inst 0xc120C000" : : : ); 72 + 73 + /* SMSTOP */ 74 + asm volatile("msr S0_3_C4_C6_3, xzr" : : : ); 75 + } 76 + 77 + static void smei16i32_sigill(void) 78 + { 79 + /* SMSTART */ 80 + asm volatile("msr S0_3_C4_C7_3, xzr" : : : ); 81 + 82 + /* SMOPA ZA0.S, P0/M, P0/M, Z0.B, Z0.B */ 83 + asm volatile(".inst 0xa0800000" : : : ); 84 + 85 + /* SMSTOP */ 86 + asm volatile("msr S0_3_C4_C6_3, xzr" : : : ); 87 + } 88 + 89 + static void smebi32i32_sigill(void) 90 + { 91 + /* SMSTART */ 92 + asm volatile("msr S0_3_C4_C7_3, xzr" : : : ); 93 + 94 + /* BMOPA ZA0.S, P0/M, P0/M, Z0.B, Z0.B */ 95 + asm volatile(".inst 0x80800008" : : : ); 96 + 97 + /* SMSTOP */ 98 + asm volatile("msr S0_3_C4_C6_3, xzr" : : : ); 99 + } 100 + 101 + static void smeb16b16_sigill(void) 102 + { 103 + /* SMSTART */ 104 + asm volatile("msr S0_3_C4_C7_3, xzr" : : : ); 105 + 106 + /* BFADD ZA.H[W0, 0], {Z0.H-Z1.H} */ 107 + asm volatile(".inst 0xC1E41C00" : : : ); 108 + 109 + /* SMSTOP */ 110 + asm volatile("msr S0_3_C4_C6_3, xzr" : : : ); 111 + } 112 + 113 + static void smef16f16_sigill(void) 114 + { 115 + /* SMSTART */ 116 + asm volatile("msr S0_3_C4_C7_3, xzr" : : : ); 117 + 118 + /* FADD ZA.H[W0, 0], { Z0.H-Z1.H } */ 119 + asm volatile(".inst 0xc1a41C00" : : : ); 120 + 121 + /* SMSTOP */ 122 + asm volatile("msr S0_3_C4_C6_3, xzr" : : : ); 123 + } 124 + 53 125 static void sve_sigill(void) 54 126 { 55 127 /* RDVL x0, #0 */ ··· 229 157 .cpuinfo = "sme", 230 158 .sigill_fn = sme_sigill, 231 159 .sigill_reliable = true, 160 + }, 161 + { 162 + .name = "SME2", 163 + .at_hwcap = AT_HWCAP2, 164 + .hwcap_bit = HWCAP2_SME2, 165 + .cpuinfo = "sme2", 166 + .sigill_fn = sme2_sigill, 167 + .sigill_reliable = true, 168 + }, 169 + { 170 + .name = "SME 2.1", 171 + .at_hwcap = AT_HWCAP2, 172 + .hwcap_bit = HWCAP2_SME2P1, 173 + .cpuinfo = "sme2p1", 174 + .sigill_fn = sme2p1_sigill, 175 + }, 176 + { 177 + .name = "SME I16I32", 178 + .at_hwcap = AT_HWCAP2, 179 + .hwcap_bit = HWCAP2_SME_I16I32, 180 + .cpuinfo = "smei16i32", 181 + .sigill_fn = smei16i32_sigill, 182 + }, 183 + { 184 + .name = "SME BI32I32", 185 + .at_hwcap = AT_HWCAP2, 186 + .hwcap_bit = HWCAP2_SME_BI32I32, 187 + .cpuinfo = "smebi32i32", 188 + .sigill_fn = smebi32i32_sigill, 189 + }, 190 + { 191 + .name = "SME B16B16", 192 + .at_hwcap = AT_HWCAP2, 193 + .hwcap_bit = HWCAP2_SME_B16B16, 194 + .cpuinfo = "smeb16b16", 195 + .sigill_fn = smeb16b16_sigill, 196 + }, 197 + { 198 + .name = "SME F16F16", 199 + .at_hwcap = AT_HWCAP2, 200 + .hwcap_bit = HWCAP2_SME_F16F16, 201 + .cpuinfo = "smef16f16", 202 + .sigill_fn = smef16f16_sigill, 232 203 }, 233 204 { 234 205 .name = "SVE",
+51 -6
tools/testing/selftests/arm64/abi/syscall-abi-asm.S
··· 23 23 24 24 .arch_extension sve 25 25 26 + #define ID_AA64SMFR0_EL1_SMEver_SHIFT 56 27 + #define ID_AA64SMFR0_EL1_SMEver_WIDTH 4 28 + 26 29 /* 27 30 * LDR (vector to ZA array): 28 31 * LDR ZA[\nw, #\offset], [X\nxbase, #\offset, MUL VL] ··· 48 45 | ((\offset) & 7) 49 46 .endm 50 47 48 + /* 49 + * LDR (ZT0) 50 + * 51 + * LDR ZT0, nx 52 + */ 53 + .macro _ldr_zt nx 54 + .inst 0xe11f8000 \ 55 + | (((\nx) & 0x1f) << 5) 56 + .endm 57 + 58 + /* 59 + * STR (ZT0) 60 + * 61 + * STR ZT0, nx 62 + */ 63 + .macro _str_zt nx 64 + .inst 0xe13f8000 \ 65 + | (((\nx) & 0x1f) << 5) 66 + .endm 67 + 51 68 .globl do_syscall 52 69 do_syscall: 53 70 // Store callee saved registers x19-x29 (80 bytes) plus x0 and x1 ··· 87 64 msr S3_3_C4_C2_2, x2 88 65 1: 89 66 90 - // Load ZA if it's enabled - uses x12 as scratch due to SME LDR 67 + // Load ZA and ZT0 if enabled - uses x12 as scratch due to SME LDR 91 68 tbz x2, #SVCR_ZA_SHIFT, 1f 92 69 mov w12, #0 93 70 ldr x2, =za_in ··· 96 73 add x12, x12, #1 97 74 cmp x1, x12 98 75 bne 2b 76 + 77 + // ZT0 78 + mrs x2, S3_0_C0_C4_5 // ID_AA64SMFR0_EL1 79 + ubfx x2, x2, #ID_AA64SMFR0_EL1_SMEver_SHIFT, \ 80 + #ID_AA64SMFR0_EL1_SMEver_WIDTH 81 + cbz x2, 1f 82 + adrp x2, zt_in 83 + add x2, x2, :lo12:zt_in 84 + _ldr_zt 2 99 85 1: 100 86 101 87 // Load GPRs x8-x28, and save our SP/FP for later comparison ··· 124 92 str x29, [x2], #8 // FP 125 93 str x30, [x2], #8 // LR 126 94 127 - // Load FPRs if we're not doing SVE 95 + // Load FPRs if we're not doing neither SVE nor streaming SVE 128 96 cbnz x0, 1f 97 + ldr x2, =svcr_in 98 + tbnz x2, #SVCR_SM_SHIFT, 1f 99 + 129 100 ldr x2, =fpr_in 130 101 ldp q0, q1, [x2] 131 102 ldp q2, q3, [x2, #16 * 2] ··· 146 111 ldp q26, q27, [x2, #16 * 26] 147 112 ldp q28, q29, [x2, #16 * 28] 148 113 ldp q30, q31, [x2, #16 * 30] 114 + 115 + b 2f 149 116 1: 150 117 151 118 // Load the SVE registers if we're doing SVE/SME 152 - cbz x0, 1f 153 119 154 120 ldr x2, =z_in 155 121 ldr z0, [x2, #0, MUL VL] ··· 191 155 ldr x2, =ffr_in 192 156 ldr p0, [x2] 193 157 ldr x2, [x2, #0] 194 - cbz x2, 2f 158 + cbz x2, 1f 195 159 wrffr p0.b 196 - 2: 160 + 1: 197 161 198 162 ldr x2, =p_in 199 163 ldr p0, [x2, #0, MUL VL] ··· 212 176 ldr p13, [x2, #13, MUL VL] 213 177 ldr p14, [x2, #14, MUL VL] 214 178 ldr p15, [x2, #15, MUL VL] 215 - 1: 179 + 2: 216 180 217 181 // Do the syscall 218 182 svc #0 ··· 271 235 add x12, x12, #1 272 236 cmp x1, x12 273 237 bne 2b 238 + 239 + // ZT0 240 + mrs x2, S3_0_C0_C4_5 // ID_AA64SMFR0_EL1 241 + ubfx x2, x2, #ID_AA64SMFR0_EL1_SMEver_SHIFT, \ 242 + #ID_AA64SMFR0_EL1_SMEver_WIDTH 243 + cbz x2, 1f 244 + adrp x2, zt_out 245 + add x2, x2, :lo12:zt_out 246 + _str_zt 2 274 247 1: 275 248 276 249 // Save the SVE state if we have some
+120 -59
tools/testing/selftests/arm64/abi/syscall-abi.c
··· 20 20 21 21 #include "syscall-abi.h" 22 22 23 - #define NUM_VL ((SVE_VQ_MAX - SVE_VQ_MIN) + 1) 24 - 25 23 static int default_sme_vl; 24 + 25 + static int sve_vl_count; 26 + static unsigned int sve_vls[SVE_VQ_MAX]; 27 + static int sme_vl_count; 28 + static unsigned int sme_vls[SVE_VQ_MAX]; 26 29 27 30 extern void do_syscall(int sve_vl, int sme_vl); 28 31 ··· 86 83 #define NUM_FPR 32 87 84 uint64_t fpr_in[NUM_FPR * 2]; 88 85 uint64_t fpr_out[NUM_FPR * 2]; 86 + uint64_t fpr_zero[NUM_FPR * 2]; 89 87 90 88 static void setup_fpr(struct syscall_cfg *cfg, int sve_vl, int sme_vl, 91 89 uint64_t svcr) ··· 101 97 int errors = 0; 102 98 int i; 103 99 104 - if (!sve_vl) { 100 + if (!sve_vl && !(svcr & SVCR_SM_MASK)) { 105 101 for (i = 0; i < ARRAY_SIZE(fpr_in); i++) { 106 102 if (fpr_in[i] != fpr_out[i]) { 107 103 ksft_print_msg("%s Q%d/%d mismatch %llx != %llx\n", ··· 110 106 fpr_in[i], fpr_out[i]); 111 107 errors++; 112 108 } 109 + } 110 + } 111 + 112 + /* 113 + * In streaming mode the whole register set should be cleared 114 + * by the transition out of streaming mode. 115 + */ 116 + if (svcr & SVCR_SM_MASK) { 117 + if (memcmp(fpr_zero, fpr_out, sizeof(fpr_out)) != 0) { 118 + ksft_print_msg("%s FPSIMD registers non-zero exiting SM\n", 119 + cfg->name); 120 + errors++; 113 121 } 114 122 } 115 123 ··· 300 284 return errors; 301 285 } 302 286 303 - uint8_t za_in[SVE_NUM_PREGS * __SVE_ZREG_SIZE(SVE_VQ_MAX)]; 304 - uint8_t za_out[SVE_NUM_PREGS * __SVE_ZREG_SIZE(SVE_VQ_MAX)]; 287 + uint8_t za_in[ZA_SIG_REGS_SIZE(SVE_VQ_MAX)]; 288 + uint8_t za_out[ZA_SIG_REGS_SIZE(SVE_VQ_MAX)]; 305 289 306 290 static void setup_za(struct syscall_cfg *cfg, int sve_vl, int sme_vl, 307 291 uint64_t svcr) ··· 321 305 322 306 if (memcmp(za_in, za_out, reg_size) != 0) { 323 307 ksft_print_msg("SME VL %d ZA does not match\n", sme_vl); 308 + errors++; 309 + } 310 + 311 + return errors; 312 + } 313 + 314 + uint8_t zt_in[ZT_SIG_REG_BYTES] __attribute__((aligned(16))); 315 + uint8_t zt_out[ZT_SIG_REG_BYTES] __attribute__((aligned(16))); 316 + 317 + static void setup_zt(struct syscall_cfg *cfg, int sve_vl, int sme_vl, 318 + uint64_t svcr) 319 + { 320 + fill_random(zt_in, sizeof(zt_in)); 321 + memset(zt_out, 0, sizeof(zt_out)); 322 + } 323 + 324 + static int check_zt(struct syscall_cfg *cfg, int sve_vl, int sme_vl, 325 + uint64_t svcr) 326 + { 327 + int errors = 0; 328 + 329 + if (!(getauxval(AT_HWCAP2) & HWCAP2_SME2)) 330 + return 0; 331 + 332 + if (!(svcr & SVCR_ZA_MASK)) 333 + return 0; 334 + 335 + if (memcmp(zt_in, zt_out, sizeof(zt_in)) != 0) { 336 + ksft_print_msg("SME VL %d ZT does not match\n", sme_vl); 324 337 errors++; 325 338 } 326 339 ··· 379 334 { setup_ffr, check_ffr }, 380 335 { setup_svcr, check_svcr }, 381 336 { setup_za, check_za }, 337 + { setup_zt, check_zt }, 382 338 }; 383 339 384 340 static bool do_test(struct syscall_cfg *cfg, int sve_vl, int sme_vl, ··· 401 355 402 356 static void test_one_syscall(struct syscall_cfg *cfg) 403 357 { 404 - int sve_vq, sve_vl; 405 - int sme_vq, sme_vl; 358 + int sve, sme; 359 + int ret; 406 360 407 361 /* FPSIMD only case */ 408 362 ksft_test_result(do_test(cfg, 0, default_sme_vl, 0), 409 363 "%s FPSIMD\n", cfg->name); 410 364 411 - if (!(getauxval(AT_HWCAP) & HWCAP_SVE)) 412 - return; 413 - 414 - for (sve_vq = SVE_VQ_MAX; sve_vq > 0; --sve_vq) { 415 - sve_vl = prctl(PR_SVE_SET_VL, sve_vq * 16); 416 - if (sve_vl == -1) 365 + for (sve = 0; sve < sve_vl_count; sve++) { 366 + ret = prctl(PR_SVE_SET_VL, sve_vls[sve]); 367 + if (ret == -1) 417 368 ksft_exit_fail_msg("PR_SVE_SET_VL failed: %s (%d)\n", 418 369 strerror(errno), errno); 419 370 420 - sve_vl &= PR_SVE_VL_LEN_MASK; 371 + ksft_test_result(do_test(cfg, sve_vls[sve], default_sme_vl, 0), 372 + "%s SVE VL %d\n", cfg->name, sve_vls[sve]); 421 373 422 - if (sve_vq != sve_vq_from_vl(sve_vl)) 423 - sve_vq = sve_vq_from_vl(sve_vl); 424 - 425 - ksft_test_result(do_test(cfg, sve_vl, default_sme_vl, 0), 426 - "%s SVE VL %d\n", cfg->name, sve_vl); 427 - 428 - if (!(getauxval(AT_HWCAP2) & HWCAP2_SME)) 429 - continue; 430 - 431 - for (sme_vq = SVE_VQ_MAX; sme_vq > 0; --sme_vq) { 432 - sme_vl = prctl(PR_SME_SET_VL, sme_vq * 16); 433 - if (sme_vl == -1) 374 + for (sme = 0; sme < sme_vl_count; sme++) { 375 + ret = prctl(PR_SME_SET_VL, sme_vls[sme]); 376 + if (ret == -1) 434 377 ksft_exit_fail_msg("PR_SME_SET_VL failed: %s (%d)\n", 435 378 strerror(errno), errno); 436 379 437 - sme_vl &= PR_SME_VL_LEN_MASK; 438 - 439 - if (sme_vq != sve_vq_from_vl(sme_vl)) 440 - sme_vq = sve_vq_from_vl(sme_vl); 441 - 442 - ksft_test_result(do_test(cfg, sve_vl, sme_vl, 380 + ksft_test_result(do_test(cfg, sve_vls[sve], 381 + sme_vls[sme], 443 382 SVCR_ZA_MASK | SVCR_SM_MASK), 444 383 "%s SVE VL %d/SME VL %d SM+ZA\n", 445 - cfg->name, sve_vl, sme_vl); 446 - ksft_test_result(do_test(cfg, sve_vl, sme_vl, 447 - SVCR_SM_MASK), 384 + cfg->name, sve_vls[sve], 385 + sme_vls[sme]); 386 + ksft_test_result(do_test(cfg, sve_vls[sve], 387 + sme_vls[sme], SVCR_SM_MASK), 448 388 "%s SVE VL %d/SME VL %d SM\n", 449 - cfg->name, sve_vl, sme_vl); 450 - ksft_test_result(do_test(cfg, sve_vl, sme_vl, 451 - SVCR_ZA_MASK), 389 + cfg->name, sve_vls[sve], 390 + sme_vls[sme]); 391 + ksft_test_result(do_test(cfg, sve_vls[sve], 392 + sme_vls[sme], SVCR_ZA_MASK), 452 393 "%s SVE VL %d/SME VL %d ZA\n", 453 - cfg->name, sve_vl, sme_vl); 394 + cfg->name, sve_vls[sve], 395 + sme_vls[sme]); 454 396 } 397 + } 398 + 399 + for (sme = 0; sme < sme_vl_count; sme++) { 400 + ret = prctl(PR_SME_SET_VL, sme_vls[sme]); 401 + if (ret == -1) 402 + ksft_exit_fail_msg("PR_SME_SET_VL failed: %s (%d)\n", 403 + strerror(errno), errno); 404 + 405 + ksft_test_result(do_test(cfg, 0, sme_vls[sme], 406 + SVCR_ZA_MASK | SVCR_SM_MASK), 407 + "%s SME VL %d SM+ZA\n", 408 + cfg->name, sme_vls[sme]); 409 + ksft_test_result(do_test(cfg, 0, sme_vls[sme], SVCR_SM_MASK), 410 + "%s SME VL %d SM\n", 411 + cfg->name, sme_vls[sme]); 412 + ksft_test_result(do_test(cfg, 0, sme_vls[sme], SVCR_ZA_MASK), 413 + "%s SME VL %d ZA\n", 414 + cfg->name, sme_vls[sme]); 455 415 } 456 416 } 457 417 458 - int sve_count_vls(void) 418 + void sve_count_vls(void) 459 419 { 460 420 unsigned int vq; 461 - int vl_count = 0; 462 421 int vl; 463 422 464 423 if (!(getauxval(AT_HWCAP) & HWCAP_SVE)) 465 - return 0; 424 + return; 466 425 467 426 /* 468 427 * Enumerate up to SVE_VQ_MAX vector lengths 469 428 */ 470 - for (vq = SVE_VQ_MAX; vq > 0; --vq) { 429 + for (vq = SVE_VQ_MAX; vq > 0; vq /= 2) { 471 430 vl = prctl(PR_SVE_SET_VL, vq * 16); 472 431 if (vl == -1) 473 432 ksft_exit_fail_msg("PR_SVE_SET_VL failed: %s (%d)\n", ··· 483 432 if (vq != sve_vq_from_vl(vl)) 484 433 vq = sve_vq_from_vl(vl); 485 434 486 - vl_count++; 435 + sve_vls[sve_vl_count++] = vl; 487 436 } 488 - 489 - return vl_count; 490 437 } 491 438 492 - int sme_count_vls(void) 439 + void sme_count_vls(void) 493 440 { 494 441 unsigned int vq; 495 - int vl_count = 0; 496 442 int vl; 497 443 498 444 if (!(getauxval(AT_HWCAP2) & HWCAP2_SME)) 499 - return 0; 500 - 501 - /* Ensure we configure a SME VL, used to flag if SVCR is set */ 502 - default_sme_vl = 16; 445 + return; 503 446 504 447 /* 505 448 * Enumerate up to SVE_VQ_MAX vector lengths 506 449 */ 507 - for (vq = SVE_VQ_MAX; vq > 0; --vq) { 450 + for (vq = SVE_VQ_MAX; vq > 0; vq /= 2) { 508 451 vl = prctl(PR_SME_SET_VL, vq * 16); 509 452 if (vl == -1) 510 453 ksft_exit_fail_msg("PR_SME_SET_VL failed: %s (%d)\n", ··· 506 461 507 462 vl &= PR_SME_VL_LEN_MASK; 508 463 464 + /* Found lowest VL */ 465 + if (sve_vq_from_vl(vl) > vq) 466 + break; 467 + 509 468 if (vq != sve_vq_from_vl(vl)) 510 469 vq = sve_vq_from_vl(vl); 511 470 512 - vl_count++; 471 + sme_vls[sme_vl_count++] = vl; 513 472 } 514 473 515 - return vl_count; 474 + /* Ensure we configure a SME VL, used to flag if SVCR is set */ 475 + default_sme_vl = sme_vls[0]; 516 476 } 517 477 518 478 int main(void) 519 479 { 520 480 int i; 521 481 int tests = 1; /* FPSIMD */ 482 + int sme_ver; 522 483 523 484 srandom(getpid()); 524 485 525 486 ksft_print_header(); 526 - tests += sve_count_vls(); 527 - tests += (sve_count_vls() * sme_count_vls()) * 3; 487 + 488 + sve_count_vls(); 489 + sme_count_vls(); 490 + 491 + tests += sve_vl_count; 492 + tests += sme_vl_count * 3; 493 + tests += (sve_vl_count * sme_vl_count) * 3; 528 494 ksft_set_plan(ARRAY_SIZE(syscalls) * tests); 529 495 496 + if (getauxval(AT_HWCAP2) & HWCAP2_SME2) 497 + sme_ver = 2; 498 + else 499 + sme_ver = 1; 500 + 530 501 if (getauxval(AT_HWCAP2) & HWCAP2_SME_FA64) 531 - ksft_print_msg("SME with FA64\n"); 502 + ksft_print_msg("SME%d with FA64\n", sme_ver); 532 503 else if (getauxval(AT_HWCAP2) & HWCAP2_SME) 533 - ksft_print_msg("SME without FA64\n"); 504 + ksft_print_msg("SME%d without FA64\n", sme_ver); 534 505 535 506 for (i = 0; i < ARRAY_SIZE(syscalls); i++) 536 507 test_one_syscall(&syscalls[i]);
+10 -15
tools/testing/selftests/arm64/bti/test.c
··· 6 6 7 7 #include "system.h" 8 8 9 + #include <stdbool.h> 9 10 #include <stddef.h> 10 11 #include <linux/errno.h> 11 12 #include <linux/auxvec.h> ··· 102 101 uc->uc_mcontext.pstate &= ~PSR_BTYPE_MASK; 103 102 } 104 103 105 - static int skip_all; 104 + /* Does the system have BTI? */ 105 + static bool have_bti; 106 106 107 107 static void __do_test(void (*trampoline)(void (*)(void)), 108 108 void (*fn)(void), ··· 111 109 const char *name, 112 110 int expect_sigill) 113 111 { 114 - if (skip_all) { 115 - test_skipped++; 116 - putstr("ok "); 117 - putnum(test_num); 118 - putstr(" "); 119 - puttestname(name, trampoline_name); 120 - putstr(" # SKIP\n"); 121 - 122 - return; 123 - } 124 - 125 - /* Branch Target exceptions should only happen in BTI binaries: */ 126 - if (!BTI) 112 + /* 113 + * Branch Target exceptions should only happen for BTI 114 + * binaries running on a system with BTI: 115 + */ 116 + if (!BTI || !have_bti) 127 117 expect_sigill = 0; 128 118 129 119 sigill_expected = expect_sigill; ··· 193 199 putstr("# HWCAP2_BTI present\n"); 194 200 if (!(hwcap & HWCAP_PACA)) 195 201 putstr("# Bad hardware? Expect problems.\n"); 202 + have_bti = true; 196 203 } else { 197 204 putstr("# HWCAP2_BTI not present\n"); 198 - skip_all = 1; 205 + have_bti = false; 199 206 } 200 207 201 208 putstr("# Test binary");
+2
tools/testing/selftests/arm64/fp/.gitignore
··· 12 12 za-fork 13 13 za-ptrace 14 14 za-test 15 + zt-ptrace 16 + zt-test
+5
tools/testing/selftests/arm64/fp/Makefile
··· 14 14 sve-test \ 15 15 ssve-test \ 16 16 za-test \ 17 + zt-ptrace \ 18 + zt-test \ 17 19 vlset 18 20 TEST_PROGS_EXTENDED := fpsimd-stress sve-stress ssve-stress za-stress 19 21 ··· 42 40 -static -ffreestanding -Wall $^ -o $@ 43 41 $(OUTPUT)/za-ptrace: za-ptrace.c 44 42 $(OUTPUT)/za-test: za-test.S $(OUTPUT)/asm-utils.o 43 + $(CC) -nostdlib $^ -o $@ 44 + $(OUTPUT)/zt-ptrace: zt-ptrace.c 45 + $(OUTPUT)/zt-test: zt-test.S $(OUTPUT)/asm-utils.o 45 46 $(CC) -nostdlib $^ -o $@ 46 47 47 48 include ../../lib.mk
+1 -1
tools/testing/selftests/arm64/fp/assembler.h
··· 57 57 // Utility macro to print a literal string 58 58 // Clobbers x0-x4,x8 59 59 .macro puts string 60 - .pushsection .rodata.str1.1, "aMS", 1 60 + .pushsection .rodata.str1.1, "aMS", @progbits, 1 61 61 .L__puts_literal\@: .string "\string" 62 62 .popsection 63 63
-1
tools/testing/selftests/arm64/fp/fp-pidbench.S
··· 31 31 // Main program entry point 32 32 .globl _start 33 33 function _start 34 - _start: 35 34 puts "Iterations per test: " 36 35 mov x20, #10000 37 36 lsl x20, x20, #8
+31 -3
tools/testing/selftests/arm64/fp/fp-stress.c
··· 370 370 ksft_print_msg("Started %s\n", child->name); 371 371 } 372 372 373 + static void start_zt(struct child_data *child, int cpu) 374 + { 375 + int ret; 376 + 377 + ret = asprintf(&child->name, "ZT-%d", cpu); 378 + if (ret == -1) 379 + ksft_exit_fail_msg("asprintf() failed\n"); 380 + 381 + child_start(child, "./zt-test"); 382 + 383 + ksft_print_msg("Started %s\n", child->name); 384 + } 385 + 373 386 static void probe_vls(int vls[], int *vl_count, int set_vl) 374 387 { 375 388 unsigned int vq; ··· 390 377 391 378 *vl_count = 0; 392 379 393 - for (vq = SVE_VQ_MAX; vq > 0; --vq) { 380 + for (vq = SVE_VQ_MAX; vq > 0; vq /= 2) { 394 381 vl = prctl(set_vl, vq * 16); 395 382 if (vl == -1) 396 383 ksft_exit_fail_msg("SET_VL failed: %s (%d)\n", 397 384 strerror(errno), errno); 398 385 399 386 vl &= PR_SVE_VL_LEN_MASK; 387 + 388 + if (*vl_count && (vl == vls[*vl_count - 1])) 389 + break; 400 390 401 391 vq = sve_vq_from_vl(vl); 402 392 ··· 442 426 bool all_children_started = false; 443 427 int seen_children; 444 428 int sve_vls[MAX_VLS], sme_vls[MAX_VLS]; 429 + bool have_sme2; 445 430 struct sigaction sa; 446 431 447 432 while ((c = getopt_long(argc, argv, "t:", options, NULL)) != -1) { ··· 475 458 sme_vl_count = 0; 476 459 } 477 460 461 + if (getauxval(AT_HWCAP2) & HWCAP2_SME2) { 462 + tests += cpus; 463 + have_sme2 = true; 464 + } else { 465 + have_sme2 = false; 466 + } 467 + 478 468 /* Force context switching if we only have FPSIMD */ 479 469 if (!sve_vl_count && !sme_vl_count) 480 470 fpsimd_per_cpu = 2; ··· 492 468 ksft_print_header(); 493 469 ksft_set_plan(tests); 494 470 495 - ksft_print_msg("%d CPUs, %d SVE VLs, %d SME VLs\n", 496 - cpus, sve_vl_count, sme_vl_count); 471 + ksft_print_msg("%d CPUs, %d SVE VLs, %d SME VLs, SME2 %s\n", 472 + cpus, sve_vl_count, sme_vl_count, 473 + have_sme2 ? "present" : "absent"); 497 474 498 475 if (timeout > 0) 499 476 ksft_print_msg("Will run for %ds\n", timeout); ··· 552 527 start_ssve(&children[num_children++], sme_vls[j], i); 553 528 start_za(&children[num_children++], sme_vls[j], i); 554 529 } 530 + 531 + if (have_sme2) 532 + start_zt(&children[num_children++], i); 555 533 } 556 534 557 535 /*
-1
tools/testing/selftests/arm64/fp/fpsimd-test.S
··· 215 215 // Main program entry point 216 216 .globl _start 217 217 function _start 218 - _start: 219 218 mov x23, #0 // signal count 220 219 221 220 mov w0, #SIGINT
+20
tools/testing/selftests/arm64/fp/sme-inst.h
··· 48 48 | ((\offset) & 7) 49 49 .endm 50 50 51 + /* 52 + * LDR (ZT0) 53 + * 54 + * LDR ZT0, nx 55 + */ 56 + .macro _ldr_zt nx 57 + .inst 0xe11f8000 \ 58 + | (((\nx) & 0x1f) << 5) 59 + .endm 60 + 61 + /* 62 + * STR (ZT0) 63 + * 64 + * STR ZT0, nx 65 + */ 66 + .macro _str_zt nx 67 + .inst 0xe13f8000 \ 68 + | (((\nx) & 0x1f) << 5) 69 + .endm 70 + 51 71 #endif
+12 -2
tools/testing/selftests/arm64/fp/sve-ptrace.c
··· 30 30 #define NT_ARM_SSVE 0x40b 31 31 #endif 32 32 33 + /* 34 + * The architecture defines the maximum VQ as 16 but for extensibility 35 + * the kernel specifies the SVE_VQ_MAX as 512 resulting in us running 36 + * a *lot* more tests than are useful if we use it. Until the 37 + * architecture is extended let's limit our coverage to what is 38 + * currently allowed, plus one extra to ensure we cover constraining 39 + * the VL as expected. 40 + */ 41 + #define TEST_VQ_MAX 17 42 + 33 43 struct vec_type { 34 44 const char *name; 35 45 unsigned long hwcap_type; ··· 65 55 }, 66 56 }; 67 57 68 - #define VL_TESTS (((SVE_VQ_MAX - SVE_VQ_MIN) + 1) * 4) 58 + #define VL_TESTS (((TEST_VQ_MAX - SVE_VQ_MIN) + 1) * 4) 69 59 #define FLAG_TESTS 2 70 60 #define FPSIMD_TESTS 2 71 61 ··· 699 689 } 700 690 701 691 /* Step through every possible VQ */ 702 - for (vq = SVE_VQ_MIN; vq <= SVE_VQ_MAX; vq++) { 692 + for (vq = SVE_VQ_MIN; vq <= TEST_VQ_MAX; vq++) { 703 693 vl = sve_vl_from_vq(vq); 704 694 705 695 /* First, try to set this vector length */
-1
tools/testing/selftests/arm64/fp/sve-test.S
··· 378 378 // Main program entry point 379 379 .globl _start 380 380 function _start 381 - _start: 382 381 mov x23, #0 // Irritation signal count 383 382 384 383 mov w0, #SIGINT
+12 -2
tools/testing/selftests/arm64/fp/za-ptrace.c
··· 25 25 #define NT_ARM_ZA 0x40c 26 26 #endif 27 27 28 - #define EXPECTED_TESTS (((SVE_VQ_MAX - SVE_VQ_MIN) + 1) * 3) 28 + /* 29 + * The architecture defines the maximum VQ as 16 but for extensibility 30 + * the kernel specifies the SVE_VQ_MAX as 512 resulting in us running 31 + * a *lot* more tests than are useful if we use it. Until the 32 + * architecture is extended let's limit our coverage to what is 33 + * currently allowed, plus one extra to ensure we cover constraining 34 + * the VL as expected. 35 + */ 36 + #define TEST_VQ_MAX 17 37 + 38 + #define EXPECTED_TESTS (((TEST_VQ_MAX - SVE_VQ_MIN) + 1) * 3) 29 39 30 40 static void fill_buf(char *buf, size_t size) 31 41 { ··· 311 301 ksft_print_msg("Parent is %d, child is %d\n", getpid(), child); 312 302 313 303 /* Step through every possible VQ */ 314 - for (vq = SVE_VQ_MIN; vq <= SVE_VQ_MAX; vq++) { 304 + for (vq = SVE_VQ_MIN; vq <= TEST_VQ_MAX; vq++) { 315 305 vl = sve_vl_from_vq(vq); 316 306 317 307 /* First, try to set this vector length */
-1
tools/testing/selftests/arm64/fp/za-test.S
··· 231 231 // Main program entry point 232 232 .globl _start 233 233 function _start 234 - _start: 235 234 mov x23, #0 // signal count 236 235 237 236 mov w0, #SIGINT
+365
tools/testing/selftests/arm64/fp/zt-ptrace.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 2 + /* 3 + * Copyright (C) 2021 ARM Limited. 4 + */ 5 + #include <errno.h> 6 + #include <stdbool.h> 7 + #include <stddef.h> 8 + #include <stdio.h> 9 + #include <stdlib.h> 10 + #include <string.h> 11 + #include <unistd.h> 12 + #include <sys/auxv.h> 13 + #include <sys/prctl.h> 14 + #include <sys/ptrace.h> 15 + #include <sys/types.h> 16 + #include <sys/uio.h> 17 + #include <sys/wait.h> 18 + #include <asm/sigcontext.h> 19 + #include <asm/ptrace.h> 20 + 21 + #include "../../kselftest.h" 22 + 23 + /* <linux/elf.h> and <sys/auxv.h> don't like each other, so: */ 24 + #ifndef NT_ARM_ZA 25 + #define NT_ARM_ZA 0x40c 26 + #endif 27 + #ifndef NT_ARM_ZT 28 + #define NT_ARM_ZT 0x40d 29 + #endif 30 + 31 + #define EXPECTED_TESTS 3 32 + 33 + static int sme_vl; 34 + 35 + static void fill_buf(char *buf, size_t size) 36 + { 37 + int i; 38 + 39 + for (i = 0; i < size; i++) 40 + buf[i] = random(); 41 + } 42 + 43 + static int do_child(void) 44 + { 45 + if (ptrace(PTRACE_TRACEME, -1, NULL, NULL)) 46 + ksft_exit_fail_msg("PTRACE_TRACEME", strerror(errno)); 47 + 48 + if (raise(SIGSTOP)) 49 + ksft_exit_fail_msg("raise(SIGSTOP)", strerror(errno)); 50 + 51 + return EXIT_SUCCESS; 52 + } 53 + 54 + static struct user_za_header *get_za(pid_t pid, void **buf, size_t *size) 55 + { 56 + struct user_za_header *za; 57 + void *p; 58 + size_t sz = sizeof(*za); 59 + struct iovec iov; 60 + 61 + while (1) { 62 + if (*size < sz) { 63 + p = realloc(*buf, sz); 64 + if (!p) { 65 + errno = ENOMEM; 66 + goto error; 67 + } 68 + 69 + *buf = p; 70 + *size = sz; 71 + } 72 + 73 + iov.iov_base = *buf; 74 + iov.iov_len = sz; 75 + if (ptrace(PTRACE_GETREGSET, pid, NT_ARM_ZA, &iov)) 76 + goto error; 77 + 78 + za = *buf; 79 + if (za->size <= sz) 80 + break; 81 + 82 + sz = za->size; 83 + } 84 + 85 + return za; 86 + 87 + error: 88 + return NULL; 89 + } 90 + 91 + static int set_za(pid_t pid, const struct user_za_header *za) 92 + { 93 + struct iovec iov; 94 + 95 + iov.iov_base = (void *)za; 96 + iov.iov_len = za->size; 97 + return ptrace(PTRACE_SETREGSET, pid, NT_ARM_ZA, &iov); 98 + } 99 + 100 + static int get_zt(pid_t pid, char zt[ZT_SIG_REG_BYTES]) 101 + { 102 + struct iovec iov; 103 + 104 + iov.iov_base = zt; 105 + iov.iov_len = ZT_SIG_REG_BYTES; 106 + return ptrace(PTRACE_GETREGSET, pid, NT_ARM_ZT, &iov); 107 + } 108 + 109 + 110 + static int set_zt(pid_t pid, const char zt[ZT_SIG_REG_BYTES]) 111 + { 112 + struct iovec iov; 113 + 114 + iov.iov_base = (void *)zt; 115 + iov.iov_len = ZT_SIG_REG_BYTES; 116 + return ptrace(PTRACE_SETREGSET, pid, NT_ARM_ZT, &iov); 117 + } 118 + 119 + /* Reading with ZA disabled returns all zeros */ 120 + static void ptrace_za_disabled_read_zt(pid_t child) 121 + { 122 + struct user_za_header za; 123 + char zt[ZT_SIG_REG_BYTES]; 124 + int ret, i; 125 + bool fail = false; 126 + 127 + /* Disable PSTATE.ZA using the ZA interface */ 128 + memset(&za, 0, sizeof(za)); 129 + za.vl = sme_vl; 130 + za.size = sizeof(za); 131 + 132 + ret = set_za(child, &za); 133 + if (ret != 0) { 134 + ksft_print_msg("Failed to disable ZA\n"); 135 + fail = true; 136 + } 137 + 138 + /* Read back ZT */ 139 + ret = get_zt(child, zt); 140 + if (ret != 0) { 141 + ksft_print_msg("Failed to read ZT\n"); 142 + fail = true; 143 + } 144 + 145 + for (i = 0; i < ARRAY_SIZE(zt); i++) { 146 + if (zt[i]) { 147 + ksft_print_msg("zt[%d]: 0x%x != 0\n", i, zt[i]); 148 + fail = true; 149 + } 150 + } 151 + 152 + ksft_test_result(!fail, "ptrace_za_disabled_read_zt\n"); 153 + } 154 + 155 + /* Writing then reading ZT should return the data written */ 156 + static void ptrace_set_get_zt(pid_t child) 157 + { 158 + char zt_in[ZT_SIG_REG_BYTES]; 159 + char zt_out[ZT_SIG_REG_BYTES]; 160 + int ret, i; 161 + bool fail = false; 162 + 163 + fill_buf(zt_in, sizeof(zt_in)); 164 + 165 + ret = set_zt(child, zt_in); 166 + if (ret != 0) { 167 + ksft_print_msg("Failed to set ZT\n"); 168 + fail = true; 169 + } 170 + 171 + ret = get_zt(child, zt_out); 172 + if (ret != 0) { 173 + ksft_print_msg("Failed to read ZT\n"); 174 + fail = true; 175 + } 176 + 177 + for (i = 0; i < ARRAY_SIZE(zt_in); i++) { 178 + if (zt_in[i] != zt_out[i]) { 179 + ksft_print_msg("zt[%d]: 0x%x != 0x%x\n", i, 180 + zt_in[i], zt_out[i]); 181 + fail = true; 182 + } 183 + } 184 + 185 + ksft_test_result(!fail, "ptrace_set_get_zt\n"); 186 + } 187 + 188 + /* Writing ZT should set PSTATE.ZA */ 189 + static void ptrace_enable_za_via_zt(pid_t child) 190 + { 191 + struct user_za_header za_in; 192 + struct user_za_header *za_out; 193 + char zt[ZT_SIG_REG_BYTES]; 194 + char *za_data; 195 + size_t za_out_size; 196 + int ret, i, vq; 197 + bool fail = false; 198 + 199 + /* Disable PSTATE.ZA using the ZA interface */ 200 + memset(&za_in, 0, sizeof(za_in)); 201 + za_in.vl = sme_vl; 202 + za_in.size = sizeof(za_in); 203 + 204 + ret = set_za(child, &za_in); 205 + if (ret != 0) { 206 + ksft_print_msg("Failed to disable ZA\n"); 207 + fail = true; 208 + } 209 + 210 + /* Write ZT */ 211 + fill_buf(zt, sizeof(zt)); 212 + ret = set_zt(child, zt); 213 + if (ret != 0) { 214 + ksft_print_msg("Failed to set ZT\n"); 215 + fail = true; 216 + } 217 + 218 + /* Read back ZA and check for register data */ 219 + za_out = NULL; 220 + za_out_size = 0; 221 + if (get_za(child, (void **)&za_out, &za_out_size)) { 222 + /* Should have an unchanged VL */ 223 + if (za_out->vl != sme_vl) { 224 + ksft_print_msg("VL changed from %d to %d\n", 225 + sme_vl, za_out->vl); 226 + fail = true; 227 + } 228 + vq = __sve_vq_from_vl(za_out->vl); 229 + za_data = (char *)za_out + ZA_PT_ZA_OFFSET; 230 + 231 + /* Should have register data */ 232 + if (za_out->size < ZA_PT_SIZE(vq)) { 233 + ksft_print_msg("ZA data less than expected: %u < %u\n", 234 + za_out->size, ZA_PT_SIZE(vq)); 235 + fail = true; 236 + vq = 0; 237 + } 238 + 239 + /* That register data should be non-zero */ 240 + for (i = 0; i < ZA_PT_ZA_SIZE(vq); i++) { 241 + if (za_data[i]) { 242 + ksft_print_msg("ZA byte %d is %x\n", 243 + i, za_data[i]); 244 + fail = true; 245 + } 246 + } 247 + } else { 248 + ksft_print_msg("Failed to read ZA\n"); 249 + fail = true; 250 + } 251 + 252 + ksft_test_result(!fail, "ptrace_enable_za_via_zt\n"); 253 + } 254 + 255 + static int do_parent(pid_t child) 256 + { 257 + int ret = EXIT_FAILURE; 258 + pid_t pid; 259 + int status; 260 + siginfo_t si; 261 + 262 + /* Attach to the child */ 263 + while (1) { 264 + int sig; 265 + 266 + pid = wait(&status); 267 + if (pid == -1) { 268 + perror("wait"); 269 + goto error; 270 + } 271 + 272 + /* 273 + * This should never happen but it's hard to flag in 274 + * the framework. 275 + */ 276 + if (pid != child) 277 + continue; 278 + 279 + if (WIFEXITED(status) || WIFSIGNALED(status)) 280 + ksft_exit_fail_msg("Child died unexpectedly\n"); 281 + 282 + if (!WIFSTOPPED(status)) 283 + goto error; 284 + 285 + sig = WSTOPSIG(status); 286 + 287 + if (ptrace(PTRACE_GETSIGINFO, pid, NULL, &si)) { 288 + if (errno == ESRCH) 289 + goto disappeared; 290 + 291 + if (errno == EINVAL) { 292 + sig = 0; /* bust group-stop */ 293 + goto cont; 294 + } 295 + 296 + ksft_test_result_fail("PTRACE_GETSIGINFO: %s\n", 297 + strerror(errno)); 298 + goto error; 299 + } 300 + 301 + if (sig == SIGSTOP && si.si_code == SI_TKILL && 302 + si.si_pid == pid) 303 + break; 304 + 305 + cont: 306 + if (ptrace(PTRACE_CONT, pid, NULL, sig)) { 307 + if (errno == ESRCH) 308 + goto disappeared; 309 + 310 + ksft_test_result_fail("PTRACE_CONT: %s\n", 311 + strerror(errno)); 312 + goto error; 313 + } 314 + } 315 + 316 + ksft_print_msg("Parent is %d, child is %d\n", getpid(), child); 317 + 318 + ptrace_za_disabled_read_zt(child); 319 + ptrace_set_get_zt(child); 320 + ptrace_enable_za_via_zt(child); 321 + 322 + ret = EXIT_SUCCESS; 323 + 324 + error: 325 + kill(child, SIGKILL); 326 + 327 + disappeared: 328 + return ret; 329 + } 330 + 331 + int main(void) 332 + { 333 + int ret = EXIT_SUCCESS; 334 + pid_t child; 335 + 336 + srandom(getpid()); 337 + 338 + ksft_print_header(); 339 + 340 + if (!(getauxval(AT_HWCAP2) & HWCAP2_SME2)) { 341 + ksft_set_plan(1); 342 + ksft_exit_skip("SME2 not available\n"); 343 + } 344 + 345 + /* We need a valid SME VL to enable/disable ZA */ 346 + sme_vl = prctl(PR_SME_GET_VL); 347 + if (sme_vl == -1) { 348 + ksft_set_plan(1); 349 + ksft_exit_skip("Failed to read SME VL: %d (%s)\n", 350 + errno, strerror(errno)); 351 + } 352 + 353 + ksft_set_plan(EXPECTED_TESTS); 354 + 355 + child = fork(); 356 + if (!child) 357 + return do_child(); 358 + 359 + if (do_parent(child)) 360 + ret = EXIT_FAILURE; 361 + 362 + ksft_print_cnts(); 363 + 364 + return ret; 365 + }
+316
tools/testing/selftests/arm64/fp/zt-test.S
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 2 + // Copyright (C) 2021-2 ARM Limited. 3 + // Original author: Mark Brown <broonie@kernel.org> 4 + // 5 + // Scalable Matrix Extension ZT context switch test 6 + // Repeatedly writes unique test patterns into ZT0 7 + // and reads them back to verify integrity. 8 + 9 + #include <asm/unistd.h> 10 + #include "assembler.h" 11 + #include "asm-offsets.h" 12 + #include "sme-inst.h" 13 + 14 + .arch_extension sve 15 + 16 + #define ZT_SZ 512 17 + #define ZT_B (ZT_SZ / 8) 18 + 19 + // Declare some storage space to shadow ZT register contents and a 20 + // scratch buffer. 21 + .pushsection .text 22 + .data 23 + .align 4 24 + ztref: 25 + .space ZT_B 26 + scratch: 27 + .space ZT_B 28 + .popsection 29 + 30 + 31 + // Generate a test pattern for storage in ZT 32 + // x0: pid 33 + // x1: generation 34 + 35 + // These values are used to construct a 32-bit pattern that is repeated in the 36 + // scratch buffer as many times as will fit: 37 + // bits 31:24 generation number (increments once per test_loop) 38 + // bits 23: 8 pid 39 + // bits 7: 0 32-bit lane index 40 + 41 + function pattern 42 + mov w3, wzr 43 + bfi w3, w0, #8, #16 // PID 44 + bfi w3, w1, #24, #8 // Generation 45 + 46 + ldr x0, =scratch 47 + mov w1, #ZT_B / 4 48 + 49 + 0: str w3, [x0], #4 50 + add w3, w3, #1 // Lane 51 + subs w1, w1, #1 52 + b.ne 0b 53 + 54 + ret 55 + endfunction 56 + 57 + // Set up test pattern in a ZT horizontal vector 58 + // x0: pid 59 + // x1: generation 60 + function setup_zt 61 + mov x4, x30 62 + 63 + bl pattern // Get pattern in scratch buffer 64 + ldr x0, =ztref 65 + ldr x1, =scratch 66 + mov x2, #ZT_B 67 + bl memcpy 68 + 69 + ldr x0, =ztref 70 + _ldr_zt 0 // load zt0 from pointer x0 71 + 72 + ret x4 73 + endfunction 74 + 75 + // Trivial memory compare: compare x2 bytes starting at address x0 with 76 + // bytes starting at address x1. 77 + // Returns only if all bytes match; otherwise, the program is aborted. 78 + // Clobbers x0-x5. 79 + function memcmp 80 + cbz x2, 2f 81 + 82 + stp x0, x1, [sp, #-0x20]! 83 + str x2, [sp, #0x10] 84 + 85 + mov x5, #0 86 + 0: ldrb w3, [x0, x5] 87 + ldrb w4, [x1, x5] 88 + add x5, x5, #1 89 + cmp w3, w4 90 + b.ne 1f 91 + subs x2, x2, #1 92 + b.ne 0b 93 + 94 + 1: ldr x2, [sp, #0x10] 95 + ldp x0, x1, [sp], #0x20 96 + b.ne barf 97 + 98 + 2: ret 99 + endfunction 100 + 101 + // Verify that a ZT vector matches its shadow in memory, else abort 102 + // Clobbers x0-x3 103 + function check_zt 104 + mov x3, x30 105 + 106 + ldr x0, =scratch // Poison scratch 107 + mov x1, #ZT_B 108 + bl memfill_ae 109 + 110 + ldr x0, =scratch 111 + _str_zt 0 112 + 113 + ldr x0, =ztref 114 + ldr x1, =scratch 115 + mov x2, #ZT_B 116 + mov x30, x3 117 + b memcmp 118 + endfunction 119 + 120 + // Any SME register modified here can cause corruption in the main 121 + // thread -- but *only* the locations modified here. 122 + function irritator_handler 123 + // Increment the irritation signal count (x23): 124 + ldr x0, [x2, #ucontext_regs + 8 * 23] 125 + add x0, x0, #1 126 + str x0, [x2, #ucontext_regs + 8 * 23] 127 + 128 + // Corrupt some random ZT data 129 + #if 0 130 + adr x0, .text + (irritator_handler - .text) / 16 * 16 131 + movi v0.8b, #1 132 + movi v9.16b, #2 133 + movi v31.8b, #3 134 + #endif 135 + 136 + ret 137 + endfunction 138 + 139 + function tickle_handler 140 + // Increment the signal count (x23): 141 + ldr x0, [x2, #ucontext_regs + 8 * 23] 142 + add x0, x0, #1 143 + str x0, [x2, #ucontext_regs + 8 * 23] 144 + 145 + ret 146 + endfunction 147 + 148 + function terminate_handler 149 + mov w21, w0 150 + mov x20, x2 151 + 152 + puts "Terminated by signal " 153 + mov w0, w21 154 + bl putdec 155 + puts ", no error, iterations=" 156 + ldr x0, [x20, #ucontext_regs + 8 * 22] 157 + bl putdec 158 + puts ", signals=" 159 + ldr x0, [x20, #ucontext_regs + 8 * 23] 160 + bl putdecn 161 + 162 + mov x0, #0 163 + mov x8, #__NR_exit 164 + svc #0 165 + endfunction 166 + 167 + // w0: signal number 168 + // x1: sa_action 169 + // w2: sa_flags 170 + // Clobbers x0-x6,x8 171 + function setsignal 172 + str x30, [sp, #-((sa_sz + 15) / 16 * 16 + 16)]! 173 + 174 + mov w4, w0 175 + mov x5, x1 176 + mov w6, w2 177 + 178 + add x0, sp, #16 179 + mov x1, #sa_sz 180 + bl memclr 181 + 182 + mov w0, w4 183 + add x1, sp, #16 184 + str w6, [x1, #sa_flags] 185 + str x5, [x1, #sa_handler] 186 + mov x2, #0 187 + mov x3, #sa_mask_sz 188 + mov x8, #__NR_rt_sigaction 189 + svc #0 190 + 191 + cbz w0, 1f 192 + 193 + puts "sigaction failure\n" 194 + b .Labort 195 + 196 + 1: ldr x30, [sp], #((sa_sz + 15) / 16 * 16 + 16) 197 + ret 198 + endfunction 199 + 200 + // Main program entry point 201 + .globl _start 202 + function _start 203 + mov x23, #0 // signal count 204 + 205 + mov w0, #SIGINT 206 + adr x1, terminate_handler 207 + mov w2, #SA_SIGINFO 208 + bl setsignal 209 + 210 + mov w0, #SIGTERM 211 + adr x1, terminate_handler 212 + mov w2, #SA_SIGINFO 213 + bl setsignal 214 + 215 + mov w0, #SIGUSR1 216 + adr x1, irritator_handler 217 + mov w2, #SA_SIGINFO 218 + orr w2, w2, #SA_NODEFER 219 + bl setsignal 220 + 221 + mov w0, #SIGUSR2 222 + adr x1, tickle_handler 223 + mov w2, #SA_SIGINFO 224 + orr w2, w2, #SA_NODEFER 225 + bl setsignal 226 + 227 + smstart_za 228 + 229 + // Obtain our PID, to ensure test pattern uniqueness between processes 230 + mov x8, #__NR_getpid 231 + svc #0 232 + mov x20, x0 233 + 234 + puts "PID:\t" 235 + mov x0, x20 236 + bl putdecn 237 + 238 + mov x22, #0 // generation number, increments per iteration 239 + .Ltest_loop: 240 + mov x0, x20 241 + mov x1, x22 242 + bl setup_zt 243 + 244 + mov x8, #__NR_sched_yield // Encourage preemption 245 + svc #0 246 + 247 + mrs x0, S3_3_C4_C2_2 // SVCR should have ZA=1,SM=0 248 + and x1, x0, #3 249 + cmp x1, #2 250 + b.ne svcr_barf 251 + 252 + bl check_zt 253 + 254 + add x22, x22, #1 // Everything still working 255 + b .Ltest_loop 256 + 257 + .Labort: 258 + mov x0, #0 259 + mov x1, #SIGABRT 260 + mov x8, #__NR_kill 261 + svc #0 262 + endfunction 263 + 264 + function barf 265 + // fpsimd.c acitivty log dump hack 266 + // ldr w0, =0xdeadc0de 267 + // mov w8, #__NR_exit 268 + // svc #0 269 + // end hack 270 + smstop 271 + mov x10, x0 // expected data 272 + mov x11, x1 // actual data 273 + mov x12, x2 // data size 274 + 275 + puts "Mismatch: PID=" 276 + mov x0, x20 277 + bl putdec 278 + puts ", iteration=" 279 + mov x0, x22 280 + bl putdec 281 + puts "\tExpected [" 282 + mov x0, x10 283 + mov x1, x12 284 + bl dumphex 285 + puts "]\n\tGot [" 286 + mov x0, x11 287 + mov x1, x12 288 + bl dumphex 289 + puts "]\n" 290 + 291 + mov x8, #__NR_getpid 292 + svc #0 293 + // fpsimd.c acitivty log dump hack 294 + // ldr w0, =0xdeadc0de 295 + // mov w8, #__NR_exit 296 + // svc #0 297 + // ^ end of hack 298 + mov x1, #SIGABRT 299 + mov x8, #__NR_kill 300 + svc #0 301 + // mov x8, #__NR_exit 302 + // mov x1, #1 303 + // svc #0 304 + endfunction 305 + 306 + function svcr_barf 307 + mov x10, x0 308 + 309 + puts "Bad SVCR: " 310 + mov x0, x10 311 + bl putdecn 312 + 313 + mov x8, #__NR_exit 314 + mov x1, #1 315 + svc #0 316 + endfunction
+15 -6
tools/testing/selftests/arm64/mte/Makefile
··· 1 1 # SPDX-License-Identifier: GPL-2.0 2 2 # Copyright (C) 2020 ARM Limited 3 3 4 - # preserve CC value from top level Makefile 5 - ifeq ($(CC),cc) 6 - CC := $(CROSS_COMPILE)gcc 7 - endif 8 - 9 4 CFLAGS += -std=gnu99 -I. -pthread 10 5 LDFLAGS += -pthread 11 6 SRCS := $(filter-out mte_common_util.c,$(wildcard *.c)) 12 7 PROGS := $(patsubst %.c,%,$(SRCS)) 13 8 9 + ifeq ($(LLVM),) 10 + # For GCC check that the toolchain has MTE support. 11 + 12 + # preserve CC value from top level Makefile 13 + ifeq ($(CC),cc) 14 + CC := $(CROSS_COMPILE)gcc 15 + endif 16 + 14 17 #check if the compiler works well 15 18 mte_cc_support := $(shell if ($(CC) $(CFLAGS) -march=armv8.5-a+memtag -E -x c /dev/null -o /dev/null 2>&1) then echo "1"; fi) 19 + 20 + else 21 + 22 + # All supported clang versions also support MTE. 23 + mte_cc_support := 1 24 + 25 + endif 16 26 17 27 ifeq ($(mte_cc_support),1) 18 28 # Generated binaries to be installed by top KSFT script 19 29 TEST_GEN_PROGS := $(PROGS) 20 30 21 - # Get Kernel headers installed and use them. 22 31 else 23 32 $(warning compiler "$(CC)" does not support the ARMv8.5 MTE extension.) 24 33 $(warning test program "mte" will not be created.)
+2
tools/testing/selftests/arm64/signal/.gitignore
··· 4 4 sme_* 5 5 ssve_* 6 6 sve_* 7 + tpidr2_siginfo 7 8 za_* 9 + zt_* 8 10 !*.[ch]
+6 -2
tools/testing/selftests/arm64/signal/Makefile
··· 22 22 23 23 # Common test-unit targets to build common-layout test-cases executables 24 24 # Needs secondary expansion to properly include the testcase c-file in pre-reqs 25 + COMMON_SOURCES := test_signals.c test_signals_utils.c testcases/testcases.c \ 26 + signals.S 27 + COMMON_HEADERS := test_signals.h test_signals_utils.h testcases/testcases.h 28 + 25 29 .SECONDEXPANSION: 26 - $(PROGS): test_signals.c test_signals_utils.c testcases/testcases.c signals.S $$@.c test_signals.h test_signals_utils.h testcases/testcases.h 27 - $(CC) $(CFLAGS) $^ -o $@ 30 + $(PROGS): $$@.c ${COMMON_SOURCES} ${COMMON_HEADERS} 31 + $(CC) $(CFLAGS) ${@}.c ${COMMON_SOURCES} -o $@
+1 -3
tools/testing/selftests/arm64/signal/test_signals.c
··· 12 12 #include "test_signals.h" 13 13 #include "test_signals_utils.h" 14 14 15 - struct tdescr *current; 15 + struct tdescr *current = &tde; 16 16 17 17 int main(int argc, char *argv[]) 18 18 { 19 - current = &tde; 20 - 21 19 ksft_print_msg("%s :: %s\n", current->name, current->descr); 22 20 if (test_setup(current) && test_init(current)) { 23 21 test_run(current);
+2
tools/testing/selftests/arm64/signal/test_signals.h
··· 34 34 FSVE_BIT, 35 35 FSME_BIT, 36 36 FSME_FA64_BIT, 37 + FSME2_BIT, 37 38 FMAX_END 38 39 }; 39 40 ··· 42 41 #define FEAT_SVE (1UL << FSVE_BIT) 43 42 #define FEAT_SME (1UL << FSME_BIT) 44 43 #define FEAT_SME_FA64 (1UL << FSME_FA64_BIT) 44 + #define FEAT_SME2 (1UL << FSME2_BIT) 45 45 46 46 /* 47 47 * A descriptor used to describe and configure a test case.
+7 -2
tools/testing/selftests/arm64/signal/test_signals_utils.c
··· 29 29 " SVE ", 30 30 " SME ", 31 31 " FA64 ", 32 + " SME2 ", 32 33 }; 33 34 34 35 #define MAX_FEATS_SZ 128 ··· 193 192 * in the copy, this was previously validated in 194 193 * ASSERT_GOOD_CONTEXT(). 195 194 */ 196 - to_copy = offset + sizeof(struct extra_context) + 16 + 197 - extra->size; 195 + to_copy = __builtin_offsetof(ucontext_t, 196 + uc_mcontext.__reserved); 197 + to_copy += offset + sizeof(struct extra_context) + 16; 198 + to_copy += extra->size; 198 199 copied_extra = (struct extra_context *)&(td->live_uc->uc_mcontext.__reserved[offset]); 199 200 } else { 200 201 copied_extra = NULL; ··· 326 323 td->feats_supported |= FEAT_SME; 327 324 if (getauxval(AT_HWCAP2) & HWCAP2_SME_FA64) 328 325 td->feats_supported |= FEAT_SME_FA64; 326 + if (getauxval(AT_HWCAP2) & HWCAP2_SME2) 327 + td->feats_supported |= FEAT_SME2; 329 328 if (feats_ok(td)) { 330 329 if (td->feats_required & td->feats_supported) 331 330 fprintf(stderr,
+10 -6
tools/testing/selftests/arm64/signal/testcases/ssve_regs.c
··· 34 34 35 35 vl &= PR_SME_VL_LEN_MASK; 36 36 37 + /* Did we find the lowest supported VL? */ 38 + if (vq < sve_vq_from_vl(vl)) 39 + break; 40 + 37 41 /* Skip missing VLs */ 38 42 vq = sve_vq_from_vl(vl); 39 43 ··· 96 92 return 1; 97 93 } 98 94 95 + if (!(ssve->flags & SVE_SIG_FLAG_SM)) { 96 + fprintf(stderr, "SVE_SIG_FLAG_SM not set in SVE record\n"); 97 + return 1; 98 + } 99 + 99 100 /* The actual size validation is done in get_current_context() */ 100 101 fprintf(stderr, "Got expected size %u and VL %d\n", 101 102 head->size, ssve->vl); ··· 125 116 struct tdescr tde = { 126 117 .name = "Streaming SVE registers", 127 118 .descr = "Check that we get the right Streaming SVE registers reported", 128 - /* 129 - * We shouldn't require FA64 but things like memset() used in the 130 - * helpers might use unsupported instructions so for now disable 131 - * the test unless we've got the full instruction set. 132 - */ 133 - .feats_required = FEAT_SME | FEAT_SME_FA64, 119 + .feats_required = FEAT_SME, 134 120 .timeout = 3, 135 121 .init = sme_get_vls, 136 122 .run = sme_regs,
+161
tools/testing/selftests/arm64/signal/testcases/ssve_za_regs.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* 3 + * Copyright (C) 2021 ARM Limited 4 + * 5 + * Verify that both the streaming SVE and ZA register context in 6 + * signal frames is set up as expected when enabled simultaneously. 7 + */ 8 + 9 + #include <signal.h> 10 + #include <ucontext.h> 11 + #include <sys/prctl.h> 12 + 13 + #include "test_signals_utils.h" 14 + #include "testcases.h" 15 + 16 + static union { 17 + ucontext_t uc; 18 + char buf[1024 * 128]; 19 + } context; 20 + static unsigned int vls[SVE_VQ_MAX]; 21 + unsigned int nvls = 0; 22 + 23 + static bool sme_get_vls(struct tdescr *td) 24 + { 25 + int vq, vl; 26 + 27 + /* 28 + * Enumerate up to SVE_VQ_MAX vector lengths 29 + */ 30 + for (vq = SVE_VQ_MAX; vq > 0; --vq) { 31 + vl = prctl(PR_SME_SET_VL, vq * 16); 32 + if (vl == -1) 33 + return false; 34 + 35 + vl &= PR_SME_VL_LEN_MASK; 36 + 37 + /* Did we find the lowest supported VL? */ 38 + if (vq < sve_vq_from_vl(vl)) 39 + break; 40 + 41 + /* Skip missing VLs */ 42 + vq = sve_vq_from_vl(vl); 43 + 44 + vls[nvls++] = vl; 45 + } 46 + 47 + /* We need at least one VL */ 48 + if (nvls < 1) { 49 + fprintf(stderr, "Only %d VL supported\n", nvls); 50 + return false; 51 + } 52 + 53 + return true; 54 + } 55 + 56 + static void setup_regs(void) 57 + { 58 + /* smstart sm; real data is TODO */ 59 + asm volatile(".inst 0xd503437f" : : : ); 60 + 61 + /* smstart za; real data is TODO */ 62 + asm volatile(".inst 0xd503457f" : : : ); 63 + } 64 + 65 + static char zeros[ZA_SIG_REGS_SIZE(SVE_VQ_MAX)]; 66 + 67 + static int do_one_sme_vl(struct tdescr *td, siginfo_t *si, ucontext_t *uc, 68 + unsigned int vl) 69 + { 70 + size_t offset; 71 + struct _aarch64_ctx *head = GET_BUF_RESV_HEAD(context); 72 + struct _aarch64_ctx *regs; 73 + struct sve_context *ssve; 74 + struct za_context *za; 75 + int ret; 76 + 77 + fprintf(stderr, "Testing VL %d\n", vl); 78 + 79 + ret = prctl(PR_SME_SET_VL, vl); 80 + if (ret != vl) { 81 + fprintf(stderr, "Failed to set VL, got %d\n", ret); 82 + return 1; 83 + } 84 + 85 + /* 86 + * Get a signal context which should have the SVE and ZA 87 + * frames in it. 88 + */ 89 + setup_regs(); 90 + if (!get_current_context(td, &context.uc, sizeof(context))) 91 + return 1; 92 + 93 + regs = get_header(head, SVE_MAGIC, GET_BUF_RESV_SIZE(context), 94 + &offset); 95 + if (!regs) { 96 + fprintf(stderr, "No SVE context\n"); 97 + return 1; 98 + } 99 + 100 + ssve = (struct sve_context *)regs; 101 + if (ssve->vl != vl) { 102 + fprintf(stderr, "Got SSVE VL %d, expected %d\n", ssve->vl, vl); 103 + return 1; 104 + } 105 + 106 + if (!(ssve->flags & SVE_SIG_FLAG_SM)) { 107 + fprintf(stderr, "SVE_SIG_FLAG_SM not set in SVE record\n"); 108 + return 1; 109 + } 110 + 111 + fprintf(stderr, "Got expected SSVE size %u and VL %d\n", 112 + regs->size, ssve->vl); 113 + 114 + regs = get_header(head, ZA_MAGIC, GET_BUF_RESV_SIZE(context), 115 + &offset); 116 + if (!regs) { 117 + fprintf(stderr, "No ZA context\n"); 118 + return 1; 119 + } 120 + 121 + za = (struct za_context *)regs; 122 + if (za->vl != vl) { 123 + fprintf(stderr, "Got ZA VL %d, expected %d\n", za->vl, vl); 124 + return 1; 125 + } 126 + 127 + fprintf(stderr, "Got expected ZA size %u and VL %d\n", 128 + regs->size, za->vl); 129 + 130 + /* We didn't load any data into ZA so it should be all zeros */ 131 + if (memcmp(zeros, (char *)za + ZA_SIG_REGS_OFFSET, 132 + ZA_SIG_REGS_SIZE(sve_vq_from_vl(za->vl))) != 0) { 133 + fprintf(stderr, "ZA data invalid\n"); 134 + return 1; 135 + } 136 + 137 + return 0; 138 + } 139 + 140 + static int sme_regs(struct tdescr *td, siginfo_t *si, ucontext_t *uc) 141 + { 142 + int i; 143 + 144 + for (i = 0; i < nvls; i++) { 145 + if (do_one_sme_vl(td, si, uc, vls[i])) 146 + return 1; 147 + } 148 + 149 + td->pass = 1; 150 + 151 + return 0; 152 + } 153 + 154 + struct tdescr tde = { 155 + .name = "Streaming SVE registers", 156 + .descr = "Check that we get the right Streaming SVE registers reported", 157 + .feats_required = FEAT_SME, 158 + .timeout = 3, 159 + .init = sme_get_vls, 160 + .run = sme_regs, 161 + };
+40
tools/testing/selftests/arm64/signal/testcases/testcases.c
··· 108 108 return true; 109 109 } 110 110 111 + bool validate_zt_context(struct zt_context *zt, char **err) 112 + { 113 + if (!zt || !err) 114 + return false; 115 + 116 + /* If the context is present there should be at least one register */ 117 + if (zt->nregs == 0) { 118 + *err = "no registers"; 119 + return false; 120 + } 121 + 122 + /* Size should agree with the number of registers */ 123 + if (zt->head.size != ZT_SIG_CONTEXT_SIZE(zt->nregs)) { 124 + *err = "register count does not match size"; 125 + return false; 126 + } 127 + 128 + return true; 129 + } 130 + 111 131 bool validate_reserved(ucontext_t *uc, size_t resv_sz, char **err) 112 132 { 113 133 bool terminated = false; ··· 137 117 struct extra_context *extra = NULL; 138 118 struct sve_context *sve = NULL; 139 119 struct za_context *za = NULL; 120 + struct zt_context *zt = NULL; 140 121 struct _aarch64_ctx *head = 141 122 (struct _aarch64_ctx *)uc->uc_mcontext.__reserved; 142 123 void *extra_data = NULL; ··· 184 163 if (head->size != sizeof(struct esr_context)) 185 164 *err = "Bad size for esr_context"; 186 165 break; 166 + case TPIDR2_MAGIC: 167 + if (head->size != sizeof(struct tpidr2_context)) 168 + *err = "Bad size for tpidr2_context"; 169 + break; 187 170 case SVE_MAGIC: 188 171 if (flags & SVE_CTX) 189 172 *err = "Multiple SVE_MAGIC"; ··· 201 176 /* Size is validated in validate_za_context() */ 202 177 za = (struct za_context *)head; 203 178 new_flags |= ZA_CTX; 179 + break; 180 + case ZT_MAGIC: 181 + if (flags & ZT_CTX) 182 + *err = "Multiple ZT_MAGIC"; 183 + /* Size is validated in validate_za_context() */ 184 + zt = (struct zt_context *)head; 185 + new_flags |= ZT_CTX; 204 186 break; 205 187 case EXTRA_MAGIC: 206 188 if (flags & EXTRA_CTX) ··· 266 234 if (new_flags & ZA_CTX) 267 235 if (!validate_za_context(za, err)) 268 236 return false; 237 + if (new_flags & ZT_CTX) 238 + if (!validate_zt_context(zt, err)) 239 + return false; 269 240 270 241 flags |= new_flags; 271 242 ··· 277 242 278 243 if (terminated && !(flags & FPSIMD_CTX)) { 279 244 *err = "Missing FPSIMD"; 245 + return false; 246 + } 247 + 248 + if (terminated && (flags & ZT_CTX) && !(flags & ZA_CTX)) { 249 + *err = "ZT context but no ZA context"; 280 250 return false; 281 251 } 282 252
+1
tools/testing/selftests/arm64/signal/testcases/testcases.h
··· 18 18 #define SVE_CTX (1 << 1) 19 19 #define ZA_CTX (1 << 2) 20 20 #define EXTRA_CTX (1 << 3) 21 + #define ZT_CTX (1 << 4) 21 22 22 23 #define KSFT_BAD_MAGIC 0xdeadbeef 23 24
+90
tools/testing/selftests/arm64/signal/testcases/tpidr2_siginfo.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* 3 + * Copyright (C) 2022 ARM Limited 4 + * 5 + * Verify that the TPIDR2 register context in signal frames is set up as 6 + * expected. 7 + */ 8 + 9 + #include <signal.h> 10 + #include <ucontext.h> 11 + #include <sys/auxv.h> 12 + #include <sys/prctl.h> 13 + #include <unistd.h> 14 + #include <asm/sigcontext.h> 15 + 16 + #include "test_signals_utils.h" 17 + #include "testcases.h" 18 + 19 + static union { 20 + ucontext_t uc; 21 + char buf[1024 * 128]; 22 + } context; 23 + 24 + #define SYS_TPIDR2 "S3_3_C13_C0_5" 25 + 26 + static uint64_t get_tpidr2(void) 27 + { 28 + uint64_t val; 29 + 30 + asm volatile ( 31 + "mrs %0, " SYS_TPIDR2 "\n" 32 + : "=r"(val) 33 + : 34 + : "cc"); 35 + 36 + return val; 37 + } 38 + 39 + int tpidr2_present(struct tdescr *td, siginfo_t *si, ucontext_t *uc) 40 + { 41 + struct _aarch64_ctx *head = GET_BUF_RESV_HEAD(context); 42 + struct tpidr2_context *tpidr2_ctx; 43 + size_t offset; 44 + bool in_sigframe; 45 + bool have_sme; 46 + __u64 orig_tpidr2; 47 + 48 + have_sme = getauxval(AT_HWCAP2) & HWCAP2_SME; 49 + if (have_sme) 50 + orig_tpidr2 = get_tpidr2(); 51 + 52 + if (!get_current_context(td, &context.uc, sizeof(context))) 53 + return 1; 54 + 55 + tpidr2_ctx = (struct tpidr2_context *) 56 + get_header(head, TPIDR2_MAGIC, td->live_sz, &offset); 57 + 58 + in_sigframe = tpidr2_ctx != NULL; 59 + 60 + fprintf(stderr, "TPIDR2 sigframe %s on system %s SME\n", 61 + in_sigframe ? "present" : "absent", 62 + have_sme ? "with" : "without"); 63 + 64 + td->pass = (in_sigframe == have_sme); 65 + 66 + /* 67 + * Check that the value we read back was the one present at 68 + * the time that the signal was triggered. TPIDR2 is owned by 69 + * libc so we can't safely choose the value and it is possible 70 + * that we may need to revisit this in future if something 71 + * starts deciding to set a new TPIDR2 between us reading and 72 + * the signal. 73 + */ 74 + if (have_sme && tpidr2_ctx) { 75 + if (tpidr2_ctx->tpidr2 != orig_tpidr2) { 76 + fprintf(stderr, "TPIDR2 in frame is %llx, was %llx\n", 77 + tpidr2_ctx->tpidr2, orig_tpidr2); 78 + td->pass = false; 79 + } 80 + } 81 + 82 + return 0; 83 + } 84 + 85 + struct tdescr tde = { 86 + .name = "TPIDR2", 87 + .descr = "Validate that TPIDR2 is present as expected", 88 + .timeout = 3, 89 + .run = tpidr2_present, 90 + };
+4
tools/testing/selftests/arm64/signal/testcases/za_regs.c
··· 34 34 35 35 vl &= PR_SME_VL_LEN_MASK; 36 36 37 + /* Did we find the lowest supported VL? */ 38 + if (vq < sve_vq_from_vl(vl)) 39 + break; 40 + 37 41 /* Skip missing VLs */ 38 42 vq = sve_vq_from_vl(vl); 39 43
+51
tools/testing/selftests/arm64/signal/testcases/zt_no_regs.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* 3 + * Copyright (C) 2021 ARM Limited 4 + * 5 + * Verify that using an instruction not supported in streaming mode 6 + * traps when in streaming mode. 7 + */ 8 + 9 + #include <signal.h> 10 + #include <ucontext.h> 11 + #include <sys/prctl.h> 12 + 13 + #include "test_signals_utils.h" 14 + #include "testcases.h" 15 + 16 + static union { 17 + ucontext_t uc; 18 + char buf[1024 * 128]; 19 + } context; 20 + 21 + int zt_no_regs_run(struct tdescr *td, siginfo_t *si, ucontext_t *uc) 22 + { 23 + size_t offset; 24 + struct _aarch64_ctx *head = GET_BUF_RESV_HEAD(context); 25 + 26 + /* 27 + * Get a signal context which should not have a ZT frame and 28 + * registers in it. 29 + */ 30 + if (!get_current_context(td, &context.uc, sizeof(context))) 31 + return 1; 32 + 33 + head = get_header(head, ZT_MAGIC, GET_BUF_RESV_SIZE(context), &offset); 34 + if (head) { 35 + fprintf(stderr, "Got unexpected ZT context\n"); 36 + return 1; 37 + } 38 + 39 + td->pass = 1; 40 + 41 + return 0; 42 + } 43 + 44 + struct tdescr tde = { 45 + .name = "ZT register data not present", 46 + .descr = "Validate that ZT is not present when ZA is disabled", 47 + .feats_required = FEAT_SME2, 48 + .timeout = 3, 49 + .sanity_disabled = true, 50 + .run = zt_no_regs_run, 51 + };
+85
tools/testing/selftests/arm64/signal/testcases/zt_regs.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* 3 + * Copyright (C) 2021 ARM Limited 4 + * 5 + * Verify that using an instruction not supported in streaming mode 6 + * traps when in streaming mode. 7 + */ 8 + 9 + #include <signal.h> 10 + #include <ucontext.h> 11 + #include <sys/prctl.h> 12 + 13 + #include "test_signals_utils.h" 14 + #include "testcases.h" 15 + 16 + static union { 17 + ucontext_t uc; 18 + char buf[1024 * 128]; 19 + } context; 20 + 21 + static void enable_za(void) 22 + { 23 + /* smstart za; real data is TODO */ 24 + asm volatile(".inst 0xd503457f" : : : ); 25 + } 26 + 27 + int zt_regs_run(struct tdescr *td, siginfo_t *si, ucontext_t *uc) 28 + { 29 + size_t offset; 30 + struct _aarch64_ctx *head = GET_BUF_RESV_HEAD(context); 31 + struct zt_context *zt; 32 + char *zeros; 33 + 34 + /* 35 + * Get a signal context which should have a ZT frame and registers 36 + * in it. 37 + */ 38 + enable_za(); 39 + if (!get_current_context(td, &context.uc, sizeof(context))) 40 + return 1; 41 + 42 + head = get_header(head, ZT_MAGIC, GET_BUF_RESV_SIZE(context), &offset); 43 + if (!head) { 44 + fprintf(stderr, "No ZT context\n"); 45 + return 1; 46 + } 47 + 48 + zt = (struct zt_context *)head; 49 + if (zt->nregs == 0) { 50 + fprintf(stderr, "Got context with no registers\n"); 51 + return 1; 52 + } 53 + 54 + fprintf(stderr, "Got expected size %u for %d registers\n", 55 + head->size, zt->nregs); 56 + 57 + /* We didn't load any data into ZT so it should be all zeros */ 58 + zeros = malloc(ZT_SIG_REGS_SIZE(zt->nregs)); 59 + if (!zeros) { 60 + fprintf(stderr, "Out of memory, nregs=%u\n", zt->nregs); 61 + return 1; 62 + } 63 + memset(zeros, 0, ZT_SIG_REGS_SIZE(zt->nregs)); 64 + 65 + if (memcmp(zeros, (char *)zt + ZT_SIG_REGS_OFFSET, 66 + ZT_SIG_REGS_SIZE(zt->nregs)) != 0) { 67 + fprintf(stderr, "ZT data invalid\n"); 68 + return 1; 69 + } 70 + 71 + free(zeros); 72 + 73 + td->pass = 1; 74 + 75 + return 0; 76 + } 77 + 78 + struct tdescr tde = { 79 + .name = "ZT register data", 80 + .descr = "Validate that ZT is present and has data when ZA is enabled", 81 + .feats_required = FEAT_SME2, 82 + .timeout = 3, 83 + .sanity_disabled = true, 84 + .run = zt_regs_run, 85 + };