1 /* SPDX-License-Identifier: GPL-2.0-only */
3 * Copyright (C) 2023 ARM Ltd.
9 #include <asm/uaccess.h>
11 struct kernel_clone_args;
14 static inline void gcsb_dsync(void)
16 asm volatile(".inst 0xd503227f" : : : "memory");
19 static inline void gcsstr(u64 *addr, u64 val)
21 register u64 *_addr __asm__ ("x0") = addr;
22 register long _val __asm__ ("x1") = val;
28 : "rZ" (_val), "r" (_addr)
32 static inline void gcsss1(u64 Xt)
35 "sys #3, C7, C7, #2, %0\n"
41 static inline u64 gcsss2(void)
46 "SYSL %0, #3, C7, C7, #3\n"
54 #define PR_SHADOW_STACK_SUPPORTED_STATUS_MASK \
55 (PR_SHADOW_STACK_ENABLE | PR_SHADOW_STACK_WRITE | PR_SHADOW_STACK_PUSH)
57 #ifdef CONFIG_ARM64_GCS
59 static inline bool task_gcs_el0_enabled(struct task_struct *task)
61 return current->thread.gcs_el0_mode & PR_SHADOW_STACK_ENABLE;
64 void gcs_set_el0_mode(struct task_struct *task);
65 void gcs_free(struct task_struct *task);
66 void gcs_preserve_current_state(void);
67 unsigned long gcs_alloc_thread_stack(struct task_struct *tsk,
68 const struct kernel_clone_args *args);
70 static inline int gcs_check_locked(struct task_struct *task,
71 unsigned long new_val)
73 unsigned long cur_val = task->thread.gcs_el0_mode;
75 cur_val &= task->thread.gcs_el0_locked;
76 new_val &= task->thread.gcs_el0_locked;
78 if (cur_val != new_val)
86 static inline bool task_gcs_el0_enabled(struct task_struct *task)
91 static inline void gcs_set_el0_mode(struct task_struct *task) { }
92 static inline void gcs_free(struct task_struct *task) { }
93 static inline void gcs_preserve_current_state(void) { }
94 static inline unsigned long gcs_alloc_thread_stack(struct task_struct *tsk,
95 const struct kernel_clone_args *args)
99 static inline int gcs_check_locked(struct task_struct *task,
100 unsigned long new_val)