diff mbox series

[56/60] linux-user/x86_64: Handle the vsyscall page in open_self_maps_{2, 4}

Message ID 20240301230619.661008-57-richard.henderson@linaro.org
State Accepted
Commit 4ef1f559f270c66b3ffc23f6c845ff3d008c6356
Headers show
Series [01/60] linux-user/elfload: Disable core dump if getrlimit fails | expand

Commit Message

Richard Henderson March 1, 2024, 11:06 p.m. UTC
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>
---
 linux-user/syscall.c | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

Comments

Michael Tokarev April 11, 2024, 10:09 p.m. UTC | #1
On 3/2/24 02:06, Richard Henderson wrote:
> 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>

This change fixes a real bug reported against debian qemu package,
https://bugs.debian.org/1068740 .

It looks like it should be picked up for stable-8.2.  And it looks
like I missed this one when it's been applied to master - usually
I take a look at all stuff going to master and pick fixes from there,
but not this time.  Is there anything else from this series which
needs to go to stable too?

Thanks,

/mjt

>   linux-user/syscall.c | 16 ++++++++++++++++
>   1 file changed, 16 insertions(+)
> 
> diff --git a/linux-user/syscall.c b/linux-user/syscall.c
> index e384e14248..bc8c06522f 100644
> --- a/linux-user/syscall.c
> +++ b/linux-user/syscall.c
> @@ -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. */
> @@ -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);
diff mbox series

Patch

diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index e384e14248..bc8c06522f 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -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. */
@@ -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);