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

Merge branches 'for-next/livepatch', 'for-next/user-contig-bbml2', 'for-next/misc', 'for-next/acpi', 'for-next/debug-entry', 'for-next/feat_mte_tagged_far', 'for-next/kselftest', 'for-next/mdscr-cleanup' and 'for-next/vmap-stack', remote-tracking branch 'arm64/for-next/perf' into for-next/core

* arm64/for-next/perf: (23 commits)
drivers/perf: hisi: Support PMUs with no interrupt
drivers/perf: hisi: Relax the event number check of v2 PMUs
drivers/perf: hisi: Add support for HiSilicon SLLC v3 PMU driver
drivers/perf: hisi: Use ACPI driver_data to retrieve SLLC PMU information
drivers/perf: hisi: Add support for HiSilicon DDRC v3 PMU driver
drivers/perf: hisi: Simplify the probe process for each DDRC version
perf/arm-ni: Support sharing IRQs within an NI instance
perf/arm-ni: Consolidate CPU affinity handling
perf/cxlpmu: Fix typos in cxl_pmu.c comments and documentation
perf/cxlpmu: Remove unintended newline from IRQ name format string
perf/cxlpmu: Fix devm_kcalloc() argument order in cxl_pmu_probe()
perf: arm_spe: Relax period restriction
perf: arm_pmuv3: Add support for the Branch Record Buffer Extension (BRBE)
KVM: arm64: nvhe: Disable branch generation in nVHE guests
arm64: Handle BRBE booting requirements
arm64/sysreg: Add BRBE registers and fields
perf/arm: Add missing .suppress_bind_attrs
perf/arm-cmn: Reduce stack usage during discovery
perf: imx9_perf: make the read-only array mask static const
perf/arm-cmn: Broaden module description for wider interconnect support
...

* for-next/livepatch:
: Support for HAVE_LIVEPATCH on arm64
arm64: Kconfig: Keep selects somewhat alphabetically ordered
arm64: Implement HAVE_LIVEPATCH
arm64: stacktrace: Implement arch_stack_walk_reliable()
arm64: stacktrace: Check kretprobe_find_ret_addr() return value
arm64/module: Use text-poke API for late relocations.

* for-next/user-contig-bbml2:
: Optimise the TLBI when folding/unfolding contigous PTEs on hardware with BBML2 and no TLB conflict aborts
arm64/mm: Elide tlbi in contpte_convert() under BBML2
iommu/arm: Add BBM Level 2 smmu feature
arm64: Add BBM Level 2 cpu feature
arm64: cpufeature: Introduce MATCH_ALL_EARLY_CPUS capability type

* for-next/misc:
: Miscellaneous arm64 patches
arm64/gcs: task_gcs_el0_enable() should use passed task
arm64: signal: Remove ISB when resetting POR_EL0
arm64/mm: Drop redundant addr increment in set_huge_pte_at()
arm64: Mark kernel as tainted on SAE and SError panic
arm64/gcs: Don't call gcs_free() when releasing task_struct
arm64: fix unnecessary rebuilding when CONFIG_DEBUG_EFI=y
arm64/mm: Optimize loop to reduce redundant operations of contpte_ptep_get
arm64: pi: use 'targets' instead of extra-y in Makefile

* for-next/acpi:
: Various ACPI arm64 changes
ACPI: Suppress misleading SPCR console message when SPCR table is absent
ACPI: Return -ENODEV from acpi_parse_spcr() when SPCR support is disabled

* for-next/debug-entry:
: Simplify the debug exception entry path
arm64: debug: remove debug exception registration infrastructure
arm64: debug: split bkpt32 exception entry
arm64: debug: split brk64 exception entry
arm64: debug: split hardware watchpoint exception entry
arm64: debug: split single stepping exception entry
arm64: debug: refactor reinstall_suspended_bps()
arm64: debug: split hardware breakpoint exception entry
arm64: entry: Add entry and exit functions for debug exceptions
arm64: debug: remove break/step handler registration infrastructure
arm64: debug: call step handlers statically
arm64: debug: call software breakpoint handlers statically
arm64: refactor aarch32_break_handler()
arm64: debug: clean up single_step_handler logic

* for-next/feat_mte_tagged_far:
: Support for reporting the non-address bits during a synchronous MTE tag check fault
kselftest/arm64/mte: Add mtefar tests on check_mmap_options
kselftest/arm64/mte: Refactor check_mmap_option test
kselftest/arm64/mte: Add verification for address tag in signal handler
kselftest/arm64/mte: Add address tag related macro and function
kselftest/arm64/mte: Check MTE_FAR feature is supported
kselftest/arm64/mte: Register mte signal handler with SA_EXPOSE_TAGBITS
kselftest/arm64: Add MTE_FAR hwcap test
KVM: arm64: Expose FEAT_MTE_TAGGED_FAR feature to guest
arm64: Report address tag when FEAT_MTE_TAGGED_FAR is supported
arm64/cpufeature: Add FEAT_MTE_TAGGED_FAR feature

* for-next/kselftest:
: Kselftest updates for arm64
kselftest/arm64: Handle attempts to disable SM on SME only systems
kselftest/arm64: Fix SVE write data generation for SME only systems
kselftest/arm64: Test SME on SME only systems in fp-ptrace
kselftest/arm64: Test FPSIMD format data writes via NT_ARM_SVE in fp-ptrace
kselftest/arm64: Allow sve-ptrace to run on SME only systems
kselftest/arm4: Provide local defines for AT_HWCAP3
kselftest/arm64: Specify SVE data when testing VL set in sve-ptrace
kselftest/arm64: Fix test for streaming FPSIMD write in sve-ptrace
kselftest/arm64: Fix check for setting new VLs in sve-ptrace
kselftest/arm64: Convert tpidr2 test to use kselftest.h

* for-next/mdscr-cleanup:
: Drop redundant DBG_MDSCR_* macros
KVM: selftests: Change MDSCR_EL1 register holding variables as uint64_t
arm64/debug: Drop redundant DBG_MDSCR_* macros

* for-next/vmap-stack:
: Force VMAP_STACK on arm64
arm64: remove CONFIG_VMAP_STACK checks from entry code
arm64: remove CONFIG_VMAP_STACK checks from SDEI stack handling
arm64: remove CONFIG_VMAP_STACK checks from stacktrace overflow logic
arm64: remove CONFIG_VMAP_STACK conditionals from traps overflow stack
arm64: remove CONFIG_VMAP_STACK conditionals from irq stack setup
arm64: Remove CONFIG_VMAP_STACK conditionals from THREAD_SHIFT and THREAD_ALIGN
arm64: efi: Remove CONFIG_VMAP_STACK check
arm64: Mandate VMAP_STACK
arm64: efi: Fix KASAN false positive for EFI runtime stack
arm64/ptrace: Fix stack-out-of-bounds read in regs_get_kernel_stack_nth()
arm64/gcs: Don't call gcs_free() during flush_gcs()
arm64: Restrict pagetable teardown to avoid false warning
docs: arm64: Fix ICC_SRE_EL2 register typo in booting.rst

