Bug 998611

Summary: efibootmgr creates wrong UEFI boot option on OVMF
Product: Red Hat Enterprise Linux 6 Reporter: Laszlo Ersek <lersek>
Component: efibootmgrAssignee: Peter Jones <pjones>
Status: CLOSED NOTABUG QA Contact: Release Test Team <release-test-team-automation>
Severity: unspecified Docs Contact:
Priority: unspecified    
Version: 6.4CC: pjones, the.ridikulus.rat, vpavlin
Target Milestone: rc   
Target Release: ---   
Hardware: Unspecified   
OS: Unspecified   
Whiteboard:
Fixed In Version: Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2013-08-28 18:48:38 UTC Type: Bug
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:

Description Laszlo Ersek 2013-08-19 15:22:17 UTC
When installing an x86_64 RHEL-6.4 guest, using fresh OVMF firmware, on a virtio-blk or a virtio-scsi disk, Anaconda creates a boot option with the following contents:

  HD(1,GPT,1E8BDD9C-EA19-4049-8A91-74E8974F1FFE,0x800,0x64000)/\EFI\redhat\grub.efi

As stated above, the problem surfaces with both virtio-blk and virtio-scsi disks. The correct device paths would be:

(1) for virtio-scsi:

  PciRoot(0x0)/Pci(0x4,0x0)/Scsi(0x0,0x0)/HD(1,GPT,1E8BDD9C-EA19-4049-8A91-74E8974F1FFE,0x800,0x64000)/\EFI\redhat\grub.efi

- Pci(X,Y): "X" is the PCI slot (device), "Y" is the PCI function, corresponding to the virtio-scsi host bus adapter,
- Scsi(P,Q): "P" is SCSI target, "Q" is the LUN.

(2) for virtio-blk:

  PciRoot(0x0)/Pci(0x7,0x0)/HD(1,GPT,1E8BDD9C-EA19-4049-8A91-74E8974F1FFE,0x800,0x64000)/\EFI\redhat\grub.efi

- Pci(X,Y): "X" is the PCI slot (device), "Y" is the PCI function, corresponding to the virtio-blk device


I believe the problem could be somewhere near the getEfiProductPath() function in "booty".


See also bug 916016.

Comment 2 Laszlo Ersek 2013-08-26 10:23:21 UTC
Bug 621175 appears to be related.

Comment 3 Laszlo Ersek 2013-08-26 12:19:06 UTC
Now I'm thinking the problem is in efibootmgr actually.

I installed yet another guest on OVMF, this time to an (emulated) IDE disk.

This is what /tmp/program.log contains at the end of the installation (just
before clicking the Reboot button on the Anaconda screen) -- timestamps and
INFO loglevel identification stripped to conserve space:

Running... ['efibootmgr']
BootCurrent: 0000
BootOrder: 0003,0000
Boot0000* EFI DVD/CDROM
Boot0001* EFI Floppy
Boot0002* EFI Floppy 1
Boot0003* EFI Hard Drive
Boot0004* EFI Internal Shell

Running... ['efibootmgr', '-c', '-w', '-L', 'Red Hat Enterprise Linux',
            '-d', '/dev/sda', '-p', '1', '-l', '\\EFI\\redhat\\grub.efi']
BootCurrent: 0000
BootOrder: 0005,0003,0000
Boot0000* EFI DVD/CDROM
Boot0001* EFI Floppy
Boot0002* EFI Floppy 1
Boot0003* EFI Hard Drive
Boot0004* EFI Internal Shell
Boot0005* Red Hat Enterprise Linux

Running... ['efibootmgr', '-v']
BootCurrent: 0000
BootOrder: 0005,0003,0000
Boot0000* EFI DVD/CDROM  ACPI(a0341d0,0)PCI(1,1)ATAPI(1,0,0)
Boot0001* EFI Floppy     ACPI(a0341d0,0)PCI(1,0)ACPI(60441d0,0)
Boot0002* EFI Floppy 1   ACPI(a0341d0,0)PCI(1,0)ACPI(60441d0,1)
Boot0003* EFI Hard Drive ACPI(a0341d0,0)PCI(1,1)ATAPI(0,0,0)
Boot0004* EFI Internal Shell     MM(b,3f91e000,3ffbdfff)
Boot0005* Red Hat Enterprise Linux
HD(1,800,64000,de2980f4-bd5b-45b1-8efc-5b893f81a6e5)File(\EFI\redhat\grub.efi)

I guess anaconda invokes efibootmgr correctly. However the boot option (the
device path in particular) that efibootmgr creates for the grub binary, to
be found on the IDE disk, is wrong. It is wrong in the exact same way as
with virtio-blk and virtio-scsi. Device path nodes before HD() are missing.

I listed the correct device paths in comment 0, for virtio-blk and
virtio-scsi. For IDE it is:

  PciRoot(0x0)/Pci(0x1,0x1)/Ata(Primary,Master,0x0)/HD(1,GPT,DE2980F4-BD5B-45B1-8EFC-5B893F81A6E5,0x800,0x64000)/\EFI\redhat\grub.efi

Interestingly, when I set up these device paths manually, and OVMF can
actually boot grub.efi, then "efibootmgr -v" lists them as follows:

- IDE, wrong (set by efibootmgr):
HD(1,800,64000,de2980f4-bd5b-45b1-8efc-5b893f81a6e5)File(\EFI\redhat\grub.efi)

