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