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 __POINTER_AUTH_CONTEXT_H
7419b0af8Sopenharmony_ci#define __POINTER_AUTH_CONTEXT_H
8419b0af8Sopenharmony_ci
9419b0af8Sopenharmony_cistruct pt_regs;
10419b0af8Sopenharmony_ci
11419b0af8Sopenharmony_cienum pac_pt_regs {
12419b0af8Sopenharmony_ci	REGS_X16 = 0,
13419b0af8Sopenharmony_ci	REGS_X17,
14419b0af8Sopenharmony_ci	REGS_LR,
15419b0af8Sopenharmony_ci	REGS_SP,
16419b0af8Sopenharmony_ci	REGS_PC,
17419b0af8Sopenharmony_ci	REGS_PSTATE,
18419b0af8Sopenharmony_ci};
19419b0af8Sopenharmony_ci
20419b0af8Sopenharmony_civoid sign_thread_context(void *cpu_context);
21419b0af8Sopenharmony_civoid auth_thread_context(void *cpu_context);
22419b0af8Sopenharmony_ci
23419b0af8Sopenharmony_civoid sign_exception_context_asm(void *regs);
24419b0af8Sopenharmony_civoid auth_exception_context_asm(void *regs);
25419b0af8Sopenharmony_ci
26419b0af8Sopenharmony_ciint set_exception_context_register_asm(void *regs, int offset, u64 val);
27419b0af8Sopenharmony_ci
28419b0af8Sopenharmony_ci#ifdef CONFIG_COMPAT
29419b0af8Sopenharmony_civoid sign_compat_exception_context_asm(void *regs);
30419b0af8Sopenharmony_civoid auth_compat_exception_context_asm(void *regs);
31419b0af8Sopenharmony_ci
32419b0af8Sopenharmony_ciint set_compat_exception_context_register_asm(void *regs, int offset, u64 val);
33419b0af8Sopenharmony_ci#else
34419b0af8Sopenharmony_cistatic inline void sign_compat_exception_context_asm(void *regs)
35419b0af8Sopenharmony_ci{
36419b0af8Sopenharmony_ci}
37419b0af8Sopenharmony_ci
38419b0af8Sopenharmony_cistatic inline void auth_compat_exception_context_asm(void *regs)
39419b0af8Sopenharmony_ci{
40419b0af8Sopenharmony_ci}
41419b0af8Sopenharmony_ci
42419b0af8Sopenharmony_cistatic inline int set_compat_exception_context_register_asm(void *regs, int offset, u64 val)
43419b0af8Sopenharmony_ci{
44419b0af8Sopenharmony_ci	return 0;
45419b0af8Sopenharmony_ci}
46419b0af8Sopenharmony_ci#endif
47419b0af8Sopenharmony_ci
48419b0af8Sopenharmony_cistatic inline void sign_compat_exception_context_unsafe(void *regs)
49419b0af8Sopenharmony_ci{
50419b0af8Sopenharmony_ci	return sign_compat_exception_context_asm(regs);
51419b0af8Sopenharmony_ci}
52419b0af8Sopenharmony_ci
53419b0af8Sopenharmony_cistatic inline void auth_compat_exception_context_unsafe(void *regs)
54419b0af8Sopenharmony_ci{
55419b0af8Sopenharmony_ci	return auth_compat_exception_context_asm(regs);
56419b0af8Sopenharmony_ci}
57419b0af8Sopenharmony_ci
58419b0af8Sopenharmony_cistatic inline void sign_exception_context_unsafe(void *regs)
59419b0af8Sopenharmony_ci{
60419b0af8Sopenharmony_ci	if (compat_user_mode((struct pt_regs *)regs)) {
61419b0af8Sopenharmony_ci		sign_compat_exception_context_asm(regs);
62419b0af8Sopenharmony_ci	} else {
63419b0af8Sopenharmony_ci		sign_exception_context_asm(regs);
64419b0af8Sopenharmony_ci	}
65419b0af8Sopenharmony_ci}
66419b0af8Sopenharmony_ci
67419b0af8Sopenharmony_cistatic inline void auth_exception_context_unsafe(void *regs)
68419b0af8Sopenharmony_ci{
69419b0af8Sopenharmony_ci	if (compat_user_mode((struct pt_regs *)regs)) {
70419b0af8Sopenharmony_ci		auth_compat_exception_context_asm(regs);
71419b0af8Sopenharmony_ci	} else {
72419b0af8Sopenharmony_ci		auth_exception_context_asm(regs);
73419b0af8Sopenharmony_ci	}
74419b0af8Sopenharmony_ci}
75419b0af8Sopenharmony_ci
76419b0af8Sopenharmony_ci#define resign_compat_exception_context_start(regs)		\
77419b0af8Sopenharmony_cido {								\
78419b0af8Sopenharmony_ci	unsigned long irq_flags;				\
79419b0af8Sopenharmony_ci	local_irq_save(irq_flags);				\
80419b0af8Sopenharmony_ci	auth_compat_exception_context_asm(regs);
81419b0af8Sopenharmony_ci
82419b0af8Sopenharmony_ci#define resign_compat_exception_context_end(regs)		\
83419b0af8Sopenharmony_ci	sign_compat_exception_context_asm(regs);		\
84419b0af8Sopenharmony_ci	local_irq_restore(irq_flags);				\
85419b0af8Sopenharmony_ci} while (0)
86419b0af8Sopenharmony_ci
87419b0af8Sopenharmony_ci#define resign_exception_context_start(regs)			\
88419b0af8Sopenharmony_cido {								\
89419b0af8Sopenharmony_ci	unsigned long irq_flags;				\
90419b0af8Sopenharmony_ci	local_irq_save(irq_flags);				\
91419b0af8Sopenharmony_ci	auth_exception_context_unsafe(regs);
92419b0af8Sopenharmony_ci
93419b0af8Sopenharmony_ci#define resign_exception_context_end(regs)			\
94419b0af8Sopenharmony_ci	sign_exception_context_unsafe(regs);				\
95419b0af8Sopenharmony_ci	local_irq_restore(irq_flags);				\
96419b0af8Sopenharmony_ci} while (0)
97419b0af8Sopenharmony_ci
98419b0af8Sopenharmony_ci#define sign_exception_context_start(regs)			\
99419b0af8Sopenharmony_cido {								\
100419b0af8Sopenharmony_ci	unsigned long irq_flags;				\
101419b0af8Sopenharmony_ci	local_irq_save(irq_flags);
102419b0af8Sopenharmony_ci
103419b0af8Sopenharmony_ci#define sign_exception_context_end(regs)			\
104419b0af8Sopenharmony_ci	sign_exception_context_unsafe(regs);				\
105419b0af8Sopenharmony_ci	local_irq_restore(irq_flags);				\
106419b0af8Sopenharmony_ci} while (0)
107419b0af8Sopenharmony_ci
108419b0af8Sopenharmony_civoid sign_compat_exception_context(void *regs);
109419b0af8Sopenharmony_civoid auth_compat_exception_context(void *regs);
110419b0af8Sopenharmony_civoid sign_exception_context(void *regs);
111419b0af8Sopenharmony_civoid auth_exception_context(void *regs);
112419b0af8Sopenharmony_ci
113419b0af8Sopenharmony_ciint set_compat_exception_context_register(void *regs, enum pac_pt_regs regs_enum, u64 val);
114419b0af8Sopenharmony_civoid set_compat_exception_context_register_index(struct pt_regs *regs, int index, u64 val);
115419b0af8Sopenharmony_ciint set_exception_context_register(void *regs, enum pac_pt_regs regs_enum, u64 val);
116419b0af8Sopenharmony_civoid set_exception_context_register_index(struct pt_regs *regs, int index, u64 val);
117419b0af8Sopenharmony_ci
118419b0af8Sopenharmony_ci#endif /* __POINTER_AUTH_CONTEXT_H */
119419b0af8Sopenharmony_ci
120