Bug 1733940 - RFE: Report firmware (FW) paths in domainCapabilities based on FW descriptor files
Summary: RFE: Report firmware (FW) paths in domainCapabilities based on FW descriptor ...
Keywords:
Status: CLOSED NEXTRELEASE
Alias: None
Product: Fedora
Classification: Fedora
Component: libvirt
Version: rawhide
Hardware: Unspecified
OS: Unspecified
unspecified
unspecified
Target Milestone: ---
Assignee: Michal Privoznik
QA Contact: Fedora Extras Quality Assurance
URL:
Whiteboard:
Depends On:
Blocks:
TreeView+ depends on / blocked
 
Reported: 2019-07-29 09:37 UTC by Kashyap Chamarthy
Modified: 2019-10-01 07:27 UTC (History)
12 users (show)

Fixed In Version: libvirt-5.8.0
Doc Type: If docs needed, set a value
Doc Text:
Clone Of:
Environment:
Last Closed: 2019-10-01 07:27:04 UTC
Type: Bug
Embargoed:


Attachments (Terms of Use)
Full `virsh domcapabilities` output from F31 (Rawhide, as of this writing) (5.10 KB, text/plain)
2019-07-29 09:41 UTC, Kashyap Chamarthy
no flags Details
domainCapabilities with 'q35' (5.21 KB, text/plain)
2019-07-29 14:07 UTC, Kashyap Chamarthy
no flags Details
Full QEMU command-line of the VM booted with Secure Boot (3.11 KB, text/plain)
2019-07-30 08:43 UTC, Kashyap Chamarthy
no flags Details

Description Kashyap Chamarthy 2019-07-29 09:37:46 UTC
On a system with Secure Boot (SB) and non-SB variant OVMF binaries, the
getDomainCapabilities() API reports just the non-SB binary as part of
the 'loader' element value.

E.g. with the below versions on Fedora 31 (Rawdide, at the time of this
writing):

    libvirt-daemon-driver-qemu-5.5.0-1.fc31.x86_64
    qemu-system-x86-core-4.1.0-0.1.rc2.fc31.x86_64
    edk2-ovmf-20190501stable-2.fc31.noarch

Check the output of 'os' element from `virsh domcapabilities`:

    ...
    <os supported='yes'>
      <enum name='firmware'>
        <value>efi</value>
      </enum>
      <loader supported='yes'>
        <value>/usr/share/edk2/ovmf/OVMF_CODE.fd</value>
        <enum name='type'>
          <value>rom</value>
          <value>pflash</value>
        </enum>
        <enum name='readonly'>
          <value>yes</value>
          <value>no</value>
        </enum>
        <enum name='secure'>
          <value>no</value>
        </enum>
      </loader>
    </os>
    ...

However, the 'edk2-ovmf' has both OVMF_CODE.fd _and_
OVMF_CODE.secboot.fd binaries.

    $> rpm -ql edk2-ovmf | grep fd
    /usr/share/OVMF
    /usr/share/OVMF/OVMF_CODE.fd
    /usr/share/OVMF/OVMF_CODE.secboot.fd
    /usr/share/OVMF/OVMF_VARS.fd
    /usr/share/OVMF/OVMF_VARS.secboot.fd
    /usr/share/OVMF/UefiShell.iso
    /usr/share/doc/edk2-ovmf
    /usr/share/doc/edk2-ovmf/README
    /usr/share/doc/edk2-ovmf/ovmf-whitepaper-c770f8c.txt
    /usr/share/edk2
    /usr/share/edk2/ovmf
    /usr/share/edk2/ovmf/EnrollDefaultKeys.efi
    /usr/share/edk2/ovmf/OVMF_CODE.fd
    /usr/share/edk2/ovmf/OVMF_CODE.secboot.fd
    /usr/share/edk2/ovmf/OVMF_VARS.fd
    /usr/share/edk2/ovmf/OVMF_VARS.secboot.fd
    /usr/share/edk2/ovmf/Shell.efi
    /usr/share/edk2/ovmf/UefiShell.iso
    /usr/share/licenses/edk2-ovmf
    /usr/share/licenses/edk2-ovmf/LICENSE.openssl
    /usr/share/licenses/edk2-ovmf/License.txt
    /usr/share/qemu/firmware
    /usr/share/qemu/firmware/40-edk2-ovmf-x64-sb-enrolled.json
    /usr/share/qemu/firmware/50-edk2-ovmf-x64-sb.json
    /usr/share/qemu/firmware/60-edk2-ovmf-x64.json

