mbox series

[v3,0/4] QEMU changes to do PVH boot

Message ID 1547554687-12687-1-git-send-email-liam.merwick@oracle.com (mailing list archive)
Headers show
Series QEMU changes to do PVH boot | expand

Message

Liam Merwick Jan. 15, 2019, 12:18 p.m. UTC
For certain applications it is desirable to rapidly boot a KVM virtual
machine. In cases where legacy hardware and software support within the
guest is not needed, QEMU should be able to boot directly into the
uncompressed Linux kernel binary with minimal firmware involvement.

There already exists an ABI to allow this for Xen PVH guests and the ABI
is supported by Linux and FreeBSD:

   https://xenbits.xen.org/docs/unstable/misc/pvh.html

Details on the Linux changes (in 4.21): https://lkml.org/lkml/2018/12/14/1330
qboot pull request integrated: https://github.com/bonzini/qboot/pull/17 

This patch series provides QEMU support to read the ELF header of an
uncompressed kernel binary and get the 32-bit PVH kernel entry point
from an ELF Note.  In load_linux() a call is made to load_elfboot()
so see if the header matches that of an uncompressed kernel binary (ELF)
and if so, loads the binary and determines the kernel entry address
from an ELF Note in the binary.  Then qboot does futher initialisation
of the guest (e820, etc.) and jumps to the kernel entry address and
boots the guest.

changes v1 -> v2
- Based on feedback from Stefan Hajnoczi
- The reading of the PVH entry point is now done in a single pass during
  elf_load() which results in Patch2 in v1 being split into Patches 1&2 in v2
  and considerably reworked.
