1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * Copyright (c) 2023 Huawei Device Co., Ltd.
4  */
5 
6 #ifndef __POINTER_AUTH_COMMON_H__
7 #define __POINTER_AUTH_COMMON_H__
8 
9 #define is_addr_error(addr) (((addr) >> 48) ^ 0xffff)
10 
11 #define pauth_sign(type, key, addr, mod) \
12 	pauth_common(pac, type, key, addr, mod)
13 
14 #define pauth_validate(type, key, addr, mod) \
15 	pauth_common(aut, type, key, addr, mod)
16 
17 #define pauth_strip(type, addr) \
18 ({ \
19 	const void *__addr = (addr); \
20 \
21 	asm ("xpac" #type " %0\n" : "+r" (__addr)); \
22 	(typeof (addr))__addr; \
23 })
24 
25 #define pauth_hash(addr, mod) ((unsigned int) (pauth_pacga(addr, mod) >> 32))
26 
27 #define pauth_common(prefix, type, key, addr, mod) \
28 ({ \
29 	const void *__addr = (addr); \
30 	unsigned long __mod = (unsigned long)(mod); \
31 \
32 	if (__builtin_constant_p(mod) && (__mod == 0)) \
33 		asm (#prefix #type "z" #key " %0\n" : "+r" (__addr)); \
34 	else \
35 		asm (#prefix #type #key " %0, %1\n" : "+r" (__addr) : \
36 			"r" (__mod)); \
37 	(typeof (addr))(__addr); \
38 })
39 
40 #define pauth_get_raw_data(addr) \
41 ({ \
42 	const void *__addr; \
43 	asm ("mov %0, %1\n" : "=&r" (__addr) : \
44 		"r" (addr)); \
45 	(void *)(__addr); \
46 })
47 
48 #define pauth_sign_function(fun, mod, key) \
49 ({ \
50 	const void *__fun = (fun); \
51 	unsigned long __mod = (unsigned long)(mod); \
52 	asm ("paci" #key " %0, %1\n" : "+r" (__fun) :   \
53 		"r" (__mod));  \
54 	(void *)(__fun); \
55 })
56 
57 #define pauth_pacda(addr, mod)	pauth_common(pac, d, a, addr, mod)
58 
59 #define pauth_pacdb(addr, mod)	pauth_common(pac, d, b, addr, mod)
60 
61 #define pauth_pacia(addr, mod)	pauth_common(pac, i, a, addr, mod)
62 
63 #define pauth_pacib(addr, mod)	pauth_common(pac, i, b, addr, mod)
64 
65 #define pauth_pacga(addr, mod) \
66 ({ \
67 	const void *__addr = (addr); \
68 	unsigned long __mod = (unsigned long)(mod); \
69 	unsigned long __pac; \
70 \
71 	asm ("pacga %0, %1, %2\n" : "=r" (__pac) : "r" (__addr), \
72 		"r" (__mod)); \
73 	__pac; \
74 })
75 
76 #define pauth_autda(addr, mod)	pauth_common(aut, d, a, addr, mod)
77 
78 #define pauth_autdb(addr, mod)	pauth_common(aut, d, b, addr, mod)
79 
80 #define pauth_autia(addr, mod)	pauth_common(aut, i, a, addr, mod)
81 
82 #define pauth_autib(addr, mod)	pauth_common(aut, i, b, addr, mod)
83 
84 #define pauth_xpacd(addr)		pauth_strip(d, addr)
85 
86 #define pauth_xpaci(addr)		pauth_strip(i, addr)
87 
88 #endif /* __POINTER_AUTH_COMMON_H__ */
89