Given the above, I was expecting the 'loader' value to report *both* 
OVMF binaries, e.g.  something like:

    ...
    <loader supported='yes'>
      <value>/usr/share/edk2/ovmf/OVMF_CODE.fd</value>
      <value>/usr/share/edk2/ovmf/OVMF_CODE.secboot.fd</value>
    ...

NB: I'm reporting this for 'rawhide', but you see the same behaviour on
Fedora 29 and 30, too.

Comment 1 Kashyap Chamarthy 2019-07-29 09:41:35 UTC
Created attachment 1594231 [details]
Full `virsh domcapabilities` output from F31 (Rawhide, as of this writing)

Comment 2 Michal Privoznik 2019-07-29 10:54:07 UTC
There are two things that are at play. Firstly, the default machine type is 'pc' which doesn't support secure boot. So you want to be passing 'virsh domcapabilities --machine q35'. This is because with newer libvirt (which understands FW descriptor files), libvirt won't report secboot FW images if secboot is not supported. With older libvirt, the other issue is at play - it has a compile time list of FW paths (which can be overriden via qemu.conf) which are then checked at runtime if they exist. On rawhide this is the list that is given to libvirt at compile time:

/usr/share/edk2.git/ovmf-x64/OVMF_CODE-pure-efi.fd
/usr/share/edk2.git/ovmf-x64/OVMF_VARS-pure-efi.fd
/usr/share/edk2.git/ovmf-ia32/OVMF_CODE-pure-efi.fd
/usr/share/edk2.git/ovmf-ia32/OVMF_VARS-pure-efi.fd
/usr/share/edk2.git/aarch64/QEMU_EFI-pflash.raw
/usr/share/edk2.git/aarch64/vars-template-pflash.raw
/usr/share/edk2.git/arm/QEMU_EFI-pflash.raw
/usr/share/edk2.git/arm/vars-template-pflash.raw
/usr/share/edk2/ovmf/OVMF_CODE.fd
/usr/share/edk2/ovmf/OVMF_VARS.fd
/usr/share/edk2/ovmf-ia32/OVMF_CODE.fd
/usr/share/edk2/ovmf-ia32/OVMF_VARS.fd
/usr/share/edk2/aarch64/QEMU_EFI-pflash.raw
/usr/share/edk2/aarch64/vars-template-pflash.raw
/usr/share/edk2/arm/QEMU_EFI-pflash.raw
/usr/share/edk2/arm/vars-template-pflash.raw


Therefore, I don't think this is a bug after all.

Comment 3 Kashyap Chamarthy 2019-07-29 14:07:57 UTC
Created attachment 1594299 [details]
domainCapabilities with 'q35'

