Skip to content

Commit

Permalink
[LibOS] Lock mmap'ed memory area from mmap during checkpointing
Browse files Browse the repository at this point in the history
When mmap() is run concurrently to a fork() & checkpoint, mmap may add
not-yet-mapped memory areas to the memory mapped areas of a process.
If the checkpoint code wants to transfer them to the destination then
this leads to memory access errors. Therefore, make the addition of
the memory area and the actual memory mapping atomic relative to the
checkpointing.

In particular, make code sequences like the following one atomic
relative to checkpointing:

  bkeep_mmap_xyz()

  ...

  PalVirtualMemoryAlloc()

Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
  • Loading branch information
stefanberger committed Feb 27, 2024
1 parent f1b0132 commit 1acd0fb
Showing 1 changed file with 8 additions and 0 deletions.
8 changes: 8 additions & 0 deletions libos/src/sys/libos_mmap.c
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ void* libos_syscall_mmap(void* addr, size_t length, int prot, int flags, int fd,
unsigned long offset) {
struct libos_handle* hdl = NULL;
long ret = 0;
bool unlock = false;

ret = check_prot(prot);
if (ret < 0)
Expand Down Expand Up @@ -165,6 +166,10 @@ void* libos_syscall_mmap(void* addr, size_t length, int prot, int flags, int fd,
memory_range_start = g_pal_public_state->memory_address_start;
memory_range_end = g_pal_public_state->memory_address_end;
}

rwlock_read_lock(&checkpoint_lock);
unlock = true;

if (flags & (MAP_FIXED | MAP_FIXED_NOREPLACE)) {
/* We know that `addr + length` does not overflow (`access_ok` above). */
if (addr < memory_range_start || (uintptr_t)memory_range_end < (uintptr_t)addr + length) {
Expand Down Expand Up @@ -270,6 +275,9 @@ void* libos_syscall_mmap(void* addr, size_t length, int prot, int flags, int fd,
}

out_handle:
if (unlock)
rwlock_read_unlock(&checkpoint_lock);

if (hdl) {
put_handle(hdl);
}
Expand Down

0 comments on commit 1acd0fb

Please sign in to comment.