All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH v2 0/4] linux-user fixes for va mapping
@ 2017-10-05 14:35 Richard Henderson
  2017-10-05 14:35 ` [Qemu-devel] [PATCH v2 1/4] linux-user: Allow -R values up to 0xffff0000 for 32-bit ARM guests Richard Henderson
                   ` (4 more replies)
  0 siblings, 5 replies; 8+ messages in thread
From: Richard Henderson @ 2017-10-05 14:35 UTC (permalink / raw)
  To: qemu-devel; +Cc: riku.voipio, peter.maydell

Version 1 was back in July,

  https://lists.gnu.org/archive/html/qemu-devel/2017-07/msg02033.html

  > At first I was simply going to add TARGET_SH to the existing
  > set of defines that trigger a 31-bit address space.  But then
  > I realized that one could create non-working va configurations
  > from the command-line.

Changes since v1:
  * Peter fixes the elfload bug that prevented ARM using the proper
    MAX_RESERVED_VA setting.
  * Adjust the arm MAX_RESERVED_VA.


r~


Peter Maydell (1):
  linux-user: Allow -R values up to 0xffff0000 for 32-bit ARM guests

Richard Henderson (3):
  tcg: Fix off-by-one in assert in page_set_flags
  linux-user: Tidy and enforce reserved_va initialization
  linux-user/sh4: Reduce TARGET_VIRT_ADDR_SPACE_BITS to 31

 linux-user/arm/target_cpu.h |  4 ++++
 target/mips/mips-defs.h     |  6 +++++-
 target/nios2/cpu.h          |  6 +++++-
 target/sh4/cpu.h            |  6 +++++-
 accel/tcg/translate-all.c   |  2 +-
 linux-user/elfload.c        |  2 +-
 linux-user/main.c           | 38 +++++++++++++++++++++++++-------------
 7 files changed, 46 insertions(+), 18 deletions(-)

-- 
2.13.6

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [Qemu-devel] [PATCH v2 1/4] linux-user: Allow -R values up to 0xffff0000 for 32-bit ARM guests
  2017-10-05 14:35 [Qemu-devel] [PATCH v2 0/4] linux-user fixes for va mapping Richard Henderson
@ 2017-10-05 14:35 ` Richard Henderson
  2017-10-05 14:35 ` [Qemu-devel] [PATCH v2 2/4] tcg: Fix off-by-one in assert in page_set_flags Richard Henderson
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 8+ messages in thread
From: Richard Henderson @ 2017-10-05 14:35 UTC (permalink / raw)
  To: qemu-devel; +Cc: riku.voipio, peter.maydell

From: Peter Maydell <peter.maydell@linaro.org>

The 32-bit ARM validate_guest_space() check tests whether the
specified -R value leaves enough space for us to put the
commpage in at 0xffff0f00. However it was incorrectly doing
a <= check for the check against (guest_base + guest_size),
which meant that it wasn't permitting the guest space to
butt right up against the commpage.

Fix the comparison, so that -R values all the way up to 0xffff0000
work correctly.

