aboutsummaryrefslogtreecommitdiff
path: root/src/raw.rs
blob: 28039c7c95393e593f1b4a994bf51a9367cb308d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
use libc::{c_int, c_long, syscall, SYS_userfaultfd, INT_MAX};
pub use userfaultfd_sys::*;

pub unsafe fn userfaultfd(flags: c_int) -> c_int {
    let fd = syscall(SYS_userfaultfd, flags as c_long);
    if fd > INT_MAX as c_long {
        panic!("fd doesn't fit in a c_int");
    } else {
        fd as c_int
    }
}

nix::ioctl_readwrite!(api, UFFDIO, _UFFDIO_API, uffdio_api);
nix::ioctl_readwrite!(register, UFFDIO, _UFFDIO_REGISTER, uffdio_register);
nix::ioctl_read!(unregister, UFFDIO, _UFFDIO_UNREGISTER, uffdio_range);
nix::ioctl_read!(wake, UFFDIO, _UFFDIO_WAKE, uffdio_range);
nix::ioctl_readwrite!(copy, UFFDIO, _UFFDIO_COPY, uffdio_copy);
nix::ioctl_readwrite!(zeropage, UFFDIO, _UFFDIO_ZEROPAGE, uffdio_zeropage);
#[cfg(feature = "linux5_7")]
nix::ioctl_readwrite!(
    write_protect,
    UFFDIO,
    _UFFDIO_WRITEPROTECT,
    uffdio_writeprotect
);

// ioctls for /dev/userfaultfd

// This is the `/dev/userfaultfd` ioctl() from creating a new userfault file descriptor.
// It is a "bad" ioctl in the sense that it is defined as an _IOC:
// https://elixir.bootlin.com/linux/latest/source/include/uapi/linux/userfaultfd.h#L17,
// aka `nix::ioctl_none`, however it does receive an integer argument:
// https://elixir.bootlin.com/linux/latest/source/fs/userfaultfd.c#L2186. That is the same argument
// that the userfaultfd() system call receives.
nix::ioctl_write_int_bad!(
    /// Create a new userfault file descriptor from the `/dev/userfaultfd`
    /// device. This receives the same arguments as the userfaultfd system call.
    new_uffd,
    nix::request_code_none!(USERFAULTFD_IOC, 0x00)
);