treewide: remove redundant IS_ERR() before error code check
[linux/fpc-iii.git] / Documentation / arm64 / tagged-address-abi.rst
blobd4a85d535bf99e09cfe5c3dc41652eaa3b64f21b
1 ==========================
2 AArch64 TAGGED ADDRESS ABI
3 ==========================
5 Authors: Vincenzo Frascino <vincenzo.frascino@arm.com>
6          Catalin Marinas <catalin.marinas@arm.com>
8 Date: 21 August 2019
10 This document describes the usage and semantics of the Tagged Address
11 ABI on AArch64 Linux.
13 1. Introduction
14 ---------------
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.
22 2. AArch64 Tagged Address ABI
23 -----------------------------
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:
30 - ``mmap()`` syscall where either:
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``
36 - ``brk()`` syscall (i.e. the heap area between the initial location of
37   the program break at process creation and its current location).
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).
43 The AArch64 Tagged Address ABI has two stages of relaxation depending
44 how the user addresses are used by the kernel:
46 1. User addresses not accessed by the kernel but used for address space
47    management (e.g. ``mmap()``, ``mprotect()``, ``madvise()``). The use
48    of valid tagged pointers in this context is always allowed.
50 2. User addresses accessed by the kernel (e.g. ``write()``). This ABI
51    relaxation is disabled by default and the application thread needs to
52    explicitly enable it via ``prctl()`` as follows:
54    - ``PR_SET_TAGGED_ADDR_CTRL``: enable or disable the AArch64 Tagged
55      Address ABI for the calling thread.
57      The ``(unsigned int) arg2`` argument is a bit mask describing the
58      control mode used:
60      - ``PR_TAGGED_ADDR_ENABLE``: enable AArch64 Tagged Address ABI.
61        Default status is disabled.
63      Arguments ``arg3``, ``arg4``, and ``arg5`` must be 0.
65    - ``PR_GET_TAGGED_ADDR_CTRL``: get the status of the AArch64 Tagged
66      Address ABI for the calling thread.
68      Arguments ``arg2``, ``arg3``, ``arg4``, and ``arg5`` must be 0.
70    The ABI properties described above are thread-scoped, inherited on
71    clone() and fork() and cleared on exec().
73    Calling ``prctl(PR_SET_TAGGED_ADDR_CTRL, PR_TAGGED_ADDR_ENABLE, 0, 0, 0)``
74    returns ``-EINVAL`` if the AArch64 Tagged Address ABI is globally
75    disabled by ``sysctl abi.tagged_addr_disabled=1``. The default
76    ``sysctl abi.tagged_addr_disabled`` configuration is 0.
78 When the AArch64 Tagged Address ABI is enabled for a thread, the
79 following behaviours are guaranteed:
81 - All syscalls except the cases mentioned in section 3 can accept any
82   valid tagged pointer.
84 - The syscall behaviour is undefined for invalid tagged pointers: it may
85   result in an error code being returned, a (fatal) signal being raised,
86   or other modes of failure.
88 - The syscall behaviour for a valid tagged pointer is the same as for
89   the corresponding untagged pointer.
92 A definition of the meaning of tagged pointers on AArch64 can be found
93 in Documentation/arm64/tagged-pointers.rst.
95 3. AArch64 Tagged Address ABI Exceptions
96 -----------------------------------------
98 The following system call parameters must be untagged regardless of the
99 ABI relaxation:
101 - ``prctl()`` other than pointers to user data either passed directly or
102   indirectly as arguments to be accessed by the kernel.
104 - ``ioctl()`` other than pointers to user data either passed directly or
105   indirectly as arguments to be accessed by the kernel.
107 - ``shmat()`` and ``shmdt()``.
109 Any attempt to use non-zero tagged pointers may result in an error code
110 being returned, a (fatal) signal being raised, or other modes of
111 failure.
113 4. Example of correct usage
114 ---------------------------
115 .. code-block:: c
117    #include <stdlib.h>
118    #include <string.h>
119    #include <unistd.h>
120    #include <sys/mman.h>
121    #include <sys/prctl.h>
122    
123    #define PR_SET_TAGGED_ADDR_CTRL      55
124    #define PR_TAGGED_ADDR_ENABLE        (1UL << 0)
125    
126    #define TAG_SHIFT            56
127    
128    int main(void)
129    {
130         int tbi_enabled = 0;
131         unsigned long tag = 0;
132         char *ptr;
133    
134         /* check/enable the tagged address ABI */
135         if (!prctl(PR_SET_TAGGED_ADDR_CTRL, PR_TAGGED_ADDR_ENABLE, 0, 0, 0))
136                 tbi_enabled = 1;
137    
138         /* memory allocation */
139         ptr = mmap(NULL, sysconf(_SC_PAGE_SIZE), PROT_READ | PROT_WRITE,
140                    MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
141         if (ptr == MAP_FAILED)
142                 return 1;
143    
144         /* set a non-zero tag if the ABI is available */
145         if (tbi_enabled)
146                 tag = rand() & 0xff;
147         ptr = (char *)((unsigned long)ptr | (tag << TAG_SHIFT));
148    
149         /* memory access to a tagged address */
150         strcpy(ptr, "tagged pointer\n");
151    
152         /* syscall with a tagged pointer */
153         write(1, ptr, strlen(ptr));
154    
155         return 0;
156    }