Linux 6.7-rc7
[linux-modified.git] / arch / arm64 / include / asm / asm-uaccess.h
1 /* SPDX-License-Identifier: GPL-2.0 */
2 #ifndef __ASM_ASM_UACCESS_H
3 #define __ASM_ASM_UACCESS_H
4
5 #include <asm/alternative-macros.h>
6 #include <asm/asm-extable.h>
7 #include <asm/assembler.h>
8 #include <asm/kernel-pgtable.h>
9 #include <asm/mmu.h>
10 #include <asm/sysreg.h>
11
12 /*
13  * User access enabling/disabling macros.
14  */
15 #ifdef CONFIG_ARM64_SW_TTBR0_PAN
16         .macro  __uaccess_ttbr0_disable, tmp1
17         mrs     \tmp1, ttbr1_el1                        // swapper_pg_dir
18         bic     \tmp1, \tmp1, #TTBR_ASID_MASK
19         sub     \tmp1, \tmp1, #RESERVED_SWAPPER_OFFSET  // reserved_pg_dir
20         msr     ttbr0_el1, \tmp1                        // set reserved TTBR0_EL1
21         add     \tmp1, \tmp1, #RESERVED_SWAPPER_OFFSET
22         msr     ttbr1_el1, \tmp1                // set reserved ASID
23         isb
24         .endm
25
26         .macro  __uaccess_ttbr0_enable, tmp1, tmp2
27         get_current_task \tmp1
28         ldr     \tmp1, [\tmp1, #TSK_TI_TTBR0]   // load saved TTBR0_EL1
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         msr     ttbr0_el1, \tmp1                // set the non-PAN TTBR0_EL1
34         isb
35         .endm
36
37         .macro  uaccess_ttbr0_disable, tmp1, tmp2
38 alternative_if_not ARM64_HAS_PAN
39         save_and_disable_irq \tmp2              // avoid preemption
40         __uaccess_ttbr0_disable \tmp1
41         restore_irq \tmp2
42 alternative_else_nop_endif
43         .endm
44
45         .macro  uaccess_ttbr0_enable, tmp1, tmp2, tmp3
46 alternative_if_not ARM64_HAS_PAN
47         save_and_disable_irq \tmp3              // avoid preemption
48         __uaccess_ttbr0_enable \tmp1, \tmp2
49         restore_irq \tmp3
50 alternative_else_nop_endif
51         .endm
52 #else
53         .macro  uaccess_ttbr0_disable, tmp1, tmp2
54         .endm
55
56         .macro  uaccess_ttbr0_enable, tmp1, tmp2, tmp3
57         .endm
58 #endif
59
60 #define USER(l, x...)                           \
61 9999:   x;                                      \
62         _asm_extable_uaccess    9999b, l
63
64 /*
65  * Generate the assembly for LDTR/STTR with exception table entries.
66  * This is complicated as there is no post-increment or pair versions of the
67  * unprivileged instructions, and USER() only works for single instructions.
68  */
69         .macro user_ldp l, reg1, reg2, addr, post_inc
70 8888:           ldtr    \reg1, [\addr];
71 8889:           ldtr    \reg2, [\addr, #8];
72                 add     \addr, \addr, \post_inc;
73
74                 _asm_extable_uaccess    8888b, \l;
75                 _asm_extable_uaccess    8889b, \l;
76         .endm
77
78         .macro user_stp l, reg1, reg2, addr, post_inc
79 8888:           sttr    \reg1, [\addr];
80 8889:           sttr    \reg2, [\addr, #8];
81                 add     \addr, \addr, \post_inc;
82
83                 _asm_extable_uaccess    8888b,\l;
84                 _asm_extable_uaccess    8889b,\l;
85         .endm
86
87         .macro user_ldst l, inst, reg, addr, post_inc
88 8888:           \inst           \reg, [\addr];
89                 add             \addr, \addr, \post_inc;
90
91                 _asm_extable_uaccess    8888b, \l;
92         .endm
93 #endif