Bug 1216789

Summary: Got "Unable to find any firmware to satisfy efi" message when using ovmf-x86_64-ms-code.bin
Product: [openSUSE] openSUSE Tumbleweed Reporter: Joey Lee <jlee>
Component: Virtualization:OtherAssignee: virt-bugs list <virt-bugs>
Status: RESOLVED INVALID QA Contact: E-mail List <qa-bugs>
Severity: Normal    
Priority: P5 - None CC: jfehlig, jlee
Version: Current   
Target Milestone: ---   
Hardware: Other   
OS: Other   
Whiteboard:
Found By: --- Services Priority:
Business Priority: Blocker: ---
Marketing QA Status: --- IT Deployment: ---

Description Joey Lee 2023-11-01 13:54:50 UTC
When I am tracing bsc#1216472. I found that the ovmf-x86_64-ms-code.bin image file can NOT be used in libvirt xml file when saving xml. Using "virsh edit" and save, it shows:

錯誤:operation failed: Unable to find any firmware to satisfy 'efi'
Failed. Try again? [y,n,i,f,?]:

The firmware image definition in my xml is:

    <loader readonly='yes' secure='no' type='pflash'>/usr/share/qemu/ovmf-x86_64-ms-code.bin</loader>
    <nvram template='/usr/share/qemu/ovmf-x86_64-ms-vars.bin'>/var/lib/libvirt/qemu/nvram/opensuseTW_VARS.fd</nvram>

But using ovmf-x86_64-code.bin image does NOT have problem. The following setting works fine:

    <loader readonly='yes' secure='no' type='pflash'>/usr/share/qemu/ovmf-x86_64-code.bin</loader>
    <nvram template='/usr/share/qemu/ovmf-x86_64-vars.bin'>/var/lib/libvirt/qemu/nvram/opensuseTW_VARS.fd</nvram>

I have tested qemu-ovmf-x86_64-202208 and qemu-ovmf-x86_64-202308, both of them has this problem.
Comment 1 Joey Lee 2023-11-01 14:11:59 UTC
I have compared with my another old host, it uses libvirt-daemon-8.0.0 and did not see problem:

Success case:

  <os>
    <type arch='x86_64' machine='pc-q35-5.2'>hvm</type>
    <loader readonly='yes' secure='no' type='pflash'>/usr/share/qemu/ovmf-x86_64-ms-4m-code.bin</loader>
    <nvram template='/usr/share/qemu/ovmf-x86_64-ms-4m-vars.bin'>/var/lib/libvirt/qemu/nvram/opensuseTW_VARS.fd</nvram>
    <boot dev='hd'/>
  </os>


The issue host machine uses libvirt-daemon-9.4.0-3.1.x86_64.

fail case:
  <os firmware='efi'>
    <type arch='x86_64' machine='pc-q35-7.1'>hvm</type>
    <firmware>
      <feature enabled='no' name='enrolled-keys'/>
      <feature enabled='no' name='secure-boot'/>
    </firmware>
    <loader readonly='yes' secure='no' type='pflash'>/usr/share/qemu/ovmf-x86_64-code.bin</loader>
    <nvram template='/usr/share/qemu/ovmf-x86_64-vars.bin'>/var/lib/libvirt/qemu/nvram/opensuseTW_VARS.fd</nvram>
    <boot dev='hd'/>
  </os>

