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