- Patch1 adds a new optional function pointer to parse the ELF note type
  (the type is passed in via the existing translate_opaque arg - the
  function already had 11 args so I didn't want to add more than one new arg).
- Patch2 adds a function to elf_ops.h to find an ELF note
  matching a specific type 
- Patch3 just has a line added to the commit message to state that the Xen
  repo is the canonical location
- Patch4 (that does the PVH boot) is mainly equivalent to Patch3 in v1
  just minor load_elfboot() changes and the addition of a
  read_pvh_start_addr() helper function for load_elf()

changes v2 -> v3
- Based on feedback from Stefan Hajnoczi
- Fix formatting issues where a few tabs snuck in v2
- Moved code to use ELF Note in load_elf() from Patch1 to Patch2
- In load_elf() set data to NULL after g_free() [now in Patch2 following move]
- Added Patch5 containing changes by Stefano Garzarella to support -initrd

Usіng the method/scripts documented by the NEMU team at

   https://github.com/intel/nemu/wiki/Measuring-Boot-Latency
   https://lists.gnu.org/archive/html/qemu-devel/2018-12/msg00200.html

below are some timings measured (vmlinux and bzImage from the same build)
Time to get to kernel start is almost halved (95ṁs -> 48ms)

QEMU + qboot + vmlinux (PVH + 4.20-rc4)
 qemu_init_end: 41.550521
 fw_start: 41.667139 (+0.116618)
 fw_do_boot: 47.448495 (+5.781356)
 linux_startup_64: 47.720785 (+0.27229)
 linux_start_kernel: 48.399541 (+0.678756)
 linux_start_user: 296.952056 (+248.552515)

QEMU + qboot + bzImage:
 qemu_init_end: 29.209276
 fw_start: 29.317342 (+0.108066)
 linux_start_boot: 36.679362 (+7.36202)
 linux_startup_64: 94.531349 (+57.851987)
 linux_start_kernel: 94.900913 (+0.369564)
 linux_start_user: 401.060971 (+306.160058)

QEMU + bzImage:
 qemu_init_end: 30.424430
 linux_startup_64: 893.770334 (+863.345904)
 linux_start_kernel: 894.17049 (+0.400156)
 linux_start_user: 1208.679768 (+314.509278)


Liam Merwick (4):
  elf: Add optional function ptr to load_elf() to parse ELF notes
  elf-ops.h: Add get_elf_note_type()
  pvh: Add x86/HVM direct boot ABI header file
  pvh: Boot uncompressed kernel using direct boot ABI

 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/i386/pc.c                   | 135 +++++++++++++++++++++++++++++++++++++
 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/elf.h                  |  10 +++
 include/hw/elf_ops.h           |  77 ++++++++++++++++++++++
 include/hw/loader.h            |   9 ++-
 include/hw/xen/start_info.h    | 146 +++++++++++++++++++++++++++++++++++++++++
 44 files changed, 479 insertions(+), 70 deletions(-)
 create mode 100644 include/hw/xen/start_info.h

Comments

Paolo Bonzini Jan. 15, 2019, 11:09 p.m. UTC | #1
On 15/01/19 13:18, Liam Merwick wrote:
> For certain applications it is desirable to rapidly boot a KVM virtual
> machine. In cases where legacy hardware and software support within the
> guest is not needed, QEMU should be able to boot directly into the
> uncompressed Linux kernel binary with minimal firmware involvement.
> 
> There already exists an ABI to allow this for Xen PVH guests and the ABI
> is supported by Linux and FreeBSD:
> 
>    https://xenbits.xen.org/docs/unstable/misc/pvh.html
> 
> Details on the Linux changes (in 4.21): https://lkml.org/lkml/2018/12/14/1330
> qboot pull request integrated: https://github.com/bonzini/qboot/pull/17 
> 
> This patch series provides QEMU support to read the ELF header of an
> uncompressed kernel binary and get the 32-bit PVH kernel entry point
> from an ELF Note.  In load_linux() a call is made to load_elfboot()
> so see if the header matches that of an uncompressed kernel binary (ELF)
> and if so, loads the binary and determines the kernel entry address
> from an ELF Note in the binary.  Then qboot does futher initialisation
> of the guest (e820, etc.) and jumps to the kernel entry address and
> boots the guest.

Queued, thanks!

Paolo

> changes v1 -> v2
> - Based on feedback from Stefan Hajnoczi
> - The reading of the PVH entry point is now done in a single pass during
>   elf_load() which results in Patch2 in v1 being split into Patches 1&2 in v2
>   and considerably reworked.
> - Patch1 adds a new optional function pointer to parse the ELF note type
>   (the type is passed in via the existing translate_opaque arg - the
>   function already had 11 args so I didn't want to add more than one new arg).
> - Patch2 adds a function to elf_ops.h to find an ELF note
>   matching a specific type 
> - Patch3 just has a line added to the commit message to state that the Xen
>   repo is the canonical location
> - Patch4 (that does the PVH boot) is mainly equivalent to Patch3 in v1
>   just minor load_elfboot() changes and the addition of a
>   read_pvh_start_addr() helper function for load_elf()
> 
> changes v2 -> v3
> - Based on feedback from Stefan Hajnoczi
> - Fix formatting issues where a few tabs snuck in v2
> - Moved code to use ELF Note in load_elf() from Patch1 to Patch2
> - In load_elf() set data to NULL after g_free() [now in Patch2 following move]
> - Added Patch5 containing changes by Stefano Garzarella to support -initrd
> 
> Usіng the method/scripts documented by the NEMU team at
> 
>    https://github.com/intel/nemu/wiki/Measuring-Boot-Latency
>    https://lists.gnu.org/archive/html/qemu-devel/2018-12/msg00200.html
> 
> below are some timings measured (vmlinux and bzImage from the same build)
> Time to get to kernel start is almost halved (95ṁs -> 48ms)
> 
> QEMU + qboot + vmlinux (PVH + 4.20-rc4)
>  qemu_init_end: 41.550521
>  fw_start: 41.667139 (+0.116618)
>  fw_do_boot: 47.448495 (+5.781356)
>  linux_startup_64: 47.720785 (+0.27229)
>  linux_start_kernel: 48.399541 (+0.678756)
>  linux_start_user: 296.952056 (+248.552515)
> 
> QEMU + qboot + bzImage:
>  qemu_init_end: 29.209276
>  fw_start: 29.317342 (+0.108066)
>  linux_start_boot: 36.679362 (+7.36202)
>  linux_startup_64: 94.531349 (+57.851987)
>  linux_start_kernel: 94.900913 (+0.369564)
>  linux_start_user: 401.060971 (+306.160058)
> 
> QEMU + bzImage:
>  qemu_init_end: 30.424430
>  linux_startup_64: 893.770334 (+863.345904)
>  linux_start_kernel: 894.17049 (+0.400156)
>  linux_start_user: 1208.679768 (+314.509278)
> 
> 
> Liam Merwick (4):
>   elf: Add optional function ptr to load_elf() to parse ELF notes
>   elf-ops.h: Add get_elf_note_type()
>   pvh: Add x86/HVM direct boot ABI header file
>   pvh: Boot uncompressed kernel using direct boot ABI
> 
>  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/i386/pc.c                   | 135 +++++++++++++++++++++++++++++++++++++
>  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/elf.h                  |  10 +++
>  include/hw/elf_ops.h           |  77 ++++++++++++++++++++++
>  include/hw/loader.h            |   9 ++-
>  include/hw/xen/start_info.h    | 146 +++++++++++++++++++++++++++++++++++++++++
>  44 files changed, 479 insertions(+), 70 deletions(-)
>  create mode 100644 include/hw/xen/start_info.h
>
no-reply@patchew.org Jan. 21, 2019, 2:31 a.m. UTC | #2
Patchew URL: https://patchew.org/QEMU/1547554687-12687-1-git-send-email-liam.merwick@oracle.com/



Hi,

This series failed the docker-mingw@fedora build test. Please find the testing commands and
their output below. If you have Docker installed, you can probably reproduce it
locally.

=== TEST SCRIPT BEGIN ===
#!/bin/bash
time make docker-test-mingw@fedora SHOW_ENV=1 J=14
=== TEST SCRIPT END ===

  CC      dma-helpers.o
  CC      vl.o
/tmp/qemu-test/src/block/sheepdog.c: In function 'find_vdi_name':
/tmp/qemu-test/src/block/sheepdog.c:1239:5: error: 'strncpy' specified bound 256 equals destination size [-Werror=stringop-truncation]
     strncpy(buf + SD_MAX_VDI_LEN, tag, SD_MAX_VDI_TAG_LEN);
     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
cc1: all warnings being treated as errors


The full log is available at
http://patchew.org/logs/1547554687-12687-1-git-send-email-liam.merwick@oracle.com/testing.docker-mingw@fedora/?type=message.
---
Email generated automatically by Patchew [http://patchew.org/].
Please send your feedback to patchew-devel@redhat.com
Liam Merwick Jan. 21, 2019, 8:19 a.m. UTC | #3
On 21/01/2019 02:31, no-reply@patchew.org wrote:
> Patchew URL: https://patchew.org/QEMU/1547554687-12687-1-git-send-email-liam.merwick@oracle.com/
...>
>    CC      dma-helpers.o
>    CC      vl.o
> /tmp/qemu-test/src/block/sheepdog.c: In function 'find_vdi_name':
> /tmp/qemu-test/src/block/sheepdog.c:1239:5: error: 'strncpy' specified bound 256 equals destination size [-Werror=stringop-truncation]
>       strncpy(buf + SD_MAX_VDI_LEN, tag, SD_MAX_VDI_TAG_LEN);
>       ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> cc1: all warnings being treated as errors
> 


Given the PVH patch series was posted 5 days ago and the following 
change was committed 3 days ago, I'm assuming this is not related to the 
PVH changes (which do not touch this file).

commit 97b583f46c435aaa40942ca73739d79190776b7f
Author: Philippe Mathieu-Daudé <philmd@redhat.com>
Date:   Thu Jan 3 09:56:35 2019 +0100

     block/sheepdog: Use QEMU_NONSTRING for non NUL-terminated arrays

Regards,
Liam


> 
> The full log is available at
> http://patchew.org/logs/1547554687-12687-1-git-send-email-liam.merwick@oracle.com/testing.docker-mingw@fedora/?type=message.
> ---
> Email generated automatically by Patchew [http://patchew.org/].
> Please send your feedback to patchew-devel@redhat.com
>
Stefan Hajnoczi Jan. 21, 2019, 10:54 a.m. UTC | #4
On Mon, Jan 21, 2019 at 08:19:03AM +0000, Liam Merwick wrote:
> On 21/01/2019 02:31, no-reply@patchew.org wrote:
> > Patchew URL: https://patchew.org/QEMU/1547554687-12687-1-git-send-email-liam.merwick@oracle.com/
> ...>
> >    CC      dma-helpers.o
> >    CC      vl.o
> > /tmp/qemu-test/src/block/sheepdog.c: In function 'find_vdi_name':
> > /tmp/qemu-test/src/block/sheepdog.c:1239:5: error: 'strncpy' specified bound 256 equals destination size [-Werror=stringop-truncation]
> >       strncpy(buf + SD_MAX_VDI_LEN, tag, SD_MAX_VDI_TAG_LEN);
> >       ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> > cc1: all warnings being treated as errors
> > 
> 
> 
> Given the PVH patch series was posted 5 days ago and the following change
> was committed 3 days ago, I'm assuming this is not related to the PVH
> changes (which do not touch this file).
> 
> commit 97b583f46c435aaa40942ca73739d79190776b7f
> Author: Philippe Mathieu-Daudé <philmd@redhat.com>
> Date:   Thu Jan 3 09:56:35 2019 +0100
> 
>     block/sheepdog: Use QEMU_NONSTRING for non NUL-terminated arrays

Yes, don't worry, it's a false positive.

Stefan