* [PATCH v2 0/2] Fix PVH entrypoint parsing
@ 2024-09-29 18:06 Ard Biesheuvel
2024-09-29 18:06 ` [PATCH v2 1/2] hw/elf_ops: Implement missing endian swabbing for ELF notes Ard Biesheuvel
` (2 more replies)
0 siblings, 3 replies; 4+ messages in thread
From: Ard Biesheuvel @ 2024-09-29 18:06 UTC (permalink / raw)
To: qemu-devel; +Cc: pbonzini, Ard Biesheuvel
Fix the handling of the ELF note that describes the PVH entrypoint
v2: fix broken ELF note handling on big endian hosts
Ard Biesheuvel (2):
hw/elf_ops: Implement missing endian swabbing for ELF notes
hw/x86: Always treat the PVH entrypoint as a 32-bit LE field
hw/i386/x86-common.c | 7 ++-----
include/hw/elf_ops.h.inc | 19 +++++++++++++++++--
2 files changed, 19 insertions(+), 7 deletions(-)
--
2.39.5
^ permalink raw reply [flat|nested] 4+ messages in thread
* [PATCH v2 1/2] hw/elf_ops: Implement missing endian swabbing for ELF notes
2024-09-29 18:06 [PATCH v2 0/2] Fix PVH entrypoint parsing Ard Biesheuvel
@ 2024-09-29 18:06 ` Ard Biesheuvel
2024-09-29 18:06 ` [PATCH v2 2/2] hw/x86: Always treat the PVH entrypoint as a 32-bit LE field Ard Biesheuvel
2024-11-21 8:08 ` [PATCH v2 0/2] Fix PVH entrypoint parsing Ard Biesheuvel
2 siblings, 0 replies; 4+ messages in thread
From: Ard Biesheuvel @ 2024-09-29 18:06 UTC (permalink / raw)
To: qemu-devel; +Cc: pbonzini, Ard Biesheuvel
ELF notes have type and size fields in the elf_note header that need to
be swabbed before use if the host endianness differs from the endianness
of the ELF binary.
Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
---
include/hw/elf_ops.h.inc | 19 +++++++++++++++++--
1 file changed, 17 insertions(+), 2 deletions(-)
diff --git a/include/hw/elf_ops.h.inc b/include/hw/elf_ops.h.inc
index 9c35d1b9da..8b563db2a3 100644
--- a/include/hw/elf_ops.h.inc
+++ b/include/hw/elf_ops.h.inc
@@ -41,6 +41,13 @@ static void glue(bswap_shdr, SZ)(struct elf_shdr *shdr)
bswapSZs(&shdr->sh_entsize);
}
+static void glue(bswap_nhdr, SZ)(struct elf_note *nhdr)
+{
+ bswap32s(&nhdr->n_namesz);
+ bswap32s(&nhdr->n_descsz);
+ bswap32s(&nhdr->n_type);
+}
+
static void glue(bswap_sym, SZ)(struct elf_sym *sym)
{
bswap32s(&sym->st_name);
@@ -275,7 +282,8 @@ fail:
static struct elf_note *glue(get_elf_note_type, SZ)(struct elf_note *nhdr,
elf_word note_size,
elf_word phdr_align,
- elf_word elf_note_type)
+ elf_word elf_note_type,
+ int must_swab)
{
elf_word nhdr_size = sizeof(struct elf_note);
elf_word elf_note_entry_offset = 0;
@@ -287,6 +295,9 @@ static struct elf_note *glue(get_elf_note_type, SZ)(struct elf_note *nhdr,
return NULL;
}
+ if (must_swab) {
+ glue(bswap_nhdr, SZ)(nhdr);
+ }
note_type = nhdr->n_type;
while (note_type != elf_note_type) {
nhdr_namesz = nhdr->n_namesz;
@@ -306,6 +317,9 @@ static struct elf_note *glue(get_elf_note_type, SZ)(struct elf_note *nhdr,
/* skip to the next ELF Note entry */
nhdr = (void *)nhdr + elf_note_entry_offset;
+ if (must_swab) {
+ glue(bswap_nhdr, SZ)(nhdr);
+ }
note_type = nhdr->n_type;
}
@@ -603,7 +617,8 @@ static ssize_t glue(load_elf, SZ)(const char *name, int fd,
nhdr = (struct elf_note *)data;
assert(translate_opaque != NULL);
nhdr = glue(get_elf_note_type, SZ)(nhdr, file_size, ph->p_align,
- *(uint64_t *)translate_opaque);
+ *(uint64_t *)translate_opaque,
+ must_swab);
if (nhdr != NULL) {
elf_note_fn((void *)nhdr, (void *)&ph->p_align, SZ == 64);
}
--
2.39.5
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [PATCH v2 2/2] hw/x86: Always treat the PVH entrypoint as a 32-bit LE field
2024-09-29 18:06 [PATCH v2 0/2] Fix PVH entrypoint parsing Ard Biesheuvel
2024-09-29 18:06 ` [PATCH v2 1/2] hw/elf_ops: Implement missing endian swabbing for ELF notes Ard Biesheuvel
@ 2024-09-29 18:06 ` Ard Biesheuvel
2024-11-21 8:08 ` [PATCH v2 0/2] Fix PVH entrypoint parsing Ard Biesheuvel
2 siblings, 0 replies; 4+ messages in thread
From: Ard Biesheuvel @ 2024-09-29 18:06 UTC (permalink / raw)
To: qemu-devel; +Cc: pbonzini, Ard Biesheuvel
The PVH entrypoint is entered in 32-bit mode, and is documented as being
a 32-bit field. Linux happens to widen the field in the ELF note to 64
bits so treating it as a 64-bit field works for booting the kernel.
However, Xen documents the ELF note with the following example
ELFNOTE(Xen, XEN_ELFNOTE_PHYS32_ENTRY, .long, xen_start32)
and uses .long in the code as well, and so reading more than 32 bits
here is risky. And dereferencing a size_t* in portable code is just
bizarre, so let's use a uint32_t specifically in all cases here.
While at it, read the field as little-endian explicitly, so things work
as expected on big endian hosts too.
Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
---
hw/i386/x86-common.c | 7 ++-----
1 file changed, 2 insertions(+), 5 deletions(-)
diff --git a/hw/i386/x86-common.c b/hw/i386/x86-common.c
index 992ea1f25e..44e5c365f1 100644
--- a/hw/i386/x86-common.c
+++ b/hw/i386/x86-common.c
@@ -539,7 +539,7 @@ DeviceState *ioapic_init_secondary(GSIState *gsi_state)
*/
static uint64_t read_pvh_start_addr(void *arg1, void *arg2, bool is64)
{
- size_t *elf_note_data_addr;
+ void *elf_note_data_addr;
/* Check if ELF Note header passed in is valid */
if (arg1 == NULL) {
@@ -555,8 +555,6 @@ static uint64_t read_pvh_start_addr(void *arg1, void *arg2, bool is64)
elf_note_data_addr =
((void *)nhdr64) + nhdr_size64 +
QEMU_ALIGN_UP(nhdr_namesz, phdr_align);
-
- pvh_start_addr = *elf_note_data_addr;
} else {
struct elf32_note *nhdr32 = (struct elf32_note *)arg1;
uint32_t nhdr_size32 = sizeof(struct elf32_note);
@@ -566,10 +564,9 @@ static uint64_t read_pvh_start_addr(void *arg1, void *arg2, bool is64)
elf_note_data_addr =
((void *)nhdr32) + nhdr_size32 +
QEMU_ALIGN_UP(nhdr_namesz, phdr_align);
-
- pvh_start_addr = *(uint32_t *)elf_note_data_addr;
}
+ pvh_start_addr = ldl_le_p(elf_note_data_addr);
return pvh_start_addr;
}
--
2.39.5
^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [PATCH v2 0/2] Fix PVH entrypoint parsing
2024-09-29 18:06 [PATCH v2 0/2] Fix PVH entrypoint parsing Ard Biesheuvel
2024-09-29 18:06 ` [PATCH v2 1/2] hw/elf_ops: Implement missing endian swabbing for ELF notes Ard Biesheuvel
2024-09-29 18:06 ` [PATCH v2 2/2] hw/x86: Always treat the PVH entrypoint as a 32-bit LE field Ard Biesheuvel
@ 2024-11-21 8:08 ` Ard Biesheuvel
2 siblings, 0 replies; 4+ messages in thread
From: Ard Biesheuvel @ 2024-11-21 8:08 UTC (permalink / raw)
To: qemu-devel; +Cc: pbonzini
On Sun, 29 Sept 2024 at 20:07, Ard Biesheuvel <ardb@kernel.org> wrote:
>
> Fix the handling of the ELF note that describes the PVH entrypoint
>
> v2: fix broken ELF note handling on big endian hosts
>
> Ard Biesheuvel (2):
> hw/elf_ops: Implement missing endian swabbing for ELF notes
> hw/x86: Always treat the PVH entrypoint as a 32-bit LE field
>
> hw/i386/x86-common.c | 7 ++-----
> include/hw/elf_ops.h.inc | 19 +++++++++++++++++--
> 2 files changed, 19 insertions(+), 7 deletions(-)
>
Ping?
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2024-11-21 8:10 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-09-29 18:06 [PATCH v2 0/2] Fix PVH entrypoint parsing Ard Biesheuvel
2024-09-29 18:06 ` [PATCH v2 1/2] hw/elf_ops: Implement missing endian swabbing for ELF notes Ard Biesheuvel
2024-09-29 18:06 ` [PATCH v2 2/2] hw/x86: Always treat the PVH entrypoint as a 32-bit LE field Ard Biesheuvel
2024-11-21 8:08 ` [PATCH v2 0/2] Fix PVH entrypoint parsing Ard Biesheuvel
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).