Merge tag 'docs-5.15' of git://git.lwn.net/linux
[linux-2.6-microblaze.git] / Documentation / arm64 / memory-tagging-extension.rst
1 ===============================================
2 Memory Tagging Extension (MTE) in AArch64 Linux
3 ===============================================
4
5 Authors: Vincenzo Frascino <vincenzo.frascino@arm.com>
6          Catalin Marinas <catalin.marinas@arm.com>
7
8 Date: 2020-02-25
9
10 This document describes the provision of the Memory Tagging Extension
11 functionality in AArch64 Linux.
12
13 Introduction
14 ============
15
16 ARMv8.5 based processors introduce the Memory Tagging Extension (MTE)
17 feature. MTE is built on top of the ARMv8.0 virtual address tagging TBI
18 (Top Byte Ignore) feature and allows software to access a 4-bit
19 allocation tag for each 16-byte granule in the physical address space.
20 Such memory range must be mapped with the Normal-Tagged memory
21 attribute. A logical tag is derived from bits 59-56 of the virtual
22 address used for the memory access. A CPU with MTE enabled will compare
23 the logical tag against the allocation tag and potentially raise an
24 exception on mismatch, subject to system registers configuration.
25
26 Userspace Support
27 =================
28
29 When ``CONFIG_ARM64_MTE`` is selected and Memory Tagging Extension is
30 supported by the hardware, the kernel advertises the feature to
31 userspace via ``HWCAP2_MTE``.
32
33 PROT_MTE
34 --------
35
36 To access the allocation tags, a user process must enable the Tagged
37 memory attribute on an address range using a new ``prot`` flag for
38 ``mmap()`` and ``mprotect()``:
39
40 ``PROT_MTE`` - Pages allow access to the MTE allocation tags.
41
42 The allocation tag is set to 0 when such pages are first mapped in the
43 user address space and preserved on copy-on-write. ``MAP_SHARED`` is
44 supported and the allocation tags can be shared between processes.
45
46 **Note**: ``PROT_MTE`` is only supported on ``MAP_ANONYMOUS`` and
47 RAM-based file mappings (``tmpfs``, ``memfd``). Passing it to other
48 types of mapping will result in ``-EINVAL`` returned by these system
49 calls.
50
51 **Note**: The ``PROT_MTE`` flag (and corresponding memory type) cannot
52 be cleared by ``mprotect()``.
53
54 **Note**: ``madvise()`` memory ranges with ``MADV_DONTNEED`` and
55 ``MADV_FREE`` may have the allocation tags cleared (set to 0) at any
56 point after the system call.
57
58 Tag Check Faults
59 ----------------
60
61 When ``PROT_MTE`` is enabled on an address range and a mismatch between
62 the logical and allocation tags occurs on access, there are three
63 configurable behaviours:
64
65 - *Ignore* - This is the default mode. The CPU (and kernel) ignores the
66   tag check fault.
67
68 - *Synchronous* - The kernel raises a ``SIGSEGV`` synchronously, with
69   ``.si_code = SEGV_MTESERR`` and ``.si_addr = <fault-address>``. The
70   memory access is not performed. If ``SIGSEGV`` is ignored or blocked
71   by the offending thread, the containing process is terminated with a
72   ``coredump``.
73
74 - *Asynchronous* - The kernel raises a ``SIGSEGV``, in the offending
75   thread, asynchronously following one or multiple tag check faults,
76   with ``.si_code = SEGV_MTEAERR`` and ``.si_addr = 0`` (the faulting
77   address is unknown).
78
79 The user can select the above modes, per thread, using the
80 ``prctl(PR_SET_TAGGED_ADDR_CTRL, flags, 0, 0, 0)`` system call where ``flags``
81 contains any number of the following values in the ``PR_MTE_TCF_MASK``
82 bit-field:
83
84 - ``PR_MTE_TCF_NONE``  - *Ignore* tag check faults
85                          (ignored if combined with other options)
86 - ``PR_MTE_TCF_SYNC``  - *Synchronous* tag check fault mode
87 - ``PR_MTE_TCF_ASYNC`` - *Asynchronous* tag check fault mode
88
89 If no modes are specified, tag check faults are ignored. If a single
90 mode is specified, the program will run in that mode. If multiple
91 modes are specified, the mode is selected as described in the "Per-CPU
92 preferred tag checking modes" section below.
93
94 The current tag check fault mode can be read using the
95 ``prctl(PR_GET_TAGGED_ADDR_CTRL, 0, 0, 0, 0)`` system call.
96
97 Tag checking can also be disabled for a user thread by setting the
98 ``PSTATE.TCO`` bit with ``MSR TCO, #1``.
99
100 **Note**: Signal handlers are always invoked with ``PSTATE.TCO = 0``,
101 irrespective of the interrupted context. ``PSTATE.TCO`` is restored on
102 ``sigreturn()``.
103
104 **Note**: There are no *match-all* logical tags available for user
105 applications.
106
107 **Note**: Kernel accesses to the user address space (e.g. ``read()``
108 system call) are not checked if the user thread tag checking mode is
109 ``PR_MTE_TCF_NONE`` or ``PR_MTE_TCF_ASYNC``. If the tag checking mode is
110 ``PR_MTE_TCF_SYNC``, the kernel makes a best effort to check its user
111 address accesses, however it cannot always guarantee it. Kernel accesses
112 to user addresses are always performed with an effective ``PSTATE.TCO``
113 value of zero, regardless of the user configuration.
114
115 Excluding Tags in the ``IRG``, ``ADDG`` and ``SUBG`` instructions
116 -----------------------------------------------------------------
117
118 The architecture allows excluding certain tags to be randomly generated
119 via the ``GCR_EL1.Exclude`` register bit-field. By default, Linux
120 excludes all tags other than 0. A user thread can enable specific tags
121 in the randomly generated set using the ``prctl(PR_SET_TAGGED_ADDR_CTRL,
122 flags, 0, 0, 0)`` system call where ``flags`` contains the tags bitmap
123 in the ``PR_MTE_TAG_MASK`` bit-field.
124
125 **Note**: The hardware uses an exclude mask but the ``prctl()``
126 interface provides an include mask. An include mask of ``0`` (exclusion
127 mask ``0xffff``) results in the CPU always generating tag ``0``.
128
129 Per-CPU preferred tag checking mode
130 -----------------------------------
131
132 On some CPUs the performance of MTE in stricter tag checking modes
133 is similar to that of less strict tag checking modes. This makes it
134 worthwhile to enable stricter checks on those CPUs when a less strict
135 checking mode is requested, in order to gain the error detection
136 benefits of the stricter checks without the performance downsides. To
137 support this scenario, a privileged user may configure a stricter
138 tag checking mode as the CPU's preferred tag checking mode.
139
140 The preferred tag checking mode for each CPU is controlled by
141 ``/sys/devices/system/cpu/cpu<N>/mte_tcf_preferred``, to which a
142 privileged user may write the value ``async`` or ``sync``.  The default
143 preferred mode for each CPU is ``async``.
144
145 To allow a program to potentially run in the CPU's preferred tag
146 checking mode, the user program may set multiple tag check fault mode
147 bits in the ``flags`` argument to the ``prctl(PR_SET_TAGGED_ADDR_CTRL,
148 flags, 0, 0, 0)`` system call. If the CPU's preferred tag checking
149 mode is in the task's set of provided tag checking modes (this will
150 always be the case at present because the kernel only supports two
151 tag checking modes, but future kernels may support more modes), that
152 mode will be selected. Otherwise, one of the modes in the task's mode
153 set will be selected in a currently unspecified manner.
154
155 Initial process state
156 ---------------------
157
158 On ``execve()``, the new process has the following configuration:
159
160 - ``PR_TAGGED_ADDR_ENABLE`` set to 0 (disabled)
161 - No tag checking modes are selected (tag check faults ignored)
162 - ``PR_MTE_TAG_MASK`` set to 0 (all tags excluded)
163 - ``PSTATE.TCO`` set to 0
164 - ``PROT_MTE`` not set on any of the initial memory maps
165
166 On ``fork()``, the new process inherits the parent's configuration and
167 memory map attributes with the exception of the ``madvise()`` ranges
168 with ``MADV_WIPEONFORK`` which will have the data and tags cleared (set
169 to 0).
170
171 The ``ptrace()`` interface
172 --------------------------
173
174 ``PTRACE_PEEKMTETAGS`` and ``PTRACE_POKEMTETAGS`` allow a tracer to read
175 the tags from or set the tags to a tracee's address space. The
176 ``ptrace()`` system call is invoked as ``ptrace(request, pid, addr,
177 data)`` where:
178
179 - ``request`` - one of ``PTRACE_PEEKMTETAGS`` or ``PTRACE_POKEMTETAGS``.
180 - ``pid`` - the tracee's PID.
181 - ``addr`` - address in the tracee's address space.
182 - ``data`` - pointer to a ``struct iovec`` where ``iov_base`` points to
183   a buffer of ``iov_len`` length in the tracer's address space.
184
185 The tags in the tracer's ``iov_base`` buffer are represented as one
186 4-bit tag per byte and correspond to a 16-byte MTE tag granule in the
187 tracee's address space.
188
189 **Note**: If ``addr`` is not aligned to a 16-byte granule, the kernel
190 will use the corresponding aligned address.
191
192 ``ptrace()`` return value:
193
194 - 0 - tags were copied, the tracer's ``iov_len`` was updated to the
195   number of tags transferred. This may be smaller than the requested
196   ``iov_len`` if the requested address range in the tracee's or the
197   tracer's space cannot be accessed or does not have valid tags.
198 - ``-EPERM`` - the specified process cannot be traced.
199 - ``-EIO`` - the tracee's address range cannot be accessed (e.g. invalid
200   address) and no tags copied. ``iov_len`` not updated.
201 - ``-EFAULT`` - fault on accessing the tracer's memory (``struct iovec``
202   or ``iov_base`` buffer) and no tags copied. ``iov_len`` not updated.
203 - ``-EOPNOTSUPP`` - the tracee's address does not have valid tags (never
204   mapped with the ``PROT_MTE`` flag). ``iov_len`` not updated.
205
206 **Note**: There are no transient errors for the requests above, so user
207 programs should not retry in case of a non-zero system call return.
208
209 ``PTRACE_GETREGSET`` and ``PTRACE_SETREGSET`` with ``addr ==
210 ``NT_ARM_TAGGED_ADDR_CTRL`` allow ``ptrace()`` access to the tagged
211 address ABI control and MTE configuration of a process as per the
212 ``prctl()`` options described in
213 Documentation/arm64/tagged-address-abi.rst and above. The corresponding
214 ``regset`` is 1 element of 8 bytes (``sizeof(long))``).
215
216 Example of correct usage
217 ========================
218
219 *MTE Example code*
220
221 .. code-block:: c
222
223     /*
224      * To be compiled with -march=armv8.5-a+memtag
225      */
226     #include <errno.h>
227     #include <stdint.h>
228     #include <stdio.h>
229     #include <stdlib.h>
230     #include <unistd.h>
231     #include <sys/auxv.h>
232     #include <sys/mman.h>
233     #include <sys/prctl.h>
234
235     /*
236      * From arch/arm64/include/uapi/asm/hwcap.h
237      */
238     #define HWCAP2_MTE              (1 << 18)
239
240     /*
241      * From arch/arm64/include/uapi/asm/mman.h
242      */
243     #define PROT_MTE                 0x20
244
245     /*
246      * From include/uapi/linux/prctl.h
247      */
248     #define PR_SET_TAGGED_ADDR_CTRL 55
249     #define PR_GET_TAGGED_ADDR_CTRL 56
250     # define PR_TAGGED_ADDR_ENABLE  (1UL << 0)
251     # define PR_MTE_TCF_SHIFT       1
252     # define PR_MTE_TCF_NONE        (0UL << PR_MTE_TCF_SHIFT)
253     # define PR_MTE_TCF_SYNC        (1UL << PR_MTE_TCF_SHIFT)
254     # define PR_MTE_TCF_ASYNC       (2UL << PR_MTE_TCF_SHIFT)
255     # define PR_MTE_TCF_MASK        (3UL << PR_MTE_TCF_SHIFT)
256     # define PR_MTE_TAG_SHIFT       3
257     # define PR_MTE_TAG_MASK        (0xffffUL << PR_MTE_TAG_SHIFT)
258
259     /*
260      * Insert a random logical tag into the given pointer.
261      */
262     #define insert_random_tag(ptr) ({                       \
263             uint64_t __val;                                 \
264             asm("irg %0, %1" : "=r" (__val) : "r" (ptr));   \
265             __val;                                          \
266     })
267
268     /*
269      * Set the allocation tag on the destination address.
270      */
271     #define set_tag(tagged_addr) do {                                      \
272             asm volatile("stg %0, [%0]" : : "r" (tagged_addr) : "memory"); \
273     } while (0)
274
275     int main()
276     {
277             unsigned char *a;
278             unsigned long page_sz = sysconf(_SC_PAGESIZE);
279             unsigned long hwcap2 = getauxval(AT_HWCAP2);
280
281             /* check if MTE is present */
282             if (!(hwcap2 & HWCAP2_MTE))
283                     return EXIT_FAILURE;
284
285             /*
286              * Enable the tagged address ABI, synchronous or asynchronous MTE
287              * tag check faults (based on per-CPU preference) and allow all
288              * non-zero tags in the randomly generated set.
289              */
290             if (prctl(PR_SET_TAGGED_ADDR_CTRL,
291                       PR_TAGGED_ADDR_ENABLE | PR_MTE_TCF_SYNC | PR_MTE_TCF_ASYNC |
292                       (0xfffe << PR_MTE_TAG_SHIFT),
293                       0, 0, 0)) {
294                     perror("prctl() failed");
295                     return EXIT_FAILURE;
296             }
297
298             a = mmap(0, page_sz, PROT_READ | PROT_WRITE,
299                      MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
300             if (a == MAP_FAILED) {
301                     perror("mmap() failed");
302                     return EXIT_FAILURE;
303             }
304
305             /*
306              * Enable MTE on the above anonymous mmap. The flag could be passed
307              * directly to mmap() and skip this step.
308              */
309             if (mprotect(a, page_sz, PROT_READ | PROT_WRITE | PROT_MTE)) {
310                     perror("mprotect() failed");
311                     return EXIT_FAILURE;
312             }
313
314             /* access with the default tag (0) */
315             a[0] = 1;
316             a[1] = 2;
317
318             printf("a[0] = %hhu a[1] = %hhu\n", a[0], a[1]);
319
320             /* set the logical and allocation tags */
321             a = (unsigned char *)insert_random_tag(a);
322             set_tag(a);
323
324             printf("%p\n", a);
325
326             /* non-zero tag access */
327             a[0] = 3;
328             printf("a[0] = %hhu a[1] = %hhu\n", a[0], a[1]);
329
330             /*
331              * If MTE is enabled correctly the next instruction will generate an
332              * exception.
333              */
334             printf("Expecting SIGSEGV...\n");
335             a[16] = 0xdd;
336
337             /* this should not be printed in the PR_MTE_TCF_SYNC mode */
338             printf("...haven't got one\n");
339
340             return EXIT_FAILURE;
341     }