From nobody Sun Feb 8 22:22:38 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=oracle.com Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1547554985248244.87887755386066; Tue, 15 Jan 2019 04:23:05 -0800 (PST) Received: from localhost ([127.0.0.1]:57911 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gjNkG-0002Mx-45 for importer@patchew.org; Tue, 15 Jan 2019 07:23:04 -0500 Received: from eggs.gnu.org ([209.51.188.92]:41817) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gjNg0-0007fi-Ji for qemu-devel@nongnu.org; Tue, 15 Jan 2019 07:18:43 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gjNfx-0003Gg-53 for qemu-devel@nongnu.org; Tue, 15 Jan 2019 07:18:40 -0500 Received: from userp2120.oracle.com ([156.151.31.85]:43424) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gjNfw-0003G4-PD for qemu-devel@nongnu.org; Tue, 15 Jan 2019 07:18:37 -0500 Received: from pps.filterd (userp2120.oracle.com [127.0.0.1]) by userp2120.oracle.com (8.16.0.22/8.16.0.22) with SMTP id x0FC98SP147011; Tue, 15 Jan 2019 12:18:33 GMT Received: from aserv0022.oracle.com (aserv0022.oracle.com [141.146.126.234]) by userp2120.oracle.com with ESMTP id 2pybjs3hhw-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Tue, 15 Jan 2019 12:18:33 +0000 Received: from userv0122.oracle.com (userv0122.oracle.com [156.151.31.75]) by aserv0022.oracle.com (8.14.4/8.14.4) with ESMTP id x0FCIVTK030409 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Tue, 15 Jan 2019 12:18:32 GMT Received: from abhmp0005.oracle.com (abhmp0005.oracle.com [141.146.116.11]) by userv0122.oracle.com (8.14.4/8.14.4) with ESMTP id x0FCIViB024438; Tue, 15 Jan 2019 12:18:31 GMT Received: from ol7.uk.oracle.com (/10.175.168.140) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Tue, 15 Jan 2019 04:18:30 -0800 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oracle.com; h=from : to : cc : subject : date : message-id : in-reply-to : references; s=corp-2018-07-02; bh=MZ2rpO9INBiuI3Xmx+ZlJ+EjJcIfYzzUHnvjBNdAwoU=; b=ef7XHmcZcIQFiueps9zkmHwZcN/rdhujQFobGvWzpTELB7iuYJBBsJWlI9BSmeIwHAr/ TZvwXdTiiFTNXUynbKwr90R61L9d6cCfYNX8z4kIWlLpJvkX09oQqPDg0/yv6SDBd8d7 NhzubWH8m6XA38bCCXPUmtZLW/0JVx48Q/Y4nCaNAs4k3+PYtd7knwOKD1y/RO3MtG/w nUFC3Cer5lxfxfLPkgyGdZs+YdHsJmUYoWlLFr9HnOVtzEpY2qQH9k5nNS/ONW/9r6U2 jFDRHGgYNPQJOPtRVupX+M3XEv2KKFMaPBKwqeMi8B+hf7LwPuN/VeuiHKlhcaqH8YUz oA== From: Liam Merwick To: qemu-devel@nongnu.org Date: Tue, 15 Jan 2019 12:18:03 +0000 Message-Id: <1547554687-12687-2-git-send-email-liam.merwick@oracle.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1547554687-12687-1-git-send-email-liam.merwick@oracle.com> References: <1547554687-12687-1-git-send-email-liam.merwick@oracle.com> X-Proofpoint-Virus-Version: vendor=nai engine=5900 definitions=9136 signatures=668680 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 suspectscore=3 malwarescore=0 phishscore=0 bulkscore=0 spamscore=0 mlxscore=0 mlxlogscore=999 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1810050000 definitions=main-1901150102 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x [generic] X-Received-From: 156.151.31.85 Subject: [Qemu-devel] [PATCH v3 1/5] elf: Add optional function ptr to load_elf() to parse ELF notes X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: ehabkost@redhat.com, mst@redhat.com, maran.wilson@oracle.com, george.kennedy@oracle.com, stefanha@redhat.com, xen-devel@lists.xenproject.org, pbonzini@redhat.com, boris.ostrovsky@oracle.com, rth@twiddle.net, sgarzare@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" This patch adds an optional function pointer, 'elf_note_fn', to load_elf() which causes load_elf() to additionally parse any ELF program headers of type PT_NOTE and check to see if the ELF Note is of the type specified by the 'translate_opaque' arg. If a matching ELF Note is found then the specfied function pointer is called to process the ELF note. Passing a NULL function pointer results in ELF Notes being skipped. The first consumer of this functionality is the PVHboot support which needs to read the XEN_ELFNOTE_PHYS32_ENTRY ELF Note while loading the uncompressed kernel binary in order to discover the boot entry address for the x86/HVM direct boot ABI. Signed-off-by: Liam Merwick --- hw/alpha/dp264.c | 4 ++-- hw/arm/armv7m.c | 3 ++- hw/arm/boot.c | 2 +- hw/core/generic-loader.c | 2 +- hw/core/loader.c | 24 ++++++++++++++++-------- hw/cris/boot.c | 3 ++- hw/hppa/machine.c | 6 +++--- hw/i386/multiboot.c | 2 +- hw/lm32/lm32_boards.c | 6 ++++-- hw/lm32/milkymist.c | 3 ++- hw/m68k/an5206.c | 2 +- hw/m68k/mcf5208.c | 2 +- hw/microblaze/boot.c | 7 ++++--- hw/mips/mips_fulong2e.c | 5 +++-- hw/mips/mips_malta.c | 5 +++-- hw/mips/mips_mipssim.c | 5 +++-- hw/mips/mips_r4k.c | 5 +++-- hw/moxie/moxiesim.c | 2 +- hw/nios2/boot.c | 7 ++++--- hw/openrisc/openrisc_sim.c | 2 +- hw/pci-host/prep.c | 2 +- hw/ppc/e500.c | 3 ++- hw/ppc/mac_newworld.c | 5 +++-- hw/ppc/mac_oldworld.c | 5 +++-- hw/ppc/ppc440_bamboo.c | 2 +- hw/ppc/sam460ex.c | 3 ++- hw/ppc/spapr.c | 7 ++++--- hw/ppc/virtex_ml507.c | 2 +- hw/riscv/sifive_e.c | 2 +- hw/riscv/sifive_u.c | 2 +- hw/riscv/spike.c | 2 +- hw/riscv/virt.c | 2 +- hw/s390x/ipl.c | 9 ++++++--- hw/sparc/leon3.c | 3 ++- hw/sparc/sun4m.c | 6 ++++-- hw/sparc64/sun4u.c | 4 ++-- hw/tricore/tricore_testboard.c | 2 +- hw/xtensa/sim.c | 12 ++++++++---- hw/xtensa/xtfpga.c | 2 +- include/hw/elf_ops.h | 2 ++ include/hw/loader.h | 9 ++++++++- 41 files changed, 113 insertions(+), 70 deletions(-) diff --git a/hw/alpha/dp264.c b/hw/alpha/dp264.c index dd62f2a4050c..0347eb897c8a 100644 --- a/hw/alpha/dp264.c +++ b/hw/alpha/dp264.c @@ -114,7 +114,7 @@ static void clipper_init(MachineState *machine) error_report("no palcode provided"); exit(1); } - size =3D load_elf(palcode_filename, cpu_alpha_superpage_to_phys, + size =3D load_elf(palcode_filename, NULL, cpu_alpha_superpage_to_phys, NULL, &palcode_entry, &palcode_low, &palcode_high, 0, EM_ALPHA, 0, 0); if (size < 0) { @@ -133,7 +133,7 @@ static void clipper_init(MachineState *machine) if (kernel_filename) { uint64_t param_offset; =20 - size =3D load_elf(kernel_filename, cpu_alpha_superpage_to_phys, + size =3D load_elf(kernel_filename, NULL, cpu_alpha_superpage_to_ph= ys, NULL, &kernel_entry, &kernel_low, &kernel_high, 0, EM_ALPHA, 0, 0); if (size < 0) { diff --git a/hw/arm/armv7m.c b/hw/arm/armv7m.c index f4446528307f..ae68aadef965 100644 --- a/hw/arm/armv7m.c +++ b/hw/arm/armv7m.c @@ -293,7 +293,8 @@ void armv7m_load_kernel(ARMCPU *cpu, const char *kernel= _filename, int mem_size) as =3D cpu_get_address_space(cs, asidx); =20 if (kernel_filename) { - image_size =3D load_elf_as(kernel_filename, NULL, NULL, &entry, &l= owaddr, + image_size =3D load_elf_as(kernel_filename, NULL, NULL, NULL, + &entry, &lowaddr, NULL, big_endian, EM_ARM, 1, 0, as); if (image_size < 0) { image_size =3D load_image_targphys_as(kernel_filename, 0, diff --git a/hw/arm/boot.c b/hw/arm/boot.c index c7a67af7a97c..9d8746f7613f 100644 --- a/hw/arm/boot.c +++ b/hw/arm/boot.c @@ -885,7 +885,7 @@ static int64_t arm_load_elf(struct arm_boot_info *info,= uint64_t *pentry, } } =20 - ret =3D load_elf_as(info->kernel_filename, NULL, NULL, + ret =3D load_elf_as(info->kernel_filename, NULL, NULL, NULL, pentry, lowaddr, highaddr, big_endian, elf_machine, 1, data_swab, as); if (ret <=3D 0) { diff --git a/hw/core/generic-loader.c b/hw/core/generic-loader.c index fbae05fb3b64..3695dd439cd0 100644 --- a/hw/core/generic-loader.c +++ b/hw/core/generic-loader.c @@ -136,7 +136,7 @@ static void generic_loader_realize(DeviceState *dev, Er= ror **errp) AddressSpace *as =3D s->cpu ? s->cpu->as : NULL; =20 if (!s->force_raw) { - size =3D load_elf_as(s->file, NULL, NULL, &entry, NULL, NULL, + size =3D load_elf_as(s->file, NULL, NULL, NULL, &entry, NULL, = NULL, big_endian, 0, 0, 0, as); =20 if (size < 0) { diff --git a/hw/core/loader.c b/hw/core/loader.c index c4f62fe42770..3a000d576b35 100644 --- a/hw/core/loader.c +++ b/hw/core/loader.c @@ -396,37 +396,42 @@ fail: } =20 /* return < 0 if error, otherwise the number of bytes loaded in memory */ -int load_elf(const char *filename, uint64_t (*translate_fn)(void *, uint64= _t), +int load_elf(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, int big_endian, int elf_machine, int clear_lsb, int data_swab) { - return load_elf_as(filename, translate_fn, translate_opaque, pentry, - lowaddr, highaddr, big_endian, elf_machine, clear_l= sb, - data_swab, NULL); + return load_elf_as(filename, elf_note_fn, translate_fn, translate_opaq= ue, + pentry, lowaddr, highaddr, big_endian, elf_machine, + clear_lsb, data_swab, NULL); } =20 /* return < 0 if error, otherwise the number of bytes loaded in memory */ int load_elf_as(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 *lowadd= r, uint64_t *highaddr, int big_endian, int elf_machine, int clear_lsb, int data_swab, AddressSpace *as) { - return load_elf_ram(filename, translate_fn, translate_opaque, + return load_elf_ram(filename, elf_note_fn, translate_fn, translate_opa= que, pentry, lowaddr, highaddr, big_endian, elf_machine, clear_lsb, data_swab, as, true); } =20 /* return < 0 if error, otherwise the number of bytes loaded in memory */ int load_elf_ram(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 *lowad= dr, uint64_t *highaddr, int big_endian, int elf_machine, int clear_lsb, int data_swab, AddressSpace *as, bool load_rom) { - return load_elf_ram_sym(filename, translate_fn, translate_opaque, + return load_elf_ram_sym(filename, elf_note_fn, + translate_fn, translate_opaque, pentry, lowaddr, highaddr, big_endian, elf_machine, clear_lsb, data_swab, as, load_rom, NULL); @@ -434,6 +439,7 @@ int load_elf_ram(const char *filename, =20 /* return < 0 if error, otherwise the number of bytes loaded in memory */ int 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, int big_endian, @@ -476,11 +482,13 @@ int load_elf_ram_sym(const char *filename, =20 lseek(fd, 0, SEEK_SET); if (e_ident[EI_CLASS] =3D=3D ELFCLASS64) { - ret =3D load_elf64(filename, fd, translate_fn, translate_opaque, m= ust_swab, + ret =3D load_elf64(filename, fd, elf_note_fn, + translate_fn, translate_opaque, must_swab, pentry, lowaddr, highaddr, elf_machine, clear_lsb, data_swab, as, load_rom, sym_cb); } else { - ret =3D load_elf32(filename, fd, translate_fn, translate_opaque, m= ust_swab, + ret =3D load_elf32(filename, fd, elf_note_fn, + translate_fn, translate_opaque, must_swab, pentry, lowaddr, highaddr, elf_machine, clear_lsb, data_swab, as, load_rom, sym_cb); } diff --git a/hw/cris/boot.c b/hw/cris/boot.c index f896ed7f8635..95cba2151b79 100644 --- a/hw/cris/boot.c +++ b/hw/cris/boot.c @@ -75,7 +75,8 @@ void cris_load_image(CRISCPU *cpu, struct cris_load_info = *li) env->load_info =3D li; /* Boots a kernel elf binary, os/linux-2.6/vmlinux from the axis=20 devboard SDK. */ - image_size =3D load_elf(li->image_filename, translate_kernel_address, = NULL, + image_size =3D load_elf(li->image_filename, NULL, + translate_kernel_address, NULL, &entry, NULL, &high, 0, EM_CRIS, 0, 0); li->entry =3D entry; if (image_size < 0) { diff --git a/hw/hppa/machine.c b/hw/hppa/machine.c index ac6dd7f6abdc..d1b1d3caa40d 100644 --- a/hw/hppa/machine.c +++ b/hw/hppa/machine.c @@ -135,8 +135,8 @@ static void machine_hppa_init(MachineState *machine) exit(1); } =20 - size =3D load_elf(firmware_filename, NULL, - NULL, &firmware_entry, &firmware_low, &firmware_high, + size =3D load_elf(firmware_filename, NULL, NULL, NULL, + &firmware_entry, &firmware_low, &firmware_high, true, EM_PARISC, 0, 0); =20 /* Unfortunately, load_elf sign-extends reading elf32. */ @@ -165,7 +165,7 @@ static void machine_hppa_init(MachineState *machine) =20 /* Load kernel */ if (kernel_filename) { - size =3D load_elf(kernel_filename, &cpu_hppa_to_phys, + size =3D load_elf(kernel_filename, NULL, &cpu_hppa_to_phys, NULL, &kernel_entry, &kernel_low, &kernel_high, true, EM_PARISC, 0, 0); =20 diff --git a/hw/i386/multiboot.c b/hw/i386/multiboot.c index 62340687e8ed..a3e33fbe5e18 100644 --- a/hw/i386/multiboot.c +++ b/hw/i386/multiboot.c @@ -199,7 +199,7 @@ int load_multiboot(FWCfgState *fw_cfg, exit(1); } =20 - kernel_size =3D load_elf(kernel_filename, NULL, NULL, &elf_entry, + kernel_size =3D load_elf(kernel_filename, NULL, NULL, NULL, &elf_e= ntry, &elf_low, &elf_high, 0, I386_ELF_MACHINE, 0, 0); if (kernel_size < 0) { diff --git a/hw/lm32/lm32_boards.c b/hw/lm32/lm32_boards.c index fd8eccca14d9..05157f8eab76 100644 --- a/hw/lm32/lm32_boards.c +++ b/hw/lm32/lm32_boards.c @@ -138,7 +138,8 @@ static void lm32_evr_init(MachineState *machine) uint64_t entry; int kernel_size; =20 - kernel_size =3D load_elf(kernel_filename, NULL, NULL, &entry, NULL= , NULL, + kernel_size =3D load_elf(kernel_filename, NULL, NULL, NULL, + &entry, NULL, NULL, 1, EM_LATTICEMICO32, 0, 0); reset_info->bootstrap_pc =3D entry; =20 @@ -231,7 +232,8 @@ static void lm32_uclinux_init(MachineState *machine) uint64_t entry; int kernel_size; =20 - kernel_size =3D load_elf(kernel_filename, NULL, NULL, &entry, NULL= , NULL, + kernel_size =3D load_elf(kernel_filename, NULL, NULL, NULL, + &entry, NULL, NULL, 1, EM_LATTICEMICO32, 0, 0); reset_info->bootstrap_pc =3D entry; =20 diff --git a/hw/lm32/milkymist.c b/hw/lm32/milkymist.c index 63c6894c9559..7b0046b3e821 100644 --- a/hw/lm32/milkymist.c +++ b/hw/lm32/milkymist.c @@ -175,7 +175,8 @@ milkymist_init(MachineState *machine) uint64_t entry; =20 /* Boots a kernel elf binary. */ - kernel_size =3D load_elf(kernel_filename, NULL, NULL, &entry, NULL= , NULL, + kernel_size =3D load_elf(kernel_filename, NULL, NULL, NULL, + &entry, NULL, NULL, 1, EM_LATTICEMICO32, 0, 0); reset_info->bootstrap_pc =3D entry; =20 diff --git a/hw/m68k/an5206.c b/hw/m68k/an5206.c index 5e067ea1c356..06e380325885 100644 --- a/hw/m68k/an5206.c +++ b/hw/m68k/an5206.c @@ -66,7 +66,7 @@ static void an5206_init(MachineState *machine) exit(1); } =20 - kernel_size =3D load_elf(kernel_filename, NULL, NULL, &elf_entry, + kernel_size =3D load_elf(kernel_filename, NULL, NULL, NULL, &elf_entry, NULL, NULL, 1, EM_68K, 0, 0); entry =3D elf_entry; if (kernel_size < 0) { diff --git a/hw/m68k/mcf5208.c b/hw/m68k/mcf5208.c index 0f2245dd8177..8531e07e5b57 100644 --- a/hw/m68k/mcf5208.c +++ b/hw/m68k/mcf5208.c @@ -294,7 +294,7 @@ static void mcf5208evb_init(MachineState *machine) exit(1); } =20 - kernel_size =3D load_elf(kernel_filename, NULL, NULL, &elf_entry, + kernel_size =3D load_elf(kernel_filename, NULL, NULL, NULL, &elf_entry, NULL, NULL, 1, EM_68K, 0, 0); entry =3D elf_entry; if (kernel_size < 0) { diff --git a/hw/microblaze/boot.c b/hw/microblaze/boot.c index 489ab839b7c2..a7af4c070486 100644 --- a/hw/microblaze/boot.c +++ b/hw/microblaze/boot.c @@ -142,13 +142,14 @@ void microblaze_load_kernel(MicroBlazeCPU *cpu, hwadd= r ddr_base, #endif =20 /* Boots a kernel elf binary. */ - kernel_size =3D load_elf(kernel_filename, NULL, NULL, + kernel_size =3D load_elf(kernel_filename, NULL, NULL, NULL, &entry, &low, &high, big_endian, EM_MICROBLAZE, 0, 0); base32 =3D entry; if (base32 =3D=3D 0xc0000000) { - kernel_size =3D load_elf(kernel_filename, translate_kernel_add= ress, - NULL, &entry, NULL, NULL, + kernel_size =3D load_elf(kernel_filename, NULL, + translate_kernel_address, NULL, + &entry, NULL, NULL, big_endian, EM_MICROBLAZE, 0, 0); } /* Always boot into physical ram. */ diff --git a/hw/mips/mips_fulong2e.c b/hw/mips/mips_fulong2e.c index 2fbba32c4819..1f24a9fc2e13 100644 --- a/hw/mips/mips_fulong2e.c +++ b/hw/mips/mips_fulong2e.c @@ -111,8 +111,9 @@ static int64_t load_kernel (CPUMIPSState *env) uint32_t *prom_buf; long prom_size; =20 - kernel_size =3D load_elf(loaderparams.kernel_filename, cpu_mips_kseg0_= to_phys, - NULL, (uint64_t *)&kernel_entry, + kernel_size =3D load_elf(loaderparams.kernel_filename, NULL, + cpu_mips_kseg0_to_phys, NULL, + (uint64_t *)&kernel_entry, (uint64_t *)&kernel_low, (uint64_t *)&kernel_hi= gh, 0, EM_MIPS, 1, 0); if (kernel_size < 0) { diff --git a/hw/mips/mips_malta.c b/hw/mips/mips_malta.c index c1cf0fe12e95..74667766c277 100644 --- a/hw/mips/mips_malta.c +++ b/hw/mips/mips_malta.c @@ -1010,8 +1010,9 @@ static int64_t load_kernel (void) big_endian =3D 0; #endif =20 - kernel_size =3D load_elf(loaderparams.kernel_filename, cpu_mips_kseg0_= to_phys, - NULL, (uint64_t *)&kernel_entry, NULL, + kernel_size =3D load_elf(loaderparams.kernel_filename, NULL, + cpu_mips_kseg0_to_phys, NULL, + (uint64_t *)&kernel_entry, NULL, (uint64_t *)&kernel_high, big_endian, EM_MIPS, = 1, 0); if (kernel_size < 0) { error_report("could not load kernel '%s': %s", diff --git a/hw/mips/mips_mipssim.c b/hw/mips/mips_mipssim.c index f665752a2fc6..824abda65748 100644 --- a/hw/mips/mips_mipssim.c +++ b/hw/mips/mips_mipssim.c @@ -69,8 +69,9 @@ static int64_t load_kernel(void) big_endian =3D 0; #endif =20 - kernel_size =3D load_elf(loaderparams.kernel_filename, cpu_mips_kseg0_= to_phys, - NULL, (uint64_t *)&entry, NULL, + kernel_size =3D load_elf(loaderparams.kernel_filename, NULL, + cpu_mips_kseg0_to_phys, NULL, + (uint64_t *)&entry, NULL, (uint64_t *)&kernel_high, big_endian, EM_MIPS, 1, 0); if (kernel_size >=3D 0) { diff --git a/hw/mips/mips_r4k.c b/hw/mips/mips_r4k.c index 19224073947d..a015a6d14ee6 100644 --- a/hw/mips/mips_r4k.c +++ b/hw/mips/mips_r4k.c @@ -92,8 +92,9 @@ static int64_t load_kernel(void) #else big_endian =3D 0; #endif - kernel_size =3D load_elf(loaderparams.kernel_filename, cpu_mips_kseg0_= to_phys, - NULL, (uint64_t *)&entry, NULL, + kernel_size =3D load_elf(loaderparams.kernel_filename, NULL, + cpu_mips_kseg0_to_phys, NULL, + (uint64_t *)&entry, NULL, (uint64_t *)&kernel_high, big_endian, EM_MIPS, 1, 0); if (kernel_size >=3D 0) { diff --git a/hw/moxie/moxiesim.c b/hw/moxie/moxiesim.c index c6b6f7262dce..eddeed915d3b 100644 --- a/hw/moxie/moxiesim.c +++ b/hw/moxie/moxiesim.c @@ -57,7 +57,7 @@ static void load_kernel(MoxieCPU *cpu, LoaderParams *load= er_params) long kernel_size; ram_addr_t initrd_offset; =20 - kernel_size =3D load_elf(loader_params->kernel_filename, NULL, NULL, + kernel_size =3D load_elf(loader_params->kernel_filename, NULL, NULL, = NULL, &entry, &kernel_low, &kernel_high, 1, EM_MOXIE, 0, 0); =20 diff --git a/hw/nios2/boot.c b/hw/nios2/boot.c index ed5cb28e942b..5f0ab2fbb9c2 100644 --- a/hw/nios2/boot.c +++ b/hw/nios2/boot.c @@ -146,13 +146,14 @@ void nios2_load_kernel(Nios2CPU *cpu, hwaddr ddr_base, #endif =20 /* Boots a kernel elf binary. */ - kernel_size =3D load_elf(kernel_filename, NULL, NULL, + kernel_size =3D load_elf(kernel_filename, NULL, NULL, NULL, &entry, &low, &high, big_endian, EM_ALTERA_NIOS2, 0, 0); base32 =3D entry; if (base32 =3D=3D 0xc0000000) { - kernel_size =3D load_elf(kernel_filename, translate_kernel_add= ress, - NULL, &entry, NULL, NULL, + kernel_size =3D load_elf(kernel_filename, NULL, + translate_kernel_address, NULL, + &entry, NULL, NULL, big_endian, EM_ALTERA_NIOS2, 0, 0); } =20 diff --git a/hw/openrisc/openrisc_sim.c b/hw/openrisc/openrisc_sim.c index a495a84a41d9..7d3b734d24fb 100644 --- a/hw/openrisc/openrisc_sim.c +++ b/hw/openrisc/openrisc_sim.c @@ -96,7 +96,7 @@ static void openrisc_load_kernel(ram_addr_t ram_size, hwaddr entry; =20 if (kernel_filename && !qtest_enabled()) { - kernel_size =3D load_elf(kernel_filename, NULL, NULL, + kernel_size =3D load_elf(kernel_filename, NULL, NULL, NULL, &elf_entry, NULL, NULL, 1, EM_OPENRISC, 1, 0); entry =3D elf_entry; diff --git a/hw/pci-host/prep.c b/hw/pci-host/prep.c index b1b6b16badb3..8b9e1fd0d343 100644 --- a/hw/pci-host/prep.c +++ b/hw/pci-host/prep.c @@ -331,7 +331,7 @@ static void raven_realize(PCIDevice *d, Error **errp) filename =3D qemu_find_file(QEMU_FILE_TYPE_BIOS, s->bios_name); if (filename) { if (s->elf_machine !=3D EM_NONE) { - bios_size =3D load_elf(filename, NULL, NULL, NULL, + bios_size =3D load_elf(filename, NULL, NULL, NULL, NULL, NULL, NULL, 1, s->elf_machine, 0, 0); } if (bios_size < 0) { diff --git a/hw/ppc/e500.c b/hw/ppc/e500.c index 0581e9e3d4c3..7553f674c990 100644 --- a/hw/ppc/e500.c +++ b/hw/ppc/e500.c @@ -988,7 +988,8 @@ void ppce500_init(MachineState *machine) =20 filename =3D qemu_find_file(QEMU_FILE_TYPE_BIOS, payload_name); =20 - payload_size =3D load_elf(filename, NULL, NULL, &bios_entry, &loadaddr= , NULL, + payload_size =3D load_elf(filename, NULL, NULL, NULL, + &bios_entry, &loadaddr, NULL, 1, PPC_ELF_MACHINE, 0, 0); if (payload_size < 0) { /* diff --git a/hw/ppc/mac_newworld.c b/hw/ppc/mac_newworld.c index bb19eaba36b4..40be6d0b2aba 100644 --- a/hw/ppc/mac_newworld.c +++ b/hw/ppc/mac_newworld.c @@ -165,7 +165,7 @@ static void ppc_core99_init(MachineState *machine) =20 /* Load OpenBIOS (ELF) */ if (filename) { - bios_size =3D load_elf(filename, NULL, NULL, NULL, + bios_size =3D load_elf(filename, NULL, NULL, NULL, NULL, NULL, NULL, 1, PPC_ELF_MACHINE, 0, 0); =20 g_free(filename); @@ -188,7 +188,8 @@ static void ppc_core99_init(MachineState *machine) #endif kernel_base =3D KERNEL_LOAD_ADDR; =20 - kernel_size =3D load_elf(kernel_filename, translate_kernel_address= , NULL, + kernel_size =3D load_elf(kernel_filename, NULL, + translate_kernel_address, NULL, NULL, &lowaddr, NULL, 1, PPC_ELF_MACHINE, 0, 0); if (kernel_size < 0) diff --git a/hw/ppc/mac_oldworld.c b/hw/ppc/mac_oldworld.c index 817f70e52cf3..c28dde1992f4 100644 --- a/hw/ppc/mac_oldworld.c +++ b/hw/ppc/mac_oldworld.c @@ -140,7 +140,7 @@ static void ppc_heathrow_init(MachineState *machine) =20 /* Load OpenBIOS (ELF) */ if (filename) { - bios_size =3D load_elf(filename, 0, NULL, NULL, NULL, NULL, + bios_size =3D load_elf(filename, NULL, 0, NULL, NULL, NULL, NULL, 1, PPC_ELF_MACHINE, 0, 0); g_free(filename); } else { @@ -161,7 +161,8 @@ static void ppc_heathrow_init(MachineState *machine) bswap_needed =3D 0; #endif kernel_base =3D KERNEL_LOAD_ADDR; - kernel_size =3D load_elf(kernel_filename, translate_kernel_address= , NULL, + kernel_size =3D load_elf(kernel_filename, NULL, + translate_kernel_address, NULL, NULL, &lowaddr, NULL, 1, PPC_ELF_MACHINE, 0, 0); if (kernel_size < 0) diff --git a/hw/ppc/ppc440_bamboo.c b/hw/ppc/ppc440_bamboo.c index fc0619158879..6318301c81c9 100644 --- a/hw/ppc/ppc440_bamboo.c +++ b/hw/ppc/ppc440_bamboo.c @@ -256,7 +256,7 @@ static void bamboo_init(MachineState *machine) success =3D load_uimage(kernel_filename, &entry, &loadaddr, NULL, NULL, NULL); if (success < 0) { - success =3D load_elf(kernel_filename, NULL, NULL, &elf_entry, + success =3D load_elf(kernel_filename, NULL, NULL, NULL, &elf_e= ntry, &elf_lowaddr, NULL, 1, PPC_ELF_MACHINE, 0, 0); entry =3D elf_entry; diff --git a/hw/ppc/sam460ex.c b/hw/ppc/sam460ex.c index 84ea592749c4..934674fd2da8 100644 --- a/hw/ppc/sam460ex.c +++ b/hw/ppc/sam460ex.c @@ -557,7 +557,8 @@ static void sam460ex_init(MachineState *machine) if (success < 0) { uint64_t elf_entry, elf_lowaddr; =20 - success =3D load_elf(machine->kernel_filename, NULL, NULL, &el= f_entry, + success =3D load_elf(machine->kernel_filename, NULL, + NULL, NULL, &elf_entry, &elf_lowaddr, NULL, 1, PPC_ELF_MACHINE, 0, = 0); entry =3D elf_entry; loadaddr =3D elf_lowaddr; diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index 0942f35bf87e..3cbc44c70fb7 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -2852,11 +2852,12 @@ static void spapr_machine_init(MachineState *machin= e) if (kernel_filename) { uint64_t lowaddr =3D 0; =20 - spapr->kernel_size =3D load_elf(kernel_filename, translate_kernel_= address, - NULL, NULL, &lowaddr, NULL, 1, + spapr->kernel_size =3D load_elf(kernel_filename, NULL, + translate_kernel_address, NULL, + NULL, &lowaddr, NULL, 1, PPC_ELF_MACHINE, 0, 0); if (spapr->kernel_size =3D=3D ELF_LOAD_WRONG_ENDIAN) { - spapr->kernel_size =3D load_elf(kernel_filename, + spapr->kernel_size =3D load_elf(kernel_filename, NULL, translate_kernel_address, NULL, = NULL, &lowaddr, NULL, 0, PPC_ELF_MACHI= NE, 0, 0); diff --git a/hw/ppc/virtex_ml507.c b/hw/ppc/virtex_ml507.c index 517712057434..5a711cb3d941 100644 --- a/hw/ppc/virtex_ml507.c +++ b/hw/ppc/virtex_ml507.c @@ -258,7 +258,7 @@ static void virtex_init(MachineState *machine) hwaddr boot_offset; =20 /* Boots a kernel elf binary. */ - kernel_size =3D load_elf(kernel_filename, NULL, NULL, + kernel_size =3D load_elf(kernel_filename, NULL, NULL, NULL, &entry, &low, &high, 1, PPC_ELF_MACHINE, 0, 0); boot_info.bootstrap_pc =3D entry & 0x00ffffff; diff --git a/hw/riscv/sifive_e.c b/hw/riscv/sifive_e.c index 5d9d65ff29ab..bfc086609cb9 100644 --- a/hw/riscv/sifive_e.c +++ b/hw/riscv/sifive_e.c @@ -78,7 +78,7 @@ static uint64_t load_kernel(const char *kernel_filename) { uint64_t kernel_entry, kernel_high; =20 - if (load_elf(kernel_filename, NULL, NULL, + if (load_elf(kernel_filename, NULL, NULL, NULL, &kernel_entry, NULL, &kernel_high, 0, EM_RISCV, 1, 0) < 0) { error_report("could not load kernel '%s'", kernel_filename); diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c index 3bd3b67507f8..2730b25b6032 100644 --- a/hw/riscv/sifive_u.c +++ b/hw/riscv/sifive_u.c @@ -69,7 +69,7 @@ static uint64_t load_kernel(const char *kernel_filename) { uint64_t kernel_entry, kernel_high; =20 - if (load_elf(kernel_filename, NULL, NULL, + if (load_elf(kernel_filename, NULL, NULL, NULL, &kernel_entry, NULL, &kernel_high, 0, EM_RISCV, 1, 0) < 0) { error_report("could not load kernel '%s'", kernel_filename); diff --git a/hw/riscv/spike.c b/hw/riscv/spike.c index 268df04c3c7d..c66ffc50cc74 100644 --- a/hw/riscv/spike.c +++ b/hw/riscv/spike.c @@ -57,7 +57,7 @@ static uint64_t load_kernel(const char *kernel_filename) { uint64_t kernel_entry, kernel_high; =20 - if (load_elf_ram_sym(kernel_filename, NULL, NULL, + if (load_elf_ram_sym(kernel_filename, NULL, NULL, NULL, &kernel_entry, NULL, &kernel_high, 0, EM_RISCV, 1, 0, NULL, true, htif_symbol_callback) < 0) { error_report("could not load kernel '%s'", kernel_filename); diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c index e7f0716fb667..3e8b19c66898 100644 --- a/hw/riscv/virt.c +++ b/hw/riscv/virt.c @@ -66,7 +66,7 @@ static uint64_t load_kernel(const char *kernel_filename) { uint64_t kernel_entry, kernel_high; =20 - if (load_elf(kernel_filename, NULL, NULL, + if (load_elf(kernel_filename, NULL, NULL, NULL, &kernel_entry, NULL, &kernel_high, 0, EM_RISCV, 1, 0) < 0) { error_report("could not load kernel '%s'", kernel_filename); diff --git a/hw/s390x/ipl.c b/hw/s390x/ipl.c index 21f64ad26aae..896888bf8f00 100644 --- a/hw/s390x/ipl.c +++ b/hw/s390x/ipl.c @@ -131,7 +131,8 @@ static void s390_ipl_realize(DeviceState *dev, Error **= errp) goto error; } =20 - bios_size =3D load_elf(bios_filename, bios_translate_addr, &fwbase, + bios_size =3D load_elf(bios_filename, NULL, + bios_translate_addr, &fwbase, &ipl->bios_start_addr, NULL, NULL, 1, EM_S390, 0, 0); if (bios_size > 0) { @@ -155,7 +156,8 @@ static void s390_ipl_realize(DeviceState *dev, Error **= errp) } =20 if (ipl->kernel) { - kernel_size =3D load_elf(ipl->kernel, NULL, NULL, &pentry, NULL, + kernel_size =3D load_elf(ipl->kernel, NULL, NULL, NULL, + &pentry, NULL, NULL, 1, EM_S390, 0, 0); if (kernel_size < 0) { kernel_size =3D load_image_targphys(ipl->kernel, 0, ram_size); @@ -436,7 +438,8 @@ static int load_netboot_image(Error **errp) goto unref_mr; } =20 - img_size =3D load_elf_ram(netboot_filename, NULL, NULL, &ipl->start_ad= dr, + img_size =3D load_elf_ram(netboot_filename, NULL, NULL, NULL, + &ipl->start_addr, NULL, NULL, 1, EM_S390, 0, 0, NULL, false); =20 if (img_size < 0) { diff --git a/hw/sparc/leon3.c b/hw/sparc/leon3.c index fa98ab81776c..774639af3393 100644 --- a/hw/sparc/leon3.c +++ b/hw/sparc/leon3.c @@ -190,7 +190,8 @@ static void leon3_generic_hw_init(MachineState *machine) long kernel_size; uint64_t entry; =20 - kernel_size =3D load_elf(kernel_filename, NULL, NULL, &entry, NULL= , NULL, + kernel_size =3D load_elf(kernel_filename, NULL, NULL, NULL, + &entry, NULL, NULL, 1 /* big endian */, EM_SPARC, 0, 0); if (kernel_size < 0) { error_report("could not load kernel '%s'", kernel_filename); diff --git a/hw/sparc/sun4m.c b/hw/sparc/sun4m.c index 709ee37e08a4..779f3f97d5d4 100644 --- a/hw/sparc/sun4m.c +++ b/hw/sparc/sun4m.c @@ -242,7 +242,8 @@ static unsigned long sun4m_load_kernel(const char *kern= el_filename, #else bswap_needed =3D 0; #endif - kernel_size =3D load_elf(kernel_filename, translate_kernel_address= , NULL, + kernel_size =3D load_elf(kernel_filename, NULL, + translate_kernel_address, NULL, NULL, NULL, NULL, 1, EM_SPARC, 0, 0); if (kernel_size < 0) kernel_size =3D load_aout(kernel_filename, KERNEL_LOAD_ADDR, @@ -692,7 +693,8 @@ static void prom_init(hwaddr addr, const char *bios_nam= e) } filename =3D qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name); if (filename) { - ret =3D load_elf(filename, translate_prom_address, &addr, NULL, + ret =3D load_elf(filename, NULL, + translate_prom_address, &addr, NULL, NULL, NULL, 1, EM_SPARC, 0, 0); if (ret < 0 || ret > PROM_SIZE_MAX) { ret =3D load_image_targphys(filename, addr, PROM_SIZE_MAX); diff --git a/hw/sparc64/sun4u.c b/hw/sparc64/sun4u.c index f76b19e4e93b..b9bd4be5d512 100644 --- a/hw/sparc64/sun4u.c +++ b/hw/sparc64/sun4u.c @@ -153,7 +153,7 @@ static uint64_t sun4u_load_kernel(const char *kernel_fi= lename, #else bswap_needed =3D 0; #endif - kernel_size =3D load_elf(kernel_filename, NULL, NULL, kernel_entry, + kernel_size =3D load_elf(kernel_filename, NULL, NULL, NULL, kernel= _entry, kernel_addr, &kernel_top, 1, EM_SPARCV9, 0,= 0); if (kernel_size < 0) { *kernel_addr =3D KERNEL_LOAD_ADDR; @@ -411,7 +411,7 @@ static void prom_init(hwaddr addr, const char *bios_nam= e) } filename =3D qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name); if (filename) { - ret =3D load_elf(filename, translate_prom_address, &addr, + ret =3D load_elf(filename, NULL, translate_prom_address, &addr, NULL, NULL, NULL, 1, EM_SPARCV9, 0, 0); if (ret < 0 || ret > PROM_SIZE_MAX) { ret =3D load_image_targphys(filename, addr, PROM_SIZE_MAX); diff --git a/hw/tricore/tricore_testboard.c b/hw/tricore/tricore_testboard.c index a58096f05e72..003592af27a6 100644 --- a/hw/tricore/tricore_testboard.c +++ b/hw/tricore/tricore_testboard.c @@ -45,7 +45,7 @@ static void tricore_load_kernel(CPUTriCoreState *env) long kernel_size; =20 kernel_size =3D load_elf(tricoretb_binfo.kernel_filename, NULL, - NULL, &entry, NULL, + NULL, NULL, &entry, NULL, NULL, 0, EM_TRICORE, 1, 0); if (kernel_size <=3D 0) { diff --git a/hw/xtensa/sim.c b/hw/xtensa/sim.c index b6ccb3cd4ae9..12c7437398e8 100644 --- a/hw/xtensa/sim.c +++ b/hw/xtensa/sim.c @@ -97,11 +97,15 @@ static void xtensa_sim_init(MachineState *machine) uint64_t elf_entry; uint64_t elf_lowaddr; #ifdef TARGET_WORDS_BIGENDIAN - int success =3D load_elf(kernel_filename, translate_phys_addr, cpu, - &elf_entry, &elf_lowaddr, NULL, 1, EM_XTENSA, 0, 0); + int success =3D load_elf(kernel_filename, NULL, + translate_phys_addr, cpu, + &elf_entry, &elf_lowaddr, + NULL, 1, EM_XTENSA, 0, 0); #else - int success =3D load_elf(kernel_filename, translate_phys_addr, cpu, - &elf_entry, &elf_lowaddr, NULL, 0, EM_XTENSA, 0, 0); + int success =3D load_elf(kernel_filename, NULL, + translate_phys_addr, cpu, + &elf_entry, &elf_lowaddr, + NULL, 0, EM_XTENSA, 0, 0); #endif if (success > 0) { env->pc =3D elf_entry; diff --git a/hw/xtensa/xtfpga.c b/hw/xtensa/xtfpga.c index 21094319a659..cec5bda3fc73 100644 --- a/hw/xtensa/xtfpga.c +++ b/hw/xtensa/xtfpga.c @@ -378,7 +378,7 @@ static void xtfpga_init(const XtfpgaBoardDesc *board, M= achineState *machine) =20 uint64_t elf_entry; uint64_t elf_lowaddr; - int success =3D load_elf(kernel_filename, translate_phys_addr, cpu, + int success =3D load_elf(kernel_filename, NULL, translate_phys_add= r, cpu, &elf_entry, &elf_lowaddr, NULL, be, EM_XTENSA, 0, 0); if (success > 0) { entry_point =3D elf_entry; diff --git a/include/hw/elf_ops.h b/include/hw/elf_ops.h index e2cb67519551..3438d6f69e8d 100644 --- a/include/hw/elf_ops.h +++ b/include/hw/elf_ops.h @@ -266,6 +266,7 @@ fail: } =20 static int glue(load_elf, SZ)(const char *name, int fd, + uint64_t (*elf_note_fn)(void *, void *, bool= ), uint64_t (*translate_fn)(void *, uint64_t), void *translate_opaque, int must_swab, uint64_t *pentry, @@ -498,6 +499,7 @@ static int glue(load_elf, SZ)(const char *name, int fd, data =3D NULL; } } + g_free(phdr); if (lowaddr) *lowaddr =3D (uint64_t)(elf_sword)low; diff --git a/include/hw/loader.h b/include/hw/loader.h index de8a29603b0d..3e1b3a4566c9 100644 --- a/include/hw/loader.h +++ b/include/hw/loader.h @@ -93,6 +93,8 @@ const char *load_elf_strerror(int error); =20 /** load_elf_ram_sym: * @filename: Path of ELF file + * @elf_note_fn: optional function to parse ELF Note type + * passed via @translate_opaque * @translate_fn: optional function to translate load addresses * @translate_opaque: opaque data passed to @translate_fn * @pentry: Populated with program entry point. Ignored if NULL. @@ -125,6 +127,7 @@ typedef void (*symbol_fn_t)(const char *st_name, int st= _info, uint64_t st_value, uint64_t st_size); =20 int 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, int big_endian, @@ -136,6 +139,7 @@ int load_elf_ram_sym(const char *filename, * symbol callback function */ int load_elf_ram(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 *lowad= dr, uint64_t *highaddr, int big_endian, int elf_machine, @@ -146,6 +150,7 @@ int load_elf_ram(const char *filename, * Same as load_elf_ram(), but always loads the elf as ROM */ int load_elf_as(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 *lowadd= r, uint64_t *highaddr, int big_endian, int elf_machine, @@ -155,7 +160,9 @@ int load_elf_as(const char *filename, * Same as load_elf_as(), but doesn't allow the caller to specify an * AddressSpace. */ -int load_elf(const char *filename, uint64_t (*translate_fn)(void *, uint64= _t), +int load_elf(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, int big_endian, int elf_machine, int clear_lsb, int data_swab); --=20 1.8.3.1 From nobody Sun Feb 8 22:22:38 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=oracle.com Return-Path: Received: from lists.gnu.org (209.51.188.17 [209.51.188.17]) by mx.zohomail.com with SMTPS id 154755486431127.096063087660582; Tue, 15 Jan 2019 04:21:04 -0800 (PST) Received: from localhost ([127.0.0.1]:57346 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gjNi8-0000XD-R7 for importer@patchew.org; Tue, 15 Jan 2019 07:20:52 -0500 Received: from eggs.gnu.org ([209.51.188.92]:41787) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gjNfx-0007ee-Hr for qemu-devel@nongnu.org; Tue, 15 Jan 2019 07:18:38 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gjNfw-0003GL-LL for qemu-devel@nongnu.org; Tue, 15 Jan 2019 07:18:37 -0500 Received: from userp2120.oracle.com ([156.151.31.85]:43410) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gjNfw-0003Fo-Cs for qemu-devel@nongnu.org; Tue, 15 Jan 2019 07:18:36 -0500 Received: from pps.filterd (userp2120.oracle.com [127.0.0.1]) by userp2120.oracle.com (8.16.0.22/8.16.0.22) with SMTP id x0FC8hkb146843; Tue, 15 Jan 2019 12:18:34 GMT Received: from aserv0022.oracle.com (aserv0022.oracle.com [141.146.126.234]) by userp2120.oracle.com with ESMTP id 2pybjs3hj0-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Tue, 15 Jan 2019 12:18:34 +0000 Received: from aserv0121.oracle.com (aserv0121.oracle.com [141.146.126.235]) by aserv0022.oracle.com (8.14.4/8.14.4) with ESMTP id x0FCIXrC030457 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Tue, 15 Jan 2019 12:18:33 GMT Received: from abhmp0005.oracle.com (abhmp0005.oracle.com [141.146.116.11]) by aserv0121.oracle.com (8.14.4/8.13.8) with ESMTP id x0FCIX3v031514; Tue, 15 Jan 2019 12:18:33 GMT Received: from ol7.uk.oracle.com (/10.175.168.140) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Tue, 15 Jan 2019 04:18:33 -0800 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oracle.com; h=from : to : cc : subject : date : message-id : in-reply-to : references; s=corp-2018-07-02; bh=JIDLd9Pqmke2zJyhBsbRc5FMRl/39QMt70NfSye44aM=; b=nQHRlyMgNMiH7bWU/xlKi3Bx2ldHmRIyRLKUREO0el0WtD/+b7ct3k7DCRlr0eWSKzBi LLZ2IWVUdJIiUXYlD9uGq5cLpK9PKyKuYaXBKNGJ4T+awAHajteDRE2s55sBOU2q6Nf3 tbIvKiXAnbi2B3ESHf2841MAJ5ZqkKED13WbjHvcRc+gAqOUlKCfxYWqJbJ8IcWVSdOG qo8gEZpapqtTj8nGZn51IG/NkLCFJ0LQnloDtC6h328TUDEfvvWM1VPHyeEgn2R+83ir SgclkerIqXsLlVcrYoA03q/kYfzKgiJyKQaJly+digVXDWRApHtf9ueM+Qc7Jc7/uByt Qw== From: Liam Merwick To: qemu-devel@nongnu.org Date: Tue, 15 Jan 2019 12:18:04 +0000 Message-Id: <1547554687-12687-3-git-send-email-liam.merwick@oracle.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1547554687-12687-1-git-send-email-liam.merwick@oracle.com> References: <1547554687-12687-1-git-send-email-liam.merwick@oracle.com> X-Proofpoint-Virus-Version: vendor=nai engine=5900 definitions=9136 signatures=668680 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 suspectscore=3 malwarescore=0 phishscore=0 bulkscore=0 spamscore=0 mlxscore=0 mlxlogscore=999 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1810050000 definitions=main-1901150102 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x [generic] X-Received-From: 156.151.31.85 Subject: [Qemu-devel] [PATCH v3 2/5] elf-ops.h: Add get_elf_note_type() X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: ehabkost@redhat.com, mst@redhat.com, maran.wilson@oracle.com, george.kennedy@oracle.com, stefanha@redhat.com, xen-devel@lists.xenproject.org, pbonzini@redhat.com, boris.ostrovsky@oracle.com, rth@twiddle.net, sgarzare@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Introduce a routine which, given a pointer to a range of ELF Notes, searches through them looking for a note matching the type specified and returns a pointer to the matching ELF note. get_elf_note_type() is used by elf_load[32|64]() to find the specified note type required by the 'elf_note_fn' parameter added in the previous commit. Signed-off-by: Liam Merwick --- include/hw/elf_ops.h | 75 ++++++++++++++++++++++++++++++++++++++++++++++++= ++++ 1 file changed, 75 insertions(+) diff --git a/include/hw/elf_ops.h b/include/hw/elf_ops.h index 3438d6f69e8d..690f9238c8cc 100644 --- a/include/hw/elf_ops.h +++ b/include/hw/elf_ops.h @@ -265,6 +265,51 @@ fail: return ret; } =20 +/* + * Given 'nhdr', a pointer to a range of ELF Notes, search through them + * for a note matching type 'elf_note_type' and return a pointer to + * the matching ELF note. + */ +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 nhdr_size =3D sizeof(struct elf_note); + elf_word elf_note_entry_offset =3D 0; + elf_word note_type; + elf_word nhdr_namesz; + elf_word nhdr_descsz; + + if (nhdr =3D=3D NULL) { + return NULL; + } + + note_type =3D nhdr->n_type; + while (note_type !=3D elf_note_type) { + nhdr_namesz =3D nhdr->n_namesz; + nhdr_descsz =3D nhdr->n_descsz; + + elf_note_entry_offset =3D nhdr_size + + QEMU_ALIGN_UP(nhdr_namesz, phdr_align) + + QEMU_ALIGN_UP(nhdr_descsz, phdr_align); + + /* + * If the offset calculated in this iteration exceeds the + * supplied size, we are done and no matching note was found. + */ + if (elf_note_entry_offset > note_size) { + return NULL; + } + + /* skip to the next ELF Note entry */ + nhdr =3D (void *)nhdr + elf_note_entry_offset; + note_type =3D nhdr->n_type; + } + + return nhdr; +} + static int glue(load_elf, SZ)(const char *name, int fd, uint64_t (*elf_note_fn)(void *, void *, bool= ), uint64_t (*translate_fn)(void *, uint64_t), @@ -497,6 +542,36 @@ static int glue(load_elf, SZ)(const char *name, int fd, high =3D addr + mem_size; =20 data =3D NULL; + + } else if (ph->p_type =3D=3D PT_NOTE && elf_note_fn) { + struct elf_note *nhdr =3D NULL; + + file_size =3D ph->p_filesz; /* Size of the range of ELF notes = */ + data =3D g_malloc0(file_size); + if (ph->p_filesz > 0) { + if (lseek(fd, ph->p_offset, SEEK_SET) < 0) { + goto fail; + } + if (read(fd, data, file_size) !=3D file_size) { + goto fail; + } + } + + /* + * Search the ELF notes to find one with a type matching the + * value passed in via 'translate_opaque' + */ + nhdr =3D (struct elf_note *)data; + assert(translate_opaque !=3D NULL); + nhdr =3D glue(get_elf_note_type, SZ)(nhdr, file_size, ph->p_al= ign, + *(uint64_t *)translate_opaq= ue); + if (nhdr !=3D NULL) { + bool is64 =3D + sizeof(struct elf_note) =3D=3D sizeof(struct elf64_not= e); + elf_note_fn((void *)nhdr, (void *)&ph->p_align, is64); + } + g_free(data); + data =3D NULL; } } =20 --=20 1.8.3.1 From nobody Sun Feb 8 22:22:38 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=oracle.com Return-Path: Received: from lists.gnu.org (209.51.188.17 [209.51.188.17]) by mx.zohomail.com with SMTPS id 1547554867307622.1363160985172; Tue, 15 Jan 2019 04:21:07 -0800 (PST) Received: from localhost ([127.0.0.1]:57361 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gjNiG-0000bV-E2 for importer@patchew.org; Tue, 15 Jan 2019 07:21:00 -0500 Received: from eggs.gnu.org ([209.51.188.92]:41815) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gjNg0-0007fg-H7 for qemu-devel@nongnu.org; Tue, 15 Jan 2019 07:18:42 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gjNfz-0003IC-34 for qemu-devel@nongnu.org; Tue, 15 Jan 2019 07:18:40 -0500 Received: from userp2130.oracle.com ([156.151.31.86]:53586) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gjNfy-0003Hh-R4 for qemu-devel@nongnu.org; Tue, 15 Jan 2019 07:18:39 -0500 Received: from pps.filterd (userp2130.oracle.com [127.0.0.1]) by userp2130.oracle.com (8.16.0.22/8.16.0.22) with SMTP id x0FC8geE188774; Tue, 15 Jan 2019 12:18:37 GMT Received: from aserv0021.oracle.com (aserv0021.oracle.com [141.146.126.233]) by userp2130.oracle.com with ESMTP id 2pybkcbhea-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Tue, 15 Jan 2019 12:18:36 +0000 Received: from aserv0121.oracle.com (aserv0121.oracle.com [141.146.126.235]) by aserv0021.oracle.com (8.14.4/8.14.4) with ESMTP id x0FCIawO027418 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Tue, 15 Jan 2019 12:18:36 GMT Received: from abhmp0005.oracle.com (abhmp0005.oracle.com [141.146.116.11]) by aserv0121.oracle.com (8.14.4/8.13.8) with ESMTP id x0FCIZAF031524; Tue, 15 Jan 2019 12:18:35 GMT Received: from ol7.uk.oracle.com (/10.175.168.140) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Tue, 15 Jan 2019 04:18:35 -0800 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oracle.com; h=from : to : cc : subject : date : message-id : in-reply-to : references; s=corp-2018-07-02; bh=b1r+HCDdXXUUvOMp8RTTq7uU9dSc54IYayKpP7jWD1Q=; b=szhNyR73uZA6fr12ZvV6Va5oEtHQRT8XR/Z4iCeK4q4hB1R9C/jy8JkIuUMVhpIhEjsB qNXzH46tPs7zLQpwU+n2q3yTFLPqxtXRBm8Ea9cW2Ap5Kq7LURAmoj/Fk753oa7SCXH2 vaFZsruHNgPmf/3O9nilcWfJqWrE3f+LA7qpGLhGrfXyh94FuDTZoI+lZL/bwM8ei4GX roov9mh/ZBhy1JbIMPPSKbu3jyCs7UbRnKNQl5yjvfU85J66wdYiB148xNJKA+bWHwZV nyuAWrRNM3kAQwLBykV0dg/iAKnqF5Zk8kqXr1k71EMnPkWyTPDdKeVlJHgc13xSkcci Kw== From: Liam Merwick To: qemu-devel@nongnu.org Date: Tue, 15 Jan 2019 12:18:05 +0000 Message-Id: <1547554687-12687-4-git-send-email-liam.merwick@oracle.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1547554687-12687-1-git-send-email-liam.merwick@oracle.com> References: <1547554687-12687-1-git-send-email-liam.merwick@oracle.com> X-Proofpoint-Virus-Version: vendor=nai engine=5900 definitions=9136 signatures=668680 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 suspectscore=0 malwarescore=0 phishscore=0 bulkscore=0 spamscore=0 mlxscore=0 mlxlogscore=908 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1810050000 definitions=main-1901150102 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x [generic] X-Received-From: 156.151.31.86 Subject: [Qemu-devel] [PATCH v3 3/5] pvh: Add x86/HVM direct boot ABI header file X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: ehabkost@redhat.com, mst@redhat.com, maran.wilson@oracle.com, george.kennedy@oracle.com, stefanha@redhat.com, xen-devel@lists.xenproject.org, pbonzini@redhat.com, boris.ostrovsky@oracle.com, rth@twiddle.net, sgarzare@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" From: Liam Merwick The x86/HVM direct boot ABI permits Qemu to be able to boot directly into the uncompressed Linux kernel binary with minimal firmware involvement. https://xenbits.xen.org/docs/unstable/misc/pvh.html This commit adds the header file that defines the start_info struct that needs to be populated in order to use this ABI. The canonical version of start_info.h is in the Xen codebase. (like QEMU, the Linux kernel uses a copy as well). Signed-off-by: Liam Merwick Reviewed-by: Konrad Rzeszutek Wilk --- include/hw/xen/start_info.h | 146 ++++++++++++++++++++++++++++++++++++++++= ++++ 1 file changed, 146 insertions(+) create mode 100644 include/hw/xen/start_info.h diff --git a/include/hw/xen/start_info.h b/include/hw/xen/start_info.h new file mode 100644 index 000000000000..348779eb10cd --- /dev/null +++ b/include/hw/xen/start_info.h @@ -0,0 +1,146 @@ +/* + * Permission is hereby granted, free of charge, to any person obtaining a= copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation = the + * rights to use, copy, modify, merge, publish, distribute, sublicense, an= d/or + * sell copies of the Software, and to permit persons to whom the Software= is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included= in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS= OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL= THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Copyright (c) 2016, Citrix Systems, Inc. + */ + +#ifndef __XEN_PUBLIC_ARCH_X86_HVM_START_INFO_H__ +#define __XEN_PUBLIC_ARCH_X86_HVM_START_INFO_H__ + +/* + * Start of day structure passed to PVH guests and to HVM guests in %ebx. + * + * NOTE: nothing will be loaded at physical address 0, so a 0 value in any + * of the address fields should be treated as not present. + * + * 0 +----------------+ + * | magic | Contains the magic value XEN_HVM_START_MAGIC_VALUE + * | | ("xEn3" with the 0x80 bit of the "E" set). + * 4 +----------------+ + * | version | Version of this structure. Current version is 1. = New + * | | versions are guaranteed to be backwards-compatibl= e. + * 8 +----------------+ + * | flags | SIF_xxx flags. + * 12 +----------------+ + * | nr_modules | Number of modules passed to the kernel. + * 16 +----------------+ + * | modlist_paddr | Physical address of an array of modules + * | | (layout of the structure below). + * 24 +----------------+ + * | cmdline_paddr | Physical address of the command line, + * | | a zero-terminated ASCII string. + * 32 +----------------+ + * | rsdp_paddr | Physical address of the RSDP ACPI data structure. + * 40 +----------------+ + * | memmap_paddr | Physical address of the (optional) memory map. On= ly + * | | present in version 1 and newer of the structure. + * 48 +----------------+ + * | memmap_entries | Number of entries in the memory map table. Only + * | | present in version 1 and newer of the structure. + * | | Zero if there is no memory map being provided. + * 52 +----------------+ + * | reserved | Version 1 and newer only. + * 56 +----------------+ + * + * The layout of each entry in the module structure is the following: + * + * 0 +----------------+ + * | paddr | Physical address of the module. + * 8 +----------------+ + * | size | Size of the module in bytes. + * 16 +----------------+ + * | cmdline_paddr | Physical address of the command line, + * | | a zero-terminated ASCII string. + * 24 +----------------+ + * | reserved | + * 32 +----------------+ + * + * The layout of each entry in the memory map table is as follows: + * + * 0 +----------------+ + * | addr | Base address + * 8 +----------------+ + * | size | Size of mapping in bytes + * 16 +----------------+ + * | type | Type of mapping as defined between the hypervisor + * | | and guest it's starting. E820_TYPE_xxx, for examp= le. + * 20 +----------------| + * | reserved | + * 24 +----------------+ + * + * The address and sizes are always a 64bit little endian unsigned integer. + * + * NB: Xen on x86 will always try to place all the data below the 4GiB + * boundary. + * + * Version numbers of the hvm_start_info structure have evolved like this: + * + * Version 0: + * + * Version 1: Added the memmap_paddr/memmap_entries fields (plus 4 bytes= of + * padding) to the end of the hvm_start_info struct. These new + * fields can be used to pass a memory map to the guest. The + * memory map is optional and so guests that understand versi= on 1 + * of the structure must check that memmap_entries is non-zero + * before trying to read the memory map. + */ +#define XEN_HVM_START_MAGIC_VALUE 0x336ec578 + +/* + * C representation of the x86/HVM start info layout. + * + * The canonical definition of this layout is above, this is just a way to + * represent the layout described there using C types. + */ +struct hvm_start_info { + uint32_t magic; /* Contains the magic value 0x336ec578 = */ + /* ("xEn3" with the 0x80 bit of the "E" se= t).*/ + uint32_t version; /* Version of this structure. = */ + uint32_t flags; /* SIF_xxx flags. = */ + uint32_t nr_modules; /* Number of modules passed to the kernel.= */ + uint64_t modlist_paddr; /* Physical address of an array of = */ + /* hvm_modlist_entry. = */ + uint64_t cmdline_paddr; /* Physical address of the command line. = */ + uint64_t rsdp_paddr; /* Physical address of the RSDP ACPI data = */ + /* structure. = */ + uint64_t memmap_paddr; /* Physical address of an array of = */ + /* hvm_memmap_table_entry. Only present in= */ + /* version 1 and newer of the structure = */ + uint32_t memmap_entries; /* Number of entries in the memmap table. = */ + /* Only present in version 1 and newer of = */ + /* the structure. Value will be zero if = */ + /* there is no memory map being provided. = */ + uint32_t reserved; +}; + +struct hvm_modlist_entry { + uint64_t paddr; /* Physical address of the module. = */ + uint64_t size; /* Size of the module in bytes. = */ + uint64_t cmdline_paddr; /* Physical address of the command line. = */ + uint64_t reserved; +}; + +struct hvm_memmap_table_entry { + uint64_t addr; /* Base address of the memory region = */ + uint64_t size; /* Size of the memory region in bytes = */ + uint32_t type; /* Mapping type = */ + uint32_t reserved; +}; + +#endif /* __XEN_PUBLIC_ARCH_X86_HVM_START_INFO_H__ */ --=20 1.8.3.1 From nobody Sun Feb 8 22:22:38 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=oracle.com Return-Path: Received: from lists.gnu.org (209.51.188.17 [209.51.188.17]) by mx.zohomail.com with SMTPS id 1547554866425206.77277611021054; Tue, 15 Jan 2019 04:21:06 -0800 (PST) Received: from localhost ([127.0.0.1]:57392 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gjNiL-0000jB-9R for importer@patchew.org; Tue, 15 Jan 2019 07:21:05 -0500 Received: from eggs.gnu.org ([209.51.188.92]:41849) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gjNg8-0007j1-Mw for qemu-devel@nongnu.org; Tue, 15 Jan 2019 07:18:50 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gjNg6-0003Nc-Cm for qemu-devel@nongnu.org; Tue, 15 Jan 2019 07:18:48 -0500 Received: from userp2120.oracle.com ([156.151.31.85]:43544) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gjNg6-0003ME-3K for qemu-devel@nongnu.org; Tue, 15 Jan 2019 07:18:46 -0500 Received: from pps.filterd (userp2120.oracle.com [127.0.0.1]) by userp2120.oracle.com (8.16.0.22/8.16.0.22) with SMTP id x0FC8hkc146843; Tue, 15 Jan 2019 12:18:44 GMT Received: from userv0022.oracle.com (userv0022.oracle.com [156.151.31.74]) by userp2120.oracle.com with ESMTP id 2pybjs3hjd-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Tue, 15 Jan 2019 12:18:44 +0000 Received: from userv0121.oracle.com (userv0121.oracle.com [156.151.31.72]) by userv0022.oracle.com (8.14.4/8.14.4) with ESMTP id x0FCIcev029065 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Tue, 15 Jan 2019 12:18:38 GMT Received: from abhmp0005.oracle.com (abhmp0005.oracle.com [141.146.116.11]) by userv0121.oracle.com (8.14.4/8.13.8) with ESMTP id x0FCIceZ003461; Tue, 15 Jan 2019 12:18:38 GMT Received: from ol7.uk.oracle.com (/10.175.168.140) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Tue, 15 Jan 2019 04:18:37 -0800 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oracle.com; h=from : to : cc : subject : date : message-id : in-reply-to : references; s=corp-2018-07-02; bh=uZiJ7hMcDkB2pctDWjRdMQ3YXd8NlrJjpWkkCYdmcWk=; b=Egd78jqn+feO92K2XLZf5k1hKYA4fI5+FsT9jg1wjyGuuqbI+JclCgm3ygCVKVreKMR0 RJxMaMnWZAwZMhzNR4jsfiZSzLVSSw8oGRIV/YLnEF1Y47uh3b3V/fB6XpXQOnSjp5zu qOU3z1TVKc1+KuaLTG9xsiD6wG0XrcDl9F07pR3qP4mMX+aDttSHDWjDVT0HFZkpoZWL VMaL4PiU9Xur7aP8rTrFcjZ5SgvbexOroVjBx5Mf1+ZRhWD7H/6QvRRop8oRoQyjxwPj JC4EXYihskf4Rej9zXOykfaTcC5Zc/scXYIuDZ3U756ILl7WMFOyIDuIxSAL2bdnBA2U CQ== From: Liam Merwick To: qemu-devel@nongnu.org Date: Tue, 15 Jan 2019 12:18:06 +0000 Message-Id: <1547554687-12687-5-git-send-email-liam.merwick@oracle.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1547554687-12687-1-git-send-email-liam.merwick@oracle.com> References: <1547554687-12687-1-git-send-email-liam.merwick@oracle.com> X-Proofpoint-Virus-Version: vendor=nai engine=5900 definitions=9136 signatures=668680 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 suspectscore=1 malwarescore=0 phishscore=0 bulkscore=0 spamscore=0 mlxscore=0 mlxlogscore=851 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1810050000 definitions=main-1901150102 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x [generic] X-Received-From: 156.151.31.85 Subject: [Qemu-devel] [PATCH v3 4/5] pvh: Boot uncompressed kernel using direct boot ABI X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: ehabkost@redhat.com, mst@redhat.com, maran.wilson@oracle.com, george.kennedy@oracle.com, stefanha@redhat.com, xen-devel@lists.xenproject.org, pbonzini@redhat.com, boris.ostrovsky@oracle.com, rth@twiddle.net, sgarzare@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" These changes (along with corresponding Linux kernel and qboot changes) enable a guest to be booted using the x86/HVM direct boot ABI. This commit adds a load_elfboot() routine to pass the size and location of the kernel entry point to qboot (which will fill in the start_info struct information needed to to boot the guest). Having loaded the ELF binary, load_linux() will run qboot which continues the boot. The address for the kernel entry point is read from an ELF Note in the uncompressed kernel binary by a helper routine passed to load_elf(). Co-developed-by: George Kennedy Signed-off-by: George Kennedy Signed-off-by: Liam Merwick --- hw/i386/pc.c | 135 ++++++++++++++++++++++++++++++++++++++++++++++++++++++= ++++ include/elf.h | 10 +++++ 2 files changed, 145 insertions(+) diff --git a/hw/i386/pc.c b/hw/i386/pc.c index 73d688f84239..6d549950a044 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -54,6 +54,7 @@ #include "sysemu/qtest.h" #include "kvm_i386.h" #include "hw/xen/xen.h" +#include "hw/xen/start_info.h" #include "ui/qemu-spice.h" #include "exec/memory.h" #include "exec/address-spaces.h" @@ -110,6 +111,9 @@ static struct e820_entry *e820_table; static unsigned e820_entries; struct hpet_fw_config hpet_cfg =3D {.count =3D UINT8_MAX}; =20 +/* Physical Address of PVH entry point read from kernel ELF NOTE */ +static size_t pvh_start_addr; + GlobalProperty pc_compat_3_1[] =3D { { "intel-iommu", "dma-drain", "off" }, { "Opteron_G3" "-" TYPE_X86_CPU, "rdtscp", "off" }, @@ -1060,6 +1064,109 @@ struct setup_data { uint8_t data[0]; } __attribute__((packed)); =20 + +/* + * The entry point into the kernel for PVH boot is different from + * the native entry point. The PVH entry is defined by the x86/HVM + * direct boot ABI and is available in an ELFNOTE in the kernel binary. + * + * This function is passed to load_elf() when it is called from + * load_elfboot() which then additionally checks for an ELF Note of + * type XEN_ELFNOTE_PHYS32_ENTRY and passes it to this function to + * parse the PVH entry address from the ELF Note. + * + * Due to trickery in elf_opts.h, load_elf() is actually available as + * load_elf32() or load_elf64() and this routine needs to be able + * to deal with being called as 32 or 64 bit. + * + * The address of the PVH entry point is saved to the 'pvh_start_addr' + * global variable. (although the entry point is 32-bit, the kernel + * binary can be either 32-bit or 64-bit). + */ +static uint64_t read_pvh_start_addr(void *arg1, void *arg2, bool is64) +{ + size_t *elf_note_data_addr; + + /* Check if ELF Note header passed in is valid */ + if (arg1 =3D=3D NULL) { + return 0; + } + + if (is64) { + struct elf64_note *nhdr64 =3D (struct elf64_note *)arg1; + uint64_t nhdr_size64 =3D sizeof(struct elf64_note); + uint64_t phdr_align =3D *(uint64_t *)arg2; + uint64_t nhdr_namesz =3D nhdr64->n_namesz; + + elf_note_data_addr =3D + ((void *)nhdr64) + nhdr_size64 + + QEMU_ALIGN_UP(nhdr_namesz, phdr_align); + } else { + struct elf32_note *nhdr32 =3D (struct elf32_note *)arg1; + uint32_t nhdr_size32 =3D sizeof(struct elf32_note); + uint32_t phdr_align =3D *(uint32_t *)arg2; + uint32_t nhdr_namesz =3D nhdr32->n_namesz; + + elf_note_data_addr =3D + ((void *)nhdr32) + nhdr_size32 + + QEMU_ALIGN_UP(nhdr_namesz, phdr_align); + } + + pvh_start_addr =3D *elf_note_data_addr; + + return pvh_start_addr; +} + +static bool load_elfboot(const char *kernel_filename, + int kernel_file_size, + uint8_t *header, + size_t pvh_xen_start_addr, + FWCfgState *fw_cfg) +{ + uint32_t flags =3D 0; + uint32_t mh_load_addr =3D 0; + uint32_t elf_kernel_size =3D 0; + uint64_t elf_entry; + uint64_t elf_low, elf_high; + int kernel_size; + + if (ldl_p(header) !=3D 0x464c457f) { + return false; /* no elfboot */ + } + + bool elf_is64 =3D header[EI_CLASS] =3D=3D ELFCLASS64; + flags =3D elf_is64 ? + ((Elf64_Ehdr *)header)->e_flags : ((Elf32_Ehdr *)header)->e_flags; + + if (flags & 0x00010004) { /* LOAD_ELF_HEADER_HAS_ADDR */ + error_report("elfboot unsupported flags =3D %x", flags); + exit(1); + } + + uint64_t elf_note_type =3D XEN_ELFNOTE_PHYS32_ENTRY; + kernel_size =3D load_elf(kernel_filename, read_pvh_start_addr, + NULL, &elf_note_type, &elf_entry, + &elf_low, &elf_high, 0, I386_ELF_MACHINE, + 0, 0); + + if (kernel_size < 0) { + error_report("Error while loading elf kernel"); + exit(1); + } + mh_load_addr =3D elf_low; + elf_kernel_size =3D elf_high - elf_low; + + if (pvh_start_addr =3D=3D 0) { + error_report("Error loading uncompressed kernel without PVH ELF No= te"); + exit(1); + } + fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_ENTRY, pvh_start_addr); + fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_ADDR, mh_load_addr); + fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_SIZE, elf_kernel_size); + + return true; +} + static void load_linux(PCMachineState *pcms, FWCfgState *fw_cfg) { @@ -1099,6 +1206,34 @@ static void load_linux(PCMachineState *pcms, if (ldl_p(header+0x202) =3D=3D 0x53726448) { protocol =3D lduw_p(header+0x206); } else { + /* + * Check if the file is an uncompressed kernel file (ELF) and load= it, + * saving the PVH entry point used by the x86/HVM direct boot ABI. + * If load_elfboot() is successful, populate the fw_cfg info. + */ + if (load_elfboot(kernel_filename, kernel_size, + header, pvh_start_addr, fw_cfg)) { + struct hvm_modlist_entry ramdisk_mod =3D { 0 }; + + fclose(f); + + fw_cfg_add_i32(fw_cfg, FW_CFG_CMDLINE_SIZE, + strlen(kernel_cmdline) + 1); + fw_cfg_add_string(fw_cfg, FW_CFG_CMDLINE_DATA, kernel_cmdline); + + assert(machine->device_memory !=3D NULL); + ramdisk_mod.paddr =3D machine->device_memory->base; + ramdisk_mod.size =3D + memory_region_size(&machine->device_memory->mr); + + fw_cfg_add_bytes(fw_cfg, FW_CFG_KERNEL_DATA, &ramdisk_mod, + sizeof(ramdisk_mod)); + fw_cfg_add_i32(fw_cfg, FW_CFG_SETUP_SIZE, sizeof(header)); + fw_cfg_add_bytes(fw_cfg, FW_CFG_SETUP_DATA, + header, sizeof(header)); + + return; + } /* This looks like a multiboot kernel. If it is, let's stop treating it like a Linux kernel. */ if (load_multiboot(fw_cfg, f, kernel_filename, initrd_filename, diff --git a/include/elf.h b/include/elf.h index e816fb4d7646..b35347eee767 100644 --- a/include/elf.h +++ b/include/elf.h @@ -1640,6 +1640,16 @@ typedef struct elf64_shdr { #define NT_ARM_HW_WATCH 0x403 /* ARM hardware watchpoint registe= rs */ #define NT_ARM_SYSTEM_CALL 0x404 /* ARM system call number */ =20 +/* + * Physical entry point into the kernel. + * + * 32bit entry point into the kernel. When requested to launch the + * guest kernel, use this entry point to launch the guest in 32-bit + * protected mode with paging disabled. + * + * [ Corresponding definition in Linux kernel: include/xen/interface/elfno= te.h ] + */ +#define XEN_ELFNOTE_PHYS32_ENTRY 18 /* 0x12 */ =20 /* Note header in a PT_NOTE section */ typedef struct elf32_note { --=20 1.8.3.1 From nobody Sun Feb 8 22:22:38 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=oracle.com Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1547555081017527.3069549796471; Tue, 15 Jan 2019 04:24:41 -0800 (PST) Received: from localhost ([127.0.0.1]:58355 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gjNlo-0003RC-3x for importer@patchew.org; Tue, 15 Jan 2019 07:24:40 -0500 Received: from eggs.gnu.org ([209.51.188.92]:42010) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gjNh7-00005y-RQ for qemu-devel@nongnu.org; Tue, 15 Jan 2019 07:19:50 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gjNh6-00046T-VP for qemu-devel@nongnu.org; Tue, 15 Jan 2019 07:19:49 -0500 Received: from aserp2130.oracle.com ([141.146.126.79]:40184) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gjNh6-00045t-Oj for qemu-devel@nongnu.org; Tue, 15 Jan 2019 07:19:48 -0500 Received: from pps.filterd (aserp2130.oracle.com [127.0.0.1]) by aserp2130.oracle.com (8.16.0.22/8.16.0.22) with SMTP id x0FC8hPH138858; Tue, 15 Jan 2019 12:18:47 GMT Received: from userv0021.oracle.com (userv0021.oracle.com [156.151.31.71]) by aserp2130.oracle.com with ESMTP id 2pybjnkhbq-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Tue, 15 Jan 2019 12:18:47 +0000 Received: from aserv0121.oracle.com (aserv0121.oracle.com [141.146.126.235]) by userv0021.oracle.com (8.14.4/8.14.4) with ESMTP id x0FCIeFA028818 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Tue, 15 Jan 2019 12:18:41 GMT Received: from abhmp0005.oracle.com (abhmp0005.oracle.com [141.146.116.11]) by aserv0121.oracle.com (8.14.4/8.13.8) with ESMTP id x0FCIea0031539; Tue, 15 Jan 2019 12:18:40 GMT Received: from ol7.uk.oracle.com (/10.175.168.140) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Tue, 15 Jan 2019 04:18:40 -0800 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oracle.com; h=from : to : cc : subject : date : message-id : in-reply-to : references; s=corp-2018-07-02; bh=GA1hpta+zKqI5V48a7mnOnlXUDkJJ0+74gRQ0FHk7a8=; b=cl23IkF0XB6wAA2Y/rpck2RJe+dzRIVdgFrJeOLVI5ydDpYKDKF+QcLMPLpQePPaf1VT m4srY1gIDvL/NhJzXL9PA9xqxDVilgnlq1j3ueTL1TwtE9Q42uhk4Ibe5WF1ZEbwtMnY 3q1J8yoWcpq973uBhoRyxetT4s71WQkGlb5cu3/wh8anf630qCsFqLb7p2RA4ihrfNLj ZQZtpvTGiAiAbHoSgR8zOVs5zxQXJ5sl538aX39LBpPQD83CLZwJ2+EUdpguLFab2zHZ uujpejnYqUDt6ldSg8O6kqZUa7EtTSQiBQEd4AGAMagFllcD1UWx045bZJp57rQrzYT1 Yw== From: Liam Merwick To: qemu-devel@nongnu.org Date: Tue, 15 Jan 2019 12:18:07 +0000 Message-Id: <1547554687-12687-6-git-send-email-liam.merwick@oracle.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1547554687-12687-1-git-send-email-liam.merwick@oracle.com> References: <1547554687-12687-1-git-send-email-liam.merwick@oracle.com> X-Proofpoint-Virus-Version: vendor=nai engine=5900 definitions=9136 signatures=668680 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 suspectscore=1 malwarescore=0 phishscore=0 bulkscore=0 spamscore=0 mlxscore=0 mlxlogscore=775 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1810050000 definitions=main-1901150102 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x [generic] X-Received-From: 141.146.126.79 Subject: [Qemu-devel] [PATCH v3 5/5] pvh: load initrd and expose it through fw_cfg X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: ehabkost@redhat.com, mst@redhat.com, maran.wilson@oracle.com, george.kennedy@oracle.com, stefanha@redhat.com, xen-devel@lists.xenproject.org, pbonzini@redhat.com, boris.ostrovsky@oracle.com, rth@twiddle.net, sgarzare@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" From: Stefano Garzarella When initrd is specified, load and expose it to the guest firmware through fw_cfg. The firmware will fill the hvm_start_info for the kernel. Signed-off-by: Stefano Garzarella Based-on: <1545422632-24444-5-git-send-email-liam.merwick@oracle.com> Signed-off-by: Liam Merwick --- hw/i386/pc.c | 38 +++++++++++++++++++++++++++++--------- 1 file changed, 29 insertions(+), 9 deletions(-) diff --git a/hw/i386/pc.c b/hw/i386/pc.c index 6d549950a044..9ed5063de8f8 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -1213,25 +1213,45 @@ static void load_linux(PCMachineState *pcms, */ if (load_elfboot(kernel_filename, kernel_size, header, pvh_start_addr, fw_cfg)) { - struct hvm_modlist_entry ramdisk_mod =3D { 0 }; - fclose(f); =20 fw_cfg_add_i32(fw_cfg, FW_CFG_CMDLINE_SIZE, strlen(kernel_cmdline) + 1); fw_cfg_add_string(fw_cfg, FW_CFG_CMDLINE_DATA, kernel_cmdline); =20 - assert(machine->device_memory !=3D NULL); - ramdisk_mod.paddr =3D machine->device_memory->base; - ramdisk_mod.size =3D - memory_region_size(&machine->device_memory->mr); - - fw_cfg_add_bytes(fw_cfg, FW_CFG_KERNEL_DATA, &ramdisk_mod, - sizeof(ramdisk_mod)); fw_cfg_add_i32(fw_cfg, FW_CFG_SETUP_SIZE, sizeof(header)); fw_cfg_add_bytes(fw_cfg, FW_CFG_SETUP_DATA, header, sizeof(header)); =20 + /* load initrd */ + if (initrd_filename) { + gsize initrd_size; + gchar *initrd_data; + GError *gerr =3D NULL; + + if (!g_file_get_contents(initrd_filename, &initrd_data, + &initrd_size, &gerr)) { + fprintf(stderr, "qemu: error reading initrd %s: %s\n", + initrd_filename, gerr->message); + exit(1); + } + + initrd_max =3D pcms->below_4g_mem_size - pcmc->acpi_data_s= ize - 1; + if (initrd_size >=3D initrd_max) { + fprintf(stderr, "qemu: initrd is too large, cannot sup= port." + "(max: %"PRIu32", need %"PRId64")\n", + initrd_max, (uint64_t)initrd_size); + exit(1); + } + + initrd_addr =3D (initrd_max - initrd_size) & ~4095; + + fw_cfg_add_i32(fw_cfg, FW_CFG_INITRD_ADDR, initrd_addr); + fw_cfg_add_i32(fw_cfg, FW_CFG_INITRD_SIZE, initrd_size); + fw_cfg_add_bytes(fw_cfg, FW_CFG_INITRD_DATA, initrd_data, + initrd_size); + } + return; } /* This looks like a multiboot kernel. If it is, let's stop --=20 1.8.3.1