* [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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.