xref: /third_party/ltp/include/lapi/userfaultfd.h (revision f08c3bdf)
1f08c3bdfSopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later
2f08c3bdfSopenharmony_ci/*
3f08c3bdfSopenharmony_ci * Copyright (C) 2007 Davide Libenzi <davidel@xmailserver.org>
4f08c3bdfSopenharmony_ci * Copyright (C) 2015,2022 Red Hat, Inc.
5f08c3bdfSopenharmony_ci *
6f08c3bdfSopenharmony_ci * Mostly copied/adapted from <linux/userfaultfd.h>
7f08c3bdfSopenharmony_ci */
8f08c3bdfSopenharmony_ci
9f08c3bdfSopenharmony_ci#ifndef LAPI_USERFAULTFD_H__
10f08c3bdfSopenharmony_ci#define LAPI_USERFAULTFD_H__
11f08c3bdfSopenharmony_ci
12f08c3bdfSopenharmony_ci#include <unistd.h>
13f08c3bdfSopenharmony_ci#include <sys/types.h>
14f08c3bdfSopenharmony_ci#include "lapi/syscalls.h"
15f08c3bdfSopenharmony_ci
16f08c3bdfSopenharmony_ci#ifdef HAVE_LINUX_USERFAULTFD_H
17f08c3bdfSopenharmony_ci#include <linux/userfaultfd.h>
18f08c3bdfSopenharmony_ci#endif
19f08c3bdfSopenharmony_ci
20f08c3bdfSopenharmony_ci/* userfaultfd support was added in v4.1 */
21f08c3bdfSopenharmony_ci#ifndef UFFD_API
22f08c3bdfSopenharmony_ci#define UFFD_API ((__u64)0xAA)
23f08c3bdfSopenharmony_ci
24f08c3bdfSopenharmony_ci/*
25f08c3bdfSopenharmony_ci * Valid ioctl command number range with this API is from 0x00 to
26f08c3bdfSopenharmony_ci * 0x3F.  UFFDIO_API is the fixed number, everything else can be
27f08c3bdfSopenharmony_ci * changed by implementing a different UFFD_API. If sticking to the
28f08c3bdfSopenharmony_ci * same UFFD_API more ioctl can be added and userland will be aware of
29f08c3bdfSopenharmony_ci * which ioctl the running kernel implements through the ioctl command
30f08c3bdfSopenharmony_ci * bitmask written by the UFFDIO_API.
31f08c3bdfSopenharmony_ci */
32f08c3bdfSopenharmony_ci#define _UFFDIO_REGISTER		(0x00)
33f08c3bdfSopenharmony_ci#define _UFFDIO_UNREGISTER		(0x01)
34f08c3bdfSopenharmony_ci#define _UFFDIO_WAKE			(0x02)
35f08c3bdfSopenharmony_ci#define _UFFDIO_COPY			(0x03)
36f08c3bdfSopenharmony_ci#define _UFFDIO_ZEROPAGE		(0x04)
37f08c3bdfSopenharmony_ci#define _UFFDIO_API			(0x3F)
38f08c3bdfSopenharmony_ci
39f08c3bdfSopenharmony_ci/* userfaultfd ioctl ids */
40f08c3bdfSopenharmony_ci#define UFFDIO 0xAA
41f08c3bdfSopenharmony_ci#define UFFDIO_API		_IOWR(UFFDIO, _UFFDIO_API,	\
42f08c3bdfSopenharmony_ci				      struct uffdio_api)
43f08c3bdfSopenharmony_ci#define UFFDIO_REGISTER		_IOWR(UFFDIO, _UFFDIO_REGISTER, \
44f08c3bdfSopenharmony_ci				      struct uffdio_register)
45f08c3bdfSopenharmony_ci#define UFFDIO_UNREGISTER	_IOR(UFFDIO, _UFFDIO_UNREGISTER,	\
46f08c3bdfSopenharmony_ci				     struct uffdio_range)
47f08c3bdfSopenharmony_ci#define UFFDIO_WAKE		_IOR(UFFDIO, _UFFDIO_WAKE,	\
48f08c3bdfSopenharmony_ci				     struct uffdio_range)
49f08c3bdfSopenharmony_ci#define UFFDIO_COPY		_IOWR(UFFDIO, _UFFDIO_COPY,	\
50f08c3bdfSopenharmony_ci				      struct uffdio_copy)
51f08c3bdfSopenharmony_ci#define UFFDIO_ZEROPAGE		_IOWR(UFFDIO, _UFFDIO_ZEROPAGE,	\
52f08c3bdfSopenharmony_ci				      struct uffdio_zeropage)
53f08c3bdfSopenharmony_ci
54f08c3bdfSopenharmony_ci/* read() structure */
55f08c3bdfSopenharmony_cistruct uffd_msg {
56f08c3bdfSopenharmony_ci	__u8	event;
57f08c3bdfSopenharmony_ci
58f08c3bdfSopenharmony_ci	__u8	reserved1;
59f08c3bdfSopenharmony_ci	__u16	reserved2;
60f08c3bdfSopenharmony_ci	__u32	reserved3;
61f08c3bdfSopenharmony_ci
62f08c3bdfSopenharmony_ci	union {
63f08c3bdfSopenharmony_ci		struct {
64f08c3bdfSopenharmony_ci			__u64	flags;
65f08c3bdfSopenharmony_ci			__u64	address;
66f08c3bdfSopenharmony_ci		} pagefault;
67f08c3bdfSopenharmony_ci
68f08c3bdfSopenharmony_ci		struct {
69f08c3bdfSopenharmony_ci			/* unused reserved fields */
70f08c3bdfSopenharmony_ci			__u64	reserved1;
71f08c3bdfSopenharmony_ci			__u64	reserved2;
72f08c3bdfSopenharmony_ci			__u64	reserved3;
73f08c3bdfSopenharmony_ci		} reserved;
74f08c3bdfSopenharmony_ci	} arg;
75f08c3bdfSopenharmony_ci} __packed;
76f08c3bdfSopenharmony_ci
77f08c3bdfSopenharmony_ci/*
78f08c3bdfSopenharmony_ci * Start at 0x12 and not at 0 to be more strict against bugs.
79f08c3bdfSopenharmony_ci */
80f08c3bdfSopenharmony_ci#define UFFD_EVENT_PAGEFAULT	0x12
81f08c3bdfSopenharmony_ci
82f08c3bdfSopenharmony_ci/* flags for UFFD_EVENT_PAGEFAULT */
83f08c3bdfSopenharmony_ci#define UFFD_PAGEFAULT_FLAG_WRITE	(1<<0)	/* If this was a write fault */
84f08c3bdfSopenharmony_ci#define UFFD_PAGEFAULT_FLAG_WP		(1<<1)	/* If reason is VM_UFFD_WP */
85f08c3bdfSopenharmony_ci
86f08c3bdfSopenharmony_cistruct uffdio_api {
87f08c3bdfSopenharmony_ci	/* userland asks for an API number and the features to enable */
88f08c3bdfSopenharmony_ci	__u64 api;
89f08c3bdfSopenharmony_ci	/*
90f08c3bdfSopenharmony_ci	 * Kernel answers below with the all available features for
91f08c3bdfSopenharmony_ci	 * the API, this notifies userland of which events and/or
92f08c3bdfSopenharmony_ci	 * which flags for each event are enabled in the current
93f08c3bdfSopenharmony_ci	 * kernel.
94f08c3bdfSopenharmony_ci	 *
95f08c3bdfSopenharmony_ci	 * Note: UFFD_EVENT_PAGEFAULT and UFFD_PAGEFAULT_FLAG_WRITE
96f08c3bdfSopenharmony_ci	 * are to be considered implicitly always enabled in all kernels as
97f08c3bdfSopenharmony_ci	 * long as the uffdio_api.api requested matches UFFD_API.
98f08c3bdfSopenharmony_ci	 */
99f08c3bdfSopenharmony_ci	__u64 features;
100f08c3bdfSopenharmony_ci
101f08c3bdfSopenharmony_ci	__u64 ioctls;
102f08c3bdfSopenharmony_ci};
103f08c3bdfSopenharmony_ci
104f08c3bdfSopenharmony_cistruct uffdio_range {
105f08c3bdfSopenharmony_ci	__u64 start;
106f08c3bdfSopenharmony_ci	__u64 len;
107f08c3bdfSopenharmony_ci};
108f08c3bdfSopenharmony_ci
109f08c3bdfSopenharmony_cistruct uffdio_register {
110f08c3bdfSopenharmony_ci	struct uffdio_range range;
111f08c3bdfSopenharmony_ci#define UFFDIO_REGISTER_MODE_MISSING	((__u64)1<<0)
112f08c3bdfSopenharmony_ci#define UFFDIO_REGISTER_MODE_WP		((__u64)1<<1)
113f08c3bdfSopenharmony_ci	__u64 mode;
114f08c3bdfSopenharmony_ci
115f08c3bdfSopenharmony_ci	/*
116f08c3bdfSopenharmony_ci	 * kernel answers which ioctl commands are available for the
117f08c3bdfSopenharmony_ci	 * range, keep at the end as the last 8 bytes aren't read.
118f08c3bdfSopenharmony_ci	 */
119f08c3bdfSopenharmony_ci	__u64 ioctls;
120f08c3bdfSopenharmony_ci};
121f08c3bdfSopenharmony_ci
122f08c3bdfSopenharmony_cistruct uffdio_copy {
123f08c3bdfSopenharmony_ci	__u64 dst;
124f08c3bdfSopenharmony_ci	__u64 src;
125f08c3bdfSopenharmony_ci	__u64 len;
126f08c3bdfSopenharmony_ci	/*
127f08c3bdfSopenharmony_ci	 * There will be a wrprotection flag later that allows to map
128f08c3bdfSopenharmony_ci	 * pages wrprotected on the fly. And such a flag will be
129f08c3bdfSopenharmony_ci	 * available if the wrprotection ioctl are implemented for the
130f08c3bdfSopenharmony_ci	 * range according to the uffdio_register.ioctls.
131f08c3bdfSopenharmony_ci	 */
132f08c3bdfSopenharmony_ci#define UFFDIO_COPY_MODE_DONTWAKE		((__u64)1<<0)
133f08c3bdfSopenharmony_ci	__u64 mode;
134f08c3bdfSopenharmony_ci
135f08c3bdfSopenharmony_ci	/*
136f08c3bdfSopenharmony_ci	 * "copy" is written by the ioctl and must be at the end: the
137f08c3bdfSopenharmony_ci	 * copy_from_user will not read the last 8 bytes.
138f08c3bdfSopenharmony_ci	 */
139f08c3bdfSopenharmony_ci	__s64 copy;
140f08c3bdfSopenharmony_ci};
141f08c3bdfSopenharmony_ci
142f08c3bdfSopenharmony_cistruct uffdio_zeropage {
143f08c3bdfSopenharmony_ci	struct uffdio_range range;
144f08c3bdfSopenharmony_ci#define UFFDIO_ZEROPAGE_MODE_DONTWAKE		((__u64)1<<0)
145f08c3bdfSopenharmony_ci	__u64 mode;
146f08c3bdfSopenharmony_ci
147f08c3bdfSopenharmony_ci	/*
148f08c3bdfSopenharmony_ci	 * "zeropage" is written by the ioctl and must be at the end:
149f08c3bdfSopenharmony_ci	 * the copy_from_user will not read the last 8 bytes.
150f08c3bdfSopenharmony_ci	 */
151f08c3bdfSopenharmony_ci	__s64 zeropage;
152f08c3bdfSopenharmony_ci};
153f08c3bdfSopenharmony_ci#endif /* UFFD_API */
154f08c3bdfSopenharmony_ci
155f08c3bdfSopenharmony_ci
156f08c3bdfSopenharmony_ci/* UFFD_USER_MODE_ONLY was added in v5.11 */
157f08c3bdfSopenharmony_ci#ifndef UFFD_USER_MODE_ONLY
158f08c3bdfSopenharmony_ci#define UFFD_USER_MODE_ONLY 1
159f08c3bdfSopenharmony_ci#endif /* UFFD_USER_MODE_ONLY */
160f08c3bdfSopenharmony_ci
161f08c3bdfSopenharmony_ci
162f08c3bdfSopenharmony_ci/* UFFD_PAGEFAULT_FLAG_MINOR and UFFDIO_CONTINUE were added in v5.13 */
163f08c3bdfSopenharmony_ci#ifndef UFFD_PAGEFAULT_FLAG_MINOR
164f08c3bdfSopenharmony_ci#define UFFD_FEATURE_MINOR_HUGETLBFS		(1<<9)
165f08c3bdfSopenharmony_ci#define UFFDIO_REGISTER_MODE_MINOR	((__u64)1<<2)
166f08c3bdfSopenharmony_ci
167f08c3bdfSopenharmony_ci#define _UFFDIO_CONTINUE		(0x07)
168f08c3bdfSopenharmony_ci#define UFFDIO_CONTINUE		_IOWR(UFFDIO, _UFFDIO_CONTINUE,	\
169f08c3bdfSopenharmony_ci				      struct uffdio_continue)
170f08c3bdfSopenharmony_ci
171f08c3bdfSopenharmony_cistruct uffdio_continue {
172f08c3bdfSopenharmony_ci	struct uffdio_range range;
173f08c3bdfSopenharmony_ci#define UFFDIO_CONTINUE_MODE_DONTWAKE		((__u64)1<<0)
174f08c3bdfSopenharmony_ci	__u64 mode;
175f08c3bdfSopenharmony_ci
176f08c3bdfSopenharmony_ci	/*
177f08c3bdfSopenharmony_ci	 * Fields below here are written by the ioctl and must be at the end:
178f08c3bdfSopenharmony_ci	 * the copy_from_user will not read past here.
179f08c3bdfSopenharmony_ci	 */
180f08c3bdfSopenharmony_ci	__s64 mapped;
181f08c3bdfSopenharmony_ci};
182f08c3bdfSopenharmony_ci#endif /* UFFD_PAGEFAULT_FLAG_MINOR */
183f08c3bdfSopenharmony_ci
184f08c3bdfSopenharmony_ci
185f08c3bdfSopenharmony_ci/* UFFD_FEATURE_MINOR_SHMEM was added in v5.14 */
186f08c3bdfSopenharmony_ci#ifndef UFFD_FEATURE_MINOR_SHMEM
187f08c3bdfSopenharmony_ci#define UFFD_FEATURE_MINOR_SHMEM		(1<<10)
188f08c3bdfSopenharmony_ci#endif /* UFFD_FEATURE_MINOR_SHMEM */
189f08c3bdfSopenharmony_ci
190f08c3bdfSopenharmony_ci#endif /* LAPI_USERFAULTFD_H__ */
191