+1548 -853
+1 -1
Documentation/arch/arm64/booting.rst
··· 234 234 235 235 - If the kernel is entered at EL1: 236 236 237 - - ICC.SRE_EL2.Enable (bit 3) must be initialised to 0b1 237 + - ICC_SRE_EL2.Enable (bit 3) must be initialised to 0b1 238 238 - ICC_SRE_EL2.SRE (bit 0) must be initialised to 0b1. 239 239 240 240 - The DT or ACPI tables must describe a GICv3 interrupt controller.
+3
Documentation/arch/arm64/elf_hwcaps.rst
··· 435 435 HWCAP2_POE 436 436 Functionality implied by ID_AA64MMFR3_EL1.S1POE == 0b0001. 437 437 438 + HWCAP3_MTE_FAR 439 + Functionality implied by ID_AA64PFR2_EL1.MTEFAR == 0b0001. 440 + 438 441 4. Unused AT_HWCAP bits 439 442 ----------------------- 440 443
+6 -5
Documentation/arch/arm64/tagged-pointers.rst
··· 60 60 on the tag information for user virtual addresses being maintained 61 61 in these fields unless the flag was set. 62 62 63 - Due to architecture limitations, bits 63:60 of the fault address 64 - are not preserved in response to synchronous tag check faults 65 - (SEGV_MTESERR) even if SA_EXPOSE_TAGBITS was set. Applications should 66 - treat the values of these bits as undefined in order to accommodate 67 - future architecture revisions which may preserve the bits. 63 + If FEAT_MTE_TAGGED_FAR (Armv8.9) is supported, bits 63:60 of the fault address 64 + are preserved in response to synchronous tag check faults (SEGV_MTESERR) 65 + otherwise not preserved even if SA_EXPOSE_TAGBITS was set. 66 + Applications should interpret the values of these bits based on 67 + the support for the HWCAP3_MTE_FAR. If the support is not present, 68 + the values of these bits should be considered as undefined otherwise valid. 68 69 69 70 For signals raised in response to watchpoint debug exceptions, the 70 71 tag information will be preserved regardless of the SA_EXPOSE_TAGBITS
+4
arch/arm64/Kconfig
··· 234 234 select HAVE_HW_BREAKPOINT if PERF_EVENTS 235 235 select HAVE_IOREMAP_PROT 236 236 select HAVE_IRQ_TIME_ACCOUNTING 237 + select HAVE_LIVEPATCH 237 238 select HAVE_MOD_ARCH_SPECIFIC 238 239 select HAVE_NMI 239 240 select HAVE_PERF_EVENTS ··· 243 242 select HAVE_PERF_USER_STACK_DUMP 244 243 select HAVE_PREEMPT_DYNAMIC_KEY 245 244 select HAVE_REGS_AND_STACK_ACCESS_API 245 + select HAVE_RELIABLE_STACKTRACE 246 246 select HAVE_POSIX_CPU_TIMERS_TASK_WORK 247 247 select HAVE_FUNCTION_ARG_ACCESS_API 248 248 select MMU_GATHER_RCU_TABLE_FREE ··· 281 279 select HAVE_SOFTIRQ_ON_OWN_STACK 282 280 select USER_STACKTRACE_SUPPORT 283 281 select VDSO_GETRANDOM 282 + select VMAP_STACK 284 283 help 285 284 ARM 64-bit (AArch64) Linux support. 286 285 ··· 2502 2499 2503 2500 source "arch/arm64/kvm/Kconfig" 2504 2501 2502 + source "kernel/livepatch/Kconfig"
+2 -2
arch/arm64/include/asm/assembler.h
··· 53 53 .macro disable_step_tsk, flgs, tmp 54 54 tbz \flgs, #TIF_SINGLESTEP, 9990f 55 55 mrs \tmp, mdscr_el1 56 - bic \tmp, \tmp, #DBG_MDSCR_SS 56 + bic \tmp, \tmp, #MDSCR_EL1_SS 57 57 msr mdscr_el1, \tmp 58 58 isb // Take effect before a subsequent clear of DAIF.D 59 59 9990: ··· 63 63 .macro enable_step_tsk, flgs, tmp 64 64 tbz \flgs, #TIF_SINGLESTEP, 9990f 65 65 mrs \tmp, mdscr_el1 66 - orr \tmp, \tmp, #DBG_MDSCR_SS 66 + orr \tmp, \tmp, #MDSCR_EL1_SS 67 67 msr mdscr_el1, \tmp 68 68 9990: 69 69 .endm
+28
arch/arm64/include/asm/cpufeature.h
··· 275 275 #define ARM64_CPUCAP_OPTIONAL_FOR_LATE_CPU ((u16)BIT(5)) 276 276 /* Panic when a conflict is detected */ 277 277 #define ARM64_CPUCAP_PANIC_ON_CONFLICT ((u16)BIT(6)) 278 + /* 279 + * When paired with SCOPE_LOCAL_CPU, all early CPUs must satisfy the 280 + * condition. This is different from SCOPE_SYSTEM where the check is performed 281 + * only once at the end of the SMP boot on the sanitised ID registers. 282 + * SCOPE_SYSTEM is not suitable for cases where the capability depends on 283 + * properties local to a CPU like MIDR_EL1. 284 + */ 285 + #define ARM64_CPUCAP_MATCH_ALL_EARLY_CPUS ((u16)BIT(7)) 278 286 279 287 /* 280 288 * CPU errata workarounds that need to be enabled at boot time if one or ··· 312 304 (ARM64_CPUCAP_SCOPE_LOCAL_CPU | \ 313 305 ARM64_CPUCAP_OPTIONAL_FOR_LATE_CPU | \ 314 306 ARM64_CPUCAP_PERMITTED_FOR_LATE_CPU) 307 + /* 308 + * CPU feature detected at boot time and present on all early CPUs. Late CPUs 309 + * are permitted to have the feature even if it hasn't been enabled, although 310 + * the feature will not be used by Linux in this case. If all early CPUs have 311 + * the feature, then every late CPU must have it. 312 + */ 313 + #define ARM64_CPUCAP_EARLY_LOCAL_CPU_FEATURE \ 314 + (ARM64_CPUCAP_SCOPE_LOCAL_CPU | \ 315 + ARM64_CPUCAP_PERMITTED_FOR_LATE_CPU | \ 316 + ARM64_CPUCAP_MATCH_ALL_EARLY_CPUS) 315 317 316 318 /* 317 319 * CPU feature detected at boot time, on one or more CPUs. A late CPU ··· 407 389 static inline int cpucap_default_scope(const struct arm64_cpu_capabilities *cap) 408 390 { 409 391 return cap->type & ARM64_CPUCAP_SCOPE_MASK; 392 + } 393 + 394 + static inline bool cpucap_match_all_early_cpus(const struct arm64_cpu_capabilities *cap) 395 + { 396 + return cap->type & ARM64_CPUCAP_MATCH_ALL_EARLY_CPUS; 410 397 } 411 398 412 399 /* ··· 869 846 static inline bool system_supports_pmuv3(void) 870 847 { 871 848 return cpus_have_final_cap(ARM64_HAS_PMUV3); 849 + } 850 + 851 + static inline bool system_supports_bbml2_noabort(void) 852 + { 853 + return alternative_has_cap_unlikely(ARM64_HAS_BBML2_NOABORT); 872 854 } 873 855 874 856 int do_emulate_mrs(struct pt_regs *regs, u32 sys_reg, u32 rt);
+4 -36
arch/arm64/include/asm/debug-monitors.h
··· 13 13 #include <asm/ptrace.h> 14 14 15 15 /* Low-level stepping controls. */ 16 - #define DBG_MDSCR_SS (1 << 0) 17 16 #define DBG_SPSR_SS (1 << 21) 18 - 19 - /* MDSCR_EL1 enabling bits */ 20 - #define DBG_MDSCR_KDE (1 << 13) 21 - #define DBG_MDSCR_MDE (1 << 15) 22 - #define DBG_MDSCR_MASK ~(DBG_MDSCR_KDE | DBG_MDSCR_MDE) 23 17 24 18 #define DBG_ESR_EVT(x) (((x) >> 27) & 0x7) 25 19 ··· 56 62 #define DBG_HOOK_HANDLED 0 57 63 #define DBG_HOOK_ERROR 1 58 64 59 - struct step_hook { 60 - struct list_head node; 61 - int (*fn)(struct pt_regs *regs, unsigned long esr); 62 - }; 63 - 64 - void register_user_step_hook(struct step_hook *hook); 65 - void unregister_user_step_hook(struct step_hook *hook); 66 - 67 - void register_kernel_step_hook(struct step_hook *hook); 68 - void unregister_kernel_step_hook(struct step_hook *hook); 69 - 70 - struct break_hook { 71 - struct list_head node; 72 - int (*fn)(struct pt_regs *regs, unsigned long esr); 73 - u16 imm; 74 - u16 mask; /* These bits are ignored when comparing with imm */ 75 - }; 76 - 77 - void register_user_break_hook(struct break_hook *hook); 78 - void unregister_user_break_hook(struct break_hook *hook); 79 - 80 - void register_kernel_break_hook(struct break_hook *hook); 81 - void unregister_kernel_break_hook(struct break_hook *hook); 82 - 83 65 u8 debug_monitors_arch(void); 84 66 85 67 enum dbg_active_el { ··· 78 108 void kernel_fastforward_single_step(struct pt_regs *regs); 79 109 80 110 #ifdef CONFIG_HAVE_HW_BREAKPOINT 81 - int reinstall_suspended_bps(struct pt_regs *regs); 111 + bool try_step_suspended_breakpoints(struct pt_regs *regs); 82 112 #else 83 - static inline int reinstall_suspended_bps(struct pt_regs *regs) 113 + static inline bool try_step_suspended_breakpoints(struct pt_regs *regs) 84 114 { 85 - return -ENODEV; 115 + return false; 86 116 } 87 117 #endif 88 118 89 - int aarch32_break_handler(struct pt_regs *regs); 90 - 91 - void debug_traps_init(void); 119 + bool try_handle_aarch32_break(struct pt_regs *regs); 92 120 93 121 #endif /* __ASSEMBLY */ 94 122 #endif /* __ASM_DEBUG_MONITORS_H */
+13 -1
arch/arm64/include/asm/exception.h
··· 59 59 void do_el1_bti(struct pt_regs *regs, unsigned long esr); 60 60 void do_el0_gcs(struct pt_regs *regs, unsigned long esr); 61 61 void do_el1_gcs(struct pt_regs *regs, unsigned long esr); 62 - void do_debug_exception(unsigned long addr_if_watchpoint, unsigned long esr, 62 + #ifdef CONFIG_HAVE_HW_BREAKPOINT 63 + void do_breakpoint(unsigned long esr, struct pt_regs *regs); 64 + void do_watchpoint(unsigned long addr, unsigned long esr, 63 65 struct pt_regs *regs); 66 + #else 67 + static inline void do_breakpoint(unsigned long esr, struct pt_regs *regs) {} 68 + static inline void do_watchpoint(unsigned long addr, unsigned long esr, 69 + struct pt_regs *regs) {} 70 + #endif /* CONFIG_HAVE_HW_BREAKPOINT */ 71 + void do_el0_softstep(unsigned long esr, struct pt_regs *regs); 72 + void do_el1_softstep(unsigned long esr, struct pt_regs *regs); 73 + void do_el0_brk64(unsigned long esr, struct pt_regs *regs); 74 + void do_el1_brk64(unsigned long esr, struct pt_regs *regs); 75 + void do_bkpt32(unsigned long esr, struct pt_regs *regs); 64 76 void do_fpsimd_acc(unsigned long esr, struct pt_regs *regs); 65 77 void do_sve_acc(unsigned long esr, struct pt_regs *regs); 66 78 void do_sme_acc(unsigned long esr, struct pt_regs *regs);
+1 -1
arch/arm64/include/asm/gcs.h
··· 58 58 59 59 static inline bool task_gcs_el0_enabled(struct task_struct *task) 60 60 { 61 - return current->thread.gcs_el0_mode & PR_SHADOW_STACK_ENABLE; 61 + return task->thread.gcs_el0_mode & PR_SHADOW_STACK_ENABLE; 62 62 } 63 63 64 64 void gcs_set_el0_mode(struct task_struct *task);
+1
arch/arm64/include/asm/hwcap.h
··· 176 176 #define KERNEL_HWCAP_POE __khwcap2_feature(POE) 177 177 178 178 #define __khwcap3_feature(x) (const_ilog2(HWCAP3_ ## x) + 128) 179 + #define KERNEL_HWCAP_MTE_FAR __khwcap3_feature(MTE_FAR) 179 180 180 181 /* 181 182 * This yields a mask that user programs can use to figure out what
+12
arch/arm64/include/asm/kgdb.h
··· 24 24 extern void kgdb_handle_bus_error(void); 25 25 extern int kgdb_fault_expected; 26 26 27 + int kgdb_brk_handler(struct pt_regs *regs, unsigned long esr); 28 + int kgdb_compiled_brk_handler(struct pt_regs *regs, unsigned long esr); 29 + #ifdef CONFIG_KGDB 30 + int kgdb_single_step_handler(struct pt_regs *regs, unsigned long esr); 31 + #else 32 + static inline int kgdb_single_step_handler(struct pt_regs *regs, 33 + unsigned long esr) 34 + { 35 + return DBG_HOOK_ERROR; 36 + } 37 + #endif 38 + 27 39 #endif /* !__ASSEMBLY__ */ 28 40 29 41 /*
+8
arch/arm64/include/asm/kprobes.h
··· 41 41 void __kprobes *trampoline_probe_handler(struct pt_regs *regs); 42 42 43 43 #endif /* CONFIG_KPROBES */ 44 + 45 + int __kprobes kprobe_brk_handler(struct pt_regs *regs, 46 + unsigned long esr); 47 + int __kprobes kprobe_ss_brk_handler(struct pt_regs *regs, 48 + unsigned long esr); 49 + int __kprobes kretprobe_brk_handler(struct pt_regs *regs, 50 + unsigned long esr); 51 + 44 52 #endif /* _ARM_KPROBES_H */
+1 -5
arch/arm64/include/asm/memory.h
··· 118 118 * VMAP'd stacks are allocated at page granularity, so we must ensure that such 119 119 * stacks are a multiple of page size. 120 120 */ 121 - #if defined(CONFIG_VMAP_STACK) && (MIN_THREAD_SHIFT < PAGE_SHIFT) 121 + #if (MIN_THREAD_SHIFT < PAGE_SHIFT) 122 122 #define THREAD_SHIFT PAGE_SHIFT 123 123 #else 124 124 #define THREAD_SHIFT MIN_THREAD_SHIFT ··· 135 135 * checking sp & (1 << THREAD_SHIFT), which we can do cheaply in the entry 136 136 * assembly. 137 137 */ 138 - #ifdef CONFIG_VMAP_STACK 139 138 #define THREAD_ALIGN (2 * THREAD_SIZE) 140 - #else 141 - #define THREAD_ALIGN THREAD_SIZE 142 - #endif 143 139 144 140 #define IRQ_STACK_SIZE THREAD_SIZE 145 141
+1 -5
arch/arm64/include/asm/stacktrace.h
··· 59 59 60 60 #define on_thread_stack() (on_task_stack(current, current_stack_pointer, 1)) 61 61 62 - #ifdef CONFIG_VMAP_STACK 63 62 DECLARE_PER_CPU(unsigned long [OVERFLOW_STACK_SIZE/sizeof(long)], overflow_stack); 64 63 65 64 static inline struct stack_info stackinfo_get_overflow(void) ··· 71 72 .high = high, 72 73 }; 73 74 } 74 - #else 75 - #define stackinfo_get_overflow() stackinfo_get_unknown() 76 - #endif 77 75 78 - #if defined(CONFIG_ARM_SDE_INTERFACE) && defined(CONFIG_VMAP_STACK) 76 + #if defined(CONFIG_ARM_SDE_INTERFACE) 79 77 DECLARE_PER_CPU(unsigned long *, sdei_stack_normal_ptr); 80 78 DECLARE_PER_CPU(unsigned long *, sdei_stack_critical_ptr); 81 79
-4
arch/arm64/include/asm/system_misc.h
··· 25 25 int signo, int sicode, unsigned long far, 26 26 unsigned long err); 27 27 28 - void hook_debug_fault_code(int nr, int (*fn)(unsigned long, unsigned long, 29 - struct pt_regs *), 30 - int sig, int code, const char *name); 31 - 32 28 struct mm_struct; 33 29 extern void __show_regs(struct pt_regs *); 34 30
+4 -1
arch/arm64/include/asm/thread_info.h
··· 70 70 #define TIF_SYSCALL_TRACEPOINT 10 /* syscall tracepoint for ftrace */ 71 71 #define TIF_SECCOMP 11 /* syscall secure computing */ 72 72 #define TIF_SYSCALL_EMU 12 /* syscall emulation active */ 73 + #define TIF_PATCH_PENDING 13 /* pending live patching update */ 73 74 #define TIF_MEMDIE 18 /* is terminating due to OOM killer */ 74 75 #define TIF_FREEZE 19 75 76 #define TIF_RESTORE_SIGMASK 20 ··· 97 96 #define _TIF_SYSCALL_TRACEPOINT (1 << TIF_SYSCALL_TRACEPOINT) 98 97 #define _TIF_SECCOMP (1 << TIF_SECCOMP) 99 98 #define _TIF_SYSCALL_EMU (1 << TIF_SYSCALL_EMU) 99 + #define _TIF_PATCH_PENDING (1 << TIF_PATCH_PENDING) 100 100 #define _TIF_UPROBE (1 << TIF_UPROBE) 101 101 #define _TIF_SINGLESTEP (1 << TIF_SINGLESTEP) 102 102 #define _TIF_32BIT (1 << TIF_32BIT) ··· 109 107 #define _TIF_WORK_MASK (_TIF_NEED_RESCHED | _TIF_NEED_RESCHED_LAZY | \ 110 108 _TIF_NOTIFY_RESUME | _TIF_FOREIGN_FPSTATE | \ 111 109 _TIF_UPROBE | _TIF_MTE_ASYNC_FAULT | \ 112 - _TIF_NOTIFY_SIGNAL | _TIF_SIGPENDING) 110 + _TIF_NOTIFY_SIGNAL | _TIF_SIGPENDING | \ 111 + _TIF_PATCH_PENDING) 113 112 114 113 #define _TIF_SYSCALL_WORK (_TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT | \ 115 114 _TIF_SYSCALL_TRACEPOINT | _TIF_SECCOMP | \
+6
arch/arm64/include/asm/traps.h
··· 29 29 void arm64_force_sig_mceerr(int code, unsigned long far, short lsb, const char *str); 30 30 void arm64_force_sig_ptrace_errno_trap(int errno, unsigned long far, const char *str); 31 31 32 + int bug_brk_handler(struct pt_regs *regs, unsigned long esr); 33 + int cfi_brk_handler(struct pt_regs *regs, unsigned long esr); 34 + int reserved_fault_brk_handler(struct pt_regs *regs, unsigned long esr); 35 + int kasan_brk_handler(struct pt_regs *regs, unsigned long esr); 36 + int ubsan_brk_handler(struct pt_regs *regs, unsigned long esr); 37 + 32 38 int early_brk64(unsigned long addr, unsigned long esr, struct pt_regs *regs); 33 39 34 40 /*
+11
arch/arm64/include/asm/uprobes.h
··· 28 28 bool simulate; 29 29 }; 30 30 31 + int uprobe_brk_handler(struct pt_regs *regs, unsigned long esr); 32 + #ifdef CONFIG_UPROBES 33 + int uprobe_single_step_handler(struct pt_regs *regs, unsigned long esr); 34 + #else 35 + static inline int uprobe_single_step_handler(struct pt_regs *regs, 36 + unsigned long esr) 37 + { 38 + return DBG_HOOK_ERROR; 39 + } 40 + #endif 41 + 31 42 #endif
+1
arch/arm64/include/uapi/asm/hwcap.h
··· 143 143 /* 144 144 * HWCAP3 flags - for AT_HWCAP3 145 145 */ 146 + #define HWCAP3_MTE_FAR (1UL << 0) 146 147 147 148 #endif /* _UAPI__ASM_HWCAP_H */
+1 -1
arch/arm64/kernel/Makefile
··· 81 81 always-$(KBUILD_BUILTIN) += vmlinux.lds 82 82 83 83 ifeq ($(CONFIG_DEBUG_EFI),y) 84 - AFLAGS_head.o += -DVMLINUX_PATH="\"$(realpath $(objtree)/vmlinux)\"" 84 + AFLAGS_head.o += -DVMLINUX_PATH="\"$(abspath vmlinux)\"" 85 85 endif 86 86 87 87 # for cleaning
+7 -3
arch/arm64/kernel/acpi.c
··· 197 197 */ 198 198 void __init acpi_boot_table_init(void) 199 199 { 200 + int ret; 201 + 200 202 /* 201 203 * Enable ACPI instead of device tree unless 202 204 * - ACPI has been disabled explicitly (acpi=off), or ··· 252 250 * behaviour, use acpi=nospcr to disable console in ACPI SPCR 253 251 * table as default serial console. 254 252 */ 255 - acpi_parse_spcr(earlycon_acpi_spcr_enable, 253 + ret = acpi_parse_spcr(earlycon_acpi_spcr_enable, 256 254 !param_acpi_nospcr); 257 - pr_info("Use ACPI SPCR as default console: %s\n", 258 - param_acpi_nospcr ? "No" : "Yes"); 255 + if (!ret || param_acpi_nospcr || !IS_ENABLED(CONFIG_ACPI_SPCR_TABLE)) 256 + pr_info("Use ACPI SPCR as default console: No\n"); 257 + else 258 + pr_info("Use ACPI SPCR as default console: Yes\n"); 259 259 260 260 if (IS_ENABLED(CONFIG_ACPI_BGRT)) 261 261 acpi_table_parse(ACPI_SIG_BGRT, acpi_parse_bgrt);
+96 -11
arch/arm64/kernel/cpufeature.c
··· 320 320 321 321 static const struct arm64_ftr_bits ftr_id_aa64pfr2[] = { 322 322 ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64PFR2_EL1_FPMR_SHIFT, 4, 0), 323 + ARM64_FTR_BITS(FTR_VISIBLE, FTR_NONSTRICT, FTR_LOWER_SAFE, ID_AA64PFR2_EL1_MTEFAR_SHIFT, 4, ID_AA64PFR2_EL1_MTEFAR_NI), 323 324 ARM64_FTR_END, 324 325 }; 325 326 ··· 2214 2213 return arm64_test_sw_feature_override(ARM64_SW_FEATURE_OVERRIDE_HVHE); 2215 2214 } 2216 2215 2216 + static bool has_bbml2_noabort(const struct arm64_cpu_capabilities *caps, int scope) 2217 + { 2218 + /* 2219 + * We want to allow usage of BBML2 in as wide a range of kernel contexts 2220 + * as possible. This list is therefore an allow-list of known-good 2221 + * implementations that both support BBML2 and additionally, fulfill the 2222 + * extra constraint of never generating TLB conflict aborts when using 2223 + * the relaxed BBML2 semantics (such aborts make use of BBML2 in certain 2224 + * kernel contexts difficult to prove safe against recursive aborts). 2225 + * 2226 + * Note that implementations can only be considered "known-good" if their 2227 + * implementors attest to the fact that the implementation never raises 2228 + * TLB conflict aborts for BBML2 mapping granularity changes. 2229 + */ 2230 + static const struct midr_range supports_bbml2_noabort_list[] = { 2231 + MIDR_REV_RANGE(MIDR_CORTEX_X4, 0, 3, 0xf), 2232 + MIDR_REV_RANGE(MIDR_NEOVERSE_V3, 0, 2, 0xf), 2233 + {} 2234 + }; 2235 + 2236 + /* Does our cpu guarantee to never raise TLB conflict aborts? */ 2237 + if (!is_midr_in_range_list(supports_bbml2_noabort_list)) 2238 + return false; 2239 + 2240 + /* 2241 + * We currently ignore the ID_AA64MMFR2_EL1 register, and only care 2242 + * about whether the MIDR check passes. 2243 + */ 2244 + 2245 + return true; 2246 + } 2247 + 2217 2248 #ifdef CONFIG_ARM64_PAN 2218 2249 static void cpu_enable_pan(const struct arm64_cpu_capabilities *__unused) 2219 2250 { ··· 2907 2874 .matches = has_cpuid_feature, 2908 2875 ARM64_CPUID_FIELDS(ID_AA64PFR1_EL1, MTE, MTE3) 2909 2876 }, 2877 + { 2878 + .desc = "FAR on MTE Tag Check Fault", 2879 + .capability = ARM64_MTE_FAR, 2880 + .type = ARM64_CPUCAP_SYSTEM_FEATURE, 2881 + .matches = has_cpuid_feature, 2882 + ARM64_CPUID_FIELDS(ID_AA64PFR2_EL1, MTEFAR, IMP) 2883 + }, 2910 2884 #endif /* CONFIG_ARM64_MTE */ 2911 2885 { 2912 2886 .desc = "RCpc load-acquire (LDAPR)", ··· 3019 2979 .type = ARM64_CPUCAP_SYSTEM_FEATURE, 3020 2980 .matches = has_cpuid_feature, 3021 2981 ARM64_CPUID_FIELDS(ID_AA64MMFR2_EL1, EVT, IMP) 2982 + }, 2983 + { 2984 + .desc = "BBM Level 2 without TLB conflict abort", 2985 + .capability = ARM64_HAS_BBML2_NOABORT, 2986 + .type = ARM64_CPUCAP_EARLY_LOCAL_CPU_FEATURE, 2987 + .matches = has_bbml2_noabort, 3022 2988 }, 3023 2989 { 3024 2990 .desc = "52-bit Virtual Addressing for KVM (LPA2)", ··· 3257 3211 #ifdef CONFIG_ARM64_MTE 3258 3212 HWCAP_CAP(ID_AA64PFR1_EL1, MTE, MTE2, CAP_HWCAP, KERNEL_HWCAP_MTE), 3259 3213 HWCAP_CAP(ID_AA64PFR1_EL1, MTE, MTE3, CAP_HWCAP, KERNEL_HWCAP_MTE3), 3214 + HWCAP_CAP(ID_AA64PFR2_EL1, MTEFAR, IMP, CAP_HWCAP, KERNEL_HWCAP_MTE_FAR), 3260 3215 #endif /* CONFIG_ARM64_MTE */ 3261 3216 HWCAP_CAP(ID_AA64MMFR0_EL1, ECV, IMP, CAP_HWCAP, KERNEL_HWCAP_ECV), 3262 3217 HWCAP_CAP(ID_AA64MMFR1_EL1, AFP, IMP, CAP_HWCAP, KERNEL_HWCAP_AFP), ··· 3417 3370 3418 3371 scope_mask &= ARM64_CPUCAP_SCOPE_MASK; 3419 3372 for (i = 0; i < ARM64_NCAPS; i++) { 3373 + bool match_all = false; 3374 + bool caps_set = false; 3375 + bool boot_cpu = false; 3376 + 3420 3377 caps = cpucap_ptrs[i]; 3421 - if (!caps || !(caps->type & scope_mask) || 3422 - cpus_have_cap(caps->capability) || 3423 - !caps->matches(caps, cpucap_default_scope(caps))) 3378 + if (!caps || !(caps->type & scope_mask)) 3424 3379 continue; 3425 3380 3426 - if (caps->desc && !caps->cpus) 3381 + match_all = cpucap_match_all_early_cpus(caps); 3382 + caps_set = cpus_have_cap(caps->capability); 3383 + boot_cpu = scope_mask & SCOPE_BOOT_CPU; 3384 + 3385 + /* 3386 + * Unless it's a match-all CPUs feature, avoid probing if 3387 + * already detected. 3388 + */ 3389 + if (!match_all && caps_set) 3390 + continue; 3391 + 3392 + /* 3393 + * A match-all CPUs capability is only set when probing the 3394 + * boot CPU. It may be cleared subsequently if not detected on 3395 + * secondary ones. 3396 + */ 3397 + if (match_all && !caps_set && !boot_cpu) 3398 + continue; 3399 + 3400 + if (!caps->matches(caps, cpucap_default_scope(caps))) { 3401 + if (match_all) 3402 + __clear_bit(caps->capability, system_cpucaps); 3403 + continue; 3404 + } 3405 + 3406 + /* 3407 + * Match-all CPUs capabilities are logged later when the 3408 + * system capabilities are finalised. 3409 + */ 3410 + if (!match_all && caps->desc && !caps->cpus) 3427 3411 pr_info("detected: %s\n", caps->desc); 3428 3412 3429 3413 __set_bit(caps->capability, system_cpucaps); 3430 3414 3431 - if ((scope_mask & SCOPE_BOOT_CPU) && (caps->type & SCOPE_BOOT_CPU)) 3415 + if (boot_cpu && (caps->type & SCOPE_BOOT_CPU)) 3432 3416 set_bit(caps->capability, boot_cpucaps); 3433 3417 } 3434 3418 } ··· 3860 3782 enable_cpu_capabilities(SCOPE_ALL & ~SCOPE_BOOT_CPU); 3861 3783 apply_alternatives_all(); 3862 3784 3863 - /* 3864 - * Log any cpucaps with a cpumask as these aren't logged by 3865 - * update_cpu_capabilities(). 3866 - */ 3867 3785 for (int i = 0; i < ARM64_NCAPS; i++) { 3868 3786 const struct arm64_cpu_capabilities *caps = cpucap_ptrs[i]; 3869 3787 3870 - if (caps && caps->cpus && caps->desc && 3871 - cpumask_any(caps->cpus) < nr_cpu_ids) 3788 + if (!caps || !caps->desc) 3789 + continue; 3790 + 3791 + /* 3792 + * Log any cpucaps with a cpumask as these aren't logged by 3793 + * update_cpu_capabilities(). 3794 + */ 3795 + if (caps->cpus && cpumask_any(caps->cpus) < nr_cpu_ids) 3872 3796 pr_info("detected: %s on CPU%*pbl\n", 3873 3797 caps->desc, cpumask_pr_args(caps->cpus)); 3798 + 3799 + /* Log match-all CPUs capabilities */ 3800 + if (cpucap_match_all_early_cpus(caps) && 3801 + cpus_have_cap(caps->capability)) 3802 + pr_info("detected: %s\n", caps->desc); 3874 3803 } 3875 3804 3876 3805 /*
+1
arch/arm64/kernel/cpuinfo.c
··· 160 160 [KERNEL_HWCAP_SME_SFEXPA] = "smesfexpa", 161 161 [KERNEL_HWCAP_SME_STMOP] = "smestmop", 162 162 [KERNEL_HWCAP_SME_SMOP4] = "smesmop4", 163 + [KERNEL_HWCAP_MTE_FAR] = "mtefar", 163 164 }; 164 165 165 166 #ifdef CONFIG_COMPAT
+105 -172
arch/arm64/kernel/debug-monitors.c
··· 21 21 #include <asm/cputype.h> 22 22 #include <asm/daifflags.h> 23 23 #include <asm/debug-monitors.h> 24 + #include <asm/exception.h> 25 + #include <asm/kgdb.h> 26 + #include <asm/kprobes.h> 24 27 #include <asm/system_misc.h> 25 28 #include <asm/traps.h> 29 + #include <asm/uprobes.h> 26 30 27 31 /* Determine debug architecture. */ 28 32 u8 debug_monitors_arch(void) ··· 38 34 /* 39 35 * MDSCR access routines. 40 36 */ 41 - static void mdscr_write(u32 mdscr) 37 + static void mdscr_write(u64 mdscr) 42 38 { 43 39 unsigned long flags; 44 40 flags = local_daif_save(); ··· 47 43 } 48 44 NOKPROBE_SYMBOL(mdscr_write); 49 45 50 - static u32 mdscr_read(void) 46 + static u64 mdscr_read(void) 51 47 { 52 48 return read_sysreg(mdscr_el1); 53 49 } ··· 83 79 84 80 void enable_debug_monitors(enum dbg_active_el el) 85 81 { 86 - u32 mdscr, enable = 0; 82 + u64 mdscr, enable = 0; 87 83 88 84 WARN_ON(preemptible()); 89 85 90 86 if (this_cpu_inc_return(mde_ref_count) == 1) 91 - enable = DBG_MDSCR_MDE; 87 + enable = MDSCR_EL1_MDE; 92 88 93 89 if (el == DBG_ACTIVE_EL1 && 94 90 this_cpu_inc_return(kde_ref_count) == 1) 95 - enable |= DBG_MDSCR_KDE; 91 + enable |= MDSCR_EL1_KDE; 96 92 97 93 if (enable && debug_enabled) { 98 94 mdscr = mdscr_read(); ··· 104 100 105 101 void disable_debug_monitors(enum dbg_active_el el) 106 102 { 107 - u32 mdscr, disable = 0; 103 + u64 mdscr, disable = 0; 108 104 109 105 WARN_ON(preemptible()); 110 106 111 107 if (this_cpu_dec_return(mde_ref_count) == 0) 112 - disable = ~DBG_MDSCR_MDE; 108 + disable = ~MDSCR_EL1_MDE; 113 109 114 110 if (el == DBG_ACTIVE_EL1 && 115 111 this_cpu_dec_return(kde_ref_count) == 0) 116 - disable &= ~DBG_MDSCR_KDE; 112 + disable &= ~MDSCR_EL1_KDE; 117 113 118 114 if (disable) { 119 115 mdscr = mdscr_read(); ··· 160 156 #define set_regs_spsr_ss(r) set_user_regs_spsr_ss(&(r)->user_regs) 161 157 #define clear_regs_spsr_ss(r) clear_user_regs_spsr_ss(&(r)->user_regs) 162 158 163 - static DEFINE_SPINLOCK(debug_hook_lock); 164 - static LIST_HEAD(user_step_hook); 165 - static LIST_HEAD(kernel_step_hook); 166 - 167 - static void register_debug_hook(struct list_head *node, struct list_head *list) 168 - { 169 - spin_lock(&debug_hook_lock); 170 - list_add_rcu(node, list); 171 - spin_unlock(&debug_hook_lock); 172 - 173 - } 174 - 175 - static void unregister_debug_hook(struct list_head *node) 176 - { 177 - spin_lock(&debug_hook_lock); 178 - list_del_rcu(node); 179 - spin_unlock(&debug_hook_lock); 180 - synchronize_rcu(); 181 - } 182 - 183 - void register_user_step_hook(struct step_hook *hook) 184 - { 185 - register_debug_hook(&hook->node, &user_step_hook); 186 - } 187 - 188 - void unregister_user_step_hook(struct step_hook *hook) 189 - { 190 - unregister_debug_hook(&hook->node); 191 - } 192 - 193 - void register_kernel_step_hook(struct step_hook *hook) 194 - { 195 - register_debug_hook(&hook->node, &kernel_step_hook); 196 - } 197 - 198 - void unregister_kernel_step_hook(struct step_hook *hook) 199 - { 200 - unregister_debug_hook(&hook->node); 201 - } 202 - 203 - /* 204 - * Call registered single step handlers 205 - * There is no Syndrome info to check for determining the handler. 206 - * So we call all the registered handlers, until the right handler is 207 - * found which returns zero. 208 - */ 209 - static int call_step_hook(struct pt_regs *regs, unsigned long esr) 210 - { 211 - struct step_hook *hook; 212 - struct list_head *list; 213 - int retval = DBG_HOOK_ERROR; 214 - 215 - list = user_mode(regs) ? &user_step_hook : &kernel_step_hook; 216 - 217 - /* 218 - * Since single-step exception disables interrupt, this function is 219 - * entirely not preemptible, and we can use rcu list safely here. 220 - */ 221 - list_for_each_entry_rcu(hook, list, node) { 222 - retval = hook->fn(regs, esr); 223 - if (retval == DBG_HOOK_HANDLED) 224 - break; 225 - } 226 - 227 - return retval; 228 - } 229 - NOKPROBE_SYMBOL(call_step_hook); 230 - 231 159 static void send_user_sigtrap(int si_code) 232 160 { 233 161 struct pt_regs *regs = current_pt_regs(); ··· 174 238 "User debug trap"); 175 239 } 176 240 177 - static int single_step_handler(unsigned long unused, unsigned long esr, 178 - struct pt_regs *regs) 241 + /* 242 + * We have already unmasked interrupts and enabled preemption 243 + * when calling do_el0_softstep() from entry-common.c. 244 + */ 245 + void do_el0_softstep(unsigned long esr, struct pt_regs *regs) 179 246 { 180 - bool handler_found = false; 247 + if (uprobe_single_step_handler(regs, esr) == DBG_HOOK_HANDLED) 248 + return; 181 249 250 + send_user_sigtrap(TRAP_TRACE); 182 251 /* 183 - * If we are stepping a pending breakpoint, call the hw_breakpoint 184 - * handler first. 252 + * ptrace will disable single step unless explicitly 253 + * asked to re-enable it. For other clients, it makes 254 + * sense to leave it enabled (i.e. rewind the controls 255 + * to the active-not-pending state). 185 256 */ 186 - if (!reinstall_suspended_bps(regs)) 187 - return 0; 257 + user_rewind_single_step(current); 258 + } 188 259 189 - if (!handler_found && call_step_hook(regs, esr) == DBG_HOOK_HANDLED) 190 - handler_found = true; 260 + void do_el1_softstep(unsigned long esr, struct pt_regs *regs) 261 + { 262 + if (kgdb_single_step_handler(regs, esr) == DBG_HOOK_HANDLED) 263 + return; 191 264 192 - if (!handler_found && user_mode(regs)) { 193 - send_user_sigtrap(TRAP_TRACE); 265 + pr_warn("Unexpected kernel single-step exception at EL1\n"); 266 + /* 267 + * Re-enable stepping since we know that we will be 268 + * returning to regs. 269 + */ 270 + set_regs_spsr_ss(regs); 271 + } 272 + NOKPROBE_SYMBOL(do_el1_softstep); 194 273 195 - /* 196 - * ptrace will disable single step unless explicitly 197 - * asked to re-enable it. For other clients, it makes 198 - * sense to leave it enabled (i.e. rewind the controls 199 - * to the active-not-pending state). 200 - */ 201 - user_rewind_single_step(current); 202 - } else if (!handler_found) { 203 - pr_warn("Unexpected kernel single-step exception at EL1\n"); 204 - /* 205 - * Re-enable stepping since we know that we will be 206 - * returning to regs. 207 - */ 208 - set_regs_spsr_ss(regs); 274 + static int call_el1_break_hook(struct pt_regs *regs, unsigned long esr) 275 + { 276 + if (esr_brk_comment(esr) == BUG_BRK_IMM) 277 + return bug_brk_handler(regs, esr); 278 + 279 + if (IS_ENABLED(CONFIG_CFI_CLANG) && esr_is_cfi_brk(esr)) 280 + return cfi_brk_handler(regs, esr); 281 + 282 + if (esr_brk_comment(esr) == FAULT_BRK_IMM) 283 + return reserved_fault_brk_handler(regs, esr); 284 + 285 + if (IS_ENABLED(CONFIG_KASAN_SW_TAGS) && 286 + (esr_brk_comment(esr) & ~KASAN_BRK_MASK) == KASAN_BRK_IMM) 287 + return kasan_brk_handler(regs, esr); 288 + 289 + if (IS_ENABLED(CONFIG_UBSAN_TRAP) && esr_is_ubsan_brk(esr)) 290 + return ubsan_brk_handler(regs, esr); 291 + 292 + if (IS_ENABLED(CONFIG_KGDB)) { 293 + if (esr_brk_comment(esr) == KGDB_DYN_DBG_BRK_IMM) 294 + return kgdb_brk_handler(regs, esr); 295 + if (esr_brk_comment(esr) == KGDB_COMPILED_DBG_BRK_IMM) 296 + return kgdb_compiled_brk_handler(regs, esr); 209 297 } 210 298 211 - return 0; 212 - } 213 - NOKPROBE_SYMBOL(single_step_handler); 214 - 215 - static LIST_HEAD(user_break_hook); 216 - static LIST_HEAD(kernel_break_hook); 217 - 218 - void register_user_break_hook(struct break_hook *hook) 219 - { 220 - register_debug_hook(&hook->node, &user_break_hook); 221 - } 222 - 223 - void unregister_user_break_hook(struct break_hook *hook) 224 - { 225 - unregister_debug_hook(&hook->node); 226 - } 227 - 228 - void register_kernel_break_hook(struct break_hook *hook) 229 - { 230 - register_debug_hook(&hook->node, &kernel_break_hook); 231 - } 232 - 233 - void unregister_kernel_break_hook(struct break_hook *hook) 234 - { 235 - unregister_debug_hook(&hook->node); 236 - } 237 - 238 - static int call_break_hook(struct pt_regs *regs, unsigned long esr) 239 - { 240 - struct break_hook *hook; 241 - struct list_head *list; 242 - 243 - list = user_mode(regs) ? &user_break_hook : &kernel_break_hook; 244 - 245 - /* 246 - * Since brk exception disables interrupt, this function is 247 - * entirely not preemptible, and we can use rcu list safely here. 248 - */ 249 - list_for_each_entry_rcu(hook, list, node) { 250 - if ((esr_brk_comment(esr) & ~hook->mask) == hook->imm) 251 - return hook->fn(regs, esr); 299 + if (IS_ENABLED(CONFIG_KPROBES)) { 300 + if (esr_brk_comment(esr) == KPROBES_BRK_IMM) 301 + return kprobe_brk_handler(regs, esr); 302 + if (esr_brk_comment(esr) == KPROBES_BRK_SS_IMM) 303 + return kprobe_ss_brk_handler(regs, esr); 252 304 } 305 + 306 + if (IS_ENABLED(CONFIG_KRETPROBES) && 307 + esr_brk_comment(esr) == KRETPROBES_BRK_IMM) 308 + return kretprobe_brk_handler(regs, esr); 253 309 254 310 return DBG_HOOK_ERROR; 255 311 } 256 - NOKPROBE_SYMBOL(call_break_hook); 312 + NOKPROBE_SYMBOL(call_el1_break_hook); 257 313 258 - static int brk_handler(unsigned long unused, unsigned long esr, 259 - struct pt_regs *regs) 314 + /* 315 + * We have already unmasked interrupts and enabled preemption 316 + * when calling do_el0_brk64() from entry-common.c. 317 + */ 318 + void do_el0_brk64(unsigned long esr, struct pt_regs *regs) 260 319 { 261 - if (call_break_hook(regs, esr) == DBG_HOOK_HANDLED) 262 - return 0; 320 + if (IS_ENABLED(CONFIG_UPROBES) && 321 + esr_brk_comment(esr) == UPROBES_BRK_IMM && 322 + uprobe_brk_handler(regs, esr) == DBG_HOOK_HANDLED) 323 + return; 263 324 264 - if (user_mode(regs)) { 265 - send_user_sigtrap(TRAP_BRKPT); 266 - } else { 267 - pr_warn("Unexpected kernel BRK exception at EL1\n"); 268 - return -EFAULT; 269 - } 270 - 271 - return 0; 325 + send_user_sigtrap(TRAP_BRKPT); 272 326 } 273 - NOKPROBE_SYMBOL(brk_handler); 274 327 275 - int aarch32_break_handler(struct pt_regs *regs) 328 + void do_el1_brk64(unsigned long esr, struct pt_regs *regs) 329 + { 330 + if (call_el1_break_hook(regs, esr) == DBG_HOOK_HANDLED) 331 + return; 332 + 333 + die("Oops - BRK", regs, esr); 334 + } 335 + NOKPROBE_SYMBOL(do_el1_brk64); 336 + 337 + #ifdef CONFIG_COMPAT 338 + void do_bkpt32(unsigned long esr, struct pt_regs *regs) 339 + { 340 + arm64_notify_die("aarch32 BKPT", regs, SIGTRAP, TRAP_BRKPT, regs->pc, esr); 341 + } 342 + #endif /* CONFIG_COMPAT */ 343 + 344 + bool try_handle_aarch32_break(struct pt_regs *regs) 276 345 { 277 346 u32 arm_instr; 278 347 u16 thumb_instr; ··· 285 344 void __user *pc = (void __user *)instruction_pointer(regs); 286 345 287 346 if (!compat_user_mode(regs)) 288 - return -EFAULT; 347 + return false; 289 348 290 349 if (compat_thumb_mode(regs)) { 291 350 /* get 16-bit Thumb instruction */ ··· 309 368 } 310 369 311 370 if (!bp) 312 - return -EFAULT; 371 + return false; 313 372 314 373 send_user_sigtrap(TRAP_BRKPT); 315 - return 0; 374 + return true; 316 375 } 317 - NOKPROBE_SYMBOL(aarch32_break_handler); 318 - 319 - void __init debug_traps_init(void) 320 - { 321 - hook_debug_fault_code(DBG_ESR_EVT_HWSS, single_step_handler, SIGTRAP, 322 - TRAP_TRACE, "single-step handler"); 323 - hook_debug_fault_code(DBG_ESR_EVT_BRK, brk_handler, SIGTRAP, 324 - TRAP_BRKPT, "BRK handler"); 325 - } 376 + NOKPROBE_SYMBOL(try_handle_aarch32_break); 326 377 327 378 /* Re-enable single step for syscall restarting. */ 328 379 void user_rewind_single_step(struct task_struct *task) ··· 348 415 { 349 416 WARN_ON(!irqs_disabled()); 350 417 set_regs_spsr_ss(regs); 351 - mdscr_write(mdscr_read() | DBG_MDSCR_SS); 418 + mdscr_write(mdscr_read() | MDSCR_EL1_SS); 352 419 enable_debug_monitors(DBG_ACTIVE_EL1); 353 420 } 354 421 NOKPROBE_SYMBOL(kernel_enable_single_step); ··· 356 423 void kernel_disable_single_step(void) 357 424 { 358 425 WARN_ON(!irqs_disabled()); 359 - mdscr_write(mdscr_read() & ~DBG_MDSCR_SS); 426 + mdscr_write(mdscr_read() & ~MDSCR_EL1_SS); 360 427 disable_debug_monitors(DBG_ACTIVE_EL1); 361 428 } 362 429 NOKPROBE_SYMBOL(kernel_disable_single_step); ··· 364 431 int kernel_active_single_step(void) 365 432 { 366 433 WARN_ON(!irqs_disabled()); 367 - return mdscr_read() & DBG_MDSCR_SS; 434 + return mdscr_read() & MDSCR_EL1_SS; 368 435 } 369 436 NOKPROBE_SYMBOL(kernel_active_single_step); 370 437
+3 -3
arch/arm64/kernel/efi.c
··· 15 15 16 16 #include <asm/efi.h> 17 17 #include <asm/stacktrace.h> 18 + #include <asm/vmap_stack.h> 18 19 19 20 static bool region_is_misaligned(const efi_memory_desc_t *md) 20 21 { ··· 215 214 if (!efi_enabled(EFI_RUNTIME_SERVICES)) 216 215 return 0; 217 216 218 - p = __vmalloc_node(THREAD_SIZE, THREAD_ALIGN, GFP_KERNEL, 219 - NUMA_NO_NODE, &&l); 220 - l: if (!p) { 217 + p = arch_alloc_vmap_stack(THREAD_SIZE, NUMA_NO_NODE); 218 + if (!p) { 221 219 pr_warn("Failed to allocate EFI runtime stack\n"); 222 220 clear_bit(EFI_RUNTIME_SERVICES, &efi.flags); 223 221 return -ENOMEM;
+143 -13
arch/arm64/kernel/entry-common.c
··· 8 8 #include <linux/context_tracking.h> 9 9 #include <linux/kasan.h> 10 10 #include <linux/linkage.h> 11 + #include <linux/livepatch.h> 11 12 #include <linux/lockdep.h> 12 13 #include <linux/ptrace.h> 13 14 #include <linux/resume_user_mode.h> ··· 144 143 send_sig_fault(SIGSEGV, SEGV_MTEAERR, 145 144 (void __user *)NULL, current); 146 145 } 146 + 147 + if (thread_flags & _TIF_PATCH_PENDING) 148 + klp_update_patch_state(current); 147 149 148 150 if (thread_flags & (_TIF_SIGPENDING | _TIF_NOTIFY_SIGNAL)) 149 151 do_signal(regs); ··· 348 344 349 345 static void cortex_a76_erratum_1463225_svc_handler(void) 350 346 { 351 - u32 reg, val; 347 + u64 reg, val; 352 348 353 349 if (!unlikely(test_thread_flag(TIF_SINGLESTEP))) 354 350 return; ··· 358 354 359 355 __this_cpu_write(__in_cortex_a76_erratum_1463225_wa, 1); 360 356 reg = read_sysreg(mdscr_el1); 361 - val = reg | DBG_MDSCR_SS | DBG_MDSCR_KDE; 357 + val = reg | MDSCR_EL1_SS | MDSCR_EL1_KDE; 362 358 write_sysreg(val, mdscr_el1); 363 359 asm volatile("msr daifclr, #8"); 364 360 isb(); ··· 445 441 __this_cpu_write(fpsimd_last_state.to_save, FP_STATE_CURRENT); 446 442 } 447 443 444 + /* 445 + * In debug exception context, we explicitly disable preemption despite 446 + * having interrupts disabled. 447 + * This serves two purposes: it makes it much less likely that we would 448 + * accidentally schedule in exception context and it will force a warning 449 + * if we somehow manage to schedule by accident. 450 + */ 451 + static void debug_exception_enter(struct pt_regs *regs) 452 + { 453 + preempt_disable(); 454 + 455 + /* This code is a bit fragile. Test it. */ 456 + RCU_LOCKDEP_WARN(!rcu_is_watching(), "exception_enter didn't work"); 457 + } 458 + NOKPROBE_SYMBOL(debug_exception_enter); 459 + 460 + static void debug_exception_exit(struct pt_regs *regs) 461 + { 462 + preempt_enable_no_resched(); 463 + } 464 + NOKPROBE_SYMBOL(debug_exception_exit); 465 + 448 466 UNHANDLED(el1t, 64, sync) 449 467 UNHANDLED(el1t, 64, irq) 450 468 UNHANDLED(el1t, 64, fiq) ··· 530 504 exit_to_kernel_mode(regs); 531 505 } 532 506 533 - static void noinstr el1_dbg(struct pt_regs *regs, unsigned long esr) 507 + static void noinstr el1_breakpt(struct pt_regs *regs, unsigned long esr) 534 508 { 509 + arm64_enter_el1_dbg(regs); 510 + debug_exception_enter(regs); 511 + do_breakpoint(esr, regs); 512 + debug_exception_exit(regs); 513 + arm64_exit_el1_dbg(regs); 514 + } 515 + 516 + static void noinstr el1_softstp(struct pt_regs *regs, unsigned long esr) 517 + { 518 + arm64_enter_el1_dbg(regs); 519 + if (!cortex_a76_erratum_1463225_debug_handler(regs)) { 520 + debug_exception_enter(regs); 521 + /* 522 + * After handling a breakpoint, we suspend the breakpoint 523 + * and use single-step to move to the next instruction. 524 + * If we are stepping a suspended breakpoint there's nothing more to do: 525 + * the single-step is complete. 526 + */ 527 + if (!try_step_suspended_breakpoints(regs)) 528 + do_el1_softstep(esr, regs); 529 + debug_exception_exit(regs); 530 + } 531 + arm64_exit_el1_dbg(regs); 532 + } 533 + 534 + static void noinstr el1_watchpt(struct pt_regs *regs, unsigned long esr) 535 + { 536 + /* Watchpoints are the only debug exception to write FAR_EL1 */ 535 537 unsigned long far = read_sysreg(far_el1); 536 538 537 539 arm64_enter_el1_dbg(regs); 538 - if (!cortex_a76_erratum_1463225_debug_handler(regs)) 539 - do_debug_exception(far, esr, regs); 540 + debug_exception_enter(regs); 541 + do_watchpoint(far, esr, regs); 542 + debug_exception_exit(regs); 543 + arm64_exit_el1_dbg(regs); 544 + } 545 + 546 + static void noinstr el1_brk64(struct pt_regs *regs, unsigned long esr) 547 + { 548 + arm64_enter_el1_dbg(regs); 549 + debug_exception_enter(regs); 550 + do_el1_brk64(esr, regs); 551 + debug_exception_exit(regs); 540 552 arm64_exit_el1_dbg(regs); 541 553 } 542 554 ··· 617 553 el1_mops(regs, esr); 618 554 break; 619 555 case ESR_ELx_EC_BREAKPT_CUR: 556 + el1_breakpt(regs, esr); 557 + break; 620 558 case ESR_ELx_EC_SOFTSTP_CUR: 559 + el1_softstp(regs, esr); 560 + break; 621 561 case ESR_ELx_EC_WATCHPT_CUR: 562 + el1_watchpt(regs, esr); 563 + break; 622 564 case ESR_ELx_EC_BRK64: 623 - el1_dbg(regs, esr); 565 + el1_brk64(regs, esr); 624 566 break; 625 567 case ESR_ELx_EC_FPAC: 626 568 el1_fpac(regs, esr); ··· 817 747 exit_to_user_mode(regs); 818 748 } 819 749 820 - static void noinstr el0_dbg(struct pt_regs *regs, unsigned long esr) 750 + static void noinstr el0_breakpt(struct pt_regs *regs, unsigned long esr) 821 751 { 822 - /* Only watchpoints write FAR_EL1, otherwise its UNKNOWN */ 752 + if (!is_ttbr0_addr(regs->pc)) 753 + arm64_apply_bp_hardening(); 754 + 755 + enter_from_user_mode(regs); 756 + debug_exception_enter(regs); 757 + do_breakpoint(esr, regs); 758 + debug_exception_exit(regs); 759 + local_daif_restore(DAIF_PROCCTX); 760 + exit_to_user_mode(regs); 761 + } 762 + 763 + static void noinstr el0_softstp(struct pt_regs *regs, unsigned long esr) 764 + { 765 + if (!is_ttbr0_addr(regs->pc)) 766 + arm64_apply_bp_hardening(); 767 + 768 + enter_from_user_mode(regs); 769 + /* 770 + * After handling a breakpoint, we suspend the breakpoint 771 + * and use single-step to move to the next instruction. 772 + * If we are stepping a suspended breakpoint there's nothing more to do: 773 + * the single-step is complete. 774 + */ 775 + if (!try_step_suspended_breakpoints(regs)) { 776 + local_daif_restore(DAIF_PROCCTX); 777 + do_el0_softstep(esr, regs); 778 + } 779 + exit_to_user_mode(regs); 780 + } 781 + 782 + static void noinstr el0_watchpt(struct pt_regs *regs, unsigned long esr) 783 + { 784 + /* Watchpoints are the only debug exception to write FAR_EL1 */ 823 785 unsigned long far = read_sysreg(far_el1); 824 786 825 787 enter_from_user_mode(regs); 826 - do_debug_exception(far, esr, regs); 788 + debug_exception_enter(regs); 789 + do_watchpoint(far, esr, regs); 790 + debug_exception_exit(regs); 827 791 local_daif_restore(DAIF_PROCCTX); 792 + exit_to_user_mode(regs); 793 + } 794 + 795 + static void noinstr el0_brk64(struct pt_regs *regs, unsigned long esr) 796 + { 797 + enter_from_user_mode(regs); 798 + local_daif_restore(DAIF_PROCCTX); 799 + do_el0_brk64(esr, regs); 828 800 exit_to_user_mode(regs); 829 801 } 830 802 ··· 938 826 el0_gcs(regs, esr); 939 827 break; 940 828 case ESR_ELx_EC_BREAKPT_LOW: 829 + el0_breakpt(regs, esr); 830 + break; 941 831 case ESR_ELx_EC_SOFTSTP_LOW: 832 + el0_softstp(regs, esr); 833 + break; 942 834 case ESR_ELx_EC_WATCHPT_LOW: 835 + el0_watchpt(regs, esr); 836 + break; 943 837 case ESR_ELx_EC_BRK64: 944 - el0_dbg(regs, esr); 838 + el0_brk64(regs, esr); 945 839 break; 946 840 case ESR_ELx_EC_FPAC: 947 841 el0_fpac(regs, esr); ··· 1030 912 exit_to_user_mode(regs); 1031 913 } 1032 914 915 + static void noinstr el0_bkpt32(struct pt_regs *regs, unsigned long esr) 916 + { 917 + enter_from_user_mode(regs); 918 + local_daif_restore(DAIF_PROCCTX); 919 + do_bkpt32(esr, regs); 920 + exit_to_user_mode(regs); 921 + } 922 + 1033 923 asmlinkage void noinstr el0t_32_sync_handler(struct pt_regs *regs) 1034 924 { 1035 925 unsigned long esr = read_sysreg(esr_el1); ··· 1072 946 el0_cp15(regs, esr); 1073 947 break; 1074 948 case ESR_ELx_EC_BREAKPT_LOW: 949 + el0_breakpt(regs, esr); 950 + break; 1075 951 case ESR_ELx_EC_SOFTSTP_LOW: 952 + el0_softstp(regs, esr); 953 + break; 1076 954 case ESR_ELx_EC_WATCHPT_LOW: 955 + el0_watchpt(regs, esr); 956 + break; 1077 957 case ESR_ELx_EC_BKPT32: 1078 - el0_dbg(regs, esr); 958 + el0_bkpt32(regs, esr); 1079 959 break; 1080 960 default: 1081 961 el0_inv(regs, esr); ··· 1109 977 UNHANDLED(el0t, 32, error) 1110 978 #endif /* CONFIG_COMPAT */ 1111 979 1112 - #ifdef CONFIG_VMAP_STACK 1113 980 asmlinkage void noinstr __noreturn handle_bad_stack(struct pt_regs *regs) 1114 981 { 1115 982 unsigned long esr = read_sysreg(esr_el1); ··· 1117 986 arm64_enter_nmi(regs); 1118 987 panic_bad_stack(regs, esr, far); 1119 988 } 1120 - #endif /* CONFIG_VMAP_STACK */ 1121 989 1122 990 #ifdef CONFIG_ARM_SDE_INTERFACE 1123 991 asmlinkage noinstr unsigned long
-6
arch/arm64/kernel/entry.S
··· 55 55 .endif 56 56 57 57 sub sp, sp, #PT_REGS_SIZE 58 - #ifdef CONFIG_VMAP_STACK 59 58 /* 60 59 * Test whether the SP has overflowed, without corrupting a GPR. 61 60 * Task and IRQ stacks are aligned so that SP & (1 << THREAD_SHIFT) ··· 96 97 /* We were already on the overflow stack. Restore sp/x0 and carry on. */ 97 98 sub sp, sp, x0 98 99 mrs x0, tpidrro_el0 99 - #endif 100 100 b el\el\ht\()_\regsize\()_\label 101 101 .org .Lventry_start\@ + 128 // Did we overflow the ventry slot? 102 102 .endm ··· 538 540 kernel_ventry 0, t, 32, error // Error 32-bit EL0 539 541 SYM_CODE_END(vectors) 540 542 541 - #ifdef CONFIG_VMAP_STACK 542 543 SYM_CODE_START_LOCAL(__bad_stack) 543 544 /* 544 545 * We detected an overflow in kernel_ventry, which switched to the ··· 565 568 bl handle_bad_stack 566 569 ASM_BUG() 567 570 SYM_CODE_END(__bad_stack) 568 - #endif /* CONFIG_VMAP_STACK */ 569 571 570 572 571 573 .macro entry_handler el:req, ht:req, regsize:req, label:req ··· 999 1003 1: adr_this_cpu dst=x5, sym=sdei_active_critical_event, tmp=x6 1000 1004 2: str x19, [x5] 1001 1005 1002 - #ifdef CONFIG_VMAP_STACK 1003 1006 /* 1004 1007 * entry.S may have been using sp as a scratch register, find whether 1005 1008 * this is a normal or critical event and switch to the appropriate ··· 1011 1016 2: mov x6, #SDEI_STACK_SIZE 1012 1017 add x5, x5, x6 1013 1018 mov sp, x5 1014 - #endif 1015 1019 1016 1020 #ifdef CONFIG_SHADOW_CALL_STACK 1017 1021 /* Use a separate shadow call stack for normal and critical events */
+24 -36
arch/arm64/kernel/hw_breakpoint.c
··· 22 22 #include <asm/current.h> 23 23 #include <asm/debug-monitors.h> 24 24 #include <asm/esr.h> 25 + #include <asm/exception.h> 25 26 #include <asm/hw_breakpoint.h> 26 27 #include <asm/traps.h> 27 28 #include <asm/cputype.h> ··· 619 618 /* 620 619 * Debug exception handlers. 621 620 */ 622 - static int breakpoint_handler(unsigned long unused, unsigned long esr, 623 - struct pt_regs *regs) 621 + void do_breakpoint(unsigned long esr, struct pt_regs *regs) 624 622 { 625 623 int i, step = 0, *kernel_step; 626 624 u32 ctrl_reg; ··· 662 662 } 663 663 664 664 if (!step) 665 - return 0; 665 + return; 666 666 667 667 if (user_mode(regs)) { 668 668 debug_info->bps_disabled = 1; ··· 670 670 671 671 /* If we're already stepping a watchpoint, just return. */ 672 672 if (debug_info->wps_disabled) 673 - return 0; 673 + return; 674 674 675 675 if (test_thread_flag(TIF_SINGLESTEP)) 676 676 debug_info->suspended_step = 1; ··· 681 681 kernel_step = this_cpu_ptr(&stepping_kernel_bp); 682 682 683 683 if (*kernel_step != ARM_KERNEL_STEP_NONE) 684 - return 0; 684 + return; 685 685 686 686 if (kernel_active_single_step()) { 687 687 *kernel_step = ARM_KERNEL_STEP_SUSPEND; ··· 690 690 kernel_enable_single_step(regs); 691 691 } 692 692 } 693 - 694 - return 0; 695 693 } 696 - NOKPROBE_SYMBOL(breakpoint_handler); 694 + NOKPROBE_SYMBOL(do_breakpoint); 697 695 698 696 /* 699 697 * Arm64 hardware does not always report a watchpoint hit address that matches ··· 750 752 return step; 751 753 } 752 754 753 - static int watchpoint_handler(unsigned long addr, unsigned long esr, 754 - struct pt_regs *regs) 755 + void do_watchpoint(unsigned long addr, unsigned long esr, struct pt_regs *regs) 755 756 { 756 757 int i, step = 0, *kernel_step, access, closest_match = 0; 757 758 u64 min_dist = -1, dist; ··· 805 808 rcu_read_unlock(); 806 809 807 810 if (!step) 808 - return 0; 811 + return; 809 812 810 813 /* 811 814 * We always disable EL0 watchpoints because the kernel can ··· 818 821 819 822 /* If we're already stepping a breakpoint, just return. */ 820 823 if (debug_info->bps_disabled) 821 - return 0; 824 + return; 822 825 823 826 if (test_thread_flag(TIF_SINGLESTEP)) 824 827 debug_info->suspended_step = 1; ··· 829 832 kernel_step = this_cpu_ptr(&stepping_kernel_bp); 830 833 831 834 if (*kernel_step != ARM_KERNEL_STEP_NONE) 832 - return 0; 835 + return; 833 836 834 837 if (kernel_active_single_step()) { 835 838 *kernel_step = ARM_KERNEL_STEP_SUSPEND; ··· 838 841 kernel_enable_single_step(regs); 839 842 } 840 843 } 841 - 842 - return 0; 843 844 } 844 - NOKPROBE_SYMBOL(watchpoint_handler); 845 + NOKPROBE_SYMBOL(do_watchpoint); 845 846 846 847 /* 847 848 * Handle single-step exception. 848 849 */ 849 - int reinstall_suspended_bps(struct pt_regs *regs) 850 + bool try_step_suspended_breakpoints(struct pt_regs *regs) 850 851 { 851 852 struct debug_info *debug_info = &current->thread.debug; 852 - int handled_exception = 0, *kernel_step; 853 - 854 - kernel_step = this_cpu_ptr(&stepping_kernel_bp); 853 + int *kernel_step = this_cpu_ptr(&stepping_kernel_bp); 854 + bool handled_exception = false; 855 855 856 856 /* 857 - * Called from single-step exception handler. 858 - * Return 0 if execution can resume, 1 if a SIGTRAP should be 859 - * reported. 857 + * Called from single-step exception entry. 858 + * Return true if we stepped a breakpoint and can resume execution, 859 + * false if we need to handle a single-step. 860 860 */ 861 861 if (user_mode(regs)) { 862 862 if (debug_info->bps_disabled) { 863 863 debug_info->bps_disabled = 0; 864 864 toggle_bp_registers(AARCH64_DBG_REG_BCR, DBG_ACTIVE_EL0, 1); 865 - handled_exception = 1; 865 + handled_exception = true; 866 866 } 867 867 868 868 if (debug_info->wps_disabled) { 869 869 debug_info->wps_disabled = 0; 870 870 toggle_bp_registers(AARCH64_DBG_REG_WCR, DBG_ACTIVE_EL0, 1); 871 - handled_exception = 1; 871 + handled_exception = true; 872 872 } 873 873 874 874 if (handled_exception) { 875 875 if (debug_info->suspended_step) { 876 876 debug_info->suspended_step = 0; 877 877 /* Allow exception handling to fall-through. */ 878 - handled_exception = 0; 878 + handled_exception = false; 879 879 } else { 880 880 user_disable_single_step(current); 881 881 } ··· 886 892 887 893 if (*kernel_step != ARM_KERNEL_STEP_SUSPEND) { 888 894 kernel_disable_single_step(); 889 - handled_exception = 1; 895 + handled_exception = true; 890 896 } else { 891 - handled_exception = 0; 897 + handled_exception = false; 892 898 } 893 899 894 900 *kernel_step = ARM_KERNEL_STEP_NONE; 895 901 } 896 902 897 - return !handled_exception; 903 + return handled_exception; 898 904 } 899 - NOKPROBE_SYMBOL(reinstall_suspended_bps); 905 + NOKPROBE_SYMBOL(try_step_suspended_breakpoints); 900 906 901 907 /* 902 908 * Context-switcher for restoring suspended breakpoints. ··· 980 986 981 987 pr_info("found %d breakpoint and %d watchpoint registers.\n", 982 988 core_num_brps, core_num_wrps); 983 - 984 - /* Register debug fault handlers. */ 985 - hook_debug_fault_code(DBG_ESR_EVT_HWBP, breakpoint_handler, SIGTRAP, 986 - TRAP_HWBKPT, "hw-breakpoint handler"); 987 - hook_debug_fault_code(DBG_ESR_EVT_HWWP, watchpoint_handler, SIGTRAP, 988 - TRAP_HWBKPT, "hw-watchpoint handler"); 989 989 990 990 /* 991 991 * Reset the breakpoint resources. We assume that a halting
-13
arch/arm64/kernel/irq.c
··· 51 51 scs_alloc(early_cpu_to_node(cpu)); 52 52 } 53 53 54 - #ifdef CONFIG_VMAP_STACK 55 54 static void __init init_irq_stacks(void) 56 55 { 57 56 int cpu; ··· 61 62 per_cpu(irq_stack_ptr, cpu) = p; 62 63 } 63 64 } 64 - #else 65 - /* irq stack only needs to be 16 byte aligned - not IRQ_STACK_SIZE aligned. */ 66 - DEFINE_PER_CPU_ALIGNED(unsigned long [IRQ_STACK_SIZE/sizeof(long)], irq_stack); 67 - 68 - static void init_irq_stacks(void) 69 - { 70 - int cpu; 71 - 72 - for_each_possible_cpu(cpu) 73 - per_cpu(irq_stack_ptr, cpu) = per_cpu(irq_stack, cpu); 74 - } 75 - #endif 76 65 77 66 #ifndef CONFIG_PREEMPT_RT 78 67 static void ____do_softirq(struct pt_regs *regs)
+7 -32
arch/arm64/kernel/kgdb.c
··· 234 234 return err; 235 235 } 236 236 237 - static int kgdb_brk_fn(struct pt_regs *regs, unsigned long esr) 237 + int kgdb_brk_handler(struct pt_regs *regs, unsigned long esr) 238 238 { 239 239 kgdb_handle_exception(1, SIGTRAP, 0, regs); 240 240 return DBG_HOOK_HANDLED; 241 241 } 242 - NOKPROBE_SYMBOL(kgdb_brk_fn) 242 + NOKPROBE_SYMBOL(kgdb_brk_handler) 243 243 244 - static int kgdb_compiled_brk_fn(struct pt_regs *regs, unsigned long esr) 244 + int kgdb_compiled_brk_handler(struct pt_regs *regs, unsigned long esr) 245 245 { 246 246 compiled_break = 1; 247 247 kgdb_handle_exception(1, SIGTRAP, 0, regs); 248 248 249 249 return DBG_HOOK_HANDLED; 250 250 } 251 - NOKPROBE_SYMBOL(kgdb_compiled_brk_fn); 251 + NOKPROBE_SYMBOL(kgdb_compiled_brk_handler); 252 252 253 - static int kgdb_step_brk_fn(struct pt_regs *regs, unsigned long esr) 253 + int kgdb_single_step_handler(struct pt_regs *regs, unsigned long esr) 254 254 { 255 255 if (!kgdb_single_step) 256 256 return DBG_HOOK_ERROR; ··· 258 258 kgdb_handle_exception(0, SIGTRAP, 0, regs); 259 259 return DBG_HOOK_HANDLED; 260 260 } 261 - NOKPROBE_SYMBOL(kgdb_step_brk_fn); 262 - 263 - static struct break_hook kgdb_brkpt_hook = { 264 - .fn = kgdb_brk_fn, 265 - .imm = KGDB_DYN_DBG_BRK_IMM, 266 - }; 267 - 268 - static struct break_hook kgdb_compiled_brkpt_hook = { 269 - .fn = kgdb_compiled_brk_fn, 270 - .imm = KGDB_COMPILED_DBG_BRK_IMM, 271 - }; 272 - 273 - static struct step_hook kgdb_step_hook = { 274 - .fn = kgdb_step_brk_fn 275 - }; 261 + NOKPROBE_SYMBOL(kgdb_single_step_handler); 276 262 277 263 static int __kgdb_notify(struct die_args *args, unsigned long cmd) 278 264 { ··· 297 311 */ 298 312 int kgdb_arch_init(void) 299 313 { 300 - int ret = register_die_notifier(&kgdb_notifier); 301 - 302 - if (ret != 0) 303 - return ret; 304 - 305 - register_kernel_break_hook(&kgdb_brkpt_hook); 306 - register_kernel_break_hook(&kgdb_compiled_brkpt_hook); 307 - register_kernel_step_hook(&kgdb_step_hook); 308 - return 0; 314 + return register_die_notifier(&kgdb_notifier); 309 315 } 310 316 311 317 /* ··· 307 329 */ 308 330 void kgdb_arch_exit(void) 309 331 { 310 - unregister_kernel_break_hook(&kgdb_brkpt_hook); 311 - unregister_kernel_break_hook(&kgdb_compiled_brkpt_hook); 312 - unregister_kernel_step_hook(&kgdb_step_hook); 313 332 unregister_die_notifier(&kgdb_notifier); 314 333 } 315 334
+57 -44
arch/arm64/kernel/module.c
··· 23 23 #include <asm/insn.h> 24 24 #include <asm/scs.h> 25 25 #include <asm/sections.h> 26 + #include <asm/text-patching.h> 26 27 27 28 enum aarch64_reloc_op { 28 29 RELOC_OP_NONE, ··· 49 48 return 0; 50 49 } 51 50 52 - static int reloc_data(enum aarch64_reloc_op op, void *place, u64 val, int len) 51 + #define WRITE_PLACE(place, val, mod) do { \ 52 + __typeof__(val) __val = (val); \ 53 + \ 54 + if (mod->state == MODULE_STATE_UNFORMED) \ 55 + *(place) = __val; \ 56 + else \ 57 + aarch64_insn_copy(place, &(__val), sizeof(*place)); \ 58 + } while (0) 59 + 60 + static int reloc_data(enum aarch64_reloc_op op, void *place, u64 val, int len, 61 + struct module *me) 53 62 { 54 63 s64 sval = do_reloc(op, place, val); 55 64 ··· 77 66 78 67 switch (len) { 79 68 case 16: 80 - *(s16 *)place = sval; 69 + WRITE_PLACE((s16 *)place, sval, me); 81 70 switch (op) { 82 71 case RELOC_OP_ABS: 83 72 if (sval < 0 || sval > U16_MAX) ··· 93 82 } 94 83 break; 95 84 case 32: 96 - *(s32 *)place = sval; 85 + WRITE_PLACE((s32 *)place, sval, me); 97 86 switch (op) { 98 87 case RELOC_OP_ABS: 99 88 if (sval < 0 || sval > U32_MAX) ··· 109 98 } 110 99 break; 111 100 case 64: 112 - *(s64 *)place = sval; 101 + WRITE_PLACE((s64 *)place, sval, me); 113 102 break; 114 103 default: 115 104 pr_err("Invalid length (%d) for data relocation\n", len); ··· 124 113 }; 125 114 126 115 static int reloc_insn_movw(enum aarch64_reloc_op op, __le32 *place, u64 val, 127 - int lsb, enum aarch64_insn_movw_imm_type imm_type) 116 + int lsb, enum aarch64_insn_movw_imm_type imm_type, 117 + struct module *me) 128 118 { 129 119 u64 imm; 130 120 s64 sval; ··· 157 145 158 146 /* Update the instruction with the new encoding. */ 159 147 insn = aarch64_insn_encode_immediate(AARCH64_INSN_IMM_16, insn, imm); 160 - *place = cpu_to_le32(insn); 148 + WRITE_PLACE(place, cpu_to_le32(insn), me); 161 149 162 150 if (imm > U16_MAX) 163 151 return -ERANGE; ··· 166 154 } 167 155 168 156 static int reloc_insn_imm(enum aarch64_reloc_op op, __le32 *place, u64 val, 169 - int lsb, int len, enum aarch64_insn_imm_type imm_type) 157 + int lsb, int len, enum aarch64_insn_imm_type imm_type, 158 + struct module *me) 170 159 { 171 160 u64 imm, imm_mask; 172 161 s64 sval; ··· 183 170 184 171 /* Update the instruction's immediate field. */ 185 172 insn = aarch64_insn_encode_immediate(imm_type, insn, imm); 186 - *place = cpu_to_le32(insn); 173 + WRITE_PLACE(place, cpu_to_le32(insn), me); 187 174 188 175 /* 189 176 * Extract the upper value bits (including the sign bit) and ··· 202 189 } 203 190 204 191 static int reloc_insn_adrp(struct module *mod, Elf64_Shdr *sechdrs, 205 - __le32 *place, u64 val) 192 + __le32 *place, u64 val, struct module *me) 206 193 { 207 194 u32 insn; 208 195 209 196 if (!is_forbidden_offset_for_adrp(place)) 210 197 return reloc_insn_imm(RELOC_OP_PAGE, place, val, 12, 21, 211 - AARCH64_INSN_IMM_ADR); 198 + AARCH64_INSN_IMM_ADR, me); 212 199 213 200 /* patch ADRP to ADR if it is in range */ 214 201 if (!reloc_insn_imm(RELOC_OP_PREL, place, val & ~0xfff, 0, 21, 215 - AARCH64_INSN_IMM_ADR)) { 202 + AARCH64_INSN_IMM_ADR, me)) { 216 203 insn = le32_to_cpu(*place); 217 204 insn &= ~BIT(31); 218 205 } else { ··· 224 211 AARCH64_INSN_BRANCH_NOLINK); 225 212 } 226 213 227 - *place = cpu_to_le32(insn); 214 + WRITE_PLACE(place, cpu_to_le32(insn), me); 228 215 return 0; 229 216 } 230 217 ··· 268 255 /* Data relocations. */ 269 256 case R_AARCH64_ABS64: 270 257 overflow_check = false; 271 - ovf = reloc_data(RELOC_OP_ABS, loc, val, 64); 258 + ovf = reloc_data(RELOC_OP_ABS, loc, val, 64, me); 272 259 break; 273 260 case R_AARCH64_ABS32: 274 - ovf = reloc_data(RELOC_OP_ABS, loc, val, 32); 261 + ovf = reloc_data(RELOC_OP_ABS, loc, val, 32, me); 275 262 break; 276 263 case R_AARCH64_ABS16: 277 - ovf = reloc_data(RELOC_OP_ABS, loc, val, 16); 264 + ovf = reloc_data(RELOC_OP_ABS, loc, val, 16, me); 278 265 break; 279 266 case R_AARCH64_PREL64: 280 267 overflow_check = false; 281 - ovf = reloc_data(RELOC_OP_PREL, loc, val, 64); 268 + ovf = reloc_data(RELOC_OP_PREL, loc, val, 64, me); 282 269 break; 283 270 case R_AARCH64_PREL32: 284 - ovf = reloc_data(RELOC_OP_PREL, loc, val, 32); 271 + ovf = reloc_data(RELOC_OP_PREL, loc, val, 32, me); 285 272 break; 286 273 case R_AARCH64_PREL16: 287 - ovf = reloc_data(RELOC_OP_PREL, loc, val, 16); 274 + ovf = reloc_data(RELOC_OP_PREL, loc, val, 16, me); 288 275 break; 289 276 290 277 /* MOVW instruction relocations. */ ··· 293 280 fallthrough; 294 281 case R_AARCH64_MOVW_UABS_G0: 295 282 ovf = reloc_insn_movw(RELOC_OP_ABS, loc, val, 0, 296 - AARCH64_INSN_IMM_MOVKZ); 283 + AARCH64_INSN_IMM_MOVKZ, me); 297 284 break; 298 285 case R_AARCH64_MOVW_UABS_G1_NC: 299 286 overflow_check = false; 300 287 fallthrough; 301 288 case R_AARCH64_MOVW_UABS_G1: 302 289 ovf = reloc_insn_movw(RELOC_OP_ABS, loc, val, 16, 303 - AARCH64_INSN_IMM_MOVKZ); 290 + AARCH64_INSN_IMM_MOVKZ, me); 304 291 break; 305 292 case R_AARCH64_MOVW_UABS_G2_NC: 306 293 overflow_check = false; 307 294 fallthrough; 308 295 case R_AARCH64_MOVW_UABS_G2: 309 296 ovf = reloc_insn_movw(RELOC_OP_ABS, loc, val, 32, 310 - AARCH64_INSN_IMM_MOVKZ); 297 + AARCH64_INSN_IMM_MOVKZ, me); 311 298 break; 312 299 case R_AARCH64_MOVW_UABS_G3: 313 300 /* We're using the top bits so we can't overflow. */ 314 301 overflow_check = false; 315 302 ovf = reloc_insn_movw(RELOC_OP_ABS, loc, val, 48, 316 - AARCH64_INSN_IMM_MOVKZ); 303 + AARCH64_INSN_IMM_MOVKZ, me); 317 304 break; 318 305 case R_AARCH64_MOVW_SABS_G0: 319 306 ovf = reloc_insn_movw(RELOC_OP_ABS, loc, val, 0, 320 - AARCH64_INSN_IMM_MOVNZ); 307 + AARCH64_INSN_IMM_MOVNZ, me); 321 308 break; 322 309 case R_AARCH64_MOVW_SABS_G1: 323 310 ovf = reloc_insn_movw(RELOC_OP_ABS, loc, val, 16, 324 - AARCH64_INSN_IMM_MOVNZ); 311 + AARCH64_INSN_IMM_MOVNZ, me); 325 312 break; 326 313 case R_AARCH64_MOVW_SABS_G2: 327 314 ovf = reloc_insn_movw(RELOC_OP_ABS, loc, val, 32, 328 - AARCH64_INSN_IMM_MOVNZ); 315 + AARCH64_INSN_IMM_MOVNZ, me); 329 316 break; 330 317 case R_AARCH64_MOVW_PREL_G0_NC: 331 318 overflow_check = false; 332 319 ovf = reloc_insn_movw(RELOC_OP_PREL, loc, val, 0, 333 - AARCH64_INSN_IMM_MOVKZ); 320 + AARCH64_INSN_IMM_MOVKZ, me); 334 321 break; 335 322 case R_AARCH64_MOVW_PREL_G0: 336 323 ovf = reloc_insn_movw(RELOC_OP_PREL, loc, val, 0, 337 - AARCH64_INSN_IMM_MOVNZ); 324 + AARCH64_INSN_IMM_MOVNZ, me); 338 325 break; 339 326 case R_AARCH64_MOVW_PREL_G1_NC: 340 327 overflow_check = false; 341 328 ovf = reloc_insn_movw(RELOC_OP_PREL, loc, val, 16, 342 - AARCH64_INSN_IMM_MOVKZ); 329 + AARCH64_INSN_IMM_MOVKZ, me); 343 330 break; 344 331 case R_AARCH64_MOVW_PREL_G1: 345 332 ovf = reloc_insn_movw(RELOC_OP_PREL, loc, val, 16, 346 - AARCH64_INSN_IMM_MOVNZ); 333 + AARCH64_INSN_IMM_MOVNZ, me); 347 334 break; 348 335 case R_AARCH64_MOVW_PREL_G2_NC: 349 336 overflow_check = false; 350 337 ovf = reloc_insn_movw(RELOC_OP_PREL, loc, val, 32, 351 - AARCH64_INSN_IMM_MOVKZ); 338 + AARCH64_INSN_IMM_MOVKZ, me); 352 339 break; 353 340 case R_AARCH64_MOVW_PREL_G2: 354 341 ovf = reloc_insn_movw(RELOC_OP_PREL, loc, val, 32, 355 - AARCH64_INSN_IMM_MOVNZ); 342 + AARCH64_INSN_IMM_MOVNZ, me); 356 343 break; 357 344 case R_AARCH64_MOVW_PREL_G3: 358 345 /* We're using the top bits so we can't overflow. */ 359 346 overflow_check = false; 360 347 ovf = reloc_insn_movw(RELOC_OP_PREL, loc, val, 48, 361 - AARCH64_INSN_IMM_MOVNZ); 348 + AARCH64_INSN_IMM_MOVNZ, me); 362 349 break; 363 350 364 351 /* Immediate instruction relocations. */ 365 352 case R_AARCH64_LD_PREL_LO19: 366 353 ovf = reloc_insn_imm(RELOC_OP_PREL, loc, val, 2, 19, 367 - AARCH64_INSN_IMM_19); 354 + AARCH64_INSN_IMM_19, me); 368 355 break; 369 356 case R_AARCH64_ADR_PREL_LO21: 370 357 ovf = reloc_insn_imm(RELOC_OP_PREL, loc, val, 0, 21, 371 - AARCH64_INSN_IMM_ADR); 358 + AARCH64_INSN_IMM_ADR, me); 372 359 break; 373 360 case R_AARCH64_ADR_PREL_PG_HI21_NC: 374 361 overflow_check = false; 375 362 fallthrough; 376 363 case R_AARCH64_ADR_PREL_PG_HI21: 377 - ovf = reloc_insn_adrp(me, sechdrs, loc, val); 364 + ovf = reloc_insn_adrp(me, sechdrs, loc, val, me); 378 365 if (ovf && ovf != -ERANGE) 379 366 return ovf; 380 367 break; ··· 382 369 case R_AARCH64_LDST8_ABS_LO12_NC: 383 370 overflow_check = false; 384 371 ovf = reloc_insn_imm(RELOC_OP_ABS, loc, val, 0, 12, 385 - AARCH64_INSN_IMM_12); 372 + AARCH64_INSN_IMM_12, me); 386 373 break; 387 374 case R_AARCH64_LDST16_ABS_LO12_NC: 388 375 overflow_check = false; 389 376 ovf = reloc_insn_imm(RELOC_OP_ABS, loc, val, 1, 11, 390 - AARCH64_INSN_IMM_12); 377 + AARCH64_INSN_IMM_12, me); 391 378 break; 392 379 case R_AARCH64_LDST32_ABS_LO12_NC: 393 380 overflow_check = false; 394 381 ovf = reloc_insn_imm(RELOC_OP_ABS, loc, val, 2, 10, 395 - AARCH64_INSN_IMM_12); 382 + AARCH64_INSN_IMM_12, me); 396 383 break; 397 384 case R_AARCH64_LDST64_ABS_LO12_NC: 398 385 overflow_check = false; 399 386 ovf = reloc_insn_imm(RELOC_OP_ABS, loc, val, 3, 9, 400 - AARCH64_INSN_IMM_12); 387 + AARCH64_INSN_IMM_12, me); 401 388 break; 402 389 case R_AARCH64_LDST128_ABS_LO12_NC: 403 390 overflow_check = false; 404 391 ovf = reloc_insn_imm(RELOC_OP_ABS, loc, val, 4, 8, 405 - AARCH64_INSN_IMM_12); 392 + AARCH64_INSN_IMM_12, me); 406 393 break; 407 394 case R_AARCH64_TSTBR14: 408 395 ovf = reloc_insn_imm(RELOC_OP_PREL, loc, val, 2, 14, 409 - AARCH64_INSN_IMM_14); 396 + AARCH64_INSN_IMM_14, me); 410 397 break; 411 398 case R_AARCH64_CONDBR19: 412 399 ovf = reloc_insn_imm(RELOC_OP_PREL, loc, val, 2, 19, 413 - AARCH64_INSN_IMM_19); 400 + AARCH64_INSN_IMM_19, me); 414 401 break; 415 402 case R_AARCH64_JUMP26: 416 403 case R_AARCH64_CALL26: 417 404 ovf = reloc_insn_imm(RELOC_OP_PREL, loc, val, 2, 26, 418 - AARCH64_INSN_IMM_26); 405 + AARCH64_INSN_IMM_26, me); 419 406 if (ovf == -ERANGE) { 420 407 val = module_emit_plt_entry(me, sechdrs, loc, &rel[i], sym); 421 408 if (!val) 422 409 return -ENOEXEC; 423 410 ovf = reloc_insn_imm(RELOC_OP_PREL, loc, val, 2, 424 - 26, AARCH64_INSN_IMM_26); 411 + 26, AARCH64_INSN_IMM_26, me); 425 412 } 426 413 break; 427 414
+1 -1
arch/arm64/kernel/pi/Makefile
··· 41 41 obj-$(CONFIG_RELOCATABLE) += relocate.pi.o 42 42 obj-$(CONFIG_RANDOMIZE_BASE) += kaslr_early.pi.o 43 43 obj-$(CONFIG_UNWIND_PATCH_PAC_INTO_SCS) += patch-scs.pi.o 44 - extra-y := $(patsubst %.pi.o,%.o,$(obj-y)) 44 + targets := $(patsubst %.pi.o,%.o,$(obj-y))
+6 -25
arch/arm64/kernel/probes/kprobes.c
··· 292 292 return 0; 293 293 } 294 294 295 - static int __kprobes 296 - kprobe_breakpoint_handler(struct pt_regs *regs, unsigned long esr) 295 + int __kprobes 296 + kprobe_brk_handler(struct pt_regs *regs, unsigned long esr) 297 297 { 298 298 struct kprobe *p, *cur_kprobe; 299 299 struct kprobe_ctlblk *kcb; ··· 336 336 return DBG_HOOK_HANDLED; 337 337 } 338 338 339 - static struct break_hook kprobes_break_hook = { 340 - .imm = KPROBES_BRK_IMM, 341 - .fn = kprobe_breakpoint_handler, 342 - }; 343 - 344 - static int __kprobes 345 - kprobe_breakpoint_ss_handler(struct pt_regs *regs, unsigned long esr) 339 + int __kprobes 340 + kprobe_ss_brk_handler(struct pt_regs *regs, unsigned long esr) 346 341 { 347 342 struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); 348 343 unsigned long addr = instruction_pointer(regs); ··· 355 360 return DBG_HOOK_ERROR; 356 361 } 357 362 358 - static struct break_hook kprobes_break_ss_hook = { 359 - .imm = KPROBES_BRK_SS_IMM, 360 - .fn = kprobe_breakpoint_ss_handler, 361 - }; 362 - 363 - static int __kprobes 364 - kretprobe_breakpoint_handler(struct pt_regs *regs, unsigned long esr) 363 + int __kprobes 364 + kretprobe_brk_handler(struct pt_regs *regs, unsigned long esr) 365 365 { 366 366 if (regs->pc != (unsigned long)__kretprobe_trampoline) 367 367 return DBG_HOOK_ERROR; ··· 364 374 regs->pc = kretprobe_trampoline_handler(regs, (void *)regs->regs[29]); 365 375 return DBG_HOOK_HANDLED; 366 376 } 367 - 368 - static struct break_hook kretprobes_break_hook = { 369 - .imm = KRETPROBES_BRK_IMM, 370 - .fn = kretprobe_breakpoint_handler, 371 - }; 372 377 373 378 /* 374 379 * Provide a blacklist of symbols identifying ranges which cannot be kprobed. ··· 407 422 408 423 int __init arch_init_kprobes(void) 409 424 { 410 - register_kernel_break_hook(&kprobes_break_hook); 411 - register_kernel_break_hook(&kprobes_break_ss_hook); 412 - register_kernel_break_hook(&kretprobes_break_hook); 413 - 414 425 return 0; 415 426 }
+1 -1
arch/arm64/kernel/probes/kprobes_trampoline.S
··· 12 12 SYM_CODE_START(__kretprobe_trampoline) 13 13 /* 14 14 * Trigger a breakpoint exception. The PC will be adjusted by 15 - * kretprobe_breakpoint_handler(), and no subsequent instructions will 15 + * kretprobe_brk_handler(), and no subsequent instructions will 16 16 * be executed from the trampoline. 17 17 */ 18 18 brk #KRETPROBES_BRK_IMM
+2 -22
arch/arm64/kernel/probes/uprobes.c
··· 173 173 return NOTIFY_DONE; 174 174 } 175 175 176 - static int uprobe_breakpoint_handler(struct pt_regs *regs, 176 + int uprobe_brk_handler(struct pt_regs *regs, 177 177 unsigned long esr) 178 178 { 179 179 if (uprobe_pre_sstep_notifier(regs)) ··· 182 182 return DBG_HOOK_ERROR; 183 183 } 184 184 185 - static int uprobe_single_step_handler(struct pt_regs *regs, 185 + int uprobe_single_step_handler(struct pt_regs *regs, 186 186 unsigned long esr) 187 187 { 188 188 struct uprobe_task *utask = current->utask; ··· 194 194 return DBG_HOOK_ERROR; 195 195 } 196 196 197 - /* uprobe breakpoint handler hook */ 198 - static struct break_hook uprobes_break_hook = { 199 - .imm = UPROBES_BRK_IMM, 200 - .fn = uprobe_breakpoint_handler, 201 - }; 202 - 203 - /* uprobe single step handler hook */ 204 - static struct step_hook uprobes_step_hook = { 205 - .fn = uprobe_single_step_handler, 206 - }; 207 - 208 - static int __init arch_init_uprobes(void) 209 - { 210 - register_user_break_hook(&uprobes_break_hook); 211 - register_user_step_hook(&uprobes_step_hook); 212 - 213 - return 0; 214 - } 215 - 216 - device_initcall(arch_init_uprobes);
+6 -5
arch/arm64/kernel/process.c
··· 288 288 if (!system_supports_gcs()) 289 289 return; 290 290 291 - gcs_free(current); 291 + current->thread.gcspr_el0 = 0; 292 + current->thread.gcs_base = 0; 293 + current->thread.gcs_size = 0; 292 294 current->thread.gcs_el0_mode = 0; 293 295 write_sysreg_s(GCSCRE0_EL1_nTR, SYS_GCSCRE0_EL1); 294 296 write_sysreg_s(0, SYS_GCSPR_EL0); ··· 307 305 p->thread.gcs_base = 0; 308 306 p->thread.gcs_size = 0; 309 307 308 + p->thread.gcs_el0_mode = current->thread.gcs_el0_mode; 309 + p->thread.gcs_el0_locked = current->thread.gcs_el0_locked; 310 + 310 311 gcs = gcs_alloc_thread_stack(p, args); 311 312 if (IS_ERR_VALUE(gcs)) 312 313 return PTR_ERR((void *)gcs); 313 - 314 - p->thread.gcs_el0_mode = current->thread.gcs_el0_mode; 315 - p->thread.gcs_el0_locked = current->thread.gcs_el0_locked; 316 314 317 315 return 0; 318 316 } ··· 341 339 void arch_release_task_struct(struct task_struct *tsk) 342 340 { 343 341 fpsimd_release_task(tsk); 344 - gcs_free(tsk); 345 342 } 346 343 347 344 int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src)
+1 -1
arch/arm64/kernel/ptrace.c
··· 141 141 142 142 addr += n; 143 143 if (regs_within_kernel_stack(regs, (unsigned long)addr)) 144 - return *addr; 144 + return READ_ONCE_NOCHECK(*addr); 145 145 else 146 146 return 0; 147 147 }
+2 -6
arch/arm64/kernel/sdei.c
··· 34 34 DECLARE_PER_CPU(unsigned long *, sdei_stack_normal_ptr); 35 35 DECLARE_PER_CPU(unsigned long *, sdei_stack_critical_ptr); 36 36 37 - #ifdef CONFIG_VMAP_STACK 38 37 DEFINE_PER_CPU(unsigned long *, sdei_stack_normal_ptr); 39 38 DEFINE_PER_CPU(unsigned long *, sdei_stack_critical_ptr); 40 - #endif 41 39 42 40 DECLARE_PER_CPU(unsigned long *, sdei_shadow_call_stack_normal_ptr); 43 41 DECLARE_PER_CPU(unsigned long *, sdei_shadow_call_stack_critical_ptr); ··· 63 65 { 64 66 int cpu; 65 67 66 - if (!IS_ENABLED(CONFIG_VMAP_STACK)) 67 - return; 68 + BUILD_BUG_ON(!IS_ENABLED(CONFIG_VMAP_STACK)); 68 69 69 70 for_each_possible_cpu(cpu) { 70 71 _free_sdei_stack(&sdei_stack_normal_ptr, cpu); ··· 88 91 int cpu; 89 92 int err = 0; 90 93 91 - if (!IS_ENABLED(CONFIG_VMAP_STACK)) 92 - return 0; 94 + BUILD_BUG_ON(!IS_ENABLED(CONFIG_VMAP_STACK)); 93 95 94 96 for_each_possible_cpu(cpu) { 95 97 err = _init_sdei_stack(&sdei_stack_normal_ptr, cpu);
+5 -2
arch/arm64/kernel/signal.c
··· 95 95 96 96 ua_state->por_el0 = read_sysreg_s(SYS_POR_EL0); 97 97 write_sysreg_s(por_enable_all, SYS_POR_EL0); 98 - /* Ensure that any subsequent uaccess observes the updated value */ 99 - isb(); 98 + /* 99 + * No ISB required as we can tolerate spurious Overlay faults - 100 + * the fault handler will check again based on the new value 101 + * of POR_EL0. 102 + */ 100 103 } 101 104 } 102 105
+46 -13
arch/arm64/kernel/stacktrace.c
··· 152 152 orig_pc = kretprobe_find_ret_addr(state->task, 153 153 (void *)state->common.fp, 154 154 &state->kr_cur); 155 + if (!orig_pc) 156 + return -EINVAL; 155 157 state->common.pc = orig_pc; 156 158 state->flags.kretprobe = 1; 157 159 } ··· 279 277 280 278 typedef bool (*kunwind_consume_fn)(const struct kunwind_state *state, void *cookie); 281 279 282 - static __always_inline void 280 + static __always_inline int 283 281 do_kunwind(struct kunwind_state *state, kunwind_consume_fn consume_state, 284 282 void *cookie) 285 283 { 286 - if (kunwind_recover_return_address(state)) 287 - return; 284 + int ret; 285 + 286 + ret = kunwind_recover_return_address(state); 287 + if (ret) 288 + return ret; 288 289 289 290 while (1) { 290 - int ret; 291 - 292 291 if (!consume_state(state, cookie)) 293 - break; 292 + return -EINVAL; 294 293 ret = kunwind_next(state); 294 + if (ret == -ENOENT) 295 + return 0; 295 296 if (ret < 0) 296 - break; 297 + return ret; 297 298 } 298 299 } 299 300 ··· 329 324 : stackinfo_get_unknown(); \ 330 325 }) 331 326 332 - static __always_inline void 327 + static __always_inline int 333 328 kunwind_stack_walk(kunwind_consume_fn consume_state, 334 329 void *cookie, struct task_struct *task, 335 330 struct pt_regs *regs) ··· 337 332 struct stack_info stacks[] = { 338 333 stackinfo_get_task(task), 339 334 STACKINFO_CPU(irq), 340 - #if defined(CONFIG_VMAP_STACK) 341 335 STACKINFO_CPU(overflow), 342 - #endif 343 - #if defined(CONFIG_VMAP_STACK) && defined(CONFIG_ARM_SDE_INTERFACE) 336 + #if defined(CONFIG_ARM_SDE_INTERFACE) 344 337 STACKINFO_SDEI(normal), 345 338 STACKINFO_SDEI(critical), 346 339 #endif ··· 355 352 356 353 if (regs) { 357 354 if (task != current) 358 - return; 355 + return -EINVAL; 359 356 kunwind_init_from_regs(&state, regs); 360 357 } else if (task == current) { 361 358 kunwind_init_from_caller(&state); ··· 363 360 kunwind_init_from_task(&state, task); 364 361 } 365 362 366 - do_kunwind(&state, consume_state, cookie); 363 + return do_kunwind(&state, consume_state, cookie); 367 364 } 368 365 369 366 struct kunwind_consume_entry_data { ··· 388 385 }; 389 386 390 387 kunwind_stack_walk(arch_kunwind_consume_entry, &data, task, regs); 388 + } 389 + 390 + static __always_inline bool 391 + arch_reliable_kunwind_consume_entry(const struct kunwind_state *state, void *cookie) 392 + { 393 + /* 394 + * At an exception boundary we can reliably consume the saved PC. We do 395 + * not know whether the LR was live when the exception was taken, and 396 + * so we cannot perform the next unwind step reliably. 397 + * 398 + * All that matters is whether the *entire* unwind is reliable, so give 399 + * up as soon as we hit an exception boundary. 400 + */ 401 + if (state->source == KUNWIND_SOURCE_REGS_PC) 402 + return false; 403 + 404 + return arch_kunwind_consume_entry(state, cookie); 405 + } 406 + 407 + noinline noinstr int arch_stack_walk_reliable(stack_trace_consume_fn consume_entry, 408 + void *cookie, 409 + struct task_struct *task) 410 + { 411 + struct kunwind_consume_entry_data data = { 412 + .consume_entry = consume_entry, 413 + .cookie = cookie, 414 + }; 415 + 416 + return kunwind_stack_walk(arch_reliable_kunwind_consume_entry, &data, 417 + task, NULL); 391 418 } 392 419 393 420 struct bpf_unwind_consume_entry_data {
+8 -76
arch/arm64/kernel/traps.c
··· 454 454 u32 insn; 455 455 456 456 /* check for AArch32 breakpoint instructions */ 457 - if (!aarch32_break_handler(regs)) 457 + if (try_handle_aarch32_break(regs)) 458 458 return; 459 459 460 460 if (user_insn_read(regs, &insn)) ··· 894 894 "Bad EL0 synchronous exception"); 895 895 } 896 896 897 - #ifdef CONFIG_VMAP_STACK 898 - 899 897 DEFINE_PER_CPU(unsigned long [OVERFLOW_STACK_SIZE/sizeof(long)], overflow_stack) 900 898 __aligned(16); 901 899 ··· 925 927 nmi_panic(NULL, "kernel stack overflow"); 926 928 cpu_park_loop(); 927 929 } 928 - #endif 929 930 930 931 void __noreturn arm64_serror_panic(struct pt_regs *regs, unsigned long esr) 931 932 { 933 + add_taint(TAINT_MACHINE_CHECK, LOCKDEP_STILL_OK); 932 934 console_verbose(); 933 935 934 936 pr_crit("SError Interrupt on CPU%d, code 0x%016lx -- %s\n", ··· 985 987 int is_valid_bugaddr(unsigned long addr) 986 988 { 987 989 /* 988 - * bug_handler() only called for BRK #BUG_BRK_IMM. 990 + * bug_brk_handler() only called for BRK #BUG_BRK_IMM. 989 991 * So the answer is trivial -- any spurious instances with no 990 992 * bug table entry will be rejected by report_bug() and passed 991 993 * back to the debug-monitors code and handled as a fatal ··· 995 997 } 996 998 #endif 997 999 998 - static int bug_handler(struct pt_regs *regs, unsigned long esr) 1000 + int bug_brk_handler(struct pt_regs *regs, unsigned long esr) 999 1001 { 1000 1002 switch (report_bug(regs->pc, regs)) { 1001 1003 case BUG_TRAP_TYPE_BUG: ··· 1015 1017 return DBG_HOOK_HANDLED; 1016 1018 } 1017 1019 1018 - static struct break_hook bug_break_hook = { 1019 - .fn = bug_handler, 1020 - .imm = BUG_BRK_IMM, 1021 - }; 1022 - 1023 1020 #ifdef CONFIG_CFI_CLANG 1024 - static int cfi_handler(struct pt_regs *regs, unsigned long esr) 1021 + int cfi_brk_handler(struct pt_regs *regs, unsigned long esr) 1025 1022 { 1026 1023 unsigned long target; 1027 1024 u32 type; ··· 1039 1046 arm64_skip_faulting_instruction(regs, AARCH64_INSN_SIZE); 1040 1047 return DBG_HOOK_HANDLED; 1041 1048 } 1042 - 1043 - static struct break_hook cfi_break_hook = { 1044 - .fn = cfi_handler, 1045 - .imm = CFI_BRK_IMM_BASE, 1046 - .mask = CFI_BRK_IMM_MASK, 1047 - }; 1048 1049 #endif /* CONFIG_CFI_CLANG */ 1049 1050 1050 - static int reserved_fault_handler(struct pt_regs *regs, unsigned long esr) 1051 + int reserved_fault_brk_handler(struct pt_regs *regs, unsigned long esr) 1051 1052 { 1052 1053 pr_err("%s generated an invalid instruction at %pS!\n", 1053 1054 "Kernel text patching", ··· 1051 1064 return DBG_HOOK_ERROR; 1052 1065 } 1053 1066 1054 - static struct break_hook fault_break_hook = { 1055 - .fn = reserved_fault_handler, 1056 - .imm = FAULT_BRK_IMM, 1057 - }; 1058 - 1059 1067 #ifdef CONFIG_KASAN_SW_TAGS 1060 1068 1061 1069 #define KASAN_ESR_RECOVER 0x20 ··· 1058 1076 #define KASAN_ESR_SIZE_MASK 0x0f 1059 1077 #define KASAN_ESR_SIZE(esr) (1 << ((esr) & KASAN_ESR_SIZE_MASK)) 1060 1078 1061 - static int kasan_handler(struct pt_regs *regs, unsigned long esr) 1079 + int kasan_brk_handler(struct pt_regs *regs, unsigned long esr) 1062 1080 { 1063 1081 bool recover = esr & KASAN_ESR_RECOVER; 1064 1082 bool write = esr & KASAN_ESR_WRITE; ··· 1089 1107 arm64_skip_faulting_instruction(regs, AARCH64_INSN_SIZE); 1090 1108 return DBG_HOOK_HANDLED; 1091 1109 } 1092 - 1093 - static struct break_hook kasan_break_hook = { 1094 - .fn = kasan_handler, 1095 - .imm = KASAN_BRK_IMM, 1096 - .mask = KASAN_BRK_MASK, 1097 - }; 1098 1110 #endif 1099 1111 1100 1112 #ifdef CONFIG_UBSAN_TRAP 1101 - static int ubsan_handler(struct pt_regs *regs, unsigned long esr) 1113 + int ubsan_brk_handler(struct pt_regs *regs, unsigned long esr) 1102 1114 { 1103 1115 die(report_ubsan_failure(esr & UBSAN_BRK_MASK), regs, esr); 1104 1116 return DBG_HOOK_HANDLED; 1105 1117 } 1106 - 1107 - static struct break_hook ubsan_break_hook = { 1108 - .fn = ubsan_handler, 1109 - .imm = UBSAN_BRK_IMM, 1110 - .mask = UBSAN_BRK_MASK, 1111 - }; 1112 1118 #endif 1113 - 1114 - /* 1115 - * Initial handler for AArch64 BRK exceptions 1116 - * This handler only used until debug_traps_init(). 1117 - */ 1118 - int __init early_brk64(unsigned long addr, unsigned long esr, 1119 - struct pt_regs *regs) 1120 - { 1121 - #ifdef CONFIG_CFI_CLANG 1122 - if (esr_is_cfi_brk(esr)) 1123 - return cfi_handler(regs, esr) != DBG_HOOK_HANDLED; 1124 - #endif 1125 - #ifdef CONFIG_KASAN_SW_TAGS 1126 - if ((esr_brk_comment(esr) & ~KASAN_BRK_MASK) == KASAN_BRK_IMM) 1127 - return kasan_handler(regs, esr) != DBG_HOOK_HANDLED; 1128 - #endif 1129 - #ifdef CONFIG_UBSAN_TRAP 1130 - if (esr_is_ubsan_brk(esr)) 1131 - return ubsan_handler(regs, esr) != DBG_HOOK_HANDLED; 1132 - #endif 1133 - return bug_handler(regs, esr) != DBG_HOOK_HANDLED; 1134 - } 1135 - 1136 - void __init trap_init(void) 1137 - { 1138 - register_kernel_break_hook(&bug_break_hook); 1139 - #ifdef CONFIG_CFI_CLANG 1140 - register_kernel_break_hook(&cfi_break_hook); 1141 - #endif 1142 - register_kernel_break_hook(&fault_break_hook); 1143 - #ifdef CONFIG_KASAN_SW_TAGS 1144 - register_kernel_break_hook(&kasan_break_hook); 1145 - #endif 1146 - #ifdef CONFIG_UBSAN_TRAP 1147 - register_kernel_break_hook(&ubsan_break_hook); 1148 - #endif 1149 - debug_traps_init(); 1150 - }
+5 -3
arch/arm64/kvm/sys_regs.c
··· 1617 1617 val &= ~ARM64_FEATURE_MASK(ID_AA64PFR1_EL1_MPAM_frac); 1618 1618 break; 1619 1619 case SYS_ID_AA64PFR2_EL1: 1620 - /* We only expose FPMR */ 1621 - val &= ID_AA64PFR2_EL1_FPMR; 1620 + val &= ID_AA64PFR2_EL1_FPMR | 1621 + (kvm_has_mte(vcpu->kvm) ? ID_AA64PFR2_EL1_MTEFAR : 0); 1622 1622 break; 1623 1623 case SYS_ID_AA64ISAR1_EL1: 1624 1624 if (!vcpu_has_ptrauth(vcpu)) ··· 2876 2876 ID_AA64PFR1_EL1_MPAM_frac | 2877 2877 ID_AA64PFR1_EL1_RAS_frac | 2878 2878 ID_AA64PFR1_EL1_MTE)), 2879 - ID_WRITABLE(ID_AA64PFR2_EL1, ID_AA64PFR2_EL1_FPMR), 2879 + ID_WRITABLE(ID_AA64PFR2_EL1, 2880 + ID_AA64PFR2_EL1_FPMR | 2881 + ID_AA64PFR2_EL1_MTEFAR), 2880 2882 ID_UNALLOCATED(4,3), 2881 2883 ID_WRITABLE(ID_AA64ZFR0_EL1, ~ID_AA64ZFR0_EL1_RES0), 2882 2884 ID_HIDDEN(ID_AA64SMFR0_EL1),
+201 -10
arch/arm64/mm/contpte.c
··· 68 68 pte = pte_mkyoung(pte); 69 69 } 70 70 71 - __flush_tlb_range(&vma, start_addr, addr, PAGE_SIZE, true, 3); 71 + /* 72 + * On eliding the __tlb_flush_range() under BBML2+noabort: 73 + * 74 + * NOTE: Instead of using N=16 as the contiguous block length, we use 75 + * N=4 for clarity. 76 + * 77 + * NOTE: 'n' and 'c' are used to denote the "contiguous bit" being 78 + * unset and set, respectively. 79 + * 80 + * We worry about two cases where contiguous bit is used: 81 + * - When folding N smaller non-contiguous ptes as 1 contiguous block. 82 + * - When unfolding a contiguous block into N smaller non-contiguous ptes. 83 + * 84 + * Currently, the BBML0 folding case looks as follows: 85 + * 86 + * 0) Initial page-table layout: 87 + * 88 + * +----+----+----+----+ 89 + * |RO,n|RO,n|RO,n|RW,n| <--- last page being set as RO 90 + * +----+----+----+----+ 91 + * 92 + * 1) Aggregate AF + dirty flags using __ptep_get_and_clear(): 93 + * 94 + * +----+----+----+----+ 95 + * | 0 | 0 | 0 | 0 | 96 + * +----+----+----+----+ 97 + * 98 + * 2) __flush_tlb_range(): 99 + * 100 + * |____ tlbi + dsb ____| 101 + * 102 + * 3) __set_ptes() to repaint contiguous block: 103 + * 104 + * +----+----+----+----+ 105 + * |RO,c|RO,c|RO,c|RO,c| 106 + * +----+----+----+----+ 107 + * 108 + * 4) The kernel will eventually __flush_tlb() for changed page: 109 + * 110 + * |____| <--- tlbi + dsb 111 + * 112 + * As expected, the intermediate tlbi+dsb ensures that other PEs 113 + * only ever see an invalid (0) entry, or the new contiguous TLB entry. 114 + * The final tlbi+dsb will always throw away the newly installed 115 + * contiguous TLB entry, which is a micro-optimisation opportunity, 116 + * but does not affect correctness. 117 + * 118 + * In the BBML2 case, the change is avoiding the intermediate tlbi+dsb. 119 + * This means a few things, but notably other PEs will still "see" any 120 + * stale cached TLB entries. This could lead to a "contiguous bit 121 + * misprogramming" issue until the final tlbi+dsb of the changed page, 122 + * which would clear out both the stale (RW,n) entry and the new (RO,c) 123 + * contiguous entry installed in its place. 124 + * 125 + * What this is saying, is the following: 126 + * 127 + * +----+----+----+----+ 128 + * |RO,n|RO,n|RO,n|RW,n| <--- old page tables, all non-contiguous 129 + * +----+----+----+----+ 130 + * 131 + * +----+----+----+----+ 132 + * |RO,c|RO,c|RO,c|RO,c| <--- new page tables, all contiguous 133 + * +----+----+----+----+ 134 + * /\ 135 + * || 136 + * 137 + * If both the old single (RW,n) and new contiguous (RO,c) TLB entries 138 + * are present, and a write is made to this address, do we fault or 139 + * is the write permitted (via amalgamation)? 140 + * 141 + * The relevant Arm ARM DDI 0487L.a requirements are RNGLXZ and RJQQTC, 142 + * and together state that when BBML1 or BBML2 are implemented, either 143 + * a TLB conflict abort is raised (which we expressly forbid), or will 144 + * "produce an OA, access permissions, and memory attributes that are 145 + * consistent with any of the programmed translation table values". 146 + * 147 + * That is to say, will either raise a TLB conflict, or produce one of 148 + * the cached TLB entries, but never amalgamate. 149 + * 150 + * Thus, as the page tables are only considered "consistent" after 151 + * the final tlbi+dsb (which evicts both the single stale (RW,n) TLB 152 + * entry as well as the new contiguous (RO,c) TLB entry), omitting the 153 + * initial tlbi+dsb is correct. 154 + * 155 + * It is also important to note that at the end of the BBML2 folding 156 + * case, we are still left with potentially all N TLB entries still 157 + * cached (the N-1 non-contiguous ptes, and the single contiguous 158 + * block). However, over time, natural TLB pressure will cause the 159 + * non-contiguous pte TLB entries to be flushed, leaving only the 160 + * contiguous block TLB entry. This means that omitting the tlbi+dsb is 161 + * not only correct, but also keeps our eventual performance benefits. 162 + * 163 + * For the unfolding case, BBML0 looks as follows: 164 + * 165 + * 0) Initial page-table layout: 166 + * 167 + * +----+----+----+----+ 168 + * |RW,c|RW,c|RW,c|RW,c| <--- last page being set as RO 169 + * +----+----+----+----+ 170 + * 171 + * 1) Aggregate AF + dirty flags using __ptep_get_and_clear(): 172 + * 173 + * +----+----+----+----+ 174 + * | 0 | 0 | 0 | 0 | 175 + * +----+----+----+----+ 176 + * 177 + * 2) __flush_tlb_range(): 178 + * 179 + * |____ tlbi + dsb ____| 180 + * 181 + * 3) __set_ptes() to repaint as non-contiguous: 182 + * 183 + * +----+----+----+----+ 184 + * |RW,n|RW,n|RW,n|RW,n| 185 + * +----+----+----+----+ 186 + * 187 + * 4) Update changed page permissions: 188 + * 189 + * +----+----+----+----+ 190 + * |RW,n|RW,n|RW,n|RO,n| <--- last page permissions set 191 + * +----+----+----+----+ 192 + * 193 + * 5) The kernel will eventually __flush_tlb() for changed page: 194 + * 195 + * |____| <--- tlbi + dsb 196 + * 197 + * For BBML2, we again remove the intermediate tlbi+dsb. Here, there 198 + * are no issues, as the final tlbi+dsb covering the changed page is 199 + * guaranteed to remove the original large contiguous (RW,c) TLB entry, 200 + * as well as the intermediate (RW,n) TLB entry; the next access will 201 + * install the new (RO,n) TLB entry and the page tables are only 202 + * considered "consistent" after the final tlbi+dsb, so software must 203 + * be prepared for this inconsistency prior to finishing the mm dance 204 + * regardless. 205 + */ 206 + 207 + if (!system_supports_bbml2_noabort()) 208 + __flush_tlb_range(&vma, start_addr, addr, PAGE_SIZE, true, 3); 72 209 73 210 __set_ptes(mm, start_addr, start_ptep, pte, CONT_PTES); 74 211 } ··· 306 169 for (i = 0; i < CONT_PTES; i++, ptep++) { 307 170 pte = __ptep_get(ptep); 308 171 309 - if (pte_dirty(pte)) 172 + if (pte_dirty(pte)) { 310 173 orig_pte = pte_mkdirty(orig_pte); 174 + for (; i < CONT_PTES; i++, ptep++) { 175 + pte = __ptep_get(ptep); 176 + if (pte_young(pte)) { 177 + orig_pte = pte_mkyoung(orig_pte); 178 + break; 179 + } 180 + } 181 + break; 182 + } 311 183 312 - if (pte_young(pte)) 184 + if (pte_young(pte)) { 313 185 orig_pte = pte_mkyoung(orig_pte); 186 + i++; 187 + ptep++; 188 + for (; i < CONT_PTES; i++, ptep++) { 189 + pte = __ptep_get(ptep); 190 + if (pte_dirty(pte)) { 191 + orig_pte = pte_mkdirty(orig_pte); 192 + break; 193 + } 194 + } 195 + break; 196 + } 314 197 } 315 198 316 199 return orig_pte; 317 200 } 318 201 EXPORT_SYMBOL_GPL(contpte_ptep_get); 202 + 203 + static inline bool contpte_is_consistent(pte_t pte, unsigned long pfn, 204 + pgprot_t orig_prot) 205 + { 206 + pgprot_t prot = pte_pgprot(pte_mkold(pte_mkclean(pte))); 207 + 208 + return pte_valid_cont(pte) && pte_pfn(pte) == pfn && 209 + pgprot_val(prot) == pgprot_val(orig_prot); 210 + } 319 211 320 212 pte_t contpte_ptep_get_lockless(pte_t *orig_ptep) 321 213 { ··· 368 202 pgprot_t orig_prot; 369 203 unsigned long pfn; 370 204 pte_t orig_pte; 371 - pgprot_t prot; 372 205 pte_t *ptep; 373 206 pte_t pte; 374 207 int i; ··· 384 219 385 220 for (i = 0; i < CONT_PTES; i++, ptep++, pfn++) { 386 221 pte = __ptep_get(ptep); 387 - prot = pte_pgprot(pte_mkold(pte_mkclean(pte))); 388 222 389 - if (!pte_valid_cont(pte) || 390 - pte_pfn(pte) != pfn || 391 - pgprot_val(prot) != pgprot_val(orig_prot)) 223 + if (!contpte_is_consistent(pte, pfn, orig_prot)) 392 224 goto retry; 393 225 394 - if (pte_dirty(pte)) 226 + if (pte_dirty(pte)) { 395 227 orig_pte = pte_mkdirty(orig_pte); 228 + for (; i < CONT_PTES; i++, ptep++, pfn++) { 229 + pte = __ptep_get(ptep); 396 230 397 - if (pte_young(pte)) 231 + if (!contpte_is_consistent(pte, pfn, orig_prot)) 232 + goto retry; 233 + 234 + if (pte_young(pte)) { 235 + orig_pte = pte_mkyoung(orig_pte); 236 + break; 237 + } 238 + } 239 + break; 240 + } 241 + 242 + if (pte_young(pte)) { 398 243 orig_pte = pte_mkyoung(orig_pte); 244 + i++; 245 + ptep++; 246 + pfn++; 247 + for (; i < CONT_PTES; i++, ptep++, pfn++) { 248 + pte = __ptep_get(ptep); 249 + 250 + if (!contpte_is_consistent(pte, pfn, orig_prot)) 251 + goto retry; 252 + 253 + if (pte_dirty(pte)) { 254 + orig_pte = pte_mkdirty(orig_pte); 255 + break; 256 + } 257 + } 258 + break; 259 + } 399 260 } 400 261 401 262 return orig_pte;
+6 -77
arch/arm64/mm/fault.c
··· 53 53 }; 54 54 55 55 static const struct fault_info fault_info[]; 56 - static struct fault_info debug_fault_info[]; 57 56 58 57 static inline const struct fault_info *esr_to_fault_info(unsigned long esr) 59 58 { 60 59 return fault_info + (esr & ESR_ELx_FSC); 61 - } 62 - 63 - static inline const struct fault_info *esr_to_debug_fault_info(unsigned long esr) 64 - { 65 - return debug_fault_info + DBG_ESR_EVT(esr); 66 60 } 67 61 68 62 static void data_abort_decode(unsigned long esr) ··· 820 826 */ 821 827 siaddr = untagged_addr(far); 822 828 } 829 + add_taint(TAINT_MACHINE_CHECK, LOCKDEP_STILL_OK); 823 830 arm64_notify_die(inf->name, regs, inf->sig, inf->code, siaddr, esr); 824 831 825 832 return 0; ··· 832 837 /* 833 838 * The architecture specifies that bits 63:60 of FAR_EL1 are UNKNOWN 834 839 * for tag check faults. Set them to corresponding bits in the untagged 835 - * address. 840 + * address if ARM64_MTE_FAR isn't supported. 841 + * Otherwise, bits 63:60 of FAR_EL1 are not UNKNOWN. 836 842 */ 837 - far = (__untagged_addr(far) & ~MTE_TAG_MASK) | (far & MTE_TAG_MASK); 843 + if (!cpus_have_cap(ARM64_MTE_FAR)) 844 + far = (__untagged_addr(far) & ~MTE_TAG_MASK) | (far & MTE_TAG_MASK); 845 + 838 846 do_bad_area(far, esr, regs); 839 847 return 0; 840 848 } ··· 935 937 addr, esr); 936 938 } 937 939 NOKPROBE_SYMBOL(do_sp_pc_abort); 938 - 939 - /* 940 - * __refdata because early_brk64 is __init, but the reference to it is 941 - * clobbered at arch_initcall time. 942 - * See traps.c and debug-monitors.c:debug_traps_init(). 943 - */ 944 - static struct fault_info __refdata debug_fault_info[] = { 945 - { do_bad, SIGTRAP, TRAP_HWBKPT, "hardware breakpoint" }, 946 - { do_bad, SIGTRAP, TRAP_HWBKPT, "hardware single-step" }, 947 - { do_bad, SIGTRAP, TRAP_HWBKPT, "hardware watchpoint" }, 948 - { do_bad, SIGKILL, SI_KERNEL, "unknown 3" }, 949 - { do_bad, SIGTRAP, TRAP_BRKPT, "aarch32 BKPT" }, 950 - { do_bad, SIGKILL, SI_KERNEL, "aarch32 vector catch" }, 951 - { early_brk64, SIGTRAP, TRAP_BRKPT, "aarch64 BRK" }, 952 - { do_bad, SIGKILL, SI_KERNEL, "unknown 7" }, 953 - }; 954 - 955 - void __init hook_debug_fault_code(int nr, 956 - int (*fn)(unsigned long, unsigned long, struct pt_regs *), 957 - int sig, int code, const char *name) 958 - { 959 - BUG_ON(nr < 0 || nr >= ARRAY_SIZE(debug_fault_info)); 960 - 961 - debug_fault_info[nr].fn = fn; 962 - debug_fault_info[nr].sig = sig; 963 - debug_fault_info[nr].code = code; 964 - debug_fault_info[nr].name = name; 965 - } 966 - 967 - /* 968 - * In debug exception context, we explicitly disable preemption despite 969 - * having interrupts disabled. 970 - * This serves two purposes: it makes it much less likely that we would 971 - * accidentally schedule in exception context and it will force a warning 972 - * if we somehow manage to schedule by accident. 973 - */ 974 - static void debug_exception_enter(struct pt_regs *regs) 975 - { 976 - preempt_disable(); 977 - 978 - /* This code is a bit fragile. Test it. */ 979 - RCU_LOCKDEP_WARN(!rcu_is_watching(), "exception_enter didn't work"); 980 - } 981 - NOKPROBE_SYMBOL(debug_exception_enter); 982 - 983 - static void debug_exception_exit(struct pt_regs *regs) 984 - { 985 - preempt_enable_no_resched(); 986 - } 987 - NOKPROBE_SYMBOL(debug_exception_exit); 988 - 989 - void do_debug_exception(unsigned long addr_if_watchpoint, unsigned long esr, 990 - struct pt_regs *regs) 991 - { 992 - const struct fault_info *inf = esr_to_debug_fault_info(esr); 993 - unsigned long pc = instruction_pointer(regs); 994 - 995 - debug_exception_enter(regs); 996 - 997 - if (user_mode(regs) && !is_ttbr0_addr(pc)) 998 - arm64_apply_bp_hardening(); 999 - 1000 - if (inf->fn(addr_if_watchpoint, esr, regs)) { 1001 - arm64_notify_die(inf->name, regs, inf->sig, inf->code, pc, esr); 1002 - } 1003 - 1004 - debug_exception_exit(regs); 1005 - } 1006 - NOKPROBE_SYMBOL(do_debug_exception); 1007 940 1008 941 /* 1009 942 * Used during anonymous page fault handling.
-6
arch/arm64/mm/gcs.c
··· 157 157 if (!system_supports_gcs()) 158 158 return; 159 159 160 - /* 161 - * When fork() with CLONE_VM fails, the child (tsk) already 162 - * has a GCS allocated, and exit_thread() calls this function 163 - * to free it. In this case the parent (current) and the 164 - * child share the same mm struct. 165 - */ 166 160 if (!task->mm || task->mm != current->mm) 167 161 return; 168 162
+1 -1
arch/arm64/mm/hugetlbpage.c
··· 225 225 ncontig = num_contig_ptes(sz, &pgsize); 226 226 227 227 if (!pte_present(pte)) { 228 - for (i = 0; i < ncontig; i++, ptep++, addr += pgsize) 228 + for (i = 0; i < ncontig; i++, ptep++) 229 229 __set_ptes_anysz(mm, ptep, pte, 1, pgsize); 230 230 return; 231 231 }
+2 -1
arch/arm64/mm/mmu.c
··· 1305 1305 next = addr; 1306 1306 end = addr + PUD_SIZE; 1307 1307 do { 1308 - pmd_free_pte_page(pmdp, next); 1308 + if (pmd_present(pmdp_get(pmdp))) 1309 + pmd_free_pte_page(pmdp, next); 1309 1310 } while (pmdp++, next += PMD_SIZE, next != end); 1310 1311 1311 1312 pud_clear(pudp);
+1 -1
arch/arm64/mm/proc.S
··· 454 454 dsb nsh 455 455 456 456 msr cpacr_el1, xzr // Reset cpacr_el1 457 - mov x1, #1 << 12 // Reset mdscr_el1 and disable 457 + mov x1, MDSCR_EL1_TDCC // Reset mdscr_el1 and disable 458 458 msr mdscr_el1, x1 // access to the DCC from EL0 459 459 reset_pmuserenr_el0 x1 // Disable PMU access from EL0 460 460 reset_amuserenr_el0 x1 // Disable AMU access from EL0
+2
arch/arm64/tools/cpucaps
··· 45 45 HAS_LSE_ATOMICS 46 46 HAS_MOPS 47 47 HAS_NESTED_VIRT 48 + HAS_BBML2_NOABORT 48 49 HAS_PAN 49 50 HAS_PMUV3 50 51 HAS_S1PIE ··· 69 68 MPAM_HCR 70 69 MTE 71 70 MTE_ASYMM 71 + MTE_FAR 72 72 SME 73 73 SME_FA64 74 74 SME2
+1 -1
drivers/firmware/efi/libstub/Makefile.zboot
··· 36 36 -DPE_DLL_CHAR_EX=IMAGE_DLLCHARACTERISTICS_EX_FORWARD_CFI_COMPAT 37 37 38 38 AFLAGS_zboot-header.o += -DMACHINE_TYPE=IMAGE_FILE_MACHINE_$(EFI_ZBOOT_MACH_TYPE) \ 39 - -DZBOOT_EFI_PATH="\"$(realpath $(obj)/vmlinuz.efi.elf)\"" \ 39 + -DZBOOT_EFI_PATH="\"$(abspath $(obj)/vmlinuz.efi.elf)\"" \ 40 40 -DZBOOT_SIZE_LEN=$(zboot-size-len-y) \ 41 41 -DCOMP_TYPE="\"$(comp-type-y)\"" \ 42 42 $(aflags-zboot-header-y)
+3
drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-sva.c
··· 220 220 feat_mask |= ARM_SMMU_FEAT_VAX; 221 221 } 222 222 223 + if (system_supports_bbml2_noabort()) 224 + feat_mask |= ARM_SMMU_FEAT_BBML2; 225 + 223 226 if ((smmu->features & feat_mask) != feat_mask) 224 227 return false; 225 228
+3
drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
··· 4457 4457 if (FIELD_GET(IDR3_FWB, reg)) 4458 4458 smmu->features |= ARM_SMMU_FEAT_S2FWB; 4459 4459 4460 + if (FIELD_GET(IDR3_BBM, reg) == 2) 4461 + smmu->features |= ARM_SMMU_FEAT_BBML2; 4462 + 4460 4463 /* IDR5 */ 4461 4464 reg = readl_relaxed(smmu->base + ARM_SMMU_IDR5); 4462 4465
+2
drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
··· 60 60 #define ARM_SMMU_IDR3 0xc 61 61 #define IDR3_FWB (1 << 8) 62 62 #define IDR3_RIL (1 << 10) 63 + #define IDR3_BBM GENMASK(12, 11) 63 64 64 65 #define ARM_SMMU_IDR5 0x14 65 66 #define IDR5_STALL_MAX GENMASK(31, 16) ··· 756 755 #define ARM_SMMU_FEAT_HA (1 << 21) 757 756 #define ARM_SMMU_FEAT_HD (1 << 22) 758 757 #define ARM_SMMU_FEAT_S2FWB (1 << 23) 758 + #define ARM_SMMU_FEAT_BBML2 (1 << 24) 759 759 u32 features; 760 760 761 761 #define ARM_SMMU_OPT_SKIP_PREFETCH (1 << 0)
+1 -1
include/linux/acpi.h
··· 1503 1503 #else 1504 1504 static inline int acpi_parse_spcr(bool enable_earlycon, bool enable_console) 1505 1505 { 1506 - return 0; 1506 + return -ENODEV; 1507 1507 } 1508 1508 #endif 1509 1509
+1 -1
tools/testing/selftests/arm64/abi/Makefile
··· 12 12 $(OUTPUT)/tpidr2: tpidr2.c 13 13 $(CC) -fno-asynchronous-unwind-tables -fno-ident -s -Os -nostdlib \ 14 14 -static -include ../../../../include/nolibc/nolibc.h \ 15 - -ffreestanding -Wall $^ -o $@ -lgcc 15 + -I../.. -ffreestanding -Wall $^ -o $@ -lgcc
+10
tools/testing/selftests/arm64/abi/hwcap.c
··· 21 21 22 22 #define TESTS_PER_HWCAP 3 23 23 24 + #ifndef AT_HWCAP3 25 + #define AT_HWCAP3 29 26 + #endif 27 + 24 28 /* 25 29 * Function expected to generate exception when the feature is not 26 30 * supported and return when it is supported. If the specific exception ··· 1101 1097 .cpuinfo = "hbc", 1102 1098 .sigill_fn = hbc_sigill, 1103 1099 .sigill_reliable = true, 1100 + }, 1101 + { 1102 + .name = "MTE_FAR", 1103 + .at_hwcap = AT_HWCAP3, 1104 + .hwcap_bit = HWCAP3_MTE_FAR, 1105 + .cpuinfo = "mtefar", 1104 1106 }, 1105 1107 }; 1106 1108
+37 -103
tools/testing/selftests/arm64/abi/tpidr2.c
··· 3 3 #include <linux/sched.h> 4 4 #include <linux/wait.h> 5 5 6 + #include "kselftest.h" 7 + 6 8 #define SYS_TPIDR2 "S3_3_C13_C0_5" 7 9 8 10 #define EXPECTED_TESTS 5 9 - 10 - static void putstr(const char *str) 11 - { 12 - write(1, str, strlen(str)); 13 - } 14 - 15 - static void putnum(unsigned int num) 16 - { 17 - char c; 18 - 19 - if (num / 10) 20 - putnum(num / 10); 21 - 22 - c = '0' + (num % 10); 23 - write(1, &c, 1); 24 - } 25 - 26 - static int tests_run; 27 - static int tests_passed; 28 - static int tests_failed; 29 - static int tests_skipped; 30 11 31 12 static void set_tpidr2(uint64_t val) 32 13 { ··· 29 48 : "cc"); 30 49 31 50 return val; 32 - } 33 - 34 - static void print_summary(void) 35 - { 36 - if (tests_passed + tests_failed + tests_skipped != EXPECTED_TESTS) 37 - putstr("# UNEXPECTED TEST COUNT: "); 38 - 39 - putstr("# Totals: pass:"); 40 - putnum(tests_passed); 41 - putstr(" fail:"); 42 - putnum(tests_failed); 43 - putstr(" xfail:0 xpass:0 skip:"); 44 - putnum(tests_skipped); 45 - putstr(" error:0\n"); 46 51 } 47 52 48 53 /* Processes should start with TPIDR2 == 0 */ ··· 72 105 if (newpid == 0) { 73 106 /* In child */ 74 107 if (get_tpidr2() != oldpid) { 75 - putstr("# TPIDR2 changed in child: "); 76 - putnum(get_tpidr2()); 77 - putstr("\n"); 108 + ksft_print_msg("TPIDR2 changed in child: %llx\n", 109 + get_tpidr2()); 78 110 exit(0); 79 111 } 80 112 ··· 81 115 if (get_tpidr2() == getpid()) { 82 116 exit(1); 83 117 } else { 84 - putstr("# Failed to set TPIDR2 in child\n"); 118 + ksft_print_msg("Failed to set TPIDR2 in child\n"); 85 119 exit(0); 86 120 } 87 121 } 88 122 if (newpid < 0) { 89 - putstr("# fork() failed: -"); 90 - putnum(-newpid); 91 - putstr("\n"); 123 + ksft_print_msg("fork() failed: %d\n", newpid); 92 124 return 0; 93 125 } 94 126 ··· 96 132 if (waiting < 0) { 97 133 if (errno == EINTR) 98 134 continue; 99 - putstr("# waitpid() failed: "); 100 - putnum(errno); 101 - putstr("\n"); 135 + ksft_print_msg("waitpid() failed: %d\n", errno); 102 136 return 0; 103 137 } 104 138 if (waiting != newpid) { 105 - putstr("# waitpid() returned wrong PID\n"); 139 + ksft_print_msg("waitpid() returned wrong PID: %d != %d\n", 140 + waiting, newpid); 106 141 return 0; 107 142 } 108 143 109 144 if (!WIFEXITED(status)) { 110 - putstr("# child did not exit\n"); 145 + ksft_print_msg("child did not exit\n"); 111 146 return 0; 112 147 } 113 148 114 149 if (getpid() != get_tpidr2()) { 115 - putstr("# TPIDR2 corrupted in parent\n"); 150 + ksft_print_msg("TPIDR2 corrupted in parent\n"); 116 151 return 0; 117 152 } 118 153 ··· 151 188 152 189 stack = malloc(__STACK_SIZE); 153 190 if (!stack) { 154 - putstr("# malloc() failed\n"); 191 + ksft_print_msg("malloc() failed\n"); 155 192 return 0; 156 193 } 157 194 158 195 ret = sys_clone(CLONE_VM, (unsigned long)stack + __STACK_SIZE, 159 196 &parent_tid, 0, &child_tid); 160 197 if (ret == -1) { 161 - putstr("# clone() failed\n"); 162 - putnum(errno); 163 - putstr("\n"); 198 + ksft_print_msg("clone() failed: %d\n", errno); 164 199 return 0; 165 200 } 166 201 167 202 if (ret == 0) { 168 203 /* In child */ 169 204 if (get_tpidr2() != 0) { 170 - putstr("# TPIDR2 non-zero in child: "); 171 - putnum(get_tpidr2()); 172 - putstr("\n"); 205 + ksft_print_msg("TPIDR2 non-zero in child: %llx\n", 206 + get_tpidr2()); 173 207 exit(0); 174 208 } 175 209 176 210 if (gettid() == 0) 177 - putstr("# Child TID==0\n"); 211 + ksft_print_msg("Child TID==0\n"); 178 212 set_tpidr2(gettid()); 179 213 if (get_tpidr2() == gettid()) { 180 214 exit(1); 181 215 } else { 182 - putstr("# Failed to set TPIDR2 in child\n"); 216 + ksft_print_msg("Failed to set TPIDR2 in child\n"); 183 217 exit(0); 184 218 } 185 219 } ··· 187 227 if (waiting < 0) { 188 228 if (errno == EINTR) 189 229 continue; 190 - putstr("# wait4() failed: "); 191 - putnum(errno); 192 - putstr("\n"); 230 + ksft_print_msg("wait4() failed: %d\n", errno); 193 231 return 0; 194 232 } 195 233 if (waiting != ret) { 196 - putstr("# wait4() returned wrong PID "); 197 - putnum(waiting); 198 - putstr("\n"); 234 + ksft_print_msg("wait4() returned wrong PID %d\n", 235 + waiting); 199 236 return 0; 200 237 } 201 238 202 239 if (!WIFEXITED(status)) { 203 - putstr("# child did not exit\n"); 240 + ksft_print_msg("child did not exit\n"); 204 241 return 0; 205 242 } 206 243 207 244 if (parent != get_tpidr2()) { 208 - putstr("# TPIDR2 corrupted in parent\n"); 245 + ksft_print_msg("TPIDR2 corrupted in parent\n"); 209 246 return 0; 210 247 } 211 248 ··· 210 253 } 211 254 } 212 255 213 - #define run_test(name) \ 214 - if (name()) { \ 215 - tests_passed++; \ 216 - } else { \ 217 - tests_failed++; \ 218 - putstr("not "); \ 219 - } \ 220 - putstr("ok "); \ 221 - putnum(++tests_run); \ 222 - putstr(" " #name "\n"); 223 - 224 - #define skip_test(name) \ 225 - tests_skipped++; \ 226 - putstr("ok "); \ 227 - putnum(++tests_run); \ 228 - putstr(" # SKIP " #name "\n"); 229 - 230 256 int main(int argc, char **argv) 231 257 { 232 258 int ret; 233 259 234 - putstr("TAP version 13\n"); 235 - putstr("1.."); 236 - putnum(EXPECTED_TESTS); 237 - putstr("\n"); 260 + ksft_print_header(); 261 + ksft_set_plan(5); 238 262 239 - putstr("# PID: "); 240 - putnum(getpid()); 241 - putstr("\n"); 263 + ksft_print_msg("PID: %d\n", getpid()); 242 264 243 265 /* 244 266 * This test is run with nolibc which doesn't support hwcap and ··· 226 290 */ 227 291 ret = open("/proc/sys/abi/sme_default_vector_length", O_RDONLY, 0); 228 292 if (ret >= 0) { 229 - run_test(default_value); 230 - run_test(write_read); 231 - run_test(write_sleep_read); 232 - run_test(write_fork_read); 233 - run_test(write_clone_read); 293 + ksft_test_result(default_value(), "default_value\n"); 294 + ksft_test_result(write_read, "write_read\n"); 295 + ksft_test_result(write_sleep_read, "write_sleep_read\n"); 296 + ksft_test_result(write_fork_read, "write_fork_read\n"); 297 + ksft_test_result(write_clone_read, "write_clone_read\n"); 234 298 235 299 } else { 236 - putstr("# SME support not present\n"); 300 + ksft_print_msg("SME support not present\n"); 237 301 238 - skip_test(default_value); 239 - skip_test(write_read); 240 - skip_test(write_sleep_read); 241 - skip_test(write_fork_read); 242 - skip_test(write_clone_read); 302 + ksft_test_result_skip("default_value\n"); 303 + ksft_test_result_skip("write_read\n"); 304 + ksft_test_result_skip("write_sleep_read\n"); 305 + ksft_test_result_skip("write_fork_read\n"); 306 + ksft_test_result_skip("write_clone_read\n"); 243 307 } 244 308 245 - print_summary(); 246 - 247 - return 0; 309 + ksft_finished(); 248 310 }
+74 -3
tools/testing/selftests/arm64/fp/fp-ptrace.c
··· 1061 1061 if (config->sme_vl_in != config->sme_vl_expected) { 1062 1062 return false; 1063 1063 } 1064 + 1065 + if (!sve_supported()) 1066 + return false; 1064 1067 } 1068 + 1069 + return true; 1070 + } 1071 + 1072 + static bool sve_write_fpsimd_supported(struct test_config *config) 1073 + { 1074 + if (!sve_supported()) 1075 + return false; 1076 + 1077 + if ((config->svcr_in & SVCR_ZA) != (config->svcr_expected & SVCR_ZA)) 1078 + return false; 1079 + 1080 + if (config->svcr_expected & SVCR_SM) 1081 + return false; 1082 + 1083 + if (config->sme_vl_in != config->sme_vl_expected) 1084 + return false; 1065 1085 1066 1086 return true; 1067 1087 } ··· 1154 1134 int vl = vl_expected(config); 1155 1135 int sme_vq = __sve_vq_from_vl(config->sme_vl_expected); 1156 1136 1137 + if (!vl) 1138 + return; 1139 + 1157 1140 fill_random(z_expected, __SVE_ZREGS_SIZE(__sve_vq_from_vl(vl))); 1158 1141 fill_random(p_expected, __SVE_PREGS_SIZE(__sve_vq_from_vl(vl))); 1159 1142 ··· 1175 1152 } 1176 1153 } 1177 1154 1178 - static void sve_write(pid_t child, struct test_config *config) 1155 + static void sve_write_sve(pid_t child, struct test_config *config) 1179 1156 { 1180 1157 struct user_sve_header *sve; 1181 1158 struct iovec iov; ··· 1183 1160 1184 1161 vl = vl_expected(config); 1185 1162 vq = __sve_vq_from_vl(vl); 1163 + 1164 + if (!vl) 1165 + return; 1186 1166 1187 1167 iov.iov_len = SVE_PT_SVE_OFFSET + SVE_PT_SVE_SIZE(vq, SVE_PT_REGS_SVE); 1188 1168 iov.iov_base = malloc(iov.iov_len); ··· 1214 1188 regset = NT_ARM_SVE; 1215 1189 1216 1190 ret = ptrace(PTRACE_SETREGSET, child, regset, &iov); 1191 + if (ret != 0) 1192 + ksft_print_msg("Failed to write SVE: %s (%d)\n", 1193 + strerror(errno), errno); 1194 + 1195 + free(iov.iov_base); 1196 + } 1197 + 1198 + static void sve_write_fpsimd(pid_t child, struct test_config *config) 1199 + { 1200 + struct user_sve_header *sve; 1201 + struct user_fpsimd_state *fpsimd; 1202 + struct iovec iov; 1203 + int ret, vl, vq; 1204 + 1205 + vl = vl_expected(config); 1206 + vq = __sve_vq_from_vl(vl); 1207 + 1208 + if (!vl) 1209 + return; 1210 + 1211 + iov.iov_len = SVE_PT_SVE_OFFSET + SVE_PT_SVE_SIZE(vq, 1212 + SVE_PT_REGS_FPSIMD); 1213 + iov.iov_base = malloc(iov.iov_len); 1214 + if (!iov.iov_base) { 1215 + ksft_print_msg("Failed allocating %lu byte SVE write buffer\n", 1216 + iov.iov_len); 1217 + return; 1218 + } 1219 + memset(iov.iov_base, 0, iov.iov_len); 1220 + 1221 + sve = iov.iov_base; 1222 + sve->size = iov.iov_len; 1223 + sve->flags = SVE_PT_REGS_FPSIMD; 1224 + sve->vl = vl; 1225 + 1226 + fpsimd = iov.iov_base + SVE_PT_REGS_OFFSET; 1227 + memcpy(&fpsimd->vregs, v_expected, sizeof(v_expected)); 1228 + 1229 + ret = ptrace(PTRACE_SETREGSET, child, NT_ARM_SVE, &iov); 1217 1230 if (ret != 0) 1218 1231 ksft_print_msg("Failed to write SVE: %s (%d)\n", 1219 1232 strerror(errno), errno); ··· 1451 1386 .name = "SVE write", 1452 1387 .supported = sve_write_supported, 1453 1388 .set_expected_values = sve_write_expected, 1454 - .modify_values = sve_write, 1389 + .modify_values = sve_write_sve, 1390 + }, 1391 + { 1392 + .name = "SVE write FPSIMD format", 1393 + .supported = sve_write_fpsimd_supported, 1394 + .set_expected_values = fpsimd_write_expected, 1395 + .modify_values = sve_write_fpsimd, 1455 1396 }, 1456 1397 }; 1457 1398 ··· 1678 1607 * Run the test set if there is no SVE or SME, with those we 1679 1608 * have to pick a VL for each run. 1680 1609 */ 1681 - if (!sve_supported()) { 1610 + if (!sve_supported() && !sme_supported()) { 1682 1611 test_config.sve_vl_in = 0; 1683 1612 test_config.sve_vl_expected = 0; 1684 1613 test_config.sme_vl_in = 0;
+6 -6
tools/testing/selftests/arm64/fp/sve-ptrace.c
··· 170 170 memset(&sve, 0, sizeof(sve)); 171 171 sve.size = sizeof(sve); 172 172 sve.vl = sve_vl_from_vq(SVE_VQ_MIN); 173 - sve.flags = SVE_PT_VL_INHERIT; 173 + sve.flags = SVE_PT_VL_INHERIT | SVE_PT_REGS_SVE; 174 174 ret = set_sve(child, type, &sve); 175 175 if (ret != 0) { 176 176 ksft_test_result_fail("Failed to set %s SVE_PT_VL_INHERIT\n", ··· 235 235 /* Set the VL by doing a set with no register payload */ 236 236 memset(&sve, 0, sizeof(sve)); 237 237 sve.size = sizeof(sve); 238 + sve.flags = SVE_PT_REGS_SVE; 238 239 sve.vl = vl; 239 240 ret = set_sve(child, type, &sve); 240 241 if (ret != 0) { ··· 254 253 return; 255 254 } 256 255 257 - ksft_test_result(new_sve->vl = prctl_vl, "Set %s VL %u\n", 256 + ksft_test_result(new_sve->vl == prctl_vl, "Set %s VL %u\n", 258 257 type->name, vl); 259 258 260 259 free(new_sve); ··· 302 301 p[j] = j; 303 302 } 304 303 304 + /* This should only succeed for SVE */ 305 305 ret = set_sve(child, type, sve); 306 - ksft_test_result(ret == 0, "%s FPSIMD set via SVE: %d\n", 306 + ksft_test_result((type->regset == NT_ARM_SVE) == (ret == 0), 307 + "%s FPSIMD set via SVE: %d\n", 307 308 type->name, ret); 308 309 if (ret) 309 310 goto out; ··· 752 749 753 750 ksft_print_header(); 754 751 ksft_set_plan(EXPECTED_TESTS); 755 - 756 - if (!(getauxval(AT_HWCAP) & HWCAP_SVE)) 757 - ksft_exit_skip("SVE not available\n"); 758 752 759 753 child = fork(); 760 754 if (!child)
+1 -1
tools/testing/selftests/arm64/mte/check_buffer_fill.c
··· 415 415 return err; 416 416 417 417 /* Register SIGSEGV handler */ 418 - mte_register_signal(SIGSEGV, mte_default_handler); 418 + mte_register_signal(SIGSEGV, mte_default_handler, false); 419 419 420 420 /* Set test plan */ 421 421 ksft_set_plan(20);
+2 -2
tools/testing/selftests/arm64/mte/check_child_memory.c
··· 160 160 return err; 161 161 162 162 /* Register SIGSEGV handler */ 163 - mte_register_signal(SIGSEGV, mte_default_handler); 164 - mte_register_signal(SIGBUS, mte_default_handler); 163 + mte_register_signal(SIGSEGV, mte_default_handler, false); 164 + mte_register_signal(SIGBUS, mte_default_handler, false); 165 165 166 166 /* Set test plan */ 167 167 ksft_set_plan(12);
+2 -2
tools/testing/selftests/arm64/mte/check_hugetlb_options.c
··· 235 235 return err; 236 236 237 237 /* Register signal handlers */ 238 - mte_register_signal(SIGBUS, mte_default_handler); 239 - mte_register_signal(SIGSEGV, mte_default_handler); 238 + mte_register_signal(SIGBUS, mte_default_handler, false); 239 + mte_register_signal(SIGSEGV, mte_default_handler, false); 240 240 241 241 allocate_hugetlb(); 242 242
+2 -2
tools/testing/selftests/arm64/mte/check_ksm_options.c
··· 141 141 return KSFT_FAIL; 142 142 } 143 143 /* Register signal handlers */ 144 - mte_register_signal(SIGBUS, mte_default_handler); 145 - mte_register_signal(SIGSEGV, mte_default_handler); 144 + mte_register_signal(SIGBUS, mte_default_handler, false); 145 + mte_register_signal(SIGSEGV, mte_default_handler, false); 146 146 147 147 /* Set test plan */ 148 148 ksft_set_plan(4);
+476 -69
tools/testing/selftests/arm64/mte/check_mmap_options.c
··· 3 3 4 4 #define _GNU_SOURCE 5 5 6 + #include <assert.h> 6 7 #include <errno.h> 7 8 #include <fcntl.h> 8 9 #include <signal.h> ··· 24 23 #define OVERFLOW MT_GRANULE_SIZE 25 24 #define TAG_CHECK_ON 0 26 25 #define TAG_CHECK_OFF 1 26 + #define ATAG_CHECK_ON 1 27 + #define ATAG_CHECK_OFF 0 28 + 29 + #define TEST_NAME_MAX 256 30 + 31 + enum mte_mem_check_type { 32 + CHECK_ANON_MEM = 0, 33 + CHECK_FILE_MEM = 1, 34 + CHECK_CLEAR_PROT_MTE = 2, 35 + }; 36 + 37 + struct check_mmap_testcase { 38 + int check_type; 39 + int mem_type; 40 + int mte_sync; 41 + int mapping; 42 + int tag_check; 43 + int atag_check; 44 + bool enable_tco; 45 + }; 27 46 28 47 static size_t page_size; 29 48 static int sizes[] = { ··· 51 30 /* page size - 1*/ 0, /* page_size */ 0, /* page size + 1 */ 0 52 31 }; 53 32 54 - static int check_mte_memory(char *ptr, int size, int mode, int tag_check) 33 + static int check_mte_memory(char *ptr, int size, int mode, int tag_check, int atag_check) 55 34 { 35 + if (!mtefar_support && atag_check == ATAG_CHECK_ON) 36 + return KSFT_SKIP; 37 + 38 + if (atag_check == ATAG_CHECK_ON) 39 + ptr = mte_insert_atag(ptr); 40 + 56 41 mte_initialize_current_context(mode, (uintptr_t)ptr, size); 57 42 memset(ptr, '1', size); 58 43 mte_wait_after_trig(); ··· 84 57 return KSFT_PASS; 85 58 } 86 59 87 - static int check_anonymous_memory_mapping(int mem_type, int mode, int mapping, int tag_check) 60 + static int check_anonymous_memory_mapping(int mem_type, int mode, int mapping, int tag_check, int atag_check) 88 61 { 89 62 char *ptr, *map_ptr; 90 63 int run, result, map_size; ··· 106 79 munmap((void *)map_ptr, map_size); 107 80 return KSFT_FAIL; 108 81 } 109 - result = check_mte_memory(ptr, sizes[run], mode, tag_check); 82 + result = check_mte_memory(ptr, sizes[run], mode, tag_check, atag_check); 110 83 mte_clear_tags((void *)ptr, sizes[run]); 111 84 mte_free_memory((void *)map_ptr, map_size, mem_type, false); 112 - if (result == KSFT_FAIL) 113 - return KSFT_FAIL; 85 + if (result != KSFT_PASS) 86 + return result; 114 87 } 115 88 return KSFT_PASS; 116 89 } 117 90 118 - static int check_file_memory_mapping(int mem_type, int mode, int mapping, int tag_check) 91 + static int check_file_memory_mapping(int mem_type, int mode, int mapping, int tag_check, int atag_check) 119 92 { 120 93 char *ptr, *map_ptr; 121 94 int run, fd, map_size; ··· 144 117 close(fd); 145 118 return KSFT_FAIL; 146 119 } 147 - result = check_mte_memory(ptr, sizes[run], mode, tag_check); 120 + result = check_mte_memory(ptr, sizes[run], mode, tag_check, atag_check); 148 121 mte_clear_tags((void *)ptr, sizes[run]); 149 122 munmap((void *)map_ptr, map_size); 150 123 close(fd); 151 - if (result == KSFT_FAIL) 152 - break; 124 + if (result != KSFT_PASS) 125 + return result; 153 126 } 154 - return result; 127 + return KSFT_PASS; 155 128 } 156 129 157 - static int check_clear_prot_mte_flag(int mem_type, int mode, int mapping) 130 + static int check_clear_prot_mte_flag(int mem_type, int mode, int mapping, int atag_check) 158 131 { 159 132 char *ptr, *map_ptr; 160 133 int run, prot_flag, result, fd, map_size; ··· 177 150 ksft_print_msg("FAIL: mprotect not ignoring clear PROT_MTE property\n"); 178 151 return KSFT_FAIL; 179 152 } 180 - result = check_mte_memory(ptr, sizes[run], mode, TAG_CHECK_ON); 153 + result = check_mte_memory(ptr, sizes[run], mode, TAG_CHECK_ON, atag_check); 181 154 mte_free_memory_tag_range((void *)ptr, sizes[run], mem_type, UNDERFLOW, OVERFLOW); 182 155 if (result != KSFT_PASS) 183 156 return KSFT_FAIL; ··· 201 174 close(fd); 202 175 return KSFT_FAIL; 203 176 } 204 - result = check_mte_memory(ptr, sizes[run], mode, TAG_CHECK_ON); 177 + result = check_mte_memory(ptr, sizes[run], mode, TAG_CHECK_ON, atag_check); 205 178 mte_free_memory_tag_range((void *)ptr, sizes[run], mem_type, UNDERFLOW, OVERFLOW); 206 179 close(fd); 207 180 if (result != KSFT_PASS) 208 - return KSFT_FAIL; 181 + return result; 209 182 } 210 183 return KSFT_PASS; 211 184 } 212 185 186 + const char *format_test_name(struct check_mmap_testcase *tc) 187 + { 188 + static char test_name[TEST_NAME_MAX]; 189 + const char *check_type_str; 190 + const char *mem_type_str; 191 + const char *sync_str; 192 + const char *mapping_str; 193 + const char *tag_check_str; 194 + const char *atag_check_str; 195 + 196 + switch (tc->check_type) { 197 + case CHECK_ANON_MEM: 198 + check_type_str = "anonymous memory"; 199 + break; 200 + case CHECK_FILE_MEM: 201 + check_type_str = "file memory"; 202 + break; 203 + case CHECK_CLEAR_PROT_MTE: 204 + check_type_str = "clear PROT_MTE flags"; 205 + break; 206 + default: 207 + assert(0); 208 + break; 209 + } 210 + 211 + switch (tc->mem_type) { 212 + case USE_MMAP: 213 + mem_type_str = "mmap"; 214 + break; 215 + case USE_MPROTECT: 216 + mem_type_str = "mmap/mprotect"; 217 + break; 218 + default: 219 + assert(0); 220 + break; 221 + } 222 + 223 + switch (tc->mte_sync) { 224 + case MTE_NONE_ERR: 225 + sync_str = "no error"; 226 + break; 227 + case MTE_SYNC_ERR: 228 + sync_str = "sync error"; 229 + break; 230 + case MTE_ASYNC_ERR: 231 + sync_str = "async error"; 232 + break; 233 + default: 234 + assert(0); 235 + break; 236 + } 237 + 238 + switch (tc->mapping) { 239 + case MAP_SHARED: 240 + mapping_str = "shared"; 241 + break; 242 + case MAP_PRIVATE: 243 + mapping_str = "private"; 244 + break; 245 + default: 246 + assert(0); 247 + break; 248 + } 249 + 250 + switch (tc->tag_check) { 251 + case TAG_CHECK_ON: 252 + tag_check_str = "tag check on"; 253 + break; 254 + case TAG_CHECK_OFF: 255 + tag_check_str = "tag check off"; 256 + break; 257 + default: 258 + assert(0); 259 + break; 260 + } 261 + 262 + switch (tc->atag_check) { 263 + case ATAG_CHECK_ON: 264 + atag_check_str = "with address tag [63:60]"; 265 + break; 266 + case ATAG_CHECK_OFF: 267 + atag_check_str = "without address tag [63:60]"; 268 + break; 269 + default: 270 + assert(0); 271 + break; 272 + } 273 + 274 + snprintf(test_name, sizeof(test_name), 275 + "Check %s with %s mapping, %s mode, %s memory and %s (%s)\n", 276 + check_type_str, mapping_str, sync_str, mem_type_str, 277 + tag_check_str, atag_check_str); 278 + 279 + return test_name; 280 + } 281 + 213 282 int main(int argc, char *argv[]) 214 283 { 215 - int err; 284 + int err, i; 216 285 int item = ARRAY_SIZE(sizes); 286 + struct check_mmap_testcase test_cases[]= { 287 + { 288 + .check_type = CHECK_ANON_MEM, 289 + .mem_type = USE_MMAP, 290 + .mte_sync = MTE_SYNC_ERR, 291 + .mapping = MAP_PRIVATE, 292 + .tag_check = TAG_CHECK_OFF, 293 + .atag_check = ATAG_CHECK_OFF, 294 + .enable_tco = true, 295 + }, 296 + { 297 + .check_type = CHECK_FILE_MEM, 298 + .mem_type = USE_MPROTECT, 299 + .mte_sync = MTE_SYNC_ERR, 300 + .mapping = MAP_PRIVATE, 301 + .tag_check = TAG_CHECK_OFF, 302 + .atag_check = ATAG_CHECK_OFF, 303 + .enable_tco = true, 304 + }, 305 + { 306 + .check_type = CHECK_ANON_MEM, 307 + .mem_type = USE_MMAP, 308 + .mte_sync = MTE_NONE_ERR, 309 + .mapping = MAP_PRIVATE, 310 + .tag_check = TAG_CHECK_OFF, 311 + .atag_check = ATAG_CHECK_OFF, 312 + .enable_tco = false, 313 + }, 314 + { 315 + .check_type = CHECK_FILE_MEM, 316 + .mem_type = USE_MPROTECT, 317 + .mte_sync = MTE_NONE_ERR, 318 + .mapping = MAP_PRIVATE, 319 + .tag_check = TAG_CHECK_OFF, 320 + .atag_check = ATAG_CHECK_OFF, 321 + .enable_tco = false, 322 + }, 323 + { 324 + .check_type = CHECK_ANON_MEM, 325 + .mem_type = USE_MMAP, 326 + .mte_sync = MTE_SYNC_ERR, 327 + .mapping = MAP_PRIVATE, 328 + .tag_check = TAG_CHECK_ON, 329 + .atag_check = ATAG_CHECK_OFF, 330 + .enable_tco = false, 331 + }, 332 + { 333 + .check_type = CHECK_ANON_MEM, 334 + .mem_type = USE_MPROTECT, 335 + .mte_sync = MTE_SYNC_ERR, 336 + .mapping = MAP_PRIVATE, 337 + .tag_check = TAG_CHECK_ON, 338 + .atag_check = ATAG_CHECK_OFF, 339 + .enable_tco = false, 340 + }, 341 + { 342 + .check_type = CHECK_ANON_MEM, 343 + .mem_type = USE_MMAP, 344 + .mte_sync = MTE_SYNC_ERR, 345 + .mapping = MAP_SHARED, 346 + .tag_check = TAG_CHECK_ON, 347 + .atag_check = ATAG_CHECK_OFF, 348 + .enable_tco = false, 349 + }, 350 + { 351 + .check_type = CHECK_ANON_MEM, 352 + .mem_type = USE_MPROTECT, 353 + .mte_sync = MTE_SYNC_ERR, 354 + .mapping = MAP_SHARED, 355 + .tag_check = TAG_CHECK_ON, 356 + .atag_check = ATAG_CHECK_OFF, 357 + .enable_tco = false, 358 + }, 359 + { 360 + .check_type = CHECK_ANON_MEM, 361 + .mem_type = USE_MMAP, 362 + .mte_sync = MTE_ASYNC_ERR, 363 + .mapping = MAP_PRIVATE, 364 + .tag_check = TAG_CHECK_ON, 365 + .atag_check = ATAG_CHECK_OFF, 366 + .enable_tco = false, 367 + }, 368 + { 369 + .check_type = CHECK_ANON_MEM, 370 + .mem_type = USE_MPROTECT, 371 + .mte_sync = MTE_ASYNC_ERR, 372 + .mapping = MAP_PRIVATE, 373 + .tag_check = TAG_CHECK_ON, 374 + .atag_check = ATAG_CHECK_OFF, 375 + .enable_tco = false, 376 + }, 377 + { 378 + .check_type = CHECK_ANON_MEM, 379 + .mem_type = USE_MMAP, 380 + .mte_sync = MTE_ASYNC_ERR, 381 + .mapping = MAP_SHARED, 382 + .tag_check = TAG_CHECK_ON, 383 + .atag_check = ATAG_CHECK_OFF, 384 + .enable_tco = false, 385 + }, 386 + { 387 + .check_type = CHECK_ANON_MEM, 388 + .mem_type = USE_MPROTECT, 389 + .mte_sync = MTE_ASYNC_ERR, 390 + .mapping = MAP_SHARED, 391 + .tag_check = TAG_CHECK_ON, 392 + .atag_check = ATAG_CHECK_OFF, 393 + .enable_tco = false, 394 + }, 395 + { 396 + .check_type = CHECK_FILE_MEM, 397 + .mem_type = USE_MMAP, 398 + .mte_sync = MTE_SYNC_ERR, 399 + .mapping = MAP_PRIVATE, 400 + .tag_check = TAG_CHECK_ON, 401 + .atag_check = ATAG_CHECK_OFF, 402 + .enable_tco = false, 403 + }, 404 + { 405 + .check_type = CHECK_FILE_MEM, 406 + .mem_type = USE_MPROTECT, 407 + .mte_sync = MTE_SYNC_ERR, 408 + .mapping = MAP_PRIVATE, 409 + .tag_check = TAG_CHECK_ON, 410 + .atag_check = ATAG_CHECK_OFF, 411 + .enable_tco = false, 412 + }, 413 + { 414 + .check_type = CHECK_FILE_MEM, 415 + .mem_type = USE_MMAP, 416 + .mte_sync = MTE_SYNC_ERR, 417 + .mapping = MAP_SHARED, 418 + .tag_check = TAG_CHECK_ON, 419 + .atag_check = ATAG_CHECK_OFF, 420 + .enable_tco = false, 421 + }, 422 + { 423 + .check_type = CHECK_FILE_MEM, 424 + .mem_type = USE_MPROTECT, 425 + .mte_sync = MTE_SYNC_ERR, 426 + .mapping = MAP_SHARED, 427 + .tag_check = TAG_CHECK_ON, 428 + .atag_check = ATAG_CHECK_OFF, 429 + .enable_tco = false, 430 + }, 431 + { 432 + .check_type = CHECK_FILE_MEM, 433 + .mem_type = USE_MMAP, 434 + .mte_sync = MTE_ASYNC_ERR, 435 + .mapping = MAP_PRIVATE, 436 + .tag_check = TAG_CHECK_ON, 437 + .atag_check = ATAG_CHECK_OFF, 438 + .enable_tco = false, 439 + }, 440 + { 441 + .check_type = CHECK_FILE_MEM, 442 + .mem_type = USE_MPROTECT, 443 + .mte_sync = MTE_ASYNC_ERR, 444 + .mapping = MAP_PRIVATE, 445 + .tag_check = TAG_CHECK_ON, 446 + .atag_check = ATAG_CHECK_OFF, 447 + .enable_tco = false, 448 + }, 449 + { 450 + .check_type = CHECK_FILE_MEM, 451 + .mem_type = USE_MMAP, 452 + .mte_sync = MTE_ASYNC_ERR, 453 + .mapping = MAP_SHARED, 454 + .tag_check = TAG_CHECK_ON, 455 + .atag_check = ATAG_CHECK_OFF, 456 + .enable_tco = false, 457 + }, 458 + { 459 + .check_type = CHECK_FILE_MEM, 460 + .mem_type = USE_MPROTECT, 461 + .mte_sync = MTE_ASYNC_ERR, 462 + .mapping = MAP_SHARED, 463 + .tag_check = TAG_CHECK_ON, 464 + .atag_check = ATAG_CHECK_OFF, 465 + .enable_tco = false, 466 + }, 467 + { 468 + .check_type = CHECK_CLEAR_PROT_MTE, 469 + .mem_type = USE_MMAP, 470 + .mte_sync = MTE_SYNC_ERR, 471 + .mapping = MAP_PRIVATE, 472 + .tag_check = TAG_CHECK_ON, 473 + .atag_check = ATAG_CHECK_OFF, 474 + .enable_tco = false, 475 + }, 476 + { 477 + .check_type = CHECK_CLEAR_PROT_MTE, 478 + .mem_type = USE_MPROTECT, 479 + .mte_sync = MTE_SYNC_ERR, 480 + .mapping = MAP_PRIVATE, 481 + .tag_check = TAG_CHECK_ON, 482 + .atag_check = ATAG_CHECK_OFF, 483 + .enable_tco = false, 484 + }, 485 + { 486 + .check_type = CHECK_ANON_MEM, 487 + .mem_type = USE_MMAP, 488 + .mte_sync = MTE_SYNC_ERR, 489 + .mapping = MAP_PRIVATE, 490 + .tag_check = TAG_CHECK_ON, 491 + .atag_check = ATAG_CHECK_ON, 492 + .enable_tco = false, 493 + }, 494 + { 495 + .check_type = CHECK_ANON_MEM, 496 + .mem_type = USE_MPROTECT, 497 + .mte_sync = MTE_SYNC_ERR, 498 + .mapping = MAP_PRIVATE, 499 + .tag_check = TAG_CHECK_ON, 500 + .atag_check = ATAG_CHECK_ON, 501 + .enable_tco = false, 502 + }, 503 + { 504 + .check_type = CHECK_ANON_MEM, 505 + .mem_type = USE_MMAP, 506 + .mte_sync = MTE_SYNC_ERR, 507 + .mapping = MAP_SHARED, 508 + .tag_check = TAG_CHECK_ON, 509 + .atag_check = ATAG_CHECK_ON, 510 + .enable_tco = false, 511 + }, 512 + { 513 + .check_type = CHECK_ANON_MEM, 514 + .mem_type = USE_MPROTECT, 515 + .mte_sync = MTE_SYNC_ERR, 516 + .mapping = MAP_SHARED, 517 + .tag_check = TAG_CHECK_ON, 518 + .atag_check = ATAG_CHECK_ON, 519 + .enable_tco = false, 520 + }, 521 + { 522 + .check_type = CHECK_FILE_MEM, 523 + .mem_type = USE_MMAP, 524 + .mte_sync = MTE_SYNC_ERR, 525 + .mapping = MAP_PRIVATE, 526 + .tag_check = TAG_CHECK_ON, 527 + .atag_check = ATAG_CHECK_ON, 528 + .enable_tco = false, 529 + }, 530 + { 531 + .check_type = CHECK_FILE_MEM, 532 + .mem_type = USE_MPROTECT, 533 + .mte_sync = MTE_SYNC_ERR, 534 + .mapping = MAP_PRIVATE, 535 + .tag_check = TAG_CHECK_ON, 536 + .atag_check = ATAG_CHECK_ON, 537 + .enable_tco = false, 538 + }, 539 + { 540 + .check_type = CHECK_FILE_MEM, 541 + .mem_type = USE_MMAP, 542 + .mte_sync = MTE_SYNC_ERR, 543 + .mapping = MAP_SHARED, 544 + .tag_check = TAG_CHECK_ON, 545 + .atag_check = ATAG_CHECK_ON, 546 + .enable_tco = false, 547 + }, 548 + { 549 + .check_type = CHECK_FILE_MEM, 550 + .mem_type = USE_MPROTECT, 551 + .mte_sync = MTE_SYNC_ERR, 552 + .mapping = MAP_SHARED, 553 + .tag_check = TAG_CHECK_ON, 554 + .atag_check = ATAG_CHECK_ON, 555 + .enable_tco = false, 556 + }, 557 + { 558 + .check_type = CHECK_FILE_MEM, 559 + .mem_type = USE_MMAP, 560 + .mte_sync = MTE_ASYNC_ERR, 561 + .mapping = MAP_PRIVATE, 562 + .tag_check = TAG_CHECK_ON, 563 + .atag_check = ATAG_CHECK_ON, 564 + .enable_tco = false, 565 + }, 566 + { 567 + .check_type = CHECK_CLEAR_PROT_MTE, 568 + .mem_type = USE_MMAP, 569 + .mte_sync = MTE_SYNC_ERR, 570 + .mapping = MAP_PRIVATE, 571 + .tag_check = TAG_CHECK_ON, 572 + .atag_check = ATAG_CHECK_ON, 573 + .enable_tco = false, 574 + }, 575 + { 576 + .check_type = CHECK_CLEAR_PROT_MTE, 577 + .mem_type = USE_MPROTECT, 578 + .mte_sync = MTE_SYNC_ERR, 579 + .mapping = MAP_PRIVATE, 580 + .tag_check = TAG_CHECK_ON, 581 + .atag_check = ATAG_CHECK_ON, 582 + .enable_tco = false, 583 + }, 584 + }; 217 585 218 586 err = mte_default_setup(); 219 587 if (err) ··· 622 200 sizes[item - 2] = page_size; 623 201 sizes[item - 1] = page_size + 1; 624 202 625 - /* Register signal handlers */ 626 - mte_register_signal(SIGBUS, mte_default_handler); 627 - mte_register_signal(SIGSEGV, mte_default_handler); 628 - 629 203 /* Set test plan */ 630 - ksft_set_plan(22); 204 + ksft_set_plan(ARRAY_SIZE(test_cases)); 631 205 632 - mte_enable_pstate_tco(); 206 + for (i = 0 ; i < ARRAY_SIZE(test_cases); i++) { 207 + /* Register signal handlers */ 208 + mte_register_signal(SIGBUS, mte_default_handler, 209 + test_cases[i].atag_check == ATAG_CHECK_ON); 210 + mte_register_signal(SIGSEGV, mte_default_handler, 211 + test_cases[i].atag_check == ATAG_CHECK_ON); 633 212 634 - evaluate_test(check_anonymous_memory_mapping(USE_MMAP, MTE_SYNC_ERR, MAP_PRIVATE, TAG_CHECK_OFF), 635 - "Check anonymous memory with private mapping, sync error mode, mmap memory and tag check off\n"); 636 - evaluate_test(check_file_memory_mapping(USE_MPROTECT, MTE_SYNC_ERR, MAP_PRIVATE, TAG_CHECK_OFF), 637 - "Check file memory with private mapping, sync error mode, mmap/mprotect memory and tag check off\n"); 213 + if (test_cases[i].enable_tco) 214 + mte_enable_pstate_tco(); 215 + else 216 + mte_disable_pstate_tco(); 638 217 639 - mte_disable_pstate_tco(); 640 - evaluate_test(check_anonymous_memory_mapping(USE_MMAP, MTE_NONE_ERR, MAP_PRIVATE, TAG_CHECK_OFF), 641 - "Check anonymous memory with private mapping, no error mode, mmap memory and tag check off\n"); 642 - evaluate_test(check_file_memory_mapping(USE_MPROTECT, MTE_NONE_ERR, MAP_PRIVATE, TAG_CHECK_OFF), 643 - "Check file memory with private mapping, no error mode, mmap/mprotect memory and tag check off\n"); 644 - 645 - evaluate_test(check_anonymous_memory_mapping(USE_MMAP, MTE_SYNC_ERR, MAP_PRIVATE, TAG_CHECK_ON), 646 - "Check anonymous memory with private mapping, sync error mode, mmap memory and tag check on\n"); 647 - evaluate_test(check_anonymous_memory_mapping(USE_MPROTECT, MTE_SYNC_ERR, MAP_PRIVATE, TAG_CHECK_ON), 648 - "Check anonymous memory with private mapping, sync error mode, mmap/mprotect memory and tag check on\n"); 649 - evaluate_test(check_anonymous_memory_mapping(USE_MMAP, MTE_SYNC_ERR, MAP_SHARED, TAG_CHECK_ON), 650 - "Check anonymous memory with shared mapping, sync error mode, mmap memory and tag check on\n"); 651 - evaluate_test(check_anonymous_memory_mapping(USE_MPROTECT, MTE_SYNC_ERR, MAP_SHARED, TAG_CHECK_ON), 652 - "Check anonymous memory with shared mapping, sync error mode, mmap/mprotect memory and tag check on\n"); 653 - evaluate_test(check_anonymous_memory_mapping(USE_MMAP, MTE_ASYNC_ERR, MAP_PRIVATE, TAG_CHECK_ON), 654 - "Check anonymous memory with private mapping, async error mode, mmap memory and tag check on\n"); 655 - evaluate_test(check_anonymous_memory_mapping(USE_MPROTECT, MTE_ASYNC_ERR, MAP_PRIVATE, TAG_CHECK_ON), 656 - "Check anonymous memory with private mapping, async error mode, mmap/mprotect memory and tag check on\n"); 657 - evaluate_test(check_anonymous_memory_mapping(USE_MMAP, MTE_ASYNC_ERR, MAP_SHARED, TAG_CHECK_ON), 658 - "Check anonymous memory with shared mapping, async error mode, mmap memory and tag check on\n"); 659 - evaluate_test(check_anonymous_memory_mapping(USE_MPROTECT, MTE_ASYNC_ERR, MAP_SHARED, TAG_CHECK_ON), 660 - "Check anonymous memory with shared mapping, async error mode, mmap/mprotect memory and tag check on\n"); 661 - 662 - evaluate_test(check_file_memory_mapping(USE_MMAP, MTE_SYNC_ERR, MAP_PRIVATE, TAG_CHECK_ON), 663 - "Check file memory with private mapping, sync error mode, mmap memory and tag check on\n"); 664 - evaluate_test(check_file_memory_mapping(USE_MPROTECT, MTE_SYNC_ERR, MAP_PRIVATE, TAG_CHECK_ON), 665 - "Check file memory with private mapping, sync error mode, mmap/mprotect memory and tag check on\n"); 666 - evaluate_test(check_file_memory_mapping(USE_MMAP, MTE_SYNC_ERR, MAP_SHARED, TAG_CHECK_ON), 667 - "Check file memory with shared mapping, sync error mode, mmap memory and tag check on\n"); 668 - evaluate_test(check_file_memory_mapping(USE_MPROTECT, MTE_SYNC_ERR, MAP_SHARED, TAG_CHECK_ON), 669 - "Check file memory with shared mapping, sync error mode, mmap/mprotect memory and tag check on\n"); 670 - evaluate_test(check_file_memory_mapping(USE_MMAP, MTE_ASYNC_ERR, MAP_PRIVATE, TAG_CHECK_ON), 671 - "Check file memory with private mapping, async error mode, mmap memory and tag check on\n"); 672 - evaluate_test(check_file_memory_mapping(USE_MPROTECT, MTE_ASYNC_ERR, MAP_PRIVATE, TAG_CHECK_ON), 673 - "Check file memory with private mapping, async error mode, mmap/mprotect memory and tag check on\n"); 674 - evaluate_test(check_file_memory_mapping(USE_MMAP, MTE_ASYNC_ERR, MAP_SHARED, TAG_CHECK_ON), 675 - "Check file memory with shared mapping, async error mode, mmap memory and tag check on\n"); 676 - evaluate_test(check_file_memory_mapping(USE_MPROTECT, MTE_ASYNC_ERR, MAP_SHARED, TAG_CHECK_ON), 677 - "Check file memory with shared mapping, async error mode, mmap/mprotect memory and tag check on\n"); 678 - 679 - evaluate_test(check_clear_prot_mte_flag(USE_MMAP, MTE_SYNC_ERR, MAP_PRIVATE), 680 - "Check clear PROT_MTE flags with private mapping, sync error mode and mmap memory\n"); 681 - evaluate_test(check_clear_prot_mte_flag(USE_MPROTECT, MTE_SYNC_ERR, MAP_PRIVATE), 682 - "Check clear PROT_MTE flags with private mapping and sync error mode and mmap/mprotect memory\n"); 218 + switch (test_cases[i].check_type) { 219 + case CHECK_ANON_MEM: 220 + evaluate_test(check_anonymous_memory_mapping(test_cases[i].mem_type, 221 + test_cases[i].mte_sync, 222 + test_cases[i].mapping, 223 + test_cases[i].tag_check, 224 + test_cases[i].atag_check), 225 + format_test_name(&test_cases[i])); 226 + break; 227 + case CHECK_FILE_MEM: 228 + evaluate_test(check_file_memory_mapping(test_cases[i].mem_type, 229 + test_cases[i].mte_sync, 230 + test_cases[i].mapping, 231 + test_cases[i].tag_check, 232 + test_cases[i].atag_check), 233 + format_test_name(&test_cases[i])); 234 + break; 235 + case CHECK_CLEAR_PROT_MTE: 236 + evaluate_test(check_clear_prot_mte_flag(test_cases[i].mem_type, 237 + test_cases[i].mte_sync, 238 + test_cases[i].mapping, 239 + test_cases[i].atag_check), 240 + format_test_name(&test_cases[i])); 241 + break; 242 + default: 243 + exit(KSFT_FAIL); 244 + } 245 + } 683 246 684 247 mte_restore_setup(); 685 248 ksft_print_cnts();
+4
tools/testing/selftests/arm64/mte/check_prctl.c
··· 12 12 13 13 #include "kselftest.h" 14 14 15 + #ifndef AT_HWCAP3 16 + #define AT_HWCAP3 29 17 + #endif 18 + 15 19 static int set_tagged_addr_ctrl(int val) 16 20 { 17 21 int ret;
+1 -1
tools/testing/selftests/arm64/mte/check_tags_inclusion.c
··· 180 180 return err; 181 181 182 182 /* Register SIGSEGV handler */ 183 - mte_register_signal(SIGSEGV, mte_default_handler); 183 + mte_register_signal(SIGSEGV, mte_default_handler, false); 184 184 185 185 /* Set test plan */ 186 186 ksft_set_plan(4);
+1 -1
tools/testing/selftests/arm64/mte/check_user_mem.c
··· 211 211 return err; 212 212 213 213 /* Register signal handlers */ 214 - mte_register_signal(SIGSEGV, mte_default_handler); 214 + mte_register_signal(SIGSEGV, mte_default_handler, false); 215 215 216 216 /* Set test plan */ 217 217 ksft_set_plan(64);
+59 -11
tools/testing/selftests/arm64/mte/mte_common_util.c
··· 6 6 #include <signal.h> 7 7 #include <stdio.h> 8 8 #include <stdlib.h> 9 + #include <time.h> 9 10 #include <unistd.h> 10 11 11 12 #include <linux/auxvec.h> ··· 20 19 #include "mte_common_util.h" 21 20 #include "mte_def.h" 22 21 22 + #ifndef SA_EXPOSE_TAGBITS 23 + #define SA_EXPOSE_TAGBITS 0x00000800 24 + #endif 25 + 23 26 #define INIT_BUFFER_SIZE 256 24 27 25 28 struct mte_fault_cxt cur_mte_cxt; 29 + bool mtefar_support; 26 30 static unsigned int mte_cur_mode; 27 31 static unsigned int mte_cur_pstate_tco; 28 32 29 33 void mte_default_handler(int signum, siginfo_t *si, void *uc) 30 34 { 35 + struct sigaction sa; 31 36 unsigned long addr = (unsigned long)si->si_addr; 37 + unsigned char si_tag, si_atag; 38 + 39 + sigaction(signum, NULL, &sa); 40 + 41 + if (sa.sa_flags & SA_EXPOSE_TAGBITS) { 42 + si_tag = MT_FETCH_TAG(addr); 43 + si_atag = MT_FETCH_ATAG(addr); 44 + addr = MT_CLEAR_TAGS(addr); 45 + } else { 46 + si_tag = 0; 47 + si_atag = 0; 48 + } 32 49 33 50 if (signum == SIGSEGV) { 34 51 #ifdef DEBUG 35 - ksft_print_msg("INFO: SIGSEGV signal at pc=%lx, fault addr=%lx, si_code=%lx\n", 36 - ((ucontext_t *)uc)->uc_mcontext.pc, addr, si->si_code); 52 + ksft_print_msg("INFO: SIGSEGV signal at pc=%lx, fault addr=%lx, si_code=%lx, si_tag=%x, si_atag=%x\n", 53 + ((ucontext_t *)uc)->uc_mcontext.pc, addr, si->si_code, si_tag, si_atag); 37 54 #endif 38 55 if (si->si_code == SEGV_MTEAERR) { 39 56 if (cur_mte_cxt.trig_si_code == si->si_code) ··· 64 45 } 65 46 /* Compare the context for precise error */ 66 47 else if (si->si_code == SEGV_MTESERR) { 48 + if ((!mtefar_support && si_atag) || (si_atag != MT_FETCH_ATAG(cur_mte_cxt.trig_addr))) { 49 + ksft_print_msg("Invalid MTE synchronous exception caught for address tag! si_tag=%x, si_atag: %x\n", si_tag, si_atag); 50 + exit(KSFT_FAIL); 51 + } 52 + 67 53 if (cur_mte_cxt.trig_si_code == si->si_code && 68 54 ((cur_mte_cxt.trig_range >= 0 && 69 - addr >= MT_CLEAR_TAG(cur_mte_cxt.trig_addr) && 70 - addr <= (MT_CLEAR_TAG(cur_mte_cxt.trig_addr) + cur_mte_cxt.trig_range)) || 55 + addr >= MT_CLEAR_TAGS(cur_mte_cxt.trig_addr) && 56 + addr <= (MT_CLEAR_TAGS(cur_mte_cxt.trig_addr) + cur_mte_cxt.trig_range)) || 71 57 (cur_mte_cxt.trig_range < 0 && 72 - addr <= MT_CLEAR_TAG(cur_mte_cxt.trig_addr) && 73 - addr >= (MT_CLEAR_TAG(cur_mte_cxt.trig_addr) + cur_mte_cxt.trig_range)))) { 58 + addr <= MT_CLEAR_TAGS(cur_mte_cxt.trig_addr) && 59 + addr >= (MT_CLEAR_TAGS(cur_mte_cxt.trig_addr) + cur_mte_cxt.trig_range)))) { 74 60 cur_mte_cxt.fault_valid = true; 75 61 /* Adjust the pc by 4 */ 76 62 ((ucontext_t *)uc)->uc_mcontext.pc += 4; ··· 91 67 ksft_print_msg("INFO: SIGBUS signal at pc=%llx, fault addr=%lx, si_code=%x\n", 92 68 ((ucontext_t *)uc)->uc_mcontext.pc, addr, si->si_code); 93 69 if ((cur_mte_cxt.trig_range >= 0 && 94 - addr >= MT_CLEAR_TAG(cur_mte_cxt.trig_addr) && 95 - addr <= (MT_CLEAR_TAG(cur_mte_cxt.trig_addr) + cur_mte_cxt.trig_range)) || 70 + addr >= MT_CLEAR_TAGS(cur_mte_cxt.trig_addr) && 71 + addr <= (MT_CLEAR_TAGS(cur_mte_cxt.trig_addr) + cur_mte_cxt.trig_range)) || 96 72 (cur_mte_cxt.trig_range < 0 && 97 - addr <= MT_CLEAR_TAG(cur_mte_cxt.trig_addr) && 98 - addr >= (MT_CLEAR_TAG(cur_mte_cxt.trig_addr) + cur_mte_cxt.trig_range))) { 73 + addr <= MT_CLEAR_TAGS(cur_mte_cxt.trig_addr) && 74 + addr >= (MT_CLEAR_TAGS(cur_mte_cxt.trig_addr) + cur_mte_cxt.trig_range))) { 99 75 cur_mte_cxt.fault_valid = true; 100 76 /* Adjust the pc by 4 */ 101 77 ((ucontext_t *)uc)->uc_mcontext.pc += 4; ··· 103 79 } 104 80 } 105 81 106 - void mte_register_signal(int signal, void (*handler)(int, siginfo_t *, void *)) 82 + void mte_register_signal(int signal, void (*handler)(int, siginfo_t *, void *), 83 + bool export_tags) 107 84 { 108 85 struct sigaction sa; 109 86 110 87 sa.sa_sigaction = handler; 111 88 sa.sa_flags = SA_SIGINFO; 89 + 90 + if (export_tags && signal == SIGSEGV) 91 + sa.sa_flags |= SA_EXPOSE_TAGBITS; 92 + 112 93 sigemptyset(&sa.sa_mask); 113 94 sigaction(signal, &sa, NULL); 114 95 } ··· 147 118 size = MT_ALIGN_UP(size); 148 119 ptr = (void *)MT_CLEAR_TAG((unsigned long)ptr); 149 120 mte_clear_tag_address_range(ptr, size); 121 + } 122 + 123 + void *mte_insert_atag(void *ptr) 124 + { 125 + unsigned char atag; 126 + 127 + atag = mtefar_support ? (random() % MT_ATAG_MASK) + 1 : 0; 128 + return (void *)MT_SET_ATAG((unsigned long)ptr, atag); 129 + } 130 + 131 + void *mte_clear_atag(void *ptr) 132 + { 133 + return (void *)MT_CLEAR_ATAG((unsigned long)ptr); 150 134 } 151 135 152 136 static void *__mte_allocate_memory_range(size_t size, int mem_type, int mapping, ··· 358 316 int mte_default_setup(void) 359 317 { 360 318 unsigned long hwcaps2 = getauxval(AT_HWCAP2); 319 + unsigned long hwcaps3 = getauxval(AT_HWCAP3); 361 320 unsigned long en = 0; 362 321 int ret; 363 322 323 + /* To generate random address tag */ 324 + srandom(time(NULL)); 325 + 364 326 if (!(hwcaps2 & HWCAP2_MTE)) 365 327 ksft_exit_skip("MTE features unavailable\n"); 328 + 329 + mtefar_support = !!(hwcaps3 & HWCAP3_MTE_FAR); 366 330 367 331 /* Get current mte mode */ 368 332 ret = prctl(PR_GET_TAGGED_ADDR_CTRL, en, 0, 0, 0);
+5 -1
tools/testing/selftests/arm64/mte/mte_common_util.h
··· 37 37 }; 38 38 39 39 extern struct mte_fault_cxt cur_mte_cxt; 40 + extern bool mtefar_support; 40 41 41 42 /* MTE utility functions */ 42 43 void mte_default_handler(int signum, siginfo_t *si, void *uc); 43 - void mte_register_signal(int signal, void (*handler)(int, siginfo_t *, void *)); 44 + void mte_register_signal(int signal, void (*handler)(int, siginfo_t *, void *), 45 + bool export_tags); 44 46 void mte_wait_after_trig(void); 45 47 void *mte_allocate_memory(size_t size, int mem_type, int mapping, bool tags); 46 48 void *mte_allocate_memory_tag_range(size_t size, int mem_type, int mapping, ··· 56 54 size_t range_before, size_t range_after); 57 55 void *mte_insert_tags(void *ptr, size_t size); 58 56 void mte_clear_tags(void *ptr, size_t size); 57 + void *mte_insert_atag(void *ptr); 58 + void *mte_clear_atag(void *ptr); 59 59 int mte_default_setup(void); 60 60 void mte_restore_setup(void); 61 61 int mte_switch_mode(int mte_option, unsigned long incl_mask);
+8
tools/testing/selftests/arm64/mte/mte_def.h
··· 42 42 #define MT_TAG_COUNT 16 43 43 #define MT_INCLUDE_TAG_MASK 0xFFFF 44 44 #define MT_EXCLUDE_TAG_MASK 0x0 45 + #define MT_ATAG_SHIFT 60 46 + #define MT_ATAG_MASK 0xFUL 45 47 46 48 #define MT_ALIGN_GRANULE (MT_GRANULE_SIZE - 1) 47 49 #define MT_CLEAR_TAG(x) ((x) & ~(MT_TAG_MASK << MT_TAG_SHIFT)) 48 50 #define MT_SET_TAG(x, y) ((x) | (y << MT_TAG_SHIFT)) 49 51 #define MT_FETCH_TAG(x) ((x >> MT_TAG_SHIFT) & (MT_TAG_MASK)) 50 52 #define MT_ALIGN_UP(x) ((x + MT_ALIGN_GRANULE) & ~(MT_ALIGN_GRANULE)) 53 + 54 + #define MT_CLEAR_ATAG(x) ((x) & ~(MT_TAG_MASK << MT_ATAG_SHIFT)) 55 + #define MT_SET_ATAG(x, y) ((x) | (((y) & MT_ATAG_MASK) << MT_ATAG_SHIFT)) 56 + #define MT_FETCH_ATAG(x) ((x >> MT_ATAG_SHIFT) & (MT_ATAG_MASK)) 57 + 58 + #define MT_CLEAR_TAGS(x) (MT_CLEAR_ATAG(MT_CLEAR_TAG(x))) 51 59 52 60 #define MT_PSTATE_TCO_SHIFT 25 53 61 #define MT_PSTATE_TCO_MASK ~(0x1 << MT_PSTATE_TCO_SHIFT)
+2 -2
tools/testing/selftests/kvm/arm64/debug-exceptions.c
··· 140 140 141 141 static void enable_monitor_debug_exceptions(void) 142 142 { 143 - uint32_t mdscr; 143 + uint64_t mdscr; 144 144 145 145 asm volatile("msr daifclr, #8"); 146 146 ··· 223 223 224 224 static void install_ss(void) 225 225 { 226 - uint32_t mdscr; 226 + uint64_t mdscr; 227 227 228 228 asm volatile("msr daifclr, #8"); 229 229