Message ID | 20240102015808.132373-30-richard.henderson@linaro.org |
---|---|
State | Superseded |
Headers | show |
Series | linux-user: Improve host and guest page size handling | expand |
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
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~
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);