Reviewed-by: Emilio G. Cota <cota@braap.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Message-Id: <1507047703-10774-1-git-send-email-peter.maydell@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 linux-user/elfload.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/linux-user/elfload.c b/linux-user/elfload.c
index 79062882ba..3b857fbc9c 100644
--- a/linux-user/elfload.c
+++ b/linux-user/elfload.c
@@ -377,7 +377,7 @@ static int validate_guest_space(unsigned long guest_base,
      * then there is no way we can allocate it.
      */
     if (test_page_addr >= guest_base
-        && test_page_addr <= (guest_base + guest_size)) {
+        && test_page_addr < (guest_base + guest_size)) {
         return -1;
     }
 
-- 
2.13.6

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [Qemu-devel] [PATCH v2 2/4] tcg: Fix off-by-one in assert in page_set_flags
  2017-10-05 14:35 [Qemu-devel] [PATCH v2 0/4] linux-user fixes for va mapping Richard Henderson
  2017-10-05 14:35 ` [Qemu-devel] [PATCH v2 1/4] linux-user: Allow -R values up to 0xffff0000 for 32-bit ARM guests Richard Henderson
@ 2017-10-05 14:35 ` Richard Henderson
  2017-10-05 14:36 ` [Qemu-devel] [PATCH v2 3/4] linux-user: Tidy and enforce reserved_va initialization Richard Henderson
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 8+ messages in thread
From: Richard Henderson @ 2017-10-05 14:35 UTC (permalink / raw)
  To: qemu-devel; +Cc: riku.voipio, peter.maydell, Richard Henderson

From: Richard Henderson <rth@twiddle.net>

Most of the users of page_set_flags offset (page, page + len) as
the end points.  One might consider this an error, since the other
users do supply an endpoint as the last byte of the region.

However, the first thing that page_set_flags does is round end UP
to the start of the next page.  Which means computing page + len - 1
is in the end pointless.  Therefore, accept this usage and do not
assert when given the exact size of the vm as the endpoint.

Signed-off-by: Richard Henderson <rth@twiddle.net>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Message-Id: <20170708025030.15845-2-rth@twiddle.net>
---
 accel/tcg/translate-all.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/accel/tcg/translate-all.c b/accel/tcg/translate-all.c
index 2d1ed06065..ebfc2e7024 100644
--- a/accel/tcg/translate-all.c
+++ b/accel/tcg/translate-all.c
@@ -2090,7 +2090,7 @@ void page_set_flags(target_ulong start, target_ulong end, int flags)
        guest address space.  If this assert fires, it probably indicates
        a missing call to h2g_valid.  */
 #if TARGET_ABI_BITS > L1_MAP_ADDR_SPACE_BITS
-    assert(end < ((target_ulong)1 << L1_MAP_ADDR_SPACE_BITS));
+    assert(end <= ((target_ulong)1 << L1_MAP_ADDR_SPACE_BITS));
 #endif
     assert(start < end);
     assert_memory_lock();
-- 
2.13.6

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [Qemu-devel] [PATCH v2 3/4] linux-user: Tidy and enforce reserved_va initialization
  2017-10-05 14:35 [Qemu-devel] [PATCH v2 0/4] linux-user fixes for va mapping Richard Henderson
  2017-10-05 14:35 ` [Qemu-devel] [PATCH v2 1/4] linux-user: Allow -R values up to 0xffff0000 for 32-bit ARM guests Richard Henderson
  2017-10-05 14:35 ` [Qemu-devel] [PATCH v2 2/4] tcg: Fix off-by-one in assert in page_set_flags Richard Henderson
@ 2017-10-05 14:36 ` Richard Henderson
  2018-01-12 20:37   ` Alistair Francis
  2017-10-05 14:36 ` [Qemu-devel] [PATCH v2 4/4] linux-user/sh4: Reduce TARGET_VIRT_ADDR_SPACE_BITS to 31 Richard Henderson
  2017-10-16 12:41 ` [Qemu-devel] [PATCH v2 0/4] linux-user fixes for va mapping Riku Voipio
  4 siblings, 1 reply; 8+ messages in thread
From: Richard Henderson @ 2017-10-05 14:36 UTC (permalink / raw)
  To: qemu-devel; +Cc: riku.voipio, peter.maydell, Richard Henderson

From: Richard Henderson <rth@twiddle.net>

We had a check using TARGET_VIRT_ADDR_SPACE_BITS to make sure
that the allocation coming in from the command-line option was
not too large, but that didn't include target-specific knowledge
about other restrictions on user-space.

Remove several target-specific hacks in linux-user/main.c.

For MIPS and Nios, we can replace them with proper adjustments
to the respective target's TARGET_VIRT_ADDR_SPACE_BITS definition.

For ARM, we had no existing ifdef but I suspect that the current
default value of 0xf7000000 was chosen with this in mind.  Define
a workable value in linux-user/arm/, and also document why the
special case is required.

Signed-off-by: Richard Henderson <rth@twiddle.net>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Message-Id: <20170708025030.15845-3-rth@twiddle.net>
---
 linux-user/arm/target_cpu.h |  4 ++++
 target/mips/mips-defs.h     |  6 +++++-
 target/nios2/cpu.h          |  6 +++++-
 linux-user/main.c           | 38 +++++++++++++++++++++++++-------------
 4 files changed, 39 insertions(+), 15 deletions(-)

diff --git a/linux-user/arm/target_cpu.h b/linux-user/arm/target_cpu.h
index d888219150..c3eb4b243d 100644
--- a/linux-user/arm/target_cpu.h
+++ b/linux-user/arm/target_cpu.h
@@ -19,6 +19,10 @@
 #ifndef ARM_TARGET_CPU_H
 #define ARM_TARGET_CPU_H
 
+/* We need to be able to map the commpage.
+   See validate_guest_space in linux-user/elfload.c.  */
+#define MAX_RESERVED_VA  0xffff0000ul
+
 static inline void cpu_clone_regs(CPUARMState *env, target_ulong newsp)
 {
     if (newsp) {
diff --git a/target/mips/mips-defs.h b/target/mips/mips-defs.h
index 047554ee45..d239069975 100644
--- a/target/mips/mips-defs.h
+++ b/target/mips/mips-defs.h
@@ -15,7 +15,11 @@
 #else
 #define TARGET_LONG_BITS 32
 #define TARGET_PHYS_ADDR_SPACE_BITS 40
-#define TARGET_VIRT_ADDR_SPACE_BITS 32
+# ifdef CONFIG_USER_ONLY
+#  define TARGET_VIRT_ADDR_SPACE_BITS 31
+# else
+#  define TARGET_VIRT_ADDR_SPACE_BITS 32
+#endif
 #endif
 
 /* Masks used to mark instructions to indicate which ISA level they
diff --git a/target/nios2/cpu.h b/target/nios2/cpu.h
index 50d803a217..9119eee587 100644
--- a/target/nios2/cpu.h
+++ b/target/nios2/cpu.h
@@ -226,7 +226,11 @@ qemu_irq *nios2_cpu_pic_init(Nios2CPU *cpu);
 void nios2_check_interrupts(CPUNios2State *env);
 
 #define TARGET_PHYS_ADDR_SPACE_BITS 32
-#define TARGET_VIRT_ADDR_SPACE_BITS 32
+#ifdef CONFIG_USER_ONLY
+# define TARGET_VIRT_ADDR_SPACE_BITS 31
+#else
+# define TARGET_VIRT_ADDR_SPACE_BITS 32
+#endif
 
 #define cpu_init(cpu_model) cpu_generic_init(TYPE_NIOS2_CPU, cpu_model)
 
diff --git a/linux-user/main.c b/linux-user/main.c
index 829f974662..fd54d344bb 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -60,23 +60,38 @@ do {                                                                    \
     }                                                                   \
 } while (0)
 
-#if (TARGET_LONG_BITS == 32) && (HOST_LONG_BITS == 64)
 /*
  * When running 32-on-64 we should make sure we can fit all of the possible
  * guest address space into a contiguous chunk of virtual host memory.
  *
  * This way we will never overlap with our own libraries or binaries or stack
  * or anything else that QEMU maps.
+ *
+ * Many cpus reserve the high bit (or more than one for some 64-bit cpus)
+ * of the address for the kernel.  Some cpus rely on this and user space
+ * uses the high bit(s) for pointer tagging and the like.  For them, we
+ * must preserve the expected address space.
  */
-# if defined(TARGET_MIPS) || defined(TARGET_NIOS2)
-/*
- * MIPS only supports 31 bits of virtual address space for user space.
- * Nios2 also only supports 31 bits.
- */
-unsigned long reserved_va = 0x77000000;
+#ifndef MAX_RESERVED_VA
+# if HOST_LONG_BITS > TARGET_VIRT_ADDR_SPACE_BITS
+#  if TARGET_VIRT_ADDR_SPACE_BITS == 32 && \
+      (TARGET_LONG_BITS == 32 || defined(TARGET_ABI32))
+/* There are a number of places where we assign reserved_va to a variable
+   of type abi_ulong and expect it to fit.  Avoid the last page.  */
+#   define MAX_RESERVED_VA  (0xfffffffful & TARGET_PAGE_MASK)
+#  else
+#   define MAX_RESERVED_VA  (1ul << TARGET_VIRT_ADDR_SPACE_BITS)
+#  endif
 # else
-unsigned long reserved_va = 0xf7000000;
+#  define MAX_RESERVED_VA  0
 # endif
+#endif
+
+/* That said, reserving *too* much vm space via mmap can run into problems
+   with rlimits, oom due to page table creation, etc.  We will still try it,
+   if directed by the command-line option, but not by default.  */
+#if HOST_LONG_BITS == 64 && TARGET_VIRT_ADDR_SPACE_BITS <= 32
+unsigned long reserved_va = MAX_RESERVED_VA;
 #else
 unsigned long reserved_va;
 #endif
@@ -3978,11 +3993,8 @@ static void handle_arg_reserved_va(const char *arg)
         unsigned long unshifted = reserved_va;
         p++;
         reserved_va <<= shift;
-        if (((reserved_va >> shift) != unshifted)
-#if HOST_LONG_BITS > TARGET_VIRT_ADDR_SPACE_BITS
-            || (reserved_va > (1ul << TARGET_VIRT_ADDR_SPACE_BITS))
-#endif
-            ) {
+        if (reserved_va >> shift != unshifted
+            || (MAX_RESERVED_VA && reserved_va > MAX_RESERVED_VA)) {
             fprintf(stderr, "Reserved virtual address too big\n");
             exit(EXIT_FAILURE);
         }
-- 
2.13.6

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [Qemu-devel] [PATCH v2 4/4] linux-user/sh4: Reduce TARGET_VIRT_ADDR_SPACE_BITS to 31
  2017-10-05 14:35 [Qemu-devel] [PATCH v2 0/4] linux-user fixes for va mapping Richard Henderson
                   ` (2 preceding siblings ...)
  2017-10-05 14:36 ` [Qemu-devel] [PATCH v2 3/4] linux-user: Tidy and enforce reserved_va initialization Richard Henderson
@ 2017-10-05 14:36 ` Richard Henderson
  2017-10-16 12:41 ` [Qemu-devel] [PATCH v2 0/4] linux-user fixes for va mapping Riku Voipio
  4 siblings, 0 replies; 8+ messages in thread
From: Richard Henderson @ 2017-10-05 14:36 UTC (permalink / raw)
  To: qemu-devel; +Cc: riku.voipio, peter.maydell, Richard Henderson

From: Richard Henderson <rth@twiddle.net>

The real kernel has TASK_SIZE as 0x7c000000, due to quirks with
a couple of SH parts.  But nominally user-space is limited to 2GB.

Signed-off-by: Richard Henderson <rth@twiddle.net>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Message-Id: <20170708025030.15845-4-rth@twiddle.net>
---
 target/sh4/cpu.h | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/target/sh4/cpu.h b/target/sh4/cpu.h
index 79f85d3365..123f34783a 100644
--- a/target/sh4/cpu.h
+++ b/target/sh4/cpu.h
@@ -45,7 +45,11 @@
 #define TARGET_PAGE_BITS 12	/* 4k XXXXX */
 
 #define TARGET_PHYS_ADDR_SPACE_BITS 32
-#define TARGET_VIRT_ADDR_SPACE_BITS 32
+#ifdef CONFIG_USER_ONLY
+# define TARGET_VIRT_ADDR_SPACE_BITS 31
+#else
+# define TARGET_VIRT_ADDR_SPACE_BITS 32
+#endif
 
 #define SR_MD 30
 #define SR_RB 29
-- 
2.13.6

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [Qemu-devel] [PATCH v2 0/4] linux-user fixes for va mapping
  2017-10-05 14:35 [Qemu-devel] [PATCH v2 0/4] linux-user fixes for va mapping Richard Henderson
                   ` (3 preceding siblings ...)
  2017-10-05 14:36 ` [Qemu-devel] [PATCH v2 4/4] linux-user/sh4: Reduce TARGET_VIRT_ADDR_SPACE_BITS to 31 Richard Henderson
@ 2017-10-16 12:41 ` Riku Voipio
  4 siblings, 0 replies; 8+ messages in thread
From: Riku Voipio @ 2017-10-16 12:41 UTC (permalink / raw)
  To: Richard Henderson; +Cc: qemu-devel, peter.maydell

On Thu, Oct 05, 2017 at 10:35:57AM -0400, Richard Henderson wrote:
> Version 1 was back in July,
> 
>   https://lists.gnu.org/archive/html/qemu-devel/2017-07/msg02033.html
> 
>   > At first I was simply going to add TARGET_SH to the existing
>   > set of defines that trigger a 31-bit address space.  But then
>   > I realized that one could create non-working va configurations
>   > from the command-line.
> 
> Changes since v1:
>   * Peter fixes the elfload bug that prevented ARM using the proper
>     MAX_RESERVED_VA setting.
>   * Adjust the arm MAX_RESERVED_VA.
> 

Thanks, applied to linux-user
 
> r~
> 
> 
> Peter Maydell (1):
>   linux-user: Allow -R values up to 0xffff0000 for 32-bit ARM guests
> 
> Richard Henderson (3):
>   tcg: Fix off-by-one in assert in page_set_flags
>   linux-user: Tidy and enforce reserved_va initialization
>   linux-user/sh4: Reduce TARGET_VIRT_ADDR_SPACE_BITS to 31
> 
>  linux-user/arm/target_cpu.h |  4 ++++
>  target/mips/mips-defs.h     |  6 +++++-
>  target/nios2/cpu.h          |  6 +++++-
>  target/sh4/cpu.h            |  6 +++++-
>  accel/tcg/translate-all.c   |  2 +-
>  linux-user/elfload.c        |  2 +-
>  linux-user/main.c           | 38 +++++++++++++++++++++++++-------------
>  7 files changed, 46 insertions(+), 18 deletions(-)
> 
> -- 
> 2.13.6
> 

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [Qemu-devel] [PATCH v2 3/4] linux-user: Tidy and enforce reserved_va initialization
  2017-10-05 14:36 ` [Qemu-devel] [PATCH v2 3/4] linux-user: Tidy and enforce reserved_va initialization Richard Henderson
@ 2018-01-12 20:37   ` Alistair Francis
  2018-01-12 22:12     ` Alistair Francis
  0 siblings, 1 reply; 8+ messages in thread
From: Alistair Francis @ 2018-01-12 20:37 UTC (permalink / raw)
  To: Richard Henderson
  Cc: qemu-devel@nongnu.org Developers, Peter Maydell, riku.voipio,
	Richard Henderson

On Thu, Oct 5, 2017 at 7:36 AM, Richard Henderson
<richard.henderson@linaro.org> wrote:
> From: Richard Henderson <rth@twiddle.net>
>
> We had a check using TARGET_VIRT_ADDR_SPACE_BITS to make sure
> that the allocation coming in from the command-line option was
> not too large, but that didn't include target-specific knowledge
> about other restrictions on user-space.
>
> Remove several target-specific hacks in linux-user/main.c.
>
> For MIPS and Nios, we can replace them with proper adjustments
> to the respective target's TARGET_VIRT_ADDR_SPACE_BITS definition.
>
> For ARM, we had no existing ifdef but I suspect that the current
> default value of 0xf7000000 was chosen with this in mind.  Define
> a workable value in linux-user/arm/, and also document why the
> special case is required.
>
> Signed-off-by: Richard Henderson <rth@twiddle.net>
> Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
> Message-Id: <20170708025030.15845-3-rth@twiddle.net>

Hey,

I just had the arduous task of bisecting QEMU 2.10 and 2.11 to figure
out that somehow this patch causes the Yocto webkitgtk build for x86
to hang.

Any ideas?

My host is 64-bit x86 and I'm building for 32-bit x86. I'm going to
test now to see if I see the same hang building for 64-bit. I am not
sure yet where QEMU usermode is used, but apparently it is.

Thanks,
Alistair

> ---
>  linux-user/arm/target_cpu.h |  4 ++++
>  target/mips/mips-defs.h     |  6 +++++-
>  target/nios2/cpu.h          |  6 +++++-
>  linux-user/main.c           | 38 +++++++++++++++++++++++++-------------
>  4 files changed, 39 insertions(+), 15 deletions(-)
>
> diff --git a/linux-user/arm/target_cpu.h b/linux-user/arm/target_cpu.h
> index d888219150..c3eb4b243d 100644
> --- a/linux-user/arm/target_cpu.h
> +++ b/linux-user/arm/target_cpu.h
> @@ -19,6 +19,10 @@
>  #ifndef ARM_TARGET_CPU_H
>  #define ARM_TARGET_CPU_H
>
> +/* We need to be able to map the commpage.
> +   See validate_guest_space in linux-user/elfload.c.  */
> +#define MAX_RESERVED_VA  0xffff0000ul
> +
>  static inline void cpu_clone_regs(CPUARMState *env, target_ulong newsp)
>  {
>      if (newsp) {
> diff --git a/target/mips/mips-defs.h b/target/mips/mips-defs.h
> index 047554ee45..d239069975 100644
> --- a/target/mips/mips-defs.h
> +++ b/target/mips/mips-defs.h
> @@ -15,7 +15,11 @@
>  #else
>  #define TARGET_LONG_BITS 32
>  #define TARGET_PHYS_ADDR_SPACE_BITS 40
> -#define TARGET_VIRT_ADDR_SPACE_BITS 32
> +# ifdef CONFIG_USER_ONLY
> +#  define TARGET_VIRT_ADDR_SPACE_BITS 31
> +# else
> +#  define TARGET_VIRT_ADDR_SPACE_BITS 32
> +#endif
>  #endif
>
>  /* Masks used to mark instructions to indicate which ISA level they
> diff --git a/target/nios2/cpu.h b/target/nios2/cpu.h
> index 50d803a217..9119eee587 100644
> --- a/target/nios2/cpu.h
> +++ b/target/nios2/cpu.h
> @@ -226,7 +226,11 @@ qemu_irq *nios2_cpu_pic_init(Nios2CPU *cpu);
>  void nios2_check_interrupts(CPUNios2State *env);
>
>  #define TARGET_PHYS_ADDR_SPACE_BITS 32
> -#define TARGET_VIRT_ADDR_SPACE_BITS 32
> +#ifdef CONFIG_USER_ONLY
> +# define TARGET_VIRT_ADDR_SPACE_BITS 31
> +#else
> +# define TARGET_VIRT_ADDR_SPACE_BITS 32
> +#endif
>
>  #define cpu_init(cpu_model) cpu_generic_init(TYPE_NIOS2_CPU, cpu_model)
>
> diff --git a/linux-user/main.c b/linux-user/main.c
> index 829f974662..fd54d344bb 100644
> --- a/linux-user/main.c
> +++ b/linux-user/main.c
> @@ -60,23 +60,38 @@ do {                                                                    \
>      }                                                                   \
>  } while (0)
>
> -#if (TARGET_LONG_BITS == 32) && (HOST_LONG_BITS == 64)
>  /*
>   * When running 32-on-64 we should make sure we can fit all of the possible
>   * guest address space into a contiguous chunk of virtual host memory.
>   *
>   * This way we will never overlap with our own libraries or binaries or stack
>   * or anything else that QEMU maps.
> + *
> + * Many cpus reserve the high bit (or more than one for some 64-bit cpus)
> + * of the address for the kernel.  Some cpus rely on this and user space
> + * uses the high bit(s) for pointer tagging and the like.  For them, we
> + * must preserve the expected address space.
>   */
> -# if defined(TARGET_MIPS) || defined(TARGET_NIOS2)
> -/*
> - * MIPS only supports 31 bits of virtual address space for user space.
> - * Nios2 also only supports 31 bits.
> - */
> -unsigned long reserved_va = 0x77000000;
> +#ifndef MAX_RESERVED_VA
> +# if HOST_LONG_BITS > TARGET_VIRT_ADDR_SPACE_BITS
> +#  if TARGET_VIRT_ADDR_SPACE_BITS == 32 && \
> +      (TARGET_LONG_BITS == 32 || defined(TARGET_ABI32))
> +/* There are a number of places where we assign reserved_va to a variable
> +   of type abi_ulong and expect it to fit.  Avoid the last page.  */
> +#   define MAX_RESERVED_VA  (0xfffffffful & TARGET_PAGE_MASK)
> +#  else
> +#   define MAX_RESERVED_VA  (1ul << TARGET_VIRT_ADDR_SPACE_BITS)
> +#  endif
>  # else
> -unsigned long reserved_va = 0xf7000000;
> +#  define MAX_RESERVED_VA  0
>  # endif
> +#endif
> +
> +/* That said, reserving *too* much vm space via mmap can run into problems
> +   with rlimits, oom due to page table creation, etc.  We will still try it,
> +   if directed by the command-line option, but not by default.  */
> +#if HOST_LONG_BITS == 64 && TARGET_VIRT_ADDR_SPACE_BITS <= 32
> +unsigned long reserved_va = MAX_RESERVED_VA;
>  #else
>  unsigned long reserved_va;
>  #endif
> @@ -3978,11 +3993,8 @@ static void handle_arg_reserved_va(const char *arg)
>          unsigned long unshifted = reserved_va;
>          p++;
>          reserved_va <<= shift;
> -        if (((reserved_va >> shift) != unshifted)
> -#if HOST_LONG_BITS > TARGET_VIRT_ADDR_SPACE_BITS
> -            || (reserved_va > (1ul << TARGET_VIRT_ADDR_SPACE_BITS))
> -#endif
> -            ) {
> +        if (reserved_va >> shift != unshifted
> +            || (MAX_RESERVED_VA && reserved_va > MAX_RESERVED_VA)) {
>              fprintf(stderr, "Reserved virtual address too big\n");
>              exit(EXIT_FAILURE);
>          }
> --
> 2.13.6
>
>

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [Qemu-devel] [PATCH v2 3/4] linux-user: Tidy and enforce reserved_va initialization
  2018-01-12 20:37   ` Alistair Francis
@ 2018-01-12 22:12     ` Alistair Francis
  0 siblings, 0 replies; 8+ messages in thread
From: Alistair Francis @ 2018-01-12 22:12 UTC (permalink / raw)
  To: Richard Henderson
  Cc: qemu-devel@nongnu.org Developers, Peter Maydell, riku.voipio,
	Richard Henderson

On Fri, Jan 12, 2018 at 12:37 PM, Alistair Francis <alistair23@gmail.com> wrote:
> On Thu, Oct 5, 2017 at 7:36 AM, Richard Henderson
> <richard.henderson@linaro.org> wrote:
>> From: Richard Henderson <rth@twiddle.net>
>>
>> We had a check using TARGET_VIRT_ADDR_SPACE_BITS to make sure
>> that the allocation coming in from the command-line option was
>> not too large, but that didn't include target-specific knowledge
>> about other restrictions on user-space.
>>
>> Remove several target-specific hacks in linux-user/main.c.
>>
>> For MIPS and Nios, we can replace them with proper adjustments
>> to the respective target's TARGET_VIRT_ADDR_SPACE_BITS definition.
>>
>> For ARM, we had no existing ifdef but I suspect that the current
>> default value of 0xf7000000 was chosen with this in mind.  Define
>> a workable value in linux-user/arm/, and also document why the
>> special case is required.
>>
>> Signed-off-by: Richard Henderson <rth@twiddle.net>
>> Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
>> Message-Id: <20170708025030.15845-3-rth@twiddle.net>
>
> Hey,
>
> I just had the arduous task of bisecting QEMU 2.10 and 2.11 to figure
> out that somehow this patch causes the Yocto webkitgtk build for x86
> to hang.
>
> Any ideas?
>
> My host is 64-bit x86 and I'm building for 32-bit x86. I'm going to
> test now to see if I see the same hang building for 64-bit. I am not
> sure yet where QEMU usermode is used, but apparently it is.

The hang only occurs if building for x86-32bit on a 64-bit machine.

Alistair

>
> Thanks,
> Alistair
>
>> ---
>>  linux-user/arm/target_cpu.h |  4 ++++
>>  target/mips/mips-defs.h     |  6 +++++-
>>  target/nios2/cpu.h          |  6 +++++-
>>  linux-user/main.c           | 38 +++++++++++++++++++++++++-------------
>>  4 files changed, 39 insertions(+), 15 deletions(-)
>>
>> diff --git a/linux-user/arm/target_cpu.h b/linux-user/arm/target_cpu.h
>> index d888219150..c3eb4b243d 100644
>> --- a/linux-user/arm/target_cpu.h
>> +++ b/linux-user/arm/target_cpu.h
>> @@ -19,6 +19,10 @@
>>  #ifndef ARM_TARGET_CPU_H
>>  #define ARM_TARGET_CPU_H
>>
>> +/* We need to be able to map the commpage.
>> +   See validate_guest_space in linux-user/elfload.c.  */
>> +#define MAX_RESERVED_VA  0xffff0000ul
>> +
>>  static inline void cpu_clone_regs(CPUARMState *env, target_ulong newsp)
>>  {
>>      if (newsp) {
>> diff --git a/target/mips/mips-defs.h b/target/mips/mips-defs.h
>> index 047554ee45..d239069975 100644
>> --- a/target/mips/mips-defs.h
>> +++ b/target/mips/mips-defs.h
>> @@ -15,7 +15,11 @@
>>  #else
>>  #define TARGET_LONG_BITS 32
>>  #define TARGET_PHYS_ADDR_SPACE_BITS 40
>> -#define TARGET_VIRT_ADDR_SPACE_BITS 32
>> +# ifdef CONFIG_USER_ONLY
>> +#  define TARGET_VIRT_ADDR_SPACE_BITS 31
>> +# else
>> +#  define TARGET_VIRT_ADDR_SPACE_BITS 32
>> +#endif
>>  #endif
>>
>>  /* Masks used to mark instructions to indicate which ISA level they
>> diff --git a/target/nios2/cpu.h b/target/nios2/cpu.h
>> index 50d803a217..9119eee587 100644
>> --- a/target/nios2/cpu.h
>> +++ b/target/nios2/cpu.h
>> @@ -226,7 +226,11 @@ qemu_irq *nios2_cpu_pic_init(Nios2CPU *cpu);
>>  void nios2_check_interrupts(CPUNios2State *env);
>>
>>  #define TARGET_PHYS_ADDR_SPACE_BITS 32
>> -#define TARGET_VIRT_ADDR_SPACE_BITS 32
>> +#ifdef CONFIG_USER_ONLY
>> +# define TARGET_VIRT_ADDR_SPACE_BITS 31
>> +#else
>> +# define TARGET_VIRT_ADDR_SPACE_BITS 32
>> +#endif
>>
>>  #define cpu_init(cpu_model) cpu_generic_init(TYPE_NIOS2_CPU, cpu_model)
>>
>> diff --git a/linux-user/main.c b/linux-user/main.c
>> index 829f974662..fd54d344bb 100644
>> --- a/linux-user/main.c
>> +++ b/linux-user/main.c
>> @@ -60,23 +60,38 @@ do {                                                                    \
>>      }                                                                   \
>>  } while (0)
>>
>> -#if (TARGET_LONG_BITS == 32) && (HOST_LONG_BITS == 64)
>>  /*
>>   * When running 32-on-64 we should make sure we can fit all of the possible
>>   * guest address space into a contiguous chunk of virtual host memory.
>>   *
>>   * This way we will never overlap with our own libraries or binaries or stack
>>   * or anything else that QEMU maps.
>> + *
>> + * Many cpus reserve the high bit (or more than one for some 64-bit cpus)
>> + * of the address for the kernel.  Some cpus rely on this and user space
>> + * uses the high bit(s) for pointer tagging and the like.  For them, we
>> + * must preserve the expected address space.
>>   */
>> -# if defined(TARGET_MIPS) || defined(TARGET_NIOS2)
>> -/*
>> - * MIPS only supports 31 bits of virtual address space for user space.
>> - * Nios2 also only supports 31 bits.
>> - */
>> -unsigned long reserved_va = 0x77000000;
>> +#ifndef MAX_RESERVED_VA
>> +# if HOST_LONG_BITS > TARGET_VIRT_ADDR_SPACE_BITS
>> +#  if TARGET_VIRT_ADDR_SPACE_BITS == 32 && \
>> +      (TARGET_LONG_BITS == 32 || defined(TARGET_ABI32))
>> +/* There are a number of places where we assign reserved_va to a variable
>> +   of type abi_ulong and expect it to fit.  Avoid the last page.  */
>> +#   define MAX_RESERVED_VA  (0xfffffffful & TARGET_PAGE_MASK)
>> +#  else
>> +#   define MAX_RESERVED_VA  (1ul << TARGET_VIRT_ADDR_SPACE_BITS)
>> +#  endif
>>  # else
>> -unsigned long reserved_va = 0xf7000000;
>> +#  define MAX_RESERVED_VA  0
>>  # endif
>> +#endif
>> +
>> +/* That said, reserving *too* much vm space via mmap can run into problems
>> +   with rlimits, oom due to page table creation, etc.  We will still try it,
>> +   if directed by the command-line option, but not by default.  */
>> +#if HOST_LONG_BITS == 64 && TARGET_VIRT_ADDR_SPACE_BITS <= 32
>> +unsigned long reserved_va = MAX_RESERVED_VA;
>>  #else
>>  unsigned long reserved_va;
>>  #endif
>> @@ -3978,11 +3993,8 @@ static void handle_arg_reserved_va(const char *arg)
>>          unsigned long unshifted = reserved_va;
>>          p++;
>>          reserved_va <<= shift;
>> -        if (((reserved_va >> shift) != unshifted)
>> -#if HOST_LONG_BITS > TARGET_VIRT_ADDR_SPACE_BITS
>> -            || (reserved_va > (1ul << TARGET_VIRT_ADDR_SPACE_BITS))
>> -#endif
>> -            ) {
>> +        if (reserved_va >> shift != unshifted
>> +            || (MAX_RESERVED_VA && reserved_va > MAX_RESERVED_VA)) {
>>              fprintf(stderr, "Reserved virtual address too big\n");
>>              exit(EXIT_FAILURE);
>>          }
>> --
>> 2.13.6
>>
>>

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2018-01-12 22:12 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-10-05 14:35 [Qemu-devel] [PATCH v2 0/4] linux-user fixes for va mapping Richard Henderson
2017-10-05 14:35 ` [Qemu-devel] [PATCH v2 1/4] linux-user: Allow -R values up to 0xffff0000 for 32-bit ARM guests Richard Henderson
2017-10-05 14:35 ` [Qemu-devel] [PATCH v2 2/4] tcg: Fix off-by-one in assert in page_set_flags Richard Henderson
2017-10-05 14:36 ` [Qemu-devel] [PATCH v2 3/4] linux-user: Tidy and enforce reserved_va initialization Richard Henderson
2018-01-12 20:37   ` Alistair Francis
2018-01-12 22:12     ` Alistair Francis
2017-10-05 14:36 ` [Qemu-devel] [PATCH v2 4/4] linux-user/sh4: Reduce TARGET_VIRT_ADDR_SPACE_BITS to 31 Richard Henderson
2017-10-16 12:41 ` [Qemu-devel] [PATCH v2 0/4] linux-user fixes for va mapping Riku Voipio

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.