1 /* SPDX-License-Identifier: GPL-2.0-only */ 2 /* 3 * Copyright (C) 2023 ARM Limited. 4 */ 5 6 #ifndef GCS_UTIL_H 7 #define GCS_UTIL_H 8 9 #include <stdbool.h> 10 11 #ifndef __NR_map_shadow_stack 12 #define __NR_map_shadow_stack 453 13 #endif 14 15 #ifndef __NR_prctl 16 #define __NR_prctl 167 17 #endif 18 19 #ifndef NT_ARM_GCS 20 #define NT_ARM_GCS 0x410 21 #endif 22 23 /* Shadow Stack/Guarded Control Stack interface */ 24 #define PR_GET_SHADOW_STACK_STATUS 74 25 #define PR_SET_SHADOW_STACK_STATUS 75 26 #define PR_LOCK_SHADOW_STACK_STATUS 76 27 28 # define PR_SHADOW_STACK_ENABLE (1UL << 0) 29 # define PR_SHADOW_STACK_WRITE (1UL << 1) 30 # define PR_SHADOW_STACK_PUSH (1UL << 2) 31 32 #define PR_SHADOW_STACK_ALL_MODES \ 33 PR_SHADOW_STACK_ENABLE | PR_SHADOW_STACK_WRITE | PR_SHADOW_STACK_PUSH 34 35 #define SHADOW_STACK_SET_TOKEN (1ULL << 0) /* Set up a restore token in the shadow stack */ 36 #define SHADOW_STACK_SET_MARKER (1ULL << 1) /* Set up a top of stack merker in the shadow stack */ 37 38 #define GCS_CAP_ADDR_MASK (0xfffffffffffff000UL) 39 #define GCS_CAP_TOKEN_MASK (0x0000000000000fffUL) 40 #define GCS_CAP_VALID_TOKEN 1 41 #define GCS_CAP_IN_PROGRESS_TOKEN 5 42 43 #define GCS_CAP(x) (((unsigned long)(x) & GCS_CAP_ADDR_MASK) | \ 44 GCS_CAP_VALID_TOKEN) 45 get_gcspr(void)46static inline unsigned long *get_gcspr(void) 47 { 48 unsigned long *gcspr; 49 50 asm volatile( 51 "mrs %0, S3_3_C2_C5_1" 52 : "=r" (gcspr) 53 : 54 : "cc"); 55 56 return gcspr; 57 } 58 gcsss1(unsigned long * Xt)59static inline void __attribute__((always_inline)) gcsss1(unsigned long *Xt) 60 { 61 asm volatile ( 62 "sys #3, C7, C7, #2, %0\n" 63 : 64 : "rZ" (Xt) 65 : "memory"); 66 } 67 gcsss2(void)68static inline unsigned long __attribute__((always_inline)) *gcsss2(void) 69 { 70 unsigned long *Xt; 71 72 asm volatile( 73 "SYSL %0, #3, C7, C7, #3\n" 74 : "=r" (Xt) 75 : 76 : "memory"); 77 78 return Xt; 79 } 80 chkfeat_gcs(void)81static inline bool chkfeat_gcs(void) 82 { 83 register long val __asm__ ("x16") = 1; 84 85 /* CHKFEAT x16 */ 86 asm volatile( 87 "hint #0x28\n" 88 : "=r" (val) 89 : "r" (val)); 90 91 return val != 1; 92 } 93 94 #endif 95