From nobody Wed Oct 1 01:33:44 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.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 208.118.235.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 [208.118.235.17]) by mx.zohomail.com with SMTPS id 1545424134149897.7816785827102; Fri, 21 Dec 2018 12:28:54 -0800 (PST) Received: from localhost ([::1]:47754 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gaRPg-0004ev-BP for importer@patchew.org; Fri, 21 Dec 2018 15:28:52 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:41471) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gaROQ-000427-Vk for qemu-devel@nongnu.org; Fri, 21 Dec 2018 15:27:37 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gaROM-0001q7-0D for qemu-devel@nongnu.org; Fri, 21 Dec 2018 15:27:34 -0500 Received: from aserp2130.oracle.com ([141.146.126.79]:49614) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gaR4I-00055J-Hm for qemu-devel@nongnu.org; Fri, 21 Dec 2018 15:06:47 -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 wBLK46VG129529; Fri, 21 Dec 2018 20:04:08 GMT Received: from aserv0022.oracle.com (aserv0022.oracle.com [141.146.126.234]) by aserp2130.oracle.com with ESMTP id 2pf8gfquec-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Fri, 21 Dec 2018 20:04:07 +0000 Received: from aserv0122.oracle.com (aserv0122.oracle.com [141.146.126.236]) by aserv0022.oracle.com (8.14.4/8.14.4) with ESMTP id wBLK47hQ004574 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Fri, 21 Dec 2018 20:04:07 GMT Received: from abhmp0014.oracle.com (abhmp0014.oracle.com [141.146.116.20]) by aserv0122.oracle.com (8.14.4/8.14.4) with ESMTP id wBLK47Bt015392; Fri, 21 Dec 2018 20:04:07 GMT Received: from ol7.uk.oracle.com (/10.175.186.114) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Fri, 21 Dec 2018 12:04:06 -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=Fh+DzzoRj2iTVkrqA7kuRJ/g2HFNQMBM9hLTKJCp5LA=; b=YQbDAJYSONfOo1MivC9f6UGlBMGOjqtowBN4SeWioroTHO0VK8Hz401phvvu3jyvf4vR NaKIHl+mCu3S2ZGlwj3umLzFbP43aVJnKakhOxBJkArK6FSKMjqw1WJ08qj+ZtyrJkYj sHiwxt9u2L7PAk+9UQoDFt6U7dMFUqWkuNmTZ8Zx1ejd43F/Bt8S6bDy1v9eVP9/sM7m HDHKQiAQdGaEMvoUgYiNFqLGQ9mMZyNUMPIkfzIydgN07IKuiPhrbSzylvIS/pJec4FK q250Ubx0WdJ13MN2TFXL6hzXX0ywqZkNC0g3TKIf2vGPlmGWVK6ser3WhFNIVkR4oWJN iA== From: Liam Merwick To: qemu-devel@nongnu.org Date: Fri, 21 Dec 2018 20:03:49 +0000 Message-Id: <1545422632-24444-2-git-send-email-liam.merwick@oracle.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1545422632-24444-1-git-send-email-liam.merwick@oracle.com> References: <1545422632-24444-1-git-send-email-liam.merwick@oracle.com> X-Proofpoint-Virus-Version: vendor=nai engine=5900 definitions=9114 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-1812210150 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x [generic] [fuzzy] X-Received-From: 141.146.126.79 Subject: [Qemu-devel] [RFC v2 1/4] 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 | 23 +++++++++++++++++++++++ include/hw/loader.h | 9 ++++++++- 41 files changed, 134 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 4bf9131b81e4..a4d528537eb4 100644 --- a/hw/arm/armv7m.c +++ b/hw/arm/armv7m.c @@ -298,7 +298,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 94fce128028c..2b59379be6af 100644 --- a/hw/arm/boot.c +++ b/hw/arm/boot.c @@ -884,7 +884,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 fa41842280a0..eefa74c218a8 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 35bfeda7aa71..54c646810aa5 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 3e852e98cf9c..29eae06e9ad1 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 4b0ce09c5ee5..db11c00677de 100644 --- a/hw/moxie/moxiesim.c +++ b/hw/moxie/moxiesim.c @@ -58,7 +58,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 4bb5b601d3af..bc6a68cfa60a 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 e6747fce282a..28c77b693f59 100644 --- a/hw/ppc/e500.c +++ b/hw/ppc/e500.c @@ -990,7 +990,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 7e45afae7c55..f5a68be6319f 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 f5720f979e42..9bb71fbdcd4f 100644 --- a/hw/ppc/ppc440_bamboo.c +++ b/hw/ppc/ppc440_bamboo.c @@ -257,7 +257,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 5aac58f36ee1..4dfd47766aa6 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 55be0f56cbe2..6b4f1da197b1 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -2777,11 +2777,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 ee9b4b449086..9b383dc3d551 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 cb513cc3bb50..242773232e22 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 ef07df244241..21fbb732a74f 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 2b38f890702c..dcfbb99e4a16 100644 --- a/hw/riscv/virt.c +++ b/hw/riscv/virt.c @@ -61,7 +61,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 639906cca30c..c6a10cc8e1a2 100644 --- a/hw/sparc/sun4m.c +++ b/hw/sparc/sun4m.c @@ -243,7 +243,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, @@ -693,7 +694,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 74679ff8da3a..37d20a3800c1 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, @@ -496,8 +497,30 @@ 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; + } + } + + 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); } } + 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 0a0ad808ea39..130e73c32b21 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 Wed Oct 1 01:33:44 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.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 208.118.235.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 [208.118.235.17]) by mx.zohomail.com with SMTPS id 1545430216658674.0918589812217; Fri, 21 Dec 2018 14:10:16 -0800 (PST) Received: from localhost ([::1]:48344 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gaSzm-0001Xy-Lp for importer@patchew.org; Fri, 21 Dec 2018 17:10:14 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:46339) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gaSyh-00013l-38 for qemu-devel@nongnu.org; Fri, 21 Dec 2018 17:09:10 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gaSye-0000tY-0i for qemu-devel@nongnu.org; Fri, 21 Dec 2018 17:09:07 -0500 Received: from userp2130.oracle.com ([156.151.31.86]:34538) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gaR4R-00056f-Gy for qemu-devel@nongnu.org; Fri, 21 Dec 2018 15:06:57 -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 wBLK4CMF172401; Fri, 21 Dec 2018 20:04:12 GMT Received: from aserv0021.oracle.com (aserv0021.oracle.com [141.146.126.233]) by userp2130.oracle.com with ESMTP id 2pfh3ae60x-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Fri, 21 Dec 2018 20:04:12 +0000 Received: from userv0121.oracle.com (userv0121.oracle.com [156.151.31.72]) by aserv0021.oracle.com (8.14.4/8.14.4) with ESMTP id wBLK4ADb004085 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Fri, 21 Dec 2018 20:04:11 GMT Received: from abhmp0014.oracle.com (abhmp0014.oracle.com [141.146.116.20]) by userv0121.oracle.com (8.14.4/8.13.8) with ESMTP id wBLK4AZb023564; Fri, 21 Dec 2018 20:04:10 GMT Received: from ol7.uk.oracle.com (/10.175.186.114) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Fri, 21 Dec 2018 12:04:09 -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=kTb5k1sJ8zYSNI1cPIcdbIq5REK6VYmfmQpJ84AEBeY=; b=BLkDC01poXPICh24tAZOQ2rbCFIdrlFlvAA7W2sEZ+nltRIAtv0fXrWzfxse+kocy9JC 3Zh/lXhOdvk2WX2mTUeaYa2JD8peiUhDY/Va7hThAuXh09FIIOZh9DjfATHj4lyt5JRs XqO6BQsqejnlfIkbYegkLgRPpn3uOq2HS8yZ7NMSCkxNe6WdrpXeVmd96ioedyAlbFwJ dzQ1XZuJ1chHfLzTM4+ip/OfcQhtdGPa4UpCTqFXePTTh43gAtJ1lX29guQxI8fvo2X+ dKFX2UYH8LJNT9k4jtIcbTXzl0eKB6/hC+Oox2Q4edSHzNgbKl4c5yDC0a7FtSK2joSI Cw== From: Liam Merwick To: qemu-devel@nongnu.org Date: Fri, 21 Dec 2018 20:03:50 +0000 Message-Id: <1545422632-24444-3-git-send-email-liam.merwick@oracle.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1545422632-24444-1-git-send-email-liam.merwick@oracle.com> References: <1545422632-24444-1-git-send-email-liam.merwick@oracle.com> X-Proofpoint-Virus-Version: vendor=nai engine=5900 definitions=9114 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=999 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1810050000 definitions=main-1812210150 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x [generic] [fuzzy] X-Received-From: 156.151.31.86 Subject: [Qemu-devel] [RFC v2 2/4] 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. Signed-off-by: Liam Merwick --- include/hw/elf_ops.h | 50 ++++++++++++++++++++++++++++++++++++++++++++++++= ++ 1 file changed, 50 insertions(+) diff --git a/include/hw/elf_ops.h b/include/hw/elf_ops.h index 37d20a3800c1..ffbdfbe9c2d8 100644 --- a/include/hw/elf_ops.h +++ b/include/hw/elf_ops.h @@ -265,6 +265,49 @@ 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), @@ -512,6 +555,13 @@ static int glue(load_elf, SZ)(const char *name, int fd, } } =20 + /* 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); --=20 1.8.3.1 From nobody Wed Oct 1 01:33:44 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.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 208.118.235.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 [208.118.235.17]) by mx.zohomail.com with SMTPS id 1545422963260449.5850348020249; Fri, 21 Dec 2018 12:09:23 -0800 (PST) Received: from localhost ([::1]:47628 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gaR6m-0003x7-GG for importer@patchew.org; Fri, 21 Dec 2018 15:09:20 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:57264) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gaR4s-0002jG-Kv for qemu-devel@nongnu.org; Fri, 21 Dec 2018 15:07:28 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gaR4p-0006Pt-Ce for qemu-devel@nongnu.org; Fri, 21 Dec 2018 15:07:22 -0500 Received: from aserp2130.oracle.com ([141.146.126.79]:49782) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gaR4n-00057w-KL for qemu-devel@nongnu.org; Fri, 21 Dec 2018 15:07:19 -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 wBLK4Fd4129853; Fri, 21 Dec 2018 20:04:15 GMT Received: from aserv0021.oracle.com (aserv0021.oracle.com [141.146.126.233]) by aserp2130.oracle.com with ESMTP id 2pf8gfquf0-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Fri, 21 Dec 2018 20:04:15 +0000 Received: from userv0122.oracle.com (userv0122.oracle.com [156.151.31.75]) by aserv0021.oracle.com (8.14.4/8.14.4) with ESMTP id wBLK4E5f004183 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Fri, 21 Dec 2018 20:04:15 GMT Received: from abhmp0014.oracle.com (abhmp0014.oracle.com [141.146.116.20]) by userv0122.oracle.com (8.14.4/8.14.4) with ESMTP id wBLK4E8p028898; Fri, 21 Dec 2018 20:04:14 GMT Received: from ol7.uk.oracle.com (/10.175.186.114) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Fri, 21 Dec 2018 12:04:13 -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=d18htsxuSA9mC6Jx7TYy1+E3mKQwVNiMmwn69DaZ66HH59TMQ8Jv8CF99x3Jsio9Cobl D5GdvtvYi+cZS0JAz/4Knv0KBcyen40Ib31Be/QEUlmUb13Tjrb9k65f+QLWls4M6Lj9 gbA+aaSUG/z6NpliLMqVzLZEKPcCg3lVSfLGTwofiRSnmvPHpVxA+SABfd62cSgNBJ59 Y9Rgj6RzJiyHUENlPreS2qK/rWO1yg1dM4YjoiI09OUiteji4kWezO5lnSMrfOuF7kBn bGg80wzv/i9V/hxDc0yGzNY/49mxzjcizwwPEGk0jML2capYAPaW3AGQ7eIsPpiIJ+2G GQ== From: Liam Merwick To: qemu-devel@nongnu.org Date: Fri, 21 Dec 2018 20:03:51 +0000 Message-Id: <1545422632-24444-4-git-send-email-liam.merwick@oracle.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1545422632-24444-1-git-send-email-liam.merwick@oracle.com> References: <1545422632-24444-1-git-send-email-liam.merwick@oracle.com> X-Proofpoint-Virus-Version: vendor=nai engine=5900 definitions=9114 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=828 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1810050000 definitions=main-1812210150 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x [generic] [fuzzy] X-Received-From: 141.146.126.79 Subject: [Qemu-devel] [RFC v2 3/4] 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 Wed Oct 1 01:33:44 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.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 208.118.235.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 [208.118.235.17]) by mx.zohomail.com with SMTPS id 1545424677055348.63070563203553; Fri, 21 Dec 2018 12:37:57 -0800 (PST) Received: from localhost ([::1]:47797 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gaRYR-0007zd-JQ for importer@patchew.org; Fri, 21 Dec 2018 15:37:55 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:44577) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gaRXb-0007gO-7c for qemu-devel@nongnu.org; Fri, 21 Dec 2018 15:37:04 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gaRXV-0006sj-GU for qemu-devel@nongnu.org; Fri, 21 Dec 2018 15:37:03 -0500 Received: from userp2130.oracle.com ([156.151.31.86]:34648) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gaR4I-00058Y-Hl for qemu-devel@nongnu.org; Fri, 21 Dec 2018 15:06:47 -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 wBLK4Ihe172444; Fri, 21 Dec 2018 20:04:18 GMT Received: from userv0021.oracle.com (userv0021.oracle.com [156.151.31.71]) by userp2130.oracle.com with ESMTP id 2pfh3ae61f-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Fri, 21 Dec 2018 20:04:18 +0000 Received: from userv0122.oracle.com (userv0122.oracle.com [156.151.31.75]) by userv0021.oracle.com (8.14.4/8.14.4) with ESMTP id wBLK4HIH024269 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Fri, 21 Dec 2018 20:04:17 GMT Received: from abhmp0014.oracle.com (abhmp0014.oracle.com [141.146.116.20]) by userv0122.oracle.com (8.14.4/8.14.4) with ESMTP id wBLK4HfR028906; Fri, 21 Dec 2018 20:04:17 GMT Received: from ol7.uk.oracle.com (/10.175.186.114) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Fri, 21 Dec 2018 12:04:16 -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=KeHZ8qgeQSeKxRv7Zemzhe28NlE1ELU0Kr56sTschik=; b=MUDgiLhNtGrMc4YtWM3weKDI11bJ31QGeDV2DGHRtJrOihGZDeOqI/gNOf3fjJQUooJj zP4ELirUiR5KxqYYXIqeCcR2d1mV605j2vZxuFUTVFE0AmLjVDR+uIQasppxIKc1xrgr 55I4twFsdHMizVbJ5m4fSmx4Fh0yMs7oU8mlpJO1EzI3wGW4nd6ec5nTIryNU/2G2zrM 07pVKrKqWrkTjVfHnlye0I368W5yRcvrCc+8EJMajR+/nc6SfcgzWQIyE7YvNKTVNsMk ySDWO54La/oEIhuGx+5oubtbOoDlwe5Lq6tjsDIWuDZnjORnzPebA3fTFBeiOwejfFM6 +Q== From: Liam Merwick To: qemu-devel@nongnu.org Date: Fri, 21 Dec 2018 20:03:52 +0000 Message-Id: <1545422632-24444-5-git-send-email-liam.merwick@oracle.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1545422632-24444-1-git-send-email-liam.merwick@oracle.com> References: <1545422632-24444-1-git-send-email-liam.merwick@oracle.com> X-Proofpoint-Virus-Version: vendor=nai engine=5900 definitions=9114 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=626 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1810050000 definitions=main-1812210150 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x [generic] [fuzzy] X-Received-From: 156.151.31.86 Subject: [Qemu-devel] [RFC v2 4/4] 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 | 136 ++++++++++++++++++++++++++++++++++++++++++++++++++++++= +++- include/elf.h | 10 +++++ 2 files changed, 145 insertions(+), 1 deletion(-) diff --git a/hw/i386/pc.c b/hw/i386/pc.c index 115bc2825ce4..6d44a14da44d 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" @@ -109,6 +110,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; + void gsi_handler(void *opaque, int n, int level) { GSIState *s =3D opaque; @@ -834,6 +838,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) { @@ -873,6 +980,33 @@ static void load_linux(PCMachineState *pcms, if (ldl_p(header+0x202) =3D=3D 0x53726448) { protocol =3D lduw_p(header+0x206); } else { + /* + * If the kernel address for using the x86/HVM direct boot ABI has + * been saved then proceed with booting the uncompressed kernel + */ + 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, @@ -1336,7 +1470,7 @@ void pc_memory_init(PCMachineState *pcms, int linux_boot, i; MemoryRegion *ram, *option_rom_mr; MemoryRegion *ram_below_4g, *ram_above_4g; - FWCfgState *fw_cfg; + FWCfgState *fw_cfg =3D NULL; MachineState *machine =3D MACHINE(pcms); PCMachineClass *pcmc =3D PC_MACHINE_GET_CLASS(pcms); =20 diff --git a/include/elf.h b/include/elf.h index c151164b63da..1f82c7a7124b 100644 --- a/include/elf.h +++ b/include/elf.h @@ -1585,6 +1585,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