qemu/target
Daniel Henrique Barboza 3a2fc23563 target/riscv: fix satp_mode_finalize() when satp_mode.supported = 0
In the same emulated RISC-V host, the 'host' KVM CPU takes 4 times
longer to boot than the 'rv64' KVM CPU.

The reason is an unintended behavior of riscv_cpu_satp_mode_finalize()
when satp_mode.supported = 0, i.e. when cpu_init() does not set
satp_mode_max_supported(). satp_mode_max_from_map(map) does:

31 - __builtin_clz(map)

This means that, if satp_mode.supported = 0, satp_mode_supported_max
wil be '31 - 32'. But this is C, so satp_mode_supported_max will gladly
set it to UINT_MAX (4294967295). After that, if the user didn't set a
satp_mode, set_satp_mode_default_map(cpu) will make

cfg.satp_mode.map = cfg.satp_mode.supported

So satp_mode.map = 0. And then satp_mode_map_max will be set to
satp_mode_max_from_map(cpu->cfg.satp_mode.map), i.e. also UINT_MAX. The
guard "satp_mode_map_max > satp_mode_supported_max" doesn't protect us
here since both are UINT_MAX.

And finally we have 2 loops:

        for (int i = satp_mode_map_max - 1; i >= 0; --i) {

Which are, in fact, 2 loops from UINT_MAX -1 to -1. This is where the
extra delay when booting the 'host' CPU is coming from.

Commit 43d1de32f8 already set a precedence for satp_mode.supported = 0
in a different manner. We're doing the same here. If supported == 0,
interpret as 'the CPU wants the OS to handle satp mode alone' and skip
satp_mode_finalize().

We'll also put a guard in satp_mode_max_from_map() to assert out if map
is 0 since the function is not ready to deal with it.

Cc: Alexandre Ghiti <alexghiti@rivosinc.com>
Fixes: 6f23aaeb9b ("riscv: Allow user to set the satp mode")
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
Message-ID: <20230817152903.694926-1-dbarboza@ventanamicro.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
2023-09-11 11:45:55 +10:00
..
alpha target/translate: Remove unnecessary 'exec/cpu_ldst.h' header 2023-08-31 19:47:43 +02:00
arm crypto: Create sm4_subword 2023-09-11 11:45:55 +10:00
avr target/translate: Include missing 'exec/cpu_ldst.h' header 2023-08-31 19:47:43 +02:00
cris target/helpers: Remove unnecessary 'exec/cpu_ldst.h' header 2023-08-31 19:47:43 +02:00
hexagon hexagon: spelling fixes 2023-09-08 13:08:52 +03:00
hppa target/translate: Remove unnecessary 'exec/cpu_ldst.h' header 2023-08-31 19:47:43 +02:00
i386 * only build util/async-teardown.c when system build is requested 2023-09-07 10:29:06 -04:00
loongarch target/helpers: Remove unnecessary 'qemu/main-loop.h' header 2023-08-31 19:47:43 +02:00
m68k target/translate: Remove unnecessary 'exec/cpu_ldst.h' header 2023-08-31 19:47:43 +02:00
microblaze target/translate: Remove unnecessary 'exec/cpu_ldst.h' header 2023-08-31 19:47:43 +02:00
mips hw/mips: spelling fixes 2023-08-31 19:47:43 +02:00
nios2 target/helpers: Remove unnecessary 'qemu/main-loop.h' header 2023-08-31 19:47:43 +02:00
openrisc target/translate: Remove unnecessary 'exec/cpu_ldst.h' header 2023-08-31 19:47:43 +02:00
ppc target/ppc: use g_free() in test_opcode_table() 2023-09-08 13:08:52 +03:00
riscv target/riscv: fix satp_mode_finalize() when satp_mode.supported = 0 2023-09-11 11:45:55 +10:00
rx include/exec: Replace target_ulong with abi_ptr in cpu_[st|ld]*() 2023-08-24 11:21:46 -07:00
s390x trace-events: Fix the name of the tracing.rst file 2023-09-08 13:08:51 +03:00
sh4 target/translate: Remove unnecessary 'exec/cpu_ldst.h' header 2023-08-31 19:47:43 +02:00
sparc target/translate: Remove unnecessary 'exec/cpu_ldst.h' header 2023-08-31 19:47:43 +02:00
tricore target/tricore: Replace gen_cond_w with tcg_gen_negsetcond_tl 2023-08-24 11:22:42 -07:00
xtensa target/xtensa: Include missing 'qemu/atomic.h' header 2023-08-31 19:47:43 +02:00
Kconfig hw/loongarch: Add support loongson3 virt machine type. 2022-06-06 18:09:03 +00:00
meson.build target/loongarch: Add target build suport 2022-06-06 18:09:03 +00:00