1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * Copyright (c) 2023 Huawei Device Co., Ltd.
4  */
5 
6 #ifndef __ASM_POINTER_AUTH_CONTEXT_H
7 #define __ASM_POINTER_AUTH_CONTEXT_H
8 
9 #include <asm/asm-offsets.h>
10 #include <asm/sysreg.h>
11 
12 	/* Compute and store hash value of cpu context. */
13 	.macro sign_thread_context_common, tmp1=x0, tmp2=x1, tmp3=x2
14 	pacga	\tmp2, \tmp1, \tmp2
15 	pacga	\tmp2, \tmp3, \tmp2
16 	str	\tmp2, [\tmp1, CPU_CONTEXT_PAC_HASH]
17 	.endm
18 
19 	/* Compute and auth hash value of cpu context. */
20 	.macro auth_thread_context_common, tmp1=x0, tmp2=x1, tmp3=x2
21 	pacga	\tmp2, \tmp1, \tmp2
22 	pacga	\tmp2, \tmp3, \tmp2
23 	ldr	\tmp3, [\tmp1, CPU_CONTEXT_PAC_HASH]
24 	cmp	\tmp2, \tmp3
25 	b.ne	.Lthread_context_pac_panic\@
26 	b	.Lauth_thread_context_done\@
27 .Lthread_context_pac_panic\@:
28 	adrp	x0, .Lthread_context_pac_str
29 	add	x0, x0, :lo12:.Lthread_context_pac_str
30 	bl	panic
31 .Lauth_thread_context_done\@:
32 	.endm
33 
34 	/* Compute and store hash value of the regs. */
35 	.macro sign_exception_context_common, tmp1=x0, tmp2=x1, tmp3=x2, tmp4=x3, tmp5=x4, tmp6=x5, tmp7=x6
36 	pacga	\tmp2, \tmp1, \tmp2
37 	pacga	\tmp2, \tmp3, \tmp2
38 	pacga	\tmp2, \tmp4, \tmp2
39 	pacga	\tmp2, \tmp5, \tmp2
40 	pacga	\tmp2, \tmp6, \tmp2
41 	pacga	\tmp2, \tmp7, \tmp2
42 	str	\tmp2, [\tmp1, S_PAC_HASH]
43 	.endm
44 
45 	/* Compute and auth hash value of the regs. */
46 	.macro auth_exception_context_common, tmp1=x0, tmp2=x1, tmp3=x2, tmp4=x3, tmp5=x4, tmp6=x5, tmp7=x6
47 	pacga	\tmp2, \tmp1, \tmp2
48 	pacga	\tmp2, \tmp3, \tmp2
49 	pacga	\tmp2, \tmp4, \tmp2
50 	pacga	\tmp2, \tmp5, \tmp2
51 	pacga	\tmp2, \tmp6, \tmp2
52 	pacga	\tmp2, \tmp7, \tmp2
53 	ldr	\tmp3, [\tmp1, S_PAC_HASH]
54 	cmp	\tmp2, \tmp3
55 	b.ne	.Lpt_regs_pac_panic\@
56 	b	.Lauth_exception_context_done\@
57 .Lpt_regs_pac_panic\@:
58 	adrp	x0, .Lpt_regs_pac_panic_str
59 	add	x0, x0, :lo12:.Lpt_regs_pac_panic_str
60 	bl	panic
61 .Lauth_exception_context_done\@:
62 	.endm
63 
64 .Lpt_regs_pac_panic_str:
65 	.asciz	"Failed to match pac hash of exception context!\n"
66 	.align 2
67 
68 .Lthread_context_pac_str:
69 	.asciz	"Failed to match pac hash of cpu context!\n"
70 	.align 2
71 
72 	.macro pac_cpu_context sign_or_auth
73 	.if	\sign_or_auth == 0
74 	/* x0: base of curr task */
75 	mov	x2, x0
76 	.else
77 	/* x1: base of next task */
78 	mov	x2, x1
79 	.endif
80 	add	x2, x2, #THREAD_CPU_CONTEXT
81 	/* sign sp, lr of cpu context. */
82 	mov	x3, lr
83 	mov	x4, x9
84 	.if	\sign_or_auth == 0
85 	sign_thread_context_common x2, x3, x4
86 	.else
87 	auth_thread_context_common x2, x3, x4
88 	.endif
89 	.endm
90 
91 	.macro sign_cpu_context sign=0
92 	pac_cpu_context \sign
93 	.endm
94 
95 	.macro auth_cpu_context auth=1
96 	pac_cpu_context \auth
97 	.endm
98 
99 	.macro prepare_compat_pt_regs, sign_or_auth
100 	/* base of pt_regs */
101 	mov	x23, sp
102 	mov	x24, #0
103 	mov	x25, #0
104 	/* sign lr, sp, pc, pstate of compat task */
105 	mov	x26, x14
106 	mov	x27, x13
107 	mrs	x20, elr_el1
108 	.if	\sign_or_auth == 0
109 	mrs	x21, spsr_el1
110 	.else
111 	mov	x21, x22
112 	.endif
113 	.endm
114 
115 	.macro prepare_pt_regs, el, sign_or_auth
116 	/* base of pt_regs */
117 	mov	x23, sp
118 	/* sign x16, x17, lr, sp, pc, pstate of task */
119 	mov	x24, x16
120 	mov	x25, x17
121 	.if	\sign_or_auth == 0
122 	mov	x26, lr
123 	.else
124 	ldr	x26, [x23, #S_LR]
125 	.endif
126 	.if	\el == 0
127 	mrs	x27, sp_el0
128 	.else
129 	add	x27, x23, #S_FRAME_SIZE
130 	.endif
131 	mrs	x20, elr_el1
132 	.if	\sign_or_auth == 0
133 	mrs	x21, spsr_el1
134 	.else
135 	mov	x21, x22
136 	.endif
137 	.endm
138 
139 	.macro pac_pt_regs, el, sign_or_auth
140 	.if	\el == 0
141 	/* Test the task is in the mode of 32-bit or 64-bit */
142 	mrs	x23, spsr_el1
143 	mov	x24, #(PSR_MODE32_BIT | PSR_MODE_MASK)
144 	mov	x25, #(PSR_MODE32_BIT | PSR_MODE_EL0t)
145 	and	x23, x23, x24
146 	sub	x23, x23, x25
147 	cbnz	x23, .Lis_not_compat_task\@
148 	/* Task in 32-bit mode */
149 	prepare_compat_pt_regs \sign_or_auth
150 	b	.Lpac_handle\@
151 	.endif
152 	/* Task in 64-bit mode */
153 .Lis_not_compat_task\@:
154 	prepare_pt_regs \el, \sign_or_auth
155 	/* Call the sign or auth function. */
156 .Lpac_handle\@:
157 	.if	\sign_or_auth == 0
158 	sign_exception_context_common x23, x24, x25, x26, x27, x20, x21
159 	.else
160 	auth_exception_context_common x23, x24, x25, x26, x27, x20, x21
161 	.endif
162 	.endm
163 
164 	.macro sign_pt_regs, el, sign=0
165 	pac_pt_regs \el, \sign
166 	.endm
167 
168 	.macro auth_pt_regs, el, auth=1
169 	pac_pt_regs \el, \auth
170 	.endm
171 
172 #endif /* __ASM_POINTER_AUTH_CONTEXT_H */
173