- IDE, correct (set in OVMF TUI):
ACPI(a0341d0,0)PCI(1,1)ATAPI(0,0,0)HD(1,800,64000,de2980f4-bd5b-45b1-8efc-5b893f81a6e5)File(\EFI\redhat\grub.efi)

- virtio-scsi, wrong (set by efibootmgr):
HD(1,800,64000,87b09cbe-32b9-4737-8ecc-c1e65702cfb6)File(\EFI\redhat\grub.efi)

- virtio-scsi, correct (set in OVMF TUI):
ACPI(a0341d0,0)PCI(7,0)HD(1,800,64000,87b09cbe-32b9-4737-8ecc-c1e65702cfb6)File(\EFI\redhat\grub.efi)

Thus,

(a) efibootmgr fails to add any requried device nodes in front of HD(),
independently of virtio-scsi / virtio-blk / ide.

(b) When the device paths are configured correctly in the OVMF (UEFI) setup
utility, efibootmgr displays the leading PciRoot element as ACPI(a0341d0,0).

(This is actually allowed by the UEFI 2.4 standard; see 9.6.1.2
"Readability". In "Name(_HID, EISAID("PNP0A03"))",  PNP0A03 stands for PCI
bus / PCI root bridge, and EISAID() encodes it to the integer 0x0A0341D0.)

Comment 4 Laszlo Ersek 2013-08-26 12:40:08 UTC
In "efibootmgr-0.5.4-10.el6_4",

show_boot_vars() [src/efibootmgr/efibootmgr.c] // opts.verbose is set
  unparse_path() [src/lib/unparse_path.c]

I think this works correctly -- the devpath to text conversions listed in comment 3 are OK.

make_disk_load_option() [src/lib/efi.c]
  make_edd30_device_path()        absent
  make_edd10_device_path()        absent
  disk_get_partition_info()
  make_harddrive_device_path()    present
  make_file_path_device_path()    present
  make_end_device_path()          present

Comment 5 Laszlo Ersek 2013-08-26 13:35:48 UTC
OK, so the leading device path entries are missing because make_disk_load_option() doesn't generate them, due to "lack of EDD version".

The EDD version 1.0 logic would create an unusable device path for us anyway, so let's concentrate on EDD version 3.0.

The EDD version is determined by:
(1) "-e 1" or "-e 3" (not done by anaconda),
(2) guessing.

Guessing the version, in get_edd_version(), involves:
- formatting the following UEFI variable name (from "BLKX_UNKNOWN_GUID"):
  blk0-47c7b225-c42a-11d2-8e57-00a0c969723b
- looking up its contents,
- if there's no such variable --> no EDD support,
- if the contents, interpreted as a device path, starts with a node of type 2
  (ACPI) subtype 1 (ACPI Device Path: _HID, _UID) --> guessed EDD 3.0
- otherwise, guessed EDD 1.0

This code is from *before* May 2001. Googling for the above variable name (with the GUID in it) returns four results, for OS X and IA64. Most probably some EFI (EDK1, not UEFI/EDK2) relic.

I don't understand how this code can work on bare-metal UEFI2 systems.


Regarding EDD version 3.0:

If it is ascertained in any way (eg. due to "-e 3", then make_edd30_device_path() is invoked. If I add "-e 3" to the efibootmgr command line that anaconda composes, ie.

efibootmgr -e 3 -c -w -L 'Red Hat Enterprise Linux' \
    -d /dev/sda -p 1 -l '\\EFI\\redhat\\grub.efi'

Then the new boot option is still wrong (no different) on the emulated IDE disk.

The code that should run with -e 3 is in theory correct, for IDE and virtio-scsi:

make_disk_load_option() [src/lib/efi.c]
  make_edd30_device_path()
    disk_get_pci() [src/lib/disk.c]
      disk_info_from_fd() -- reports scsi for /dev/sda
      disk_get_scsi_pci()
        get_scsi_pci()
          SCSI_IOCTL_GET_PCI
    get_scsi_idlun()
      SCSI_IOCTL_GET_IDLUN
    idlun_to_components()
    make_acpi_device_path()
    make_pci_device_path()
    make_scsi_device_path()

however even if it worked for IDE and/or virtio-scsi (which it doesn't), it would still be wrong for virtio-blk.

Comment 6 Laszlo Ersek 2013-08-26 13:39:18 UTC
'-e 3' doesn't work for even for virtio-scsi / IDE because disk_info_from_fd() has a bug -- it fails to determine scsi and even reports "Unknown interface type".

The bug is that disk_info_from_fd() looks at "buf.st_dev" instead of "buf.st_rdev". The former describes the device *containing* the special file, while the latter is the device described by the special file.

Comment 7 Laszlo Ersek 2013-08-26 23:05:59 UTC
posted upstream series:
http://thread.gmane.org/gmane.comp.bios.tianocore.devel/3841

Comment 8 Laszlo Ersek 2013-08-28 18:48:38 UTC
Turns out this is a bug in OVMF's QemuBootOrder code -- device paths starting with HD(...) are valid for booting in UEFI. This patch fixes it for me:
http://thread.gmane.org/gmane.comp.bios.tianocore.devel/3884

Efibootmgr is not the place to fix this problem, so I'm closing out this BZ as NOTABUG.

(Of course it would still be nice to see the efibootmgr series merged -- efibootmgr does support, under EDD 3.0, the installation of full device paths in general, just not for virtio-blk and virtio-scsi.)