Merge tag 'for-linus-5.15-1' of git://github.com/cminyard/linux-ipmi
[linux-2.6-microblaze.git] / Documentation / arm64 / tagged-address-abi.rst
1 ==========================
2 AArch64 TAGGED ADDRESS ABI
3 ==========================
4
5 Authors: Vincenzo Frascino <vincenzo.frascino@arm.com>
6          Catalin Marinas <catalin.marinas@arm.com>
7
8 Date: 21 August 2019
9
10 This document describes the usage and semantics of the Tagged Address
11 ABI on AArch64 Linux.
12
13 1. Introduction
14 ---------------
15
16 On AArch64 the ``TCR_EL1.TBI0`` bit is set by default, allowing
17 userspace (EL0) to perform memory accesses through 64-bit pointers with
18 a non-zero top byte. This document describes the relaxation of the
19 syscall ABI that allows userspace to pass certain tagged pointers to
20 kernel syscalls.
21
22 2. AArch64 Tagged Address ABI
23 -----------------------------
24
25 From the kernel syscall interface perspective and for the purposes of
26 this document, a "valid tagged pointer" is a pointer with a potentially
27 non-zero top-byte that references an address in the user process address
28 space obtained in one of the following ways:
29
30 - ``mmap()`` syscall where either:
31
32   - flags have the ``MAP_ANONYMOUS`` bit set or
33   - the file descriptor refers to a regular file (including those
34     returned by ``memfd_create()``) or ``/dev/zero``
35
36 - ``brk()`` syscall (i.e. the heap area between the initial location of
37   the program break at process creation and its current location).
38
39 - any memory mapped by the kernel in the address space of the process
40   during creation and with the same restrictions as for ``mmap()`` above
41   (e.g. data, bss, stack).
42
43 The AArch64 Tagged Address ABI has two stages of relaxation depending on
44 how the user addresses are used by the kernel:
45
46 1. User addresses not accessed by the kernel but used for address space
47    management (e.g. ``mprotect()``, ``madvise()``). The use of valid
48    tagged pointers in this context is allowed with these exceptions:
49
50    - ``brk()``, ``mmap()`` and the ``new_address`` argument to
51      ``mremap()`` as these have the potential to alias with existing
52       user addresses.
53
54      NOTE: This behaviour changed in v5.6 and so some earlier kernels may
55      incorrectly accept valid tagged pointers for the ``brk()``,
56      ``mmap()`` and ``mremap()`` system calls.
57
58    - The ``range.start``, ``start`` and ``dst`` arguments to the
59      ``UFFDIO_*`` ``ioctl()``s used on a file descriptor obtained from
60      ``userfaultfd()``, as fault addresses subsequently obtained by reading
61      the file descriptor will be untagged, which may otherwise confuse
62      tag-unaware programs.
63
64      NOTE: This behaviour changed in v5.14 and so some earlier kernels may
65      incorrectly accept valid tagged pointers for this system call.
66
67 2. User addresses accessed by the kernel (e.g. ``write()``). This ABI
68    relaxation is disabled by default and the application thread needs to
69    explicitly enable it via ``prctl()`` as follows:
70
71    - ``PR_SET_TAGGED_ADDR_CTRL``: enable or disable the AArch64 Tagged
72      Address ABI for the calling thread.
73
74      The ``(unsigned int) arg2`` argument is a bit mask describing the
75      control mode used:
76
77      - ``PR_TAGGED_ADDR_ENABLE``: enable AArch64 Tagged Address ABI.
78        Default status is disabled.
79
80      Arguments ``arg3``, ``arg4``, and ``arg5`` must be 0.
81
82    - ``PR_GET_TAGGED_ADDR_CTRL``: get the status of the AArch64 Tagged
83      Address ABI for the calling thread.
84
85      Arguments ``arg2``, ``arg3``, ``arg4``, and ``arg5`` must be 0.
86
87    The ABI properties described above are thread-scoped, inherited on
88    clone() and fork() and cleared on exec().
89
90    Calling ``prctl(PR_SET_TAGGED_ADDR_CTRL, PR_TAGGED_ADDR_ENABLE, 0, 0, 0)``
91    returns ``-EINVAL`` if the AArch64 Tagged Address ABI is globally
92    disabled by ``sysctl abi.tagged_addr_disabled=1``. The default
93    ``sysctl abi.tagged_addr_disabled`` configuration is 0.
94
95 When the AArch64 Tagged Address ABI is enabled for a thread, the
96 following behaviours are guaranteed:
97
98 - All syscalls except the cases mentioned in section 3 can accept any
99   valid tagged pointer.
100
101 - The syscall behaviour is undefined for invalid tagged pointers: it may
102   result in an error code being returned, a (fatal) signal being raised,
103   or other modes of failure.
104
105 - The syscall behaviour for a valid tagged pointer is the same as for
106   the corresponding untagged pointer.
107
108
109 A definition of the meaning of tagged pointers on AArch64 can be found
110 in Documentation/arm64/tagged-pointers.rst.
111
112 3. AArch64 Tagged Address ABI Exceptions
113 -----------------------------------------
114
115 The following system call parameters must be untagged regardless of the
116 ABI relaxation:
117
118 - ``prctl()`` other than pointers to user data either passed directly or
119   indirectly as arguments to be accessed by the kernel.
120
121 - ``ioctl()`` other than pointers to user data either passed directly or
122   indirectly as arguments to be accessed by the kernel.
123
124 - ``shmat()`` and ``shmdt()``.
125
126 - ``brk()`` (since kernel v5.6).
127
128 - ``mmap()`` (since kernel v5.6).
129
130 - ``mremap()``, the ``new_address`` argument (since kernel v5.6).
131
132 Any attempt to use non-zero tagged pointers may result in an error code
133 being returned, a (fatal) signal being raised, or other modes of
134 failure.
135
136 4. Example of correct usage
137 ---------------------------
138 .. code-block:: c
139
140    #include <stdlib.h>
141    #include <string.h>
142    #include <unistd.h>
143    #include <sys/mman.h>
144    #include <sys/prctl.h>
145    
146    #define PR_SET_TAGGED_ADDR_CTRL      55
147    #define PR_TAGGED_ADDR_ENABLE        (1UL << 0)
148    
149    #define TAG_SHIFT            56
150    
151    int main(void)
152    {
153         int tbi_enabled = 0;
154         unsigned long tag = 0;
155         char *ptr;
156    
157         /* check/enable the tagged address ABI */
158         if (!prctl(PR_SET_TAGGED_ADDR_CTRL, PR_TAGGED_ADDR_ENABLE, 0, 0, 0))
159                 tbi_enabled = 1;
160    
161         /* memory allocation */
162         ptr = mmap(NULL, sysconf(_SC_PAGE_SIZE), PROT_READ | PROT_WRITE,
163                    MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
164         if (ptr == MAP_FAILED)
165                 return 1;
166    
167         /* set a non-zero tag if the ABI is available */
168         if (tbi_enabled)
169                 tag = rand() & 0xff;
170         ptr = (char *)((unsigned long)ptr | (tag << TAG_SHIFT));
171    
172         /* memory access to a tagged address */
173         strcpy(ptr, "tagged pointer\n");
174    
175         /* syscall with a tagged pointer */
176         write(1, ptr, strlen(ptr));
177    
178         return 0;
179    }