Pull arm64 updates from Will Deacon: "A sizeable pile of arm64 updates for 5.8. Summary below, but the big two features are support for Branch Target Identification and Clang's Shadow Call stack. The latter is currently arm64-only, but the high-level parts are all in core code so it could easily be adopted by other architectures pending toolchain support Branch Target Identification (BTI): - Support for ARMv8.5-BTI in both user- and kernel-space. This allows branch targets to limit the types of branch from which they can be called and additionally prevents branching to arbitrary code, although kernel support requires a very recent toolchain. - Function annotation via SYM_FUNC_START() so that assembly functions are wrapped with the relevant "landing pad" instructions. - BPF and vDSO updates to use the new instructions. - Addition of a new HWCAP and exposure of BTI capability to userspace via ID register emulation, along with ELF loader support for the BTI feature in .note.gnu.property. - Non-critical fixes to CFI unwind annotations in the sigreturn trampoline. Shadow Call Stack (SCS): - Support for Clang's Shadow Call Stack feature, which reserves platform register x18 to point at a separate stack for each task that holds only return addresses. This protects function return control flow from buffer overruns on the main stack. - Save/restore of x18 across problematic boundaries (user-mode, hypervisor, EFI, suspend, etc). - Core support for SCS, should other architectures want to use it too. - SCS overflow checking on context-switch as part of the existing stack limit check if CONFIG_SCHED_STACK_END_CHECK=y. CPU feature detection: - Removed numerous "SANITY CHECK" errors when running on a system with mismatched AArch32 support at EL1. This is primarily a concern for KVM, which disabled support for 32-bit guests on such a system. - Addition of new ID registers and fields as the architecture has been extended. Perf and PMU drivers: - Minor fixes and cleanups to system PMU drivers. Hardware errata: - Unify KVM workarounds for VHE and nVHE configurations. - Sort vendor errata entries in Kconfig. Secure Monitor Call Calling Convention (SMCCC): - Update to the latest specification from Arm (v1.2). - Allow PSCI code to query the SMCCC version. Software Delegated Exception Interface (SDEI): - Unexport a bunch of unused symbols. - Minor fixes to handling of firmware data. Pointer authentication: - Add support for dumping the kernel PAC mask in vmcoreinfo so that the stack can be unwound by tools such as kdump. - Simplification of key initialisation during CPU bringup. BPF backend: - Improve immediate generation for logical and add/sub instructions. vDSO: - Minor fixes to the linker flags for consistency with other architectures and support for LLVM's unwinder. - Clean up logic to initialise and map the vDSO into userspace. ACPI: - Work around for an ambiguity in the IORT specification relating to the "num_ids" field. - Support _DMA method for all named components rather than only PCIe root complexes. - Minor other IORT-related fixes. Miscellaneous: - Initialise debug traps early for KGDB and fix KDB cacheflushing deadlock. - Minor tweaks to early boot state (documentation update, set TEXT_OFFSET to 0x0, increase alignment of PE/COFF sections). - Refactoring and cleanup" * tag 'arm64-upstream' of git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux: (148 commits) KVM: arm64: Move __load_guest_stage2 to kvm_mmu.h KVM: arm64: Check advertised Stage-2 page size capability arm64/cpufeature: Add get_arm64_ftr_reg_nowarn() ACPI/IORT: Remove the unused __get_pci_rid() arm64/cpuinfo: Add ID_MMFR4_EL1 into the cpuinfo_arm64 context arm64/cpufeature: Add remaining feature bits in ID_AA64PFR1 register arm64/cpufeature: Add remaining feature bits in ID_AA64PFR0 register arm64/cpufeature: Add remaining feature bits in ID_AA64ISAR0 register arm64/cpufeature: Add remaining feature bits in ID_MMFR4 register arm64/cpufeature: Add remaining feature bits in ID_PFR0 register arm64/cpufeature: Introduce ID_MMFR5 CPU register arm64/cpufeature: Introduce ID_DFR1 CPU register arm64/cpufeature: Introduce ID_PFR2 CPU register arm64/cpufeature: Make doublelock a signed feature in ID_AA64DFR0 arm64/cpufeature: Drop TraceFilt feature exposure from ID_DFR0 register arm64/cpufeature: Add explicit ftr_id_isar0[] for ID_ISAR0 register arm64: mm: Add asid_gen_match() helper firmware: smccc: Fix missing prototype warning for arm_smccc_version_init arm64: vdso: Fix CFI directives in sigreturn trampoline arm64: vdso: Don't prefix sigreturn trampoline with a BTI C instruction ...
Showing the changes to include/linux (9 of 159 files). Show all
Unified · Split
| @@ -5,12 +5,15 @@ · 4 unmodified lines | ||
| 5 | 5 | #ifndef __LINUX_ARM_SMCCC_H |
| 6 | 6 | #define __LINUX_ARM_SMCCC_H |
| 7 | 7 | |
| 8 | +#include <linux/init.h> | |
| 8 | 9 | #include <uapi/linux/const.h> |
| 9 | 10 | |
| 10 | 11 | /* |
| 11 | 12 | * This file provides common defines for ARM SMC Calling Convention as |
| 12 | 13 | * specified in |
| 13 | − * http://infocenter.arm.com/help/topic/com.arm.doc.den0028a/index.html | |
| 14 | + * https://developer.arm.com/docs/den0028/latest | |
| 15 | + * | |
| 16 | + * This code is up-to-date with version DEN 0028 C | |
| 14 | 17 | */ |
| 15 | 18 | |
| 16 | 19 | #define ARM_SMCCC_STD_CALL _AC(0,U) |
| @@ -56,6 +59,7 @@ · 39 unmodified lines | ||
| 56 | 59 | |
| 57 | 60 | #define ARM_SMCCC_VERSION_1_0 0x10000 |
| 58 | 61 | #define ARM_SMCCC_VERSION_1_1 0x10001 |
| 62 | +#define ARM_SMCCC_VERSION_1_2 0x10002 | |
| 59 | 63 | |
| 60 | 64 | #define ARM_SMCCC_VERSION_FUNC_ID \ |
| 61 | 65 | ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \ |
| @@ -97,6 +101,19 @@ enum arm_smccc_conduit { · 35 unmodified lines | ||
| 97 | 101 | */ |
| 98 | 102 | enum arm_smccc_conduit arm_smccc_1_1_get_conduit(void); |
| 99 | 103 | |
| 104 | +/** | |
| 105 | + * arm_smccc_get_version() | |
| 106 | + * | |
| 107 | + * Returns the version to be used for SMCCCv1.1 or later. | |
| 108 | + * | |
| 109 | + * When SMCCCv1.1 or above is not present, returns SMCCCv1.0, but this | |
| 110 | + * does not imply the presence of firmware or a valid conduit. Caller | |
| 111 | + * handling SMCCCv1.0 must determine the conduit by other means. | |
| 112 | + */ | |
| 113 | +u32 arm_smccc_get_version(void); | |
| 114 | + | |
| 115 | +void __init arm_smccc_version_init(u32 version, enum arm_smccc_conduit conduit); | |
| 116 | + | |
| 100 | 117 | /** |
| 101 | 118 | * struct arm_smccc_res - Result from SMC/HVC call |
| 102 | 119 | * @a0-a3 result values from registers 0 to 3 |
| @@ -314,10 +331,14 @@ asmlinkage void __arm_smccc_hvc(unsigned long a0, unsigned long a1, · 211 unmodified lines | ||
| 314 | 331 | */ |
| 315 | 332 | #define arm_smccc_1_1_hvc(...) __arm_smccc_1_1(SMCCC_HVC_INST, __VA_ARGS__) |
| 316 | 333 | |
| 317 | −/* Return codes defined in ARM DEN 0070A */ | |
| 334 | +/* | |
| 335 | + * Return codes defined in ARM DEN 0070A | |
| 336 | + * ARM DEN 0070A is now merged/consolidated into ARM DEN 0028 C | |
| 337 | + */ | |
| 318 | 338 | #define SMCCC_RET_SUCCESS 0 |
| 319 | 339 | #define SMCCC_RET_NOT_SUPPORTED -1 |
| 320 | 340 | #define SMCCC_RET_NOT_REQUIRED -2 |
| 341 | +#define SMCCC_RET_INVALID_PARAMETER -3 | |
| 321 | 342 | |
| 322 | 343 | /* |
| 323 | 344 | * Like arm_smccc_1_1* but always returns SMCCC_RET_NOT_SUPPORTED. |
| @@ -42,3 +42,7 @@ · 41 unmodified lines | ||
| 42 | 42 | * compilers, like ICC. |
| 43 | 43 | */ |
| 44 | 44 | #define barrier() __asm__ __volatile__("" : : : "memory") |
| 45 | + | |
| 46 | +#if __has_feature(shadow_call_stack) | |
| 47 | +# define __noscs __attribute__((__no_sanitize__("shadow-call-stack"))) | |
| 48 | +#endif | |
| @@ -197,6 +197,10 @@ struct ftrace_likely_data { · 196 unmodified lines | ||
| 197 | 197 | # define randomized_struct_fields_end |
| 198 | 198 | #endif |
| 199 | 199 | |
| 200 | +#ifndef __noscs | |
| 201 | +# define __noscs | |
| 202 | +#endif | |
| 203 | + | |
| 200 | 204 | #ifndef asm_volatile_goto |
| 201 | 205 | #define asm_volatile_goto(x...) asm goto(x) |
| 202 | 206 | #endif |
| @@ -2,6 +2,7 @@ · 1 unmodified line | ||
| 2 | 2 | #ifndef _LINUX_ELF_H |
| 3 | 3 | #define _LINUX_ELF_H |
| 4 | 4 | |
| 5 | +#include <linux/types.h> | |
| 5 | 6 | #include <asm/elf.h> |
| 6 | 7 | #include <uapi/linux/elf.h> |
| 7 | 8 | |
| @@ -21,6 +22,9 @@ · 13 unmodified lines | ||
| 21 | 22 | SET_PERSONALITY(ex) |
| 22 | 23 | #endif |
| 23 | 24 | |
| 25 | +#define ELF32_GNU_PROPERTY_ALIGN 4 | |
| 26 | +#define ELF64_GNU_PROPERTY_ALIGN 8 | |
| 27 | + | |
| 24 | 28 | #if ELF_CLASS == ELFCLASS32 |
| 25 | 29 | |
| 26 | 30 | extern Elf32_Dyn _DYNAMIC []; |
| @@ -31,6 +35,7 @@ extern Elf32_Dyn _DYNAMIC []; · 4 unmodified lines | ||
| 31 | 35 | #define elf_addr_t Elf32_Off |
| 32 | 36 | #define Elf_Half Elf32_Half |
| 33 | 37 | #define Elf_Word Elf32_Word |
| 38 | +#define ELF_GNU_PROPERTY_ALIGN ELF32_GNU_PROPERTY_ALIGN | |
| 34 | 39 | |
| 35 | 40 | #else |
| 36 | 41 | |
| @@ -42,6 +47,7 @@ extern Elf64_Dyn _DYNAMIC []; · 5 unmodified lines | ||
| 42 | 47 | #define elf_addr_t Elf64_Off |
| 43 | 48 | #define Elf_Half Elf64_Half |
| 44 | 49 | #define Elf_Word Elf64_Word |
| 50 | +#define ELF_GNU_PROPERTY_ALIGN ELF64_GNU_PROPERTY_ALIGN | |
| 45 | 51 | |
| 46 | 52 | #endif |
| 47 | 53 | |
| @@ -56,4 +62,41 @@ static inline int elf_coredump_extra_notes_write(struct coredump_params *cprm) { · 8 unmodified lines | ||
| 56 | 62 | extern int elf_coredump_extra_notes_size(void); |
| 57 | 63 | extern int elf_coredump_extra_notes_write(struct coredump_params *cprm); |
| 58 | 64 | #endif |
| 65 | + | |
| 66 | +/* | |
| 67 | + * NT_GNU_PROPERTY_TYPE_0 header: | |
| 68 | + * Keep this internal until/unless there is an agreed UAPI definition. | |
| 69 | + * pr_type values (GNU_PROPERTY_*) are public and defined in the UAPI header. | |
| 70 | + */ | |
| 71 | +struct gnu_property { | |
| 72 | + u32 pr_type; | |
| 73 | + u32 pr_datasz; | |
| 74 | +}; | |
| 75 | + | |
| 76 | +struct arch_elf_state; | |
| 77 | + | |
| 78 | +#ifndef CONFIG_ARCH_USE_GNU_PROPERTY | |
| 79 | +static inline int arch_parse_elf_property(u32 type, const void *data, | |
| 80 | + size_t datasz, bool compat, | |
| 81 | + struct arch_elf_state *arch) | |
| 82 | +{ | |
| 83 | + return 0; | |
| 84 | +} | |
| 85 | +#else | |
| 86 | +extern int arch_parse_elf_property(u32 type, const void *data, size_t datasz, | |
| 87 | + bool compat, struct arch_elf_state *arch); | |
| 88 | +#endif | |
| 89 | + | |
| 90 | +#ifdef CONFIG_ARCH_HAVE_ELF_PROT | |
| 91 | +int arch_elf_adjust_prot(int prot, const struct arch_elf_state *state, | |
| 92 | + bool has_interp, bool is_interp); | |
| 93 | +#else | |
| 94 | +static inline int arch_elf_adjust_prot(int prot, | |
| 95 | + const struct arch_elf_state *state, | |
| 96 | + bool has_interp, bool is_interp) | |
| 97 | +{ | |
| 98 | + return prot; | |
| 99 | +} | |
| 100 | +#endif | |
| 101 | + | |
| 59 | 102 | #endif /* _LINUX_ELF_H */ |
| @@ -105,7 +105,7 @@ · 104 unmodified lines | ||
| 105 | 105 | |
| 106 | 106 | /* === DEPRECATED annotations === */ |
| 107 | 107 | |
| 108 | −#ifndef CONFIG_X86 | |
| 108 | +#ifndef CONFIG_ARCH_USE_SYM_ANNOTATIONS | |
| 109 | 109 | #ifndef GLOBAL |
| 110 | 110 | /* deprecated, use SYM_DATA*, SYM_ENTRY, or similar */ |
| 111 | 111 | #define GLOBAL(name) \ |
| @@ -118,10 +118,10 @@ · 6 unmodified lines | ||
| 118 | 118 | #define ENTRY(name) \ |
| 119 | 119 | SYM_FUNC_START(name) |
| 120 | 120 | #endif |
| 121 | −#endif /* CONFIG_X86 */ | |
| 121 | +#endif /* CONFIG_ARCH_USE_SYM_ANNOTATIONS */ | |
| 122 | 122 | #endif /* LINKER_SCRIPT */ |
| 123 | 123 | |
| 124 | −#ifndef CONFIG_X86 | |
| 124 | +#ifndef CONFIG_ARCH_USE_SYM_ANNOTATIONS | |
| 125 | 125 | #ifndef WEAK |
| 126 | 126 | /* deprecated, use SYM_FUNC_START_WEAK* */ |
| 127 | 127 | #define WEAK(name) \ |
| @@ -143,7 +143,7 @@ · 15 unmodified lines | ||
| 143 | 143 | #define ENDPROC(name) \ |
| 144 | 144 | SYM_FUNC_END(name) |
| 145 | 145 | #endif |
| 146 | −#endif /* CONFIG_X86 */ | |
| 146 | +#endif /* CONFIG_ARCH_USE_SYM_ANNOTATIONS */ | |
| 147 | 147 | |
| 148 | 148 | /* === generic annotations === */ |
| 149 | 149 | |
| @@ -325,6 +325,9 @@ extern unsigned int kobjsize(const void *objp); · 324 unmodified lines | ||
| 325 | 325 | #elif defined(CONFIG_SPARC64) |
| 326 | 326 | # define VM_SPARC_ADI VM_ARCH_1 /* Uses ADI tag for access control */ |
| 327 | 327 | # define VM_ARCH_CLEAR VM_SPARC_ADI |
| 328 | +#elif defined(CONFIG_ARM64) | |
| 329 | +# define VM_ARM64_BTI VM_ARCH_1 /* BTI guarded page, a.k.a. GP bit */ | |
| 330 | +# define VM_ARCH_CLEAR VM_ARM64_BTI | |
| 328 | 331 | #elif !defined(CONFIG_MMU) |
| 329 | 332 | # define VM_MAPPED_COPY VM_ARCH_1 /* T if mapped copy of data (nommu mmap) */ |
| 330 | 333 | #endif |
| @@ -156,6 +156,9 @@ enum zone_stat_item { · 155 unmodified lines | ||
| 156 | 156 | NR_MLOCK, /* mlock()ed pages found and moved off LRU */ |
| 157 | 157 | NR_PAGETABLE, /* used for pagetables */ |
| 158 | 158 | NR_KERNEL_STACK_KB, /* measured in KiB */ |
| 159 | +#if IS_ENABLED(CONFIG_SHADOW_CALL_STACK) | |
| 160 | + NR_KERNEL_SCS_KB, /* measured in KiB */ | |
| 161 | +#endif | |
| 159 | 162 | /* Second 128 byte cacheline */ |
| 160 | 163 | NR_BOUNCE, |
| 161 | 164 | #if IS_ENABLED(CONFIG_ZSMALLOC) |
| @@ -21,11 +21,6 @@ bool psci_power_state_is_valid(u32 state); · 20 unmodified lines | ||
| 21 | 21 | int psci_set_osi_mode(void); |
| 22 | 22 | bool psci_has_osi_support(void); |
| 23 | 23 | |
| 24 | −enum smccc_version { | |
| 25 | − SMCCC_VERSION_1_0, | |
| 26 | − SMCCC_VERSION_1_1, | |
| 27 | −}; | |
| 28 | − | |
| 29 | 24 | struct psci_operations { |
| 30 | 25 | u32 (*get_version)(void); |
| 31 | 26 | int (*cpu_suspend)(u32 state, unsigned long entry_point); |
| @@ -35,8 +30,6 @@ struct psci_operations { · 3 unmodified lines | ||
| 35 | 30 | int (*affinity_info)(unsigned long target_affinity, |
| 36 | 31 | unsigned long lowest_affinity_level); |
| 37 | 32 | int (*migrate_info_type)(void); |
| 38 | − enum arm_smccc_conduit conduit; | |
| 39 | − enum smccc_version smccc_version; | |
| 40 | 33 | }; |
| 41 | 34 | |
| 42 | 35 | extern struct psci_operations psci_ops; |
| @@ -0,0 +1,72 @@ | ||
| 1 | +/* SPDX-License-Identifier: GPL-2.0 */ | |
| 2 | +/* | |
| 3 | + * Shadow Call Stack support. | |
| 4 | + * | |
| 5 | + * Copyright (C) 2019 Google LLC | |
| 6 | + */ | |
| 7 | + | |
| 8 | +#ifndef _LINUX_SCS_H | |
| 9 | +#define _LINUX_SCS_H | |
| 10 | + | |
| 11 | +#include <linux/gfp.h> | |
| 12 | +#include <linux/poison.h> | |
| 13 | +#include <linux/sched.h> | |
| 14 | +#include <linux/sizes.h> | |
| 15 | + | |
| 16 | +#ifdef CONFIG_SHADOW_CALL_STACK | |
| 17 | + | |
| 18 | +/* | |
| 19 | + * In testing, 1 KiB shadow stack size (i.e. 128 stack frames on a 64-bit | |
| 20 | + * architecture) provided ~40% safety margin on stack usage while keeping | |
| 21 | + * memory allocation overhead reasonable. | |
| 22 | + */ | |
| 23 | +#define SCS_SIZE SZ_1K | |
| 24 | +#define GFP_SCS (GFP_KERNEL | __GFP_ZERO) | |
| 25 | + | |
| 26 | +/* An illegal pointer value to mark the end of the shadow stack. */ | |
| 27 | +#define SCS_END_MAGIC (0x5f6UL + POISON_POINTER_DELTA) | |
| 28 | + | |
| 29 | +/* Allocate a static per-CPU shadow stack */ | |
| 30 | +#define DEFINE_SCS(name) \ | |
| 31 | + DEFINE_PER_CPU(unsigned long [SCS_SIZE/sizeof(long)], name) \ | |
| 32 | + | |
| 33 | +#define task_scs(tsk) (task_thread_info(tsk)->scs_base) | |
| 34 | +#define task_scs_sp(tsk) (task_thread_info(tsk)->scs_sp) | |
| 35 | + | |
| 36 | +void scs_init(void); | |
| 37 | +int scs_prepare(struct task_struct *tsk, int node); | |
| 38 | +void scs_release(struct task_struct *tsk); | |
| 39 | + | |
| 40 | +static inline void scs_task_reset(struct task_struct *tsk) | |
| 41 | +{ | |
| 42 | + /* | |
| 43 | + * Reset the shadow stack to the base address in case the task | |
| 44 | + * is reused. | |
| 45 | + */ | |
| 46 | + task_scs_sp(tsk) = task_scs(tsk); | |
| 47 | +} | |
| 48 | + | |
| 49 | +static inline unsigned long *__scs_magic(void *s) | |
| 50 | +{ | |
| 51 | + return (unsigned long *)(s + SCS_SIZE) - 1; | |
| 52 | +} | |
| 53 | + | |
| 54 | +static inline bool task_scs_end_corrupted(struct task_struct *tsk) | |
| 55 | +{ | |
| 56 | + unsigned long *magic = __scs_magic(task_scs(tsk)); | |
| 57 | + unsigned long sz = task_scs_sp(tsk) - task_scs(tsk); | |
| 58 | + | |
| 59 | + return sz >= SCS_SIZE - 1 || READ_ONCE_NOCHECK(*magic) != SCS_END_MAGIC; | |
| 60 | +} | |
| 61 | + | |
| 62 | +#else /* CONFIG_SHADOW_CALL_STACK */ | |
| 63 | + | |
| 64 | +static inline void scs_init(void) {} | |
| 65 | +static inline void scs_task_reset(struct task_struct *tsk) {} | |
| 66 | +static inline int scs_prepare(struct task_struct *tsk, int node) { return 0; } | |
| 67 | +static inline void scs_release(struct task_struct *tsk) {} | |
| 68 | +static inline bool task_scs_end_corrupted(struct task_struct *tsk) { return false; } | |
| 69 | + | |
| 70 | +#endif /* CONFIG_SHADOW_CALL_STACK */ | |
| 71 | + | |
| 72 | +#endif /* _LINUX_SCS_H */ | |