Commit | Line | Data |
---|---|---|
b2441318 | 1 | /* SPDX-License-Identifier: GPL-2.0 */ |
b4b8664d AV |
2 | #ifndef __ASM_ASM_UACCESS_H |
3 | #define __ASM_ASM_UACCESS_H | |
4 | ||
5 | #include <asm/alternative.h> | |
6 | #include <asm/kernel-pgtable.h> | |
b519538d | 7 | #include <asm/mmu.h> |
b4b8664d AV |
8 | #include <asm/sysreg.h> |
9 | #include <asm/assembler.h> | |
10 | ||
11 | /* | |
12 | * User access enabling/disabling macros. | |
13 | */ | |
14 | #ifdef CONFIG_ARM64_SW_TTBR0_PAN | |
15 | .macro __uaccess_ttbr0_disable, tmp1 | |
9dfe4828 | 16 | mrs \tmp1, ttbr1_el1 // swapper_pg_dir |
6b88a32c | 17 | bic \tmp1, \tmp1, #TTBR_ASID_MASK |
9dfe4828 SC |
18 | sub \tmp1, \tmp1, #RESERVED_TTBR0_SIZE // reserved_ttbr0 just before swapper_pg_dir |
19 | msr ttbr0_el1, \tmp1 // set reserved TTBR0_EL1 | |
b4b8664d | 20 | isb |
9dfe4828 | 21 | add \tmp1, \tmp1, #RESERVED_TTBR0_SIZE |
27a921e7 WD |
22 | msr ttbr1_el1, \tmp1 // set reserved ASID |
23 | isb | |
b4b8664d AV |
24 | .endm |
25 | ||
27a921e7 | 26 | .macro __uaccess_ttbr0_enable, tmp1, tmp2 |
4caf8758 | 27 | get_current_task \tmp1 |
b4b8664d | 28 | ldr \tmp1, [\tmp1, #TSK_TI_TTBR0] // load saved TTBR0_EL1 |
27a921e7 WD |
29 | mrs \tmp2, ttbr1_el1 |
30 | extr \tmp2, \tmp2, \tmp1, #48 | |
31 | ror \tmp2, \tmp2, #16 | |
32 | msr ttbr1_el1, \tmp2 // set the active ASID | |
33 | isb | |
b4b8664d AV |
34 | msr ttbr0_el1, \tmp1 // set the non-PAN TTBR0_EL1 |
35 | isb | |
36 | .endm | |
37 | ||
6b88a32c | 38 | .macro uaccess_ttbr0_disable, tmp1, tmp2 |
b4b8664d | 39 | alternative_if_not ARM64_HAS_PAN |
6b88a32c | 40 | save_and_disable_irq \tmp2 // avoid preemption |
b4b8664d | 41 | __uaccess_ttbr0_disable \tmp1 |
6b88a32c | 42 | restore_irq \tmp2 |
b4b8664d AV |
43 | alternative_else_nop_endif |
44 | .endm | |
45 | ||
27a921e7 | 46 | .macro uaccess_ttbr0_enable, tmp1, tmp2, tmp3 |
b4b8664d | 47 | alternative_if_not ARM64_HAS_PAN |
27a921e7 WD |
48 | save_and_disable_irq \tmp3 // avoid preemption |
49 | __uaccess_ttbr0_enable \tmp1, \tmp2 | |
50 | restore_irq \tmp3 | |
b4b8664d AV |
51 | alternative_else_nop_endif |
52 | .endm | |
53 | #else | |
6b88a32c | 54 | .macro uaccess_ttbr0_disable, tmp1, tmp2 |
b4b8664d AV |
55 | .endm |
56 | ||
27a921e7 | 57 | .macro uaccess_ttbr0_enable, tmp1, tmp2, tmp3 |
b4b8664d AV |
58 | .endm |
59 | #endif | |
60 | ||
e2a2190a MR |
61 | /* |
62 | * Generate the assembly for UAO alternatives with exception table entries. | |
63 | * This is complicated as there is no post-increment or pair versions of the | |
64 | * unprivileged instructions, and USER() only works for single instructions. | |
65 | */ | |
66 | #ifdef CONFIG_ARM64_UAO | |
67 | .macro uao_ldp l, reg1, reg2, addr, post_inc | |
68 | alternative_if_not ARM64_HAS_UAO | |
69 | 8888: ldp \reg1, \reg2, [\addr], \post_inc; | |
70 | 8889: nop; | |
71 | nop; | |
72 | alternative_else | |
73 | ldtr \reg1, [\addr]; | |
74 | ldtr \reg2, [\addr, #8]; | |
75 | add \addr, \addr, \post_inc; | |
76 | alternative_endif | |
77 | ||
78 | _asm_extable 8888b,\l; | |
79 | _asm_extable 8889b,\l; | |
80 | .endm | |
81 | ||
82 | .macro uao_stp l, reg1, reg2, addr, post_inc | |
83 | alternative_if_not ARM64_HAS_UAO | |
84 | 8888: stp \reg1, \reg2, [\addr], \post_inc; | |
85 | 8889: nop; | |
86 | nop; | |
87 | alternative_else | |
88 | sttr \reg1, [\addr]; | |
89 | sttr \reg2, [\addr, #8]; | |
90 | add \addr, \addr, \post_inc; | |
91 | alternative_endif | |
92 | ||
93 | _asm_extable 8888b,\l; | |
94 | _asm_extable 8889b,\l; | |
95 | .endm | |
96 | ||
97 | .macro uao_user_alternative l, inst, alt_inst, reg, addr, post_inc | |
98 | alternative_if_not ARM64_HAS_UAO | |
99 | 8888: \inst \reg, [\addr], \post_inc; | |
100 | nop; | |
101 | alternative_else | |
102 | \alt_inst \reg, [\addr]; | |
103 | add \addr, \addr, \post_inc; | |
104 | alternative_endif | |
105 | ||
106 | _asm_extable 8888b,\l; | |
107 | .endm | |
108 | #else | |
109 | .macro uao_ldp l, reg1, reg2, addr, post_inc | |
110 | USER(\l, ldp \reg1, \reg2, [\addr], \post_inc) | |
111 | .endm | |
112 | .macro uao_stp l, reg1, reg2, addr, post_inc | |
113 | USER(\l, stp \reg1, \reg2, [\addr], \post_inc) | |
114 | .endm | |
115 | .macro uao_user_alternative l, inst, alt_inst, reg, addr, post_inc | |
116 | USER(\l, \inst \reg, [\addr], \post_inc) | |
117 | .endm | |
118 | #endif | |
119 | ||
b4b8664d | 120 | #endif |