qemu-riscv
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH v8 3/3] hw/riscv: clear kernel_entry higher bits in load_elf_


From: Daniel Henrique Barboza
Subject: Re: [PATCH v8 3/3] hw/riscv: clear kernel_entry higher bits in load_elf_ram_sym()
Date: Wed, 18 Jan 2023 20:34:41 -0300
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 Thunderbird/102.6.0



On 1/18/23 19:45, Alistair Francis wrote:
On Mon, Jan 16, 2023 at 10:46 PM Daniel Henrique Barboza
<dbarboza@ventanamicro.com> wrote:


On 1/16/23 09:37, Philippe Mathieu-Daudé wrote:
On 16/1/23 13:29, Daniel Henrique Barboza wrote:
Recent hw/risc/boot.c changes caused a regression in an use case with
the Xvisor hypervisor. Running a 32 bit QEMU guest with '-kernel'
stopped working. The reason seems to be that Xvisor is using 64 bit to
encode the 32 bit addresses from the guest, and load_elf_ram_sym() is
sign-extending the result with '1's [1].

Use a translate_fn() callback to be called by load_elf_ram_sym() and
return only the 32 bits address if we're running a 32 bit CPU.

[1] https://lists.gnu.org/archive/html/qemu-devel/2023-01/msg02281.html

Suggested-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Suggested-by: Bin Meng <bmeng.cn@gmail.com>
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
---
   hw/riscv/boot.c            | 20 +++++++++++++++++++-
   hw/riscv/microchip_pfsoc.c |  4 ++--
   hw/riscv/opentitan.c       |  3 ++-
   hw/riscv/sifive_e.c        |  3 ++-
   hw/riscv/sifive_u.c        |  4 ++--
   hw/riscv/spike.c           |  2 +-
   hw/riscv/virt.c            |  4 ++--
   include/hw/riscv/boot.h    |  1 +
   target/riscv/cpu_bits.h    |  1 +
   9 files changed, 32 insertions(+), 10 deletions(-)

diff --git a/hw/riscv/boot.c b/hw/riscv/boot.c
index e868fb6ade..0fd39df7f3 100644
--- a/hw/riscv/boot.c
+++ b/hw/riscv/boot.c
@@ -213,7 +213,24 @@ static void riscv_load_initrd(MachineState *machine, 
uint64_t kernel_entry)
       }
   }
   +static uint64_t translate_kernel_address(void *opaque, uint64_t addr)
+{
+    RISCVHartArrayState *harts = opaque;
+
+    /*
+     * For 32 bit CPUs, kernel_load_base is sign-extended (i.e.
+     * it can be padded with '1's) if the hypervisor is using
+     * 64 bit addresses with 32 bit guests.
+     */
+    if (riscv_is_32bit(harts)) {
Maybe move the comment within the if() and add " so remove the sign
extension by truncating to 32-bit".

+        return extract64(addr, 0, RV32_KERNEL_ADDR_LEN);
For 32-bit maybe a definition is not necessary, I asked before
you used 24-bit in the previous version. As the maintainer prefer :)
That was unintentional. I missed a 'f' in that 0x0fffffff, which I noticed only
now when doing this version. It's curious because Alistair mentioned that
the patch apparently solved the bug ....
I never tested it, I'm not sure if this solves the problem or not.

This patch needs to be merged *before* the initrd patch (patch 1 of
this series) to avoid breaking users.

Makes sense. I'll change it in v9.

Daniel

I don't mind creating a macro for the 32 bit value. If we decide it's unneeded
I can remove it and just put a '32' there. I'll also make the comment change
you mentioned above.
I think 32 if fine, I don't think we need a macro

Alistair


Thanks,


Daniel

+    }
+
+    return addr;
+}
diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
index 8b0d7e20ea..8fcaeae342 100644
--- a/target/riscv/cpu_bits.h
+++ b/target/riscv/cpu_bits.h
@@ -751,6 +751,7 @@ typedef enum RISCVException {
   #define MENVCFG_STCE                       (1ULL << 63)
     /* For RV32 */
+#define RV32_KERNEL_ADDR_LEN               32
   #define MENVCFGH_PBMTE                     BIT(30)
   #define MENVCFGH_STCE                      BIT(31)
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>







reply via email to

[Prev in Thread] Current Thread [Next in Thread]