1 #ifndef __ASM_ASM_UACCESS_H
2 #define __ASM_ASM_UACCESS_H
3 
4 #include <asm/alternative.h>
5 #include <asm/kernel-pgtable.h>
6 #include <asm/sysreg.h>
7 #include <asm/assembler.h>
8 
9 /*
10  * User access enabling/disabling macros.
11  */
12 #ifdef CONFIG_ARM64_SW_TTBR0_PAN
13 	.macro	__uaccess_ttbr0_disable, tmp1
14 	mrs	\tmp1, ttbr1_el1		// swapper_pg_dir
15 	add	\tmp1, \tmp1, #SWAPPER_DIR_SIZE	// reserved_ttbr0 at the end of swapper_pg_dir
16 	msr	ttbr0_el1, \tmp1		// set reserved TTBR0_EL1
17 	isb
18 	.endm
19 
20 	.macro	__uaccess_ttbr0_enable, tmp1
21 	get_thread_info \tmp1
22 	ldr	\tmp1, [\tmp1, #TSK_TI_TTBR0]	// load saved TTBR0_EL1
23 	msr	ttbr0_el1, \tmp1		// set the non-PAN TTBR0_EL1
24 	isb
25 	.endm
26 
27 	.macro	uaccess_ttbr0_disable, tmp1
28 alternative_if_not ARM64_HAS_PAN
29 	__uaccess_ttbr0_disable \tmp1
30 alternative_else_nop_endif
31 	.endm
32 
33 	.macro	uaccess_ttbr0_enable, tmp1, tmp2
34 alternative_if_not ARM64_HAS_PAN
35 	save_and_disable_irq \tmp2		// avoid preemption
36 	__uaccess_ttbr0_enable \tmp1
37 	restore_irq \tmp2
38 alternative_else_nop_endif
39 	.endm
40 #else
41 	.macro	uaccess_ttbr0_disable, tmp1
42 	.endm
43 
44 	.macro	uaccess_ttbr0_enable, tmp1, tmp2
45 	.endm
46 #endif
47 
48 /*
49  * These macros are no-ops when UAO is present.
50  */
51 	.macro	uaccess_disable_not_uao, tmp1
52 	uaccess_ttbr0_disable \tmp1
53 alternative_if ARM64_ALT_PAN_NOT_UAO
54 	SET_PSTATE_PAN(1)
55 alternative_else_nop_endif
56 	.endm
57 
58 	.macro	uaccess_enable_not_uao, tmp1, tmp2
59 	uaccess_ttbr0_enable \tmp1, \tmp2
60 alternative_if ARM64_ALT_PAN_NOT_UAO
61 	SET_PSTATE_PAN(0)
62 alternative_else_nop_endif
63 	.endm
64 
65 /*
66  * Remove the address tag from a virtual address, if present.
67  */
68 	.macro	clear_address_tag, dst, addr
69 	tst	\addr, #(1 << 55)
70 	bic	\dst, \addr, #(0xff << 56)
71 	csel	\dst, \dst, \addr, eq
72 	.endm
73 
74 #endif
75