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