qemu-discuss
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-discuss] Impact of incorrectly-mapped OVMF


From: Prerna
Subject: Re: [Qemu-discuss] Impact of incorrectly-mapped OVMF
Date: Fri, 20 Apr 2018 19:58:43 +0530

On Fri, Apr 20, 2018 at 2:24 PM, Laszlo Ersek <address@hidden> wrote:

> On 04/19/18 18:35, Prerna wrote:
> > On Thu, Apr 19, 2018 at 7:59 AM, Prerna <address@hidden> wrote:
> >
> >> Hi all,
> >> In playing around with OVMF a few times I accidentally specified my
> >> qemu-kvm binary with this erroneous command line: "qemu-kvm ... -bios
> >> /usr/share/OVMF/OVMF_CODE.fd" instead of passing this as if=pflash.
> >>
> >> I was expecting this to error out in qemu, but surprisingly qemu(2.6)
> let
> >> the VM boot into EDK2 shell, and even past that into the VM's cdrom that
> >> ran an installer.  Ofcourse the VM would sporadically see odd
> hangs/crashes
> >> but that would always happen at a different time instant (sometimes not
> >> happening for even days).
> >>
> >> My question is, what happens from a firmware initialisation perspective
> if
> >> edk2 is passed as a bios rom instead of as pflash? Also, given that all
> >> these are effectively blobs that load into memory, is there some sort of
> >> pre-check that can be done by QEMU to avoid loading OVMF binary as a
> bios
> >> ROM ?
> >>
> >> (Note that this is purely out of curiosity, I understand it is risky to
> >> run this in production )
> >> (with mismatched -bios/pflash tag)
> >>
> >
> > Laszlo, if you could provide any pointers for me to understand this
> better ?
>
> Sure.
>
> The OvmfPkg/README file has a section called "OVMF Flash Layout". It
> explains where / how the unified (OVMF.fd) image is mapped just under
> 4GB in guest-phys address space.
>
> (1) If you map the unified image with -bios, all of that becomes ROM --
> read-only memory.
>
> (2) If you map the unified image with -pflash, all of that becomes
> read-write MMIO.
>
> (3) If you use the split images (OVMF_CODE.fd and a copy of
> OVMF_VARS.fd), and map then as flash chips, then the top part
> (OVMF_CODE.fd, consisting of SECFV and FVMAIN_COMPACT) becomes read-only
> flash (MMIO), and the bottom part (copy of OVMF_VARS.fd, consisting of
> FTW Spare, FTW Work, Event log, and NV store) becomes read-write flash
> (MMIO).
>
> (4) If you use -bios with OVMF_CODE.fd only, then the top part will be
> ROM, and the bottom part will be "black hole" MMIO.
>
> Option (4) is totally invalid.
>
> Option (3) is the best solution and it is what everybody should use (the
> virt stack / libvirt already uses that).
>
> Option (2) is acceptable, but it's suboptimal from a firmware binary
> update POV -- you cannot replace your binary without losing your variables.
>
> Option (1) is the ancient relic that once (before qemu-1.6) used to be
> the only option. When you use Xen, this is the only option still today.
>
> OVMF contains detection code that tells apart case (1) from the set {
> case (2), case (3) }. (Cases (2) and (3) in the latter set look
> indistinguishable to the firmware, by design.) If pflash is detected,
> then you get a UEFI variable service implementation that conforms to the
> UEFI spec, and everything will work fine. If, however, case (1) is
> detected, then OVMF switches to a kind of variable store "emulation",
> where:
> - variables (even non-volatile variables) primarily live in RAM only,
> - a file called \NvVars on the EFI System Partition (a FAT filesystem)
>   contains a serialized image of the variables,
> - when booting the VM, \NvVars is de-serialized into RAM,
> - until the OS is launched, variable changes (initiated from the
>   firmware), are synched out to \NvVars at once,
> - after the OS is launched, variable changes remain only in memory,
> - if you gracefully reboot the VM into the firmware, then OS-initiated
>   variable changes are synched out to \NvVars,
> - if you power down the VM from within the OS, you'll lose any
>   OS-initiated variable changes
> - Another limitation is that some kinds of variables cannot be
>   serialized and de-serialized like this; in particular variables
>   related to Secure Boot.
>
> Unfortunately this detection logic is extremely prone to mis-use (and
> esp. it was never meant to deal with case (4)) and to causing confusion.
> For this reason, I have had patches for a long time now that allow the
> user to compile "-bios" support out of OVMF, with a build flag
> (-DMEM_VARSTORE_EMU_ENABLE=FALSE). Then you will simply become unable to
> boot with "-bios" -- the firmware will just hang with a black screen.
> (If you capture the debug log (see OvmfPkg/README), you'll know what's
> up though.) Note that this would not be the default -- the default build
> wouldn't change.
>
>
Thanks for the detailed explanation. I now understand better why the use of
-bios is such a bad idea.


> Firmware built like this is much better to use on QEMU (much less room
> for error, and there are some firmware features that become possible --
> the UEFI memmap will be de-fragmented over time, and the foundation for
> S4 support, i.e., suspend to disk, is laid).
>

I agree.


>
> In particular if you build OVMF with -DSMM_REQUIRE, then "-bios" support
> is *already* compiled out. (If you use OVMF on Xen, then your only
> choice is option (1) (because Xen does not implement flash), so OVMF
> binaries built with either -DSMM_REQUIRE, or my (proposed)
> -DMEM_VARSTORE_EMU_ENABLE=FALSE flag, will not run on Xen.)
>
>
Unfortunately not using -DSMM_REQUIRE, since that works only with supported
Q35 machine type in QEMU.


> My work related to -DMEM_VARSTORE_EMU_ENABLE=FALSE can be seen in
> <https://bugzilla.tianocore.org/show_bug.cgi?id=386>.
>
> You might be curious why these patches aren't upstream (despite me
> having run them on my end for more than a year now). Well, both times I
> posted them, they were blocked for non-technical reasons that make zero
> sense to me. They boil down to, "we shouldn't enable the user to build
> an OVMF binary that cannot run on Xen; instead we should implement a
> fake PEI-phase r/o variable service for Xen too, *even though* that
> service could *never* report valid variable contents". Thus, I'm not
> allowed to improve the situation on QEMU, even conditionally, without
> working a bunch more on a shim for Xen that *would not work* anyway,
> functionally speaking.
>
> So there you have it. Just be sure to use flash, or -- even better --
> use libvirt to start QEMU for you. That's what I do anyway (beyond using
> my patches for TianoCore BZ#386, obviously).
>
>
I had been using libvirt, but unfortunately libvirt also does not block
this. It really would not have the intelligence to identify whether the
OVMF binary should or not be misused as ROM.


> We could perhaps ask Gerd to incorporate my patches, for TianoCore
> BZ#386, into a new firmware image at kraxel.org/repos; then users
> interested in this feature -- deterministic failure to boot with -bios,
> and a defragmented UEFI memmap -- could switch to that new image.
>
>
Yes, that would be convenient. I am still going over your patches to
understand more about defrag UEFI memmap. Thanks for all the pointers and
the detailed explanation once again :)

Regards,
Prerna


> Thanks
> Laszlo
>


reply via email to

[Prev in Thread] Current Thread [Next in Thread]