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
9struct pt_regs;
10
11enum pac_pt_regs {
12	REGS_X16 = 0,
13	REGS_X17,
14	REGS_LR,
15	REGS_SP,
16	REGS_PC,
17	REGS_PSTATE,
18};
19
20void sign_thread_context(void *cpu_context);
21void auth_thread_context(void *cpu_context);
22
23void sign_exception_context_asm(void *regs);
24void auth_exception_context_asm(void *regs);
25
26int set_exception_context_register_asm(void *regs, int offset, u64 val);
27
28#ifdef CONFIG_COMPAT
29void sign_compat_exception_context_asm(void *regs);
30void auth_compat_exception_context_asm(void *regs);
31
32int set_compat_exception_context_register_asm(void *regs, int offset, u64 val);
33#else
34static inline void sign_compat_exception_context_asm(void *regs)
35{
36}
37
38static inline void auth_compat_exception_context_asm(void *regs)
39{
40}
41
42static inline int set_compat_exception_context_register_asm(void *regs, int offset, u64 val)
43{
44	return 0;
45}
46#endif
47
48static inline void sign_compat_exception_context_unsafe(void *regs)
49{
50	return sign_compat_exception_context_asm(regs);
51}
52
53static inline void auth_compat_exception_context_unsafe(void *regs)
54{
55	return auth_compat_exception_context_asm(regs);
56}
57
58static 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
67static 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)		\
77do {								\
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)			\
88do {								\
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)			\
99do {								\
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
108void sign_compat_exception_context(void *regs);
109void auth_compat_exception_context(void *regs);
110void sign_exception_context(void *regs);
111void auth_exception_context(void *regs);
112
113int set_compat_exception_context_register(void *regs, enum pac_pt_regs regs_enum, u64 val);
114void set_compat_exception_context_register_index(struct pt_regs *regs, int index, u64 val);
115int set_exception_context_register(void *regs, enum pac_pt_regs regs_enum, u64 val);
116void set_exception_context_register_index(struct pt_regs *regs, int index, u64 val);
117
118#endif /* __POINTER_AUTH_CONTEXT_H */
119
120