Comment 4 Kashyap Chamarthy 2019-07-29 14:11:44 UTC
(In reply to Michal Privoznik from comment #2)
> There are two things that are at play. Firstly, the default machine type is
> 'pc' which doesn't support secure boot. So you want to be passing 'virsh
> domcapabilities --machine q35'. 

Ah, yes, I'm aware of it.  Just forgot that when I ran this invocation.  
Attached the domainCapabilities with `q35`, obtained via:

    $> virsh domcapabilities \
        --virttype kvm \
        --emulatorbin /usr/bin/qemu-system-x86_64 \
        --arch x86_64 \
        --machine q35

> This is because with newer libvirt (which
> understands FW descriptor files), libvirt won't report secboot FW images if
> secboot is not supported.

So, even with '--machine q35', domainCapabilities does not show 
'secboot' image, refer the attachment (domainCapabilities with 'q35')

I should note that I'm running this _inside_ a "level-1" VM (that is 
KVM-capable) that itself is booted with Secure Boot:

    $> virt-what
    -bash: virt-what: command not found
    [root@rawhide-1 ~]# systemd-detect-virt

    $> dmesg | grep -i secure
    [    0.000000] secureboot: Secure boot enabled
    [    0.000000] Kernel is locked down from EFI secure boot; see man kernel_lockdown.7


> With older libvirt, the other issue is at play -
> it has a compile time list of FW paths (which can be overriden via
> qemu.conf) which are then checked at runtime if they exist. On rawhide this
> is the list that is given to libvirt at compile time:
> 
> /usr/share/edk2.git/ovmf-x64/OVMF_CODE-pure-efi.fd
> /usr/share/edk2.git/ovmf-x64/OVMF_VARS-pure-efi.fd
> /usr/share/edk2.git/ovmf-ia32/OVMF_CODE-pure-efi.fd
> /usr/share/edk2.git/ovmf-ia32/OVMF_VARS-pure-efi.fd
> /usr/share/edk2.git/aarch64/QEMU_EFI-pflash.raw
> /usr/share/edk2.git/aarch64/vars-template-pflash.raw
> /usr/share/edk2.git/arm/QEMU_EFI-pflash.raw
> /usr/share/edk2.git/arm/vars-template-pflash.raw
> /usr/share/edk2/ovmf/OVMF_CODE.fd
> /usr/share/edk2/ovmf/OVMF_VARS.fd
> /usr/share/edk2/ovmf-ia32/OVMF_CODE.fd
> /usr/share/edk2/ovmf-ia32/OVMF_VARS.fd
> /usr/share/edk2/aarch64/QEMU_EFI-pflash.raw
> /usr/share/edk2/aarch64/vars-template-pflash.raw
> /usr/share/edk2/arm/QEMU_EFI-pflash.raw
> /usr/share/edk2/arm/vars-template-pflash.raw
  
I see, pointed note.  (But just to note explicitly, the "older" libvirt 
issue is not at play here -- since I'm using a libvirt version that
understands FW descriptor files:
libvirt-daemon-driver-qemu-5.5.0-1.fc31.x86_64)

> Therefore, I don't think this is a bug after all.

Even the part with new enough libvirt (libvirt 5.5) + domainCapabilities 
with 'q35' not returning the 'secboot' binary?

Comment 5 Laszlo Ersek 2019-07-29 16:14:38 UTC
Hi Kashyap,

(In reply to Kashyap Chamarthy from comment #4)

> I should note that I'm running this _inside_ a "level-1" VM (that is
> KVM-capable) that itself is booted with Secure Boot:
>
>     $> virt-what
>     -bash: virt-what: command not found
>     [root@rawhide-1 ~]# systemd-detect-virt
>
>     $> dmesg | grep -i secure
>     [    0.000000] secureboot: Secure boot enabled
>     [    0.000000] Kernel is locked down from EFI secure boot; see man
>                    kernel_lockdown.7

is this indeed the command output you meant to capture in the BZ?

Because, the shell failed to locate the "virt-what" utility, and
"systemd-detect-virt" printed nothing. So I'm not sure if those checks
support your statement that the L1 VM was itself KVM-capable. (For that,
primarily the "vmx" capability should be exposed in L1, if we're talking
Intel CPUs.)

... I'm not implying that "vmx" should matter a whole lot here; libvirt
manages emulated (as opposed to virtualized) domains just fine:

  <domain type='qemu'>
    ...
  </domain>

and I'd expect that to be transparent to the firmware selection logic.
So I think your question & setup are valid, it's just that parts of your
comment 4 appear inconsistent.