Looks that the firmware='efi' and features section will be auto-add (force) to os section. It causes that only ovmf-x86_64-code.bin image file can pass the xml checking.
Comment 2 Joey Lee 2023-11-01 14:13:21 UTC
Need libvirt expert's help.
Comment 3 James Fehlig 2023-11-01 15:55:56 UTC
(In reply to Joey Lee from comment #1)
> The issue host machine uses libvirt-daemon-9.4.0-3.1.x86_64.

That's an old libvirt. Can you try the latest 9.8.0 in TW? There have been quite a few changes in the firmware handling code over the past few releases. I can also check the status of this bug while packaging/testing the freshly released 9.9.0.
Comment 4 James Fehlig 2023-11-01 22:22:03 UTC
(In reply to Joey Lee from comment #0)
> When I am tracing bsc#1216472. I found that the ovmf-x86_64-ms-code.bin
> image file can NOT be used in libvirt xml file when saving xml. Using "virsh
> edit" and save, it shows:
> 
> 錯誤:operation failed: Unable to find any firmware to satisfy 'efi'
> Failed. Try again? [y,n,i,f,?]:
> 
> The firmware image definition in my xml is:
> 
>     <loader readonly='yes' secure='no'
> type='pflash'>/usr/share/qemu/ovmf-x86_64-ms-code.bin</loader>
>     <nvram
> template='/usr/share/qemu/ovmf-x86_64-ms-vars.bin'>/var/lib/libvirt/qemu/
> nvram/opensuseTW_VARS.fd</nvram>

According to the json definition for this firmware, it has 'enrolled-keys' set, which according to $qemu-src/docs/interop/firmware.json means secure-boot is enabled

# @enrolled-keys: The variable store (NVRAM) template associated with
#                 the firmware binary has the UEFI Secure Boot
#                 operational mode turned on, with certificates
#                 enrolled.

Trying to define a VM with such config using libvirt 9.9.0 fails with

virt82:/vm_images/jim/images/sles15sp3-kvm-ovmf # virsh define sles15sp3-kvm-ovmf-autoselect-test.xml
error: Failed to define domain from sles15sp3-kvm-ovmf-autoselect-test.xml
error: firmware feature 'enrolled-keys' cannot be enabled when firmware feature 'secure-boot' is disabled

Using a firmware that does not advertise secure-boot or enrolled-keys should work fine.

> But using ovmf-x86_64-code.bin image does NOT have problem. The following
> setting works fine:

Yeah, like that one :-).
Comment 5 James Fehlig 2023-11-01 22:38:01 UTC
(In reply to Joey Lee from comment #1)
> fail case:
>   <os firmware='efi'>
>     <type arch='x86_64' machine='pc-q35-7.1'>hvm</type>
>     <firmware>
>       <feature enabled='no' name='enrolled-keys'/>
>       <feature enabled='no' name='secure-boot'/>
>     </firmware>
>     <loader readonly='yes' secure='no'
> type='pflash'>/usr/share/qemu/ovmf-x86_64-code.bin</loader>
>     <nvram
> template='/usr/share/qemu/ovmf-x86_64-vars.bin'>/var/lib/libvirt/qemu/nvram/
> opensuseTW_VARS.fd</nvram>
>     <boot dev='hd'/>
>   </os>

When using firmware='efi', you're instructing libvirt to pick an appropriate firmware based on the requested features, aka firmware autoselection. See the examples and description of the firmware attribute in the domXML docs

https://libvirt.org/formatdomain.html#bios-bootloader

When using firmware autoselection, your example would work with

  <os firmware='efi'>
    <firmware>
      <feature enabled='no' name='enrolled-keys'/>
      <feature enabled='no' name='secure-boot'/>
    </firmware>
    <type arch='x86_64' machine='pc-q35-5.2'>hvm</type>
    <boot dev='hd'/>
  </os>

> Looks that the firmware='efi' and features section will be auto-add (force)
> to os section. It causes that only ovmf-x86_64-code.bin image file can pass
> the xml checking.

With firmware autoselection, libvirt will ensure it can find a firmware that meets the specified criteria. When not using autoselection and specifying the firmware directly, libvirt still sanity checks the config against the firmware json descriptor files.
Comment 6 Joey Lee 2023-11-02 06:54:55 UTC
After upgraded qemu-kvm and libvirt, I can edit xml success after removed firmware='efi' and firmware/features section now.

My environment:

qemu-8.1.2-1.2.x86_64
libvirt-9.8.0-2.1.x86_64
qemu-ovmf-x86_64-202308-1.2.noarch
 
The following configuration is success case:

  <os firmware='efi'>
    <type arch='x86_64' machine='pc-q35-7.1'>hvm</type>
    <firmware>
      <feature enabled='yes' name='enrolled-keys'/>
      <feature enabled='yes' name='secure-boot'/>
    </firmware>
    <loader readonly='yes' secure='yes' type='pflash'>/usr/share/qemu/ovmf-x86_64-smm-ms-code.bin</loader>
    <nvram template='/usr/share/qemu/ovmf-x86_64-smm-ms-vars.bin'>/var/lib/libvirt/qemu/nvram/opensuseTW_VARS.fd</nvram>
    <boot dev='hd'/>
  </os>

The above firmware='efi' and firmware/feature section are auto-added by libvirt after I edit and save the xml config. The ovmf-x86_64-smm-ms-code.bin can be used with libvirt now.
Comment 7 Joey Lee 2023-11-02 06:55:43 UTC
Thanks for James's help! Closed this issue to INVALID.