---
name: "UFFDIO_MOVE"
section: "2const"
platform: "linux"
package: "man-pages"
version: "6.19-1"
release: "Arch Linux 2026-11-01"
platforms: ["linux"]
url: "https://new.carta.tech/UFFDIO_MOVE"
---

# UFFDIO\_MOVE(2const)

atomically move a continuous memory chunk into the userfault registered range

## NAME

UFFDIO\_MOVE - atomically move a continuous memory chunk into the userfault registered range

## LIBRARY

Standard C library (*libc*, *-lc*)

## SYNOPSIS

```
#include <linux/userfaultfd.h>  /* Definition of UFFD* constants */
#include <sys/ioctl.h>
```

**int ioctl(int** *fd***, UFFDIO\_MOVE, struct uffdio\_move \****argp***);**

**#include \<linux/userfaultfd.h\>**

```
struct uffdio_move {
    __u64  dst;   /* Destination of move */
    __u64  src;   /* Source of move */
    __u64  len;   /* Number of bytes to move */
    __u64  mode;  /* Flags controlling behavior of move */
    __s64  move;  /* Number of bytes moved, or negated error */
};
```

## DESCRIPTION

Atomically move a continuous memory chunk into the userfault registered range and optionally wake up the blocked thread.

The following value may be bitwise ORed in *.mode* to change the behavior of the **UFFDIO\_MOVE** operation:

- **UFFDIO\_MOVE\_MODE\_DONTWAKE**

  Do not wake up the thread that waits for page-fault resolution

- **UFFDIO\_MOVE\_MODE\_ALLOW\_SRC\_HOLES**

  Allow holes in the source virtual range that is being moved. When not specified, the holes will result in **ENOENT** error. When specified, the holes will be accounted as successfully moved memory. This is mostly useful to move hugepage aligned virtual regions without knowing if there are transparent hugepages in the regions or not, but preventing the risk of having to split the hugepage during the operation.

The *.move* field is used by the kernel to return the number of bytes that was actually moved, or an error (a negated *errno*-style value). The *.move* field is output-only; it is not read by the **UFFDIO\_MOVE** operation.

## RETURN VALUE

On success, 0 is returned. In this case, the entire area was moved.

On error, -1 is returned and *errno* is set to indicate the error.

## ERRORS

- **EAGAIN**

  The number of bytes moved (i.e., the value returned in the *.move* field) does not equal the value that was specified in the *.len* field.

- **EINVAL**

  Either *.dst* or *.len* was not a multiple of the system page size, or the range specified by *.src* and *.len* or *.dst* and *.len* was invalid.

- **EINVAL**

  An invalid bit was specified in the *.mode* field.

- **ENOENT**

  The source virtual memory range has unmapped holes and **UFFDIO\_MOVE\_MODE\_ALLOW\_SRC\_HOLES** is not set.

- **EEXIST**

  The destination virtual memory range is fully or partially mapped.

- **EBUSY**

  The pages in the source virtual memory range are either pinned or not exclusive to the process. Once KSM deduplicates pages or [**fork**(2)](/fork/2.md) COW-shares pages during [**fork**(2)](/fork/2.md) with child processes, they are no longer exclusive. The kernel might only perform lightweight checks for detecting whether the pages are exclusive. To make the operation more likely to succeed, KSM should be disabled, [**fork**(2)](/fork/2.md) should be avoided or **MADV\_DONTFORK** should be configured for the source virtual memory area before [**fork**(2)](/fork/2.md).

- **ENOMEM**

  Allocating memory needed for the operation failed.

- **ESRCH**

  The target process has exited at the time of a **UFFDIO\_MOVE** operation.

## STANDARDS

Linux.

## HISTORY

Linux 6.8.

## SEE ALSO

[**ioctl**(2)](/ioctl/2.md), [**ioctl\_userfaultfd**(2)](/ioctl_userfaultfd/2.md), [**userfaultfd**(2)](/userfaultfd/2.md)

*linux.git/Documentation/admin-guide/mm/userfaultfd.rst*
