[PATCH v3 29/33] linux-user: Allow TARGET_PAGE_BITS_VARY

Richard Henderson posted 33 patches 10 months, 4 weeks ago
Maintainers: Richard Henderson <richard.henderson@linaro.org>, Paolo Bonzini <pbonzini@redhat.com>, Riku Voipio <riku.voipio@iki.fi>, Warner Losh <imp@bsdimp.com>, Kyle Evans <kevans@freebsd.org>, Stefan Berger <stefanb@linux.vnet.ibm.com>, Eduardo Habkost <eduardo@habkost.net>, Marcel Apfelbaum <marcel.apfelbaum@gmail.com>, "Philippe Mathieu-Daudé" <philmd@linaro.org>, Yanan Wang <wangyanan55@huawei.com>, Laurent Vivier <laurent@vivier.eu>, Peter Xu <peterx@redhat.com>, Fabiano Rosas <farosas@suse.de>, David Hildenbrand <david@redhat.com>, Peter Maydell <peter.maydell@linaro.org>, Nicholas Piggin <npiggin@gmail.com>, Daniel Henrique Barboza <danielhb413@gmail.com>, "Cédric Le Goater" <clg@kaod.org>, "Alex Bennée" <alex.bennee@linaro.org>, Yoshinori Sato <ysato@users.sourceforge.jp>
There is a newer version of this series
[PATCH v3 29/33] linux-user: Allow TARGET_PAGE_BITS_VARY
Posted by Richard Henderson 10 months, 4 weeks ago
If set, match the host and guest page sizes.

Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 linux-user/main.c | 16 +++++++++++++---
 1 file changed, 13 insertions(+), 3 deletions(-)

diff --git a/linux-user/main.c b/linux-user/main.c
index 9ba4dc5872..d00a0d7d1f 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -55,6 +55,7 @@
 #include "loader.h"
 #include "user-mmap.h"
 #include "accel/tcg/perf.h"
+#include "exec/page-vary.h"
 
 #ifdef CONFIG_SEMIHOSTING
 #include "semihosting/semihost.h"
@@ -683,6 +684,7 @@ int main(int argc, char **argv, char **envp)
     int i;
     int ret;
     int execfd;
+    int host_page_size;
     unsigned long max_reserved_va;
     bool preserve_argv0;
 
@@ -794,6 +796,16 @@ int main(int argc, char **argv, char **envp)
                                  opt_one_insn_per_tb, &error_abort);
         ac->init_machine(NULL);
     }
+
+    /*
+     * Finalize page size before creating CPUs.
+     * This will do nothing if !TARGET_PAGE_BITS_VARY.
+     * The most efficient setting is to match the host.
+     */
+    host_page_size = qemu_real_host_page_size();
+    set_preferred_target_page_bits(ctz32(host_page_size));
+    finalize_target_page_bits();
+
     cpu = cpu_create(cpu_type);
     env = cpu_env(cpu);
     cpu_reset(cpu);
@@ -807,8 +819,6 @@ int main(int argc, char **argv, char **envp)
      */
     max_reserved_va = MAX_RESERVED_VA(cpu);
     if (reserved_va != 0) {
-        int host_page_size = qemu_real_host_page_size();
-
         if ((reserved_va + 1) % host_page_size) {
             char *s = size_to_str(host_page_size);
             fprintf(stderr, "Reserved virtual address not aligned mod %s\n", s);
@@ -907,7 +917,7 @@ int main(int argc, char **argv, char **envp)
      * If we're in a chroot with no /proc, fall back to 1 page.
      */
     if (mmap_min_addr == 0) {
-        mmap_min_addr = qemu_real_host_page_size();
+        mmap_min_addr = host_page_size;
         qemu_log_mask(CPU_LOG_PAGE,
                       "host mmap_min_addr=0x%lx (fallback)\n",
                       mmap_min_addr);
-- 
2.34.1


Re: [PATCH v3 29/33] linux-user: Allow TARGET_PAGE_BITS_VARY
Posted by Ilya Leoshkevich 10 months ago
On Tue, Jan 02, 2024 at 12:58:04PM +1100, Richard Henderson wrote:
> If set, match the host and guest page sizes.
> 
> Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>  linux-user/main.c | 16 +++++++++++++---
>  1 file changed, 13 insertions(+), 3 deletions(-)

[...]

> @@ -794,6 +796,16 @@ int main(int argc, char **argv, char **envp)
>                                   opt_one_insn_per_tb, &error_abort);
>          ac->init_machine(NULL);
>      }
> +
> +    /*
> +     * Finalize page size before creating CPUs.
> +     * This will do nothing if !TARGET_PAGE_BITS_VARY.
> +     * The most efficient setting is to match the host.
> +     */
> +    host_page_size = qemu_real_host_page_size();
> +    set_preferred_target_page_bits(ctz32(host_page_size));
> +    finalize_target_page_bits();
> +
>      cpu = cpu_create(cpu_type);
>      env = cpu_env(cpu);
>      cpu_reset(cpu);

Not sure if that's an officially blessed use case, but I tried to
increase the alpha page size to 8k by doing

--- a/target/alpha/cpu-param.h
+++ b/target/alpha/cpu-param.h
@@ -20,7 +20,7 @@
  * a 4k minimum to match x86 host, which can minimize emulation issues.
  */
 # define TARGET_PAGE_BITS_VARY
-# define TARGET_PAGE_BITS_MIN 12
+# define TARGET_PAGE_BITS_MIN 13
 # define TARGET_VIRT_ADDR_SPACE_BITS  63
 #else
 # define TARGET_PAGE_BITS 13

and this triggered an assetion in set_preferred_target_page_bits().
I wonder if it would make sense to add something like the following to
this patch?

--- a/page-vary-target.c
+++ b/page-vary-target.c
@@ -26,8 +26,7 @@
 bool set_preferred_target_page_bits(int bits)
 {
 #ifdef TARGET_PAGE_BITS_VARY
-    assert(bits >= TARGET_PAGE_BITS_MIN);
-    return set_preferred_target_page_bits_common(bits);
+    return set_preferred_target_page_bits_common(MAX(TARGET_PAGE_BITS_MIN, bits));
 #else
     return true;
 #endif
Re: [PATCH v3 29/33] linux-user: Allow TARGET_PAGE_BITS_VARY
Posted by Richard Henderson 9 months, 2 weeks ago
On 1/30/24 03:47, Ilya Leoshkevich wrote:
> I wonder if it would make sense to add something like the following to
> this patch?
> 
> --- a/page-vary-target.c
> +++ b/page-vary-target.c
> @@ -26,8 +26,7 @@
>   bool set_preferred_target_page_bits(int bits)
>   {
>   #ifdef TARGET_PAGE_BITS_VARY
> -    assert(bits >= TARGET_PAGE_BITS_MIN);
> -    return set_preferred_target_page_bits_common(bits);
> +    return set_preferred_target_page_bits_common(MAX(TARGET_PAGE_BITS_MIN, bits));
>   #else
>       return true;
>   #endif

No, this conflicts with the system-mode usage.
If we want to bound, then we need this MAX in the user-only caller.


r~