1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3 * Copyright (c) 2023 Huawei Device Co., Ltd.
4 */
5
6 #ifndef __POINTER_AUTH_CONTEXT_H
7 #define __POINTER_AUTH_CONTEXT_H
8
9 struct pt_regs;
10
11 enum pac_pt_regs {
12 REGS_X16 = 0,
13 REGS_X17,
14 REGS_LR,
15 REGS_SP,
16 REGS_PC,
17 REGS_PSTATE,
18 };
19
20 void sign_thread_context(void *cpu_context);
21 void auth_thread_context(void *cpu_context);
22
23 void sign_exception_context_asm(void *regs);
24 void auth_exception_context_asm(void *regs);
25
26 int set_exception_context_register_asm(void *regs, int offset, u64 val);
27
28 #ifdef CONFIG_COMPAT
29 void sign_compat_exception_context_asm(void *regs);
30 void auth_compat_exception_context_asm(void *regs);
31
32 int set_compat_exception_context_register_asm(void *regs, int offset, u64 val);
33 #else
sign_compat_exception_context_asm(void *regs)34 static inline void sign_compat_exception_context_asm(void *regs)
35 {
36 }
37
auth_compat_exception_context_asm(void *regs)38 static inline void auth_compat_exception_context_asm(void *regs)
39 {
40 }
41
set_compat_exception_context_register_asm(void *regs, int offset, u64 val)42 static inline int set_compat_exception_context_register_asm(void *regs, int offset, u64 val)
43 {
44 return 0;
45 }
46 #endif
47
sign_compat_exception_context_unsafe(void *regs)48 static inline void sign_compat_exception_context_unsafe(void *regs)
49 {
50 return sign_compat_exception_context_asm(regs);
51 }
52
auth_compat_exception_context_unsafe(void *regs)53 static inline void auth_compat_exception_context_unsafe(void *regs)
54 {
55 return auth_compat_exception_context_asm(regs);
56 }
57
sign_exception_context_unsafe(void *regs)58 static inline void sign_exception_context_unsafe(void *regs)
59 {
60 if (compat_user_mode((struct pt_regs *)regs)) {
61 sign_compat_exception_context_asm(regs);
62 } else {
63 sign_exception_context_asm(regs);
64 }
65 }
66
auth_exception_context_unsafe(void *regs)67 static inline void auth_exception_context_unsafe(void *regs)
68 {
69 if (compat_user_mode((struct pt_regs *)regs)) {
70 auth_compat_exception_context_asm(regs);
71 } else {
72 auth_exception_context_asm(regs);
73 }
74 }
75
76 #define resign_compat_exception_context_start(regs) \
77 do { \
78 unsigned long irq_flags; \
79 local_irq_save(irq_flags); \
80 auth_compat_exception_context_asm(regs);
81
82 #define resign_compat_exception_context_end(regs) \
83 sign_compat_exception_context_asm(regs); \
84 local_irq_restore(irq_flags); \
85 } while (0)
86
87 #define resign_exception_context_start(regs) \
88 do { \
89 unsigned long irq_flags; \
90 local_irq_save(irq_flags); \
91 auth_exception_context_unsafe(regs);
92
93 #define resign_exception_context_end(regs) \
94 sign_exception_context_unsafe(regs); \
95 local_irq_restore(irq_flags); \
96 } while (0)
97
98 #define sign_exception_context_start(regs) \
99 do { \
100 unsigned long irq_flags; \
101 local_irq_save(irq_flags);
102
103 #define sign_exception_context_end(regs) \
104 sign_exception_context_unsafe(regs); \
105 local_irq_restore(irq_flags); \
106 } while (0)
107
108 void sign_compat_exception_context(void *regs);
109 void auth_compat_exception_context(void *regs);
110 void sign_exception_context(void *regs);
111 void auth_exception_context(void *regs);
112
113 int set_compat_exception_context_register(void *regs, enum pac_pt_regs regs_enum, u64 val);
114 void set_compat_exception_context_register_index(struct pt_regs *regs, int index, u64 val);
115 int set_exception_context_register(void *regs, enum pac_pt_regs regs_enum, u64 val);
116 void set_exception_context_register_index(struct pt_regs *regs, int index, u64 val);
117
118 #endif /* __POINTER_AUTH_CONTEXT_H */
119
120