Comment 6 Michal Privoznik 2019-07-29 16:41:20 UTC
Thing is, even with FW descriptor files, libvirt use them only to report "secure" attribute. But I guess we can take advantage of this bug and make libvirt report paths based on FW descriptor files too.

Comment 7 Kashyap Chamarthy 2019-07-30 08:40:31 UTC
(In reply to Laszlo Ersek from comment #5)
> Hi Kashyap,
> 
> (In reply to Kashyap Chamarthy from comment #4)
> 
> > I should note that I'm running this _inside_ a "level-1" VM (that is
> > KVM-capable) that itself is booted with Secure Boot:
> >
> >     $> virt-what
> >     -bash: virt-what: command not found
> >     [root@rawhide-1 ~]# systemd-detect-virt

Err, that was supposed to be:

        [root@rawhide-1 ~]# systemd-detect-virt 
        kvm

(Which indicates that we are indeed running in a VM.)

> >
> >     $> dmesg | grep -i secure
> >     [    0.000000] secureboot: Secure boot enabled
> >     [    0.000000] Kernel is locked down from EFI secure boot; see man
> >                    kernel_lockdown.7
> 
> is this indeed the command output you meant to capture in the BZ?
> 
> Because, the shell failed to locate the "virt-what" utility, and
> "systemd-detect-virt" printed nothing. 

Good catch on `virt-what`, Laszlo.  It was my sloppiness in copy/pasting. 
As you saw, I didn't have `virt-what` installed, so I proceeded to use
`systemd-detect-virt`, and missed to paste its output, 'kvm', which 
was the key bit I wanted to convey :-)

> So I'm not sure if those checks
> support your statement that the L1 VM was itself KVM-capable. (For that,
> primarily the "vmx" capability should be exposed in L1, if we're talking
> Intel CPUs.)

Indeed, this is an Intel CPU, and here is the evidence from the guest 
command-line of KVM-capability:

    ... -machine pc-q35-4.0,accel=kvm,usb=off,smm=on,dump-guest-core=off -cpu host ...

(I'll also attach the full QEMU command-line.)

> ... I'm not implying that "vmx" should matter a whole lot here; libvirt
> manages emulated (as opposed to virtualized) domains just fine:
> 
>   <domain type='qemu'>
>     ...
>   </domain>
> 
> and I'd expect that to be transparent to the firmware selection logic.

Yes, indeed.

> So I think your question & setup are valid, it's just that parts of your
> comment 4 appear inconsistent.

Thank you for the eagle eyes, as usual.  Now corrected.

Comment 8 Kashyap Chamarthy 2019-07-30 08:43:21 UTC
Created attachment 1594540 [details]
Full QEMU command-line of the VM booted with Secure Boot

Comment 9 Michal Privoznik 2019-08-05 16:16:21 UTC
Patches posted upstream:

https://www.redhat.com/archives/libvir-list/2019-August/msg00109.html

Comment 10 Michal Privoznik 2019-09-12 13:49:41 UTC
I've pushed patches upstream:

e9d51a221c qemu: Use FW descriptors to report FW image paths
5a5b8f74d4 qemufirmwaretest: Test FW path getting through qemuFirmwareGetSupported()
78f8769a84 qemu_firmware: Extend qemuFirmwareGetSupported to return FW paths
bc7fe2f56d qemu_firmware: Document qemuFirmwareGetSupported
48f8aee2ab virfirmware: Expose and define autoptr for virFirmwareFree

v5.7.0-114-gc64cfb45f4

However, it may be worth to wait for this one too:

https://www.redhat.com/archives/libvir-list/2019-September/msg00485.html

Comment 11 Michal Privoznik 2019-10-01 07:27:04 UTC
And the last patch is also pushed:

2f163204ff qemu_capabilities: Put only unique FW images into domcaps

v5.7.0-306-g2f163204ff


Note You need to log in before you can comment on or make changes to this bug.