Skip to content

Commit

Permalink
linux-user/x86_64: Handle the vsyscall page in open_self_maps_{2,4}
Browse files Browse the repository at this point in the history
This is the only case in which we expect to have no host memory backing
for a guest memory page, because in general linux user processes cannot
map any pages in the top half of the 64-bit address space.

Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2170
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
  • Loading branch information
rth7680 committed Mar 1, 2024
1 parent ff20281 commit 4ef1f55
Showing 1 changed file with 16 additions and 0 deletions.
16 changes: 16 additions & 0 deletions linux-user/syscall.c
Original file line number Diff line number Diff line change
Expand Up @@ -7994,6 +7994,10 @@ static void open_self_maps_4(const struct open_self_maps_data *d,
path = "[heap]";
} else if (start == info->vdso) {
path = "[vdso]";
#ifdef TARGET_X86_64
} else if (start == TARGET_VSYSCALL_PAGE) {
path = "[vsyscall]";
#endif
}

/* Except null device (MAP_ANON), adjust offset for this fragment. */
Expand Down Expand Up @@ -8082,6 +8086,18 @@ static int open_self_maps_2(void *opaque, target_ulong guest_start,
uintptr_t host_start = (uintptr_t)g2h_untagged(guest_start);
uintptr_t host_last = (uintptr_t)g2h_untagged(guest_end - 1);

#ifdef TARGET_X86_64
/*
* Because of the extremely high position of the page within the guest
* virtual address space, this is not backed by host memory at all.
* Therefore the loop below would fail. This is the only instance
* of not having host backing memory.
*/
if (guest_start == TARGET_VSYSCALL_PAGE) {
return open_self_maps_3(opaque, guest_start, guest_end, flags);
}
#endif

while (1) {
IntervalTreeNode *n =
interval_tree_iter_first(d->host_maps, host_start, host_start);
Expand Down

0 comments on commit 4ef1f55

Please sign in to comment.