1419b0af8Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later
2419b0af8Sopenharmony_ci/*
3419b0af8Sopenharmony_ci * Copyright (c) 2023 Huawei Device Co., Ltd.
4419b0af8Sopenharmony_ci */
5419b0af8Sopenharmony_ci
6419b0af8Sopenharmony_ci#ifndef __ASM_POINTER_AUTH_CONTEXT_H
7419b0af8Sopenharmony_ci#define __ASM_POINTER_AUTH_CONTEXT_H
8419b0af8Sopenharmony_ci
9419b0af8Sopenharmony_ci#include <asm/asm-offsets.h>
10419b0af8Sopenharmony_ci#include <asm/sysreg.h>
11419b0af8Sopenharmony_ci
12419b0af8Sopenharmony_ci	/* Compute and store hash value of cpu context. */
13419b0af8Sopenharmony_ci	.macro sign_thread_context_common, tmp1=x0, tmp2=x1, tmp3=x2
14419b0af8Sopenharmony_ci	pacga	\tmp2, \tmp1, \tmp2
15419b0af8Sopenharmony_ci	pacga	\tmp2, \tmp3, \tmp2
16419b0af8Sopenharmony_ci	str	\tmp2, [\tmp1, CPU_CONTEXT_PAC_HASH]
17419b0af8Sopenharmony_ci	.endm
18419b0af8Sopenharmony_ci
19419b0af8Sopenharmony_ci	/* Compute and auth hash value of cpu context. */
20419b0af8Sopenharmony_ci	.macro auth_thread_context_common, tmp1=x0, tmp2=x1, tmp3=x2
21419b0af8Sopenharmony_ci	pacga	\tmp2, \tmp1, \tmp2
22419b0af8Sopenharmony_ci	pacga	\tmp2, \tmp3, \tmp2
23419b0af8Sopenharmony_ci	ldr	\tmp3, [\tmp1, CPU_CONTEXT_PAC_HASH]
24419b0af8Sopenharmony_ci	cmp	\tmp2, \tmp3
25419b0af8Sopenharmony_ci	b.ne	.Lthread_context_pac_panic\@
26419b0af8Sopenharmony_ci	b	.Lauth_thread_context_done\@
27419b0af8Sopenharmony_ci.Lthread_context_pac_panic\@:
28419b0af8Sopenharmony_ci	adrp	x0, .Lthread_context_pac_str
29419b0af8Sopenharmony_ci	add	x0, x0, :lo12:.Lthread_context_pac_str
30419b0af8Sopenharmony_ci	bl	panic
31419b0af8Sopenharmony_ci.Lauth_thread_context_done\@:
32419b0af8Sopenharmony_ci	.endm
33419b0af8Sopenharmony_ci
34419b0af8Sopenharmony_ci	/* Compute and store hash value of the regs. */
35419b0af8Sopenharmony_ci	.macro sign_exception_context_common, tmp1=x0, tmp2=x1, tmp3=x2, tmp4=x3, tmp5=x4, tmp6=x5, tmp7=x6
36419b0af8Sopenharmony_ci	pacga	\tmp2, \tmp1, \tmp2
37419b0af8Sopenharmony_ci	pacga	\tmp2, \tmp3, \tmp2
38419b0af8Sopenharmony_ci	pacga	\tmp2, \tmp4, \tmp2
39419b0af8Sopenharmony_ci	pacga	\tmp2, \tmp5, \tmp2
40419b0af8Sopenharmony_ci	pacga	\tmp2, \tmp6, \tmp2
41419b0af8Sopenharmony_ci	pacga	\tmp2, \tmp7, \tmp2
42419b0af8Sopenharmony_ci	str	\tmp2, [\tmp1, S_PAC_HASH]
43419b0af8Sopenharmony_ci	.endm
44419b0af8Sopenharmony_ci
45419b0af8Sopenharmony_ci	/* Compute and auth hash value of the regs. */
46419b0af8Sopenharmony_ci	.macro auth_exception_context_common, tmp1=x0, tmp2=x1, tmp3=x2, tmp4=x3, tmp5=x4, tmp6=x5, tmp7=x6
47419b0af8Sopenharmony_ci	pacga	\tmp2, \tmp1, \tmp2
48419b0af8Sopenharmony_ci	pacga	\tmp2, \tmp3, \tmp2
49419b0af8Sopenharmony_ci	pacga	\tmp2, \tmp4, \tmp2
50419b0af8Sopenharmony_ci	pacga	\tmp2, \tmp5, \tmp2
51419b0af8Sopenharmony_ci	pacga	\tmp2, \tmp6, \tmp2
52419b0af8Sopenharmony_ci	pacga	\tmp2, \tmp7, \tmp2
53419b0af8Sopenharmony_ci	ldr	\tmp3, [\tmp1, S_PAC_HASH]
54419b0af8Sopenharmony_ci	cmp	\tmp2, \tmp3
55419b0af8Sopenharmony_ci	b.ne	.Lpt_regs_pac_panic\@
56419b0af8Sopenharmony_ci	b	.Lauth_exception_context_done\@
57419b0af8Sopenharmony_ci.Lpt_regs_pac_panic\@:
58419b0af8Sopenharmony_ci	adrp	x0, .Lpt_regs_pac_panic_str
59419b0af8Sopenharmony_ci	add	x0, x0, :lo12:.Lpt_regs_pac_panic_str
60419b0af8Sopenharmony_ci	bl	panic
61419b0af8Sopenharmony_ci.Lauth_exception_context_done\@:
62419b0af8Sopenharmony_ci	.endm
63419b0af8Sopenharmony_ci
64419b0af8Sopenharmony_ci.Lpt_regs_pac_panic_str:
65419b0af8Sopenharmony_ci	.asciz	"Failed to match pac hash of exception context!\n"
66419b0af8Sopenharmony_ci	.align 2
67419b0af8Sopenharmony_ci
68419b0af8Sopenharmony_ci.Lthread_context_pac_str:
69419b0af8Sopenharmony_ci	.asciz	"Failed to match pac hash of cpu context!\n"
70419b0af8Sopenharmony_ci	.align 2
71419b0af8Sopenharmony_ci
72419b0af8Sopenharmony_ci	.macro pac_cpu_context sign_or_auth
73419b0af8Sopenharmony_ci	.if	\sign_or_auth == 0
74419b0af8Sopenharmony_ci	/* x0: base of curr task */
75419b0af8Sopenharmony_ci	mov	x2, x0
76419b0af8Sopenharmony_ci	.else
77419b0af8Sopenharmony_ci	/* x1: base of next task */
78419b0af8Sopenharmony_ci	mov	x2, x1
79419b0af8Sopenharmony_ci	.endif
80419b0af8Sopenharmony_ci	add	x2, x2, #THREAD_CPU_CONTEXT
81419b0af8Sopenharmony_ci	/* sign sp, lr of cpu context. */
82419b0af8Sopenharmony_ci	mov	x3, lr
83419b0af8Sopenharmony_ci	mov	x4, x9
84419b0af8Sopenharmony_ci	.if	\sign_or_auth == 0
85419b0af8Sopenharmony_ci	sign_thread_context_common x2, x3, x4
86419b0af8Sopenharmony_ci	.else
87419b0af8Sopenharmony_ci	auth_thread_context_common x2, x3, x4
88419b0af8Sopenharmony_ci	.endif
89419b0af8Sopenharmony_ci	.endm
90419b0af8Sopenharmony_ci
91419b0af8Sopenharmony_ci	.macro sign_cpu_context sign=0
92419b0af8Sopenharmony_ci	pac_cpu_context \sign
93419b0af8Sopenharmony_ci	.endm
94419b0af8Sopenharmony_ci
95419b0af8Sopenharmony_ci	.macro auth_cpu_context auth=1
96419b0af8Sopenharmony_ci	pac_cpu_context \auth
97419b0af8Sopenharmony_ci	.endm
98419b0af8Sopenharmony_ci
99419b0af8Sopenharmony_ci	.macro prepare_compat_pt_regs, sign_or_auth
100419b0af8Sopenharmony_ci	/* base of pt_regs */
101419b0af8Sopenharmony_ci	mov	x23, sp
102419b0af8Sopenharmony_ci	mov	x24, #0
103419b0af8Sopenharmony_ci	mov	x25, #0
104419b0af8Sopenharmony_ci	/* sign lr, sp, pc, pstate of compat task */
105419b0af8Sopenharmony_ci	mov	x26, x14
106419b0af8Sopenharmony_ci	mov	x27, x13
107419b0af8Sopenharmony_ci	mrs	x20, elr_el1
108419b0af8Sopenharmony_ci	.if	\sign_or_auth == 0
109419b0af8Sopenharmony_ci	mrs	x21, spsr_el1
110419b0af8Sopenharmony_ci	.else
111419b0af8Sopenharmony_ci	mov	x21, x22
112419b0af8Sopenharmony_ci	.endif
113419b0af8Sopenharmony_ci	.endm
114419b0af8Sopenharmony_ci
115419b0af8Sopenharmony_ci	.macro prepare_pt_regs, el, sign_or_auth
116419b0af8Sopenharmony_ci	/* base of pt_regs */
117419b0af8Sopenharmony_ci	mov	x23, sp
118419b0af8Sopenharmony_ci	/* sign x16, x17, lr, sp, pc, pstate of task */
119419b0af8Sopenharmony_ci	mov	x24, x16
120419b0af8Sopenharmony_ci	mov	x25, x17
121419b0af8Sopenharmony_ci	.if	\sign_or_auth == 0
122419b0af8Sopenharmony_ci	mov	x26, lr
123419b0af8Sopenharmony_ci	.else
124419b0af8Sopenharmony_ci	ldr	x26, [x23, #S_LR]
125419b0af8Sopenharmony_ci	.endif
126419b0af8Sopenharmony_ci	.if	\el == 0
127419b0af8Sopenharmony_ci	mrs	x27, sp_el0
128419b0af8Sopenharmony_ci	.else
129419b0af8Sopenharmony_ci	add	x27, x23, #S_FRAME_SIZE
130419b0af8Sopenharmony_ci	.endif
131419b0af8Sopenharmony_ci	mrs	x20, elr_el1
132419b0af8Sopenharmony_ci	.if	\sign_or_auth == 0
133419b0af8Sopenharmony_ci	mrs	x21, spsr_el1
134419b0af8Sopenharmony_ci	.else
135419b0af8Sopenharmony_ci	mov	x21, x22
136419b0af8Sopenharmony_ci	.endif
137419b0af8Sopenharmony_ci	.endm
138419b0af8Sopenharmony_ci
139419b0af8Sopenharmony_ci	.macro pac_pt_regs, el, sign_or_auth
140419b0af8Sopenharmony_ci	.if	\el == 0
141419b0af8Sopenharmony_ci	/* Test the task is in the mode of 32-bit or 64-bit */
142419b0af8Sopenharmony_ci	mrs	x23, spsr_el1
143419b0af8Sopenharmony_ci	mov	x24, #(PSR_MODE32_BIT | PSR_MODE_MASK)
144419b0af8Sopenharmony_ci	mov	x25, #(PSR_MODE32_BIT | PSR_MODE_EL0t)
145419b0af8Sopenharmony_ci	and	x23, x23, x24
146419b0af8Sopenharmony_ci	sub	x23, x23, x25
147419b0af8Sopenharmony_ci	cbnz	x23, .Lis_not_compat_task\@
148419b0af8Sopenharmony_ci	/* Task in 32-bit mode */
149419b0af8Sopenharmony_ci	prepare_compat_pt_regs \sign_or_auth
150419b0af8Sopenharmony_ci	b	.Lpac_handle\@
151419b0af8Sopenharmony_ci	.endif
152419b0af8Sopenharmony_ci	/* Task in 64-bit mode */
153419b0af8Sopenharmony_ci.Lis_not_compat_task\@:
154419b0af8Sopenharmony_ci	prepare_pt_regs \el, \sign_or_auth
155419b0af8Sopenharmony_ci	/* Call the sign or auth function. */
156419b0af8Sopenharmony_ci.Lpac_handle\@:
157419b0af8Sopenharmony_ci	.if	\sign_or_auth == 0
158419b0af8Sopenharmony_ci	sign_exception_context_common x23, x24, x25, x26, x27, x20, x21
159419b0af8Sopenharmony_ci	.else
160419b0af8Sopenharmony_ci	auth_exception_context_common x23, x24, x25, x26, x27, x20, x21
161419b0af8Sopenharmony_ci	.endif
162419b0af8Sopenharmony_ci	.endm
163419b0af8Sopenharmony_ci
164419b0af8Sopenharmony_ci	.macro sign_pt_regs, el, sign=0
165419b0af8Sopenharmony_ci	pac_pt_regs \el, \sign
166419b0af8Sopenharmony_ci	.endm
167419b0af8Sopenharmony_ci
168419b0af8Sopenharmony_ci	.macro auth_pt_regs, el, auth=1
169419b0af8Sopenharmony_ci	pac_pt_regs \el, \auth
170419b0af8Sopenharmony_ci	.endm
171419b0af8Sopenharmony_ci
172419b0af8Sopenharmony_ci#endif /* __ASM_POINTER_AUTH_CONTEXT_H */
173