1 /* SPDX-License-Identifier: GPL-2.0 */ 2 #ifndef _ASM_SCS_H 3 #define _ASM_SCS_H 4 5 #ifdef __ASSEMBLY__ 6 7 #include <asm/asm-offsets.h> 8 #include <asm/sysreg.h> 9 10 #ifdef CONFIG_SHADOW_CALL_STACK 11 scs_sp .req x18 12 13 .macro scs_load tsk 14 ldr scs_sp, [\tsk, #TSK_TI_SCS_SP] 15 .endm 16 17 .macro scs_save tsk 18 str scs_sp, [\tsk, #TSK_TI_SCS_SP] 19 .endm 20 #else 21 .macro scs_load tsk 22 .endm 23 24 .macro scs_save tsk 25 .endm 26 #endif /* CONFIG_SHADOW_CALL_STACK */ 27 28 29 #else 30 31 #include <linux/scs.h> 32 #include <asm/cpufeature.h> 33 34 #ifdef CONFIG_UNWIND_PATCH_PAC_INTO_SCS 35 static inline bool should_patch_pac_into_scs(void) 36 { 37 u64 reg; 38 39 /* 40 * We only enable the shadow call stack dynamically if we are running 41 * on a system that does not implement PAC or BTI. PAC and SCS provide 42 * roughly the same level of protection, and BTI relies on the PACIASP 43 * instructions serving as landing pads, preventing us from patching 44 * those instructions into something else. 45 */ 46 reg = read_sysreg_s(SYS_ID_AA64ISAR1_EL1); 47 if (SYS_FIELD_GET(ID_AA64ISAR1_EL1, APA, reg) | 48 SYS_FIELD_GET(ID_AA64ISAR1_EL1, API, reg)) 49 return false; 50 51 reg = read_sysreg_s(SYS_ID_AA64ISAR2_EL1); 52 if (SYS_FIELD_GET(ID_AA64ISAR2_EL1, APA3, reg)) 53 return false; 54 55 if (IS_ENABLED(CONFIG_ARM64_BTI_KERNEL)) { 56 reg = read_sysreg_s(SYS_ID_AA64PFR1_EL1); 57 if (reg & (0xf << ID_AA64PFR1_EL1_BT_SHIFT)) 58 return false; 59 } 60 return true; 61 } 62 63 static inline void dynamic_scs_init(void) 64 { 65 if (should_patch_pac_into_scs()) { 66 pr_info("Enabling dynamic shadow call stack\n"); 67 static_branch_enable(&dynamic_scs_enabled); 68 } 69 } 70 #else 71 static inline void dynamic_scs_init(void) {} 72 #endif 73 74 int scs_patch(const u8 eh_frame[], int size); 75 76 #endif /* __ASSEMBLY __ */ 77 78 #endif /* _ASM_SCS_H */ 79