| /* SPDX-License-Identifier: GPL-2.0-only */ | |
| /* | |
| * Copyright (C) 2023 ARM Limited. | |
| */ | |
| #ifndef GCS_UTIL_H | |
| #define GCS_UTIL_H | |
| #include <stdbool.h> | |
| #ifndef __NR_map_shadow_stack | |
| #define __NR_map_shadow_stack 453 | |
| #endif | |
| #ifndef __NR_prctl | |
| #define __NR_prctl 167 | |
| #endif | |
| #ifndef NT_ARM_GCS | |
| #define NT_ARM_GCS 0x410 | |
| #endif | |
| /* Shadow Stack/Guarded Control Stack interface */ | |
| #define PR_GET_SHADOW_STACK_STATUS 74 | |
| #define PR_SET_SHADOW_STACK_STATUS 75 | |
| #define PR_LOCK_SHADOW_STACK_STATUS 76 | |
| # define PR_SHADOW_STACK_ENABLE (1UL << 0) | |
| # define PR_SHADOW_STACK_WRITE (1UL << 1) | |
| # define PR_SHADOW_STACK_PUSH (1UL << 2) | |
| #define PR_SHADOW_STACK_ALL_MODES \ | |
| PR_SHADOW_STACK_ENABLE | PR_SHADOW_STACK_WRITE | PR_SHADOW_STACK_PUSH | |
| #define SHADOW_STACK_SET_TOKEN (1ULL << 0) /* Set up a restore token in the shadow stack */ | |
| #define SHADOW_STACK_SET_MARKER (1ULL << 1) /* Set up a top of stack merker in the shadow stack */ | |
| #define GCS_CAP_ADDR_MASK (0xfffffffffffff000UL) | |
| #define GCS_CAP_TOKEN_MASK (0x0000000000000fffUL) | |
| #define GCS_CAP_VALID_TOKEN 1 | |
| #define GCS_CAP_IN_PROGRESS_TOKEN 5 | |
| #define GCS_CAP(x) (((unsigned long)(x) & GCS_CAP_ADDR_MASK) | \ | |
| GCS_CAP_VALID_TOKEN) | |
| static inline unsigned long *get_gcspr(void) | |
| { | |
| unsigned long *gcspr; | |
| asm volatile( | |
| "mrs %0, S3_3_C2_C5_1" | |
| : "=r" (gcspr) | |
| : | |
| : "cc"); | |
| return gcspr; | |
| } | |
| static inline void __attribute__((always_inline)) gcsss1(unsigned long *Xt) | |
| { | |
| asm volatile ( | |
| "sys #3, C7, C7, #2, %0\n" | |
| : | |
| : "rZ" (Xt) | |
| : "memory"); | |
| } | |
| static inline unsigned long __attribute__((always_inline)) *gcsss2(void) | |
| { | |
| unsigned long *Xt; | |
| asm volatile( | |
| "SYSL %0, #3, C7, C7, #3\n" | |
| : "=r" (Xt) | |
| : | |
| : "memory"); | |
| return Xt; | |
| } | |
| static inline bool chkfeat_gcs(void) | |
| { | |
| register long val __asm__ ("x16") = 1; | |
| /* CHKFEAT x16 */ | |
| asm volatile( | |
| "hint #0x28\n" | |
| : "=r" (val) | |
| : "r" (val)); | |
| return val != 1; | |
| } | |
| #endif |