Przeglądaj źródła

linux-user: Allow TARGET_PAGE_BITS_VARY

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>
Acked-by: Helge Deller <deller@gmx.de>
Message-Id: <20240102015808.132373-30-richard.henderson@linaro.org>
Richard Henderson 1 rok temu
rodzic
commit
ff8a8bbc2a
1 zmienionych plików z 13 dodań i 3 usunięć
  1. 13 3
      linux-user/main.c

+ 13 - 3
linux-user/main.c

@@ -55,6 +55,7 @@
 #include "loader.h"
 #include "loader.h"
 #include "user-mmap.h"
 #include "user-mmap.h"
 #include "tcg/perf.h"
 #include "tcg/perf.h"
+#include "exec/page-vary.h"
 
 
 #ifdef CONFIG_SEMIHOSTING
 #ifdef CONFIG_SEMIHOSTING
 #include "semihosting/semihost.h"
 #include "semihosting/semihost.h"
@@ -680,6 +681,7 @@ int main(int argc, char **argv, char **envp)
     int i;
     int i;
     int ret;
     int ret;
     int execfd;
     int execfd;
+    int host_page_size;
     unsigned long max_reserved_va;
     unsigned long max_reserved_va;
     bool preserve_argv0;
     bool preserve_argv0;
 
 
@@ -791,6 +793,16 @@ int main(int argc, char **argv, char **envp)
                                  opt_one_insn_per_tb, &error_abort);
                                  opt_one_insn_per_tb, &error_abort);
         ac->init_machine(NULL);
         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);
     cpu = cpu_create(cpu_type);
     env = cpu_env(cpu);
     env = cpu_env(cpu);
     cpu_reset(cpu);
     cpu_reset(cpu);
@@ -804,8 +816,6 @@ int main(int argc, char **argv, char **envp)
      */
      */
     max_reserved_va = MAX_RESERVED_VA(cpu);
     max_reserved_va = MAX_RESERVED_VA(cpu);
     if (reserved_va != 0) {
     if (reserved_va != 0) {
-        int host_page_size = qemu_real_host_page_size();
-
         if ((reserved_va + 1) % host_page_size) {
         if ((reserved_va + 1) % host_page_size) {
             char *s = size_to_str(host_page_size);
             char *s = size_to_str(host_page_size);
             fprintf(stderr, "Reserved virtual address not aligned mod %s\n", s);
             fprintf(stderr, "Reserved virtual address not aligned mod %s\n", s);
@@ -904,7 +914,7 @@ int main(int argc, char **argv, char **envp)
      * If we're in a chroot with no /proc, fall back to 1 page.
      * If we're in a chroot with no /proc, fall back to 1 page.
      */
      */
     if (mmap_min_addr == 0) {
     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,
         qemu_log_mask(CPU_LOG_PAGE,
                       "host mmap_min_addr=0x%lx (fallback)\n",
                       "host mmap_min_addr=0x%lx (fallback)\n",
                       mmap_min_addr);
                       mmap_min_addr);