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

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

Pull arm64 festive updates from Will Deacon:
"In the end, we ended up with quite a lot more than I expected:

- Support for ARMv8.3 Pointer Authentication in userspace (CRIU and
kernel-side support to come later)

- Support for per-thread stack canaries, pending an update to GCC
that is currently undergoing review

- Support for kexec_file_load(), which permits secure boot of a kexec
payload but also happens to improve the performance of kexec
dramatically because we can avoid the sucky purgatory code from
userspace. Kdump will come later (requires updates to libfdt).

- Optimisation of our dynamic CPU feature framework, so that all
detected features are enabled via a single stop_machine()
invocation

- KPTI whitelisting of Cortex-A CPUs unaffected by Meltdown, so that
they can benefit from global TLB entries when KASLR is not in use

- 52-bit virtual addressing for userspace (kernel remains 48-bit)

- Patch in LSE atomics for per-cpu atomic operations

- Custom preempt.h implementation to avoid unconditional calls to
preempt_schedule() from preempt_enable()

- Support for the new 'SB' Speculation Barrier instruction

- Vectorised implementation of XOR checksumming and CRC32
optimisations

- Workaround for Cortex-A76 erratum #1165522

- Improved compatibility with Clang/LLD

- Support for TX2 system PMUS for profiling the L3 cache and DMC

- Reflect read-only permissions in the linear map by default

- Ensure MMIO reads are ordered with subsequent calls to Xdelay()

- Initial support for memory hotplug

- Tweak the threshold when we invalidate the TLB by-ASID, so that
mremap() performance is improved for ranges spanning multiple PMDs.

- Minor refactoring and cleanups"

* tag 'arm64-upstream' of git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux: (125 commits)
arm64: kaslr: print PHYS_OFFSET in dump_kernel_offset()
arm64: sysreg: Use _BITUL() when defining register bits
arm64: cpufeature: Rework ptr auth hwcaps using multi_entry_cap_matches
arm64: cpufeature: Reduce number of pointer auth CPU caps from 6 to 4
arm64: docs: document pointer authentication
arm64: ptr auth: Move per-thread keys from thread_info to thread_struct
arm64: enable pointer authentication
arm64: add prctl control for resetting ptrauth keys
arm64: perf: strip PAC when unwinding userspace
arm64: expose user PAC bit positions via ptrace
arm64: add basic pointer authentication support
arm64/cpufeature: detect pointer authentication
arm64: Don't trap host pointer auth use to EL2
arm64/kvm: hide ptrauth from guests
arm64/kvm: consistently handle host HCR_EL2 flags
arm64: add pointer authentication register bits
arm64: add comments about EC exception levels
arm64: perf: Treat EXCLUDE_EL* bit definitions as unsigned
arm64: kpti: Whitelist Cortex-A CPUs that don't implement the CSV3 field
arm64: enable per-task stack canaries
...

+4288 -1198
+8
Documentation/arm64/booting.txt
··· 205 205 ICC_SRE_EL2.SRE (bit 0) must be initialised to 0b0. 206 206 - The DT or ACPI tables must describe a GICv2 interrupt controller. 207 207 208 + For CPUs with pointer authentication functionality: 209 + - If EL3 is present: 210 + SCR_EL3.APK (bit 16) must be initialised to 0b1 211 + SCR_EL3.API (bit 17) must be initialised to 0b1 212 + - If the kernel is entered at EL1: 213 + HCR_EL2.APK (bit 40) must be initialised to 0b1 214 + HCR_EL2.API (bit 41) must be initialised to 0b1 215 + 208 216 The requirements described above for CPU mode, caches, MMUs, architected 209 217 timers, coherency and system registers apply to all CPUs. All CPUs must 210 218 enter the kernel in the same exception level.
+8
Documentation/arm64/cpu-feature-registers.txt
··· 184 184 x--------------------------------------------------x 185 185 | Name | bits | visible | 186 186 |--------------------------------------------------| 187 + | GPI | [31-28] | y | 188 + |--------------------------------------------------| 189 + | GPA | [27-24] | y | 190 + |--------------------------------------------------| 187 191 | LRCPC | [23-20] | y | 188 192 |--------------------------------------------------| 189 193 | FCMA | [19-16] | y | 190 194 |--------------------------------------------------| 191 195 | JSCVT | [15-12] | y | 196 + |--------------------------------------------------| 197 + | API | [11-8] | y | 198 + |--------------------------------------------------| 199 + | APA | [7-4] | y | 192 200 |--------------------------------------------------| 193 201 | DPB | [3-0] | y | 194 202 x--------------------------------------------------x
+12
Documentation/arm64/elf_hwcaps.txt
··· 182 182 HWCAP_SSBS 183 183 184 184 Functionality implied by ID_AA64PFR1_EL1.SSBS == 0b0010. 185 + 186 + HWCAP_PACA 187 + 188 + Functionality implied by ID_AA64ISAR1_EL1.APA == 0b0001 or 189 + ID_AA64ISAR1_EL1.API == 0b0001, as described by 190 + Documentation/arm64/pointer-authentication.txt. 191 + 192 + HWCAP_PACG 193 + 194 + Functionality implied by ID_AA64ISAR1_EL1.GPA == 0b0001 or 195 + ID_AA64ISAR1_EL1.GPI == 0b0001, as described by 196 + Documentation/arm64/pointer-authentication.txt.
+88
Documentation/arm64/pointer-authentication.txt
··· 1 + Pointer authentication in AArch64 Linux 2 + ======================================= 3 + 4 + Author: Mark Rutland <mark.rutland@arm.com> 5 + Date: 2017-07-19 6 + 7 + This document briefly describes the provision of pointer authentication 8 + functionality in AArch64 Linux. 9 + 10 + 11 + Architecture overview 12 + --------------------- 13 + 14 + The ARMv8.3 Pointer Authentication extension adds primitives that can be 15 + used to mitigate certain classes of attack where an attacker can corrupt 16 + the contents of some memory (e.g. the stack). 17 + 18 + The extension uses a Pointer Authentication Code (PAC) to determine 19 + whether pointers have been modified unexpectedly. A PAC is derived from 20 + a pointer, another value (such as the stack pointer), and a secret key 21 + held in system registers. 22 + 23 + The extension adds instructions to insert a valid PAC into a pointer, 24 + and to verify/remove the PAC from a pointer. The PAC occupies a number 25 + of high-order bits of the pointer, which varies dependent on the 26 + configured virtual address size and whether pointer tagging is in use. 27 + 28 + A subset of these instructions have been allocated from the HINT 29 + encoding space. In the absence of the extension (or when disabled), 30 + these instructions behave as NOPs. Applications and libraries using 31 + these instructions operate correctly regardless of the presence of the 32 + extension. 33 + 34 + The extension provides five separate keys to generate PACs - two for 35 + instruction addresses (APIAKey, APIBKey), two for data addresses 36 + (APDAKey, APDBKey), and one for generic authentication (APGAKey). 37 + 38 + 39 + Basic support 40 + ------------- 41 + 42 + When CONFIG_ARM64_PTR_AUTH is selected, and relevant HW support is 43 + present, the kernel will assign random key values to each process at 44 + exec*() time. The keys are shared by all threads within the process, and 45 + are preserved across fork(). 46 + 47 + Presence of address authentication functionality is advertised via 48 + HWCAP_PACA, and generic authentication functionality via HWCAP_PACG. 49 + 50 + The number of bits that the PAC occupies in a pointer is 55 minus the 51 + virtual address size configured by the kernel. For example, with a 52 + virtual address size of 48, the PAC is 7 bits wide. 53 + 54 + Recent versions of GCC can compile code with APIAKey-based return 55 + address protection when passed the -msign-return-address option. This 56 + uses instructions in the HINT space (unless -march=armv8.3-a or higher 57 + is also passed), and such code can run on systems without the pointer 58 + authentication extension. 59 + 60 + In addition to exec(), keys can also be reinitialized to random values 61 + using the PR_PAC_RESET_KEYS prctl. A bitmask of PR_PAC_APIAKEY, 62 + PR_PAC_APIBKEY, PR_PAC_APDAKEY, PR_PAC_APDBKEY and PR_PAC_APGAKEY 63 + specifies which keys are to be reinitialized; specifying 0 means "all 64 + keys". 65 + 66 + 67 + Debugging 68 + --------- 69 + 70 + When CONFIG_ARM64_PTR_AUTH is selected, and HW support for address 71 + authentication is present, the kernel will expose the position of TTBR0 72 + PAC bits in the NT_ARM_PAC_MASK regset (struct user_pac_mask), which 73 + userspace can acquire via PTRACE_GETREGSET. 74 + 75 + The regset is exposed only when HWCAP_PACA is set. Separate masks are 76 + exposed for data pointers and instruction pointers, as the set of PAC 77 + bits can vary between the two. Note that the masks apply to TTBR0 78 + addresses, and are not valid to apply to TTBR1 addresses (e.g. kernel 79 + pointers). 80 + 81 + 82 + Virtualization 83 + -------------- 84 + 85 + Pointer authentication is not currently supported in KVM guests. KVM 86 + will mask the feature bits from ID_AA64ISAR1_EL1, and attempted use of 87 + the feature will result in an UNDEFINED exception being injected into 88 + the guest.
+1
Documentation/arm64/silicon-errata.txt
··· 57 57 | ARM | Cortex-A73 | #858921 | ARM64_ERRATUM_858921 | 58 58 | ARM | Cortex-A55 | #1024718 | ARM64_ERRATUM_1024718 | 59 59 | ARM | Cortex-A76 | #1188873 | ARM64_ERRATUM_1188873 | 60 + | ARM | Cortex-A76 | #1165522 | ARM64_ERRATUM_1165522 | 60 61 | ARM | Cortex-A76 | #1286807 | ARM64_ERRATUM_1286807 | 61 62 | ARM | MMU-500 | #841119,#826419 | N/A | 62 63 | | | | |
+41
Documentation/perf/thunderx2-pmu.txt
··· 1 + Cavium ThunderX2 SoC Performance Monitoring Unit (PMU UNCORE) 2 + ============================================================= 3 + 4 + The ThunderX2 SoC PMU consists of independent, system-wide, per-socket 5 + PMUs such as the Level 3 Cache (L3C) and DDR4 Memory Controller (DMC). 6 + 7 + The DMC has 8 interleaved channels and the L3C has 16 interleaved tiles. 8 + Events are counted for the default channel (i.e. channel 0) and prorated 9 + to the total number of channels/tiles. 10 + 11 + The DMC and L3C support up to 4 counters. Counters are independently 12 + programmable and can be started and stopped individually. Each counter 13 + can be set to a different event. Counters are 32-bit and do not support 14 + an overflow interrupt; they are read every 2 seconds. 15 + 16 + PMU UNCORE (perf) driver: 17 + 18 + The thunderx2_pmu driver registers per-socket perf PMUs for the DMC and 19 + L3C devices. Each PMU can be used to count up to 4 events 20 + simultaneously. The PMUs provide a description of their available events 21 + and configuration options under sysfs, see 22 + /sys/devices/uncore_<l3c_S/dmc_S/>; S is the socket id. 23 + 24 + The driver does not support sampling, therefore "perf record" will not 25 + work. Per-task perf sessions are also not supported. 26 + 27 + Examples: 28 + 29 + # perf stat -a -e uncore_dmc_0/cnt_cycles/ sleep 1 30 + 31 + # perf stat -a -e \ 32 + uncore_dmc_0/cnt_cycles/,\ 33 + uncore_dmc_0/data_transfers/,\ 34 + uncore_dmc_0/read_txns/,\ 35 + uncore_dmc_0/write_txns/ sleep 1 36 + 37 + # perf stat -a -e \ 38 + uncore_l3c_0/read_request/,\ 39 + uncore_l3c_0/read_hit/,\ 40 + uncore_l3c_0/inv_request/,\ 41 + uncore_l3c_0/inv_hit/ sleep 1
+1 -1
arch/arm/include/asm/kvm_host.h
··· 285 285 286 286 struct kvm_vcpu *kvm_mpidr_to_vcpu(struct kvm *kvm, unsigned long mpidr); 287 287 288 - static inline bool kvm_arch_check_sve_has_vhe(void) { return true; } 288 + static inline bool kvm_arch_requires_vhe(void) { return false; } 289 289 static inline void kvm_arch_hardware_unsetup(void) {} 290 290 static inline void kvm_arch_sync_events(struct kvm *kvm) {} 291 291 static inline void kvm_arch_vcpu_uninit(struct kvm_vcpu *vcpu) {}
+129 -2
arch/arm64/Kconfig
··· 261 261 config HAVE_GENERIC_GUP 262 262 def_bool y 263 263 264 + config ARCH_ENABLE_MEMORY_HOTPLUG 265 + def_bool y 266 + 264 267 config SMP 265 268 def_bool y 266 269 ··· 277 274 int 278 275 default 2 if ARM64_16K_PAGES && ARM64_VA_BITS_36 279 276 default 2 if ARM64_64K_PAGES && ARM64_VA_BITS_42 280 - default 3 if ARM64_64K_PAGES && ARM64_VA_BITS_48 277 + default 3 if ARM64_64K_PAGES && (ARM64_VA_BITS_48 || ARM64_USER_VA_BITS_52) 281 278 default 3 if ARM64_4K_PAGES && ARM64_VA_BITS_39 282 279 default 3 if ARM64_16K_PAGES && ARM64_VA_BITS_47 283 280 default 4 if !ARM64_64K_PAGES && ARM64_VA_BITS_48 ··· 316 313 317 314 menu "ARM errata workarounds via the alternatives framework" 318 315 316 + config ARM64_WORKAROUND_CLEAN_CACHE 317 + def_bool n 318 + 319 319 config ARM64_ERRATUM_826319 320 320 bool "Cortex-A53: 826319: System might deadlock if a write cannot complete until read data is accepted" 321 321 default y 322 + select ARM64_WORKAROUND_CLEAN_CACHE 322 323 help 323 324 This option adds an alternative code sequence to work around ARM 324 325 erratum 826319 on Cortex-A53 parts up to r0p2 with an AMBA 4 ACE or ··· 344 337 config ARM64_ERRATUM_827319 345 338 bool "Cortex-A53: 827319: Data cache clean instructions might cause overlapping transactions to the interconnect" 346 339 default y 340 + select ARM64_WORKAROUND_CLEAN_CACHE 347 341 help 348 342 This option adds an alternative code sequence to work around ARM 349 343 erratum 827319 on Cortex-A53 parts up to r0p2 with an AMBA 5 CHI ··· 366 358 config ARM64_ERRATUM_824069 367 359 bool "Cortex-A53: 824069: Cache line might not be marked as clean after a CleanShared snoop" 368 360 default y 361 + select ARM64_WORKAROUND_CLEAN_CACHE 369 362 help 370 363 This option adds an alternative code sequence to work around ARM 371 364 erratum 824069 on Cortex-A53 parts up to r0p2 when it is connected ··· 389 380 config ARM64_ERRATUM_819472 390 381 bool "Cortex-A53: 819472: Store exclusive instructions might cause data corruption" 391 382 default y 383 + select ARM64_WORKAROUND_CLEAN_CACHE 392 384 help 393 385 This option adds an alternative code sequence to work around ARM 394 386 erratum 819472 on Cortex-A53 parts up to r0p1 with an L2 cache ··· 504 494 Affected Cortex-A76 cores (r0p0, r1p0, r2p0) could cause 505 495 register corruption when accessing the timer registers from 506 496 AArch32 userspace. 497 + 498 + If unsure, say Y. 499 + 500 + config ARM64_ERRATUM_1165522 501 + bool "Cortex-A76: Speculative AT instruction using out-of-context translation regime could cause subsequent request to generate an incorrect translation" 502 + default y 503 + help 504 + This option adds work arounds for ARM Cortex-A76 erratum 1165522 505 + 506 + Affected Cortex-A76 cores (r0p0, r1p0, r2p0) could end-up with 507 + corrupted TLBs by speculating an AT instruction during a guest 508 + context switch. 507 509 508 510 If unsure, say Y. 509 511 ··· 722 700 config ARM64_VA_BITS_48 723 701 bool "48-bit" 724 702 703 + config ARM64_USER_VA_BITS_52 704 + bool "52-bit (user)" 705 + depends on ARM64_64K_PAGES && (ARM64_PAN || !ARM64_SW_TTBR0_PAN) 706 + help 707 + Enable 52-bit virtual addressing for userspace when explicitly 708 + requested via a hint to mmap(). The kernel will continue to 709 + use 48-bit virtual addresses for its own mappings. 710 + 711 + NOTE: Enabling 52-bit virtual addressing in conjunction with 712 + ARMv8.3 Pointer Authentication will result in the PAC being 713 + reduced from 7 bits to 3 bits, which may have a significant 714 + impact on its susceptibility to brute-force attacks. 715 + 716 + If unsure, select 48-bit virtual addressing instead. 717 + 725 718 endchoice 719 + 720 + config ARM64_FORCE_52BIT 721 + bool "Force 52-bit virtual addresses for userspace" 722 + depends on ARM64_USER_VA_BITS_52 && EXPERT 723 + help 724 + For systems with 52-bit userspace VAs enabled, the kernel will attempt 725 + to maintain compatibility with older software by providing 48-bit VAs 726 + unless a hint is supplied to mmap. 727 + 728 + This configuration option disables the 48-bit compatibility logic, and 729 + forces all userspace addresses to be 52-bit on HW that supports it. One 730 + should only enable this configuration option for stress testing userspace 731 + memory management code. If unsure say N here. 726 732 727 733 config ARM64_VA_BITS 728 734 int ··· 758 708 default 39 if ARM64_VA_BITS_39 759 709 default 42 if ARM64_VA_BITS_42 760 710 default 47 if ARM64_VA_BITS_47 761 - default 48 if ARM64_VA_BITS_48 711 + default 48 if ARM64_VA_BITS_48 || ARM64_USER_VA_BITS_52 762 712 763 713 choice 764 714 prompt "Physical address space size" ··· 933 883 but it is independent of the system firmware. And like a reboot 934 884 you can start any kernel with it, not just Linux. 935 885 886 + config KEXEC_FILE 887 + bool "kexec file based system call" 888 + select KEXEC_CORE 889 + help 890 + This is new version of kexec system call. This system call is 891 + file based and takes file descriptors as system call argument 892 + for kernel and initramfs as opposed to list of segments as 893 + accepted by previous system call. 894 + 895 + config KEXEC_VERIFY_SIG 896 + bool "Verify kernel signature during kexec_file_load() syscall" 897 + depends on KEXEC_FILE 898 + help 899 + Select this option to verify a signature with loaded kernel 900 + image. If configured, any attempt of loading a image without 901 + valid signature will fail. 902 + 903 + In addition to that option, you need to enable signature 904 + verification for the corresponding kernel image type being 905 + loaded in order for this to work. 906 + 907 + config KEXEC_IMAGE_VERIFY_SIG 908 + bool "Enable Image signature verification support" 909 + default y 910 + depends on KEXEC_VERIFY_SIG 911 + depends on EFI && SIGNED_PE_FILE_VERIFICATION 912 + help 913 + Enable Image signature verification support. 914 + 915 + comment "Support for PE file signature verification disabled" 916 + depends on KEXEC_VERIFY_SIG 917 + depends on !EFI || !SIGNED_PE_FILE_VERIFICATION 918 + 936 919 config CRASH_DUMP 937 920 bool "Build kdump crash kernel" 938 921 help ··· 1065 982 by speculative loads. 1066 983 1067 984 If unsure, say Y. 985 + 986 + config RODATA_FULL_DEFAULT_ENABLED 987 + bool "Apply r/o permissions of VM areas also to their linear aliases" 988 + default y 989 + help 990 + Apply read-only attributes of VM areas to the linear alias of 991 + the backing pages as well. This prevents code or read-only data 992 + from being modified (inadvertently or intentionally) via another 993 + mapping of the same memory page. This additional enhancement can 994 + be turned off at runtime by passing rodata=[off|on] (and turned on 995 + with rodata=full if this option is set to 'n') 996 + 997 + This requires the linear region to be mapped down to pages, 998 + which may adversely affect performance in some cases. 1068 999 1069 1000 menuconfig ARMV8_DEPRECATED 1070 1001 bool "Emulate deprecated/obsolete ARMv8 instructions" ··· 1285 1188 1286 1189 endmenu 1287 1190 1191 + menu "ARMv8.3 architectural features" 1192 + 1193 + config ARM64_PTR_AUTH 1194 + bool "Enable support for pointer authentication" 1195 + default y 1196 + help 1197 + Pointer authentication (part of the ARMv8.3 Extensions) provides 1198 + instructions for signing and authenticating pointers against secret 1199 + keys, which can be used to mitigate Return Oriented Programming (ROP) 1200 + and other attacks. 1201 + 1202 + This option enables these instructions at EL0 (i.e. for userspace). 1203 + 1204 + Choosing this option will cause the kernel to initialise secret keys 1205 + for each process at exec() time, with these keys being 1206 + context-switched along with the process. 1207 + 1208 + The feature is detected at runtime. If the feature is not present in 1209 + hardware it will not be advertised to userspace nor will it be 1210 + enabled. 1211 + 1212 + endmenu 1213 + 1288 1214 config ARM64_SVE 1289 1215 bool "ARM Scalable Vector Extension support" 1290 1216 default y ··· 1391 1271 When this option is not set, the module region will be randomized over 1392 1272 a limited range that contains the [_stext, _etext] interval of the 1393 1273 core kernel, so branch relocations are always in range. 1274 + 1275 + config CC_HAVE_STACKPROTECTOR_SYSREG 1276 + def_bool $(cc-option,-mstack-protector-guard=sysreg -mstack-protector-guard-reg=sp_el0 -mstack-protector-guard-offset=0) 1277 + 1278 + config STACKPROTECTOR_PER_TASK 1279 + def_bool y 1280 + depends on STACKPROTECTOR && CC_HAVE_STACKPROTECTOR_SYSREG 1394 1281 1395 1282 endmenu 1396 1283
+11 -1
arch/arm64/Makefile
··· 18 18 # Pass --no-apply-dynamic-relocs to restore pre-binutils-2.27 behaviour 19 19 # for relative relocs, since this leads to better Image compression 20 20 # with the relocation offsets always being zero. 21 - LDFLAGS_vmlinux += -pie -shared -Bsymbolic \ 21 + LDFLAGS_vmlinux += -shared -Bsymbolic -z notext -z norelro \ 22 22 $(call ld-option, --no-apply-dynamic-relocs) 23 23 endif 24 24 ··· 55 55 56 56 KBUILD_CFLAGS += $(call cc-option,-mabi=lp64) 57 57 KBUILD_AFLAGS += $(call cc-option,-mabi=lp64) 58 + 59 + ifeq ($(CONFIG_STACKPROTECTOR_PER_TASK),y) 60 + prepare: stack_protector_prepare 61 + stack_protector_prepare: prepare0 62 + $(eval KBUILD_CFLAGS += -mstack-protector-guard=sysreg \ 63 + -mstack-protector-guard-reg=sp_el0 \ 64 + -mstack-protector-guard-offset=$(shell \ 65 + awk '{if ($$2 == "TSK_STACK_CANARY") print $$3;}' \ 66 + include/generated/asm-offsets.h)) 67 + endif 58 68 59 69 ifeq ($(CONFIG_CPU_BIG_ENDIAN), y) 60 70 KBUILD_CPPFLAGS += -mbig-endian
-2
arch/arm64/include/asm/Kbuild
··· 14 14 generic-y += mcs_spinlock.h 15 15 generic-y += mm-arch-hooks.h 16 16 generic-y += msi.h 17 - generic-y += preempt.h 18 17 generic-y += qrwlock.h 19 18 generic-y += qspinlock.h 20 19 generic-y += rwsem.h ··· 26 27 generic-y += unaligned.h 27 28 generic-y += user.h 28 29 generic-y += vga.h 29 - generic-y += xor.h
+15 -4
arch/arm64/include/asm/acpi.h
··· 22 22 #include <asm/tlbflush.h> 23 23 24 24 /* Macros for consistency checks of the GICC subtable of MADT */ 25 - #define ACPI_MADT_GICC_LENGTH \ 26 - (acpi_gbl_FADT.header.revision < 6 ? 76 : 80) 25 + 26 + /* 27 + * MADT GICC minimum length refers to the MADT GICC structure table length as 28 + * defined in the earliest ACPI version supported on arm64, ie ACPI 5.1. 29 + * 30 + * The efficiency_class member was added to the 31 + * struct acpi_madt_generic_interrupt to represent the MADT GICC structure 32 + * "Processor Power Efficiency Class" field, added in ACPI 6.0 whose offset 33 + * is therefore used to delimit the MADT GICC structure minimum length 34 + * appropriately. 35 + */ 36 + #define ACPI_MADT_GICC_MIN_LENGTH ACPI_OFFSET( \ 37 + struct acpi_madt_generic_interrupt, efficiency_class) 27 38 28 39 #define BAD_MADT_GICC_ENTRY(entry, end) \ 29 - (!(entry) || (entry)->header.length != ACPI_MADT_GICC_LENGTH || \ 30 - (unsigned long)(entry) + ACPI_MADT_GICC_LENGTH > (end)) 40 + (!(entry) || (entry)->header.length < ACPI_MADT_GICC_MIN_LENGTH || \ 41 + (unsigned long)(entry) + (entry)->header.length > (end)) 31 42 32 43 /* Basic configuration for ACPI */ 33 44 #ifdef CONFIG_ACPI
+26
arch/arm64/include/asm/asm-prototypes.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 + #ifndef __ASM_PROTOTYPES_H 3 + #define __ASM_PROTOTYPES_H 4 + /* 5 + * CONFIG_MODEVERIONS requires a C declaration to generate the appropriate CRC 6 + * for each symbol. Since commit: 7 + * 8 + * 4efca4ed05cbdfd1 ("kbuild: modversions for EXPORT_SYMBOL() for asm") 9 + * 10 + * ... kbuild will automatically pick these up from <asm/asm-prototypes.h> and 11 + * feed this to genksyms when building assembly files. 12 + */ 13 + #include <linux/arm-smccc.h> 14 + 15 + #include <asm/ftrace.h> 16 + #include <asm/page.h> 17 + #include <asm/string.h> 18 + #include <asm/uaccess.h> 19 + 20 + #include <asm-generic/asm-prototypes.h> 21 + 22 + long long __ashlti3(long long a, int b); 23 + long long __ashrti3(long long a, int b); 24 + long long __lshrti3(long long a, int b); 25 + 26 + #endif /* __ASM_PROTOTYPES_H */
+69 -21
arch/arm64/include/asm/assembler.h
··· 23 23 #ifndef __ASM_ASSEMBLER_H 24 24 #define __ASM_ASSEMBLER_H 25 25 26 + #include <asm-generic/export.h> 27 + 26 28 #include <asm/asm-offsets.h> 27 29 #include <asm/cpufeature.h> 28 30 #include <asm/debug-monitors.h> ··· 122 120 */ 123 121 .macro csdb 124 122 hint #20 123 + .endm 124 + 125 + /* 126 + * Speculation barrier 127 + */ 128 + .macro sb 129 + alternative_if_not ARM64_HAS_SB 130 + dsb nsh 131 + isb 132 + alternative_else 133 + SB_BARRIER_INSN 134 + nop 135 + alternative_endif 125 136 .endm 126 137 127 138 /* ··· 357 342 .endm 358 343 359 344 /* 360 - * tcr_set_idmap_t0sz - update TCR.T0SZ so that we can load the ID map 345 + * tcr_set_t0sz - update TCR.T0SZ so that we can load the ID map 361 346 */ 362 - .macro tcr_set_idmap_t0sz, valreg, tmpreg 363 - ldr_l \tmpreg, idmap_t0sz 364 - bfi \valreg, \tmpreg, #TCR_T0SZ_OFFSET, #TCR_TxSZ_WIDTH 347 + .macro tcr_set_t0sz, valreg, t0sz 348 + bfi \valreg, \t0sz, #TCR_T0SZ_OFFSET, #TCR_TxSZ_WIDTH 365 349 .endm 366 350 367 351 /* ··· 391 377 * size: size of the region 392 378 * Corrupts: kaddr, size, tmp1, tmp2 393 379 */ 380 + .macro __dcache_op_workaround_clean_cache, op, kaddr 381 + alternative_if_not ARM64_WORKAROUND_CLEAN_CACHE 382 + dc \op, \kaddr 383 + alternative_else 384 + dc civac, \kaddr 385 + alternative_endif 386 + .endm 387 + 394 388 .macro dcache_by_line_op op, domain, kaddr, size, tmp1, tmp2 395 389 dcache_line_size \tmp1, \tmp2 396 390 add \size, \kaddr, \size 397 391 sub \tmp2, \tmp1, #1 398 392 bic \kaddr, \kaddr, \tmp2 399 393 9998: 400 - .if (\op == cvau || \op == cvac) 401 - alternative_if_not ARM64_WORKAROUND_CLEAN_CACHE 402 - dc \op, \kaddr 403 - alternative_else 404 - dc civac, \kaddr 405 - alternative_endif 406 - .elseif (\op == cvap) 407 - alternative_if ARM64_HAS_DCPOP 408 - sys 3, c7, c12, 1, \kaddr // dc cvap 409 - alternative_else 410 - dc cvac, \kaddr 411 - alternative_endif 394 + .ifc \op, cvau 395 + __dcache_op_workaround_clean_cache \op, \kaddr 396 + .else 397 + .ifc \op, cvac 398 + __dcache_op_workaround_clean_cache \op, \kaddr 399 + .else 400 + .ifc \op, cvap 401 + sys 3, c7, c12, 1, \kaddr // dc cvap 412 402 .else 413 403 dc \op, \kaddr 404 + .endif 405 + .endif 414 406 .endif 415 407 add \kaddr, \kaddr, \tmp1 416 408 cmp \kaddr, \size ··· 497 477 #else 498 478 #define NOKPROBE(x) 499 479 #endif 480 + 481 + #ifdef CONFIG_KASAN 482 + #define EXPORT_SYMBOL_NOKASAN(name) 483 + #else 484 + #define EXPORT_SYMBOL_NOKASAN(name) EXPORT_SYMBOL(name) 485 + #endif 486 + 500 487 /* 501 488 * Emit a 64-bit absolute little endian symbol reference in a way that 502 489 * ensures that it will be resolved at build time, even when building a ··· 540 513 */ 541 514 .macro get_thread_info, rd 542 515 mrs \rd, sp_el0 516 + .endm 517 + 518 + /* 519 + * Offset ttbr1 to allow for 48-bit kernel VAs set with 52-bit PTRS_PER_PGD. 520 + * orr is used as it can cover the immediate value (and is idempotent). 521 + * In future this may be nop'ed out when dealing with 52-bit kernel VAs. 522 + * ttbr: Value of ttbr to set, modified. 523 + */ 524 + .macro offset_ttbr1, ttbr 525 + #ifdef CONFIG_ARM64_USER_VA_BITS_52 526 + orr \ttbr, \ttbr, #TTBR1_BADDR_4852_OFFSET 527 + #endif 528 + .endm 529 + 530 + /* 531 + * Perform the reverse of offset_ttbr1. 532 + * bic is used as it can cover the immediate value and, in future, won't need 533 + * to be nop'ed out when dealing with 52-bit kernel VAs. 534 + */ 535 + .macro restore_ttbr1, ttbr 536 + #ifdef CONFIG_ARM64_USER_VA_BITS_52 537 + bic \ttbr, \ttbr, #TTBR1_BADDR_4852_OFFSET 538 + #endif 543 539 .endm 544 540 545 541 /* ··· 722 672 .macro if_will_cond_yield_neon 723 673 #ifdef CONFIG_PREEMPT 724 674 get_thread_info x0 725 - ldr w1, [x0, #TSK_TI_PREEMPT] 726 - ldr x0, [x0, #TSK_TI_FLAGS] 727 - cmp w1, #PREEMPT_DISABLE_OFFSET 728 - csel x0, x0, xzr, eq 729 - tbnz x0, #TIF_NEED_RESCHED, .Lyield_\@ // needs rescheduling? 675 + ldr x0, [x0, #TSK_TI_PREEMPT] 676 + sub x0, x0, #PREEMPT_DISABLE_OFFSET 677 + cbz x0, .Lyield_\@ 730 678 /* fall through to endif_yield_neon */ 731 679 .subsection 1 732 680 .Lyield_\@ :
+36 -27
arch/arm64/include/asm/atomic_ll_sc.h
··· 248 248 } 249 249 __LL_SC_EXPORT(atomic64_dec_if_positive); 250 250 251 - #define __CMPXCHG_CASE(w, sz, name, mb, acq, rel, cl) \ 252 - __LL_SC_INLINE unsigned long \ 253 - __LL_SC_PREFIX(__cmpxchg_case_##name(volatile void *ptr, \ 254 - unsigned long old, \ 255 - unsigned long new)) \ 251 + #define __CMPXCHG_CASE(w, sfx, name, sz, mb, acq, rel, cl) \ 252 + __LL_SC_INLINE u##sz \ 253 + __LL_SC_PREFIX(__cmpxchg_case_##name##sz(volatile void *ptr, \ 254 + unsigned long old, \ 255 + u##sz new)) \ 256 256 { \ 257 - unsigned long tmp, oldval; \ 257 + unsigned long tmp; \ 258 + u##sz oldval; \ 259 + \ 260 + /* \ 261 + * Sub-word sizes require explicit casting so that the compare \ 262 + * part of the cmpxchg doesn't end up interpreting non-zero \ 263 + * upper bits of the register containing "old". \ 264 + */ \ 265 + if (sz < 32) \ 266 + old = (u##sz)old; \ 258 267 \ 259 268 asm volatile( \ 260 269 " prfm pstl1strm, %[v]\n" \ 261 - "1: ld" #acq "xr" #sz "\t%" #w "[oldval], %[v]\n" \ 270 + "1: ld" #acq "xr" #sfx "\t%" #w "[oldval], %[v]\n" \ 262 271 " eor %" #w "[tmp], %" #w "[oldval], %" #w "[old]\n" \ 263 272 " cbnz %" #w "[tmp], 2f\n" \ 264 - " st" #rel "xr" #sz "\t%w[tmp], %" #w "[new], %[v]\n" \ 273 + " st" #rel "xr" #sfx "\t%w[tmp], %" #w "[new], %[v]\n" \ 265 274 " cbnz %w[tmp], 1b\n" \ 266 275 " " #mb "\n" \ 267 276 "2:" \ 268 277 : [tmp] "=&r" (tmp), [oldval] "=&r" (oldval), \ 269 - [v] "+Q" (*(unsigned long *)ptr) \ 270 - : [old] "Lr" (old), [new] "r" (new) \ 278 + [v] "+Q" (*(u##sz *)ptr) \ 279 + : [old] "Kr" (old), [new] "r" (new) \ 271 280 : cl); \ 272 281 \ 273 282 return oldval; \ 274 283 } \ 275 - __LL_SC_EXPORT(__cmpxchg_case_##name); 284 + __LL_SC_EXPORT(__cmpxchg_case_##name##sz); 276 285 277 - __CMPXCHG_CASE(w, b, 1, , , , ) 278 - __CMPXCHG_CASE(w, h, 2, , , , ) 279 - __CMPXCHG_CASE(w, , 4, , , , ) 280 - __CMPXCHG_CASE( , , 8, , , , ) 281 - __CMPXCHG_CASE(w, b, acq_1, , a, , "memory") 282 - __CMPXCHG_CASE(w, h, acq_2, , a, , "memory") 283 - __CMPXCHG_CASE(w, , acq_4, , a, , "memory") 284 - __CMPXCHG_CASE( , , acq_8, , a, , "memory") 285 - __CMPXCHG_CASE(w, b, rel_1, , , l, "memory") 286 - __CMPXCHG_CASE(w, h, rel_2, , , l, "memory") 287 - __CMPXCHG_CASE(w, , rel_4, , , l, "memory") 288 - __CMPXCHG_CASE( , , rel_8, , , l, "memory") 289 - __CMPXCHG_CASE(w, b, mb_1, dmb ish, , l, "memory") 290 - __CMPXCHG_CASE(w, h, mb_2, dmb ish, , l, "memory") 291 - __CMPXCHG_CASE(w, , mb_4, dmb ish, , l, "memory") 292 - __CMPXCHG_CASE( , , mb_8, dmb ish, , l, "memory") 286 + __CMPXCHG_CASE(w, b, , 8, , , , ) 287 + __CMPXCHG_CASE(w, h, , 16, , , , ) 288 + __CMPXCHG_CASE(w, , , 32, , , , ) 289 + __CMPXCHG_CASE( , , , 64, , , , ) 290 + __CMPXCHG_CASE(w, b, acq_, 8, , a, , "memory") 291 + __CMPXCHG_CASE(w, h, acq_, 16, , a, , "memory") 292 + __CMPXCHG_CASE(w, , acq_, 32, , a, , "memory") 293 + __CMPXCHG_CASE( , , acq_, 64, , a, , "memory") 294 + __CMPXCHG_CASE(w, b, rel_, 8, , , l, "memory") 295 + __CMPXCHG_CASE(w, h, rel_, 16, , , l, "memory") 296 + __CMPXCHG_CASE(w, , rel_, 32, , , l, "memory") 297 + __CMPXCHG_CASE( , , rel_, 64, , , l, "memory") 298 + __CMPXCHG_CASE(w, b, mb_, 8, dmb ish, , l, "memory") 299 + __CMPXCHG_CASE(w, h, mb_, 16, dmb ish, , l, "memory") 300 + __CMPXCHG_CASE(w, , mb_, 32, dmb ish, , l, "memory") 301 + __CMPXCHG_CASE( , , mb_, 64, dmb ish, , l, "memory") 293 302 294 303 #undef __CMPXCHG_CASE 295 304
+24 -24
arch/arm64/include/asm/atomic_lse.h
··· 446 446 447 447 #define __LL_SC_CMPXCHG(op) __LL_SC_CALL(__cmpxchg_case_##op) 448 448 449 - #define __CMPXCHG_CASE(w, sz, name, mb, cl...) \ 450 - static inline unsigned long __cmpxchg_case_##name(volatile void *ptr, \ 451 - unsigned long old, \ 452 - unsigned long new) \ 449 + #define __CMPXCHG_CASE(w, sfx, name, sz, mb, cl...) \ 450 + static inline u##sz __cmpxchg_case_##name##sz(volatile void *ptr, \ 451 + u##sz old, \ 452 + u##sz new) \ 453 453 { \ 454 454 register unsigned long x0 asm ("x0") = (unsigned long)ptr; \ 455 - register unsigned long x1 asm ("x1") = old; \ 456 - register unsigned long x2 asm ("x2") = new; \ 455 + register u##sz x1 asm ("x1") = old; \ 456 + register u##sz x2 asm ("x2") = new; \ 457 457 \ 458 458 asm volatile(ARM64_LSE_ATOMIC_INSN( \ 459 459 /* LL/SC */ \ 460 - __LL_SC_CMPXCHG(name) \ 460 + __LL_SC_CMPXCHG(name##sz) \ 461 461 __nops(2), \ 462 462 /* LSE atomics */ \ 463 463 " mov " #w "30, %" #w "[old]\n" \ 464 - " cas" #mb #sz "\t" #w "30, %" #w "[new], %[v]\n" \ 464 + " cas" #mb #sfx "\t" #w "30, %" #w "[new], %[v]\n" \ 465 465 " mov %" #w "[ret], " #w "30") \ 466 466 : [ret] "+r" (x0), [v] "+Q" (*(unsigned long *)ptr) \ 467 467 : [old] "r" (x1), [new] "r" (x2) \ ··· 470 470 return x0; \ 471 471 } 472 472 473 - __CMPXCHG_CASE(w, b, 1, ) 474 - __CMPXCHG_CASE(w, h, 2, ) 475 - __CMPXCHG_CASE(w, , 4, ) 476 - __CMPXCHG_CASE(x, , 8, ) 477 - __CMPXCHG_CASE(w, b, acq_1, a, "memory") 478 - __CMPXCHG_CASE(w, h, acq_2, a, "memory") 479 - __CMPXCHG_CASE(w, , acq_4, a, "memory") 480 - __CMPXCHG_CASE(x, , acq_8, a, "memory") 481 - __CMPXCHG_CASE(w, b, rel_1, l, "memory") 482 - __CMPXCHG_CASE(w, h, rel_2, l, "memory") 483 - __CMPXCHG_CASE(w, , rel_4, l, "memory") 484 - __CMPXCHG_CASE(x, , rel_8, l, "memory") 485 - __CMPXCHG_CASE(w, b, mb_1, al, "memory") 486 - __CMPXCHG_CASE(w, h, mb_2, al, "memory") 487 - __CMPXCHG_CASE(w, , mb_4, al, "memory") 488 - __CMPXCHG_CASE(x, , mb_8, al, "memory") 473 + __CMPXCHG_CASE(w, b, , 8, ) 474 + __CMPXCHG_CASE(w, h, , 16, ) 475 + __CMPXCHG_CASE(w, , , 32, ) 476 + __CMPXCHG_CASE(x, , , 64, ) 477 + __CMPXCHG_CASE(w, b, acq_, 8, a, "memory") 478 + __CMPXCHG_CASE(w, h, acq_, 16, a, "memory") 479 + __CMPXCHG_CASE(w, , acq_, 32, a, "memory") 480 + __CMPXCHG_CASE(x, , acq_, 64, a, "memory") 481 + __CMPXCHG_CASE(w, b, rel_, 8, l, "memory") 482 + __CMPXCHG_CASE(w, h, rel_, 16, l, "memory") 483 + __CMPXCHG_CASE(w, , rel_, 32, l, "memory") 484 + __CMPXCHG_CASE(x, , rel_, 64, l, "memory") 485 + __CMPXCHG_CASE(w, b, mb_, 8, al, "memory") 486 + __CMPXCHG_CASE(w, h, mb_, 16, al, "memory") 487 + __CMPXCHG_CASE(w, , mb_, 32, al, "memory") 488 + __CMPXCHG_CASE(x, , mb_, 64, al, "memory") 489 489 490 490 #undef __LL_SC_CMPXCHG 491 491 #undef __CMPXCHG_CASE
+4
arch/arm64/include/asm/barrier.h
··· 34 34 #define psb_csync() asm volatile("hint #17" : : : "memory") 35 35 #define csdb() asm volatile("hint #20" : : : "memory") 36 36 37 + #define spec_bar() asm volatile(ALTERNATIVE("dsb nsh\nisb\n", \ 38 + SB_BARRIER_INSN"nop\n", \ 39 + ARM64_HAS_SB)) 40 + 37 41 #define mb() dsb(sy) 38 42 #define rmb() dsb(ld) 39 43 #define wmb() dsb(st)
+62 -62
arch/arm64/include/asm/cmpxchg.h
··· 30 30 * barrier case is generated as release+dmb for the former and 31 31 * acquire+release for the latter. 32 32 */ 33 - #define __XCHG_CASE(w, sz, name, mb, nop_lse, acq, acq_lse, rel, cl) \ 34 - static inline unsigned long __xchg_case_##name(unsigned long x, \ 35 - volatile void *ptr) \ 36 - { \ 37 - unsigned long ret, tmp; \ 38 - \ 39 - asm volatile(ARM64_LSE_ATOMIC_INSN( \ 40 - /* LL/SC */ \ 41 - " prfm pstl1strm, %2\n" \ 42 - "1: ld" #acq "xr" #sz "\t%" #w "0, %2\n" \ 43 - " st" #rel "xr" #sz "\t%w1, %" #w "3, %2\n" \ 44 - " cbnz %w1, 1b\n" \ 45 - " " #mb, \ 46 - /* LSE atomics */ \ 47 - " swp" #acq_lse #rel #sz "\t%" #w "3, %" #w "0, %2\n" \ 48 - __nops(3) \ 49 - " " #nop_lse) \ 50 - : "=&r" (ret), "=&r" (tmp), "+Q" (*(unsigned long *)ptr) \ 51 - : "r" (x) \ 52 - : cl); \ 53 - \ 54 - return ret; \ 33 + #define __XCHG_CASE(w, sfx, name, sz, mb, nop_lse, acq, acq_lse, rel, cl) \ 34 + static inline u##sz __xchg_case_##name##sz(u##sz x, volatile void *ptr) \ 35 + { \ 36 + u##sz ret; \ 37 + unsigned long tmp; \ 38 + \ 39 + asm volatile(ARM64_LSE_ATOMIC_INSN( \ 40 + /* LL/SC */ \ 41 + " prfm pstl1strm, %2\n" \ 42 + "1: ld" #acq "xr" #sfx "\t%" #w "0, %2\n" \ 43 + " st" #rel "xr" #sfx "\t%w1, %" #w "3, %2\n" \ 44 + " cbnz %w1, 1b\n" \ 45 + " " #mb, \ 46 + /* LSE atomics */ \ 47 + " swp" #acq_lse #rel #sfx "\t%" #w "3, %" #w "0, %2\n" \ 48 + __nops(3) \ 49 + " " #nop_lse) \ 50 + : "=&r" (ret), "=&r" (tmp), "+Q" (*(u##sz *)ptr) \ 51 + : "r" (x) \ 52 + : cl); \ 53 + \ 54 + return ret; \ 55 55 } 56 56 57 - __XCHG_CASE(w, b, 1, , , , , , ) 58 - __XCHG_CASE(w, h, 2, , , , , , ) 59 - __XCHG_CASE(w, , 4, , , , , , ) 60 - __XCHG_CASE( , , 8, , , , , , ) 61 - __XCHG_CASE(w, b, acq_1, , , a, a, , "memory") 62 - __XCHG_CASE(w, h, acq_2, , , a, a, , "memory") 63 - __XCHG_CASE(w, , acq_4, , , a, a, , "memory") 64 - __XCHG_CASE( , , acq_8, , , a, a, , "memory") 65 - __XCHG_CASE(w, b, rel_1, , , , , l, "memory") 66 - __XCHG_CASE(w, h, rel_2, , , , , l, "memory") 67 - __XCHG_CASE(w, , rel_4, , , , , l, "memory") 68 - __XCHG_CASE( , , rel_8, , , , , l, "memory") 69 - __XCHG_CASE(w, b, mb_1, dmb ish, nop, , a, l, "memory") 70 - __XCHG_CASE(w, h, mb_2, dmb ish, nop, , a, l, "memory") 71 - __XCHG_CASE(w, , mb_4, dmb ish, nop, , a, l, "memory") 72 - __XCHG_CASE( , , mb_8, dmb ish, nop, , a, l, "memory") 57 + __XCHG_CASE(w, b, , 8, , , , , , ) 58 + __XCHG_CASE(w, h, , 16, , , , , , ) 59 + __XCHG_CASE(w, , , 32, , , , , , ) 60 + __XCHG_CASE( , , , 64, , , , , , ) 61 + __XCHG_CASE(w, b, acq_, 8, , , a, a, , "memory") 62 + __XCHG_CASE(w, h, acq_, 16, , , a, a, , "memory") 63 + __XCHG_CASE(w, , acq_, 32, , , a, a, , "memory") 64 + __XCHG_CASE( , , acq_, 64, , , a, a, , "memory") 65 + __XCHG_CASE(w, b, rel_, 8, , , , , l, "memory") 66 + __XCHG_CASE(w, h, rel_, 16, , , , , l, "memory") 67 + __XCHG_CASE(w, , rel_, 32, , , , , l, "memory") 68 + __XCHG_CASE( , , rel_, 64, , , , , l, "memory") 69 + __XCHG_CASE(w, b, mb_, 8, dmb ish, nop, , a, l, "memory") 70 + __XCHG_CASE(w, h, mb_, 16, dmb ish, nop, , a, l, "memory") 71 + __XCHG_CASE(w, , mb_, 32, dmb ish, nop, , a, l, "memory") 72 + __XCHG_CASE( , , mb_, 64, dmb ish, nop, , a, l, "memory") 73 73 74 74 #undef __XCHG_CASE 75 75 ··· 80 80 { \ 81 81 switch (size) { \ 82 82 case 1: \ 83 - return __xchg_case##sfx##_1(x, ptr); \ 84 - case 2: \ 85 - return __xchg_case##sfx##_2(x, ptr); \ 86 - case 4: \ 87 - return __xchg_case##sfx##_4(x, ptr); \ 88 - case 8: \ 89 83 return __xchg_case##sfx##_8(x, ptr); \ 84 + case 2: \ 85 + return __xchg_case##sfx##_16(x, ptr); \ 86 + case 4: \ 87 + return __xchg_case##sfx##_32(x, ptr); \ 88 + case 8: \ 89 + return __xchg_case##sfx##_64(x, ptr); \ 90 90 default: \ 91 91 BUILD_BUG(); \ 92 92 } \ ··· 123 123 { \ 124 124 switch (size) { \ 125 125 case 1: \ 126 - return __cmpxchg_case##sfx##_1(ptr, (u8)old, new); \ 127 - case 2: \ 128 - return __cmpxchg_case##sfx##_2(ptr, (u16)old, new); \ 129 - case 4: \ 130 - return __cmpxchg_case##sfx##_4(ptr, old, new); \ 131 - case 8: \ 132 126 return __cmpxchg_case##sfx##_8(ptr, old, new); \ 127 + case 2: \ 128 + return __cmpxchg_case##sfx##_16(ptr, old, new); \ 129 + case 4: \ 130 + return __cmpxchg_case##sfx##_32(ptr, old, new); \ 131 + case 8: \ 132 + return __cmpxchg_case##sfx##_64(ptr, old, new); \ 133 133 default: \ 134 134 BUILD_BUG(); \ 135 135 } \ ··· 197 197 __ret; \ 198 198 }) 199 199 200 - #define __CMPWAIT_CASE(w, sz, name) \ 201 - static inline void __cmpwait_case_##name(volatile void *ptr, \ 202 - unsigned long val) \ 200 + #define __CMPWAIT_CASE(w, sfx, sz) \ 201 + static inline void __cmpwait_case_##sz(volatile void *ptr, \ 202 + unsigned long val) \ 203 203 { \ 204 204 unsigned long tmp; \ 205 205 \ 206 206 asm volatile( \ 207 207 " sevl\n" \ 208 208 " wfe\n" \ 209 - " ldxr" #sz "\t%" #w "[tmp], %[v]\n" \ 209 + " ldxr" #sfx "\t%" #w "[tmp], %[v]\n" \ 210 210 " eor %" #w "[tmp], %" #w "[tmp], %" #w "[val]\n" \ 211 211 " cbnz %" #w "[tmp], 1f\n" \ 212 212 " wfe\n" \ ··· 215 215 : [val] "r" (val)); \ 216 216 } 217 217 218 - __CMPWAIT_CASE(w, b, 1); 219 - __CMPWAIT_CASE(w, h, 2); 220 - __CMPWAIT_CASE(w, , 4); 221 - __CMPWAIT_CASE( , , 8); 218 + __CMPWAIT_CASE(w, b, 8); 219 + __CMPWAIT_CASE(w, h, 16); 220 + __CMPWAIT_CASE(w, , 32); 221 + __CMPWAIT_CASE( , , 64); 222 222 223 223 #undef __CMPWAIT_CASE 224 224 ··· 229 229 { \ 230 230 switch (size) { \ 231 231 case 1: \ 232 - return __cmpwait_case##sfx##_1(ptr, (u8)val); \ 232 + return __cmpwait_case##sfx##_8(ptr, (u8)val); \ 233 233 case 2: \ 234 - return __cmpwait_case##sfx##_2(ptr, (u16)val); \ 234 + return __cmpwait_case##sfx##_16(ptr, (u16)val); \ 235 235 case 4: \ 236 - return __cmpwait_case##sfx##_4(ptr, val); \ 236 + return __cmpwait_case##sfx##_32(ptr, val); \ 237 237 case 8: \ 238 - return __cmpwait_case##sfx##_8(ptr, val); \ 238 + return __cmpwait_case##sfx##_64(ptr, val); \ 239 239 default: \ 240 240 BUILD_BUG(); \ 241 241 } \
+7 -1
arch/arm64/include/asm/cpucaps.h
··· 54 54 #define ARM64_HAS_CRC32 33 55 55 #define ARM64_SSBS 34 56 56 #define ARM64_WORKAROUND_1188873 35 57 + #define ARM64_HAS_SB 36 58 + #define ARM64_WORKAROUND_1165522 37 59 + #define ARM64_HAS_ADDRESS_AUTH_ARCH 38 60 + #define ARM64_HAS_ADDRESS_AUTH_IMP_DEF 39 61 + #define ARM64_HAS_GENERIC_AUTH_ARCH 40 62 + #define ARM64_HAS_GENERIC_AUTH_IMP_DEF 41 57 63 58 - #define ARM64_NCAPS 36 64 + #define ARM64_NCAPS 42 59 65 60 66 #endif /* __ASM_CPUCAPS_H */
+111 -13
arch/arm64/include/asm/cpufeature.h
··· 321 321 bool sign; 322 322 unsigned long hwcap; 323 323 }; 324 - /* 325 - * A list of "matches/cpu_enable" pair for the same 326 - * "capability" of the same "type" as described by the parent. 327 - * Only matches(), cpu_enable() and fields relevant to these 328 - * methods are significant in the list. The cpu_enable is 329 - * invoked only if the corresponding entry "matches()". 330 - * However, if a cpu_enable() method is associated 331 - * with multiple matches(), care should be taken that either 332 - * the match criteria are mutually exclusive, or that the 333 - * method is robust against being called multiple times. 334 - */ 335 - const struct arm64_cpu_capabilities *match_list; 336 324 }; 325 + 326 + /* 327 + * An optional list of "matches/cpu_enable" pair for the same 328 + * "capability" of the same "type" as described by the parent. 329 + * Only matches(), cpu_enable() and fields relevant to these 330 + * methods are significant in the list. The cpu_enable is 331 + * invoked only if the corresponding entry "matches()". 332 + * However, if a cpu_enable() method is associated 333 + * with multiple matches(), care should be taken that either 334 + * the match criteria are mutually exclusive, or that the 335 + * method is robust against being called multiple times. 336 + */ 337 + const struct arm64_cpu_capabilities *match_list; 337 338 }; 338 339 339 340 static inline int cpucap_default_scope(const struct arm64_cpu_capabilities *cap) ··· 354 353 return !!(cap->type & ARM64_CPUCAP_PERMITTED_FOR_LATE_CPU); 355 354 } 356 355 356 + /* 357 + * Generic helper for handling capabilties with multiple (match,enable) pairs 358 + * of call backs, sharing the same capability bit. 359 + * Iterate over each entry to see if at least one matches. 360 + */ 361 + static inline bool 362 + cpucap_multi_entry_cap_matches(const struct arm64_cpu_capabilities *entry, 363 + int scope) 364 + { 365 + const struct arm64_cpu_capabilities *caps; 366 + 367 + for (caps = entry->match_list; caps->matches; caps++) 368 + if (caps->matches(caps, scope)) 369 + return true; 370 + 371 + return false; 372 + } 373 + 374 + /* 375 + * Take appropriate action for all matching entries in the shared capability 376 + * entry. 377 + */ 378 + static inline void 379 + cpucap_multi_entry_cap_cpu_enable(const struct arm64_cpu_capabilities *entry) 380 + { 381 + const struct arm64_cpu_capabilities *caps; 382 + 383 + for (caps = entry->match_list; caps->matches; caps++) 384 + if (caps->matches(caps, SCOPE_LOCAL_CPU) && 385 + caps->cpu_enable) 386 + caps->cpu_enable(caps); 387 + } 388 + 357 389 extern DECLARE_BITMAP(cpu_hwcaps, ARM64_NCAPS); 358 390 extern struct static_key_false cpu_hwcap_keys[ARM64_NCAPS]; 359 391 extern struct static_key_false arm64_const_caps_ready; 392 + 393 + #define for_each_available_cap(cap) \ 394 + for_each_set_bit(cap, cpu_hwcaps, ARM64_NCAPS) 360 395 361 396 bool this_cpu_has_cap(unsigned int cap); 362 397 ··· 510 473 void __init setup_cpu_features(void); 511 474 void check_local_cpu_capabilities(void); 512 475 513 - 514 476 u64 read_sanitised_ftr_reg(u32 id); 515 477 516 478 static inline bool cpu_supports_mixed_endian_el0(void) ··· 522 486 return cpus_have_const_cap(ARM64_HAS_32BIT_EL0); 523 487 } 524 488 489 + static inline bool system_supports_4kb_granule(void) 490 + { 491 + u64 mmfr0; 492 + u32 val; 493 + 494 + mmfr0 = read_sanitised_ftr_reg(SYS_ID_AA64MMFR0_EL1); 495 + val = cpuid_feature_extract_unsigned_field(mmfr0, 496 + ID_AA64MMFR0_TGRAN4_SHIFT); 497 + 498 + return val == ID_AA64MMFR0_TGRAN4_SUPPORTED; 499 + } 500 + 501 + static inline bool system_supports_64kb_granule(void) 502 + { 503 + u64 mmfr0; 504 + u32 val; 505 + 506 + mmfr0 = read_sanitised_ftr_reg(SYS_ID_AA64MMFR0_EL1); 507 + val = cpuid_feature_extract_unsigned_field(mmfr0, 508 + ID_AA64MMFR0_TGRAN64_SHIFT); 509 + 510 + return val == ID_AA64MMFR0_TGRAN64_SUPPORTED; 511 + } 512 + 513 + static inline bool system_supports_16kb_granule(void) 514 + { 515 + u64 mmfr0; 516 + u32 val; 517 + 518 + mmfr0 = read_sanitised_ftr_reg(SYS_ID_AA64MMFR0_EL1); 519 + val = cpuid_feature_extract_unsigned_field(mmfr0, 520 + ID_AA64MMFR0_TGRAN16_SHIFT); 521 + 522 + return val == ID_AA64MMFR0_TGRAN16_SUPPORTED; 523 + } 524 + 525 525 static inline bool system_supports_mixed_endian_el0(void) 526 526 { 527 527 return id_aa64mmfr0_mixed_endian_el0(read_sanitised_ftr_reg(SYS_ID_AA64MMFR0_EL1)); 528 + } 529 + 530 + static inline bool system_supports_mixed_endian(void) 531 + { 532 + u64 mmfr0; 533 + u32 val; 534 + 535 + mmfr0 = read_sanitised_ftr_reg(SYS_ID_AA64MMFR0_EL1); 536 + val = cpuid_feature_extract_unsigned_field(mmfr0, 537 + ID_AA64MMFR0_BIGENDEL_SHIFT); 538 + 539 + return val == 0x1; 528 540 } 529 541 530 542 static inline bool system_supports_fpsimd(void) ··· 596 512 { 597 513 return IS_ENABLED(CONFIG_ARM64_CNP) && 598 514 cpus_have_const_cap(ARM64_HAS_CNP); 515 + } 516 + 517 + static inline bool system_supports_address_auth(void) 518 + { 519 + return IS_ENABLED(CONFIG_ARM64_PTR_AUTH) && 520 + (cpus_have_const_cap(ARM64_HAS_ADDRESS_AUTH_ARCH) || 521 + cpus_have_const_cap(ARM64_HAS_ADDRESS_AUTH_IMP_DEF)); 522 + } 523 + 524 + static inline bool system_supports_generic_auth(void) 525 + { 526 + return IS_ENABLED(CONFIG_ARM64_PTR_AUTH) && 527 + (cpus_have_const_cap(ARM64_HAS_GENERIC_AUTH_ARCH) || 528 + cpus_have_const_cap(ARM64_HAS_GENERIC_AUTH_IMP_DEF)); 599 529 } 600 530 601 531 #define ARM64_SSBD_UNKNOWN -1
+2
arch/arm64/include/asm/cputype.h
··· 151 151 .rv_max = MIDR_CPU_VAR_REV(v_max, r_max), \ 152 152 } 153 153 154 + #define MIDR_REV_RANGE(m, v, r_min, r_max) MIDR_RANGE(m, v, r_min, v, r_max) 155 + #define MIDR_REV(m, v, r) MIDR_RANGE(m, v, r, v, r) 154 156 #define MIDR_ALL_VERSIONS(m) MIDR_RANGE(m, 0, 0, 0xf, 0xf) 155 157 156 158 static inline bool is_midr_in_range(u32 midr, struct midr_range const *range)
+4
arch/arm64/include/asm/elf.h
··· 117 117 * 64-bit, this is above 4GB to leave the entire 32-bit address 118 118 * space open for things that want to use the area for 32-bit pointers. 119 119 */ 120 + #ifdef CONFIG_ARM64_FORCE_52BIT 120 121 #define ELF_ET_DYN_BASE (2 * TASK_SIZE_64 / 3) 122 + #else 123 + #define ELF_ET_DYN_BASE (2 * DEFAULT_MAP_WINDOW_64 / 3) 124 + #endif /* CONFIG_ARM64_FORCE_52BIT */ 121 125 122 126 #ifndef __ASSEMBLY__ 123 127
+9 -8
arch/arm64/include/asm/esr.h
··· 29 29 #define ESR_ELx_EC_CP14_MR (0x05) 30 30 #define ESR_ELx_EC_CP14_LS (0x06) 31 31 #define ESR_ELx_EC_FP_ASIMD (0x07) 32 - #define ESR_ELx_EC_CP10_ID (0x08) 33 - /* Unallocated EC: 0x09 - 0x0B */ 32 + #define ESR_ELx_EC_CP10_ID (0x08) /* EL2 only */ 33 + #define ESR_ELx_EC_PAC (0x09) /* EL2 and above */ 34 + /* Unallocated EC: 0x0A - 0x0B */ 34 35 #define ESR_ELx_EC_CP14_64 (0x0C) 35 36 /* Unallocated EC: 0x0d */ 36 37 #define ESR_ELx_EC_ILL (0x0E) 37 38 /* Unallocated EC: 0x0F - 0x10 */ 38 39 #define ESR_ELx_EC_SVC32 (0x11) 39 - #define ESR_ELx_EC_HVC32 (0x12) 40 - #define ESR_ELx_EC_SMC32 (0x13) 40 + #define ESR_ELx_EC_HVC32 (0x12) /* EL2 only */ 41 + #define ESR_ELx_EC_SMC32 (0x13) /* EL2 and above */ 41 42 /* Unallocated EC: 0x14 */ 42 43 #define ESR_ELx_EC_SVC64 (0x15) 43 - #define ESR_ELx_EC_HVC64 (0x16) 44 - #define ESR_ELx_EC_SMC64 (0x17) 44 + #define ESR_ELx_EC_HVC64 (0x16) /* EL2 and above */ 45 + #define ESR_ELx_EC_SMC64 (0x17) /* EL2 and above */ 45 46 #define ESR_ELx_EC_SYS64 (0x18) 46 47 #define ESR_ELx_EC_SVE (0x19) 47 48 /* Unallocated EC: 0x1A - 0x1E */ 48 - #define ESR_ELx_EC_IMP_DEF (0x1f) 49 + #define ESR_ELx_EC_IMP_DEF (0x1f) /* EL3 only */ 49 50 #define ESR_ELx_EC_IABT_LOW (0x20) 50 51 #define ESR_ELx_EC_IABT_CUR (0x21) 51 52 #define ESR_ELx_EC_PC_ALIGN (0x22) ··· 69 68 /* Unallocated EC: 0x36 - 0x37 */ 70 69 #define ESR_ELx_EC_BKPT32 (0x38) 71 70 /* Unallocated EC: 0x39 */ 72 - #define ESR_ELx_EC_VECTOR32 (0x3A) 71 + #define ESR_ELx_EC_VECTOR32 (0x3A) /* EL2 only */ 73 72 /* Unallocted EC: 0x3B */ 74 73 #define ESR_ELx_EC_BRK64 (0x3C) 75 74 /* Unallocated EC: 0x3D - 0x3F */
+1
arch/arm64/include/asm/ftrace.h
··· 13 13 14 14 #include <asm/insn.h> 15 15 16 + #define HAVE_FUNCTION_GRAPH_FP_TEST 16 17 #define MCOUNT_ADDR ((unsigned long)_mcount) 17 18 #define MCOUNT_INSN_SIZE AARCH64_INSN_SIZE 18 19
+59
arch/arm64/include/asm/image.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 + 3 + #ifndef __ASM_IMAGE_H 4 + #define __ASM_IMAGE_H 5 + 6 + #define ARM64_IMAGE_MAGIC "ARM\x64" 7 + 8 + #define ARM64_IMAGE_FLAG_BE_SHIFT 0 9 + #define ARM64_IMAGE_FLAG_PAGE_SIZE_SHIFT (ARM64_IMAGE_FLAG_BE_SHIFT + 1) 10 + #define ARM64_IMAGE_FLAG_PHYS_BASE_SHIFT \ 11 + (ARM64_IMAGE_FLAG_PAGE_SIZE_SHIFT + 2) 12 + #define ARM64_IMAGE_FLAG_BE_MASK 0x1 13 + #define ARM64_IMAGE_FLAG_PAGE_SIZE_MASK 0x3 14 + #define ARM64_IMAGE_FLAG_PHYS_BASE_MASK 0x1 15 + 16 + #define ARM64_IMAGE_FLAG_LE 0 17 + #define ARM64_IMAGE_FLAG_BE 1 18 + #define ARM64_IMAGE_FLAG_PAGE_SIZE_4K 1 19 + #define ARM64_IMAGE_FLAG_PAGE_SIZE_16K 2 20 + #define ARM64_IMAGE_FLAG_PAGE_SIZE_64K 3 21 + #define ARM64_IMAGE_FLAG_PHYS_BASE 1 22 + 23 + #ifndef __ASSEMBLY__ 24 + 25 + #define arm64_image_flag_field(flags, field) \ 26 + (((flags) >> field##_SHIFT) & field##_MASK) 27 + 28 + /* 29 + * struct arm64_image_header - arm64 kernel image header 30 + * See Documentation/arm64/booting.txt for details 31 + * 32 + * @code0: Executable code, or 33 + * @mz_header alternatively used for part of MZ header 34 + * @code1: Executable code 35 + * @text_offset: Image load offset 36 + * @image_size: Effective Image size 37 + * @flags: kernel flags 38 + * @reserved: reserved 39 + * @magic: Magic number 40 + * @reserved5: reserved, or 41 + * @pe_header: alternatively used for PE COFF offset 42 + */ 43 + 44 + struct arm64_image_header { 45 + __le32 code0; 46 + __le32 code1; 47 + __le64 text_offset; 48 + __le64 image_size; 49 + __le64 flags; 50 + __le64 res2; 51 + __le64 res3; 52 + __le64 res4; 53 + __le32 magic; 54 + __le32 res5; 55 + }; 56 + 57 + #endif /* __ASSEMBLY__ */ 58 + 59 + #endif /* __ASM_IMAGE_H */
+8
arch/arm64/include/asm/insn.h
··· 261 261 AARCH64_INSN_PRFM_POLICY_STRM, 262 262 }; 263 263 264 + enum aarch64_insn_adr_type { 265 + AARCH64_INSN_ADR_TYPE_ADRP, 266 + AARCH64_INSN_ADR_TYPE_ADR, 267 + }; 268 + 264 269 #define __AARCH64_INSN_FUNCS(abbr, mask, val) \ 265 270 static __always_inline bool aarch64_insn_is_##abbr(u32 code) \ 266 271 { return (code & (mask)) == (val); } \ ··· 398 393 enum aarch64_insn_register src, 399 394 int imm, enum aarch64_insn_variant variant, 400 395 enum aarch64_insn_adsb_type type); 396 + u32 aarch64_insn_gen_adr(unsigned long pc, unsigned long addr, 397 + enum aarch64_insn_register reg, 398 + enum aarch64_insn_adr_type type); 401 399 u32 aarch64_insn_gen_bitfield(enum aarch64_insn_register dst, 402 400 enum aarch64_insn_register src, 403 401 int immr, int imms,
+24 -8
arch/arm64/include/asm/io.h
··· 104 104 } 105 105 106 106 /* IO barriers */ 107 - #define __iormb() rmb() 107 + #define __iormb(v) \ 108 + ({ \ 109 + unsigned long tmp; \ 110 + \ 111 + rmb(); \ 112 + \ 113 + /* \ 114 + * Create a dummy control dependency from the IO read to any \ 115 + * later instructions. This ensures that a subsequent call to \ 116 + * udelay() will be ordered due to the ISB in get_cycles(). \ 117 + */ \ 118 + asm volatile("eor %0, %1, %1\n" \ 119 + "cbnz %0, ." \ 120 + : "=r" (tmp) : "r" ((unsigned long)(v)) \ 121 + : "memory"); \ 122 + }) 123 + 108 124 #define __iowmb() wmb() 109 125 110 126 #define mmiowb() do { } while (0) ··· 145 129 * following Normal memory access. Writes are ordered relative to any prior 146 130 * Normal memory access. 147 131 */ 148 - #define readb(c) ({ u8 __v = readb_relaxed(c); __iormb(); __v; }) 149 - #define readw(c) ({ u16 __v = readw_relaxed(c); __iormb(); __v; }) 150 - #define readl(c) ({ u32 __v = readl_relaxed(c); __iormb(); __v; }) 151 - #define readq(c) ({ u64 __v = readq_relaxed(c); __iormb(); __v; }) 132 + #define readb(c) ({ u8 __v = readb_relaxed(c); __iormb(__v); __v; }) 133 + #define readw(c) ({ u16 __v = readw_relaxed(c); __iormb(__v); __v; }) 134 + #define readl(c) ({ u32 __v = readl_relaxed(c); __iormb(__v); __v; }) 135 + #define readq(c) ({ u64 __v = readq_relaxed(c); __iormb(__v); __v; }) 152 136 153 137 #define writeb(v,c) ({ __iowmb(); writeb_relaxed((v),(c)); }) 154 138 #define writew(v,c) ({ __iowmb(); writew_relaxed((v),(c)); }) ··· 199 183 /* 200 184 * io{read,write}{16,32,64}be() macros 201 185 */ 202 - #define ioread16be(p) ({ __u16 __v = be16_to_cpu((__force __be16)__raw_readw(p)); __iormb(); __v; }) 203 - #define ioread32be(p) ({ __u32 __v = be32_to_cpu((__force __be32)__raw_readl(p)); __iormb(); __v; }) 204 - #define ioread64be(p) ({ __u64 __v = be64_to_cpu((__force __be64)__raw_readq(p)); __iormb(); __v; }) 186 + #define ioread16be(p) ({ __u16 __v = be16_to_cpu((__force __be16)__raw_readw(p)); __iormb(__v); __v; }) 187 + #define ioread32be(p) ({ __u32 __v = be32_to_cpu((__force __be32)__raw_readl(p)); __iormb(__v); __v; }) 188 + #define ioread64be(p) ({ __u64 __v = be64_to_cpu((__force __be64)__raw_readq(p)); __iormb(__v); __v; }) 205 189 206 190 #define iowrite16be(v,p) ({ __iowmb(); __raw_writew((__force __u16)cpu_to_be16(v), p); }) 207 191 #define iowrite32be(v,p) ({ __iowmb(); __raw_writel((__force __u32)cpu_to_be32(v), p); })
+19
arch/arm64/include/asm/kexec.h
··· 93 93 static inline void crash_post_resume(void) {} 94 94 #endif 95 95 96 + #ifdef CONFIG_KEXEC_FILE 97 + #define ARCH_HAS_KIMAGE_ARCH 98 + 99 + struct kimage_arch { 100 + void *dtb; 101 + unsigned long dtb_mem; 102 + }; 103 + 104 + extern const struct kexec_file_ops kexec_image_ops; 105 + 106 + struct kimage; 107 + 108 + extern int arch_kimage_file_post_load_cleanup(struct kimage *image); 109 + extern int load_other_segments(struct kimage *image, 110 + unsigned long kernel_load_addr, unsigned long kernel_size, 111 + char *initrd, unsigned long initrd_len, 112 + char *cmdline); 113 + #endif 114 + 96 115 #endif /* __ASSEMBLY__ */ 97 116 98 117 #endif
+3
arch/arm64/include/asm/kvm_arm.h
··· 24 24 25 25 /* Hyp Configuration Register (HCR) bits */ 26 26 #define HCR_FWB (UL(1) << 46) 27 + #define HCR_API (UL(1) << 41) 28 + #define HCR_APK (UL(1) << 40) 27 29 #define HCR_TEA (UL(1) << 37) 28 30 #define HCR_TERR (UL(1) << 36) 29 31 #define HCR_TLOR (UL(1) << 35) ··· 89 87 HCR_AMO | HCR_SWIO | HCR_TIDCP | HCR_RW | HCR_TLOR | \ 90 88 HCR_FMO | HCR_IMO) 91 89 #define HCR_VIRT_EXCP_MASK (HCR_VSE | HCR_VI | HCR_VF) 90 + #define HCR_HOST_NVHE_FLAGS (HCR_RW | HCR_API | HCR_APK) 92 91 #define HCR_HOST_VHE_FLAGS (HCR_RW | HCR_TGE | HCR_E2H) 93 92 94 93 /* TCR_EL2 Registers bits */
+7 -3
arch/arm64/include/asm/kvm_host.h
··· 422 422 } 423 423 } 424 424 425 - static inline bool kvm_arch_check_sve_has_vhe(void) 425 + static inline bool kvm_arch_requires_vhe(void) 426 426 { 427 427 /* 428 428 * The Arm architecture specifies that implementation of SVE ··· 430 430 * relies on this when SVE is present: 431 431 */ 432 432 if (system_supports_sve()) 433 - return has_vhe(); 434 - else 435 433 return true; 434 + 435 + /* Some implementations have defects that confine them to VHE */ 436 + if (cpus_have_cap(ARM64_WORKAROUND_1165522)) 437 + return true; 438 + 439 + return false; 436 440 } 437 441 438 442 static inline void kvm_arch_hardware_unsetup(void) {}
+8
arch/arm64/include/asm/kvm_hyp.h
··· 20 20 21 21 #include <linux/compiler.h> 22 22 #include <linux/kvm_host.h> 23 + #include <asm/alternative.h> 23 24 #include <asm/sysreg.h> 24 25 25 26 #define __hyp_text __section(.hyp.text) notrace ··· 164 163 { 165 164 write_sysreg(kvm->arch.vtcr, vtcr_el2); 166 165 write_sysreg(kvm->arch.vttbr, vttbr_el2); 166 + 167 + /* 168 + * ARM erratum 1165522 requires the actual execution of the above 169 + * before we can switch to the EL1/EL0 translation regime used by 170 + * the guest. 171 + */ 172 + asm(ALTERNATIVE("nop", "isb", ARM64_WORKAROUND_1165522)); 167 173 } 168 174 169 175 #endif /* __ARM64_KVM_HYP_H__ */
+15 -1
arch/arm64/include/asm/memory.h
··· 64 64 #define KERNEL_START _text 65 65 #define KERNEL_END _end 66 66 67 + #ifdef CONFIG_ARM64_USER_VA_BITS_52 68 + #define MAX_USER_VA_BITS 52 69 + #else 70 + #define MAX_USER_VA_BITS VA_BITS 71 + #endif 72 + 67 73 /* 68 74 * KASAN requires 1/8th of the kernel virtual address space for the shadow 69 75 * region. KASAN can bloat the stack significantly, so double the (minimum) 70 - * stack size when KASAN is in use. 76 + * stack size when KASAN is in use, and then double it again if KASAN_EXTRA is 77 + * on. 71 78 */ 72 79 #ifdef CONFIG_KASAN 73 80 #define KASAN_SHADOW_SCALE_SHIFT 3 74 81 #define KASAN_SHADOW_SIZE (UL(1) << (VA_BITS - KASAN_SHADOW_SCALE_SHIFT)) 82 + #ifdef CONFIG_KASAN_EXTRA 83 + #define KASAN_THREAD_SHIFT 2 84 + #else 75 85 #define KASAN_THREAD_SHIFT 1 86 + #endif /* CONFIG_KASAN_EXTRA */ 76 87 #else 77 88 #define KASAN_SHADOW_SIZE (0) 78 89 #define KASAN_THREAD_SHIFT 0 ··· 197 186 { 198 187 return kimage_vaddr - KIMAGE_VADDR; 199 188 } 189 + 190 + /* the actual size of a user virtual address */ 191 + extern u64 vabits_user; 200 192 201 193 /* 202 194 * Allow all memory at the discovery stage. We will clip it later.
+5
arch/arm64/include/asm/mmu_context.h
··· 35 35 #include <asm/sysreg.h> 36 36 #include <asm/tlbflush.h> 37 37 38 + extern bool rodata_full; 39 + 38 40 static inline void contextidr_thread_switch(struct task_struct *next) 39 41 { 40 42 if (!IS_ENABLED(CONFIG_PID_IN_CONTEXTIDR)) ··· 74 72 75 73 static inline bool __cpu_uses_extended_idmap(void) 76 74 { 75 + if (IS_ENABLED(CONFIG_ARM64_USER_VA_BITS_52)) 76 + return false; 77 + 77 78 return unlikely(idmap_t0sz != TCR_T0SZ(VA_BITS)); 78 79 } 79 80
+13 -31
arch/arm64/include/asm/module.h
··· 22 22 23 23 #ifdef CONFIG_ARM64_MODULE_PLTS 24 24 struct mod_plt_sec { 25 - struct elf64_shdr *plt; 25 + int plt_shndx; 26 26 int plt_num_entries; 27 27 int plt_max_entries; 28 28 }; ··· 36 36 }; 37 37 #endif 38 38 39 - u64 module_emit_plt_entry(struct module *mod, void *loc, const Elf64_Rela *rela, 39 + u64 module_emit_plt_entry(struct module *mod, Elf64_Shdr *sechdrs, 40 + void *loc, const Elf64_Rela *rela, 40 41 Elf64_Sym *sym); 41 42 42 - u64 module_emit_veneer_for_adrp(struct module *mod, void *loc, u64 val); 43 + u64 module_emit_veneer_for_adrp(struct module *mod, Elf64_Shdr *sechdrs, 44 + void *loc, u64 val); 43 45 44 46 #ifdef CONFIG_RANDOMIZE_BASE 45 47 extern u64 module_alloc_base; ··· 58 56 * is exactly what we are dealing with here, we are free to use x16 59 57 * as a scratch register in the PLT veneers. 60 58 */ 61 - __le32 mov0; /* movn x16, #0x.... */ 62 - __le32 mov1; /* movk x16, #0x...., lsl #16 */ 63 - __le32 mov2; /* movk x16, #0x...., lsl #32 */ 59 + __le32 adrp; /* adrp x16, .... */ 60 + __le32 add; /* add x16, x16, #0x.... */ 64 61 __le32 br; /* br x16 */ 65 62 }; 66 63 67 - static inline struct plt_entry get_plt_entry(u64 val) 64 + static inline bool is_forbidden_offset_for_adrp(void *place) 68 65 { 69 - /* 70 - * MOVK/MOVN/MOVZ opcode: 71 - * +--------+------------+--------+-----------+-------------+---------+ 72 - * | sf[31] | opc[30:29] | 100101 | hw[22:21] | imm16[20:5] | Rd[4:0] | 73 - * +--------+------------+--------+-----------+-------------+---------+ 74 - * 75 - * Rd := 0x10 (x16) 76 - * hw := 0b00 (no shift), 0b01 (lsl #16), 0b10 (lsl #32) 77 - * opc := 0b11 (MOVK), 0b00 (MOVN), 0b10 (MOVZ) 78 - * sf := 1 (64-bit variant) 79 - */ 80 - return (struct plt_entry){ 81 - cpu_to_le32(0x92800010 | (((~val ) & 0xffff)) << 5), 82 - cpu_to_le32(0xf2a00010 | ((( val >> 16) & 0xffff)) << 5), 83 - cpu_to_le32(0xf2c00010 | ((( val >> 32) & 0xffff)) << 5), 84 - cpu_to_le32(0xd61f0200) 85 - }; 66 + return IS_ENABLED(CONFIG_ARM64_ERRATUM_843419) && 67 + cpus_have_const_cap(ARM64_WORKAROUND_843419) && 68 + ((u64)place & 0xfff) >= 0xff8; 86 69 } 87 70 88 - static inline bool plt_entries_equal(const struct plt_entry *a, 89 - const struct plt_entry *b) 90 - { 91 - return a->mov0 == b->mov0 && 92 - a->mov1 == b->mov1 && 93 - a->mov2 == b->mov2; 94 - } 71 + struct plt_entry get_plt_entry(u64 dst, void *pc); 72 + bool plt_entries_equal(const struct plt_entry *a, const struct plt_entry *b); 95 73 96 74 #endif /* __ASM_MODULE_H */
+39
arch/arm64/include/asm/neon-intrinsics.h
··· 1 + /* 2 + * Copyright (C) 2018 Linaro, Ltd. <ard.biesheuvel@linaro.org> 3 + * 4 + * This program is free software; you can redistribute it and/or modify 5 + * it under the terms of the GNU General Public License version 2 as 6 + * published by the Free Software Foundation. 7 + */ 8 + 9 + #ifndef __ASM_NEON_INTRINSICS_H 10 + #define __ASM_NEON_INTRINSICS_H 11 + 12 + #include <asm-generic/int-ll64.h> 13 + 14 + /* 15 + * In the kernel, u64/s64 are [un]signed long long, not [un]signed long. 16 + * So by redefining these macros to the former, we can force gcc-stdint.h 17 + * to define uint64_t / in64_t in a compatible manner. 18 + */ 19 + 20 + #ifdef __INT64_TYPE__ 21 + #undef __INT64_TYPE__ 22 + #define __INT64_TYPE__ long long 23 + #endif 24 + 25 + #ifdef __UINT64_TYPE__ 26 + #undef __UINT64_TYPE__ 27 + #define __UINT64_TYPE__ unsigned long long 28 + #endif 29 + 30 + /* 31 + * genksyms chokes on the ARM NEON instrinsics system header, but we 32 + * don't export anything it defines anyway, so just disregard when 33 + * genksyms execute. 34 + */ 35 + #ifndef __GENKSYMS__ 36 + #include <arm_neon.h> 37 + #endif 38 + 39 + #endif /* __ASM_NEON_INTRINSICS_H */
+156 -226
arch/arm64/include/asm/percpu.h
··· 48 48 } 49 49 #define __my_cpu_offset __my_cpu_offset() 50 50 51 - #define PERCPU_OP(op, asm_op) \ 52 - static inline unsigned long __percpu_##op(void *ptr, \ 53 - unsigned long val, int size) \ 51 + #define PERCPU_RW_OPS(sz) \ 52 + static inline unsigned long __percpu_read_##sz(void *ptr) \ 54 53 { \ 55 - unsigned long loop, ret; \ 54 + return READ_ONCE(*(u##sz *)ptr); \ 55 + } \ 56 56 \ 57 - switch (size) { \ 58 - case 1: \ 59 - asm ("//__per_cpu_" #op "_1\n" \ 60 - "1: ldxrb %w[ret], %[ptr]\n" \ 61 - #asm_op " %w[ret], %w[ret], %w[val]\n" \ 62 - " stxrb %w[loop], %w[ret], %[ptr]\n" \ 63 - " cbnz %w[loop], 1b" \ 64 - : [loop] "=&r" (loop), [ret] "=&r" (ret), \ 65 - [ptr] "+Q"(*(u8 *)ptr) \ 66 - : [val] "Ir" (val)); \ 67 - break; \ 68 - case 2: \ 69 - asm ("//__per_cpu_" #op "_2\n" \ 70 - "1: ldxrh %w[ret], %[ptr]\n" \ 71 - #asm_op " %w[ret], %w[ret], %w[val]\n" \ 72 - " stxrh %w[loop], %w[ret], %[ptr]\n" \ 73 - " cbnz %w[loop], 1b" \ 74 - : [loop] "=&r" (loop), [ret] "=&r" (ret), \ 75 - [ptr] "+Q"(*(u16 *)ptr) \ 76 - : [val] "Ir" (val)); \ 77 - break; \ 78 - case 4: \ 79 - asm ("//__per_cpu_" #op "_4\n" \ 80 - "1: ldxr %w[ret], %[ptr]\n" \ 81 - #asm_op " %w[ret], %w[ret], %w[val]\n" \ 82 - " stxr %w[loop], %w[ret], %[ptr]\n" \ 83 - " cbnz %w[loop], 1b" \ 84 - : [loop] "=&r" (loop), [ret] "=&r" (ret), \ 85 - [ptr] "+Q"(*(u32 *)ptr) \ 86 - : [val] "Ir" (val)); \ 87 - break; \ 88 - case 8: \ 89 - asm ("//__per_cpu_" #op "_8\n" \ 90 - "1: ldxr %[ret], %[ptr]\n" \ 91 - #asm_op " %[ret], %[ret], %[val]\n" \ 92 - " stxr %w[loop], %[ret], %[ptr]\n" \ 93 - " cbnz %w[loop], 1b" \ 94 - : [loop] "=&r" (loop), [ret] "=&r" (ret), \ 95 - [ptr] "+Q"(*(u64 *)ptr) \ 96 - : [val] "Ir" (val)); \ 97 - break; \ 98 - default: \ 99 - ret = 0; \ 100 - BUILD_BUG(); \ 101 - } \ 57 + static inline void __percpu_write_##sz(void *ptr, unsigned long val) \ 58 + { \ 59 + WRITE_ONCE(*(u##sz *)ptr, (u##sz)val); \ 60 + } 61 + 62 + #define __PERCPU_OP_CASE(w, sfx, name, sz, op_llsc, op_lse) \ 63 + static inline void \ 64 + __percpu_##name##_case_##sz(void *ptr, unsigned long val) \ 65 + { \ 66 + unsigned int loop; \ 67 + u##sz tmp; \ 68 + \ 69 + asm volatile (ARM64_LSE_ATOMIC_INSN( \ 70 + /* LL/SC */ \ 71 + "1: ldxr" #sfx "\t%" #w "[tmp], %[ptr]\n" \ 72 + #op_llsc "\t%" #w "[tmp], %" #w "[tmp], %" #w "[val]\n" \ 73 + " stxr" #sfx "\t%w[loop], %" #w "[tmp], %[ptr]\n" \ 74 + " cbnz %w[loop], 1b", \ 75 + /* LSE atomics */ \ 76 + #op_lse "\t%" #w "[val], %[ptr]\n" \ 77 + __nops(3)) \ 78 + : [loop] "=&r" (loop), [tmp] "=&r" (tmp), \ 79 + [ptr] "+Q"(*(u##sz *)ptr) \ 80 + : [val] "r" ((u##sz)(val))); \ 81 + } 82 + 83 + #define __PERCPU_RET_OP_CASE(w, sfx, name, sz, op_llsc, op_lse) \ 84 + static inline u##sz \ 85 + __percpu_##name##_return_case_##sz(void *ptr, unsigned long val) \ 86 + { \ 87 + unsigned int loop; \ 88 + u##sz ret; \ 89 + \ 90 + asm volatile (ARM64_LSE_ATOMIC_INSN( \ 91 + /* LL/SC */ \ 92 + "1: ldxr" #sfx "\t%" #w "[ret], %[ptr]\n" \ 93 + #op_llsc "\t%" #w "[ret], %" #w "[ret], %" #w "[val]\n" \ 94 + " stxr" #sfx "\t%w[loop], %" #w "[ret], %[ptr]\n" \ 95 + " cbnz %w[loop], 1b", \ 96 + /* LSE atomics */ \ 97 + #op_lse "\t%" #w "[val], %" #w "[ret], %[ptr]\n" \ 98 + #op_llsc "\t%" #w "[ret], %" #w "[ret], %" #w "[val]\n" \ 99 + __nops(2)) \ 100 + : [loop] "=&r" (loop), [ret] "=&r" (ret), \ 101 + [ptr] "+Q"(*(u##sz *)ptr) \ 102 + : [val] "r" ((u##sz)(val))); \ 102 103 \ 103 104 return ret; \ 104 105 } 105 106 106 - PERCPU_OP(add, add) 107 - PERCPU_OP(and, and) 108 - PERCPU_OP(or, orr) 107 + #define PERCPU_OP(name, op_llsc, op_lse) \ 108 + __PERCPU_OP_CASE(w, b, name, 8, op_llsc, op_lse) \ 109 + __PERCPU_OP_CASE(w, h, name, 16, op_llsc, op_lse) \ 110 + __PERCPU_OP_CASE(w, , name, 32, op_llsc, op_lse) \ 111 + __PERCPU_OP_CASE( , , name, 64, op_llsc, op_lse) 112 + 113 + #define PERCPU_RET_OP(name, op_llsc, op_lse) \ 114 + __PERCPU_RET_OP_CASE(w, b, name, 8, op_llsc, op_lse) \ 115 + __PERCPU_RET_OP_CASE(w, h, name, 16, op_llsc, op_lse) \ 116 + __PERCPU_RET_OP_CASE(w, , name, 32, op_llsc, op_lse) \ 117 + __PERCPU_RET_OP_CASE( , , name, 64, op_llsc, op_lse) 118 + 119 + PERCPU_RW_OPS(8) 120 + PERCPU_RW_OPS(16) 121 + PERCPU_RW_OPS(32) 122 + PERCPU_RW_OPS(64) 123 + PERCPU_OP(add, add, stadd) 124 + PERCPU_OP(andnot, bic, stclr) 125 + PERCPU_OP(or, orr, stset) 126 + PERCPU_RET_OP(add, add, ldadd) 127 + 128 + #undef PERCPU_RW_OPS 129 + #undef __PERCPU_OP_CASE 130 + #undef __PERCPU_RET_OP_CASE 109 131 #undef PERCPU_OP 132 + #undef PERCPU_RET_OP 110 133 111 - static inline unsigned long __percpu_read(void *ptr, int size) 112 - { 113 - unsigned long ret; 114 - 115 - switch (size) { 116 - case 1: 117 - ret = READ_ONCE(*(u8 *)ptr); 118 - break; 119 - case 2: 120 - ret = READ_ONCE(*(u16 *)ptr); 121 - break; 122 - case 4: 123 - ret = READ_ONCE(*(u32 *)ptr); 124 - break; 125 - case 8: 126 - ret = READ_ONCE(*(u64 *)ptr); 127 - break; 128 - default: 129 - ret = 0; 130 - BUILD_BUG(); 131 - } 132 - 133 - return ret; 134 - } 135 - 136 - static inline void __percpu_write(void *ptr, unsigned long val, int size) 137 - { 138 - switch (size) { 139 - case 1: 140 - WRITE_ONCE(*(u8 *)ptr, (u8)val); 141 - break; 142 - case 2: 143 - WRITE_ONCE(*(u16 *)ptr, (u16)val); 144 - break; 145 - case 4: 146 - WRITE_ONCE(*(u32 *)ptr, (u32)val); 147 - break; 148 - case 8: 149 - WRITE_ONCE(*(u64 *)ptr, (u64)val); 150 - break; 151 - default: 152 - BUILD_BUG(); 153 - } 154 - } 155 - 156 - static inline unsigned long __percpu_xchg(void *ptr, unsigned long val, 157 - int size) 158 - { 159 - unsigned long ret, loop; 160 - 161 - switch (size) { 162 - case 1: 163 - asm ("//__percpu_xchg_1\n" 164 - "1: ldxrb %w[ret], %[ptr]\n" 165 - " stxrb %w[loop], %w[val], %[ptr]\n" 166 - " cbnz %w[loop], 1b" 167 - : [loop] "=&r"(loop), [ret] "=&r"(ret), 168 - [ptr] "+Q"(*(u8 *)ptr) 169 - : [val] "r" (val)); 170 - break; 171 - case 2: 172 - asm ("//__percpu_xchg_2\n" 173 - "1: ldxrh %w[ret], %[ptr]\n" 174 - " stxrh %w[loop], %w[val], %[ptr]\n" 175 - " cbnz %w[loop], 1b" 176 - : [loop] "=&r"(loop), [ret] "=&r"(ret), 177 - [ptr] "+Q"(*(u16 *)ptr) 178 - : [val] "r" (val)); 179 - break; 180 - case 4: 181 - asm ("//__percpu_xchg_4\n" 182 - "1: ldxr %w[ret], %[ptr]\n" 183 - " stxr %w[loop], %w[val], %[ptr]\n" 184 - " cbnz %w[loop], 1b" 185 - : [loop] "=&r"(loop), [ret] "=&r"(ret), 186 - [ptr] "+Q"(*(u32 *)ptr) 187 - : [val] "r" (val)); 188 - break; 189 - case 8: 190 - asm ("//__percpu_xchg_8\n" 191 - "1: ldxr %[ret], %[ptr]\n" 192 - " stxr %w[loop], %[val], %[ptr]\n" 193 - " cbnz %w[loop], 1b" 194 - : [loop] "=&r"(loop), [ret] "=&r"(ret), 195 - [ptr] "+Q"(*(u64 *)ptr) 196 - : [val] "r" (val)); 197 - break; 198 - default: 199 - ret = 0; 200 - BUILD_BUG(); 201 - } 202 - 203 - return ret; 204 - } 205 - 206 - /* this_cpu_cmpxchg */ 207 - #define _protect_cmpxchg_local(pcp, o, n) \ 208 - ({ \ 209 - typeof(*raw_cpu_ptr(&(pcp))) __ret; \ 210 - preempt_disable(); \ 211 - __ret = cmpxchg_local(raw_cpu_ptr(&(pcp)), o, n); \ 212 - preempt_enable(); \ 213 - __ret; \ 214 - }) 215 - 216 - #define this_cpu_cmpxchg_1(ptr, o, n) _protect_cmpxchg_local(ptr, o, n) 217 - #define this_cpu_cmpxchg_2(ptr, o, n) _protect_cmpxchg_local(ptr, o, n) 218 - #define this_cpu_cmpxchg_4(ptr, o, n) _protect_cmpxchg_local(ptr, o, n) 219 - #define this_cpu_cmpxchg_8(ptr, o, n) _protect_cmpxchg_local(ptr, o, n) 220 - 134 + /* 135 + * It would be nice to avoid the conditional call into the scheduler when 136 + * re-enabling preemption for preemptible kernels, but doing that in a way 137 + * which builds inside a module would mean messing directly with the preempt 138 + * count. If you do this, peterz and tglx will hunt you down. 139 + */ 221 140 #define this_cpu_cmpxchg_double_8(ptr1, ptr2, o1, o2, n1, n2) \ 222 141 ({ \ 223 142 int __ret; \ 224 - preempt_disable(); \ 143 + preempt_disable_notrace(); \ 225 144 __ret = cmpxchg_double_local( raw_cpu_ptr(&(ptr1)), \ 226 145 raw_cpu_ptr(&(ptr2)), \ 227 146 o1, o2, n1, n2); \ 228 - preempt_enable(); \ 147 + preempt_enable_notrace(); \ 229 148 __ret; \ 230 149 }) 231 150 232 - #define _percpu_read(pcp) \ 151 + #define _pcp_protect(op, pcp, ...) \ 152 + ({ \ 153 + preempt_disable_notrace(); \ 154 + op(raw_cpu_ptr(&(pcp)), __VA_ARGS__); \ 155 + preempt_enable_notrace(); \ 156 + }) 157 + 158 + #define _pcp_protect_return(op, pcp, args...) \ 233 159 ({ \ 234 160 typeof(pcp) __retval; \ 235 161 preempt_disable_notrace(); \ 236 - __retval = (typeof(pcp))__percpu_read(raw_cpu_ptr(&(pcp)), \ 237 - sizeof(pcp)); \ 162 + __retval = (typeof(pcp))op(raw_cpu_ptr(&(pcp)), ##args); \ 238 163 preempt_enable_notrace(); \ 239 164 __retval; \ 240 165 }) 241 166 242 - #define _percpu_write(pcp, val) \ 243 - do { \ 244 - preempt_disable_notrace(); \ 245 - __percpu_write(raw_cpu_ptr(&(pcp)), (unsigned long)(val), \ 246 - sizeof(pcp)); \ 247 - preempt_enable_notrace(); \ 248 - } while(0) \ 167 + #define this_cpu_read_1(pcp) \ 168 + _pcp_protect_return(__percpu_read_8, pcp) 169 + #define this_cpu_read_2(pcp) \ 170 + _pcp_protect_return(__percpu_read_16, pcp) 171 + #define this_cpu_read_4(pcp) \ 172 + _pcp_protect_return(__percpu_read_32, pcp) 173 + #define this_cpu_read_8(pcp) \ 174 + _pcp_protect_return(__percpu_read_64, pcp) 249 175 250 - #define _pcp_protect(operation, pcp, val) \ 251 - ({ \ 252 - typeof(pcp) __retval; \ 253 - preempt_disable(); \ 254 - __retval = (typeof(pcp))operation(raw_cpu_ptr(&(pcp)), \ 255 - (val), sizeof(pcp)); \ 256 - preempt_enable(); \ 257 - __retval; \ 258 - }) 176 + #define this_cpu_write_1(pcp, val) \ 177 + _pcp_protect(__percpu_write_8, pcp, (unsigned long)val) 178 + #define this_cpu_write_2(pcp, val) \ 179 + _pcp_protect(__percpu_write_16, pcp, (unsigned long)val) 180 + #define this_cpu_write_4(pcp, val) \ 181 + _pcp_protect(__percpu_write_32, pcp, (unsigned long)val) 182 + #define this_cpu_write_8(pcp, val) \ 183 + _pcp_protect(__percpu_write_64, pcp, (unsigned long)val) 259 184 260 - #define _percpu_add(pcp, val) \ 261 - _pcp_protect(__percpu_add, pcp, val) 185 + #define this_cpu_add_1(pcp, val) \ 186 + _pcp_protect(__percpu_add_case_8, pcp, val) 187 + #define this_cpu_add_2(pcp, val) \ 188 + _pcp_protect(__percpu_add_case_16, pcp, val) 189 + #define this_cpu_add_4(pcp, val) \ 190 + _pcp_protect(__percpu_add_case_32, pcp, val) 191 + #define this_cpu_add_8(pcp, val) \ 192 + _pcp_protect(__percpu_add_case_64, pcp, val) 262 193 263 - #define _percpu_add_return(pcp, val) _percpu_add(pcp, val) 194 + #define this_cpu_add_return_1(pcp, val) \ 195 + _pcp_protect_return(__percpu_add_return_case_8, pcp, val) 196 + #define this_cpu_add_return_2(pcp, val) \ 197 + _pcp_protect_return(__percpu_add_return_case_16, pcp, val) 198 + #define this_cpu_add_return_4(pcp, val) \ 199 + _pcp_protect_return(__percpu_add_return_case_32, pcp, val) 200 + #define this_cpu_add_return_8(pcp, val) \ 201 + _pcp_protect_return(__percpu_add_return_case_64, pcp, val) 264 202 265 - #define _percpu_and(pcp, val) \ 266 - _pcp_protect(__percpu_and, pcp, val) 203 + #define this_cpu_and_1(pcp, val) \ 204 + _pcp_protect(__percpu_andnot_case_8, pcp, ~val) 205 + #define this_cpu_and_2(pcp, val) \ 206 + _pcp_protect(__percpu_andnot_case_16, pcp, ~val) 207 + #define this_cpu_and_4(pcp, val) \ 208 + _pcp_protect(__percpu_andnot_case_32, pcp, ~val) 209 + #define this_cpu_and_8(pcp, val) \ 210 + _pcp_protect(__percpu_andnot_case_64, pcp, ~val) 267 211 268 - #define _percpu_or(pcp, val) \ 269 - _pcp_protect(__percpu_or, pcp, val) 212 + #define this_cpu_or_1(pcp, val) \ 213 + _pcp_protect(__percpu_or_case_8, pcp, val) 214 + #define this_cpu_or_2(pcp, val) \ 215 + _pcp_protect(__percpu_or_case_16, pcp, val) 216 + #define this_cpu_or_4(pcp, val) \ 217 + _pcp_protect(__percpu_or_case_32, pcp, val) 218 + #define this_cpu_or_8(pcp, val) \ 219 + _pcp_protect(__percpu_or_case_64, pcp, val) 270 220 271 - #define _percpu_xchg(pcp, val) (typeof(pcp)) \ 272 - _pcp_protect(__percpu_xchg, pcp, (unsigned long)(val)) 221 + #define this_cpu_xchg_1(pcp, val) \ 222 + _pcp_protect_return(xchg_relaxed, pcp, val) 223 + #define this_cpu_xchg_2(pcp, val) \ 224 + _pcp_protect_return(xchg_relaxed, pcp, val) 225 + #define this_cpu_xchg_4(pcp, val) \ 226 + _pcp_protect_return(xchg_relaxed, pcp, val) 227 + #define this_cpu_xchg_8(pcp, val) \ 228 + _pcp_protect_return(xchg_relaxed, pcp, val) 273 229 274 - #define this_cpu_add_1(pcp, val) _percpu_add(pcp, val) 275 - #define this_cpu_add_2(pcp, val) _percpu_add(pcp, val) 276 - #define this_cpu_add_4(pcp, val) _percpu_add(pcp, val) 277 - #define this_cpu_add_8(pcp, val) _percpu_add(pcp, val) 278 - 279 - #define this_cpu_add_return_1(pcp, val) _percpu_add_return(pcp, val) 280 - #define this_cpu_add_return_2(pcp, val) _percpu_add_return(pcp, val) 281 - #define this_cpu_add_return_4(pcp, val) _percpu_add_return(pcp, val) 282 - #define this_cpu_add_return_8(pcp, val) _percpu_add_return(pcp, val) 283 - 284 - #define this_cpu_and_1(pcp, val) _percpu_and(pcp, val) 285 - #define this_cpu_and_2(pcp, val) _percpu_and(pcp, val) 286 - #define this_cpu_and_4(pcp, val) _percpu_and(pcp, val) 287 - #define this_cpu_and_8(pcp, val) _percpu_and(pcp, val) 288 - 289 - #define this_cpu_or_1(pcp, val) _percpu_or(pcp, val) 290 - #define this_cpu_or_2(pcp, val) _percpu_or(pcp, val) 291 - #define this_cpu_or_4(pcp, val) _percpu_or(pcp, val) 292 - #define this_cpu_or_8(pcp, val) _percpu_or(pcp, val) 293 - 294 - #define this_cpu_read_1(pcp) _percpu_read(pcp) 295 - #define this_cpu_read_2(pcp) _percpu_read(pcp) 296 - #define this_cpu_read_4(pcp) _percpu_read(pcp) 297 - #define this_cpu_read_8(pcp) _percpu_read(pcp) 298 - 299 - #define this_cpu_write_1(pcp, val) _percpu_write(pcp, val) 300 - #define this_cpu_write_2(pcp, val) _percpu_write(pcp, val) 301 - #define this_cpu_write_4(pcp, val) _percpu_write(pcp, val) 302 - #define this_cpu_write_8(pcp, val) _percpu_write(pcp, val) 303 - 304 - #define this_cpu_xchg_1(pcp, val) _percpu_xchg(pcp, val) 305 - #define this_cpu_xchg_2(pcp, val) _percpu_xchg(pcp, val) 306 - #define this_cpu_xchg_4(pcp, val) _percpu_xchg(pcp, val) 307 - #define this_cpu_xchg_8(pcp, val) _percpu_xchg(pcp, val) 230 + #define this_cpu_cmpxchg_1(pcp, o, n) \ 231 + _pcp_protect_return(cmpxchg_relaxed, pcp, o, n) 232 + #define this_cpu_cmpxchg_2(pcp, o, n) \ 233 + _pcp_protect_return(cmpxchg_relaxed, pcp, o, n) 234 + #define this_cpu_cmpxchg_4(pcp, o, n) \ 235 + _pcp_protect_return(cmpxchg_relaxed, pcp, o, n) 236 + #define this_cpu_cmpxchg_8(pcp, o, n) \ 237 + _pcp_protect_return(cmpxchg_relaxed, pcp, o, n) 308 238 309 239 #include <asm-generic/percpu.h> 310 240
+157 -13
arch/arm64/include/asm/perf_event.h
··· 24 24 #define ARMV8_PMU_COUNTER_MASK (ARMV8_PMU_MAX_COUNTERS - 1) 25 25 26 26 /* 27 + * Common architectural and microarchitectural event numbers. 28 + */ 29 + #define ARMV8_PMUV3_PERFCTR_SW_INCR 0x00 30 + #define ARMV8_PMUV3_PERFCTR_L1I_CACHE_REFILL 0x01 31 + #define ARMV8_PMUV3_PERFCTR_L1I_TLB_REFILL 0x02 32 + #define ARMV8_PMUV3_PERFCTR_L1D_CACHE_REFILL 0x03 33 + #define ARMV8_PMUV3_PERFCTR_L1D_CACHE 0x04 34 + #define ARMV8_PMUV3_PERFCTR_L1D_TLB_REFILL 0x05 35 + #define ARMV8_PMUV3_PERFCTR_LD_RETIRED 0x06 36 + #define ARMV8_PMUV3_PERFCTR_ST_RETIRED 0x07 37 + #define ARMV8_PMUV3_PERFCTR_INST_RETIRED 0x08 38 + #define ARMV8_PMUV3_PERFCTR_EXC_TAKEN 0x09 39 + #define ARMV8_PMUV3_PERFCTR_EXC_RETURN 0x0A 40 + #define ARMV8_PMUV3_PERFCTR_CID_WRITE_RETIRED 0x0B 41 + #define ARMV8_PMUV3_PERFCTR_PC_WRITE_RETIRED 0x0C 42 + #define ARMV8_PMUV3_PERFCTR_BR_IMMED_RETIRED 0x0D 43 + #define ARMV8_PMUV3_PERFCTR_BR_RETURN_RETIRED 0x0E 44 + #define ARMV8_PMUV3_PERFCTR_UNALIGNED_LDST_RETIRED 0x0F 45 + #define ARMV8_PMUV3_PERFCTR_BR_MIS_PRED 0x10 46 + #define ARMV8_PMUV3_PERFCTR_CPU_CYCLES 0x11 47 + #define ARMV8_PMUV3_PERFCTR_BR_PRED 0x12 48 + #define ARMV8_PMUV3_PERFCTR_MEM_ACCESS 0x13 49 + #define ARMV8_PMUV3_PERFCTR_L1I_CACHE 0x14 50 + #define ARMV8_PMUV3_PERFCTR_L1D_CACHE_WB 0x15 51 + #define ARMV8_PMUV3_PERFCTR_L2D_CACHE 0x16 52 + #define ARMV8_PMUV3_PERFCTR_L2D_CACHE_REFILL 0x17 53 + #define ARMV8_PMUV3_PERFCTR_L2D_CACHE_WB 0x18 54 + #define ARMV8_PMUV3_PERFCTR_BUS_ACCESS 0x19 55 + #define ARMV8_PMUV3_PERFCTR_MEMORY_ERROR 0x1A 56 + #define ARMV8_PMUV3_PERFCTR_INST_SPEC 0x1B 57 + #define ARMV8_PMUV3_PERFCTR_TTBR_WRITE_RETIRED 0x1C 58 + #define ARMV8_PMUV3_PERFCTR_BUS_CYCLES 0x1D 59 + #define ARMV8_PMUV3_PERFCTR_CHAIN 0x1E 60 + #define ARMV8_PMUV3_PERFCTR_L1D_CACHE_ALLOCATE 0x1F 61 + #define ARMV8_PMUV3_PERFCTR_L2D_CACHE_ALLOCATE 0x20 62 + #define ARMV8_PMUV3_PERFCTR_BR_RETIRED 0x21 63 + #define ARMV8_PMUV3_PERFCTR_BR_MIS_PRED_RETIRED 0x22 64 + #define ARMV8_PMUV3_PERFCTR_STALL_FRONTEND 0x23 65 + #define ARMV8_PMUV3_PERFCTR_STALL_BACKEND 0x24 66 + #define ARMV8_PMUV3_PERFCTR_L1D_TLB 0x25 67 + #define ARMV8_PMUV3_PERFCTR_L1I_TLB 0x26 68 + #define ARMV8_PMUV3_PERFCTR_L2I_CACHE 0x27 69 + #define ARMV8_PMUV3_PERFCTR_L2I_CACHE_REFILL 0x28 70 + #define ARMV8_PMUV3_PERFCTR_L3D_CACHE_ALLOCATE 0x29 71 + #define ARMV8_PMUV3_PERFCTR_L3D_CACHE_REFILL 0x2A 72 + #define ARMV8_PMUV3_PERFCTR_L3D_CACHE 0x2B 73 + #define ARMV8_PMUV3_PERFCTR_L3D_CACHE_WB 0x2C 74 + #define ARMV8_PMUV3_PERFCTR_L2D_TLB_REFILL 0x2D 75 + #define ARMV8_PMUV3_PERFCTR_L2I_TLB_REFILL 0x2E 76 + #define ARMV8_PMUV3_PERFCTR_L2D_TLB 0x2F 77 + #define ARMV8_PMUV3_PERFCTR_L2I_TLB 0x30 78 + #define ARMV8_PMUV3_PERFCTR_REMOTE_ACCESS 0x31 79 + #define ARMV8_PMUV3_PERFCTR_LL_CACHE 0x32 80 + #define ARMV8_PMUV3_PERFCTR_LL_CACHE_MISS 0x33 81 + #define ARMV8_PMUV3_PERFCTR_DTLB_WALK 0x34 82 + #define ARMV8_PMUV3_PERFCTR_ITLB_WALK 0x35 83 + #define ARMV8_PMUV3_PERFCTR_LL_CACHE_RD 0x36 84 + #define ARMV8_PMUV3_PERFCTR_LL_CACHE_MISS_RD 0x37 85 + #define ARMV8_PMUV3_PERFCTR_REMOTE_ACCESS_RD 0x38 86 + 87 + /* Statistical profiling extension microarchitectural events */ 88 + #define ARMV8_SPE_PERFCTR_SAMPLE_POP 0x4000 89 + #define ARMV8_SPE_PERFCTR_SAMPLE_FEED 0x4001 90 + #define ARMV8_SPE_PERFCTR_SAMPLE_FILTRATE 0x4002 91 + #define ARMV8_SPE_PERFCTR_SAMPLE_COLLISION 0x4003 92 + 93 + /* ARMv8 recommended implementation defined event types */ 94 + #define ARMV8_IMPDEF_PERFCTR_L1D_CACHE_RD 0x40 95 + #define ARMV8_IMPDEF_PERFCTR_L1D_CACHE_WR 0x41 96 + #define ARMV8_IMPDEF_PERFCTR_L1D_CACHE_REFILL_RD 0x42 97 + #define ARMV8_IMPDEF_PERFCTR_L1D_CACHE_REFILL_WR 0x43 98 + #define ARMV8_IMPDEF_PERFCTR_L1D_CACHE_REFILL_INNER 0x44 99 + #define ARMV8_IMPDEF_PERFCTR_L1D_CACHE_REFILL_OUTER 0x45 100 + #define ARMV8_IMPDEF_PERFCTR_L1D_CACHE_WB_VICTIM 0x46 101 + #define ARMV8_IMPDEF_PERFCTR_L1D_CACHE_WB_CLEAN 0x47 102 + #define ARMV8_IMPDEF_PERFCTR_L1D_CACHE_INVAL 0x48 103 + 104 + #define ARMV8_IMPDEF_PERFCTR_L1D_TLB_REFILL_RD 0x4C 105 + #define ARMV8_IMPDEF_PERFCTR_L1D_TLB_REFILL_WR 0x4D 106 + #define ARMV8_IMPDEF_PERFCTR_L1D_TLB_RD 0x4E 107 + #define ARMV8_IMPDEF_PERFCTR_L1D_TLB_WR 0x4F 108 + #define ARMV8_IMPDEF_PERFCTR_L2D_CACHE_RD 0x50 109 + #define ARMV8_IMPDEF_PERFCTR_L2D_CACHE_WR 0x51 110 + #define ARMV8_IMPDEF_PERFCTR_L2D_CACHE_REFILL_RD 0x52 111 + #define ARMV8_IMPDEF_PERFCTR_L2D_CACHE_REFILL_WR 0x53 112 + 113 + #define ARMV8_IMPDEF_PERFCTR_L2D_CACHE_WB_VICTIM 0x56 114 + #define ARMV8_IMPDEF_PERFCTR_L2D_CACHE_WB_CLEAN 0x57 115 + #define ARMV8_IMPDEF_PERFCTR_L2D_CACHE_INVAL 0x58 116 + 117 + #define ARMV8_IMPDEF_PERFCTR_L2D_TLB_REFILL_RD 0x5C 118 + #define ARMV8_IMPDEF_PERFCTR_L2D_TLB_REFILL_WR 0x5D 119 + #define ARMV8_IMPDEF_PERFCTR_L2D_TLB_RD 0x5E 120 + #define ARMV8_IMPDEF_PERFCTR_L2D_TLB_WR 0x5F 121 + #define ARMV8_IMPDEF_PERFCTR_BUS_ACCESS_RD 0x60 122 + #define ARMV8_IMPDEF_PERFCTR_BUS_ACCESS_WR 0x61 123 + #define ARMV8_IMPDEF_PERFCTR_BUS_ACCESS_SHARED 0x62 124 + #define ARMV8_IMPDEF_PERFCTR_BUS_ACCESS_NOT_SHARED 0x63 125 + #define ARMV8_IMPDEF_PERFCTR_BUS_ACCESS_NORMAL 0x64 126 + #define ARMV8_IMPDEF_PERFCTR_BUS_ACCESS_PERIPH 0x65 127 + #define ARMV8_IMPDEF_PERFCTR_MEM_ACCESS_RD 0x66 128 + #define ARMV8_IMPDEF_PERFCTR_MEM_ACCESS_WR 0x67 129 + #define ARMV8_IMPDEF_PERFCTR_UNALIGNED_LD_SPEC 0x68 130 + #define ARMV8_IMPDEF_PERFCTR_UNALIGNED_ST_SPEC 0x69 131 + #define ARMV8_IMPDEF_PERFCTR_UNALIGNED_LDST_SPEC 0x6A 132 + 133 + #define ARMV8_IMPDEF_PERFCTR_LDREX_SPEC 0x6C 134 + #define ARMV8_IMPDEF_PERFCTR_STREX_PASS_SPEC 0x6D 135 + #define ARMV8_IMPDEF_PERFCTR_STREX_FAIL_SPEC 0x6E 136 + #define ARMV8_IMPDEF_PERFCTR_STREX_SPEC 0x6F 137 + #define ARMV8_IMPDEF_PERFCTR_LD_SPEC 0x70 138 + #define ARMV8_IMPDEF_PERFCTR_ST_SPEC 0x71 139 + #define ARMV8_IMPDEF_PERFCTR_LDST_SPEC 0x72 140 + #define ARMV8_IMPDEF_PERFCTR_DP_SPEC 0x73 141 + #define ARMV8_IMPDEF_PERFCTR_ASE_SPEC 0x74 142 + #define ARMV8_IMPDEF_PERFCTR_VFP_SPEC 0x75 143 + #define ARMV8_IMPDEF_PERFCTR_PC_WRITE_SPEC 0x76 144 + #define ARMV8_IMPDEF_PERFCTR_CRYPTO_SPEC 0x77 145 + #define ARMV8_IMPDEF_PERFCTR_BR_IMMED_SPEC 0x78 146 + #define ARMV8_IMPDEF_PERFCTR_BR_RETURN_SPEC 0x79 147 + #define ARMV8_IMPDEF_PERFCTR_BR_INDIRECT_SPEC 0x7A 148 + 149 + #define ARMV8_IMPDEF_PERFCTR_ISB_SPEC 0x7C 150 + #define ARMV8_IMPDEF_PERFCTR_DSB_SPEC 0x7D 151 + #define ARMV8_IMPDEF_PERFCTR_DMB_SPEC 0x7E 152 + 153 + #define ARMV8_IMPDEF_PERFCTR_EXC_UNDEF 0x81 154 + #define ARMV8_IMPDEF_PERFCTR_EXC_SVC 0x82 155 + #define ARMV8_IMPDEF_PERFCTR_EXC_PABORT 0x83 156 + #define ARMV8_IMPDEF_PERFCTR_EXC_DABORT 0x84 157 + 158 + #define ARMV8_IMPDEF_PERFCTR_EXC_IRQ 0x86 159 + #define ARMV8_IMPDEF_PERFCTR_EXC_FIQ 0x87 160 + #define ARMV8_IMPDEF_PERFCTR_EXC_SMC 0x88 161 + 162 + #define ARMV8_IMPDEF_PERFCTR_EXC_HVC 0x8A 163 + #define ARMV8_IMPDEF_PERFCTR_EXC_TRAP_PABORT 0x8B 164 + #define ARMV8_IMPDEF_PERFCTR_EXC_TRAP_DABORT 0x8C 165 + #define ARMV8_IMPDEF_PERFCTR_EXC_TRAP_OTHER 0x8D 166 + #define ARMV8_IMPDEF_PERFCTR_EXC_TRAP_IRQ 0x8E 167 + #define ARMV8_IMPDEF_PERFCTR_EXC_TRAP_FIQ 0x8F 168 + #define ARMV8_IMPDEF_PERFCTR_RC_LD_SPEC 0x90 169 + #define ARMV8_IMPDEF_PERFCTR_RC_ST_SPEC 0x91 170 + 171 + #define ARMV8_IMPDEF_PERFCTR_L3D_CACHE_RD 0xA0 172 + #define ARMV8_IMPDEF_PERFCTR_L3D_CACHE_WR 0xA1 173 + #define ARMV8_IMPDEF_PERFCTR_L3D_CACHE_REFILL_RD 0xA2 174 + #define ARMV8_IMPDEF_PERFCTR_L3D_CACHE_REFILL_WR 0xA3 175 + 176 + #define ARMV8_IMPDEF_PERFCTR_L3D_CACHE_WB_VICTIM 0xA6 177 + #define ARMV8_IMPDEF_PERFCTR_L3D_CACHE_WB_CLEAN 0xA7 178 + #define ARMV8_IMPDEF_PERFCTR_L3D_CACHE_INVAL 0xA8 179 + 180 + /* 27 181 * Per-CPU PMCR: config reg 28 182 */ 29 183 #define ARMV8_PMU_PMCR_E (1 << 0) /* Enable all counters */ ··· 204 50 #define ARMV8_PMU_EVTYPE_EVENT 0xffff /* Mask for EVENT bits */ 205 51 206 52 /* 207 - * PMUv3 event types: required events 208 - */ 209 - #define ARMV8_PMUV3_PERFCTR_SW_INCR 0x00 210 - #define ARMV8_PMUV3_PERFCTR_L1D_CACHE_REFILL 0x03 211 - #define ARMV8_PMUV3_PERFCTR_L1D_CACHE 0x04 212 - #define ARMV8_PMUV3_PERFCTR_BR_MIS_PRED 0x10 213 - #define ARMV8_PMUV3_PERFCTR_CPU_CYCLES 0x11 214 - #define ARMV8_PMUV3_PERFCTR_BR_PRED 0x12 215 - 216 - /* 217 53 * Event filters for PMUv3 218 54 */ 219 - #define ARMV8_PMU_EXCLUDE_EL1 (1 << 31) 220 - #define ARMV8_PMU_EXCLUDE_EL0 (1 << 30) 221 - #define ARMV8_PMU_INCLUDE_EL2 (1 << 27) 55 + #define ARMV8_PMU_EXCLUDE_EL1 (1U << 31) 56 + #define ARMV8_PMU_EXCLUDE_EL0 (1U << 30) 57 + #define ARMV8_PMU_INCLUDE_EL2 (1U << 27) 222 58 223 59 /* 224 60 * PMUSERENR: user enable reg
+11 -1
arch/arm64/include/asm/pgtable-hwdef.h
··· 80 80 #define PGDIR_SHIFT ARM64_HW_PGTABLE_LEVEL_SHIFT(4 - CONFIG_PGTABLE_LEVELS) 81 81 #define PGDIR_SIZE (_AC(1, UL) << PGDIR_SHIFT) 82 82 #define PGDIR_MASK (~(PGDIR_SIZE-1)) 83 - #define PTRS_PER_PGD (1 << (VA_BITS - PGDIR_SHIFT)) 83 + #define PTRS_PER_PGD (1 << (MAX_USER_VA_BITS - PGDIR_SHIFT)) 84 84 85 85 /* 86 86 * Section address mask and size definitions. ··· 224 224 #define TCR_TxSZ_WIDTH 6 225 225 #define TCR_T0SZ_MASK (((UL(1) << TCR_TxSZ_WIDTH) - 1) << TCR_T0SZ_OFFSET) 226 226 227 + #define TCR_EPD0_SHIFT 7 228 + #define TCR_EPD0_MASK (UL(1) << TCR_EPD0_SHIFT) 227 229 #define TCR_IRGN0_SHIFT 8 228 230 #define TCR_IRGN0_MASK (UL(3) << TCR_IRGN0_SHIFT) 229 231 #define TCR_IRGN0_NC (UL(0) << TCR_IRGN0_SHIFT) ··· 233 231 #define TCR_IRGN0_WT (UL(2) << TCR_IRGN0_SHIFT) 234 232 #define TCR_IRGN0_WBnWA (UL(3) << TCR_IRGN0_SHIFT) 235 233 234 + #define TCR_EPD1_SHIFT 23 235 + #define TCR_EPD1_MASK (UL(1) << TCR_EPD1_SHIFT) 236 236 #define TCR_IRGN1_SHIFT 24 237 237 #define TCR_IRGN1_MASK (UL(3) << TCR_IRGN1_SHIFT) 238 238 #define TCR_IRGN1_NC (UL(0) << TCR_IRGN1_SHIFT) ··· 308 304 * TTBR_ELx[1] is RES0 in this configuration. 309 305 */ 310 306 #define TTBR_BADDR_MASK_52 (((UL(1) << 46) - 1) << 2) 307 + #endif 308 + 309 + #ifdef CONFIG_ARM64_USER_VA_BITS_52 310 + /* Must be at least 64-byte aligned to prevent corruption of the TTBR */ 311 + #define TTBR1_BADDR_4852_OFFSET (((UL(1) << (52 - PGDIR_SHIFT)) - \ 312 + (UL(1) << (48 - PGDIR_SHIFT))) * 8) 311 313 #endif 312 314 313 315 #endif
+22
arch/arm64/include/asm/pgtable.h
··· 22 22 #include <asm/memory.h> 23 23 #include <asm/pgtable-hwdef.h> 24 24 #include <asm/pgtable-prot.h> 25 + #include <asm/tlbflush.h> 25 26 26 27 /* 27 28 * VMALLOC range. ··· 684 683 pte_t *ptep) 685 684 { 686 685 return __ptep_test_and_clear_young(ptep); 686 + } 687 + 688 + #define __HAVE_ARCH_PTEP_CLEAR_YOUNG_FLUSH 689 + static inline int ptep_clear_flush_young(struct vm_area_struct *vma, 690 + unsigned long address, pte_t *ptep) 691 + { 692 + int young = ptep_test_and_clear_young(vma, address, ptep); 693 + 694 + if (young) { 695 + /* 696 + * We can elide the trailing DSB here since the worst that can 697 + * happen is that a CPU continues to use the young entry in its 698 + * TLB and we mistakenly reclaim the associated page. The 699 + * window for such an event is bounded by the next 700 + * context-switch, which provides a DSB to complete the TLB 701 + * invalidation. 702 + */ 703 + flush_tlb_page_nosync(vma, address); 704 + } 705 + 706 + return young; 687 707 } 688 708 689 709 #ifdef CONFIG_TRANSPARENT_HUGEPAGE
+97
arch/arm64/include/asm/pointer_auth.h
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + #ifndef __ASM_POINTER_AUTH_H 3 + #define __ASM_POINTER_AUTH_H 4 + 5 + #include <linux/bitops.h> 6 + #include <linux/random.h> 7 + 8 + #include <asm/cpufeature.h> 9 + #include <asm/memory.h> 10 + #include <asm/sysreg.h> 11 + 12 + #ifdef CONFIG_ARM64_PTR_AUTH 13 + /* 14 + * Each key is a 128-bit quantity which is split across a pair of 64-bit 15 + * registers (Lo and Hi). 16 + */ 17 + struct ptrauth_key { 18 + unsigned long lo, hi; 19 + }; 20 + 21 + /* 22 + * We give each process its own keys, which are shared by all threads. The keys 23 + * are inherited upon fork(), and reinitialised upon exec*(). 24 + */ 25 + struct ptrauth_keys { 26 + struct ptrauth_key apia; 27 + struct ptrauth_key apib; 28 + struct ptrauth_key apda; 29 + struct ptrauth_key apdb; 30 + struct ptrauth_key apga; 31 + }; 32 + 33 + static inline void ptrauth_keys_init(struct ptrauth_keys *keys) 34 + { 35 + if (system_supports_address_auth()) { 36 + get_random_bytes(&keys->apia, sizeof(keys->apia)); 37 + get_random_bytes(&keys->apib, sizeof(keys->apib)); 38 + get_random_bytes(&keys->apda, sizeof(keys->apda)); 39 + get_random_bytes(&keys->apdb, sizeof(keys->apdb)); 40 + } 41 + 42 + if (system_supports_generic_auth()) 43 + get_random_bytes(&keys->apga, sizeof(keys->apga)); 44 + } 45 + 46 + #define __ptrauth_key_install(k, v) \ 47 + do { \ 48 + struct ptrauth_key __pki_v = (v); \ 49 + write_sysreg_s(__pki_v.lo, SYS_ ## k ## KEYLO_EL1); \ 50 + write_sysreg_s(__pki_v.hi, SYS_ ## k ## KEYHI_EL1); \ 51 + } while (0) 52 + 53 + static inline void ptrauth_keys_switch(struct ptrauth_keys *keys) 54 + { 55 + if (system_supports_address_auth()) { 56 + __ptrauth_key_install(APIA, keys->apia); 57 + __ptrauth_key_install(APIB, keys->apib); 58 + __ptrauth_key_install(APDA, keys->apda); 59 + __ptrauth_key_install(APDB, keys->apdb); 60 + } 61 + 62 + if (system_supports_generic_auth()) 63 + __ptrauth_key_install(APGA, keys->apga); 64 + } 65 + 66 + extern int ptrauth_prctl_reset_keys(struct task_struct *tsk, unsigned long arg); 67 + 68 + /* 69 + * The EL0 pointer bits used by a pointer authentication code. 70 + * This is dependent on TBI0 being enabled, or bits 63:56 would also apply. 71 + */ 72 + #define ptrauth_user_pac_mask() GENMASK(54, vabits_user) 73 + 74 + /* Only valid for EL0 TTBR0 instruction pointers */ 75 + static inline unsigned long ptrauth_strip_insn_pac(unsigned long ptr) 76 + { 77 + return ptr & ~ptrauth_user_pac_mask(); 78 + } 79 + 80 + #define ptrauth_thread_init_user(tsk) \ 81 + do { \ 82 + struct task_struct *__ptiu_tsk = (tsk); \ 83 + ptrauth_keys_init(&__ptiu_tsk->thread.keys_user); \ 84 + ptrauth_keys_switch(&__ptiu_tsk->thread.keys_user); \ 85 + } while (0) 86 + 87 + #define ptrauth_thread_switch(tsk) \ 88 + ptrauth_keys_switch(&(tsk)->thread.keys_user) 89 + 90 + #else /* CONFIG_ARM64_PTR_AUTH */ 91 + #define ptrauth_prctl_reset_keys(tsk, arg) (-EINVAL) 92 + #define ptrauth_strip_insn_pac(lr) (lr) 93 + #define ptrauth_thread_init_user(tsk) 94 + #define ptrauth_thread_switch(tsk) 95 + #endif /* CONFIG_ARM64_PTR_AUTH */ 96 + 97 + #endif /* __ASM_POINTER_AUTH_H */
+89
arch/arm64/include/asm/preempt.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 + #ifndef __ASM_PREEMPT_H 3 + #define __ASM_PREEMPT_H 4 + 5 + #include <linux/thread_info.h> 6 + 7 + #define PREEMPT_NEED_RESCHED BIT(32) 8 + #define PREEMPT_ENABLED (PREEMPT_NEED_RESCHED) 9 + 10 + static inline int preempt_count(void) 11 + { 12 + return READ_ONCE(current_thread_info()->preempt.count); 13 + } 14 + 15 + static inline void preempt_count_set(u64 pc) 16 + { 17 + /* Preserve existing value of PREEMPT_NEED_RESCHED */ 18 + WRITE_ONCE(current_thread_info()->preempt.count, pc); 19 + } 20 + 21 + #define init_task_preempt_count(p) do { \ 22 + task_thread_info(p)->preempt_count = FORK_PREEMPT_COUNT; \ 23 + } while (0) 24 + 25 + #define init_idle_preempt_count(p, cpu) do { \ 26 + task_thread_info(p)->preempt_count = PREEMPT_ENABLED; \ 27 + } while (0) 28 + 29 + static inline void set_preempt_need_resched(void) 30 + { 31 + current_thread_info()->preempt.need_resched = 0; 32 + } 33 + 34 + static inline void clear_preempt_need_resched(void) 35 + { 36 + current_thread_info()->preempt.need_resched = 1; 37 + } 38 + 39 + static inline bool test_preempt_need_resched(void) 40 + { 41 + return !current_thread_info()->preempt.need_resched; 42 + } 43 + 44 + static inline void __preempt_count_add(int val) 45 + { 46 + u32 pc = READ_ONCE(current_thread_info()->preempt.count); 47 + pc += val; 48 + WRITE_ONCE(current_thread_info()->preempt.count, pc); 49 + } 50 + 51 + static inline void __preempt_count_sub(int val) 52 + { 53 + u32 pc = READ_ONCE(current_thread_info()->preempt.count); 54 + pc -= val; 55 + WRITE_ONCE(current_thread_info()->preempt.count, pc); 56 + } 57 + 58 + static inline bool __preempt_count_dec_and_test(void) 59 + { 60 + struct thread_info *ti = current_thread_info(); 61 + u64 pc = READ_ONCE(ti->preempt_count); 62 + 63 + /* Update only the count field, leaving need_resched unchanged */ 64 + WRITE_ONCE(ti->preempt.count, --pc); 65 + 66 + /* 67 + * If we wrote back all zeroes, then we're preemptible and in 68 + * need of a reschedule. Otherwise, we need to reload the 69 + * preempt_count in case the need_resched flag was cleared by an 70 + * interrupt occurring between the non-atomic READ_ONCE/WRITE_ONCE 71 + * pair. 72 + */ 73 + return !pc || !READ_ONCE(ti->preempt_count); 74 + } 75 + 76 + static inline bool should_resched(int preempt_offset) 77 + { 78 + u64 pc = READ_ONCE(current_thread_info()->preempt_count); 79 + return pc == preempt_offset; 80 + } 81 + 82 + #ifdef CONFIG_PREEMPT 83 + void preempt_schedule(void); 84 + #define __preempt_schedule() preempt_schedule() 85 + void preempt_schedule_notrace(void); 86 + #define __preempt_schedule_notrace() preempt_schedule_notrace() 87 + #endif /* CONFIG_PREEMPT */ 88 + 89 + #endif /* __ASM_PREEMPT_H */
+32 -6
arch/arm64/include/asm/processor.h
··· 19 19 #ifndef __ASM_PROCESSOR_H 20 20 #define __ASM_PROCESSOR_H 21 21 22 - #define TASK_SIZE_64 (UL(1) << VA_BITS) 23 - 24 - #define KERNEL_DS UL(-1) 25 - #define USER_DS (TASK_SIZE_64 - 1) 22 + #define KERNEL_DS UL(-1) 23 + #define USER_DS ((UL(1) << MAX_USER_VA_BITS) - 1) 26 24 27 25 /* 28 26 * On arm64 systems, unaligned accesses by the CPU are cheap, and so there is ··· 44 46 #include <asm/hw_breakpoint.h> 45 47 #include <asm/lse.h> 46 48 #include <asm/pgtable-hwdef.h> 49 + #include <asm/pointer_auth.h> 47 50 #include <asm/ptrace.h> 48 51 #include <asm/types.h> 49 52 ··· 52 53 * TASK_SIZE - the maximum size of a user space task. 53 54 * TASK_UNMAPPED_BASE - the lower boundary of the mmap VM area. 54 55 */ 56 + 57 + #define DEFAULT_MAP_WINDOW_64 (UL(1) << VA_BITS) 58 + #define TASK_SIZE_64 (UL(1) << vabits_user) 59 + 55 60 #ifdef CONFIG_COMPAT 56 61 #define TASK_SIZE_32 UL(0x100000000) 57 62 #define TASK_SIZE (test_thread_flag(TIF_32BIT) ? \ 58 63 TASK_SIZE_32 : TASK_SIZE_64) 59 64 #define TASK_SIZE_OF(tsk) (test_tsk_thread_flag(tsk, TIF_32BIT) ? \ 60 65 TASK_SIZE_32 : TASK_SIZE_64) 66 + #define DEFAULT_MAP_WINDOW (test_thread_flag(TIF_32BIT) ? \ 67 + TASK_SIZE_32 : DEFAULT_MAP_WINDOW_64) 61 68 #else 62 69 #define TASK_SIZE TASK_SIZE_64 70 + #define DEFAULT_MAP_WINDOW DEFAULT_MAP_WINDOW_64 63 71 #endif /* CONFIG_COMPAT */ 64 72 65 - #define TASK_UNMAPPED_BASE (PAGE_ALIGN(TASK_SIZE / 4)) 66 - 73 + #ifdef CONFIG_ARM64_FORCE_52BIT 67 74 #define STACK_TOP_MAX TASK_SIZE_64 75 + #define TASK_UNMAPPED_BASE (PAGE_ALIGN(TASK_SIZE / 4)) 76 + #else 77 + #define STACK_TOP_MAX DEFAULT_MAP_WINDOW_64 78 + #define TASK_UNMAPPED_BASE (PAGE_ALIGN(DEFAULT_MAP_WINDOW / 4)) 79 + #endif /* CONFIG_ARM64_FORCE_52BIT */ 80 + 68 81 #ifdef CONFIG_COMPAT 69 82 #define AARCH32_VECTORS_BASE 0xffff0000 70 83 #define STACK_TOP (test_thread_flag(TIF_32BIT) ? \ ··· 84 73 #else 85 74 #define STACK_TOP STACK_TOP_MAX 86 75 #endif /* CONFIG_COMPAT */ 76 + 77 + #ifndef CONFIG_ARM64_FORCE_52BIT 78 + #define arch_get_mmap_end(addr) ((addr > DEFAULT_MAP_WINDOW) ? TASK_SIZE :\ 79 + DEFAULT_MAP_WINDOW) 80 + 81 + #define arch_get_mmap_base(addr, base) ((addr > DEFAULT_MAP_WINDOW) ? \ 82 + base + TASK_SIZE - DEFAULT_MAP_WINDOW :\ 83 + base) 84 + #endif /* CONFIG_ARM64_FORCE_52BIT */ 87 85 88 86 extern phys_addr_t arm64_dma_phys_limit; 89 87 #define ARCH_LOW_ADDRESS_LIMIT (arm64_dma_phys_limit - 1) ··· 147 127 unsigned long fault_address; /* fault info */ 148 128 unsigned long fault_code; /* ESR_EL1 value */ 149 129 struct debug_info debug; /* debugging */ 130 + #ifdef CONFIG_ARM64_PTR_AUTH 131 + struct ptrauth_keys keys_user; 132 + #endif 150 133 }; 151 134 152 135 static inline void arch_thread_struct_whitelist(unsigned long *offset, ··· 292 269 /* Userspace interface for PR_SVE_{SET,GET}_VL prctl()s: */ 293 270 #define SVE_SET_VL(arg) sve_set_current_vl(arg) 294 271 #define SVE_GET_VL() sve_get_current_vl() 272 + 273 + /* PR_PAC_RESET_KEYS prctl */ 274 + #define PAC_RESET_KEYS(tsk, arg) ptrauth_prctl_reset_keys(tsk, arg) 295 275 296 276 /* 297 277 * For CONFIG_GCC_PLUGIN_STACKLEAK
+10 -5
arch/arm64/include/asm/smp.h
··· 17 17 #define __ASM_SMP_H 18 18 19 19 /* Values for secondary_data.status */ 20 + #define CPU_STUCK_REASON_SHIFT (8) 21 + #define CPU_BOOT_STATUS_MASK ((1U << CPU_STUCK_REASON_SHIFT) - 1) 20 22 21 - #define CPU_MMU_OFF (-1) 22 - #define CPU_BOOT_SUCCESS (0) 23 + #define CPU_MMU_OFF (-1) 24 + #define CPU_BOOT_SUCCESS (0) 23 25 /* The cpu invoked ops->cpu_die, synchronise it with cpu_kill */ 24 - #define CPU_KILL_ME (1) 26 + #define CPU_KILL_ME (1) 25 27 /* The cpu couldn't die gracefully and is looping in the kernel */ 26 - #define CPU_STUCK_IN_KERNEL (2) 28 + #define CPU_STUCK_IN_KERNEL (2) 27 29 /* Fatal system error detected by secondary CPU, crash the system */ 28 - #define CPU_PANIC_KERNEL (3) 30 + #define CPU_PANIC_KERNEL (3) 31 + 32 + #define CPU_STUCK_REASON_52_BIT_VA (1U << CPU_STUCK_REASON_SHIFT) 33 + #define CPU_STUCK_REASON_NO_GRAN (2U << CPU_STUCK_REASON_SHIFT) 29 34 30 35 #ifndef __ASSEMBLY__ 31 36
+2 -1
arch/arm64/include/asm/stackprotector.h
··· 34 34 canary &= CANARY_MASK; 35 35 36 36 current->stack_canary = canary; 37 - __stack_chk_guard = current->stack_canary; 37 + if (!IS_ENABLED(CONFIG_STACKPROTECTOR_PER_TASK)) 38 + __stack_chk_guard = current->stack_canary; 38 39 } 39 40 40 41 #endif /* _ASM_STACKPROTECTOR_H */
+72 -35
arch/arm64/include/asm/sysreg.h
··· 20 20 #ifndef __ASM_SYSREG_H 21 21 #define __ASM_SYSREG_H 22 22 23 + #include <linux/const.h> 23 24 #include <linux/stringify.h> 24 25 25 26 /* ··· 105 104 #define SET_PSTATE_UAO(x) __emit_inst(0xd500401f | PSTATE_UAO | ((!!x) << PSTATE_Imm_shift)) 106 105 #define SET_PSTATE_SSBS(x) __emit_inst(0xd500401f | PSTATE_SSBS | ((!!x) << PSTATE_Imm_shift)) 107 106 107 + #define __SYS_BARRIER_INSN(CRm, op2, Rt) \ 108 + __emit_inst(0xd5000000 | sys_insn(0, 3, 3, (CRm), (op2)) | ((Rt) & 0x1f)) 109 + 110 + #define SB_BARRIER_INSN __SYS_BARRIER_INSN(0, 7, 31) 111 + 108 112 #define SYS_DC_ISW sys_insn(1, 0, 7, 6, 2) 109 113 #define SYS_DC_CSW sys_insn(1, 0, 7, 10, 2) 110 114 #define SYS_DC_CISW sys_insn(1, 0, 7, 14, 2) ··· 188 182 #define SYS_TTBR0_EL1 sys_reg(3, 0, 2, 0, 0) 189 183 #define SYS_TTBR1_EL1 sys_reg(3, 0, 2, 0, 1) 190 184 #define SYS_TCR_EL1 sys_reg(3, 0, 2, 0, 2) 185 + 186 + #define SYS_APIAKEYLO_EL1 sys_reg(3, 0, 2, 1, 0) 187 + #define SYS_APIAKEYHI_EL1 sys_reg(3, 0, 2, 1, 1) 188 + #define SYS_APIBKEYLO_EL1 sys_reg(3, 0, 2, 1, 2) 189 + #define SYS_APIBKEYHI_EL1 sys_reg(3, 0, 2, 1, 3) 190 + 191 + #define SYS_APDAKEYLO_EL1 sys_reg(3, 0, 2, 2, 0) 192 + #define SYS_APDAKEYHI_EL1 sys_reg(3, 0, 2, 2, 1) 193 + #define SYS_APDBKEYLO_EL1 sys_reg(3, 0, 2, 2, 2) 194 + #define SYS_APDBKEYHI_EL1 sys_reg(3, 0, 2, 2, 3) 195 + 196 + #define SYS_APGAKEYLO_EL1 sys_reg(3, 0, 2, 3, 0) 197 + #define SYS_APGAKEYHI_EL1 sys_reg(3, 0, 2, 3, 1) 191 198 192 199 #define SYS_ICC_PMR_EL1 sys_reg(3, 0, 4, 6, 0) 193 200 ··· 450 431 #define SYS_ICH_LR15_EL2 __SYS__LR8_EL2(7) 451 432 452 433 /* Common SCTLR_ELx flags. */ 453 - #define SCTLR_ELx_DSSBS (1UL << 44) 454 - #define SCTLR_ELx_EE (1 << 25) 455 - #define SCTLR_ELx_IESB (1 << 21) 456 - #define SCTLR_ELx_WXN (1 << 19) 457 - #define SCTLR_ELx_I (1 << 12) 458 - #define SCTLR_ELx_SA (1 << 3) 459 - #define SCTLR_ELx_C (1 << 2) 460 - #define SCTLR_ELx_A (1 << 1) 461 - #define SCTLR_ELx_M 1 434 + #define SCTLR_ELx_DSSBS (_BITUL(44)) 435 + #define SCTLR_ELx_ENIA (_BITUL(31)) 436 + #define SCTLR_ELx_ENIB (_BITUL(30)) 437 + #define SCTLR_ELx_ENDA (_BITUL(27)) 438 + #define SCTLR_ELx_EE (_BITUL(25)) 439 + #define SCTLR_ELx_IESB (_BITUL(21)) 440 + #define SCTLR_ELx_WXN (_BITUL(19)) 441 + #define SCTLR_ELx_ENDB (_BITUL(13)) 442 + #define SCTLR_ELx_I (_BITUL(12)) 443 + #define SCTLR_ELx_SA (_BITUL(3)) 444 + #define SCTLR_ELx_C (_BITUL(2)) 445 + #define SCTLR_ELx_A (_BITUL(1)) 446 + #define SCTLR_ELx_M (_BITUL(0)) 462 447 463 448 #define SCTLR_ELx_FLAGS (SCTLR_ELx_M | SCTLR_ELx_A | SCTLR_ELx_C | \ 464 449 SCTLR_ELx_SA | SCTLR_ELx_I | SCTLR_ELx_IESB) 465 450 466 451 /* SCTLR_EL2 specific flags. */ 467 - #define SCTLR_EL2_RES1 ((1 << 4) | (1 << 5) | (1 << 11) | (1 << 16) | \ 468 - (1 << 18) | (1 << 22) | (1 << 23) | (1 << 28) | \ 469 - (1 << 29)) 470 - #define SCTLR_EL2_RES0 ((1 << 6) | (1 << 7) | (1 << 8) | (1 << 9) | \ 471 - (1 << 10) | (1 << 13) | (1 << 14) | (1 << 15) | \ 472 - (1 << 17) | (1 << 20) | (1 << 24) | (1 << 26) | \ 473 - (1 << 27) | (1 << 30) | (1 << 31) | \ 452 + #define SCTLR_EL2_RES1 ((_BITUL(4)) | (_BITUL(5)) | (_BITUL(11)) | (_BITUL(16)) | \ 453 + (_BITUL(18)) | (_BITUL(22)) | (_BITUL(23)) | (_BITUL(28)) | \ 454 + (_BITUL(29))) 455 + #define SCTLR_EL2_RES0 ((_BITUL(6)) | (_BITUL(7)) | (_BITUL(8)) | (_BITUL(9)) | \ 456 + (_BITUL(10)) | (_BITUL(13)) | (_BITUL(14)) | (_BITUL(15)) | \ 457 + (_BITUL(17)) | (_BITUL(20)) | (_BITUL(24)) | (_BITUL(26)) | \ 458 + (_BITUL(27)) | (_BITUL(30)) | (_BITUL(31)) | \ 474 459 (0xffffefffUL << 32)) 475 460 476 461 #ifdef CONFIG_CPU_BIG_ENDIAN ··· 496 473 #endif 497 474 498 475 /* SCTLR_EL1 specific flags. */ 499 - #define SCTLR_EL1_UCI (1 << 26) 500 - #define SCTLR_EL1_E0E (1 << 24) 501 - #define SCTLR_EL1_SPAN (1 << 23) 502 - #define SCTLR_EL1_NTWE (1 << 18) 503 - #define SCTLR_EL1_NTWI (1 << 16) 504 - #define SCTLR_EL1_UCT (1 << 15) 505 - #define SCTLR_EL1_DZE (1 << 14) 506 - #define SCTLR_EL1_UMA (1 << 9) 507 - #define SCTLR_EL1_SED (1 << 8) 508 - #define SCTLR_EL1_ITD (1 << 7) 509 - #define SCTLR_EL1_CP15BEN (1 << 5) 510 - #define SCTLR_EL1_SA0 (1 << 4) 476 + #define SCTLR_EL1_UCI (_BITUL(26)) 477 + #define SCTLR_EL1_E0E (_BITUL(24)) 478 + #define SCTLR_EL1_SPAN (_BITUL(23)) 479 + #define SCTLR_EL1_NTWE (_BITUL(18)) 480 + #define SCTLR_EL1_NTWI (_BITUL(16)) 481 + #define SCTLR_EL1_UCT (_BITUL(15)) 482 + #define SCTLR_EL1_DZE (_BITUL(14)) 483 + #define SCTLR_EL1_UMA (_BITUL(9)) 484 + #define SCTLR_EL1_SED (_BITUL(8)) 485 + #define SCTLR_EL1_ITD (_BITUL(7)) 486 + #define SCTLR_EL1_CP15BEN (_BITUL(5)) 487 + #define SCTLR_EL1_SA0 (_BITUL(4)) 511 488 512 - #define SCTLR_EL1_RES1 ((1 << 11) | (1 << 20) | (1 << 22) | (1 << 28) | \ 513 - (1 << 29)) 514 - #define SCTLR_EL1_RES0 ((1 << 6) | (1 << 10) | (1 << 13) | (1 << 17) | \ 515 - (1 << 27) | (1 << 30) | (1 << 31) | \ 489 + #define SCTLR_EL1_RES1 ((_BITUL(11)) | (_BITUL(20)) | (_BITUL(22)) | (_BITUL(28)) | \ 490 + (_BITUL(29))) 491 + #define SCTLR_EL1_RES0 ((_BITUL(6)) | (_BITUL(10)) | (_BITUL(13)) | (_BITUL(17)) | \ 492 + (_BITUL(27)) | (_BITUL(30)) | (_BITUL(31)) | \ 516 493 (0xffffefffUL << 32)) 517 494 518 495 #ifdef CONFIG_CPU_BIG_ENDIAN ··· 551 528 #define ID_AA64ISAR0_AES_SHIFT 4 552 529 553 530 /* id_aa64isar1 */ 531 + #define ID_AA64ISAR1_SB_SHIFT 36 532 + #define ID_AA64ISAR1_GPI_SHIFT 28 533 + #define ID_AA64ISAR1_GPA_SHIFT 24 554 534 #define ID_AA64ISAR1_LRCPC_SHIFT 20 555 535 #define ID_AA64ISAR1_FCMA_SHIFT 16 556 536 #define ID_AA64ISAR1_JSCVT_SHIFT 12 537 + #define ID_AA64ISAR1_API_SHIFT 8 538 + #define ID_AA64ISAR1_APA_SHIFT 4 557 539 #define ID_AA64ISAR1_DPB_SHIFT 0 540 + 541 + #define ID_AA64ISAR1_APA_NI 0x0 542 + #define ID_AA64ISAR1_APA_ARCHITECTED 0x1 543 + #define ID_AA64ISAR1_API_NI 0x0 544 + #define ID_AA64ISAR1_API_IMP_DEF 0x1 545 + #define ID_AA64ISAR1_GPA_NI 0x0 546 + #define ID_AA64ISAR1_GPA_ARCHITECTED 0x1 547 + #define ID_AA64ISAR1_GPI_NI 0x0 548 + #define ID_AA64ISAR1_GPI_IMP_DEF 0x1 558 549 559 550 /* id_aa64pfr0 */ 560 551 #define ID_AA64PFR0_CSV3_SHIFT 60 ··· 713 676 #define ZCR_ELx_LEN_SIZE 9 714 677 #define ZCR_ELx_LEN_MASK 0x1ff 715 678 716 - #define CPACR_EL1_ZEN_EL1EN (1 << 16) /* enable EL1 access */ 717 - #define CPACR_EL1_ZEN_EL0EN (1 << 17) /* enable EL0 access, if EL1EN set */ 679 + #define CPACR_EL1_ZEN_EL1EN (_BITUL(16)) /* enable EL1 access */ 680 + #define CPACR_EL1_ZEN_EL0EN (_BITUL(17)) /* enable EL0 access, if EL1EN set */ 718 681 #define CPACR_EL1_ZEN (CPACR_EL1_ZEN_EL1EN | CPACR_EL1_ZEN_EL0EN) 719 682 720 683 721 684 /* Safe value for MPIDR_EL1: Bit31:RES1, Bit30:U:0, Bit24:MT:0 */ 722 - #define SYS_MPIDR_SAFE_VAL (1UL << 31) 685 + #define SYS_MPIDR_SAFE_VAL (_BITUL(31)) 723 686 724 687 #ifdef __ASSEMBLY__ 725 688
+12 -1
arch/arm64/include/asm/thread_info.h
··· 42 42 #ifdef CONFIG_ARM64_SW_TTBR0_PAN 43 43 u64 ttbr0; /* saved TTBR0_EL1 */ 44 44 #endif 45 - int preempt_count; /* 0 => preemptable, <0 => bug */ 45 + union { 46 + u64 preempt_count; /* 0 => preemptible, <0 => bug */ 47 + struct { 48 + #ifdef CONFIG_CPU_BIG_ENDIAN 49 + u32 need_resched; 50 + u32 count; 51 + #else 52 + u32 count; 53 + u32 need_resched; 54 + #endif 55 + } preempt; 56 + }; 46 57 }; 47 58 48 59 #define thread_saved_pc(tsk) \
+11 -4
arch/arm64/include/asm/tlbflush.h
··· 21 21 22 22 #ifndef __ASSEMBLY__ 23 23 24 + #include <linux/mm_types.h> 24 25 #include <linux/sched.h> 25 26 #include <asm/cputype.h> 26 27 #include <asm/mmu.h> ··· 165 164 dsb(ish); 166 165 } 167 166 168 - static inline void flush_tlb_page(struct vm_area_struct *vma, 169 - unsigned long uaddr) 167 + static inline void flush_tlb_page_nosync(struct vm_area_struct *vma, 168 + unsigned long uaddr) 170 169 { 171 170 unsigned long addr = __TLBI_VADDR(uaddr, ASID(vma->vm_mm)); 172 171 173 172 dsb(ishst); 174 173 __tlbi(vale1is, addr); 175 174 __tlbi_user(vale1is, addr); 175 + } 176 + 177 + static inline void flush_tlb_page(struct vm_area_struct *vma, 178 + unsigned long uaddr) 179 + { 180 + flush_tlb_page_nosync(vma, uaddr); 176 181 dsb(ish); 177 182 } 178 183 ··· 186 179 * This is meant to avoid soft lock-ups on large TLB flushing ranges and not 187 180 * necessarily a performance improvement. 188 181 */ 189 - #define MAX_TLBI_OPS 1024UL 182 + #define MAX_TLBI_OPS PTRS_PER_PTE 190 183 191 184 static inline void __flush_tlb_range(struct vm_area_struct *vma, 192 185 unsigned long start, unsigned long end, ··· 195 188 unsigned long asid = ASID(vma->vm_mm); 196 189 unsigned long addr; 197 190 198 - if ((end - start) > (MAX_TLBI_OPS * stride)) { 191 + if ((end - start) >= (MAX_TLBI_OPS * stride)) { 199 192 flush_tlb_mm(vma->vm_mm); 200 193 return; 201 194 }
+1 -2
arch/arm64/include/asm/uaccess.h
··· 45 45 * Prevent a mispredicted conditional call to set_fs from forwarding 46 46 * the wrong address limit to access_ok under speculation. 47 47 */ 48 - dsb(nsh); 49 - isb(); 48 + spec_bar(); 50 49 51 50 /* On user-mode return, check fs is correct */ 52 51 set_thread_flag(TIF_FSCHECK);
+73
arch/arm64/include/asm/xor.h
··· 1 + /* 2 + * arch/arm64/include/asm/xor.h 3 + * 4 + * Authors: Jackie Liu <liuyun01@kylinos.cn> 5 + * Copyright (C) 2018,Tianjin KYLIN Information Technology Co., Ltd. 6 + * 7 + * This program is free software; you can redistribute it and/or modify 8 + * it under the terms of the GNU General Public License version 2 as 9 + * published by the Free Software Foundation. 10 + */ 11 + 12 + #include <linux/hardirq.h> 13 + #include <asm-generic/xor.h> 14 + #include <asm/hwcap.h> 15 + #include <asm/neon.h> 16 + 17 + #ifdef CONFIG_KERNEL_MODE_NEON 18 + 19 + extern struct xor_block_template const xor_block_inner_neon; 20 + 21 + static void 22 + xor_neon_2(unsigned long bytes, unsigned long *p1, unsigned long *p2) 23 + { 24 + kernel_neon_begin(); 25 + xor_block_inner_neon.do_2(bytes, p1, p2); 26 + kernel_neon_end(); 27 + } 28 + 29 + static void 30 + xor_neon_3(unsigned long bytes, unsigned long *p1, unsigned long *p2, 31 + unsigned long *p3) 32 + { 33 + kernel_neon_begin(); 34 + xor_block_inner_neon.do_3(bytes, p1, p2, p3); 35 + kernel_neon_end(); 36 + } 37 + 38 + static void 39 + xor_neon_4(unsigned long bytes, unsigned long *p1, unsigned long *p2, 40 + unsigned long *p3, unsigned long *p4) 41 + { 42 + kernel_neon_begin(); 43 + xor_block_inner_neon.do_4(bytes, p1, p2, p3, p4); 44 + kernel_neon_end(); 45 + } 46 + 47 + static void 48 + xor_neon_5(unsigned long bytes, unsigned long *p1, unsigned long *p2, 49 + unsigned long *p3, unsigned long *p4, unsigned long *p5) 50 + { 51 + kernel_neon_begin(); 52 + xor_block_inner_neon.do_5(bytes, p1, p2, p3, p4, p5); 53 + kernel_neon_end(); 54 + } 55 + 56 + static struct xor_block_template xor_block_arm64 = { 57 + .name = "arm64_neon", 58 + .do_2 = xor_neon_2, 59 + .do_3 = xor_neon_3, 60 + .do_4 = xor_neon_4, 61 + .do_5 = xor_neon_5 62 + }; 63 + #undef XOR_TRY_TEMPLATES 64 + #define XOR_TRY_TEMPLATES \ 65 + do { \ 66 + xor_speed(&xor_block_8regs); \ 67 + xor_speed(&xor_block_32regs); \ 68 + if (cpu_has_neon()) { \ 69 + xor_speed(&xor_block_arm64);\ 70 + } \ 71 + } while (0) 72 + 73 + #endif /* ! CONFIG_KERNEL_MODE_NEON */
+3
arch/arm64/include/uapi/asm/hwcap.h
··· 49 49 #define HWCAP_ILRCPC (1 << 26) 50 50 #define HWCAP_FLAGM (1 << 27) 51 51 #define HWCAP_SSBS (1 << 28) 52 + #define HWCAP_SB (1 << 29) 53 + #define HWCAP_PACA (1 << 30) 54 + #define HWCAP_PACG (1UL << 31) 52 55 53 56 #endif /* _UAPI__ASM_HWCAP_H */
+7
arch/arm64/include/uapi/asm/ptrace.h
··· 229 229 SVE_PT_SVE_OFFSET + SVE_PT_SVE_SIZE(vq, flags) \ 230 230 : SVE_PT_FPSIMD_OFFSET + SVE_PT_FPSIMD_SIZE(vq, flags)) 231 231 232 + /* pointer authentication masks (NT_ARM_PAC_MASK) */ 233 + 234 + struct user_pac_mask { 235 + __u64 data_mask; 236 + __u64 insn_mask; 237 + }; 238 + 232 239 #endif /* __ASSEMBLY__ */ 233 240 234 241 #endif /* _UAPI__ASM_PTRACE_H */
+4 -2
arch/arm64/kernel/Makefile
··· 30 30 arm64-obj-$(CONFIG_COMPAT) += sys32.o kuser32.o signal32.o \ 31 31 sys_compat.o 32 32 arm64-obj-$(CONFIG_FUNCTION_TRACER) += ftrace.o entry-ftrace.o 33 - arm64-obj-$(CONFIG_MODULES) += arm64ksyms.o module.o 33 + arm64-obj-$(CONFIG_MODULES) += module.o 34 34 arm64-obj-$(CONFIG_ARM64_MODULE_PLTS) += module-plts.o 35 35 arm64-obj-$(CONFIG_PERF_EVENTS) += perf_regs.o perf_callchain.o 36 36 arm64-obj-$(CONFIG_HW_PERF_EVENTS) += perf_event.o ··· 49 49 arm64-obj-$(CONFIG_PARAVIRT) += paravirt.o 50 50 arm64-obj-$(CONFIG_RANDOMIZE_BASE) += kaslr.o 51 51 arm64-obj-$(CONFIG_HIBERNATION) += hibernate.o hibernate-asm.o 52 - arm64-obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o \ 52 + arm64-obj-$(CONFIG_KEXEC_CORE) += machine_kexec.o relocate_kernel.o \ 53 53 cpu-reset.o 54 + arm64-obj-$(CONFIG_KEXEC_FILE) += machine_kexec_file.o kexec_image.o 54 55 arm64-obj-$(CONFIG_ARM64_RELOC_TEST) += arm64-reloc-test.o 55 56 arm64-reloc-test-y := reloc_test_core.o reloc_test_syms.o 56 57 arm64-obj-$(CONFIG_CRASH_DUMP) += crash_dump.o 57 58 arm64-obj-$(CONFIG_CRASH_CORE) += crash_core.o 58 59 arm64-obj-$(CONFIG_ARM_SDE_INTERFACE) += sdei.o 59 60 arm64-obj-$(CONFIG_ARM64_SSBD) += ssbd.o 61 + arm64-obj-$(CONFIG_ARM64_PTR_AUTH) += pointer_auth.o 60 62 61 63 obj-y += $(arm64-obj-y) vdso/ probes/ 62 64 obj-m += $(arm64-obj-m)
-88
arch/arm64/kernel/arm64ksyms.c
··· 1 - /* 2 - * Based on arch/arm/kernel/armksyms.c 3 - * 4 - * Copyright (C) 2000 Russell King 5 - * Copyright (C) 2012 ARM Ltd. 6 - * 7 - * This program is free software; you can redistribute it and/or modify 8 - * it under the terms of the GNU General Public License version 2 as 9 - * published by the Free Software Foundation. 10 - * 11 - * This program is distributed in the hope that it will be useful, 12 - * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 - * GNU General Public License for more details. 15 - * 16 - * You should have received a copy of the GNU General Public License 17 - * along with this program. If not, see <http://www.gnu.org/licenses/>. 18 - */ 19 - 20 - #include <linux/export.h> 21 - #include <linux/sched.h> 22 - #include <linux/string.h> 23 - #include <linux/cryptohash.h> 24 - #include <linux/delay.h> 25 - #include <linux/in6.h> 26 - #include <linux/syscalls.h> 27 - #include <linux/uaccess.h> 28 - #include <linux/io.h> 29 - #include <linux/arm-smccc.h> 30 - #include <linux/kprobes.h> 31 - 32 - #include <asm/checksum.h> 33 - 34 - EXPORT_SYMBOL(copy_page); 35 - EXPORT_SYMBOL(clear_page); 36 - 37 - /* user mem (segment) */ 38 - EXPORT_SYMBOL(__arch_copy_from_user); 39 - EXPORT_SYMBOL(__arch_copy_to_user); 40 - EXPORT_SYMBOL(__arch_clear_user); 41 - EXPORT_SYMBOL(__arch_copy_in_user); 42 - 43 - /* physical memory */ 44 - EXPORT_SYMBOL(memstart_addr); 45 - 46 - /* string / mem functions */ 47 - #ifndef CONFIG_KASAN 48 - EXPORT_SYMBOL(strchr); 49 - EXPORT_SYMBOL(strrchr); 50 - EXPORT_SYMBOL(strcmp); 51 - EXPORT_SYMBOL(strncmp); 52 - EXPORT_SYMBOL(strlen); 53 - EXPORT_SYMBOL(strnlen); 54 - EXPORT_SYMBOL(memcmp); 55 - EXPORT_SYMBOL(memchr); 56 - #endif 57 - 58 - EXPORT_SYMBOL(memset); 59 - EXPORT_SYMBOL(memcpy); 60 - EXPORT_SYMBOL(memmove); 61 - EXPORT_SYMBOL(__memset); 62 - EXPORT_SYMBOL(__memcpy); 63 - EXPORT_SYMBOL(__memmove); 64 - 65 - /* atomic bitops */ 66 - EXPORT_SYMBOL(set_bit); 67 - EXPORT_SYMBOL(test_and_set_bit); 68 - EXPORT_SYMBOL(clear_bit); 69 - EXPORT_SYMBOL(test_and_clear_bit); 70 - EXPORT_SYMBOL(change_bit); 71 - EXPORT_SYMBOL(test_and_change_bit); 72 - 73 - #ifdef CONFIG_FUNCTION_TRACER 74 - EXPORT_SYMBOL(_mcount); 75 - NOKPROBE_SYMBOL(_mcount); 76 - #endif 77 - 78 - /* arm-smccc */ 79 - EXPORT_SYMBOL(__arm_smccc_smc); 80 - EXPORT_SYMBOL(__arm_smccc_hvc); 81 - 82 - /* tishift.S */ 83 - extern long long __ashlti3(long long a, int b); 84 - EXPORT_SYMBOL(__ashlti3); 85 - extern long long __ashrti3(long long a, int b); 86 - EXPORT_SYMBOL(__ashrti3); 87 - extern long long __lshrti3(long long a, int b); 88 - EXPORT_SYMBOL(__lshrti3);
+3
arch/arm64/kernel/asm-offsets.c
··· 46 46 DEFINE(TSK_TI_TTBR0, offsetof(struct task_struct, thread_info.ttbr0)); 47 47 #endif 48 48 DEFINE(TSK_STACK, offsetof(struct task_struct, stack)); 49 + #ifdef CONFIG_STACKPROTECTOR 50 + DEFINE(TSK_STACK_CANARY, offsetof(struct task_struct, stack_canary)); 51 + #endif 49 52 BLANK(); 50 53 DEFINE(THREAD_CPU_CONTEXT, offsetof(struct task_struct, thread.cpu_context)); 51 54 BLANK();
+4 -4
arch/arm64/kernel/cpu-reset.S
··· 22 22 * __cpu_soft_restart(el2_switch, entry, arg0, arg1, arg2) - Helper for 23 23 * cpu_soft_restart. 24 24 * 25 - * @el2_switch: Flag to indicate a swich to EL2 is needed. 25 + * @el2_switch: Flag to indicate a switch to EL2 is needed. 26 26 * @entry: Location to jump to for soft reset. 27 - * arg0: First argument passed to @entry. 28 - * arg1: Second argument passed to @entry. 29 - * arg2: Third argument passed to @entry. 27 + * arg0: First argument passed to @entry. (relocation list) 28 + * arg1: Second argument passed to @entry.(physical kernel entry) 29 + * arg2: Third argument passed to @entry. (physical dtb address) 30 30 * 31 31 * Put the CPU into the same state as it would be if it had been reset, and 32 32 * branch to what would be the reset vector. It must be executed with the
+67 -82
arch/arm64/kernel/cpu_errata.c
··· 135 135 const char *hyp_vecs_start, 136 136 const char *hyp_vecs_end) 137 137 { 138 - static DEFINE_SPINLOCK(bp_lock); 138 + static DEFINE_RAW_SPINLOCK(bp_lock); 139 139 int cpu, slot = -1; 140 140 141 141 /* ··· 147 147 return; 148 148 } 149 149 150 - spin_lock(&bp_lock); 150 + raw_spin_lock(&bp_lock); 151 151 for_each_possible_cpu(cpu) { 152 152 if (per_cpu(bp_hardening_data.fn, cpu) == fn) { 153 153 slot = per_cpu(bp_hardening_data.hyp_vectors_slot, cpu); ··· 163 163 164 164 __this_cpu_write(bp_hardening_data.hyp_vectors_slot, slot); 165 165 __this_cpu_write(bp_hardening_data.fn, fn); 166 - spin_unlock(&bp_lock); 166 + raw_spin_unlock(&bp_lock); 167 167 } 168 168 #else 169 169 #define __smccc_workaround_1_smc_start NULL ··· 507 507 .type = ARM64_CPUCAP_LOCAL_CPU_ERRATUM, \ 508 508 CAP_MIDR_RANGE_LIST(midr_list) 509 509 510 - /* 511 - * Generic helper for handling capabilties with multiple (match,enable) pairs 512 - * of call backs, sharing the same capability bit. 513 - * Iterate over each entry to see if at least one matches. 514 - */ 515 - static bool __maybe_unused 516 - multi_entry_cap_matches(const struct arm64_cpu_capabilities *entry, int scope) 517 - { 518 - const struct arm64_cpu_capabilities *caps; 519 - 520 - for (caps = entry->match_list; caps->matches; caps++) 521 - if (caps->matches(caps, scope)) 522 - return true; 523 - 524 - return false; 525 - } 526 - 527 - /* 528 - * Take appropriate action for all matching entries in the shared capability 529 - * entry. 530 - */ 531 - static void __maybe_unused 532 - multi_entry_cap_cpu_enable(const struct arm64_cpu_capabilities *entry) 533 - { 534 - const struct arm64_cpu_capabilities *caps; 535 - 536 - for (caps = entry->match_list; caps->matches; caps++) 537 - if (caps->matches(caps, SCOPE_LOCAL_CPU) && 538 - caps->cpu_enable) 539 - caps->cpu_enable(caps); 540 - } 541 - 542 510 #ifdef CONFIG_HARDEN_BRANCH_PREDICTOR 543 511 544 512 /* ··· 552 584 553 585 #endif 554 586 555 - const struct arm64_cpu_capabilities arm64_errata[] = { 587 + #ifdef CONFIG_CAVIUM_ERRATUM_27456 588 + static const struct midr_range cavium_erratum_27456_cpus[] = { 589 + /* Cavium ThunderX, T88 pass 1.x - 2.1 */ 590 + MIDR_RANGE(MIDR_THUNDERX, 0, 0, 1, 1), 591 + /* Cavium ThunderX, T81 pass 1.0 */ 592 + MIDR_REV(MIDR_THUNDERX_81XX, 0, 0), 593 + {}, 594 + }; 595 + #endif 596 + 597 + #ifdef CONFIG_CAVIUM_ERRATUM_30115 598 + static const struct midr_range cavium_erratum_30115_cpus[] = { 599 + /* Cavium ThunderX, T88 pass 1.x - 2.2 */ 600 + MIDR_RANGE(MIDR_THUNDERX, 0, 0, 1, 2), 601 + /* Cavium ThunderX, T81 pass 1.0 - 1.2 */ 602 + MIDR_REV_RANGE(MIDR_THUNDERX_81XX, 0, 0, 2), 603 + /* Cavium ThunderX, T83 pass 1.0 */ 604 + MIDR_REV(MIDR_THUNDERX_83XX, 0, 0), 605 + {}, 606 + }; 607 + #endif 608 + 609 + #ifdef CONFIG_QCOM_FALKOR_ERRATUM_1003 610 + static const struct arm64_cpu_capabilities qcom_erratum_1003_list[] = { 611 + { 612 + ERRATA_MIDR_REV(MIDR_QCOM_FALKOR_V1, 0, 0), 613 + }, 614 + { 615 + .midr_range.model = MIDR_QCOM_KRYO, 616 + .matches = is_kryo_midr, 617 + }, 618 + {}, 619 + }; 620 + #endif 621 + 622 + #ifdef CONFIG_ARM64_WORKAROUND_CLEAN_CACHE 623 + static const struct midr_range workaround_clean_cache[] = { 556 624 #if defined(CONFIG_ARM64_ERRATUM_826319) || \ 557 625 defined(CONFIG_ARM64_ERRATUM_827319) || \ 558 626 defined(CONFIG_ARM64_ERRATUM_824069) 559 - { 560 - /* Cortex-A53 r0p[012] */ 561 - .desc = "ARM errata 826319, 827319, 824069", 562 - .capability = ARM64_WORKAROUND_CLEAN_CACHE, 563 - ERRATA_MIDR_REV_RANGE(MIDR_CORTEX_A53, 0, 0, 2), 564 - .cpu_enable = cpu_enable_cache_maint_trap, 565 - }, 627 + /* Cortex-A53 r0p[012]: ARM errata 826319, 827319, 824069 */ 628 + MIDR_REV_RANGE(MIDR_CORTEX_A53, 0, 0, 2), 566 629 #endif 567 - #ifdef CONFIG_ARM64_ERRATUM_819472 630 + #ifdef CONFIG_ARM64_ERRATUM_819472 631 + /* Cortex-A53 r0p[01] : ARM errata 819472 */ 632 + MIDR_REV_RANGE(MIDR_CORTEX_A53, 0, 0, 1), 633 + #endif 634 + {}, 635 + }; 636 + #endif 637 + 638 + const struct arm64_cpu_capabilities arm64_errata[] = { 639 + #ifdef CONFIG_ARM64_WORKAROUND_CLEAN_CACHE 568 640 { 569 - /* Cortex-A53 r0p[01] */ 570 - .desc = "ARM errata 819472", 641 + .desc = "ARM errata 826319, 827319, 824069, 819472", 571 642 .capability = ARM64_WORKAROUND_CLEAN_CACHE, 572 - ERRATA_MIDR_REV_RANGE(MIDR_CORTEX_A53, 0, 0, 1), 643 + ERRATA_MIDR_RANGE_LIST(workaround_clean_cache), 573 644 .cpu_enable = cpu_enable_cache_maint_trap, 574 645 }, 575 646 #endif ··· 659 652 #endif 660 653 #ifdef CONFIG_CAVIUM_ERRATUM_27456 661 654 { 662 - /* Cavium ThunderX, T88 pass 1.x - 2.1 */ 663 655 .desc = "Cavium erratum 27456", 664 656 .capability = ARM64_WORKAROUND_CAVIUM_27456, 665 - ERRATA_MIDR_RANGE(MIDR_THUNDERX, 666 - 0, 0, 667 - 1, 1), 668 - }, 669 - { 670 - /* Cavium ThunderX, T81 pass 1.0 */ 671 - .desc = "Cavium erratum 27456", 672 - .capability = ARM64_WORKAROUND_CAVIUM_27456, 673 - ERRATA_MIDR_REV(MIDR_THUNDERX_81XX, 0, 0), 657 + ERRATA_MIDR_RANGE_LIST(cavium_erratum_27456_cpus), 674 658 }, 675 659 #endif 676 660 #ifdef CONFIG_CAVIUM_ERRATUM_30115 677 661 { 678 - /* Cavium ThunderX, T88 pass 1.x - 2.2 */ 679 662 .desc = "Cavium erratum 30115", 680 663 .capability = ARM64_WORKAROUND_CAVIUM_30115, 681 - ERRATA_MIDR_RANGE(MIDR_THUNDERX, 682 - 0, 0, 683 - 1, 2), 684 - }, 685 - { 686 - /* Cavium ThunderX, T81 pass 1.0 - 1.2 */ 687 - .desc = "Cavium erratum 30115", 688 - .capability = ARM64_WORKAROUND_CAVIUM_30115, 689 - ERRATA_MIDR_REV_RANGE(MIDR_THUNDERX_81XX, 0, 0, 2), 690 - }, 691 - { 692 - /* Cavium ThunderX, T83 pass 1.0 */ 693 - .desc = "Cavium erratum 30115", 694 - .capability = ARM64_WORKAROUND_CAVIUM_30115, 695 - ERRATA_MIDR_REV(MIDR_THUNDERX_83XX, 0, 0), 664 + ERRATA_MIDR_RANGE_LIST(cavium_erratum_30115_cpus), 696 665 }, 697 666 #endif 698 667 { ··· 680 697 }, 681 698 #ifdef CONFIG_QCOM_FALKOR_ERRATUM_1003 682 699 { 683 - .desc = "Qualcomm Technologies Falkor erratum 1003", 700 + .desc = "Qualcomm Technologies Falkor/Kryo erratum 1003", 684 701 .capability = ARM64_WORKAROUND_QCOM_FALKOR_E1003, 685 - ERRATA_MIDR_REV(MIDR_QCOM_FALKOR_V1, 0, 0), 686 - }, 687 - { 688 - .desc = "Qualcomm Technologies Kryo erratum 1003", 689 - .capability = ARM64_WORKAROUND_QCOM_FALKOR_E1003, 690 - .type = ARM64_CPUCAP_LOCAL_CPU_ERRATUM, 691 - .midr_range.model = MIDR_QCOM_KRYO, 692 - .matches = is_kryo_midr, 702 + .matches = cpucap_multi_entry_cap_matches, 703 + .match_list = qcom_erratum_1003_list, 693 704 }, 694 705 #endif 695 706 #ifdef CONFIG_ARM64_WORKAROUND_REPEAT_TLBI ··· 728 751 /* Cortex-A76 r0p0 to r2p0 */ 729 752 .desc = "ARM erratum 1188873", 730 753 .capability = ARM64_WORKAROUND_1188873, 754 + ERRATA_MIDR_RANGE(MIDR_CORTEX_A76, 0, 0, 2, 0), 755 + }, 756 + #endif 757 + #ifdef CONFIG_ARM64_ERRATUM_1165522 758 + { 759 + /* Cortex-A76 r0p0 to r2p0 */ 760 + .desc = "ARM erratum 1165522", 761 + .capability = ARM64_WORKAROUND_1165522, 731 762 ERRATA_MIDR_RANGE(MIDR_CORTEX_A76, 0, 0, 2, 0), 732 763 }, 733 764 #endif
+230 -84
arch/arm64/kernel/cpufeature.c
··· 52 52 53 53 DECLARE_BITMAP(cpu_hwcaps, ARM64_NCAPS); 54 54 EXPORT_SYMBOL(cpu_hwcaps); 55 + static struct arm64_cpu_capabilities const __ro_after_init *cpu_hwcaps_ptrs[ARM64_NCAPS]; 55 56 56 57 /* 57 58 * Flag to indicate if we have computed the system wide ··· 142 141 }; 143 142 144 143 static const struct arm64_ftr_bits ftr_id_aa64isar1[] = { 144 + ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64ISAR1_SB_SHIFT, 4, 0), 145 + ARM64_FTR_BITS(FTR_VISIBLE_IF_IS_ENABLED(CONFIG_ARM64_PTR_AUTH), 146 + FTR_STRICT, FTR_LOWER_SAFE, ID_AA64ISAR1_GPI_SHIFT, 4, 0), 147 + ARM64_FTR_BITS(FTR_VISIBLE_IF_IS_ENABLED(CONFIG_ARM64_PTR_AUTH), 148 + FTR_STRICT, FTR_LOWER_SAFE, ID_AA64ISAR1_GPA_SHIFT, 4, 0), 145 149 ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64ISAR1_LRCPC_SHIFT, 4, 0), 146 150 ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64ISAR1_FCMA_SHIFT, 4, 0), 147 151 ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64ISAR1_JSCVT_SHIFT, 4, 0), 152 + ARM64_FTR_BITS(FTR_VISIBLE_IF_IS_ENABLED(CONFIG_ARM64_PTR_AUTH), 153 + FTR_STRICT, FTR_LOWER_SAFE, ID_AA64ISAR1_API_SHIFT, 4, 0), 154 + ARM64_FTR_BITS(FTR_VISIBLE_IF_IS_ENABLED(CONFIG_ARM64_PTR_AUTH), 155 + FTR_STRICT, FTR_LOWER_SAFE, ID_AA64ISAR1_APA_SHIFT, 4, 0), 148 156 ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64ISAR1_DPB_SHIFT, 4, 0), 149 157 ARM64_FTR_END, 150 158 }; ··· 528 518 } 529 519 530 520 extern const struct arm64_cpu_capabilities arm64_errata[]; 521 + static const struct arm64_cpu_capabilities arm64_features[]; 522 + 523 + static void __init 524 + init_cpu_hwcaps_indirect_list_from_array(const struct arm64_cpu_capabilities *caps) 525 + { 526 + for (; caps->matches; caps++) { 527 + if (WARN(caps->capability >= ARM64_NCAPS, 528 + "Invalid capability %d\n", caps->capability)) 529 + continue; 530 + if (WARN(cpu_hwcaps_ptrs[caps->capability], 531 + "Duplicate entry for capability %d\n", 532 + caps->capability)) 533 + continue; 534 + cpu_hwcaps_ptrs[caps->capability] = caps; 535 + } 536 + } 537 + 538 + static void __init init_cpu_hwcaps_indirect_list(void) 539 + { 540 + init_cpu_hwcaps_indirect_list_from_array(arm64_features); 541 + init_cpu_hwcaps_indirect_list_from_array(arm64_errata); 542 + } 543 + 531 544 static void __init setup_boot_cpu_capabilities(void); 532 545 533 546 void __init init_cpu_features(struct cpuinfo_arm64 *info) ··· 595 562 init_cpu_ftr_reg(SYS_ZCR_EL1, info->reg_zcr); 596 563 sve_init_vq_map(); 597 564 } 565 + 566 + /* 567 + * Initialize the indirect array of CPU hwcaps capabilities pointers 568 + * before we handle the boot CPU below. 569 + */ 570 + init_cpu_hwcaps_indirect_list(); 598 571 599 572 /* 600 573 * Detect and enable early CPU capabilities based on the boot CPU, ··· 954 915 static const struct midr_range kpti_safe_list[] = { 955 916 MIDR_ALL_VERSIONS(MIDR_CAVIUM_THUNDERX2), 956 917 MIDR_ALL_VERSIONS(MIDR_BRCM_VULCAN), 918 + MIDR_ALL_VERSIONS(MIDR_CORTEX_A35), 919 + MIDR_ALL_VERSIONS(MIDR_CORTEX_A53), 920 + MIDR_ALL_VERSIONS(MIDR_CORTEX_A55), 921 + MIDR_ALL_VERSIONS(MIDR_CORTEX_A57), 922 + MIDR_ALL_VERSIONS(MIDR_CORTEX_A72), 923 + MIDR_ALL_VERSIONS(MIDR_CORTEX_A73), 957 924 { /* sentinel */ } 958 925 }; 959 926 char const *str = "command line option"; ··· 1190 1145 } 1191 1146 #endif /* CONFIG_ARM64_RAS_EXTN */ 1192 1147 1148 + #ifdef CONFIG_ARM64_PTR_AUTH 1149 + static void cpu_enable_address_auth(struct arm64_cpu_capabilities const *cap) 1150 + { 1151 + sysreg_clear_set(sctlr_el1, 0, SCTLR_ELx_ENIA | SCTLR_ELx_ENIB | 1152 + SCTLR_ELx_ENDA | SCTLR_ELx_ENDB); 1153 + } 1154 + #endif /* CONFIG_ARM64_PTR_AUTH */ 1155 + 1193 1156 static const struct arm64_cpu_capabilities arm64_features[] = { 1194 1157 { 1195 1158 .desc = "GIC system register CPU interface", ··· 1421 1368 .cpu_enable = cpu_enable_cnp, 1422 1369 }, 1423 1370 #endif 1371 + { 1372 + .desc = "Speculation barrier (SB)", 1373 + .capability = ARM64_HAS_SB, 1374 + .type = ARM64_CPUCAP_SYSTEM_FEATURE, 1375 + .matches = has_cpuid_feature, 1376 + .sys_reg = SYS_ID_AA64ISAR1_EL1, 1377 + .field_pos = ID_AA64ISAR1_SB_SHIFT, 1378 + .sign = FTR_UNSIGNED, 1379 + .min_field_value = 1, 1380 + }, 1381 + #ifdef CONFIG_ARM64_PTR_AUTH 1382 + { 1383 + .desc = "Address authentication (architected algorithm)", 1384 + .capability = ARM64_HAS_ADDRESS_AUTH_ARCH, 1385 + .type = ARM64_CPUCAP_SYSTEM_FEATURE, 1386 + .sys_reg = SYS_ID_AA64ISAR1_EL1, 1387 + .sign = FTR_UNSIGNED, 1388 + .field_pos = ID_AA64ISAR1_APA_SHIFT, 1389 + .min_field_value = ID_AA64ISAR1_APA_ARCHITECTED, 1390 + .matches = has_cpuid_feature, 1391 + .cpu_enable = cpu_enable_address_auth, 1392 + }, 1393 + { 1394 + .desc = "Address authentication (IMP DEF algorithm)", 1395 + .capability = ARM64_HAS_ADDRESS_AUTH_IMP_DEF, 1396 + .type = ARM64_CPUCAP_SYSTEM_FEATURE, 1397 + .sys_reg = SYS_ID_AA64ISAR1_EL1, 1398 + .sign = FTR_UNSIGNED, 1399 + .field_pos = ID_AA64ISAR1_API_SHIFT, 1400 + .min_field_value = ID_AA64ISAR1_API_IMP_DEF, 1401 + .matches = has_cpuid_feature, 1402 + .cpu_enable = cpu_enable_address_auth, 1403 + }, 1404 + { 1405 + .desc = "Generic authentication (architected algorithm)", 1406 + .capability = ARM64_HAS_GENERIC_AUTH_ARCH, 1407 + .type = ARM64_CPUCAP_SYSTEM_FEATURE, 1408 + .sys_reg = SYS_ID_AA64ISAR1_EL1, 1409 + .sign = FTR_UNSIGNED, 1410 + .field_pos = ID_AA64ISAR1_GPA_SHIFT, 1411 + .min_field_value = ID_AA64ISAR1_GPA_ARCHITECTED, 1412 + .matches = has_cpuid_feature, 1413 + }, 1414 + { 1415 + .desc = "Generic authentication (IMP DEF algorithm)", 1416 + .capability = ARM64_HAS_GENERIC_AUTH_IMP_DEF, 1417 + .type = ARM64_CPUCAP_SYSTEM_FEATURE, 1418 + .sys_reg = SYS_ID_AA64ISAR1_EL1, 1419 + .sign = FTR_UNSIGNED, 1420 + .field_pos = ID_AA64ISAR1_GPI_SHIFT, 1421 + .min_field_value = ID_AA64ISAR1_GPI_IMP_DEF, 1422 + .matches = has_cpuid_feature, 1423 + }, 1424 + #endif /* CONFIG_ARM64_PTR_AUTH */ 1424 1425 {}, 1425 1426 }; 1426 1427 1427 - #define HWCAP_CAP(reg, field, s, min_value, cap_type, cap) \ 1428 - { \ 1429 - .desc = #cap, \ 1430 - .type = ARM64_CPUCAP_SYSTEM_FEATURE, \ 1431 - .matches = has_cpuid_feature, \ 1432 - .sys_reg = reg, \ 1433 - .field_pos = field, \ 1434 - .sign = s, \ 1435 - .min_field_value = min_value, \ 1436 - .hwcap_type = cap_type, \ 1437 - .hwcap = cap, \ 1428 + #define HWCAP_CPUID_MATCH(reg, field, s, min_value) \ 1429 + .matches = has_cpuid_feature, \ 1430 + .sys_reg = reg, \ 1431 + .field_pos = field, \ 1432 + .sign = s, \ 1433 + .min_field_value = min_value, 1434 + 1435 + #define __HWCAP_CAP(name, cap_type, cap) \ 1436 + .desc = name, \ 1437 + .type = ARM64_CPUCAP_SYSTEM_FEATURE, \ 1438 + .hwcap_type = cap_type, \ 1439 + .hwcap = cap, \ 1440 + 1441 + #define HWCAP_CAP(reg, field, s, min_value, cap_type, cap) \ 1442 + { \ 1443 + __HWCAP_CAP(#cap, cap_type, cap) \ 1444 + HWCAP_CPUID_MATCH(reg, field, s, min_value) \ 1438 1445 } 1446 + 1447 + #define HWCAP_MULTI_CAP(list, cap_type, cap) \ 1448 + { \ 1449 + __HWCAP_CAP(#cap, cap_type, cap) \ 1450 + .matches = cpucap_multi_entry_cap_matches, \ 1451 + .match_list = list, \ 1452 + } 1453 + 1454 + #ifdef CONFIG_ARM64_PTR_AUTH 1455 + static const struct arm64_cpu_capabilities ptr_auth_hwcap_addr_matches[] = { 1456 + { 1457 + HWCAP_CPUID_MATCH(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_APA_SHIFT, 1458 + FTR_UNSIGNED, ID_AA64ISAR1_APA_ARCHITECTED) 1459 + }, 1460 + { 1461 + HWCAP_CPUID_MATCH(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_API_SHIFT, 1462 + FTR_UNSIGNED, ID_AA64ISAR1_API_IMP_DEF) 1463 + }, 1464 + {}, 1465 + }; 1466 + 1467 + static const struct arm64_cpu_capabilities ptr_auth_hwcap_gen_matches[] = { 1468 + { 1469 + HWCAP_CPUID_MATCH(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_GPA_SHIFT, 1470 + FTR_UNSIGNED, ID_AA64ISAR1_GPA_ARCHITECTED) 1471 + }, 1472 + { 1473 + HWCAP_CPUID_MATCH(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_GPI_SHIFT, 1474 + FTR_UNSIGNED, ID_AA64ISAR1_GPI_IMP_DEF) 1475 + }, 1476 + {}, 1477 + }; 1478 + #endif 1439 1479 1440 1480 static const struct arm64_cpu_capabilities arm64_elf_hwcaps[] = { 1441 1481 HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_AES_SHIFT, FTR_UNSIGNED, 2, CAP_HWCAP, HWCAP_PMULL), ··· 1555 1409 HWCAP_CAP(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_FCMA_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, HWCAP_FCMA), 1556 1410 HWCAP_CAP(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_LRCPC_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, HWCAP_LRCPC), 1557 1411 HWCAP_CAP(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_LRCPC_SHIFT, FTR_UNSIGNED, 2, CAP_HWCAP, HWCAP_ILRCPC), 1412 + HWCAP_CAP(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_SB_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, HWCAP_SB), 1558 1413 HWCAP_CAP(SYS_ID_AA64MMFR2_EL1, ID_AA64MMFR2_AT_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, HWCAP_USCAT), 1559 1414 #ifdef CONFIG_ARM64_SVE 1560 1415 HWCAP_CAP(SYS_ID_AA64PFR0_EL1, ID_AA64PFR0_SVE_SHIFT, FTR_UNSIGNED, ID_AA64PFR0_SVE, CAP_HWCAP, HWCAP_SVE), 1561 1416 #endif 1562 1417 HWCAP_CAP(SYS_ID_AA64PFR1_EL1, ID_AA64PFR1_SSBS_SHIFT, FTR_UNSIGNED, ID_AA64PFR1_SSBS_PSTATE_INSNS, CAP_HWCAP, HWCAP_SSBS), 1418 + #ifdef CONFIG_ARM64_PTR_AUTH 1419 + HWCAP_MULTI_CAP(ptr_auth_hwcap_addr_matches, CAP_HWCAP, HWCAP_PACA), 1420 + HWCAP_MULTI_CAP(ptr_auth_hwcap_gen_matches, CAP_HWCAP, HWCAP_PACG), 1421 + #endif 1563 1422 {}, 1564 1423 }; 1565 1424 ··· 1633 1482 cap_set_elf_hwcap(hwcaps); 1634 1483 } 1635 1484 1636 - /* 1637 - * Check if the current CPU has a given feature capability. 1638 - * Should be called from non-preemptible context. 1639 - */ 1640 - static bool __this_cpu_has_cap(const struct arm64_cpu_capabilities *cap_array, 1641 - unsigned int cap) 1485 + static void update_cpu_capabilities(u16 scope_mask) 1642 1486 { 1487 + int i; 1643 1488 const struct arm64_cpu_capabilities *caps; 1644 1489 1645 - if (WARN_ON(preemptible())) 1646 - return false; 1647 - 1648 - for (caps = cap_array; caps->matches; caps++) 1649 - if (caps->capability == cap) 1650 - return caps->matches(caps, SCOPE_LOCAL_CPU); 1651 - 1652 - return false; 1653 - } 1654 - 1655 - static void __update_cpu_capabilities(const struct arm64_cpu_capabilities *caps, 1656 - u16 scope_mask, const char *info) 1657 - { 1658 1490 scope_mask &= ARM64_CPUCAP_SCOPE_MASK; 1659 - for (; caps->matches; caps++) { 1660 - if (!(caps->type & scope_mask) || 1491 + for (i = 0; i < ARM64_NCAPS; i++) { 1492 + caps = cpu_hwcaps_ptrs[i]; 1493 + if (!caps || !(caps->type & scope_mask) || 1494 + cpus_have_cap(caps->capability) || 1661 1495 !caps->matches(caps, cpucap_default_scope(caps))) 1662 1496 continue; 1663 1497 1664 - if (!cpus_have_cap(caps->capability) && caps->desc) 1665 - pr_info("%s %s\n", info, caps->desc); 1498 + if (caps->desc) 1499 + pr_info("detected: %s\n", caps->desc); 1666 1500 cpus_set_cap(caps->capability); 1667 1501 } 1668 1502 } 1669 1503 1670 - static void update_cpu_capabilities(u16 scope_mask) 1504 + /* 1505 + * Enable all the available capabilities on this CPU. The capabilities 1506 + * with BOOT_CPU scope are handled separately and hence skipped here. 1507 + */ 1508 + static int cpu_enable_non_boot_scope_capabilities(void *__unused) 1671 1509 { 1672 - __update_cpu_capabilities(arm64_errata, scope_mask, 1673 - "enabling workaround for"); 1674 - __update_cpu_capabilities(arm64_features, scope_mask, "detected:"); 1675 - } 1510 + int i; 1511 + u16 non_boot_scope = SCOPE_ALL & ~SCOPE_BOOT_CPU; 1676 1512 1677 - static int __enable_cpu_capability(void *arg) 1678 - { 1679 - const struct arm64_cpu_capabilities *cap = arg; 1513 + for_each_available_cap(i) { 1514 + const struct arm64_cpu_capabilities *cap = cpu_hwcaps_ptrs[i]; 1680 1515 1681 - cap->cpu_enable(cap); 1516 + if (WARN_ON(!cap)) 1517 + continue; 1518 + 1519 + if (!(cap->type & non_boot_scope)) 1520 + continue; 1521 + 1522 + if (cap->cpu_enable) 1523 + cap->cpu_enable(cap); 1524 + } 1682 1525 return 0; 1683 1526 } 1684 1527 ··· 1680 1535 * Run through the enabled capabilities and enable() it on all active 1681 1536 * CPUs 1682 1537 */ 1683 - static void __init 1684 - __enable_cpu_capabilities(const struct arm64_cpu_capabilities *caps, 1685 - u16 scope_mask) 1538 + static void __init enable_cpu_capabilities(u16 scope_mask) 1686 1539 { 1687 - scope_mask &= ARM64_CPUCAP_SCOPE_MASK; 1688 - for (; caps->matches; caps++) { 1689 - unsigned int num = caps->capability; 1540 + int i; 1541 + const struct arm64_cpu_capabilities *caps; 1542 + bool boot_scope; 1690 1543 1691 - if (!(caps->type & scope_mask) || !cpus_have_cap(num)) 1544 + scope_mask &= ARM64_CPUCAP_SCOPE_MASK; 1545 + boot_scope = !!(scope_mask & SCOPE_BOOT_CPU); 1546 + 1547 + for (i = 0; i < ARM64_NCAPS; i++) { 1548 + unsigned int num; 1549 + 1550 + caps = cpu_hwcaps_ptrs[i]; 1551 + if (!caps || !(caps->type & scope_mask)) 1552 + continue; 1553 + num = caps->capability; 1554 + if (!cpus_have_cap(num)) 1692 1555 continue; 1693 1556 1694 1557 /* Ensure cpus_have_const_cap(num) works */ 1695 1558 static_branch_enable(&cpu_hwcap_keys[num]); 1696 1559 1697 - if (caps->cpu_enable) { 1560 + if (boot_scope && caps->cpu_enable) 1698 1561 /* 1699 1562 * Capabilities with SCOPE_BOOT_CPU scope are finalised 1700 1563 * before any secondary CPU boots. Thus, each secondary ··· 1711 1558 * the boot CPU, for which the capability must be 1712 1559 * enabled here. This approach avoids costly 1713 1560 * stop_machine() calls for this case. 1714 - * 1715 - * Otherwise, use stop_machine() as it schedules the 1716 - * work allowing us to modify PSTATE, instead of 1717 - * on_each_cpu() which uses an IPI, giving us a PSTATE 1718 - * that disappears when we return. 1719 1561 */ 1720 - if (scope_mask & SCOPE_BOOT_CPU) 1721 - caps->cpu_enable(caps); 1722 - else 1723 - stop_machine(__enable_cpu_capability, 1724 - (void *)caps, cpu_online_mask); 1725 - } 1562 + caps->cpu_enable(caps); 1726 1563 } 1727 - } 1728 1564 1729 - static void __init enable_cpu_capabilities(u16 scope_mask) 1730 - { 1731 - __enable_cpu_capabilities(arm64_errata, scope_mask); 1732 - __enable_cpu_capabilities(arm64_features, scope_mask); 1565 + /* 1566 + * For all non-boot scope capabilities, use stop_machine() 1567 + * as it schedules the work allowing us to modify PSTATE, 1568 + * instead of on_each_cpu() which uses an IPI, giving us a 1569 + * PSTATE that disappears when we return. 1570 + */ 1571 + if (!boot_scope) 1572 + stop_machine(cpu_enable_non_boot_scope_capabilities, 1573 + NULL, cpu_online_mask); 1733 1574 } 1734 1575 1735 1576 /* ··· 1733 1586 * 1734 1587 * Returns "false" on conflicts. 1735 1588 */ 1736 - static bool 1737 - __verify_local_cpu_caps(const struct arm64_cpu_capabilities *caps, 1738 - u16 scope_mask) 1589 + static bool verify_local_cpu_caps(u16 scope_mask) 1739 1590 { 1591 + int i; 1740 1592 bool cpu_has_cap, system_has_cap; 1593 + const struct arm64_cpu_capabilities *caps; 1741 1594 1742 1595 scope_mask &= ARM64_CPUCAP_SCOPE_MASK; 1743 1596 1744 - for (; caps->matches; caps++) { 1745 - if (!(caps->type & scope_mask)) 1597 + for (i = 0; i < ARM64_NCAPS; i++) { 1598 + caps = cpu_hwcaps_ptrs[i]; 1599 + if (!caps || !(caps->type & scope_mask)) 1746 1600 continue; 1747 1601 1748 1602 cpu_has_cap = caps->matches(caps, SCOPE_LOCAL_CPU); ··· 1774 1626 } 1775 1627 } 1776 1628 1777 - if (caps->matches) { 1629 + if (i < ARM64_NCAPS) { 1778 1630 pr_crit("CPU%d: Detected conflict for capability %d (%s), System: %d, CPU: %d\n", 1779 1631 smp_processor_id(), caps->capability, 1780 1632 caps->desc, system_has_cap, cpu_has_cap); ··· 1782 1634 } 1783 1635 1784 1636 return true; 1785 - } 1786 - 1787 - static bool verify_local_cpu_caps(u16 scope_mask) 1788 - { 1789 - return __verify_local_cpu_caps(arm64_errata, scope_mask) && 1790 - __verify_local_cpu_caps(arm64_features, scope_mask); 1791 1637 } 1792 1638 1793 1639 /* ··· 1892 1750 static_branch_enable(&arm64_const_caps_ready); 1893 1751 } 1894 1752 1895 - extern const struct arm64_cpu_capabilities arm64_errata[]; 1896 - 1897 - bool this_cpu_has_cap(unsigned int cap) 1753 + bool this_cpu_has_cap(unsigned int n) 1898 1754 { 1899 - return (__this_cpu_has_cap(arm64_features, cap) || 1900 - __this_cpu_has_cap(arm64_errata, cap)); 1755 + if (!WARN_ON(preemptible()) && n < ARM64_NCAPS) { 1756 + const struct arm64_cpu_capabilities *cap = cpu_hwcaps_ptrs[n]; 1757 + 1758 + if (cap) 1759 + return cap->matches(cap, SCOPE_LOCAL_CPU); 1760 + } 1761 + 1762 + return false; 1901 1763 } 1902 1764 1903 1765 static void __init setup_system_capabilities(void)
+3
arch/arm64/kernel/cpuinfo.c
··· 82 82 "ilrcpc", 83 83 "flagm", 84 84 "ssbs", 85 + "sb", 86 + "paca", 87 + "pacg", 85 88 NULL 86 89 }; 87 90
+25 -30
arch/arm64/kernel/entry-ftrace.S
··· 79 79 .macro mcount_get_lr reg 80 80 ldr \reg, [x29] 81 81 ldr \reg, [\reg, #8] 82 - mcount_adjust_addr \reg, \reg 83 82 .endm 84 83 85 84 .macro mcount_get_lr_addr reg ··· 120 121 #endif /* CONFIG_FUNCTION_GRAPH_TRACER */ 121 122 mcount_exit 122 123 ENDPROC(_mcount) 124 + EXPORT_SYMBOL(_mcount) 125 + NOKPROBE(_mcount) 123 126 124 127 #else /* CONFIG_DYNAMIC_FTRACE */ 125 128 /* ··· 133 132 ENTRY(_mcount) 134 133 ret 135 134 ENDPROC(_mcount) 135 + EXPORT_SYMBOL(_mcount) 136 + NOKPROBE(_mcount) 136 137 137 138 /* 138 139 * void ftrace_caller(unsigned long return_address) ··· 151 148 mcount_get_pc0 x0 // function's pc 152 149 mcount_get_lr x1 // function's lr 153 150 154 - .global ftrace_call 155 - ftrace_call: // tracer(pc, lr); 151 + GLOBAL(ftrace_call) // tracer(pc, lr); 156 152 nop // This will be replaced with "bl xxx" 157 153 // where xxx can be any kind of tracer. 158 154 159 155 #ifdef CONFIG_FUNCTION_GRAPH_TRACER 160 - .global ftrace_graph_call 161 - ftrace_graph_call: // ftrace_graph_caller(); 156 + GLOBAL(ftrace_graph_call) // ftrace_graph_caller(); 162 157 nop // If enabled, this will be replaced 163 158 // "b ftrace_graph_caller" 164 159 #endif ··· 170 169 ENDPROC(ftrace_stub) 171 170 172 171 #ifdef CONFIG_FUNCTION_GRAPH_TRACER 173 - /* save return value regs*/ 174 - .macro save_return_regs 175 - sub sp, sp, #64 176 - stp x0, x1, [sp] 177 - stp x2, x3, [sp, #16] 178 - stp x4, x5, [sp, #32] 179 - stp x6, x7, [sp, #48] 180 - .endm 181 - 182 - /* restore return value regs*/ 183 - .macro restore_return_regs 184 - ldp x0, x1, [sp] 185 - ldp x2, x3, [sp, #16] 186 - ldp x4, x5, [sp, #32] 187 - ldp x6, x7, [sp, #48] 188 - add sp, sp, #64 189 - .endm 190 - 191 172 /* 192 173 * void ftrace_graph_caller(void) 193 174 * ··· 180 197 * and run return_to_handler() later on its exit. 181 198 */ 182 199 ENTRY(ftrace_graph_caller) 183 - mcount_get_lr_addr x0 // pointer to function's saved lr 184 - mcount_get_pc x1 // function's pc 200 + mcount_get_pc x0 // function's pc 201 + mcount_get_lr_addr x1 // pointer to function's saved lr 185 202 mcount_get_parent_fp x2 // parent's fp 186 - bl prepare_ftrace_return // prepare_ftrace_return(&lr, pc, fp) 203 + bl prepare_ftrace_return // prepare_ftrace_return(pc, &lr, fp) 187 204 188 205 mcount_exit 189 206 ENDPROC(ftrace_graph_caller) ··· 192 209 * void return_to_handler(void) 193 210 * 194 211 * Run ftrace_return_to_handler() before going back to parent. 195 - * @fp is checked against the value passed by ftrace_graph_caller() 196 - * only when HAVE_FUNCTION_GRAPH_FP_TEST is enabled. 212 + * @fp is checked against the value passed by ftrace_graph_caller(). 197 213 */ 198 214 ENTRY(return_to_handler) 199 - save_return_regs 215 + /* save return value regs */ 216 + sub sp, sp, #64 217 + stp x0, x1, [sp] 218 + stp x2, x3, [sp, #16] 219 + stp x4, x5, [sp, #32] 220 + stp x6, x7, [sp, #48] 221 + 200 222 mov x0, x29 // parent's fp 201 223 bl ftrace_return_to_handler// addr = ftrace_return_to_hander(fp); 202 224 mov x30, x0 // restore the original return address 203 - restore_return_regs 225 + 226 + /* restore return value regs */ 227 + ldp x0, x1, [sp] 228 + ldp x2, x3, [sp, #16] 229 + ldp x4, x5, [sp, #32] 230 + ldp x6, x7, [sp, #48] 231 + add sp, sp, #64 232 + 204 233 ret 205 234 END(return_to_handler) 206 235 #endif /* CONFIG_FUNCTION_GRAPH_TRACER */
+4 -8
arch/arm64/kernel/entry.S
··· 344 344 ldp x28, x29, [sp, #16 * 14] 345 345 ldr lr, [sp, #S_LR] 346 346 add sp, sp, #S_FRAME_SIZE // restore sp 347 - /* 348 - * ARCH_HAS_MEMBARRIER_SYNC_CORE rely on eret context synchronization 349 - * when returning from IPI handler, and when returning to user-space. 350 - */ 351 347 352 348 .if \el == 0 353 349 alternative_insn eret, nop, ARM64_UNMAP_KERNEL_AT_EL0 ··· 359 363 .else 360 364 eret 361 365 .endif 366 + sb 362 367 .endm 363 368 364 369 .macro irq_stack_entry ··· 619 622 irq_handler 620 623 621 624 #ifdef CONFIG_PREEMPT 622 - ldr w24, [tsk, #TSK_TI_PREEMPT] // get preempt count 623 - cbnz w24, 1f // preempt count != 0 624 - ldr x0, [tsk, #TSK_TI_FLAGS] // get flags 625 - tbz x0, #TIF_NEED_RESCHED, 1f // needs rescheduling? 625 + ldr x24, [tsk, #TSK_TI_PREEMPT] // get preempt count 626 + cbnz x24, 1f // preempt count != 0 626 627 bl el1_preempt 627 628 1: 628 629 #endif ··· 1001 1006 mrs x30, far_el1 1002 1007 .endif 1003 1008 eret 1009 + sb 1004 1010 .endm 1005 1011 1006 1012 .align 11
+2 -2
arch/arm64/kernel/ftrace.c
··· 104 104 * is added in the future, but for now, the pr_err() below 105 105 * deals with a theoretical issue only. 106 106 */ 107 - trampoline = get_plt_entry(addr); 107 + trampoline = get_plt_entry(addr, mod->arch.ftrace_trampoline); 108 108 if (!plt_entries_equal(mod->arch.ftrace_trampoline, 109 109 &trampoline)) { 110 110 if (!plt_entries_equal(mod->arch.ftrace_trampoline, ··· 211 211 * 212 212 * Note that @frame_pointer is used only for sanity check later. 213 213 */ 214 - void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr, 214 + void prepare_ftrace_return(unsigned long self_addr, unsigned long *parent, 215 215 unsigned long frame_pointer) 216 216 { 217 217 unsigned long return_hooker = (unsigned long)&return_to_handler;
+41 -5
arch/arm64/kernel/head.S
··· 31 31 #include <asm/cache.h> 32 32 #include <asm/cputype.h> 33 33 #include <asm/elf.h> 34 + #include <asm/image.h> 34 35 #include <asm/kernel-pgtable.h> 35 36 #include <asm/kvm_arm.h> 36 37 #include <asm/memory.h> ··· 92 91 .quad 0 // reserved 93 92 .quad 0 // reserved 94 93 .quad 0 // reserved 95 - .ascii "ARM\x64" // Magic number 94 + .ascii ARM64_IMAGE_MAGIC // Magic number 96 95 #ifdef CONFIG_EFI 97 96 .long pe_header - _head // Offset to the PE header. 98 97 ··· 319 318 adrp x0, idmap_pg_dir 320 319 adrp x3, __idmap_text_start // __pa(__idmap_text_start) 321 320 321 + #ifdef CONFIG_ARM64_USER_VA_BITS_52 322 + mrs_s x6, SYS_ID_AA64MMFR2_EL1 323 + and x6, x6, #(0xf << ID_AA64MMFR2_LVA_SHIFT) 324 + mov x5, #52 325 + cbnz x6, 1f 326 + #endif 327 + mov x5, #VA_BITS 328 + 1: 329 + adr_l x6, vabits_user 330 + str x5, [x6] 331 + dmb sy 332 + dc ivac, x6 // Invalidate potentially stale cache line 333 + 322 334 /* 323 335 * VA_BITS may be too small to allow for an ID mapping to be created 324 336 * that covers system RAM if that is located sufficiently high in the ··· 510 496 #endif 511 497 512 498 /* Hyp configuration. */ 513 - mov x0, #HCR_RW // 64-bit EL1 499 + mov_q x0, HCR_HOST_NVHE_FLAGS 514 500 cbz x2, set_hcr 515 - orr x0, x0, #HCR_TGE // Enable Host Extensions 516 - orr x0, x0, #HCR_E2H 501 + mov_q x0, HCR_HOST_VHE_FLAGS 517 502 set_hcr: 518 503 msr hcr_el2, x0 519 504 isb ··· 720 707 /* 721 708 * Common entry point for secondary CPUs. 722 709 */ 710 + bl __cpu_secondary_check52bitva 723 711 bl __cpu_setup // initialise processor 724 712 adrp x1, swapper_pg_dir 725 713 bl __enable_mmu ··· 783 769 phys_to_ttbr x1, x1 784 770 phys_to_ttbr x2, x2 785 771 msr ttbr0_el1, x2 // load TTBR0 772 + offset_ttbr1 x1 786 773 msr ttbr1_el1, x1 // load TTBR1 787 774 isb 788 775 msr sctlr_el1, x0 ··· 799 784 ret 800 785 ENDPROC(__enable_mmu) 801 786 787 + ENTRY(__cpu_secondary_check52bitva) 788 + #ifdef CONFIG_ARM64_USER_VA_BITS_52 789 + ldr_l x0, vabits_user 790 + cmp x0, #52 791 + b.ne 2f 792 + 793 + mrs_s x0, SYS_ID_AA64MMFR2_EL1 794 + and x0, x0, #(0xf << ID_AA64MMFR2_LVA_SHIFT) 795 + cbnz x0, 2f 796 + 797 + update_early_cpu_boot_status \ 798 + CPU_STUCK_IN_KERNEL | CPU_STUCK_REASON_52_BIT_VA, x0, x1 799 + 1: wfe 800 + wfi 801 + b 1b 802 + 803 + #endif 804 + 2: ret 805 + ENDPROC(__cpu_secondary_check52bitva) 806 + 802 807 __no_granule_support: 803 808 /* Indicate that this CPU can't boot and is stuck in the kernel */ 804 - update_early_cpu_boot_status CPU_STUCK_IN_KERNEL, x1, x2 809 + update_early_cpu_boot_status \ 810 + CPU_STUCK_IN_KERNEL | CPU_STUCK_REASON_NO_GRAN, x1, x2 805 811 1: 806 812 wfe 807 813 wfi
+1
arch/arm64/kernel/hibernate-asm.S
··· 40 40 tlbi vmalle1 41 41 dsb nsh 42 42 phys_to_ttbr \tmp, \page_table 43 + offset_ttbr1 \tmp 43 44 msr ttbr1_el1, \tmp 44 45 isb 45 46 .endm
+31 -36
arch/arm64/kernel/image.h
··· 15 15 * You should have received a copy of the GNU General Public License 16 16 * along with this program. If not, see <http://www.gnu.org/licenses/>. 17 17 */ 18 - #ifndef __ASM_IMAGE_H 19 - #define __ASM_IMAGE_H 18 + #ifndef __ARM64_KERNEL_IMAGE_H 19 + #define __ARM64_KERNEL_IMAGE_H 20 20 21 21 #ifndef LINKER_SCRIPT 22 22 #error This file should only be included in vmlinux.lds.S 23 23 #endif 24 + 25 + #include <asm/image.h> 24 26 25 27 /* 26 28 * There aren't any ELF relocations we can use to endian-swap values known only ··· 49 47 sym##_lo32 = DATA_LE32((data) & 0xffffffff); \ 50 48 sym##_hi32 = DATA_LE32((data) >> 32) 51 49 50 + #define __HEAD_FLAG(field) (__HEAD_FLAG_##field << \ 51 + ARM64_IMAGE_FLAG_##field##_SHIFT) 52 + 52 53 #ifdef CONFIG_CPU_BIG_ENDIAN 53 - #define __HEAD_FLAG_BE 1 54 + #define __HEAD_FLAG_BE ARM64_IMAGE_FLAG_BE 54 55 #else 55 - #define __HEAD_FLAG_BE 0 56 + #define __HEAD_FLAG_BE ARM64_IMAGE_FLAG_LE 56 57 #endif 57 58 58 59 #define __HEAD_FLAG_PAGE_SIZE ((PAGE_SHIFT - 10) / 2) 59 60 60 61 #define __HEAD_FLAG_PHYS_BASE 1 61 62 62 - #define __HEAD_FLAGS ((__HEAD_FLAG_BE << 0) | \ 63 - (__HEAD_FLAG_PAGE_SIZE << 1) | \ 64 - (__HEAD_FLAG_PHYS_BASE << 3)) 63 + #define __HEAD_FLAGS (__HEAD_FLAG(BE) | \ 64 + __HEAD_FLAG(PAGE_SIZE) | \ 65 + __HEAD_FLAG(PHYS_BASE)) 65 66 66 67 /* 67 68 * These will output as part of the Image header, which should be little-endian ··· 81 76 __efistub_stext_offset = stext - _text; 82 77 83 78 /* 84 - * Prevent the symbol aliases below from being emitted into the kallsyms 85 - * table, by forcing them to be absolute symbols (which are conveniently 86 - * ignored by scripts/kallsyms) rather than section relative symbols. 87 - * The distinction is only relevant for partial linking, and only for symbols 88 - * that are defined within a section declaration (which is not the case for 89 - * the definitions below) so the resulting values will be identical. 90 - */ 91 - #define KALLSYMS_HIDE(sym) ABSOLUTE(sym) 92 - 93 - /* 94 79 * The EFI stub has its own symbol namespace prefixed by __efistub_, to 95 80 * isolate it from the kernel proper. The following symbols are legally 96 81 * accessed by the stub, so provide some aliases to make them accessible. ··· 89 94 * linked at. The routines below are all implemented in assembler in a 90 95 * position independent manner 91 96 */ 92 - __efistub_memcmp = KALLSYMS_HIDE(__pi_memcmp); 93 - __efistub_memchr = KALLSYMS_HIDE(__pi_memchr); 94 - __efistub_memcpy = KALLSYMS_HIDE(__pi_memcpy); 95 - __efistub_memmove = KALLSYMS_HIDE(__pi_memmove); 96 - __efistub_memset = KALLSYMS_HIDE(__pi_memset); 97 - __efistub_strlen = KALLSYMS_HIDE(__pi_strlen); 98 - __efistub_strnlen = KALLSYMS_HIDE(__pi_strnlen); 99 - __efistub_strcmp = KALLSYMS_HIDE(__pi_strcmp); 100 - __efistub_strncmp = KALLSYMS_HIDE(__pi_strncmp); 101 - __efistub_strrchr = KALLSYMS_HIDE(__pi_strrchr); 102 - __efistub___flush_dcache_area = KALLSYMS_HIDE(__pi___flush_dcache_area); 97 + __efistub_memcmp = __pi_memcmp; 98 + __efistub_memchr = __pi_memchr; 99 + __efistub_memcpy = __pi_memcpy; 100 + __efistub_memmove = __pi_memmove; 101 + __efistub_memset = __pi_memset; 102 + __efistub_strlen = __pi_strlen; 103 + __efistub_strnlen = __pi_strnlen; 104 + __efistub_strcmp = __pi_strcmp; 105 + __efistub_strncmp = __pi_strncmp; 106 + __efistub_strrchr = __pi_strrchr; 107 + __efistub___flush_dcache_area = __pi___flush_dcache_area; 103 108 104 109 #ifdef CONFIG_KASAN 105 - __efistub___memcpy = KALLSYMS_HIDE(__pi_memcpy); 106 - __efistub___memmove = KALLSYMS_HIDE(__pi_memmove); 107 - __efistub___memset = KALLSYMS_HIDE(__pi_memset); 110 + __efistub___memcpy = __pi_memcpy; 111 + __efistub___memmove = __pi_memmove; 112 + __efistub___memset = __pi_memset; 108 113 #endif 109 114 110 - __efistub__text = KALLSYMS_HIDE(_text); 111 - __efistub__end = KALLSYMS_HIDE(_end); 112 - __efistub__edata = KALLSYMS_HIDE(_edata); 113 - __efistub_screen_info = KALLSYMS_HIDE(screen_info); 115 + __efistub__text = _text; 116 + __efistub__end = _end; 117 + __efistub__edata = _edata; 118 + __efistub_screen_info = screen_info; 114 119 115 120 #endif 116 121 117 - #endif /* __ASM_IMAGE_H */ 122 + #endif /* __ARM64_KERNEL_IMAGE_H */
+29
arch/arm64/kernel/insn.c
··· 1239 1239 return aarch64_insn_encode_immediate(AARCH64_INSN_IMM_6, insn, shift); 1240 1240 } 1241 1241 1242 + u32 aarch64_insn_gen_adr(unsigned long pc, unsigned long addr, 1243 + enum aarch64_insn_register reg, 1244 + enum aarch64_insn_adr_type type) 1245 + { 1246 + u32 insn; 1247 + s32 offset; 1248 + 1249 + switch (type) { 1250 + case AARCH64_INSN_ADR_TYPE_ADR: 1251 + insn = aarch64_insn_get_adr_value(); 1252 + offset = addr - pc; 1253 + break; 1254 + case AARCH64_INSN_ADR_TYPE_ADRP: 1255 + insn = aarch64_insn_get_adrp_value(); 1256 + offset = (addr - ALIGN_DOWN(pc, SZ_4K)) >> 12; 1257 + break; 1258 + default: 1259 + pr_err("%s: unknown adr encoding %d\n", __func__, type); 1260 + return AARCH64_BREAK_FAULT; 1261 + } 1262 + 1263 + if (offset < -SZ_1M || offset >= SZ_1M) 1264 + return AARCH64_BREAK_FAULT; 1265 + 1266 + insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RD, insn, reg); 1267 + 1268 + return aarch64_insn_encode_immediate(AARCH64_INSN_IMM_ADR, insn, offset); 1269 + } 1270 + 1242 1271 /* 1243 1272 * Decode the imm field of a branch, and return the byte offset as a 1244 1273 * signed value (so it can be used when computing a new branch
+130
arch/arm64/kernel/kexec_image.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* 3 + * Kexec image loader 4 + 5 + * Copyright (C) 2018 Linaro Limited 6 + * Author: AKASHI Takahiro <takahiro.akashi@linaro.org> 7 + */ 8 + 9 + #define pr_fmt(fmt) "kexec_file(Image): " fmt 10 + 11 + #include <linux/err.h> 12 + #include <linux/errno.h> 13 + #include <linux/kernel.h> 14 + #include <linux/kexec.h> 15 + #include <linux/pe.h> 16 + #include <linux/string.h> 17 + #include <linux/verification.h> 18 + #include <asm/byteorder.h> 19 + #include <asm/cpufeature.h> 20 + #include <asm/image.h> 21 + #include <asm/memory.h> 22 + 23 + static int image_probe(const char *kernel_buf, unsigned long kernel_len) 24 + { 25 + const struct arm64_image_header *h = 26 + (const struct arm64_image_header *)(kernel_buf); 27 + 28 + if (!h || (kernel_len < sizeof(*h))) 29 + return -EINVAL; 30 + 31 + if (memcmp(&h->magic, ARM64_IMAGE_MAGIC, sizeof(h->magic))) 32 + return -EINVAL; 33 + 34 + return 0; 35 + } 36 + 37 + static void *image_load(struct kimage *image, 38 + char *kernel, unsigned long kernel_len, 39 + char *initrd, unsigned long initrd_len, 40 + char *cmdline, unsigned long cmdline_len) 41 + { 42 + struct arm64_image_header *h; 43 + u64 flags, value; 44 + bool be_image, be_kernel; 45 + struct kexec_buf kbuf; 46 + unsigned long text_offset; 47 + struct kexec_segment *kernel_segment; 48 + int ret; 49 + 50 + /* We don't support crash kernels yet. */ 51 + if (image->type == KEXEC_TYPE_CRASH) 52 + return ERR_PTR(-EOPNOTSUPP); 53 + 54 + /* 55 + * We require a kernel with an unambiguous Image header. Per 56 + * Documentation/booting.txt, this is the case when image_size 57 + * is non-zero (practically speaking, since v3.17). 58 + */ 59 + h = (struct arm64_image_header *)kernel; 60 + if (!h->image_size) 61 + return ERR_PTR(-EINVAL); 62 + 63 + /* Check cpu features */ 64 + flags = le64_to_cpu(h->flags); 65 + be_image = arm64_image_flag_field(flags, ARM64_IMAGE_FLAG_BE); 66 + be_kernel = IS_ENABLED(CONFIG_CPU_BIG_ENDIAN); 67 + if ((be_image != be_kernel) && !system_supports_mixed_endian()) 68 + return ERR_PTR(-EINVAL); 69 + 70 + value = arm64_image_flag_field(flags, ARM64_IMAGE_FLAG_PAGE_SIZE); 71 + if (((value == ARM64_IMAGE_FLAG_PAGE_SIZE_4K) && 72 + !system_supports_4kb_granule()) || 73 + ((value == ARM64_IMAGE_FLAG_PAGE_SIZE_64K) && 74 + !system_supports_64kb_granule()) || 75 + ((value == ARM64_IMAGE_FLAG_PAGE_SIZE_16K) && 76 + !system_supports_16kb_granule())) 77 + return ERR_PTR(-EINVAL); 78 + 79 + /* Load the kernel */ 80 + kbuf.image = image; 81 + kbuf.buf_min = 0; 82 + kbuf.buf_max = ULONG_MAX; 83 + kbuf.top_down = false; 84 + 85 + kbuf.buffer = kernel; 86 + kbuf.bufsz = kernel_len; 87 + kbuf.mem = 0; 88 + kbuf.memsz = le64_to_cpu(h->image_size); 89 + text_offset = le64_to_cpu(h->text_offset); 90 + kbuf.buf_align = MIN_KIMG_ALIGN; 91 + 92 + /* Adjust kernel segment with TEXT_OFFSET */ 93 + kbuf.memsz += text_offset; 94 + 95 + ret = kexec_add_buffer(&kbuf); 96 + if (ret) 97 + return ERR_PTR(ret); 98 + 99 + kernel_segment = &image->segment[image->nr_segments - 1]; 100 + kernel_segment->mem += text_offset; 101 + kernel_segment->memsz -= text_offset; 102 + image->start = kernel_segment->mem; 103 + 104 + pr_debug("Loaded kernel at 0x%lx bufsz=0x%lx memsz=0x%lx\n", 105 + kernel_segment->mem, kbuf.bufsz, 106 + kernel_segment->memsz); 107 + 108 + /* Load additional data */ 109 + ret = load_other_segments(image, 110 + kernel_segment->mem, kernel_segment->memsz, 111 + initrd, initrd_len, cmdline); 112 + 113 + return ERR_PTR(ret); 114 + } 115 + 116 + #ifdef CONFIG_KEXEC_IMAGE_VERIFY_SIG 117 + static int image_verify_sig(const char *kernel, unsigned long kernel_len) 118 + { 119 + return verify_pefile_signature(kernel, kernel_len, NULL, 120 + VERIFYING_KEXEC_PE_SIGNATURE); 121 + } 122 + #endif 123 + 124 + const struct kexec_file_ops kexec_image_ops = { 125 + .probe = image_probe, 126 + .load = image_load, 127 + #ifdef CONFIG_KEXEC_IMAGE_VERIFY_SIG 128 + .verify_sig = image_verify_sig, 129 + #endif 130 + };
+10 -2
arch/arm64/kernel/machine_kexec.c
··· 212 212 * uses physical addressing to relocate the new image to its final 213 213 * position and transfers control to the image entry point when the 214 214 * relocation is complete. 215 + * In kexec case, kimage->start points to purgatory assuming that 216 + * kernel entry and dtb address are embedded in purgatory by 217 + * userspace (kexec-tools). 218 + * In kexec_file case, the kernel starts directly without purgatory. 215 219 */ 216 - 217 - cpu_soft_restart(reboot_code_buffer_phys, kimage->head, kimage->start, 0); 220 + cpu_soft_restart(reboot_code_buffer_phys, kimage->head, kimage->start, 221 + #ifdef CONFIG_KEXEC_FILE 222 + kimage->arch.dtb_mem); 223 + #else 224 + 0); 225 + #endif 218 226 219 227 BUG(); /* Should never get here. */ 220 228 }
+224
arch/arm64/kernel/machine_kexec_file.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* 3 + * kexec_file for arm64 4 + * 5 + * Copyright (C) 2018 Linaro Limited 6 + * Author: AKASHI Takahiro <takahiro.akashi@linaro.org> 7 + * 8 + * Most code is derived from arm64 port of kexec-tools 9 + */ 10 + 11 + #define pr_fmt(fmt) "kexec_file: " fmt 12 + 13 + #include <linux/ioport.h> 14 + #include <linux/kernel.h> 15 + #include <linux/kexec.h> 16 + #include <linux/libfdt.h> 17 + #include <linux/memblock.h> 18 + #include <linux/of_fdt.h> 19 + #include <linux/random.h> 20 + #include <linux/string.h> 21 + #include <linux/types.h> 22 + #include <linux/vmalloc.h> 23 + #include <asm/byteorder.h> 24 + 25 + /* relevant device tree properties */ 26 + #define FDT_PROP_INITRD_START "linux,initrd-start" 27 + #define FDT_PROP_INITRD_END "linux,initrd-end" 28 + #define FDT_PROP_BOOTARGS "bootargs" 29 + #define FDT_PROP_KASLR_SEED "kaslr-seed" 30 + 31 + const struct kexec_file_ops * const kexec_file_loaders[] = { 32 + &kexec_image_ops, 33 + NULL 34 + }; 35 + 36 + int arch_kimage_file_post_load_cleanup(struct kimage *image) 37 + { 38 + vfree(image->arch.dtb); 39 + image->arch.dtb = NULL; 40 + 41 + return kexec_image_post_load_cleanup_default(image); 42 + } 43 + 44 + static int setup_dtb(struct kimage *image, 45 + unsigned long initrd_load_addr, unsigned long initrd_len, 46 + char *cmdline, void *dtb) 47 + { 48 + int off, ret; 49 + 50 + ret = fdt_path_offset(dtb, "/chosen"); 51 + if (ret < 0) 52 + goto out; 53 + 54 + off = ret; 55 + 56 + /* add bootargs */ 57 + if (cmdline) { 58 + ret = fdt_setprop_string(dtb, off, FDT_PROP_BOOTARGS, cmdline); 59 + if (ret) 60 + goto out; 61 + } else { 62 + ret = fdt_delprop(dtb, off, FDT_PROP_BOOTARGS); 63 + if (ret && (ret != -FDT_ERR_NOTFOUND)) 64 + goto out; 65 + } 66 + 67 + /* add initrd-* */ 68 + if (initrd_load_addr) { 69 + ret = fdt_setprop_u64(dtb, off, FDT_PROP_INITRD_START, 70 + initrd_load_addr); 71 + if (ret) 72 + goto out; 73 + 74 + ret = fdt_setprop_u64(dtb, off, FDT_PROP_INITRD_END, 75 + initrd_load_addr + initrd_len); 76 + if (ret) 77 + goto out; 78 + } else { 79 + ret = fdt_delprop(dtb, off, FDT_PROP_INITRD_START); 80 + if (ret && (ret != -FDT_ERR_NOTFOUND)) 81 + goto out; 82 + 83 + ret = fdt_delprop(dtb, off, FDT_PROP_INITRD_END); 84 + if (ret && (ret != -FDT_ERR_NOTFOUND)) 85 + goto out; 86 + } 87 + 88 + /* add kaslr-seed */ 89 + ret = fdt_delprop(dtb, off, FDT_PROP_KASLR_SEED); 90 + if (ret && (ret != -FDT_ERR_NOTFOUND)) 91 + goto out; 92 + 93 + if (rng_is_initialized()) { 94 + u64 seed = get_random_u64(); 95 + ret = fdt_setprop_u64(dtb, off, FDT_PROP_KASLR_SEED, seed); 96 + if (ret) 97 + goto out; 98 + } else { 99 + pr_notice("RNG is not initialised: omitting \"%s\" property\n", 100 + FDT_PROP_KASLR_SEED); 101 + } 102 + 103 + out: 104 + if (ret) 105 + return (ret == -FDT_ERR_NOSPACE) ? -ENOMEM : -EINVAL; 106 + 107 + return 0; 108 + } 109 + 110 + /* 111 + * More space needed so that we can add initrd, bootargs and kaslr-seed. 112 + */ 113 + #define DTB_EXTRA_SPACE 0x1000 114 + 115 + static int create_dtb(struct kimage *image, 116 + unsigned long initrd_load_addr, unsigned long initrd_len, 117 + char *cmdline, void **dtb) 118 + { 119 + void *buf; 120 + size_t buf_size; 121 + int ret; 122 + 123 + buf_size = fdt_totalsize(initial_boot_params) 124 + + strlen(cmdline) + DTB_EXTRA_SPACE; 125 + 126 + for (;;) { 127 + buf = vmalloc(buf_size); 128 + if (!buf) 129 + return -ENOMEM; 130 + 131 + /* duplicate a device tree blob */ 132 + ret = fdt_open_into(initial_boot_params, buf, buf_size); 133 + if (ret) 134 + return -EINVAL; 135 + 136 + ret = setup_dtb(image, initrd_load_addr, initrd_len, 137 + cmdline, buf); 138 + if (ret) { 139 + vfree(buf); 140 + if (ret == -ENOMEM) { 141 + /* unlikely, but just in case */ 142 + buf_size += DTB_EXTRA_SPACE; 143 + continue; 144 + } else { 145 + return ret; 146 + } 147 + } 148 + 149 + /* trim it */ 150 + fdt_pack(buf); 151 + *dtb = buf; 152 + 153 + return 0; 154 + } 155 + } 156 + 157 + int load_other_segments(struct kimage *image, 158 + unsigned long kernel_load_addr, 159 + unsigned long kernel_size, 160 + char *initrd, unsigned long initrd_len, 161 + char *cmdline) 162 + { 163 + struct kexec_buf kbuf; 164 + void *dtb = NULL; 165 + unsigned long initrd_load_addr = 0, dtb_len; 166 + int ret = 0; 167 + 168 + kbuf.image = image; 169 + /* not allocate anything below the kernel */ 170 + kbuf.buf_min = kernel_load_addr + kernel_size; 171 + 172 + /* load initrd */ 173 + if (initrd) { 174 + kbuf.buffer = initrd; 175 + kbuf.bufsz = initrd_len; 176 + kbuf.mem = 0; 177 + kbuf.memsz = initrd_len; 178 + kbuf.buf_align = 0; 179 + /* within 1GB-aligned window of up to 32GB in size */ 180 + kbuf.buf_max = round_down(kernel_load_addr, SZ_1G) 181 + + (unsigned long)SZ_1G * 32; 182 + kbuf.top_down = false; 183 + 184 + ret = kexec_add_buffer(&kbuf); 185 + if (ret) 186 + goto out_err; 187 + initrd_load_addr = kbuf.mem; 188 + 189 + pr_debug("Loaded initrd at 0x%lx bufsz=0x%lx memsz=0x%lx\n", 190 + initrd_load_addr, initrd_len, initrd_len); 191 + } 192 + 193 + /* load dtb */ 194 + ret = create_dtb(image, initrd_load_addr, initrd_len, cmdline, &dtb); 195 + if (ret) { 196 + pr_err("Preparing for new dtb failed\n"); 197 + goto out_err; 198 + } 199 + 200 + dtb_len = fdt_totalsize(dtb); 201 + kbuf.buffer = dtb; 202 + kbuf.bufsz = dtb_len; 203 + kbuf.mem = 0; 204 + kbuf.memsz = dtb_len; 205 + /* not across 2MB boundary */ 206 + kbuf.buf_align = SZ_2M; 207 + kbuf.buf_max = ULONG_MAX; 208 + kbuf.top_down = true; 209 + 210 + ret = kexec_add_buffer(&kbuf); 211 + if (ret) 212 + goto out_err; 213 + image->arch.dtb = dtb; 214 + image->arch.dtb_mem = kbuf.mem; 215 + 216 + pr_debug("Loaded dtb at 0x%lx bufsz=0x%lx memsz=0x%lx\n", 217 + kbuf.mem, dtb_len, dtb_len); 218 + 219 + return 0; 220 + 221 + out_err: 222 + vfree(dtb); 223 + return ret; 224 + }
+98 -37
arch/arm64/kernel/module-plts.c
··· 11 11 #include <linux/module.h> 12 12 #include <linux/sort.h> 13 13 14 + static struct plt_entry __get_adrp_add_pair(u64 dst, u64 pc, 15 + enum aarch64_insn_register reg) 16 + { 17 + u32 adrp, add; 18 + 19 + adrp = aarch64_insn_gen_adr(pc, dst, reg, AARCH64_INSN_ADR_TYPE_ADRP); 20 + add = aarch64_insn_gen_add_sub_imm(reg, reg, dst % SZ_4K, 21 + AARCH64_INSN_VARIANT_64BIT, 22 + AARCH64_INSN_ADSB_ADD); 23 + 24 + return (struct plt_entry){ cpu_to_le32(adrp), cpu_to_le32(add) }; 25 + } 26 + 27 + struct plt_entry get_plt_entry(u64 dst, void *pc) 28 + { 29 + struct plt_entry plt; 30 + static u32 br; 31 + 32 + if (!br) 33 + br = aarch64_insn_gen_branch_reg(AARCH64_INSN_REG_16, 34 + AARCH64_INSN_BRANCH_NOLINK); 35 + 36 + plt = __get_adrp_add_pair(dst, (u64)pc, AARCH64_INSN_REG_16); 37 + plt.br = cpu_to_le32(br); 38 + 39 + return plt; 40 + } 41 + 42 + bool plt_entries_equal(const struct plt_entry *a, const struct plt_entry *b) 43 + { 44 + u64 p, q; 45 + 46 + /* 47 + * Check whether both entries refer to the same target: 48 + * do the cheapest checks first. 49 + * If the 'add' or 'br' opcodes are different, then the target 50 + * cannot be the same. 51 + */ 52 + if (a->add != b->add || a->br != b->br) 53 + return false; 54 + 55 + p = ALIGN_DOWN((u64)a, SZ_4K); 56 + q = ALIGN_DOWN((u64)b, SZ_4K); 57 + 58 + /* 59 + * If the 'adrp' opcodes are the same then we just need to check 60 + * that they refer to the same 4k region. 61 + */ 62 + if (a->adrp == b->adrp && p == q) 63 + return true; 64 + 65 + return (p + aarch64_insn_adrp_get_offset(le32_to_cpu(a->adrp))) == 66 + (q + aarch64_insn_adrp_get_offset(le32_to_cpu(b->adrp))); 67 + } 68 + 14 69 static bool in_init(const struct module *mod, void *loc) 15 70 { 16 71 return (u64)loc - (u64)mod->init_layout.base < mod->init_layout.size; 17 72 } 18 73 19 - u64 module_emit_plt_entry(struct module *mod, void *loc, const Elf64_Rela *rela, 74 + u64 module_emit_plt_entry(struct module *mod, Elf64_Shdr *sechdrs, 75 + void *loc, const Elf64_Rela *rela, 20 76 Elf64_Sym *sym) 21 77 { 22 78 struct mod_plt_sec *pltsec = !in_init(mod, loc) ? &mod->arch.core : 23 79 &mod->arch.init; 24 - struct plt_entry *plt = (struct plt_entry *)pltsec->plt->sh_addr; 80 + struct plt_entry *plt = (struct plt_entry *)sechdrs[pltsec->plt_shndx].sh_addr; 25 81 int i = pltsec->plt_num_entries; 82 + int j = i - 1; 26 83 u64 val = sym->st_value + rela->r_addend; 27 84 28 - plt[i] = get_plt_entry(val); 85 + if (is_forbidden_offset_for_adrp(&plt[i].adrp)) 86 + i++; 87 + 88 + plt[i] = get_plt_entry(val, &plt[i]); 29 89 30 90 /* 31 91 * Check if the entry we just created is a duplicate. Given that the 32 92 * relocations are sorted, this will be the last entry we allocated. 33 93 * (if one exists). 34 94 */ 35 - if (i > 0 && plt_entries_equal(plt + i, plt + i - 1)) 36 - return (u64)&plt[i - 1]; 95 + if (j >= 0 && plt_entries_equal(plt + i, plt + j)) 96 + return (u64)&plt[j]; 37 97 38 - pltsec->plt_num_entries++; 98 + pltsec->plt_num_entries += i - j; 39 99 if (WARN_ON(pltsec->plt_num_entries > pltsec->plt_max_entries)) 40 100 return 0; 41 101 ··· 103 43 } 104 44 105 45 #ifdef CONFIG_ARM64_ERRATUM_843419 106 - u64 module_emit_veneer_for_adrp(struct module *mod, void *loc, u64 val) 46 + u64 module_emit_veneer_for_adrp(struct module *mod, Elf64_Shdr *sechdrs, 47 + void *loc, u64 val) 107 48 { 108 49 struct mod_plt_sec *pltsec = !in_init(mod, loc) ? &mod->arch.core : 109 50 &mod->arch.init; 110 - struct plt_entry *plt = (struct plt_entry *)pltsec->plt->sh_addr; 51 + struct plt_entry *plt = (struct plt_entry *)sechdrs[pltsec->plt_shndx].sh_addr; 111 52 int i = pltsec->plt_num_entries++; 112 - u32 mov0, mov1, mov2, br; 53 + u32 br; 113 54 int rd; 114 55 115 56 if (WARN_ON(pltsec->plt_num_entries > pltsec->plt_max_entries)) 116 57 return 0; 117 58 59 + if (is_forbidden_offset_for_adrp(&plt[i].adrp)) 60 + i = pltsec->plt_num_entries++; 61 + 118 62 /* get the destination register of the ADRP instruction */ 119 63 rd = aarch64_insn_decode_register(AARCH64_INSN_REGTYPE_RD, 120 64 le32_to_cpup((__le32 *)loc)); 121 65 122 - /* generate the veneer instructions */ 123 - mov0 = aarch64_insn_gen_movewide(rd, (u16)~val, 0, 124 - AARCH64_INSN_VARIANT_64BIT, 125 - AARCH64_INSN_MOVEWIDE_INVERSE); 126 - mov1 = aarch64_insn_gen_movewide(rd, (u16)(val >> 16), 16, 127 - AARCH64_INSN_VARIANT_64BIT, 128 - AARCH64_INSN_MOVEWIDE_KEEP); 129 - mov2 = aarch64_insn_gen_movewide(rd, (u16)(val >> 32), 32, 130 - AARCH64_INSN_VARIANT_64BIT, 131 - AARCH64_INSN_MOVEWIDE_KEEP); 132 66 br = aarch64_insn_gen_branch_imm((u64)&plt[i].br, (u64)loc + 4, 133 67 AARCH64_INSN_BRANCH_NOLINK); 134 68 135 - plt[i] = (struct plt_entry){ 136 - cpu_to_le32(mov0), 137 - cpu_to_le32(mov1), 138 - cpu_to_le32(mov2), 139 - cpu_to_le32(br) 140 - }; 69 + plt[i] = __get_adrp_add_pair(val, (u64)&plt[i], rd); 70 + plt[i].br = cpu_to_le32(br); 141 71 142 72 return (u64)&plt[i]; 143 73 } ··· 243 193 break; 244 194 } 245 195 } 196 + 197 + if (IS_ENABLED(CONFIG_ARM64_ERRATUM_843419) && 198 + cpus_have_const_cap(ARM64_WORKAROUND_843419)) 199 + /* 200 + * Add some slack so we can skip PLT slots that may trigger 201 + * the erratum due to the placement of the ADRP instruction. 202 + */ 203 + ret += DIV_ROUND_UP(ret, (SZ_4K / sizeof(struct plt_entry))); 204 + 246 205 return ret; 247 206 } 248 207 ··· 261 202 unsigned long core_plts = 0; 262 203 unsigned long init_plts = 0; 263 204 Elf64_Sym *syms = NULL; 264 - Elf_Shdr *tramp = NULL; 205 + Elf_Shdr *pltsec, *tramp = NULL; 265 206 int i; 266 207 267 208 /* ··· 270 211 */ 271 212 for (i = 0; i < ehdr->e_shnum; i++) { 272 213 if (!strcmp(secstrings + sechdrs[i].sh_name, ".plt")) 273 - mod->arch.core.plt = sechdrs + i; 214 + mod->arch.core.plt_shndx = i; 274 215 else if (!strcmp(secstrings + sechdrs[i].sh_name, ".init.plt")) 275 - mod->arch.init.plt = sechdrs + i; 216 + mod->arch.init.plt_shndx = i; 276 217 else if (IS_ENABLED(CONFIG_DYNAMIC_FTRACE) && 277 218 !strcmp(secstrings + sechdrs[i].sh_name, 278 219 ".text.ftrace_trampoline")) ··· 281 222 syms = (Elf64_Sym *)sechdrs[i].sh_addr; 282 223 } 283 224 284 - if (!mod->arch.core.plt || !mod->arch.init.plt) { 225 + if (!mod->arch.core.plt_shndx || !mod->arch.init.plt_shndx) { 285 226 pr_err("%s: module PLT section(s) missing\n", mod->name); 286 227 return -ENOEXEC; 287 228 } ··· 313 254 sechdrs[i].sh_info, dstsec); 314 255 } 315 256 316 - mod->arch.core.plt->sh_type = SHT_NOBITS; 317 - mod->arch.core.plt->sh_flags = SHF_EXECINSTR | SHF_ALLOC; 318 - mod->arch.core.plt->sh_addralign = L1_CACHE_BYTES; 319 - mod->arch.core.plt->sh_size = (core_plts + 1) * sizeof(struct plt_entry); 257 + pltsec = sechdrs + mod->arch.core.plt_shndx; 258 + pltsec->sh_type = SHT_NOBITS; 259 + pltsec->sh_flags = SHF_EXECINSTR | SHF_ALLOC; 260 + pltsec->sh_addralign = L1_CACHE_BYTES; 261 + pltsec->sh_size = (core_plts + 1) * sizeof(struct plt_entry); 320 262 mod->arch.core.plt_num_entries = 0; 321 263 mod->arch.core.plt_max_entries = core_plts; 322 264 323 - mod->arch.init.plt->sh_type = SHT_NOBITS; 324 - mod->arch.init.plt->sh_flags = SHF_EXECINSTR | SHF_ALLOC; 325 - mod->arch.init.plt->sh_addralign = L1_CACHE_BYTES; 326 - mod->arch.init.plt->sh_size = (init_plts + 1) * sizeof(struct plt_entry); 265 + pltsec = sechdrs + mod->arch.init.plt_shndx; 266 + pltsec->sh_type = SHT_NOBITS; 267 + pltsec->sh_flags = SHF_EXECINSTR | SHF_ALLOC; 268 + pltsec->sh_addralign = L1_CACHE_BYTES; 269 + pltsec->sh_size = (init_plts + 1) * sizeof(struct plt_entry); 327 270 mod->arch.init.plt_num_entries = 0; 328 271 mod->arch.init.plt_max_entries = init_plts; 329 272
+6 -7
arch/arm64/kernel/module.c
··· 198 198 return 0; 199 199 } 200 200 201 - static int reloc_insn_adrp(struct module *mod, __le32 *place, u64 val) 201 + static int reloc_insn_adrp(struct module *mod, Elf64_Shdr *sechdrs, 202 + __le32 *place, u64 val) 202 203 { 203 204 u32 insn; 204 205 205 - if (!IS_ENABLED(CONFIG_ARM64_ERRATUM_843419) || 206 - !cpus_have_const_cap(ARM64_WORKAROUND_843419) || 207 - ((u64)place & 0xfff) < 0xff8) 206 + if (!is_forbidden_offset_for_adrp(place)) 208 207 return reloc_insn_imm(RELOC_OP_PAGE, place, val, 12, 21, 209 208 AARCH64_INSN_IMM_ADR); 210 209 ··· 214 215 insn &= ~BIT(31); 215 216 } else { 216 217 /* out of range for ADR -> emit a veneer */ 217 - val = module_emit_veneer_for_adrp(mod, place, val & ~0xfff); 218 + val = module_emit_veneer_for_adrp(mod, sechdrs, place, val & ~0xfff); 218 219 if (!val) 219 220 return -ENOEXEC; 220 221 insn = aarch64_insn_gen_branch_imm((u64)place, val, ··· 367 368 case R_AARCH64_ADR_PREL_PG_HI21_NC: 368 369 overflow_check = false; 369 370 case R_AARCH64_ADR_PREL_PG_HI21: 370 - ovf = reloc_insn_adrp(me, loc, val); 371 + ovf = reloc_insn_adrp(me, sechdrs, loc, val); 371 372 if (ovf && ovf != -ERANGE) 372 373 return ovf; 373 374 break; ··· 412 413 413 414 if (IS_ENABLED(CONFIG_ARM64_MODULE_PLTS) && 414 415 ovf == -ERANGE) { 415 - val = module_emit_plt_entry(me, loc, &rel[i], sym); 416 + val = module_emit_plt_entry(me, sechdrs, loc, &rel[i], sym); 416 417 if (!val) 417 418 return -ENOEXEC; 418 419 ovf = reloc_insn_imm(RELOC_OP_PREL, loc, val, 2,
+5 -1
arch/arm64/kernel/perf_callchain.c
··· 18 18 #include <linux/perf_event.h> 19 19 #include <linux/uaccess.h> 20 20 21 + #include <asm/pointer_auth.h> 21 22 #include <asm/stacktrace.h> 22 23 23 24 struct frame_tail { ··· 36 35 { 37 36 struct frame_tail buftail; 38 37 unsigned long err; 38 + unsigned long lr; 39 39 40 40 /* Also check accessibility of one struct frame_tail beyond */ 41 41 if (!access_ok(VERIFY_READ, tail, sizeof(buftail))) ··· 49 47 if (err) 50 48 return NULL; 51 49 52 - perf_callchain_store(entry, buftail.lr); 50 + lr = ptrauth_strip_insn_pac(buftail.lr); 51 + 52 + perf_callchain_store(entry, lr); 53 53 54 54 /* 55 55 * Frame pointers should strictly progress back up the stack
+55 -166
arch/arm64/kernel/perf_event.c
··· 1 1 /* 2 - * PMU support 2 + * ARMv8 PMUv3 Performance Events handling code. 3 3 * 4 4 * Copyright (C) 2012 ARM Limited 5 5 * Author: Will Deacon <will.deacon@arm.com> ··· 30 30 #include <linux/perf/arm_pmu.h> 31 31 #include <linux/platform_device.h> 32 32 33 - /* 34 - * ARMv8 PMUv3 Performance Events handling code. 35 - * Common event types (some are defined in asm/perf_event.h). 36 - */ 37 - 38 - /* At least one of the following is required. */ 39 - #define ARMV8_PMUV3_PERFCTR_INST_RETIRED 0x08 40 - #define ARMV8_PMUV3_PERFCTR_INST_SPEC 0x1B 41 - 42 - /* Common architectural events. */ 43 - #define ARMV8_PMUV3_PERFCTR_LD_RETIRED 0x06 44 - #define ARMV8_PMUV3_PERFCTR_ST_RETIRED 0x07 45 - #define ARMV8_PMUV3_PERFCTR_EXC_TAKEN 0x09 46 - #define ARMV8_PMUV3_PERFCTR_EXC_RETURN 0x0A 47 - #define ARMV8_PMUV3_PERFCTR_CID_WRITE_RETIRED 0x0B 48 - #define ARMV8_PMUV3_PERFCTR_PC_WRITE_RETIRED 0x0C 49 - #define ARMV8_PMUV3_PERFCTR_BR_IMMED_RETIRED 0x0D 50 - #define ARMV8_PMUV3_PERFCTR_BR_RETURN_RETIRED 0x0E 51 - #define ARMV8_PMUV3_PERFCTR_UNALIGNED_LDST_RETIRED 0x0F 52 - #define ARMV8_PMUV3_PERFCTR_TTBR_WRITE_RETIRED 0x1C 53 - #define ARMV8_PMUV3_PERFCTR_CHAIN 0x1E 54 - #define ARMV8_PMUV3_PERFCTR_BR_RETIRED 0x21 55 - 56 - /* Common microarchitectural events. */ 57 - #define ARMV8_PMUV3_PERFCTR_L1I_CACHE_REFILL 0x01 58 - #define ARMV8_PMUV3_PERFCTR_L1I_TLB_REFILL 0x02 59 - #define ARMV8_PMUV3_PERFCTR_L1D_TLB_REFILL 0x05 60 - #define ARMV8_PMUV3_PERFCTR_MEM_ACCESS 0x13 61 - #define ARMV8_PMUV3_PERFCTR_L1I_CACHE 0x14 62 - #define ARMV8_PMUV3_PERFCTR_L1D_CACHE_WB 0x15 63 - #define ARMV8_PMUV3_PERFCTR_L2D_CACHE 0x16 64 - #define ARMV8_PMUV3_PERFCTR_L2D_CACHE_REFILL 0x17 65 - #define ARMV8_PMUV3_PERFCTR_L2D_CACHE_WB 0x18 66 - #define ARMV8_PMUV3_PERFCTR_BUS_ACCESS 0x19 67 - #define ARMV8_PMUV3_PERFCTR_MEMORY_ERROR 0x1A 68 - #define ARMV8_PMUV3_PERFCTR_BUS_CYCLES 0x1D 69 - #define ARMV8_PMUV3_PERFCTR_L1D_CACHE_ALLOCATE 0x1F 70 - #define ARMV8_PMUV3_PERFCTR_L2D_CACHE_ALLOCATE 0x20 71 - #define ARMV8_PMUV3_PERFCTR_BR_MIS_PRED_RETIRED 0x22 72 - #define ARMV8_PMUV3_PERFCTR_STALL_FRONTEND 0x23 73 - #define ARMV8_PMUV3_PERFCTR_STALL_BACKEND 0x24 74 - #define ARMV8_PMUV3_PERFCTR_L1D_TLB 0x25 75 - #define ARMV8_PMUV3_PERFCTR_L1I_TLB 0x26 76 - #define ARMV8_PMUV3_PERFCTR_L2I_CACHE 0x27 77 - #define ARMV8_PMUV3_PERFCTR_L2I_CACHE_REFILL 0x28 78 - #define ARMV8_PMUV3_PERFCTR_L3D_CACHE_ALLOCATE 0x29 79 - #define ARMV8_PMUV3_PERFCTR_L3D_CACHE_REFILL 0x2A 80 - #define ARMV8_PMUV3_PERFCTR_L3D_CACHE 0x2B 81 - #define ARMV8_PMUV3_PERFCTR_L3D_CACHE_WB 0x2C 82 - #define ARMV8_PMUV3_PERFCTR_L2D_TLB_REFILL 0x2D 83 - #define ARMV8_PMUV3_PERFCTR_L2I_TLB_REFILL 0x2E 84 - #define ARMV8_PMUV3_PERFCTR_L2D_TLB 0x2F 85 - #define ARMV8_PMUV3_PERFCTR_L2I_TLB 0x30 86 - 87 - /* ARMv8 recommended implementation defined event types */ 88 - #define ARMV8_IMPDEF_PERFCTR_L1D_CACHE_RD 0x40 89 - #define ARMV8_IMPDEF_PERFCTR_L1D_CACHE_WR 0x41 90 - #define ARMV8_IMPDEF_PERFCTR_L1D_CACHE_REFILL_RD 0x42 91 - #define ARMV8_IMPDEF_PERFCTR_L1D_CACHE_REFILL_WR 0x43 92 - #define ARMV8_IMPDEF_PERFCTR_L1D_CACHE_REFILL_INNER 0x44 93 - #define ARMV8_IMPDEF_PERFCTR_L1D_CACHE_REFILL_OUTER 0x45 94 - #define ARMV8_IMPDEF_PERFCTR_L1D_CACHE_WB_VICTIM 0x46 95 - #define ARMV8_IMPDEF_PERFCTR_L1D_CACHE_WB_CLEAN 0x47 96 - #define ARMV8_IMPDEF_PERFCTR_L1D_CACHE_INVAL 0x48 97 - 98 - #define ARMV8_IMPDEF_PERFCTR_L1D_TLB_REFILL_RD 0x4C 99 - #define ARMV8_IMPDEF_PERFCTR_L1D_TLB_REFILL_WR 0x4D 100 - #define ARMV8_IMPDEF_PERFCTR_L1D_TLB_RD 0x4E 101 - #define ARMV8_IMPDEF_PERFCTR_L1D_TLB_WR 0x4F 102 - #define ARMV8_IMPDEF_PERFCTR_L2D_CACHE_RD 0x50 103 - #define ARMV8_IMPDEF_PERFCTR_L2D_CACHE_WR 0x51 104 - #define ARMV8_IMPDEF_PERFCTR_L2D_CACHE_REFILL_RD 0x52 105 - #define ARMV8_IMPDEF_PERFCTR_L2D_CACHE_REFILL_WR 0x53 106 - 107 - #define ARMV8_IMPDEF_PERFCTR_L2D_CACHE_WB_VICTIM 0x56 108 - #define ARMV8_IMPDEF_PERFCTR_L2D_CACHE_WB_CLEAN 0x57 109 - #define ARMV8_IMPDEF_PERFCTR_L2D_CACHE_INVAL 0x58 110 - 111 - #define ARMV8_IMPDEF_PERFCTR_L2D_TLB_REFILL_RD 0x5C 112 - #define ARMV8_IMPDEF_PERFCTR_L2D_TLB_REFILL_WR 0x5D 113 - #define ARMV8_IMPDEF_PERFCTR_L2D_TLB_RD 0x5E 114 - #define ARMV8_IMPDEF_PERFCTR_L2D_TLB_WR 0x5F 115 - 116 - #define ARMV8_IMPDEF_PERFCTR_BUS_ACCESS_RD 0x60 117 - #define ARMV8_IMPDEF_PERFCTR_BUS_ACCESS_WR 0x61 118 - #define ARMV8_IMPDEF_PERFCTR_BUS_ACCESS_SHARED 0x62 119 - #define ARMV8_IMPDEF_PERFCTR_BUS_ACCESS_NOT_SHARED 0x63 120 - #define ARMV8_IMPDEF_PERFCTR_BUS_ACCESS_NORMAL 0x64 121 - #define ARMV8_IMPDEF_PERFCTR_BUS_ACCESS_PERIPH 0x65 122 - 123 - #define ARMV8_IMPDEF_PERFCTR_MEM_ACCESS_RD 0x66 124 - #define ARMV8_IMPDEF_PERFCTR_MEM_ACCESS_WR 0x67 125 - #define ARMV8_IMPDEF_PERFCTR_UNALIGNED_LD_SPEC 0x68 126 - #define ARMV8_IMPDEF_PERFCTR_UNALIGNED_ST_SPEC 0x69 127 - #define ARMV8_IMPDEF_PERFCTR_UNALIGNED_LDST_SPEC 0x6A 128 - 129 - #define ARMV8_IMPDEF_PERFCTR_LDREX_SPEC 0x6C 130 - #define ARMV8_IMPDEF_PERFCTR_STREX_PASS_SPEC 0x6D 131 - #define ARMV8_IMPDEF_PERFCTR_STREX_FAIL_SPEC 0x6E 132 - #define ARMV8_IMPDEF_PERFCTR_STREX_SPEC 0x6F 133 - #define ARMV8_IMPDEF_PERFCTR_LD_SPEC 0x70 134 - #define ARMV8_IMPDEF_PERFCTR_ST_SPEC 0x71 135 - #define ARMV8_IMPDEF_PERFCTR_LDST_SPEC 0x72 136 - #define ARMV8_IMPDEF_PERFCTR_DP_SPEC 0x73 137 - #define ARMV8_IMPDEF_PERFCTR_ASE_SPEC 0x74 138 - #define ARMV8_IMPDEF_PERFCTR_VFP_SPEC 0x75 139 - #define ARMV8_IMPDEF_PERFCTR_PC_WRITE_SPEC 0x76 140 - #define ARMV8_IMPDEF_PERFCTR_CRYPTO_SPEC 0x77 141 - #define ARMV8_IMPDEF_PERFCTR_BR_IMMED_SPEC 0x78 142 - #define ARMV8_IMPDEF_PERFCTR_BR_RETURN_SPEC 0x79 143 - #define ARMV8_IMPDEF_PERFCTR_BR_INDIRECT_SPEC 0x7A 144 - 145 - #define ARMV8_IMPDEF_PERFCTR_ISB_SPEC 0x7C 146 - #define ARMV8_IMPDEF_PERFCTR_DSB_SPEC 0x7D 147 - #define ARMV8_IMPDEF_PERFCTR_DMB_SPEC 0x7E 148 - 149 - #define ARMV8_IMPDEF_PERFCTR_EXC_UNDEF 0x81 150 - #define ARMV8_IMPDEF_PERFCTR_EXC_SVC 0x82 151 - #define ARMV8_IMPDEF_PERFCTR_EXC_PABORT 0x83 152 - #define ARMV8_IMPDEF_PERFCTR_EXC_DABORT 0x84 153 - 154 - #define ARMV8_IMPDEF_PERFCTR_EXC_IRQ 0x86 155 - #define ARMV8_IMPDEF_PERFCTR_EXC_FIQ 0x87 156 - #define ARMV8_IMPDEF_PERFCTR_EXC_SMC 0x88 157 - 158 - #define ARMV8_IMPDEF_PERFCTR_EXC_HVC 0x8A 159 - #define ARMV8_IMPDEF_PERFCTR_EXC_TRAP_PABORT 0x8B 160 - #define ARMV8_IMPDEF_PERFCTR_EXC_TRAP_DABORT 0x8C 161 - #define ARMV8_IMPDEF_PERFCTR_EXC_TRAP_OTHER 0x8D 162 - #define ARMV8_IMPDEF_PERFCTR_EXC_TRAP_IRQ 0x8E 163 - #define ARMV8_IMPDEF_PERFCTR_EXC_TRAP_FIQ 0x8F 164 - #define ARMV8_IMPDEF_PERFCTR_RC_LD_SPEC 0x90 165 - #define ARMV8_IMPDEF_PERFCTR_RC_ST_SPEC 0x91 166 - 167 - #define ARMV8_IMPDEF_PERFCTR_L3D_CACHE_RD 0xA0 168 - #define ARMV8_IMPDEF_PERFCTR_L3D_CACHE_WR 0xA1 169 - #define ARMV8_IMPDEF_PERFCTR_L3D_CACHE_REFILL_RD 0xA2 170 - #define ARMV8_IMPDEF_PERFCTR_L3D_CACHE_REFILL_WR 0xA3 171 - 172 - #define ARMV8_IMPDEF_PERFCTR_L3D_CACHE_WB_VICTIM 0xA6 173 - #define ARMV8_IMPDEF_PERFCTR_L3D_CACHE_WB_CLEAN 0xA7 174 - #define ARMV8_IMPDEF_PERFCTR_L3D_CACHE_INVAL 0xA8 175 - 176 33 /* ARMv8 Cortex-A53 specific event types. */ 177 34 #define ARMV8_A53_PERFCTR_PREF_LINEFILL 0xC2 178 35 ··· 40 183 #define ARMV8_THUNDER_PERFCTR_L1I_CACHE_PREF_ACCESS 0xEC 41 184 #define ARMV8_THUNDER_PERFCTR_L1I_CACHE_PREF_MISS 0xED 42 185 43 - /* PMUv3 HW events mapping. */ 44 - 45 186 /* 46 187 * ARMv8 Architectural defined events, not all of these may 47 - * be supported on any given implementation. Undefined events will 48 - * be disabled at run-time. 188 + * be supported on any given implementation. Unsupported events will 189 + * be disabled at run-time based on the PMCEID registers. 49 190 */ 50 191 static const unsigned armv8_pmuv3_perf_map[PERF_COUNT_HW_MAX] = { 51 192 PERF_MAP_ALL_UNSUPPORTED, ··· 65 210 66 211 [C(L1D)][C(OP_READ)][C(RESULT_ACCESS)] = ARMV8_PMUV3_PERFCTR_L1D_CACHE, 67 212 [C(L1D)][C(OP_READ)][C(RESULT_MISS)] = ARMV8_PMUV3_PERFCTR_L1D_CACHE_REFILL, 68 - [C(L1D)][C(OP_WRITE)][C(RESULT_ACCESS)] = ARMV8_PMUV3_PERFCTR_L1D_CACHE, 69 - [C(L1D)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV8_PMUV3_PERFCTR_L1D_CACHE_REFILL, 70 213 71 214 [C(L1I)][C(OP_READ)][C(RESULT_ACCESS)] = ARMV8_PMUV3_PERFCTR_L1I_CACHE, 72 215 [C(L1I)][C(OP_READ)][C(RESULT_MISS)] = ARMV8_PMUV3_PERFCTR_L1I_CACHE_REFILL, ··· 77 224 78 225 [C(BPU)][C(OP_READ)][C(RESULT_ACCESS)] = ARMV8_PMUV3_PERFCTR_BR_PRED, 79 226 [C(BPU)][C(OP_READ)][C(RESULT_MISS)] = ARMV8_PMUV3_PERFCTR_BR_MIS_PRED, 80 - [C(BPU)][C(OP_WRITE)][C(RESULT_ACCESS)] = ARMV8_PMUV3_PERFCTR_BR_PRED, 81 - [C(BPU)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV8_PMUV3_PERFCTR_BR_MIS_PRED, 82 227 }; 83 228 84 229 static const unsigned armv8_a53_perf_cache_map[PERF_COUNT_HW_CACHE_MAX] ··· 221 370 ARMV8_EVENT_ATTR(l2i_tlb_refill, ARMV8_PMUV3_PERFCTR_L2I_TLB_REFILL); 222 371 ARMV8_EVENT_ATTR(l2d_tlb, ARMV8_PMUV3_PERFCTR_L2D_TLB); 223 372 ARMV8_EVENT_ATTR(l2i_tlb, ARMV8_PMUV3_PERFCTR_L2I_TLB); 373 + ARMV8_EVENT_ATTR(remote_access, ARMV8_PMUV3_PERFCTR_REMOTE_ACCESS); 374 + ARMV8_EVENT_ATTR(ll_cache, ARMV8_PMUV3_PERFCTR_LL_CACHE); 375 + ARMV8_EVENT_ATTR(ll_cache_miss, ARMV8_PMUV3_PERFCTR_LL_CACHE_MISS); 376 + ARMV8_EVENT_ATTR(dtlb_walk, ARMV8_PMUV3_PERFCTR_DTLB_WALK); 377 + ARMV8_EVENT_ATTR(itlb_walk, ARMV8_PMUV3_PERFCTR_ITLB_WALK); 378 + ARMV8_EVENT_ATTR(ll_cache_rd, ARMV8_PMUV3_PERFCTR_LL_CACHE_RD); 379 + ARMV8_EVENT_ATTR(ll_cache_miss_rd, ARMV8_PMUV3_PERFCTR_LL_CACHE_MISS_RD); 380 + ARMV8_EVENT_ATTR(remote_access_rd, ARMV8_PMUV3_PERFCTR_REMOTE_ACCESS_RD); 381 + ARMV8_EVENT_ATTR(sample_pop, ARMV8_SPE_PERFCTR_SAMPLE_POP); 382 + ARMV8_EVENT_ATTR(sample_feed, ARMV8_SPE_PERFCTR_SAMPLE_FEED); 383 + ARMV8_EVENT_ATTR(sample_filtrate, ARMV8_SPE_PERFCTR_SAMPLE_FILTRATE); 384 + ARMV8_EVENT_ATTR(sample_collision, ARMV8_SPE_PERFCTR_SAMPLE_COLLISION); 224 385 225 386 static struct attribute *armv8_pmuv3_event_attrs[] = { 226 387 &armv8_event_attr_sw_incr.attr.attr, ··· 283 420 &armv8_event_attr_l2i_tlb_refill.attr.attr, 284 421 &armv8_event_attr_l2d_tlb.attr.attr, 285 422 &armv8_event_attr_l2i_tlb.attr.attr, 423 + &armv8_event_attr_remote_access.attr.attr, 424 + &armv8_event_attr_ll_cache.attr.attr, 425 + &armv8_event_attr_ll_cache_miss.attr.attr, 426 + &armv8_event_attr_dtlb_walk.attr.attr, 427 + &armv8_event_attr_itlb_walk.attr.attr, 428 + &armv8_event_attr_ll_cache_rd.attr.attr, 429 + &armv8_event_attr_ll_cache_miss_rd.attr.attr, 430 + &armv8_event_attr_remote_access_rd.attr.attr, 431 + &armv8_event_attr_sample_pop.attr.attr, 432 + &armv8_event_attr_sample_feed.attr.attr, 433 + &armv8_event_attr_sample_filtrate.attr.attr, 434 + &armv8_event_attr_sample_collision.attr.attr, 286 435 NULL, 287 436 }; 288 437 ··· 309 434 310 435 pmu_attr = container_of(attr, struct perf_pmu_events_attr, attr.attr); 311 436 312 - if (test_bit(pmu_attr->id, cpu_pmu->pmceid_bitmap)) 437 + if (pmu_attr->id < ARMV8_PMUV3_MAX_COMMON_EVENTS && 438 + test_bit(pmu_attr->id, cpu_pmu->pmceid_bitmap)) 439 + return attr->mode; 440 + 441 + pmu_attr->id -= ARMV8_PMUV3_EXT_COMMON_EVENT_BASE; 442 + if (pmu_attr->id < ARMV8_PMUV3_MAX_COMMON_EVENTS && 443 + test_bit(pmu_attr->id, cpu_pmu->pmceid_ext_bitmap)) 313 444 return attr->mode; 314 445 315 446 return 0; ··· 890 1009 if (armv8pmu_event_is_64bit(event)) 891 1010 event->hw.flags |= ARMPMU_EVT_64BIT; 892 1011 893 - /* Onl expose micro/arch events supported by this PMU */ 1012 + /* Only expose micro/arch events supported by this PMU */ 894 1013 if ((hw_event_id > 0) && (hw_event_id < ARMV8_PMUV3_MAX_COMMON_EVENTS) 895 1014 && test_bit(hw_event_id, armpmu->pmceid_bitmap)) { 896 1015 return hw_event_id; ··· 942 1061 struct armv8pmu_probe_info *probe = info; 943 1062 struct arm_pmu *cpu_pmu = probe->pmu; 944 1063 u64 dfr0; 1064 + u64 pmceid_raw[2]; 945 1065 u32 pmceid[2]; 946 1066 int pmuver; 947 1067 ··· 961 1079 /* Add the CPU cycles counter */ 962 1080 cpu_pmu->num_events += 1; 963 1081 964 - pmceid[0] = read_sysreg(pmceid0_el0); 965 - pmceid[1] = read_sysreg(pmceid1_el0); 1082 + pmceid[0] = pmceid_raw[0] = read_sysreg(pmceid0_el0); 1083 + pmceid[1] = pmceid_raw[1] = read_sysreg(pmceid1_el0); 966 1084 967 1085 bitmap_from_arr32(cpu_pmu->pmceid_bitmap, 1086 + pmceid, ARMV8_PMUV3_MAX_COMMON_EVENTS); 1087 + 1088 + pmceid[0] = pmceid_raw[0] >> 32; 1089 + pmceid[1] = pmceid_raw[1] >> 32; 1090 + 1091 + bitmap_from_arr32(cpu_pmu->pmceid_ext_bitmap, 968 1092 pmceid, ARMV8_PMUV3_MAX_COMMON_EVENTS); 969 1093 } 970 1094 ··· 997 1109 if (ret) 998 1110 return ret; 999 1111 1000 - cpu_pmu->handle_irq = armv8pmu_handle_irq, 1001 - cpu_pmu->enable = armv8pmu_enable_event, 1002 - cpu_pmu->disable = armv8pmu_disable_event, 1003 - cpu_pmu->read_counter = armv8pmu_read_counter, 1004 - cpu_pmu->write_counter = armv8pmu_write_counter, 1005 - cpu_pmu->get_event_idx = armv8pmu_get_event_idx, 1006 - cpu_pmu->clear_event_idx = armv8pmu_clear_event_idx, 1007 - cpu_pmu->start = armv8pmu_start, 1008 - cpu_pmu->stop = armv8pmu_stop, 1009 - cpu_pmu->reset = armv8pmu_reset, 1112 + cpu_pmu->handle_irq = armv8pmu_handle_irq; 1113 + cpu_pmu->enable = armv8pmu_enable_event; 1114 + cpu_pmu->disable = armv8pmu_disable_event; 1115 + cpu_pmu->read_counter = armv8pmu_read_counter; 1116 + cpu_pmu->write_counter = armv8pmu_write_counter; 1117 + cpu_pmu->get_event_idx = armv8pmu_get_event_idx; 1118 + cpu_pmu->clear_event_idx = armv8pmu_clear_event_idx; 1119 + cpu_pmu->start = armv8pmu_start; 1120 + cpu_pmu->stop = armv8pmu_stop; 1121 + cpu_pmu->reset = armv8pmu_reset; 1010 1122 cpu_pmu->set_event_filter = armv8pmu_set_event_filter; 1011 1123 cpu_pmu->filter_match = armv8pmu_filter_match; 1012 1124 ··· 1162 1274 .driver = { 1163 1275 .name = ARMV8_PMU_PDEV_NAME, 1164 1276 .of_match_table = armv8_pmu_of_device_ids, 1277 + .suppress_bind_attrs = true, 1165 1278 }, 1166 1279 .probe = armv8_pmu_device_probe, 1167 1280 };
+47
arch/arm64/kernel/pointer_auth.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + 3 + #include <linux/errno.h> 4 + #include <linux/prctl.h> 5 + #include <linux/random.h> 6 + #include <linux/sched.h> 7 + #include <asm/cpufeature.h> 8 + #include <asm/pointer_auth.h> 9 + 10 + int ptrauth_prctl_reset_keys(struct task_struct *tsk, unsigned long arg) 11 + { 12 + struct ptrauth_keys *keys = &tsk->thread.keys_user; 13 + unsigned long addr_key_mask = PR_PAC_APIAKEY | PR_PAC_APIBKEY | 14 + PR_PAC_APDAKEY | PR_PAC_APDBKEY; 15 + unsigned long key_mask = addr_key_mask | PR_PAC_APGAKEY; 16 + 17 + if (!system_supports_address_auth() && !system_supports_generic_auth()) 18 + return -EINVAL; 19 + 20 + if (!arg) { 21 + ptrauth_keys_init(keys); 22 + ptrauth_keys_switch(keys); 23 + return 0; 24 + } 25 + 26 + if (arg & ~key_mask) 27 + return -EINVAL; 28 + 29 + if (((arg & addr_key_mask) && !system_supports_address_auth()) || 30 + ((arg & PR_PAC_APGAKEY) && !system_supports_generic_auth())) 31 + return -EINVAL; 32 + 33 + if (arg & PR_PAC_APIAKEY) 34 + get_random_bytes(&keys->apia, sizeof(keys->apia)); 35 + if (arg & PR_PAC_APIBKEY) 36 + get_random_bytes(&keys->apib, sizeof(keys->apib)); 37 + if (arg & PR_PAC_APDAKEY) 38 + get_random_bytes(&keys->apda, sizeof(keys->apda)); 39 + if (arg & PR_PAC_APDBKEY) 40 + get_random_bytes(&keys->apdb, sizeof(keys->apdb)); 41 + if (arg & PR_PAC_APGAKEY) 42 + get_random_bytes(&keys->apga, sizeof(keys->apga)); 43 + 44 + ptrauth_keys_switch(keys); 45 + 46 + return 0; 47 + }
+5 -1
arch/arm64/kernel/process.c
··· 57 57 #include <asm/fpsimd.h> 58 58 #include <asm/mmu_context.h> 59 59 #include <asm/processor.h> 60 + #include <asm/pointer_auth.h> 60 61 #include <asm/stacktrace.h> 61 62 62 - #ifdef CONFIG_STACKPROTECTOR 63 + #if defined(CONFIG_STACKPROTECTOR) && !defined(CONFIG_STACKPROTECTOR_PER_TASK) 63 64 #include <linux/stackprotector.h> 64 65 unsigned long __stack_chk_guard __read_mostly; 65 66 EXPORT_SYMBOL(__stack_chk_guard); ··· 430 429 contextidr_thread_switch(next); 431 430 entry_task_switch(next); 432 431 uao_thread_switch(next); 432 + ptrauth_thread_switch(next); 433 433 434 434 /* 435 435 * Complete any pending TLB or cache maintenance on this CPU in case ··· 498 496 void arch_setup_new_exec(void) 499 497 { 500 498 current->mm->context.flags = is_compat_task() ? MMCF_AARCH32 : 0; 499 + 500 + ptrauth_thread_init_user(current); 501 501 }
+38
arch/arm64/kernel/ptrace.c
··· 46 46 #include <asm/debug-monitors.h> 47 47 #include <asm/fpsimd.h> 48 48 #include <asm/pgtable.h> 49 + #include <asm/pointer_auth.h> 49 50 #include <asm/stacktrace.h> 50 51 #include <asm/syscall.h> 51 52 #include <asm/traps.h> ··· 957 956 958 957 #endif /* CONFIG_ARM64_SVE */ 959 958 959 + #ifdef CONFIG_ARM64_PTR_AUTH 960 + static int pac_mask_get(struct task_struct *target, 961 + const struct user_regset *regset, 962 + unsigned int pos, unsigned int count, 963 + void *kbuf, void __user *ubuf) 964 + { 965 + /* 966 + * The PAC bits can differ across data and instruction pointers 967 + * depending on TCR_EL1.TBID*, which we may make use of in future, so 968 + * we expose separate masks. 969 + */ 970 + unsigned long mask = ptrauth_user_pac_mask(); 971 + struct user_pac_mask uregs = { 972 + .data_mask = mask, 973 + .insn_mask = mask, 974 + }; 975 + 976 + if (!system_supports_address_auth()) 977 + return -EINVAL; 978 + 979 + return user_regset_copyout(&pos, &count, &kbuf, &ubuf, &uregs, 0, -1); 980 + } 981 + #endif /* CONFIG_ARM64_PTR_AUTH */ 982 + 960 983 enum aarch64_regset { 961 984 REGSET_GPR, 962 985 REGSET_FPR, ··· 992 967 REGSET_SYSTEM_CALL, 993 968 #ifdef CONFIG_ARM64_SVE 994 969 REGSET_SVE, 970 + #endif 971 + #ifdef CONFIG_ARM64_PTR_AUTH 972 + REGSET_PAC_MASK, 995 973 #endif 996 974 }; 997 975 ··· 1063 1035 .get = sve_get, 1064 1036 .set = sve_set, 1065 1037 .get_size = sve_get_size, 1038 + }, 1039 + #endif 1040 + #ifdef CONFIG_ARM64_PTR_AUTH 1041 + [REGSET_PAC_MASK] = { 1042 + .core_note_type = NT_ARM_PAC_MASK, 1043 + .n = sizeof(struct user_pac_mask) / sizeof(u64), 1044 + .size = sizeof(u64), 1045 + .align = sizeof(u64), 1046 + .get = pac_mask_get, 1047 + /* this cannot be set dynamically */ 1066 1048 }, 1067 1049 #endif 1068 1050 };
+2 -1
arch/arm64/kernel/relocate_kernel.S
··· 32 32 ENTRY(arm64_relocate_new_kernel) 33 33 34 34 /* Setup the list loop variables. */ 35 + mov x18, x2 /* x18 = dtb address */ 35 36 mov x17, x1 /* x17 = kimage_start */ 36 37 mov x16, x0 /* x16 = kimage_head */ 37 38 raw_dcache_line_size x15, x0 /* x15 = dcache line size */ ··· 108 107 isb 109 108 110 109 /* Start new image. */ 111 - mov x0, xzr 110 + mov x0, x18 112 111 mov x1, xzr 113 112 mov x2, xzr 114 113 mov x3, xzr
+1
arch/arm64/kernel/setup.c
··· 388 388 if (IS_ENABLED(CONFIG_RANDOMIZE_BASE) && offset > 0) { 389 389 pr_emerg("Kernel Offset: 0x%lx from 0x%lx\n", 390 390 offset, KIMAGE_VADDR); 391 + pr_emerg("PHYS_OFFSET: 0x%llx\n", PHYS_OFFSET); 391 392 } else { 392 393 pr_emerg("Kernel Offset: disabled\n"); 393 394 }
+4
arch/arm64/kernel/smccc-call.S
··· 13 13 */ 14 14 #include <linux/linkage.h> 15 15 #include <linux/arm-smccc.h> 16 + 16 17 #include <asm/asm-offsets.h> 18 + #include <asm/assembler.h> 17 19 18 20 .macro SMCCC instr 19 21 .cfi_startproc ··· 42 40 ENTRY(__arm_smccc_smc) 43 41 SMCCC smc 44 42 ENDPROC(__arm_smccc_smc) 43 + EXPORT_SYMBOL(__arm_smccc_smc) 45 44 46 45 /* 47 46 * void arm_smccc_hvc(unsigned long a0, unsigned long a1, unsigned long a2, ··· 53 50 ENTRY(__arm_smccc_hvc) 54 51 SMCCC hvc 55 52 ENDPROC(__arm_smccc_hvc) 53 + EXPORT_SYMBOL(__arm_smccc_hvc)
+6 -1
arch/arm64/kernel/smp.c
··· 141 141 } 142 142 } else { 143 143 pr_err("CPU%u: failed to boot: %d\n", cpu, ret); 144 + return ret; 144 145 } 145 146 146 147 secondary_data.task = NULL; ··· 152 151 if (status == CPU_MMU_OFF) 153 152 status = READ_ONCE(__early_cpu_boot_status); 154 153 155 - switch (status) { 154 + switch (status & CPU_BOOT_STATUS_MASK) { 156 155 default: 157 156 pr_err("CPU%u: failed in unknown state : 0x%lx\n", 158 157 cpu, status); ··· 166 165 pr_crit("CPU%u: may not have shut down cleanly\n", cpu); 167 166 case CPU_STUCK_IN_KERNEL: 168 167 pr_crit("CPU%u: is stuck in kernel\n", cpu); 168 + if (status & CPU_STUCK_REASON_52_BIT_VA) 169 + pr_crit("CPU%u: does not support 52-bit VAs\n", cpu); 170 + if (status & CPU_STUCK_REASON_NO_GRAN) 171 + pr_crit("CPU%u: does not support %luK granule \n", cpu, PAGE_SIZE / SZ_1K); 169 172 cpus_stuck_in_kernel++; 170 173 break; 171 174 case CPU_PANIC_KERNEL:
+5 -4
arch/arm64/kernel/vmlinux.lds.S
··· 99 99 *(.discard) 100 100 *(.discard.*) 101 101 *(.interp .dynamic) 102 - *(.dynsym .dynstr .hash) 102 + *(.dynsym .dynstr .hash .gnu.hash) 103 + *(.eh_frame) 103 104 } 104 105 105 106 . = KIMAGE_VADDR + TEXT_OFFSET; ··· 193 192 194 193 PERCPU_SECTION(L1_CACHE_BYTES) 195 194 196 - .rela : ALIGN(8) { 195 + .rela.dyn : ALIGN(8) { 197 196 *(.rela .rela*) 198 197 } 199 198 200 - __rela_offset = ABSOLUTE(ADDR(.rela) - KIMAGE_VADDR); 201 - __rela_size = SIZEOF(.rela); 199 + __rela_offset = ABSOLUTE(ADDR(.rela.dyn) - KIMAGE_VADDR); 200 + __rela_size = SIZEOF(.rela.dyn); 202 201 203 202 . = ALIGN(SEGMENT_ALIGN); 204 203 __initdata_end = .;
+18
arch/arm64/kvm/handle_exit.c
··· 173 173 return 1; 174 174 } 175 175 176 + /* 177 + * Guest usage of a ptrauth instruction (which the guest EL1 did not turn into 178 + * a NOP). 179 + */ 180 + static int kvm_handle_ptrauth(struct kvm_vcpu *vcpu, struct kvm_run *run) 181 + { 182 + /* 183 + * We don't currently support ptrauth in a guest, and we mask the ID 184 + * registers to prevent well-behaved guests from trying to make use of 185 + * it. 186 + * 187 + * Inject an UNDEF, as if the feature really isn't present. 188 + */ 189 + kvm_inject_undefined(vcpu); 190 + return 1; 191 + } 192 + 176 193 static exit_handle_fn arm_exit_handlers[] = { 177 194 [0 ... ESR_ELx_EC_MAX] = kvm_handle_unknown_ec, 178 195 [ESR_ELx_EC_WFx] = kvm_handle_wfx, ··· 212 195 [ESR_ELx_EC_BKPT32] = kvm_handle_guest_debug, 213 196 [ESR_ELx_EC_BRK64] = kvm_handle_guest_debug, 214 197 [ESR_ELx_EC_FP_ASIMD] = handle_no_fpsimd, 198 + [ESR_ELx_EC_PAC] = kvm_handle_ptrauth, 215 199 }; 216 200 217 201 static exit_handle_fn kvm_get_exit_handler(struct kvm_vcpu *vcpu)
+1
arch/arm64/kvm/hyp/entry.S
··· 83 83 84 84 // Do not touch any register after this! 85 85 eret 86 + sb 86 87 ENDPROC(__guest_enter) 87 88 88 89 ENTRY(__guest_exit)
+4
arch/arm64/kvm/hyp/hyp-entry.S
··· 96 96 do_el2_call 97 97 98 98 eret 99 + sb 99 100 100 101 el1_hvc_guest: 101 102 /* ··· 147 146 mov x0, xzr 148 147 add sp, sp, #16 149 148 eret 149 + sb 150 150 151 151 el1_trap: 152 152 get_vcpu_ptr x1, x0 ··· 201 199 b.ne __hyp_panic 202 200 mov x0, #(1 << ARM_EXIT_WITH_SERROR_BIT) 203 201 eret 202 + sb 204 203 205 204 ENTRY(__hyp_do_panic) 206 205 mov lr, #(PSR_F_BIT | PSR_I_BIT | PSR_A_BIT | PSR_D_BIT |\ ··· 210 207 ldr lr, =panic 211 208 msr elr_el2, lr 212 209 eret 210 + sb 213 211 ENDPROC(__hyp_do_panic) 214 212 215 213 ENTRY(__hyp_panic)
+22 -3
arch/arm64/kvm/hyp/switch.c
··· 143 143 { 144 144 extern char vectors[]; /* kernel exception vectors */ 145 145 write_sysreg(HCR_HOST_VHE_FLAGS, hcr_el2); 146 + 147 + /* 148 + * ARM erratum 1165522 requires the actual execution of the above 149 + * before we can switch to the EL2/EL0 translation regime used by 150 + * the host. 151 + */ 152 + asm(ALTERNATIVE("nop", "isb", ARM64_WORKAROUND_1165522)); 153 + 146 154 write_sysreg(CPACR_EL1_DEFAULT, cpacr_el1); 147 155 write_sysreg(vectors, vbar_el1); 148 156 } ··· 165 157 mdcr_el2 |= MDCR_EL2_E2PB_MASK << MDCR_EL2_E2PB_SHIFT; 166 158 167 159 write_sysreg(mdcr_el2, mdcr_el2); 168 - write_sysreg(HCR_RW, hcr_el2); 160 + write_sysreg(HCR_HOST_NVHE_FLAGS, hcr_el2); 169 161 write_sysreg(CPTR_EL2_DEFAULT, cptr_el2); 170 162 } 171 163 ··· 507 499 508 500 sysreg_save_host_state_vhe(host_ctxt); 509 501 510 - __activate_traps(vcpu); 502 + /* 503 + * ARM erratum 1165522 requires us to configure both stage 1 and 504 + * stage 2 translation for the guest context before we clear 505 + * HCR_EL2.TGE. 506 + * 507 + * We have already configured the guest's stage 1 translation in 508 + * kvm_vcpu_load_sysregs above. We must now call __activate_vm 509 + * before __activate_traps, because __activate_vm configures 510 + * stage 2 translation, and __activate_traps clear HCR_EL2.TGE 511 + * (among other things). 512 + */ 511 513 __activate_vm(vcpu->kvm); 514 + __activate_traps(vcpu); 512 515 513 516 sysreg_restore_guest_state_vhe(guest_ctxt); 514 517 __debug_switch_to_guest(vcpu); ··· 564 545 565 546 __sysreg_save_state_nvhe(host_ctxt); 566 547 567 - __activate_traps(vcpu); 568 548 __activate_vm(kern_hyp_va(vcpu->kvm)); 549 + __activate_traps(vcpu); 569 550 570 551 __hyp_vgic_restore_state(vcpu); 571 552 __timer_enable_traps(vcpu);
+61 -10
arch/arm64/kvm/hyp/tlb.c
··· 15 15 * along with this program. If not, see <http://www.gnu.org/licenses/>. 16 16 */ 17 17 18 + #include <linux/irqflags.h> 19 + 18 20 #include <asm/kvm_hyp.h> 19 21 #include <asm/kvm_mmu.h> 20 22 #include <asm/tlbflush.h> 21 23 22 - static void __hyp_text __tlb_switch_to_guest_vhe(struct kvm *kvm) 24 + struct tlb_inv_context { 25 + unsigned long flags; 26 + u64 tcr; 27 + u64 sctlr; 28 + }; 29 + 30 + static void __hyp_text __tlb_switch_to_guest_vhe(struct kvm *kvm, 31 + struct tlb_inv_context *cxt) 23 32 { 24 33 u64 val; 34 + 35 + local_irq_save(cxt->flags); 36 + 37 + if (cpus_have_const_cap(ARM64_WORKAROUND_1165522)) { 38 + /* 39 + * For CPUs that are affected by ARM erratum 1165522, we 40 + * cannot trust stage-1 to be in a correct state at that 41 + * point. Since we do not want to force a full load of the 42 + * vcpu state, we prevent the EL1 page-table walker to 43 + * allocate new TLBs. This is done by setting the EPD bits 44 + * in the TCR_EL1 register. We also need to prevent it to 45 + * allocate IPA->PA walks, so we enable the S1 MMU... 46 + */ 47 + val = cxt->tcr = read_sysreg_el1(tcr); 48 + val |= TCR_EPD1_MASK | TCR_EPD0_MASK; 49 + write_sysreg_el1(val, tcr); 50 + val = cxt->sctlr = read_sysreg_el1(sctlr); 51 + val |= SCTLR_ELx_M; 52 + write_sysreg_el1(val, sctlr); 53 + } 25 54 26 55 /* 27 56 * With VHE enabled, we have HCR_EL2.{E2H,TGE} = {1,1}, and ··· 58 29 * guest TLBs (EL1/EL0), we need to change one of these two 59 30 * bits. Changing E2H is impossible (goodbye TTBR1_EL2), so 60 31 * let's flip TGE before executing the TLB operation. 32 + * 33 + * ARM erratum 1165522 requires some special handling (again), 34 + * as we need to make sure both stages of translation are in 35 + * place before clearing TGE. __load_guest_stage2() already 36 + * has an ISB in order to deal with this. 61 37 */ 62 38 __load_guest_stage2(kvm); 63 39 val = read_sysreg(hcr_el2); ··· 71 37 isb(); 72 38 } 73 39 74 - static void __hyp_text __tlb_switch_to_guest_nvhe(struct kvm *kvm) 40 + static void __hyp_text __tlb_switch_to_guest_nvhe(struct kvm *kvm, 41 + struct tlb_inv_context *cxt) 75 42 { 76 43 __load_guest_stage2(kvm); 77 44 isb(); ··· 83 48 __tlb_switch_to_guest_vhe, 84 49 ARM64_HAS_VIRT_HOST_EXTN); 85 50 86 - static void __hyp_text __tlb_switch_to_host_vhe(struct kvm *kvm) 51 + static void __hyp_text __tlb_switch_to_host_vhe(struct kvm *kvm, 52 + struct tlb_inv_context *cxt) 87 53 { 88 54 /* 89 55 * We're done with the TLB operation, let's restore the host's ··· 92 56 */ 93 57 write_sysreg(0, vttbr_el2); 94 58 write_sysreg(HCR_HOST_VHE_FLAGS, hcr_el2); 59 + isb(); 60 + 61 + if (cpus_have_const_cap(ARM64_WORKAROUND_1165522)) { 62 + /* Restore the registers to what they were */ 63 + write_sysreg_el1(cxt->tcr, tcr); 64 + write_sysreg_el1(cxt->sctlr, sctlr); 65 + } 66 + 67 + local_irq_restore(cxt->flags); 95 68 } 96 69 97 - static void __hyp_text __tlb_switch_to_host_nvhe(struct kvm *kvm) 70 + static void __hyp_text __tlb_switch_to_host_nvhe(struct kvm *kvm, 71 + struct tlb_inv_context *cxt) 98 72 { 99 73 write_sysreg(0, vttbr_el2); 100 74 } ··· 116 70 117 71 void __hyp_text __kvm_tlb_flush_vmid_ipa(struct kvm *kvm, phys_addr_t ipa) 118 72 { 73 + struct tlb_inv_context cxt; 74 + 119 75 dsb(ishst); 120 76 121 77 /* Switch to requested VMID */ 122 78 kvm = kern_hyp_va(kvm); 123 - __tlb_switch_to_guest()(kvm); 79 + __tlb_switch_to_guest()(kvm, &cxt); 124 80 125 81 /* 126 82 * We could do so much better if we had the VA as well. ··· 165 117 if (!has_vhe() && icache_is_vpipt()) 166 118 __flush_icache_all(); 167 119 168 - __tlb_switch_to_host()(kvm); 120 + __tlb_switch_to_host()(kvm, &cxt); 169 121 } 170 122 171 123 void __hyp_text __kvm_tlb_flush_vmid(struct kvm *kvm) 172 124 { 125 + struct tlb_inv_context cxt; 126 + 173 127 dsb(ishst); 174 128 175 129 /* Switch to requested VMID */ 176 130 kvm = kern_hyp_va(kvm); 177 - __tlb_switch_to_guest()(kvm); 131 + __tlb_switch_to_guest()(kvm, &cxt); 178 132 179 133 __tlbi(vmalls12e1is); 180 134 dsb(ish); 181 135 isb(); 182 136 183 - __tlb_switch_to_host()(kvm); 137 + __tlb_switch_to_host()(kvm, &cxt); 184 138 } 185 139 186 140 void __hyp_text __kvm_tlb_flush_local_vmid(struct kvm_vcpu *vcpu) 187 141 { 188 142 struct kvm *kvm = kern_hyp_va(kern_hyp_va(vcpu)->kvm); 143 + struct tlb_inv_context cxt; 189 144 190 145 /* Switch to requested VMID */ 191 - __tlb_switch_to_guest()(kvm); 146 + __tlb_switch_to_guest()(kvm, &cxt); 192 147 193 148 __tlbi(vmalle1); 194 149 dsb(nsh); 195 150 isb(); 196 151 197 - __tlb_switch_to_host()(kvm); 152 + __tlb_switch_to_host()(kvm, &cxt); 198 153 } 199 154 200 155 void __hyp_text __kvm_flush_vm_context(void)
+8
arch/arm64/kvm/sys_regs.c
··· 1040 1040 kvm_debug("SVE unsupported for guests, suppressing\n"); 1041 1041 1042 1042 val &= ~(0xfUL << ID_AA64PFR0_SVE_SHIFT); 1043 + } else if (id == SYS_ID_AA64ISAR1_EL1) { 1044 + const u64 ptrauth_mask = (0xfUL << ID_AA64ISAR1_APA_SHIFT) | 1045 + (0xfUL << ID_AA64ISAR1_API_SHIFT) | 1046 + (0xfUL << ID_AA64ISAR1_GPA_SHIFT) | 1047 + (0xfUL << ID_AA64ISAR1_GPI_SHIFT); 1048 + if (val & ptrauth_mask) 1049 + kvm_debug("ptrauth unsupported for guests, suppressing\n"); 1050 + val &= ~ptrauth_mask; 1043 1051 } else if (id == SYS_ID_AA64MMFR1_EL1) { 1044 1052 if (val & (0xfUL << ID_AA64MMFR1_LOR_SHIFT)) 1045 1053 kvm_debug("LORegions unsupported for guests, suppressing\n");
+6
arch/arm64/lib/Makefile
··· 5 5 memcmp.o strcmp.o strncmp.o strlen.o strnlen.o \ 6 6 strchr.o strrchr.o tishift.o 7 7 8 + ifeq ($(CONFIG_KERNEL_MODE_NEON), y) 9 + obj-$(CONFIG_XOR_BLOCKS) += xor-neon.o 10 + CFLAGS_REMOVE_xor-neon.o += -mgeneral-regs-only 11 + CFLAGS_xor-neon.o += -ffreestanding 12 + endif 13 + 8 14 # Tell the compiler to treat all general purpose registers (with the 9 15 # exception of the IP registers, which are already handled by the caller 10 16 # in case of a PLT) as callee-saved, which allows for efficient runtime
+1
arch/arm64/lib/clear_page.S
··· 37 37 b.ne 1b 38 38 ret 39 39 ENDPROC(clear_page) 40 + EXPORT_SYMBOL(clear_page)
+2
arch/arm64/lib/clear_user.S
··· 18 18 #include <linux/linkage.h> 19 19 20 20 #include <asm/asm-uaccess.h> 21 + #include <asm/assembler.h> 21 22 22 23 .text 23 24 ··· 54 53 uaccess_disable_not_uao x2, x3 55 54 ret 56 55 ENDPROC(__arch_clear_user) 56 + EXPORT_SYMBOL(__arch_clear_user) 57 57 58 58 .section .fixup,"ax" 59 59 .align 2
+3 -1
arch/arm64/lib/copy_from_user.S
··· 16 16 17 17 #include <linux/linkage.h> 18 18 19 - #include <asm/cache.h> 20 19 #include <asm/asm-uaccess.h> 20 + #include <asm/assembler.h> 21 + #include <asm/cache.h> 21 22 22 23 /* 23 24 * Copy from user space to a kernel buffer (alignment handled by the hardware) ··· 72 71 mov x0, #0 // Nothing to copy 73 72 ret 74 73 ENDPROC(__arch_copy_from_user) 74 + EXPORT_SYMBOL(__arch_copy_from_user) 75 75 76 76 .section .fixup,"ax" 77 77 .align 2
+3 -1
arch/arm64/lib/copy_in_user.S
··· 18 18 19 19 #include <linux/linkage.h> 20 20 21 - #include <asm/cache.h> 22 21 #include <asm/asm-uaccess.h> 22 + #include <asm/assembler.h> 23 + #include <asm/cache.h> 23 24 24 25 /* 25 26 * Copy from user space to user space (alignment handled by the hardware) ··· 74 73 mov x0, #0 75 74 ret 76 75 ENDPROC(__arch_copy_in_user) 76 + EXPORT_SYMBOL(__arch_copy_in_user) 77 77 78 78 .section .fixup,"ax" 79 79 .align 2
+1
arch/arm64/lib/copy_page.S
··· 87 87 88 88 ret 89 89 ENDPROC(copy_page) 90 + EXPORT_SYMBOL(copy_page)
+3 -1
arch/arm64/lib/copy_to_user.S
··· 16 16 17 17 #include <linux/linkage.h> 18 18 19 - #include <asm/cache.h> 20 19 #include <asm/asm-uaccess.h> 20 + #include <asm/assembler.h> 21 + #include <asm/cache.h> 21 22 22 23 /* 23 24 * Copy to user space from a kernel buffer (alignment handled by the hardware) ··· 71 70 mov x0, #0 72 71 ret 73 72 ENDPROC(__arch_copy_to_user) 73 + EXPORT_SYMBOL(__arch_copy_to_user) 74 74 75 75 .section .fixup,"ax" 76 76 .align 2
+49 -5
arch/arm64/lib/crc32.S
··· 15 15 .cpu generic+crc 16 16 17 17 .macro __crc32, c 18 - 0: subs x2, x2, #16 19 - b.mi 8f 20 - ldp x3, x4, [x1], #16 18 + cmp x2, #16 19 + b.lt 8f // less than 16 bytes 20 + 21 + and x7, x2, #0x1f 22 + and x2, x2, #~0x1f 23 + cbz x7, 32f // multiple of 32 bytes 24 + 25 + and x8, x7, #0xf 26 + ldp x3, x4, [x1] 27 + add x8, x8, x1 28 + add x1, x1, x7 29 + ldp x5, x6, [x8] 21 30 CPU_BE( rev x3, x3 ) 22 31 CPU_BE( rev x4, x4 ) 32 + CPU_BE( rev x5, x5 ) 33 + CPU_BE( rev x6, x6 ) 34 + 35 + tst x7, #8 36 + crc32\c\()x w8, w0, x3 37 + csel x3, x3, x4, eq 38 + csel w0, w0, w8, eq 39 + tst x7, #4 40 + lsr x4, x3, #32 41 + crc32\c\()w w8, w0, w3 42 + csel x3, x3, x4, eq 43 + csel w0, w0, w8, eq 44 + tst x7, #2 45 + lsr w4, w3, #16 46 + crc32\c\()h w8, w0, w3 47 + csel w3, w3, w4, eq 48 + csel w0, w0, w8, eq 49 + tst x7, #1 50 + crc32\c\()b w8, w0, w3 51 + csel w0, w0, w8, eq 52 + tst x7, #16 53 + crc32\c\()x w8, w0, x5 54 + crc32\c\()x w8, w8, x6 55 + csel w0, w0, w8, eq 56 + cbz x2, 0f 57 + 58 + 32: ldp x3, x4, [x1], #32 59 + sub x2, x2, #32 60 + ldp x5, x6, [x1, #-16] 61 + CPU_BE( rev x3, x3 ) 62 + CPU_BE( rev x4, x4 ) 63 + CPU_BE( rev x5, x5 ) 64 + CPU_BE( rev x6, x6 ) 23 65 crc32\c\()x w0, w0, x3 24 66 crc32\c\()x w0, w0, x4 25 - b.ne 0b 26 - ret 67 + crc32\c\()x w0, w0, x5 68 + crc32\c\()x w0, w0, x6 69 + cbnz x2, 32b 70 + 0: ret 27 71 28 72 8: tbz x2, #3, 4f 29 73 ldr x3, [x1], #8
+1
arch/arm64/lib/memchr.S
··· 42 42 2: mov x0, #0 43 43 ret 44 44 ENDPIPROC(memchr) 45 + EXPORT_SYMBOL_NOKASAN(memchr)
+1
arch/arm64/lib/memcmp.S
··· 256 256 mov result, #0 257 257 ret 258 258 ENDPIPROC(memcmp) 259 + EXPORT_SYMBOL_NOKASAN(memcmp)
+2
arch/arm64/lib/memcpy.S
··· 74 74 #include "copy_template.S" 75 75 ret 76 76 ENDPIPROC(memcpy) 77 + EXPORT_SYMBOL(memcpy) 77 78 ENDPROC(__memcpy) 79 + EXPORT_SYMBOL(__memcpy)
+2
arch/arm64/lib/memmove.S
··· 197 197 b.ne .Ltail63 198 198 ret 199 199 ENDPIPROC(memmove) 200 + EXPORT_SYMBOL(memmove) 200 201 ENDPROC(__memmove) 202 + EXPORT_SYMBOL(__memmove)
+2
arch/arm64/lib/memset.S
··· 216 216 b.ne .Ltail_maybe_long 217 217 ret 218 218 ENDPIPROC(memset) 219 + EXPORT_SYMBOL(memset) 219 220 ENDPROC(__memset) 221 + EXPORT_SYMBOL(__memset)
+1
arch/arm64/lib/strchr.S
··· 40 40 csel x0, x0, xzr, eq 41 41 ret 42 42 ENDPROC(strchr) 43 + EXPORT_SYMBOL_NOKASAN(strchr)
+1
arch/arm64/lib/strcmp.S
··· 232 232 sub result, data1, data2, lsr #56 233 233 ret 234 234 ENDPIPROC(strcmp) 235 + EXPORT_SYMBOL_NOKASAN(strcmp)
+1
arch/arm64/lib/strlen.S
··· 124 124 csel data2, data2, data2a, le 125 125 b .Lrealigned 126 126 ENDPIPROC(strlen) 127 + EXPORT_SYMBOL_NOKASAN(strlen)
+1
arch/arm64/lib/strncmp.S
··· 308 308 mov result, #0 309 309 ret 310 310 ENDPIPROC(strncmp) 311 + EXPORT_SYMBOL_NOKASAN(strncmp)
+1
arch/arm64/lib/strnlen.S
··· 169 169 mov len, limit 170 170 ret 171 171 ENDPIPROC(strnlen) 172 + EXPORT_SYMBOL_NOKASAN(strnlen)
+1
arch/arm64/lib/strrchr.S
··· 41 41 2: mov x0, x3 42 42 ret 43 43 ENDPIPROC(strrchr) 44 + EXPORT_SYMBOL_NOKASAN(strrchr)
+5
arch/arm64/lib/tishift.S
··· 5 5 6 6 #include <linux/linkage.h> 7 7 8 + #include <asm/assembler.h> 9 + 8 10 ENTRY(__ashlti3) 9 11 cbz x2, 1f 10 12 mov x3, #64 ··· 27 25 mov x0, x2 28 26 ret 29 27 ENDPROC(__ashlti3) 28 + EXPORT_SYMBOL(__ashlti3) 30 29 31 30 ENTRY(__ashrti3) 32 31 cbz x2, 1f ··· 49 46 mov x1, x2 50 47 ret 51 48 ENDPROC(__ashrti3) 49 + EXPORT_SYMBOL(__ashrti3) 52 50 53 51 ENTRY(__lshrti3) 54 52 cbz x2, 1f ··· 71 67 mov x1, x2 72 68 ret 73 69 ENDPROC(__lshrti3) 70 + EXPORT_SYMBOL(__lshrti3)
+184
arch/arm64/lib/xor-neon.c
··· 1 + /* 2 + * arch/arm64/lib/xor-neon.c 3 + * 4 + * Authors: Jackie Liu <liuyun01@kylinos.cn> 5 + * Copyright (C) 2018,Tianjin KYLIN Information Technology Co., Ltd. 6 + * 7 + * This program is free software; you can redistribute it and/or modify 8 + * it under the terms of the GNU General Public License version 2 as 9 + * published by the Free Software Foundation. 10 + */ 11 + 12 + #include <linux/raid/xor.h> 13 + #include <linux/module.h> 14 + #include <asm/neon-intrinsics.h> 15 + 16 + void xor_arm64_neon_2(unsigned long bytes, unsigned long *p1, 17 + unsigned long *p2) 18 + { 19 + uint64_t *dp1 = (uint64_t *)p1; 20 + uint64_t *dp2 = (uint64_t *)p2; 21 + 22 + register uint64x2_t v0, v1, v2, v3; 23 + long lines = bytes / (sizeof(uint64x2_t) * 4); 24 + 25 + do { 26 + /* p1 ^= p2 */ 27 + v0 = veorq_u64(vld1q_u64(dp1 + 0), vld1q_u64(dp2 + 0)); 28 + v1 = veorq_u64(vld1q_u64(dp1 + 2), vld1q_u64(dp2 + 2)); 29 + v2 = veorq_u64(vld1q_u64(dp1 + 4), vld1q_u64(dp2 + 4)); 30 + v3 = veorq_u64(vld1q_u64(dp1 + 6), vld1q_u64(dp2 + 6)); 31 + 32 + /* store */ 33 + vst1q_u64(dp1 + 0, v0); 34 + vst1q_u64(dp1 + 2, v1); 35 + vst1q_u64(dp1 + 4, v2); 36 + vst1q_u64(dp1 + 6, v3); 37 + 38 + dp1 += 8; 39 + dp2 += 8; 40 + } while (--lines > 0); 41 + } 42 + 43 + void xor_arm64_neon_3(unsigned long bytes, unsigned long *p1, 44 + unsigned long *p2, unsigned long *p3) 45 + { 46 + uint64_t *dp1 = (uint64_t *)p1; 47 + uint64_t *dp2 = (uint64_t *)p2; 48 + uint64_t *dp3 = (uint64_t *)p3; 49 + 50 + register uint64x2_t v0, v1, v2, v3; 51 + long lines = bytes / (sizeof(uint64x2_t) * 4); 52 + 53 + do { 54 + /* p1 ^= p2 */ 55 + v0 = veorq_u64(vld1q_u64(dp1 + 0), vld1q_u64(dp2 + 0)); 56 + v1 = veorq_u64(vld1q_u64(dp1 + 2), vld1q_u64(dp2 + 2)); 57 + v2 = veorq_u64(vld1q_u64(dp1 + 4), vld1q_u64(dp2 + 4)); 58 + v3 = veorq_u64(vld1q_u64(dp1 + 6), vld1q_u64(dp2 + 6)); 59 + 60 + /* p1 ^= p3 */ 61 + v0 = veorq_u64(v0, vld1q_u64(dp3 + 0)); 62 + v1 = veorq_u64(v1, vld1q_u64(dp3 + 2)); 63 + v2 = veorq_u64(v2, vld1q_u64(dp3 + 4)); 64 + v3 = veorq_u64(v3, vld1q_u64(dp3 + 6)); 65 + 66 + /* store */ 67 + vst1q_u64(dp1 + 0, v0); 68 + vst1q_u64(dp1 + 2, v1); 69 + vst1q_u64(dp1 + 4, v2); 70 + vst1q_u64(dp1 + 6, v3); 71 + 72 + dp1 += 8; 73 + dp2 += 8; 74 + dp3 += 8; 75 + } while (--lines > 0); 76 + } 77 + 78 + void xor_arm64_neon_4(unsigned long bytes, unsigned long *p1, 79 + unsigned long *p2, unsigned long *p3, unsigned long *p4) 80 + { 81 + uint64_t *dp1 = (uint64_t *)p1; 82 + uint64_t *dp2 = (uint64_t *)p2; 83 + uint64_t *dp3 = (uint64_t *)p3; 84 + uint64_t *dp4 = (uint64_t *)p4; 85 + 86 + register uint64x2_t v0, v1, v2, v3; 87 + long lines = bytes / (sizeof(uint64x2_t) * 4); 88 + 89 + do { 90 + /* p1 ^= p2 */ 91 + v0 = veorq_u64(vld1q_u64(dp1 + 0), vld1q_u64(dp2 + 0)); 92 + v1 = veorq_u64(vld1q_u64(dp1 + 2), vld1q_u64(dp2 + 2)); 93 + v2 = veorq_u64(vld1q_u64(dp1 + 4), vld1q_u64(dp2 + 4)); 94 + v3 = veorq_u64(vld1q_u64(dp1 + 6), vld1q_u64(dp2 + 6)); 95 + 96 + /* p1 ^= p3 */ 97 + v0 = veorq_u64(v0, vld1q_u64(dp3 + 0)); 98 + v1 = veorq_u64(v1, vld1q_u64(dp3 + 2)); 99 + v2 = veorq_u64(v2, vld1q_u64(dp3 + 4)); 100 + v3 = veorq_u64(v3, vld1q_u64(dp3 + 6)); 101 + 102 + /* p1 ^= p4 */ 103 + v0 = veorq_u64(v0, vld1q_u64(dp4 + 0)); 104 + v1 = veorq_u64(v1, vld1q_u64(dp4 + 2)); 105 + v2 = veorq_u64(v2, vld1q_u64(dp4 + 4)); 106 + v3 = veorq_u64(v3, vld1q_u64(dp4 + 6)); 107 + 108 + /* store */ 109 + vst1q_u64(dp1 + 0, v0); 110 + vst1q_u64(dp1 + 2, v1); 111 + vst1q_u64(dp1 + 4, v2); 112 + vst1q_u64(dp1 + 6, v3); 113 + 114 + dp1 += 8; 115 + dp2 += 8; 116 + dp3 += 8; 117 + dp4 += 8; 118 + } while (--lines > 0); 119 + } 120 + 121 + void xor_arm64_neon_5(unsigned long bytes, unsigned long *p1, 122 + unsigned long *p2, unsigned long *p3, 123 + unsigned long *p4, unsigned long *p5) 124 + { 125 + uint64_t *dp1 = (uint64_t *)p1; 126 + uint64_t *dp2 = (uint64_t *)p2; 127 + uint64_t *dp3 = (uint64_t *)p3; 128 + uint64_t *dp4 = (uint64_t *)p4; 129 + uint64_t *dp5 = (uint64_t *)p5; 130 + 131 + register uint64x2_t v0, v1, v2, v3; 132 + long lines = bytes / (sizeof(uint64x2_t) * 4); 133 + 134 + do { 135 + /* p1 ^= p2 */ 136 + v0 = veorq_u64(vld1q_u64(dp1 + 0), vld1q_u64(dp2 + 0)); 137 + v1 = veorq_u64(vld1q_u64(dp1 + 2), vld1q_u64(dp2 + 2)); 138 + v2 = veorq_u64(vld1q_u64(dp1 + 4), vld1q_u64(dp2 + 4)); 139 + v3 = veorq_u64(vld1q_u64(dp1 + 6), vld1q_u64(dp2 + 6)); 140 + 141 + /* p1 ^= p3 */ 142 + v0 = veorq_u64(v0, vld1q_u64(dp3 + 0)); 143 + v1 = veorq_u64(v1, vld1q_u64(dp3 + 2)); 144 + v2 = veorq_u64(v2, vld1q_u64(dp3 + 4)); 145 + v3 = veorq_u64(v3, vld1q_u64(dp3 + 6)); 146 + 147 + /* p1 ^= p4 */ 148 + v0 = veorq_u64(v0, vld1q_u64(dp4 + 0)); 149 + v1 = veorq_u64(v1, vld1q_u64(dp4 + 2)); 150 + v2 = veorq_u64(v2, vld1q_u64(dp4 + 4)); 151 + v3 = veorq_u64(v3, vld1q_u64(dp4 + 6)); 152 + 153 + /* p1 ^= p5 */ 154 + v0 = veorq_u64(v0, vld1q_u64(dp5 + 0)); 155 + v1 = veorq_u64(v1, vld1q_u64(dp5 + 2)); 156 + v2 = veorq_u64(v2, vld1q_u64(dp5 + 4)); 157 + v3 = veorq_u64(v3, vld1q_u64(dp5 + 6)); 158 + 159 + /* store */ 160 + vst1q_u64(dp1 + 0, v0); 161 + vst1q_u64(dp1 + 2, v1); 162 + vst1q_u64(dp1 + 4, v2); 163 + vst1q_u64(dp1 + 6, v3); 164 + 165 + dp1 += 8; 166 + dp2 += 8; 167 + dp3 += 8; 168 + dp4 += 8; 169 + dp5 += 8; 170 + } while (--lines > 0); 171 + } 172 + 173 + struct xor_block_template const xor_block_inner_neon = { 174 + .name = "__inner_neon__", 175 + .do_2 = xor_arm64_neon_2, 176 + .do_3 = xor_arm64_neon_3, 177 + .do_4 = xor_arm64_neon_4, 178 + .do_5 = xor_arm64_neon_5, 179 + }; 180 + EXPORT_SYMBOL(xor_block_inner_neon); 181 + 182 + MODULE_AUTHOR("Jackie Liu <liuyun01@kylinos.cn>"); 183 + MODULE_DESCRIPTION("ARMv8 XOR Extensions"); 184 + MODULE_LICENSE("GPL");
+3
arch/arm64/mm/cache.S
··· 212 212 * - size - size in question 213 213 */ 214 214 ENTRY(__clean_dcache_area_pop) 215 + alternative_if_not ARM64_HAS_DCPOP 216 + b __clean_dcache_area_poc 217 + alternative_else_nop_endif 215 218 dcache_by_line_op cvap, sy, x0, x1, x2, x3 216 219 ret 217 220 ENDPIPROC(__clean_dcache_area_pop)
+1 -1
arch/arm64/mm/fault.c
··· 160 160 161 161 pr_alert("%s pgtable: %luk pages, %u-bit VAs, pgdp = %p\n", 162 162 mm == &init_mm ? "swapper" : "user", PAGE_SIZE / SZ_1K, 163 - VA_BITS, mm->pgd); 163 + mm == &init_mm ? VA_BITS : (int) vabits_user, mm->pgd); 164 164 pgdp = pgd_offset(mm, addr); 165 165 pgd = READ_ONCE(*pgdp); 166 166 pr_alert("[%016lx] pgd=%016llx", addr, pgd_val(pgd));
+22 -11
arch/arm64/mm/hugetlbpage.c
··· 429 429 clear_flush(vma->vm_mm, addr, ptep, pgsize, ncontig); 430 430 } 431 431 432 + static void __init add_huge_page_size(unsigned long size) 433 + { 434 + if (size_to_hstate(size)) 435 + return; 436 + 437 + hugetlb_add_hstate(ilog2(size) - PAGE_SHIFT); 438 + } 439 + 440 + static int __init hugetlbpage_init(void) 441 + { 442 + #ifdef CONFIG_ARM64_4K_PAGES 443 + add_huge_page_size(PUD_SIZE); 444 + #endif 445 + add_huge_page_size(PMD_SIZE * CONT_PMDS); 446 + add_huge_page_size(PMD_SIZE); 447 + add_huge_page_size(PAGE_SIZE * CONT_PTES); 448 + 449 + return 0; 450 + } 451 + arch_initcall(hugetlbpage_init); 452 + 432 453 static __init int setup_hugepagesz(char *opt) 433 454 { 434 455 unsigned long ps = memparse(opt, &opt); ··· 461 440 case PMD_SIZE * CONT_PMDS: 462 441 case PMD_SIZE: 463 442 case PAGE_SIZE * CONT_PTES: 464 - hugetlb_add_hstate(ilog2(ps) - PAGE_SHIFT); 443 + add_huge_page_size(ps); 465 444 return 1; 466 445 } 467 446 ··· 470 449 return 0; 471 450 } 472 451 __setup("hugepagesz=", setup_hugepagesz); 473 - 474 - #ifdef CONFIG_ARM64_64K_PAGES 475 - static __init int add_default_hugepagesz(void) 476 - { 477 - if (size_to_hstate(CONT_PTES * PAGE_SIZE) == NULL) 478 - hugetlb_add_hstate(CONT_PTE_SHIFT); 479 - return 0; 480 - } 481 - arch_initcall(add_default_hugepagesz); 482 - #endif
+11 -1
arch/arm64/mm/init.c
··· 59 59 * that cannot be mistaken for a real physical address. 60 60 */ 61 61 s64 memstart_addr __ro_after_init = -1; 62 + EXPORT_SYMBOL(memstart_addr); 63 + 62 64 phys_addr_t arm64_dma_phys_limit __ro_after_init; 63 65 64 66 #ifdef CONFIG_BLK_DEV_INITRD ··· 291 289 292 290 if ((addr >> PAGE_SHIFT) != pfn) 293 291 return 0; 292 + 293 + #ifdef CONFIG_SPARSEMEM 294 + if (pfn_to_section_nr(pfn) >= NR_MEM_SECTIONS) 295 + return 0; 296 + 297 + if (!valid_section(__nr_to_section(pfn_to_section_nr(pfn)))) 298 + return 0; 299 + #endif 294 300 return memblock_is_map_memory(addr); 295 301 } 296 302 EXPORT_SYMBOL(pfn_valid); ··· 617 607 * detected at build time already. 618 608 */ 619 609 #ifdef CONFIG_COMPAT 620 - BUILD_BUG_ON(TASK_SIZE_32 > TASK_SIZE_64); 610 + BUILD_BUG_ON(TASK_SIZE_32 > DEFAULT_MAP_WINDOW_64); 621 611 #endif 622 612 623 613 if (PAGE_SIZE >= 16384 && get_num_physpages() <= 128) {
+33 -2
arch/arm64/mm/mmu.c
··· 52 52 53 53 u64 idmap_t0sz = TCR_T0SZ(VA_BITS); 54 54 u64 idmap_ptrs_per_pgd = PTRS_PER_PGD; 55 + u64 vabits_user __ro_after_init; 56 + EXPORT_SYMBOL(vabits_user); 55 57 56 58 u64 kimage_voffset __ro_after_init; 57 59 EXPORT_SYMBOL(kimage_voffset); ··· 453 451 struct memblock_region *reg; 454 452 int flags = 0; 455 453 456 - if (debug_pagealloc_enabled()) 454 + if (rodata_full || debug_pagealloc_enabled()) 457 455 flags = NO_BLOCK_MAPPINGS | NO_CONT_MAPPINGS; 458 456 459 457 /* ··· 554 552 555 553 static int __init parse_rodata(char *arg) 556 554 { 557 - return strtobool(arg, &rodata_enabled); 555 + int ret = strtobool(arg, &rodata_enabled); 556 + if (!ret) { 557 + rodata_full = false; 558 + return 0; 559 + } 560 + 561 + /* permit 'full' in addition to boolean options */ 562 + if (strcmp(arg, "full")) 563 + return -EINVAL; 564 + 565 + rodata_enabled = true; 566 + rodata_full = true; 567 + return 0; 558 568 } 559 569 early_param("rodata", parse_rodata); 560 570 ··· 1046 1032 pmd_free(NULL, table); 1047 1033 return 1; 1048 1034 } 1035 + 1036 + #ifdef CONFIG_MEMORY_HOTPLUG 1037 + int arch_add_memory(int nid, u64 start, u64 size, struct vmem_altmap *altmap, 1038 + bool want_memblock) 1039 + { 1040 + int flags = 0; 1041 + 1042 + if (rodata_full || debug_pagealloc_enabled()) 1043 + flags = NO_BLOCK_MAPPINGS | NO_CONT_MAPPINGS; 1044 + 1045 + __create_pgd_mapping(swapper_pg_dir, start, __phys_to_virt(start), 1046 + size, PAGE_KERNEL, pgd_pgtable_alloc, flags); 1047 + 1048 + return __add_pages(nid, start >> PAGE_SHIFT, size >> PAGE_SHIFT, 1049 + altmap, want_memblock); 1050 + } 1051 + #endif
+10
arch/arm64/mm/numa.c
··· 466 466 467 467 numa_init(dummy_numa_init); 468 468 } 469 + 470 + /* 471 + * We hope that we will be hotplugging memory on nodes we already know about, 472 + * such that acpi_get_node() succeeds and we never fall back to this... 473 + */ 474 + int memory_add_physaddr_to_nid(u64 addr) 475 + { 476 + pr_warn("Unknown node for memory at 0x%llx, assuming node 0\n", addr); 477 + return 0; 478 + }
+21
arch/arm64/mm/pageattr.c
··· 25 25 pgprot_t clear_mask; 26 26 }; 27 27 28 + bool rodata_full __ro_after_init = IS_ENABLED(CONFIG_RODATA_FULL_DEFAULT_ENABLED); 29 + 28 30 static int change_page_range(pte_t *ptep, pgtable_t token, unsigned long addr, 29 31 void *data) 30 32 { ··· 66 64 unsigned long size = PAGE_SIZE*numpages; 67 65 unsigned long end = start + size; 68 66 struct vm_struct *area; 67 + int i; 69 68 70 69 if (!PAGE_ALIGNED(addr)) { 71 70 start &= PAGE_MASK; ··· 95 92 96 93 if (!numpages) 97 94 return 0; 95 + 96 + /* 97 + * If we are manipulating read-only permissions, apply the same 98 + * change to the linear mapping of the pages that back this VM area. 99 + */ 100 + if (rodata_full && (pgprot_val(set_mask) == PTE_RDONLY || 101 + pgprot_val(clear_mask) == PTE_RDONLY)) { 102 + for (i = 0; i < area->nr_pages; i++) { 103 + __change_memory_common((u64)page_address(area->pages[i]), 104 + PAGE_SIZE, set_mask, clear_mask); 105 + } 106 + } 107 + 108 + /* 109 + * Get rid of potentially aliasing lazily unmapped vm areas that may 110 + * have permissions set that deviate from the ones we are setting here. 111 + */ 112 + vm_unmap_aliases(); 98 113 99 114 return __change_memory_common(start, size, set_mask, clear_mask); 100 115 }
+13 -1
arch/arm64/mm/proc.S
··· 182 182 .macro __idmap_cpu_set_reserved_ttbr1, tmp1, tmp2 183 183 adrp \tmp1, empty_zero_page 184 184 phys_to_ttbr \tmp2, \tmp1 185 + offset_ttbr1 \tmp2 185 186 msr ttbr1_el1, \tmp2 186 187 isb 187 188 tlbi vmalle1 ··· 201 200 202 201 __idmap_cpu_set_reserved_ttbr1 x1, x3 203 202 203 + offset_ttbr1 x0 204 204 msr ttbr1_el1, x0 205 205 isb 206 206 ··· 256 254 pte .req x16 257 255 258 256 mrs swapper_ttb, ttbr1_el1 257 + restore_ttbr1 swapper_ttb 259 258 adr flag_ptr, __idmap_kpti_flag 260 259 261 260 cbnz cpu, __idmap_kpti_secondary ··· 376 373 cbnz w18, 1b 377 374 378 375 /* All done, act like nothing happened */ 376 + offset_ttbr1 swapper_ttb 379 377 msr ttbr1_el1, swapper_ttb 380 378 isb 381 379 ret ··· 450 446 ldr x10, =TCR_TxSZ(VA_BITS) | TCR_CACHE_FLAGS | TCR_SMP_FLAGS | \ 451 447 TCR_TG_FLAGS | TCR_KASLR_FLAGS | TCR_ASID16 | \ 452 448 TCR_TBI0 | TCR_A1 453 - tcr_set_idmap_t0sz x10, x9 449 + 450 + #ifdef CONFIG_ARM64_USER_VA_BITS_52 451 + ldr_l x9, vabits_user 452 + sub x9, xzr, x9 453 + add x9, x9, #64 454 + #else 455 + ldr_l x9, idmap_t0sz 456 + #endif 457 + tcr_set_t0sz x10, x9 454 458 455 459 /* 456 460 * Set the IPS bits in TCR_EL1.
-54
arch/powerpc/kernel/machine_kexec_file_64.c
··· 24 24 25 25 #include <linux/slab.h> 26 26 #include <linux/kexec.h> 27 - #include <linux/memblock.h> 28 27 #include <linux/of_fdt.h> 29 28 #include <linux/libfdt.h> 30 29 #include <asm/ima.h> ··· 43 44 return -EOPNOTSUPP; 44 45 45 46 return kexec_image_probe_default(image, buf, buf_len); 46 - } 47 - 48 - /** 49 - * arch_kexec_walk_mem - call func(data) for each unreserved memory block 50 - * @kbuf: Context info for the search. Also passed to @func. 51 - * @func: Function to call for each memory block. 52 - * 53 - * This function is used by kexec_add_buffer and kexec_locate_mem_hole 54 - * to find unreserved memory to load kexec segments into. 55 - * 56 - * Return: The memory walk will stop when func returns a non-zero value 57 - * and that value will be returned. If all free regions are visited without 58 - * func returning non-zero, then zero will be returned. 59 - */ 60 - int arch_kexec_walk_mem(struct kexec_buf *kbuf, 61 - int (*func)(struct resource *, void *)) 62 - { 63 - int ret = 0; 64 - u64 i; 65 - phys_addr_t mstart, mend; 66 - struct resource res = { }; 67 - 68 - if (kbuf->top_down) { 69 - for_each_free_mem_range_reverse(i, NUMA_NO_NODE, 0, 70 - &mstart, &mend, NULL) { 71 - /* 72 - * In memblock, end points to the first byte after the 73 - * range while in kexec, end points to the last byte 74 - * in the range. 75 - */ 76 - res.start = mstart; 77 - res.end = mend - 1; 78 - ret = func(&res, kbuf); 79 - if (ret) 80 - break; 81 - } 82 - } else { 83 - for_each_free_mem_range(i, NUMA_NO_NODE, 0, &mstart, &mend, 84 - NULL) { 85 - /* 86 - * In memblock, end points to the first byte after the 87 - * range while in kexec, end points to the last byte 88 - * in the range. 89 - */ 90 - res.start = mstart; 91 - res.end = mend - 1; 92 - ret = func(&res, kbuf); 93 - if (ret) 94 - break; 95 - } 96 - } 97 - 98 - return ret; 99 47 } 100 48 101 49 /**
+2
arch/s390/include/asm/preempt.h
··· 8 8 9 9 #ifdef CONFIG_HAVE_MARCH_Z196_FEATURES 10 10 11 + /* We use the MSB mostly because its available */ 12 + #define PREEMPT_NEED_RESCHED 0x80000000 11 13 #define PREEMPT_ENABLED (0 + PREEMPT_NEED_RESCHED) 12 14 13 15 static inline int preempt_count(void)
-10
arch/s390/kernel/machine_kexec_file.c
··· 134 134 return ret; 135 135 } 136 136 137 - /* 138 - * The kernel is loaded to a fixed location. Turn off kexec_locate_mem_hole 139 - * and provide kbuf->mem by hand. 140 - */ 141 - int arch_kexec_walk_mem(struct kexec_buf *kbuf, 142 - int (*func)(struct resource *, void *)) 143 - { 144 - return 1; 145 - } 146 - 147 137 int arch_kexec_apply_relocations_add(struct purgatory_info *pi, 148 138 Elf_Shdr *section, 149 139 const Elf_Shdr *relsec,
+3
arch/x86/include/asm/preempt.h
··· 8 8 9 9 DECLARE_PER_CPU(int, __preempt_count); 10 10 11 + /* We use the MSB mostly because its available */ 12 + #define PREEMPT_NEED_RESCHED 0x80000000 13 + 11 14 /* 12 15 * We use the PREEMPT_NEED_RESCHED bit as an inverted NEED_RESCHED such 13 16 * that a decrement hitting 0 means we can and should reschedule.
+1 -1
drivers/firmware/efi/arm-runtime.c
··· 38 38 .mm = &efi_mm, 39 39 .markers = (struct addr_marker[]){ 40 40 { 0, "UEFI runtime start" }, 41 - { TASK_SIZE_64, "UEFI runtime end" } 41 + { DEFAULT_MAP_WINDOW_64, "UEFI runtime end" } 42 42 }, 43 43 .base_addr = 0, 44 44 };
+1 -1
drivers/firmware/efi/libstub/arm-stub.c
··· 33 33 #define EFI_RT_VIRTUAL_SIZE SZ_512M 34 34 35 35 #ifdef CONFIG_ARM64 36 - # define EFI_RT_VIRTUAL_LIMIT TASK_SIZE_64 36 + # define EFI_RT_VIRTUAL_LIMIT DEFAULT_MAP_WINDOW_64 37 37 #else 38 38 # define EFI_RT_VIRTUAL_LIMIT TASK_SIZE 39 39 #endif
+9
drivers/perf/Kconfig
··· 87 87 Adds the L3 cache PMU into the perf events subsystem for 88 88 monitoring L3 cache events. 89 89 90 + config THUNDERX2_PMU 91 + tristate "Cavium ThunderX2 SoC PMU UNCORE" 92 + depends on ARCH_THUNDER2 && ARM64 && ACPI && NUMA 93 + default m 94 + help 95 + Provides support for ThunderX2 UNCORE events. 96 + The SoC has PMU support in its L3 cache controller (L3C) and 97 + in the DDR4 Memory Controller (DMC). 98 + 90 99 config XGENE_PMU 91 100 depends on ARCH_XGENE 92 101 bool "APM X-Gene SoC PMU"
+1
drivers/perf/Makefile
··· 7 7 obj-$(CONFIG_HISI_PMU) += hisilicon/ 8 8 obj-$(CONFIG_QCOM_L2_PMU) += qcom_l2_pmu.o 9 9 obj-$(CONFIG_QCOM_L3_PMU) += qcom_l3_pmu.o 10 + obj-$(CONFIG_THUNDERX2_PMU) += thunderx2_pmu.o 10 11 obj-$(CONFIG_XGENE_PMU) += xgene_pmu.o 11 12 obj-$(CONFIG_ARM_SPE_PMU) += arm_spe_pmu.o
+6
drivers/perf/arm_spe_pmu.c
··· 927 927 928 928 idx = atomic_inc_return(&pmu_idx); 929 929 name = devm_kasprintf(dev, GFP_KERNEL, "%s_%d", PMUNAME, idx); 930 + if (!name) { 931 + dev_err(dev, "failed to allocate name for pmu %d\n", idx); 932 + return -ENOMEM; 933 + } 934 + 930 935 return perf_pmu_register(&spe_pmu->pmu, name, -1); 931 936 } 932 937 ··· 1174 1169 { .compatible = "arm,statistical-profiling-extension-v1", .data = (void *)1 }, 1175 1170 { /* Sentinel */ }, 1176 1171 }; 1172 + MODULE_DEVICE_TABLE(of, arm_spe_pmu_of_match); 1177 1173 1178 1174 static int arm_spe_pmu_device_dt_probe(struct platform_device *pdev) 1179 1175 {
+861
drivers/perf/thunderx2_pmu.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* 3 + * CAVIUM THUNDERX2 SoC PMU UNCORE 4 + * Copyright (C) 2018 Cavium Inc. 5 + * Author: Ganapatrao Kulkarni <gkulkarni@cavium.com> 6 + */ 7 + 8 + #include <linux/acpi.h> 9 + #include <linux/cpuhotplug.h> 10 + #include <linux/perf_event.h> 11 + #include <linux/platform_device.h> 12 + 13 + /* Each ThunderX2(TX2) Socket has a L3C and DMC UNCORE PMU device. 14 + * Each UNCORE PMU device consists of 4 independent programmable counters. 15 + * Counters are 32 bit and do not support overflow interrupt, 16 + * they need to be sampled before overflow(i.e, at every 2 seconds). 17 + */ 18 + 19 + #define TX2_PMU_MAX_COUNTERS 4 20 + #define TX2_PMU_DMC_CHANNELS 8 21 + #define TX2_PMU_L3_TILES 16 22 + 23 + #define TX2_PMU_HRTIMER_INTERVAL (2 * NSEC_PER_SEC) 24 + #define GET_EVENTID(ev) ((ev->hw.config) & 0x1f) 25 + #define GET_COUNTERID(ev) ((ev->hw.idx) & 0x3) 26 + /* 1 byte per counter(4 counters). 27 + * Event id is encoded in bits [5:1] of a byte, 28 + */ 29 + #define DMC_EVENT_CFG(idx, val) ((val) << (((idx) * 8) + 1)) 30 + 31 + #define L3C_COUNTER_CTL 0xA8 32 + #define L3C_COUNTER_DATA 0xAC 33 + #define DMC_COUNTER_CTL 0x234 34 + #define DMC_COUNTER_DATA 0x240 35 + 36 + /* L3C event IDs */ 37 + #define L3_EVENT_READ_REQ 0xD 38 + #define L3_EVENT_WRITEBACK_REQ 0xE 39 + #define L3_EVENT_INV_N_WRITE_REQ 0xF 40 + #define L3_EVENT_INV_REQ 0x10 41 + #define L3_EVENT_EVICT_REQ 0x13 42 + #define L3_EVENT_INV_N_WRITE_HIT 0x14 43 + #define L3_EVENT_INV_HIT 0x15 44 + #define L3_EVENT_READ_HIT 0x17 45 + #define L3_EVENT_MAX 0x18 46 + 47 + /* DMC event IDs */ 48 + #define DMC_EVENT_COUNT_CYCLES 0x1 49 + #define DMC_EVENT_WRITE_TXNS 0xB 50 + #define DMC_EVENT_DATA_TRANSFERS 0xD 51 + #define DMC_EVENT_READ_TXNS 0xF 52 + #define DMC_EVENT_MAX 0x10 53 + 54 + enum tx2_uncore_type { 55 + PMU_TYPE_L3C, 56 + PMU_TYPE_DMC, 57 + PMU_TYPE_INVALID, 58 + }; 59 + 60 + /* 61 + * pmu on each socket has 2 uncore devices(dmc and l3c), 62 + * each device has 4 counters. 63 + */ 64 + struct tx2_uncore_pmu { 65 + struct hlist_node hpnode; 66 + struct list_head entry; 67 + struct pmu pmu; 68 + char *name; 69 + int node; 70 + int cpu; 71 + u32 max_counters; 72 + u32 prorate_factor; 73 + u32 max_events; 74 + u64 hrtimer_interval; 75 + void __iomem *base; 76 + DECLARE_BITMAP(active_counters, TX2_PMU_MAX_COUNTERS); 77 + struct perf_event *events[TX2_PMU_MAX_COUNTERS]; 78 + struct device *dev; 79 + struct hrtimer hrtimer; 80 + const struct attribute_group **attr_groups; 81 + enum tx2_uncore_type type; 82 + void (*init_cntr_base)(struct perf_event *event, 83 + struct tx2_uncore_pmu *tx2_pmu); 84 + void (*stop_event)(struct perf_event *event); 85 + void (*start_event)(struct perf_event *event, int flags); 86 + }; 87 + 88 + static LIST_HEAD(tx2_pmus); 89 + 90 + static inline struct tx2_uncore_pmu *pmu_to_tx2_pmu(struct pmu *pmu) 91 + { 92 + return container_of(pmu, struct tx2_uncore_pmu, pmu); 93 + } 94 + 95 + PMU_FORMAT_ATTR(event, "config:0-4"); 96 + 97 + static struct attribute *l3c_pmu_format_attrs[] = { 98 + &format_attr_event.attr, 99 + NULL, 100 + }; 101 + 102 + static struct attribute *dmc_pmu_format_attrs[] = { 103 + &format_attr_event.attr, 104 + NULL, 105 + }; 106 + 107 + static const struct attribute_group l3c_pmu_format_attr_group = { 108 + .name = "format", 109 + .attrs = l3c_pmu_format_attrs, 110 + }; 111 + 112 + static const struct attribute_group dmc_pmu_format_attr_group = { 113 + .name = "format", 114 + .attrs = dmc_pmu_format_attrs, 115 + }; 116 + 117 + /* 118 + * sysfs event attributes 119 + */ 120 + static ssize_t tx2_pmu_event_show(struct device *dev, 121 + struct device_attribute *attr, char *buf) 122 + { 123 + struct dev_ext_attribute *eattr; 124 + 125 + eattr = container_of(attr, struct dev_ext_attribute, attr); 126 + return sprintf(buf, "event=0x%lx\n", (unsigned long) eattr->var); 127 + } 128 + 129 + #define TX2_EVENT_ATTR(name, config) \ 130 + PMU_EVENT_ATTR(name, tx2_pmu_event_attr_##name, \ 131 + config, tx2_pmu_event_show) 132 + 133 + TX2_EVENT_ATTR(read_request, L3_EVENT_READ_REQ); 134 + TX2_EVENT_ATTR(writeback_request, L3_EVENT_WRITEBACK_REQ); 135 + TX2_EVENT_ATTR(inv_nwrite_request, L3_EVENT_INV_N_WRITE_REQ); 136 + TX2_EVENT_ATTR(inv_request, L3_EVENT_INV_REQ); 137 + TX2_EVENT_ATTR(evict_request, L3_EVENT_EVICT_REQ); 138 + TX2_EVENT_ATTR(inv_nwrite_hit, L3_EVENT_INV_N_WRITE_HIT); 139 + TX2_EVENT_ATTR(inv_hit, L3_EVENT_INV_HIT); 140 + TX2_EVENT_ATTR(read_hit, L3_EVENT_READ_HIT); 141 + 142 + static struct attribute *l3c_pmu_events_attrs[] = { 143 + &tx2_pmu_event_attr_read_request.attr.attr, 144 + &tx2_pmu_event_attr_writeback_request.attr.attr, 145 + &tx2_pmu_event_attr_inv_nwrite_request.attr.attr, 146 + &tx2_pmu_event_attr_inv_request.attr.attr, 147 + &tx2_pmu_event_attr_evict_request.attr.attr, 148 + &tx2_pmu_event_attr_inv_nwrite_hit.attr.attr, 149 + &tx2_pmu_event_attr_inv_hit.attr.attr, 150 + &tx2_pmu_event_attr_read_hit.attr.attr, 151 + NULL, 152 + }; 153 + 154 + TX2_EVENT_ATTR(cnt_cycles, DMC_EVENT_COUNT_CYCLES); 155 + TX2_EVENT_ATTR(write_txns, DMC_EVENT_WRITE_TXNS); 156 + TX2_EVENT_ATTR(data_transfers, DMC_EVENT_DATA_TRANSFERS); 157 + TX2_EVENT_ATTR(read_txns, DMC_EVENT_READ_TXNS); 158 + 159 + static struct attribute *dmc_pmu_events_attrs[] = { 160 + &tx2_pmu_event_attr_cnt_cycles.attr.attr, 161 + &tx2_pmu_event_attr_write_txns.attr.attr, 162 + &tx2_pmu_event_attr_data_transfers.attr.attr, 163 + &tx2_pmu_event_attr_read_txns.attr.attr, 164 + NULL, 165 + }; 166 + 167 + static const struct attribute_group l3c_pmu_events_attr_group = { 168 + .name = "events", 169 + .attrs = l3c_pmu_events_attrs, 170 + }; 171 + 172 + static const struct attribute_group dmc_pmu_events_attr_group = { 173 + .name = "events", 174 + .attrs = dmc_pmu_events_attrs, 175 + }; 176 + 177 + /* 178 + * sysfs cpumask attributes 179 + */ 180 + static ssize_t cpumask_show(struct device *dev, struct device_attribute *attr, 181 + char *buf) 182 + { 183 + struct tx2_uncore_pmu *tx2_pmu; 184 + 185 + tx2_pmu = pmu_to_tx2_pmu(dev_get_drvdata(dev)); 186 + return cpumap_print_to_pagebuf(true, buf, cpumask_of(tx2_pmu->cpu)); 187 + } 188 + static DEVICE_ATTR_RO(cpumask); 189 + 190 + static struct attribute *tx2_pmu_cpumask_attrs[] = { 191 + &dev_attr_cpumask.attr, 192 + NULL, 193 + }; 194 + 195 + static const struct attribute_group pmu_cpumask_attr_group = { 196 + .attrs = tx2_pmu_cpumask_attrs, 197 + }; 198 + 199 + /* 200 + * Per PMU device attribute groups 201 + */ 202 + static const struct attribute_group *l3c_pmu_attr_groups[] = { 203 + &l3c_pmu_format_attr_group, 204 + &pmu_cpumask_attr_group, 205 + &l3c_pmu_events_attr_group, 206 + NULL 207 + }; 208 + 209 + static const struct attribute_group *dmc_pmu_attr_groups[] = { 210 + &dmc_pmu_format_attr_group, 211 + &pmu_cpumask_attr_group, 212 + &dmc_pmu_events_attr_group, 213 + NULL 214 + }; 215 + 216 + static inline u32 reg_readl(unsigned long addr) 217 + { 218 + return readl((void __iomem *)addr); 219 + } 220 + 221 + static inline void reg_writel(u32 val, unsigned long addr) 222 + { 223 + writel(val, (void __iomem *)addr); 224 + } 225 + 226 + static int alloc_counter(struct tx2_uncore_pmu *tx2_pmu) 227 + { 228 + int counter; 229 + 230 + counter = find_first_zero_bit(tx2_pmu->active_counters, 231 + tx2_pmu->max_counters); 232 + if (counter == tx2_pmu->max_counters) 233 + return -ENOSPC; 234 + 235 + set_bit(counter, tx2_pmu->active_counters); 236 + return counter; 237 + } 238 + 239 + static inline void free_counter(struct tx2_uncore_pmu *tx2_pmu, int counter) 240 + { 241 + clear_bit(counter, tx2_pmu->active_counters); 242 + } 243 + 244 + static void init_cntr_base_l3c(struct perf_event *event, 245 + struct tx2_uncore_pmu *tx2_pmu) 246 + { 247 + struct hw_perf_event *hwc = &event->hw; 248 + 249 + /* counter ctrl/data reg offset at 8 */ 250 + hwc->config_base = (unsigned long)tx2_pmu->base 251 + + L3C_COUNTER_CTL + (8 * GET_COUNTERID(event)); 252 + hwc->event_base = (unsigned long)tx2_pmu->base 253 + + L3C_COUNTER_DATA + (8 * GET_COUNTERID(event)); 254 + } 255 + 256 + static void init_cntr_base_dmc(struct perf_event *event, 257 + struct tx2_uncore_pmu *tx2_pmu) 258 + { 259 + struct hw_perf_event *hwc = &event->hw; 260 + 261 + hwc->config_base = (unsigned long)tx2_pmu->base 262 + + DMC_COUNTER_CTL; 263 + /* counter data reg offset at 0xc */ 264 + hwc->event_base = (unsigned long)tx2_pmu->base 265 + + DMC_COUNTER_DATA + (0xc * GET_COUNTERID(event)); 266 + } 267 + 268 + static void uncore_start_event_l3c(struct perf_event *event, int flags) 269 + { 270 + u32 val; 271 + struct hw_perf_event *hwc = &event->hw; 272 + 273 + /* event id encoded in bits [07:03] */ 274 + val = GET_EVENTID(event) << 3; 275 + reg_writel(val, hwc->config_base); 276 + local64_set(&hwc->prev_count, 0); 277 + reg_writel(0, hwc->event_base); 278 + } 279 + 280 + static inline void uncore_stop_event_l3c(struct perf_event *event) 281 + { 282 + reg_writel(0, event->hw.config_base); 283 + } 284 + 285 + static void uncore_start_event_dmc(struct perf_event *event, int flags) 286 + { 287 + u32 val; 288 + struct hw_perf_event *hwc = &event->hw; 289 + int idx = GET_COUNTERID(event); 290 + int event_id = GET_EVENTID(event); 291 + 292 + /* enable and start counters. 293 + * 8 bits for each counter, bits[05:01] of a counter to set event type. 294 + */ 295 + val = reg_readl(hwc->config_base); 296 + val &= ~DMC_EVENT_CFG(idx, 0x1f); 297 + val |= DMC_EVENT_CFG(idx, event_id); 298 + reg_writel(val, hwc->config_base); 299 + local64_set(&hwc->prev_count, 0); 300 + reg_writel(0, hwc->event_base); 301 + } 302 + 303 + static void uncore_stop_event_dmc(struct perf_event *event) 304 + { 305 + u32 val; 306 + struct hw_perf_event *hwc = &event->hw; 307 + int idx = GET_COUNTERID(event); 308 + 309 + /* clear event type(bits[05:01]) to stop counter */ 310 + val = reg_readl(hwc->config_base); 311 + val &= ~DMC_EVENT_CFG(idx, 0x1f); 312 + reg_writel(val, hwc->config_base); 313 + } 314 + 315 + static void tx2_uncore_event_update(struct perf_event *event) 316 + { 317 + s64 prev, delta, new = 0; 318 + struct hw_perf_event *hwc = &event->hw; 319 + struct tx2_uncore_pmu *tx2_pmu; 320 + enum tx2_uncore_type type; 321 + u32 prorate_factor; 322 + 323 + tx2_pmu = pmu_to_tx2_pmu(event->pmu); 324 + type = tx2_pmu->type; 325 + prorate_factor = tx2_pmu->prorate_factor; 326 + 327 + new = reg_readl(hwc->event_base); 328 + prev = local64_xchg(&hwc->prev_count, new); 329 + 330 + /* handles rollover of 32 bit counter */ 331 + delta = (u32)(((1UL << 32) - prev) + new); 332 + 333 + /* DMC event data_transfers granularity is 16 Bytes, convert it to 64 */ 334 + if (type == PMU_TYPE_DMC && 335 + GET_EVENTID(event) == DMC_EVENT_DATA_TRANSFERS) 336 + delta = delta/4; 337 + 338 + /* L3C and DMC has 16 and 8 interleave channels respectively. 339 + * The sampled value is for channel 0 and multiplied with 340 + * prorate_factor to get the count for a device. 341 + */ 342 + local64_add(delta * prorate_factor, &event->count); 343 + } 344 + 345 + static enum tx2_uncore_type get_tx2_pmu_type(struct acpi_device *adev) 346 + { 347 + int i = 0; 348 + struct acpi_tx2_pmu_device { 349 + __u8 id[ACPI_ID_LEN]; 350 + enum tx2_uncore_type type; 351 + } devices[] = { 352 + {"CAV901D", PMU_TYPE_L3C}, 353 + {"CAV901F", PMU_TYPE_DMC}, 354 + {"", PMU_TYPE_INVALID} 355 + }; 356 + 357 + while (devices[i].type != PMU_TYPE_INVALID) { 358 + if (!strcmp(acpi_device_hid(adev), devices[i].id)) 359 + break; 360 + i++; 361 + } 362 + 363 + return devices[i].type; 364 + } 365 + 366 + static bool tx2_uncore_validate_event(struct pmu *pmu, 367 + struct perf_event *event, int *counters) 368 + { 369 + if (is_software_event(event)) 370 + return true; 371 + /* Reject groups spanning multiple HW PMUs. */ 372 + if (event->pmu != pmu) 373 + return false; 374 + 375 + *counters = *counters + 1; 376 + return true; 377 + } 378 + 379 + /* 380 + * Make sure the group of events can be scheduled at once 381 + * on the PMU. 382 + */ 383 + static bool tx2_uncore_validate_event_group(struct perf_event *event) 384 + { 385 + struct perf_event *sibling, *leader = event->group_leader; 386 + int counters = 0; 387 + 388 + if (event->group_leader == event) 389 + return true; 390 + 391 + if (!tx2_uncore_validate_event(event->pmu, leader, &counters)) 392 + return false; 393 + 394 + for_each_sibling_event(sibling, leader) { 395 + if (!tx2_uncore_validate_event(event->pmu, sibling, &counters)) 396 + return false; 397 + } 398 + 399 + if (!tx2_uncore_validate_event(event->pmu, event, &counters)) 400 + return false; 401 + 402 + /* 403 + * If the group requires more counters than the HW has, 404 + * it cannot ever be scheduled. 405 + */ 406 + return counters <= TX2_PMU_MAX_COUNTERS; 407 + } 408 + 409 + 410 + static int tx2_uncore_event_init(struct perf_event *event) 411 + { 412 + struct hw_perf_event *hwc = &event->hw; 413 + struct tx2_uncore_pmu *tx2_pmu; 414 + 415 + /* Test the event attr type check for PMU enumeration */ 416 + if (event->attr.type != event->pmu->type) 417 + return -ENOENT; 418 + 419 + /* 420 + * SOC PMU counters are shared across all cores. 421 + * Therefore, it does not support per-process mode. 422 + * Also, it does not support event sampling mode. 423 + */ 424 + if (is_sampling_event(event) || event->attach_state & PERF_ATTACH_TASK) 425 + return -EINVAL; 426 + 427 + /* We have no filtering of any kind */ 428 + if (event->attr.exclude_user || 429 + event->attr.exclude_kernel || 430 + event->attr.exclude_hv || 431 + event->attr.exclude_idle || 432 + event->attr.exclude_host || 433 + event->attr.exclude_guest) 434 + return -EINVAL; 435 + 436 + if (event->cpu < 0) 437 + return -EINVAL; 438 + 439 + tx2_pmu = pmu_to_tx2_pmu(event->pmu); 440 + if (tx2_pmu->cpu >= nr_cpu_ids) 441 + return -EINVAL; 442 + event->cpu = tx2_pmu->cpu; 443 + 444 + if (event->attr.config >= tx2_pmu->max_events) 445 + return -EINVAL; 446 + 447 + /* store event id */ 448 + hwc->config = event->attr.config; 449 + 450 + /* Validate the group */ 451 + if (!tx2_uncore_validate_event_group(event)) 452 + return -EINVAL; 453 + 454 + return 0; 455 + } 456 + 457 + static void tx2_uncore_event_start(struct perf_event *event, int flags) 458 + { 459 + struct hw_perf_event *hwc = &event->hw; 460 + struct tx2_uncore_pmu *tx2_pmu; 461 + 462 + hwc->state = 0; 463 + tx2_pmu = pmu_to_tx2_pmu(event->pmu); 464 + 465 + tx2_pmu->start_event(event, flags); 466 + perf_event_update_userpage(event); 467 + 468 + /* Start timer for first event */ 469 + if (bitmap_weight(tx2_pmu->active_counters, 470 + tx2_pmu->max_counters) == 1) { 471 + hrtimer_start(&tx2_pmu->hrtimer, 472 + ns_to_ktime(tx2_pmu->hrtimer_interval), 473 + HRTIMER_MODE_REL_PINNED); 474 + } 475 + } 476 + 477 + static void tx2_uncore_event_stop(struct perf_event *event, int flags) 478 + { 479 + struct hw_perf_event *hwc = &event->hw; 480 + struct tx2_uncore_pmu *tx2_pmu; 481 + 482 + if (hwc->state & PERF_HES_UPTODATE) 483 + return; 484 + 485 + tx2_pmu = pmu_to_tx2_pmu(event->pmu); 486 + tx2_pmu->stop_event(event); 487 + WARN_ON_ONCE(hwc->state & PERF_HES_STOPPED); 488 + hwc->state |= PERF_HES_STOPPED; 489 + if (flags & PERF_EF_UPDATE) { 490 + tx2_uncore_event_update(event); 491 + hwc->state |= PERF_HES_UPTODATE; 492 + } 493 + } 494 + 495 + static int tx2_uncore_event_add(struct perf_event *event, int flags) 496 + { 497 + struct hw_perf_event *hwc = &event->hw; 498 + struct tx2_uncore_pmu *tx2_pmu; 499 + 500 + tx2_pmu = pmu_to_tx2_pmu(event->pmu); 501 + 502 + /* Allocate a free counter */ 503 + hwc->idx = alloc_counter(tx2_pmu); 504 + if (hwc->idx < 0) 505 + return -EAGAIN; 506 + 507 + tx2_pmu->events[hwc->idx] = event; 508 + /* set counter control and data registers base address */ 509 + tx2_pmu->init_cntr_base(event, tx2_pmu); 510 + 511 + hwc->state = PERF_HES_UPTODATE | PERF_HES_STOPPED; 512 + if (flags & PERF_EF_START) 513 + tx2_uncore_event_start(event, flags); 514 + 515 + return 0; 516 + } 517 + 518 + static void tx2_uncore_event_del(struct perf_event *event, int flags) 519 + { 520 + struct tx2_uncore_pmu *tx2_pmu = pmu_to_tx2_pmu(event->pmu); 521 + struct hw_perf_event *hwc = &event->hw; 522 + 523 + tx2_uncore_event_stop(event, PERF_EF_UPDATE); 524 + 525 + /* clear the assigned counter */ 526 + free_counter(tx2_pmu, GET_COUNTERID(event)); 527 + 528 + perf_event_update_userpage(event); 529 + tx2_pmu->events[hwc->idx] = NULL; 530 + hwc->idx = -1; 531 + } 532 + 533 + static void tx2_uncore_event_read(struct perf_event *event) 534 + { 535 + tx2_uncore_event_update(event); 536 + } 537 + 538 + static enum hrtimer_restart tx2_hrtimer_callback(struct hrtimer *timer) 539 + { 540 + struct tx2_uncore_pmu *tx2_pmu; 541 + int max_counters, idx; 542 + 543 + tx2_pmu = container_of(timer, struct tx2_uncore_pmu, hrtimer); 544 + max_counters = tx2_pmu->max_counters; 545 + 546 + if (bitmap_empty(tx2_pmu->active_counters, max_counters)) 547 + return HRTIMER_NORESTART; 548 + 549 + for_each_set_bit(idx, tx2_pmu->active_counters, max_counters) { 550 + struct perf_event *event = tx2_pmu->events[idx]; 551 + 552 + tx2_uncore_event_update(event); 553 + } 554 + hrtimer_forward_now(timer, ns_to_ktime(tx2_pmu->hrtimer_interval)); 555 + return HRTIMER_RESTART; 556 + } 557 + 558 + static int tx2_uncore_pmu_register( 559 + struct tx2_uncore_pmu *tx2_pmu) 560 + { 561 + struct device *dev = tx2_pmu->dev; 562 + char *name = tx2_pmu->name; 563 + 564 + /* Perf event registration */ 565 + tx2_pmu->pmu = (struct pmu) { 566 + .module = THIS_MODULE, 567 + .attr_groups = tx2_pmu->attr_groups, 568 + .task_ctx_nr = perf_invalid_context, 569 + .event_init = tx2_uncore_event_init, 570 + .add = tx2_uncore_event_add, 571 + .del = tx2_uncore_event_del, 572 + .start = tx2_uncore_event_start, 573 + .stop = tx2_uncore_event_stop, 574 + .read = tx2_uncore_event_read, 575 + }; 576 + 577 + tx2_pmu->pmu.name = devm_kasprintf(dev, GFP_KERNEL, 578 + "%s", name); 579 + 580 + return perf_pmu_register(&tx2_pmu->pmu, tx2_pmu->pmu.name, -1); 581 + } 582 + 583 + static int tx2_uncore_pmu_add_dev(struct tx2_uncore_pmu *tx2_pmu) 584 + { 585 + int ret, cpu; 586 + 587 + cpu = cpumask_any_and(cpumask_of_node(tx2_pmu->node), 588 + cpu_online_mask); 589 + 590 + tx2_pmu->cpu = cpu; 591 + hrtimer_init(&tx2_pmu->hrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); 592 + tx2_pmu->hrtimer.function = tx2_hrtimer_callback; 593 + 594 + ret = tx2_uncore_pmu_register(tx2_pmu); 595 + if (ret) { 596 + dev_err(tx2_pmu->dev, "%s PMU: Failed to init driver\n", 597 + tx2_pmu->name); 598 + return -ENODEV; 599 + } 600 + 601 + /* register hotplug callback for the pmu */ 602 + ret = cpuhp_state_add_instance( 603 + CPUHP_AP_PERF_ARM_CAVIUM_TX2_UNCORE_ONLINE, 604 + &tx2_pmu->hpnode); 605 + if (ret) { 606 + dev_err(tx2_pmu->dev, "Error %d registering hotplug", ret); 607 + return ret; 608 + } 609 + 610 + /* Add to list */ 611 + list_add(&tx2_pmu->entry, &tx2_pmus); 612 + 613 + dev_dbg(tx2_pmu->dev, "%s PMU UNCORE registered\n", 614 + tx2_pmu->pmu.name); 615 + return ret; 616 + } 617 + 618 + static struct tx2_uncore_pmu *tx2_uncore_pmu_init_dev(struct device *dev, 619 + acpi_handle handle, struct acpi_device *adev, u32 type) 620 + { 621 + struct tx2_uncore_pmu *tx2_pmu; 622 + void __iomem *base; 623 + struct resource res; 624 + struct resource_entry *rentry; 625 + struct list_head list; 626 + int ret; 627 + 628 + INIT_LIST_HEAD(&list); 629 + ret = acpi_dev_get_resources(adev, &list, NULL, NULL); 630 + if (ret <= 0) { 631 + dev_err(dev, "failed to parse _CRS method, error %d\n", ret); 632 + return NULL; 633 + } 634 + 635 + list_for_each_entry(rentry, &list, node) { 636 + if (resource_type(rentry->res) == IORESOURCE_MEM) { 637 + res = *rentry->res; 638 + break; 639 + } 640 + } 641 + 642 + if (!rentry->res) 643 + return NULL; 644 + 645 + acpi_dev_free_resource_list(&list); 646 + base = devm_ioremap_resource(dev, &res); 647 + if (IS_ERR(base)) { 648 + dev_err(dev, "PMU type %d: Fail to map resource\n", type); 649 + return NULL; 650 + } 651 + 652 + tx2_pmu = devm_kzalloc(dev, sizeof(*tx2_pmu), GFP_KERNEL); 653 + if (!tx2_pmu) 654 + return NULL; 655 + 656 + tx2_pmu->dev = dev; 657 + tx2_pmu->type = type; 658 + tx2_pmu->base = base; 659 + tx2_pmu->node = dev_to_node(dev); 660 + INIT_LIST_HEAD(&tx2_pmu->entry); 661 + 662 + switch (tx2_pmu->type) { 663 + case PMU_TYPE_L3C: 664 + tx2_pmu->max_counters = TX2_PMU_MAX_COUNTERS; 665 + tx2_pmu->prorate_factor = TX2_PMU_L3_TILES; 666 + tx2_pmu->max_events = L3_EVENT_MAX; 667 + tx2_pmu->hrtimer_interval = TX2_PMU_HRTIMER_INTERVAL; 668 + tx2_pmu->attr_groups = l3c_pmu_attr_groups; 669 + tx2_pmu->name = devm_kasprintf(dev, GFP_KERNEL, 670 + "uncore_l3c_%d", tx2_pmu->node); 671 + tx2_pmu->init_cntr_base = init_cntr_base_l3c; 672 + tx2_pmu->start_event = uncore_start_event_l3c; 673 + tx2_pmu->stop_event = uncore_stop_event_l3c; 674 + break; 675 + case PMU_TYPE_DMC: 676 + tx2_pmu->max_counters = TX2_PMU_MAX_COUNTERS; 677 + tx2_pmu->prorate_factor = TX2_PMU_DMC_CHANNELS; 678 + tx2_pmu->max_events = DMC_EVENT_MAX; 679 + tx2_pmu->hrtimer_interval = TX2_PMU_HRTIMER_INTERVAL; 680 + tx2_pmu->attr_groups = dmc_pmu_attr_groups; 681 + tx2_pmu->name = devm_kasprintf(dev, GFP_KERNEL, 682 + "uncore_dmc_%d", tx2_pmu->node); 683 + tx2_pmu->init_cntr_base = init_cntr_base_dmc; 684 + tx2_pmu->start_event = uncore_start_event_dmc; 685 + tx2_pmu->stop_event = uncore_stop_event_dmc; 686 + break; 687 + case PMU_TYPE_INVALID: 688 + devm_kfree(dev, tx2_pmu); 689 + return NULL; 690 + } 691 + 692 + return tx2_pmu; 693 + } 694 + 695 + static acpi_status tx2_uncore_pmu_add(acpi_handle handle, u32 level, 696 + void *data, void **return_value) 697 + { 698 + struct tx2_uncore_pmu *tx2_pmu; 699 + struct acpi_device *adev; 700 + enum tx2_uncore_type type; 701 + 702 + if (acpi_bus_get_device(handle, &adev)) 703 + return AE_OK; 704 + if (acpi_bus_get_status(adev) || !adev->status.present) 705 + return AE_OK; 706 + 707 + type = get_tx2_pmu_type(adev); 708 + if (type == PMU_TYPE_INVALID) 709 + return AE_OK; 710 + 711 + tx2_pmu = tx2_uncore_pmu_init_dev((struct device *)data, 712 + handle, adev, type); 713 + 714 + if (!tx2_pmu) 715 + return AE_ERROR; 716 + 717 + if (tx2_uncore_pmu_add_dev(tx2_pmu)) { 718 + /* Can't add the PMU device, abort */ 719 + return AE_ERROR; 720 + } 721 + return AE_OK; 722 + } 723 + 724 + static int tx2_uncore_pmu_online_cpu(unsigned int cpu, 725 + struct hlist_node *hpnode) 726 + { 727 + struct tx2_uncore_pmu *tx2_pmu; 728 + 729 + tx2_pmu = hlist_entry_safe(hpnode, 730 + struct tx2_uncore_pmu, hpnode); 731 + 732 + /* Pick this CPU, If there is no CPU/PMU association and both are 733 + * from same node. 734 + */ 735 + if ((tx2_pmu->cpu >= nr_cpu_ids) && 736 + (tx2_pmu->node == cpu_to_node(cpu))) 737 + tx2_pmu->cpu = cpu; 738 + 739 + return 0; 740 + } 741 + 742 + static int tx2_uncore_pmu_offline_cpu(unsigned int cpu, 743 + struct hlist_node *hpnode) 744 + { 745 + int new_cpu; 746 + struct tx2_uncore_pmu *tx2_pmu; 747 + struct cpumask cpu_online_mask_temp; 748 + 749 + tx2_pmu = hlist_entry_safe(hpnode, 750 + struct tx2_uncore_pmu, hpnode); 751 + 752 + if (cpu != tx2_pmu->cpu) 753 + return 0; 754 + 755 + hrtimer_cancel(&tx2_pmu->hrtimer); 756 + cpumask_copy(&cpu_online_mask_temp, cpu_online_mask); 757 + cpumask_clear_cpu(cpu, &cpu_online_mask_temp); 758 + new_cpu = cpumask_any_and( 759 + cpumask_of_node(tx2_pmu->node), 760 + &cpu_online_mask_temp); 761 + 762 + tx2_pmu->cpu = new_cpu; 763 + if (new_cpu >= nr_cpu_ids) 764 + return 0; 765 + perf_pmu_migrate_context(&tx2_pmu->pmu, cpu, new_cpu); 766 + 767 + return 0; 768 + } 769 + 770 + static const struct acpi_device_id tx2_uncore_acpi_match[] = { 771 + {"CAV901C", 0}, 772 + {}, 773 + }; 774 + MODULE_DEVICE_TABLE(acpi, tx2_uncore_acpi_match); 775 + 776 + static int tx2_uncore_probe(struct platform_device *pdev) 777 + { 778 + struct device *dev = &pdev->dev; 779 + acpi_handle handle; 780 + acpi_status status; 781 + 782 + set_dev_node(dev, acpi_get_node(ACPI_HANDLE(dev))); 783 + 784 + if (!has_acpi_companion(dev)) 785 + return -ENODEV; 786 + 787 + handle = ACPI_HANDLE(dev); 788 + if (!handle) 789 + return -EINVAL; 790 + 791 + /* Walk through the tree for all PMU UNCORE devices */ 792 + status = acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, 1, 793 + tx2_uncore_pmu_add, 794 + NULL, dev, NULL); 795 + if (ACPI_FAILURE(status)) { 796 + dev_err(dev, "failed to probe PMU devices\n"); 797 + return_ACPI_STATUS(status); 798 + } 799 + 800 + dev_info(dev, "node%d: pmu uncore registered\n", dev_to_node(dev)); 801 + return 0; 802 + } 803 + 804 + static int tx2_uncore_remove(struct platform_device *pdev) 805 + { 806 + struct tx2_uncore_pmu *tx2_pmu, *temp; 807 + struct device *dev = &pdev->dev; 808 + 809 + if (!list_empty(&tx2_pmus)) { 810 + list_for_each_entry_safe(tx2_pmu, temp, &tx2_pmus, entry) { 811 + if (tx2_pmu->node == dev_to_node(dev)) { 812 + cpuhp_state_remove_instance_nocalls( 813 + CPUHP_AP_PERF_ARM_CAVIUM_TX2_UNCORE_ONLINE, 814 + &tx2_pmu->hpnode); 815 + perf_pmu_unregister(&tx2_pmu->pmu); 816 + list_del(&tx2_pmu->entry); 817 + } 818 + } 819 + } 820 + return 0; 821 + } 822 + 823 + static struct platform_driver tx2_uncore_driver = { 824 + .driver = { 825 + .name = "tx2-uncore-pmu", 826 + .acpi_match_table = ACPI_PTR(tx2_uncore_acpi_match), 827 + }, 828 + .probe = tx2_uncore_probe, 829 + .remove = tx2_uncore_remove, 830 + }; 831 + 832 + static int __init tx2_uncore_driver_init(void) 833 + { 834 + int ret; 835 + 836 + ret = cpuhp_setup_state_multi(CPUHP_AP_PERF_ARM_CAVIUM_TX2_UNCORE_ONLINE, 837 + "perf/tx2/uncore:online", 838 + tx2_uncore_pmu_online_cpu, 839 + tx2_uncore_pmu_offline_cpu); 840 + if (ret) { 841 + pr_err("TX2 PMU: setup hotplug failed(%d)\n", ret); 842 + return ret; 843 + } 844 + ret = platform_driver_register(&tx2_uncore_driver); 845 + if (ret) 846 + cpuhp_remove_multi_state(CPUHP_AP_PERF_ARM_CAVIUM_TX2_UNCORE_ONLINE); 847 + 848 + return ret; 849 + } 850 + module_init(tx2_uncore_driver_init); 851 + 852 + static void __exit tx2_uncore_driver_exit(void) 853 + { 854 + platform_driver_unregister(&tx2_uncore_driver); 855 + cpuhp_remove_multi_state(CPUHP_AP_PERF_ARM_CAVIUM_TX2_UNCORE_ONLINE); 856 + } 857 + module_exit(tx2_uncore_driver_exit); 858 + 859 + MODULE_DESCRIPTION("ThunderX2 UNCORE PMU driver"); 860 + MODULE_LICENSE("GPL v2"); 861 + MODULE_AUTHOR("Ganapatrao Kulkarni <gkulkarni@cavium.com>");
+73 -7
drivers/perf/xgene_pmu.c
··· 21 21 22 22 #include <linux/acpi.h> 23 23 #include <linux/clk.h> 24 + #include <linux/cpuhotplug.h> 24 25 #include <linux/cpumask.h> 25 26 #include <linux/interrupt.h> 26 27 #include <linux/io.h> ··· 131 130 132 131 struct xgene_pmu { 133 132 struct device *dev; 133 + struct hlist_node node; 134 134 int version; 135 135 void __iomem *pcppmu_csr; 136 136 u32 mcb_active_mask; 137 137 u32 mc_active_mask; 138 138 u32 l3c_active_mask; 139 139 cpumask_t cpu; 140 + int irq; 140 141 raw_spinlock_t lock; 141 142 const struct xgene_pmu_ops *ops; 142 143 struct list_head l3cpmus; ··· 1809 1806 MODULE_DEVICE_TABLE(acpi, xgene_pmu_acpi_match); 1810 1807 #endif 1811 1808 1809 + static int xgene_pmu_online_cpu(unsigned int cpu, struct hlist_node *node) 1810 + { 1811 + struct xgene_pmu *xgene_pmu = hlist_entry_safe(node, struct xgene_pmu, 1812 + node); 1813 + 1814 + if (cpumask_empty(&xgene_pmu->cpu)) 1815 + cpumask_set_cpu(cpu, &xgene_pmu->cpu); 1816 + 1817 + /* Overflow interrupt also should use the same CPU */ 1818 + WARN_ON(irq_set_affinity(xgene_pmu->irq, &xgene_pmu->cpu)); 1819 + 1820 + return 0; 1821 + } 1822 + 1823 + static int xgene_pmu_offline_cpu(unsigned int cpu, struct hlist_node *node) 1824 + { 1825 + struct xgene_pmu *xgene_pmu = hlist_entry_safe(node, struct xgene_pmu, 1826 + node); 1827 + struct xgene_pmu_dev_ctx *ctx; 1828 + unsigned int target; 1829 + 1830 + if (!cpumask_test_and_clear_cpu(cpu, &xgene_pmu->cpu)) 1831 + return 0; 1832 + target = cpumask_any_but(cpu_online_mask, cpu); 1833 + if (target >= nr_cpu_ids) 1834 + return 0; 1835 + 1836 + list_for_each_entry(ctx, &xgene_pmu->mcpmus, next) { 1837 + perf_pmu_migrate_context(&ctx->pmu_dev->pmu, cpu, target); 1838 + } 1839 + list_for_each_entry(ctx, &xgene_pmu->mcbpmus, next) { 1840 + perf_pmu_migrate_context(&ctx->pmu_dev->pmu, cpu, target); 1841 + } 1842 + list_for_each_entry(ctx, &xgene_pmu->l3cpmus, next) { 1843 + perf_pmu_migrate_context(&ctx->pmu_dev->pmu, cpu, target); 1844 + } 1845 + list_for_each_entry(ctx, &xgene_pmu->iobpmus, next) { 1846 + perf_pmu_migrate_context(&ctx->pmu_dev->pmu, cpu, target); 1847 + } 1848 + 1849 + cpumask_set_cpu(target, &xgene_pmu->cpu); 1850 + /* Overflow interrupt also should use the same CPU */ 1851 + WARN_ON(irq_set_affinity(xgene_pmu->irq, &xgene_pmu->cpu)); 1852 + 1853 + return 0; 1854 + } 1855 + 1812 1856 static int xgene_pmu_probe(struct platform_device *pdev) 1813 1857 { 1814 1858 const struct xgene_pmu_data *dev_data; ··· 1864 1814 struct resource *res; 1865 1815 int irq, rc; 1866 1816 int version; 1817 + 1818 + /* Install a hook to update the reader CPU in case it goes offline */ 1819 + rc = cpuhp_setup_state_multi(CPUHP_AP_PERF_ARM_APM_XGENE_ONLINE, 1820 + "CPUHP_AP_PERF_ARM_APM_XGENE_ONLINE", 1821 + xgene_pmu_online_cpu, 1822 + xgene_pmu_offline_cpu); 1823 + if (rc) 1824 + return rc; 1867 1825 1868 1826 xgene_pmu = devm_kzalloc(&pdev->dev, sizeof(*xgene_pmu), GFP_KERNEL); 1869 1827 if (!xgene_pmu) ··· 1923 1865 dev_err(&pdev->dev, "No IRQ resource\n"); 1924 1866 return -EINVAL; 1925 1867 } 1868 + 1926 1869 rc = devm_request_irq(&pdev->dev, irq, xgene_pmu_isr, 1927 1870 IRQF_NOBALANCING | IRQF_NO_THREAD, 1928 1871 dev_name(&pdev->dev), xgene_pmu); ··· 1931 1872 dev_err(&pdev->dev, "Could not request IRQ %d\n", irq); 1932 1873 return rc; 1933 1874 } 1875 + 1876 + xgene_pmu->irq = irq; 1934 1877 1935 1878 raw_spin_lock_init(&xgene_pmu->lock); 1936 1879 ··· 1944 1883 xgene_pmu->mc_active_mask = 0x1; 1945 1884 } 1946 1885 1947 - /* Pick one core to use for cpumask attributes */ 1948 - cpumask_set_cpu(smp_processor_id(), &xgene_pmu->cpu); 1949 - 1950 - /* Make sure that the overflow interrupt is handled by this CPU */ 1951 - rc = irq_set_affinity(irq, &xgene_pmu->cpu); 1886 + /* Add this instance to the list used by the hotplug callback */ 1887 + rc = cpuhp_state_add_instance(CPUHP_AP_PERF_ARM_APM_XGENE_ONLINE, 1888 + &xgene_pmu->node); 1952 1889 if (rc) { 1953 - dev_err(&pdev->dev, "Failed to set interrupt affinity!\n"); 1890 + dev_err(&pdev->dev, "Error %d registering hotplug", rc); 1954 1891 return rc; 1955 1892 } 1956 1893 ··· 1956 1897 rc = xgene_pmu_probe_pmu_dev(xgene_pmu, pdev); 1957 1898 if (rc) { 1958 1899 dev_err(&pdev->dev, "No PMU perf devices found!\n"); 1959 - return rc; 1900 + goto out_unregister; 1960 1901 } 1961 1902 1962 1903 /* Enable interrupt */ 1963 1904 xgene_pmu->ops->unmask_int(xgene_pmu); 1964 1905 1965 1906 return 0; 1907 + 1908 + out_unregister: 1909 + cpuhp_state_remove_instance(CPUHP_AP_PERF_ARM_APM_XGENE_ONLINE, 1910 + &xgene_pmu->node); 1911 + return rc; 1966 1912 } 1967 1913 1968 1914 static void ··· 1988 1924 xgene_pmu_dev_cleanup(xgene_pmu, &xgene_pmu->iobpmus); 1989 1925 xgene_pmu_dev_cleanup(xgene_pmu, &xgene_pmu->mcbpmus); 1990 1926 xgene_pmu_dev_cleanup(xgene_pmu, &xgene_pmu->mcpmus); 1927 + cpuhp_state_remove_instance(CPUHP_AP_PERF_ARM_APM_XGENE_ONLINE, 1928 + &xgene_pmu->node); 1991 1929 1992 1930 return 0; 1993 1931 }
+2
include/linux/cpuhotplug.h
··· 164 164 CPUHP_AP_PERF_ARM_L2X0_ONLINE, 165 165 CPUHP_AP_PERF_ARM_QCOM_L2_ONLINE, 166 166 CPUHP_AP_PERF_ARM_QCOM_L3_ONLINE, 167 + CPUHP_AP_PERF_ARM_APM_XGENE_ONLINE, 168 + CPUHP_AP_PERF_ARM_CAVIUM_TX2_UNCORE_ONLINE, 167 169 CPUHP_AP_PERF_POWERPC_NEST_IMC_ONLINE, 168 170 CPUHP_AP_PERF_POWERPC_CORE_IMC_ONLINE, 169 171 CPUHP_AP_PERF_POWERPC_THREAD_IMC_ONLINE,
+9 -2
include/linux/kexec.h
··· 143 143 144 144 int kexec_image_probe_default(struct kimage *image, void *buf, 145 145 unsigned long buf_len); 146 + int kexec_image_post_load_cleanup_default(struct kimage *image); 147 + 148 + /* 149 + * If kexec_buf.mem is set to this value, kexec_locate_mem_hole() 150 + * will try to allocate free memory. Arch may overwrite it. 151 + */ 152 + #ifndef KEXEC_BUF_MEM_UNKNOWN 153 + #define KEXEC_BUF_MEM_UNKNOWN 0 154 + #endif 146 155 147 156 /** 148 157 * struct kexec_buf - parameters for finding a place for a buffer in memory ··· 192 183 const Elf_Shdr *relsec, 193 184 const Elf_Shdr *symtab); 194 185 195 - int __weak arch_kexec_walk_mem(struct kexec_buf *kbuf, 196 - int (*func)(struct resource *, void *)); 197 186 extern int kexec_add_buffer(struct kexec_buf *kbuf); 198 187 int kexec_locate_mem_hole(struct kexec_buf *kbuf); 199 188
+6
include/linux/linkage.h
··· 79 79 #define ALIGN __ALIGN 80 80 #define ALIGN_STR __ALIGN_STR 81 81 82 + #ifndef GLOBAL 83 + #define GLOBAL(name) \ 84 + .globl name ASM_NL \ 85 + name: 86 + #endif 87 + 82 88 #ifndef ENTRY 83 89 #define ENTRY(name) \ 84 90 .globl name ASM_NL \
+1 -1
include/linux/pe.h
··· 166 166 uint16_t oem_info; /* oem specific */ 167 167 uint16_t reserved1[10]; /* reserved */ 168 168 uint32_t peaddr; /* address of pe header */ 169 - char message[64]; /* message to print */ 169 + char message[]; /* message to print */ 170 170 }; 171 171 172 172 struct mz_reloc {
+3 -1
include/linux/perf/arm_pmu.h
··· 102 102 int (*filter_match)(struct perf_event *event); 103 103 int num_events; 104 104 bool secure_access; /* 32-bit ARM only */ 105 - #define ARMV8_PMUV3_MAX_COMMON_EVENTS 0x40 105 + #define ARMV8_PMUV3_MAX_COMMON_EVENTS 0x40 106 106 DECLARE_BITMAP(pmceid_bitmap, ARMV8_PMUV3_MAX_COMMON_EVENTS); 107 + #define ARMV8_PMUV3_EXT_COMMON_EVENT_BASE 0x4000 108 + DECLARE_BITMAP(pmceid_ext_bitmap, ARMV8_PMUV3_MAX_COMMON_EVENTS); 107 109 struct platform_device *plat_device; 108 110 struct pmu_hw_events __percpu *hw_events; 109 111 struct hlist_node node;
-3
include/linux/preempt.h
··· 53 53 54 54 #define SOFTIRQ_DISABLE_OFFSET (2 * SOFTIRQ_OFFSET) 55 55 56 - /* We use the MSB mostly because its available */ 57 - #define PREEMPT_NEED_RESCHED 0x80000000 58 - 59 56 #define PREEMPT_DISABLED (PREEMPT_DISABLE_OFFSET + PREEMPT_ENABLED) 60 57 61 58 /*
+3 -1
include/uapi/asm-generic/unistd.h
··· 738 738 __SC_COMP(__NR_io_pgetevents, sys_io_pgetevents, compat_sys_io_pgetevents) 739 739 #define __NR_rseq 293 740 740 __SYSCALL(__NR_rseq, sys_rseq) 741 + #define __NR_kexec_file_load 294 742 + __SYSCALL(__NR_kexec_file_load, sys_kexec_file_load) 741 743 742 744 #undef __NR_syscalls 743 - #define __NR_syscalls 294 745 + #define __NR_syscalls 295 744 746 745 747 /* 746 748 * 32 bit systems traditionally used different
+1
include/uapi/linux/elf.h
··· 420 420 #define NT_ARM_HW_WATCH 0x403 /* ARM hardware watchpoint registers */ 421 421 #define NT_ARM_SYSTEM_CALL 0x404 /* ARM system call number */ 422 422 #define NT_ARM_SVE 0x405 /* ARM Scalable Vector Extension registers */ 423 + #define NT_ARM_PAC_MASK 0x406 /* ARM pointer authentication code masks */ 423 424 #define NT_ARC_V2 0x600 /* ARCv2 accumulator/extra registers */ 424 425 #define NT_VMCOREDD 0x700 /* Vmcore Device Dump Note */ 425 426 #define NT_MIPS_DSP 0x800 /* MIPS DSP ASE registers */
+8
include/uapi/linux/prctl.h
··· 220 220 # define PR_SPEC_DISABLE (1UL << 2) 221 221 # define PR_SPEC_FORCE_DISABLE (1UL << 3) 222 222 223 + /* Reset arm64 pointer authentication keys */ 224 + #define PR_PAC_RESET_KEYS 54 225 + # define PR_PAC_APIAKEY (1UL << 0) 226 + # define PR_PAC_APIBKEY (1UL << 1) 227 + # define PR_PAC_APDAKEY (1UL << 2) 228 + # define PR_PAC_APDBKEY (1UL << 3) 229 + # define PR_PAC_APGAKEY (1UL << 4) 230 + 223 231 #endif /* _LINUX_PRCTL_H */
+65 -5
kernel/kexec_file.c
··· 16 16 #include <linux/file.h> 17 17 #include <linux/slab.h> 18 18 #include <linux/kexec.h> 19 + #include <linux/memblock.h> 19 20 #include <linux/mutex.h> 20 21 #include <linux/list.h> 21 22 #include <linux/fs.h> ··· 77 76 return kexec_image_load_default(image); 78 77 } 79 78 80 - static int kexec_image_post_load_cleanup_default(struct kimage *image) 79 + int kexec_image_post_load_cleanup_default(struct kimage *image) 81 80 { 82 81 if (!image->fops || !image->fops->cleanup) 83 82 return 0; ··· 500 499 return locate_mem_hole_bottom_up(start, end, kbuf); 501 500 } 502 501 502 + #ifdef CONFIG_ARCH_DISCARD_MEMBLOCK 503 + static int kexec_walk_memblock(struct kexec_buf *kbuf, 504 + int (*func)(struct resource *, void *)) 505 + { 506 + return 0; 507 + } 508 + #else 509 + static int kexec_walk_memblock(struct kexec_buf *kbuf, 510 + int (*func)(struct resource *, void *)) 511 + { 512 + int ret = 0; 513 + u64 i; 514 + phys_addr_t mstart, mend; 515 + struct resource res = { }; 516 + 517 + if (kbuf->image->type == KEXEC_TYPE_CRASH) 518 + return func(&crashk_res, kbuf); 519 + 520 + if (kbuf->top_down) { 521 + for_each_free_mem_range_reverse(i, NUMA_NO_NODE, MEMBLOCK_NONE, 522 + &mstart, &mend, NULL) { 523 + /* 524 + * In memblock, end points to the first byte after the 525 + * range while in kexec, end points to the last byte 526 + * in the range. 527 + */ 528 + res.start = mstart; 529 + res.end = mend - 1; 530 + ret = func(&res, kbuf); 531 + if (ret) 532 + break; 533 + } 534 + } else { 535 + for_each_free_mem_range(i, NUMA_NO_NODE, MEMBLOCK_NONE, 536 + &mstart, &mend, NULL) { 537 + /* 538 + * In memblock, end points to the first byte after the 539 + * range while in kexec, end points to the last byte 540 + * in the range. 541 + */ 542 + res.start = mstart; 543 + res.end = mend - 1; 544 + ret = func(&res, kbuf); 545 + if (ret) 546 + break; 547 + } 548 + } 549 + 550 + return ret; 551 + } 552 + #endif 553 + 503 554 /** 504 - * arch_kexec_walk_mem - call func(data) on free memory regions 555 + * kexec_walk_resources - call func(data) on free memory regions 505 556 * @kbuf: Context info for the search. Also passed to @func. 506 557 * @func: Function to call for each memory region. 507 558 * ··· 561 508 * and that value will be returned. If all free regions are visited without 562 509 * func returning non-zero, then zero will be returned. 563 510 */ 564 - int __weak arch_kexec_walk_mem(struct kexec_buf *kbuf, 565 - int (*func)(struct resource *, void *)) 511 + static int kexec_walk_resources(struct kexec_buf *kbuf, 512 + int (*func)(struct resource *, void *)) 566 513 { 567 514 if (kbuf->image->type == KEXEC_TYPE_CRASH) 568 515 return walk_iomem_res_desc(crashk_res.desc, ··· 585 532 { 586 533 int ret; 587 534 588 - ret = arch_kexec_walk_mem(kbuf, locate_mem_hole_callback); 535 + /* Arch knows where to place */ 536 + if (kbuf->mem != KEXEC_BUF_MEM_UNKNOWN) 537 + return 0; 538 + 539 + if (IS_ENABLED(CONFIG_ARCH_DISCARD_MEMBLOCK)) 540 + ret = kexec_walk_resources(kbuf, locate_mem_hole_callback); 541 + else 542 + ret = kexec_walk_memblock(kbuf, locate_mem_hole_callback); 589 543 590 544 return ret == 1 ? 0 : -EADDRNOTAVAIL; 591 545 }
+8
kernel/sys.c
··· 121 121 #ifndef SVE_GET_VL 122 122 # define SVE_GET_VL() (-EINVAL) 123 123 #endif 124 + #ifndef PAC_RESET_KEYS 125 + # define PAC_RESET_KEYS(a, b) (-EINVAL) 126 + #endif 124 127 125 128 /* 126 129 * this is where the system-wide overflow UID and GID are defined, for ··· 2478 2475 if (arg4 || arg5) 2479 2476 return -EINVAL; 2480 2477 error = arch_prctl_spec_ctrl_set(me, arg2, arg3); 2478 + break; 2479 + case PR_PAC_RESET_KEYS: 2480 + if (arg3 || arg4 || arg5) 2481 + return -EINVAL; 2482 + error = PAC_RESET_KEYS(me, arg2); 2481 2483 break; 2482 2484 default: 2483 2485 error = -EINVAL;
+18 -7
mm/mmap.c
··· 2066 2066 return gap_end; 2067 2067 } 2068 2068 2069 + 2070 + #ifndef arch_get_mmap_end 2071 + #define arch_get_mmap_end(addr) (TASK_SIZE) 2072 + #endif 2073 + 2074 + #ifndef arch_get_mmap_base 2075 + #define arch_get_mmap_base(addr, base) (base) 2076 + #endif 2077 + 2069 2078 /* Get an address range which is currently unmapped. 2070 2079 * For shmat() with addr=0. 2071 2080 * ··· 2094 2085 struct mm_struct *mm = current->mm; 2095 2086 struct vm_area_struct *vma, *prev; 2096 2087 struct vm_unmapped_area_info info; 2088 + const unsigned long mmap_end = arch_get_mmap_end(addr); 2097 2089 2098 - if (len > TASK_SIZE - mmap_min_addr) 2090 + if (len > mmap_end - mmap_min_addr) 2099 2091 return -ENOMEM; 2100 2092 2101 2093 if (flags & MAP_FIXED) ··· 2105 2095 if (addr) { 2106 2096 addr = PAGE_ALIGN(addr); 2107 2097 vma = find_vma_prev(mm, addr, &prev); 2108 - if (TASK_SIZE - len >= addr && addr >= mmap_min_addr && 2098 + if (mmap_end - len >= addr && addr >= mmap_min_addr && 2109 2099 (!vma || addr + len <= vm_start_gap(vma)) && 2110 2100 (!prev || addr >= vm_end_gap(prev))) 2111 2101 return addr; ··· 2114 2104 info.flags = 0; 2115 2105 info.length = len; 2116 2106 info.low_limit = mm->mmap_base; 2117 - info.high_limit = TASK_SIZE; 2107 + info.high_limit = mmap_end; 2118 2108 info.align_mask = 0; 2119 2109 return vm_unmapped_area(&info); 2120 2110 } ··· 2134 2124 struct mm_struct *mm = current->mm; 2135 2125 unsigned long addr = addr0; 2136 2126 struct vm_unmapped_area_info info; 2127 + const unsigned long mmap_end = arch_get_mmap_end(addr); 2137 2128 2138 2129 /* requested length too big for entire address space */ 2139 - if (len > TASK_SIZE - mmap_min_addr) 2130 + if (len > mmap_end - mmap_min_addr) 2140 2131 return -ENOMEM; 2141 2132 2142 2133 if (flags & MAP_FIXED) ··· 2147 2136 if (addr) { 2148 2137 addr = PAGE_ALIGN(addr); 2149 2138 vma = find_vma_prev(mm, addr, &prev); 2150 - if (TASK_SIZE - len >= addr && addr >= mmap_min_addr && 2139 + if (mmap_end - len >= addr && addr >= mmap_min_addr && 2151 2140 (!vma || addr + len <= vm_start_gap(vma)) && 2152 2141 (!prev || addr >= vm_end_gap(prev))) 2153 2142 return addr; ··· 2156 2145 info.flags = VM_UNMAPPED_AREA_TOPDOWN; 2157 2146 info.length = len; 2158 2147 info.low_limit = max(PAGE_SIZE, mmap_min_addr); 2159 - info.high_limit = mm->mmap_base; 2148 + info.high_limit = arch_get_mmap_base(addr, mm->mmap_base); 2160 2149 info.align_mask = 0; 2161 2150 addr = vm_unmapped_area(&info); 2162 2151 ··· 2170 2159 VM_BUG_ON(addr != -ENOMEM); 2171 2160 info.flags = 0; 2172 2161 info.low_limit = TASK_UNMAPPED_BASE; 2173 - info.high_limit = TASK_SIZE; 2162 + info.high_limit = mmap_end; 2174 2163 addr = vm_unmapped_area(&info); 2175 2164 } 2176 2165
+4 -4
virt/kvm/arm/arm.c
··· 1640 1640 return -ENODEV; 1641 1641 } 1642 1642 1643 - if (!kvm_arch_check_sve_has_vhe()) { 1644 - kvm_pr_unimpl("SVE system without VHE unsupported. Broken cpu?"); 1643 + in_hyp_mode = is_kernel_in_hyp_mode(); 1644 + 1645 + if (!in_hyp_mode && kvm_arch_requires_vhe()) { 1646 + kvm_pr_unimpl("CPU unsupported in non-VHE mode, not initializing\n"); 1645 1647 return -ENODEV; 1646 1648 } 1647 1649 ··· 1658 1656 err = init_common_resources(); 1659 1657 if (err) 1660 1658 return err; 1661 - 1662 - in_hyp_mode = is_kernel_in_hyp_mode(); 1663 1659 1664 1660 if (!in_hyp_mode) { 1665 1661 err = init_hyp_mode();