From: Alistair Francis <alistair23@gmail.com>
To: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
Cc: Bin Meng <bmeng.cn@gmail.com>,
qemu-devel@nongnu.org, qemu-riscv@nongnu.org,
alistair.francis@wdc.com
Subject: Re: [PATCH v10 1/3] hw/riscv: handle 32 bit CPUs kernel_addr in riscv_load_kernel()
Date: Sat, 4 Feb 2023 22:03:24 +1000 [thread overview]
Message-ID: <CAKmqyKN8MB9zS-KB__Z5HXjEd_QOXEQL_zpVyNga4gQcgdSGsw@mail.gmail.com> (raw)
In-Reply-To: <e7d32c5f-a996-2d50-9362-3223c546d136@ventanamicro.com>
On Sat, Feb 4, 2023 at 7:01 AM Daniel Henrique Barboza
<dbarboza@ventanamicro.com> wrote:
>
> Hey,
>
> On 2/3/23 07:45, Bin Meng wrote:
> > Hi Daniel,
> >
> > On Fri, Feb 3, 2023 at 6:31 PM Daniel Henrique Barboza
> > <dbarboza@ventanamicro.com> wrote:
> >>
> >>
> >>
> >> On 2/3/23 02:39, Bin Meng wrote:
> >>> On Thu, Feb 2, 2023 at 9:58 PM Daniel Henrique Barboza
> >>> <dbarboza@ventanamicro.com> wrote:
> >>>>
> >>>> load_elf_ram_sym() will sign-extend 32 bit addresses. If a 32 bit QEMU
> >>>> guest happens to be running in a hypervisor that are using 64 bits to
> >>>> encode its address, kernel_entry can be padded with '1's and create
> >>>> problems [1].
> >>>
> >>> Still this commit message is inaccurate. It's not
> >>>
> >>> "a 32-bit QEMU guest happens to running in a hypervisor that are using
> >>> 64 bits to encode tis address"
> >>>
> >>> as a 32-bit ELF can only hold a 32-bit address, but it's the QEMU ELF
> >>> loader that does the sign extension and returns the address as
> >>> uint64_t. It has nothing to do with hypervisor too.
> >>
> >>
> >> Yeah I'm still focusing too much on the use case instead of the root of the
> >> problem (sign-extension from QEMU elf).
> >>
> >>>
> >>>>
> >>>> Using a translate_fn() callback in load_elf_ram_sym() to filter the
> >>>> padding from the address doesn't work. A more detailed explanation can
> >>>> be found in [2]. The short version is that glue(load_elf, SZ), from
> >>>> include/hw/elf_ops.h, will calculate 'pentry' (mapped into the
> >>>> 'kernel_load_base' var in riscv_load_Kernel()) before using
> >>>> translate_fn(), and will not recalculate it after executing it. This
> >>>> means that the callback does not prevent the padding from
> >>>> kernel_load_base to appear.
> >>>>
> >>>> Let's instead use a kernel_low var to capture the 'lowaddr' value from
> >>>> load_elf_ram_sim(), and return it when we're dealing with 32 bit CPUs.
> >>>
> >>> Looking at the prototype of load_elf_ram_sym() it has
> >>>
> >>> ssize_t load_elf_ram_sym(const char *filename,
> >>> uint64_t (*elf_note_fn)(void *, void *, bool),
> >>> uint64_t (*translate_fn)(void *, uint64_t),
> >>> void *translate_opaque, uint64_t *pentry,
> >>> uint64_t *lowaddr, uint64_t *highaddr,
> >>> uint32_t *pflags, int big_endian, int elf_machine,
> >>> int clear_lsb, int data_swab,
> >>> AddressSpace *as, bool load_rom, symbol_fn_t sym_cb)
> >>>
> >>> So kernel_low is the "highaddr" parameter, not the 'lowaddr' value.
> >>
> >> And for some reason I thought kernel_base_addr was being used as 'pentry'. kernel_base_addr
> >> is already 'lowaddr'. Guess I'll have to rewrite the commit message. And revisit why my
> >> test case worked for riscv32 (I probably didn't use an ELF image ...)
> >>
> >> And the only way out seems to be filtering the bits from lowaddr. I'll do that.
> >>
> >
> > Can you check as to why QEMU ELF loader does the sign extension?
> >
> > I personally don't know why. Maybe the ELF loader does something wrong.
>
>
> I took a look and didn't find out why. I checked that in the ELF specification some
> file headers can indicate a sign extension. E.g. R_X86_64_32S for example is described as
> "Direct 32 bit zero extended". Note that the use of the tags are dependent on how the
> ELF was built, so we would need the exact ELF to check for that. All I can say is that
> there is a sign extension going on, in the 'lowaddr' field, and that translate_fn()
> wasn't enough to filter it out. I can't say whether this is intended or a bug.
>
>
> But going back a little, this whole situation happened in v5 because, in the next
> patch, riscv_load_initrd() started to receive an uint64_t (kernel_entry) instead of
> receiving a target_ulong like it was doing before. This behavior change, which was
> accidental, not only revealed this sign-extension behavior but also potentially changed
> what riscv_load_initrd() is receiving from load_uimage_as() the same way it's
> impacting load_elf_ram_sym(). The third load option, load_image_targphys_as(), is
> already using a target_ulong (kernel_start_addr) as return value so it's not
> impacted.
>
> I believe Alistair suggested to clear bits instead of just doing a target_ulong
> cast for a reason (I guess we're trying to gate all 32/64 bit CPU logic using a
> direct approach such as checking the CPU directly), but I also think we should
> clear bits for all 'kernel_entry' possibilities, not just the one that comes from
> load_elf_ram_sym(), to be consistent in all three cases. We might be even avoiding
> a future headache from load_uimage_as().
That seems like the approach to take. That way we aren't changing
behaviour and it continues along with improving/adding RV32 support on
64-bit bit targets.
If we want to change the behaviour in the future, we can add a patch
that does that with a description of why.
Alistair
>
>
>
> Thoughts?
>
>
> Daniel
>
>
> [1] https://github.com/riscv-non-isa/riscv-elf-psabi-doc/blob/master/riscv-elf.adoc
>
> >
> > Regards,
> > Bin
>
next prev parent reply other threads:[~2023-02-04 12:04 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-02-02 13:58 [PATCH v10 0/3] hw/riscv: handle kernel_entry high bits with 32bit CPUs Daniel Henrique Barboza
2023-02-02 13:58 ` [PATCH v10 1/3] hw/riscv: handle 32 bit CPUs kernel_addr in riscv_load_kernel() Daniel Henrique Barboza
2023-02-03 5:10 ` Alistair Francis
2023-02-03 5:39 ` Bin Meng
2023-02-03 10:31 ` Daniel Henrique Barboza
2023-02-03 10:45 ` Bin Meng
2023-02-03 21:00 ` Daniel Henrique Barboza
2023-02-04 12:03 ` Alistair Francis [this message]
2023-02-02 13:58 ` [PATCH v10 2/3] hw/riscv/boot.c: consolidate all kernel init " Daniel Henrique Barboza
2023-02-02 13:58 ` [PATCH v10 3/3] hw/riscv/boot.c: make riscv_load_initrd() static Daniel Henrique Barboza
2023-02-02 17:25 ` [PATCH v10 0/3] hw/riscv: handle kernel_entry high bits with 32bit CPUs Conor Dooley
2023-02-02 18:37 ` Daniel Henrique Barboza
2023-02-02 18:46 ` Conor Dooley
2023-02-02 18:50 ` Daniel Henrique Barboza
-- strict thread matches above, loose matches on Subject: below --
2023-02-02 13:52 [PATCH v10 0/3] Daniel Henrique Barboza
2023-02-02 13:52 ` [PATCH v10 1/3] hw/riscv: handle 32 bit CPUs kernel_addr in riscv_load_kernel() Daniel Henrique Barboza
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=CAKmqyKN8MB9zS-KB__Z5HXjEd_QOXEQL_zpVyNga4gQcgdSGsw@mail.gmail.com \
--to=alistair23@gmail.com \
--cc=alistair.francis@wdc.com \
--cc=bmeng.cn@gmail.com \
--cc=dbarboza@ventanamicro.com \
--cc=qemu-devel@nongnu.org \
--cc=qemu-riscv@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).