Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
SUSE:SLE-12-SP3:GA
ovmf.14653
ovmf-bsc990773-remove-stale-boot-options.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File ovmf-bsc990773-remove-stale-boot-options.patch of Package ovmf.14653
From 2eb358986052bd0104f6d16fbeb0a450658256fc Mon Sep 17 00:00:00 2001 From: Laszlo Ersek <lersek@redhat.com> Date: Fri, 8 Jul 2016 02:49:45 +0200 Subject: [PATCH] OvmfPkg/PlatformBootManagerLib: remove stale FvFile boot options Removes any boot options that point to binaries built into the firmware and have become stale due to any of the following: - DXEFV's base address or size changed (historical), - DXEFV's FvNameGuid changed, - the FILE_GUID of the pointed-to binary changed, - the referenced binary is no longer built into the firmware. For example, multiple such "EFI Internal Shell" boot options can coexist. They technically differ from each other, but may not describe any built-in shell binary exactly. Such options can accumulate in a varstore over time, and while they remain generally bootable (thanks to the efforts of BmGetFileBufferByFvFilePath()), they look bad. Filter out any stale options. This functionality is not added to QemuBootOrderLib, because it is independent from QEMU and fw_cfg. Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org> Cc: Gary Lin <glin@suse.com> Cc: Jordan Justen <jordan.l.justen@intel.com> Cc: Ruiyu Ni <ruiyu.ni@intel.com> Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Laszlo Ersek <lersek@redhat.com> Reviewed-by: Jordan Justen <jordan.l.justen@intel.com> --- .../Library/PlatformBootManagerLib/BdsPlatform.c | 130 +++++++++++++++++++++ .../PlatformBootManagerLib.inf | 1 + 2 files changed, 131 insertions(+) Index: ovmf-2015+git1462940744.321151f/OvmfPkg/Library/PlatformBootManagerLib/BdsPlatform.c =================================================================== --- ovmf-2015+git1462940744.321151f.orig/OvmfPkg/Library/PlatformBootManagerLib/BdsPlatform.c +++ ovmf-2015+git1462940744.321151f/OvmfPkg/Library/PlatformBootManagerLib/BdsPlatform.c @@ -15,6 +15,7 @@ #include "BdsPlatform.h" #include <Guid/XenInfo.h> #include <Guid/RootBridgesConnectedEventGroup.h> +#include <Protocol/FirmwareVolume2.h> // @@ -149,6 +150,134 @@ PlatformRegisterFvBootOption ( EfiBootManagerFreeLoadOptions (BootOptions, BootOptionCount); } +/** + Remove all MemoryMapped(...)/FvFile(...) and Fv(...)/FvFile(...) boot options + whose device paths do not resolve exactly to an FvFile in the system. + + This removes any boot options that point to binaries built into the firmware + and have become stale due to any of the following: + - DXEFV's base address or size changed (historical), + - DXEFV's FvNameGuid changed, + - the FILE_GUID of the pointed-to binary changed, + - the referenced binary is no longer built into the firmware. + + EfiBootManagerFindLoadOption() used in PlatformRegisterFvBootOption() only + avoids exact duplicates. +**/ +VOID +RemoveStaleFvFileOptions ( + VOID + ) +{ + EFI_BOOT_MANAGER_LOAD_OPTION *BootOptions; + UINTN BootOptionCount; + UINTN Index; + + BootOptions = EfiBootManagerGetLoadOptions (&BootOptionCount, + LoadOptionTypeBoot); + + for (Index = 0; Index < BootOptionCount; ++Index) { + EFI_DEVICE_PATH_PROTOCOL *Node1, *Node2, *SearchNode; + EFI_STATUS Status; + EFI_HANDLE FvHandle; + + // + // If the device path starts with neither MemoryMapped(...) nor Fv(...), + // then keep the boot option. + // + Node1 = BootOptions[Index].FilePath; + if (!(DevicePathType (Node1) == HARDWARE_DEVICE_PATH && + DevicePathSubType (Node1) == HW_MEMMAP_DP) && + !(DevicePathType (Node1) == MEDIA_DEVICE_PATH && + DevicePathSubType (Node1) == MEDIA_PIWG_FW_VOL_DP)) { + continue; + } + + // + // If the second device path node is not FvFile(...), then keep the boot + // option. + // + Node2 = NextDevicePathNode (Node1); + if (DevicePathType (Node2) != MEDIA_DEVICE_PATH || + DevicePathSubType (Node2) != MEDIA_PIWG_FW_FILE_DP) { + continue; + } + + // + // Locate the Firmware Volume2 protocol instance that is denoted by the + // boot option. If this lookup fails (i.e., the boot option references a + // firmware volume that doesn't exist), then we'll proceed to delete the + // boot option. + // + SearchNode = Node1; + Status = gBS->LocateDevicePath (&gEfiFirmwareVolume2ProtocolGuid, + &SearchNode, &FvHandle); + + if (!EFI_ERROR (Status)) { + // + // The firmware volume was found; now let's see if it contains the FvFile + // identified by GUID. + // + EFI_FIRMWARE_VOLUME2_PROTOCOL *FvProtocol; + MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *FvFileNode; + UINTN BufferSize; + EFI_FV_FILETYPE FoundType; + EFI_FV_FILE_ATTRIBUTES FileAttributes; + UINT32 AuthenticationStatus; + + Status = gBS->HandleProtocol (FvHandle, &gEfiFirmwareVolume2ProtocolGuid, + (VOID **)&FvProtocol); + ASSERT_EFI_ERROR (Status); + + FvFileNode = (MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *)Node2; + // + // Buffer==NULL means we request metadata only: BufferSize, FoundType, + // FileAttributes. + // + Status = FvProtocol->ReadFile ( + FvProtocol, + &FvFileNode->FvFileName, // NameGuid + NULL, // Buffer + &BufferSize, + &FoundType, + &FileAttributes, + &AuthenticationStatus + ); + if (!EFI_ERROR (Status)) { + // + // The FvFile was found. Keep the boot option. + // + continue; + } + } + + // + // Delete the boot option. + // + Status = EfiBootManagerDeleteLoadOptionVariable ( + BootOptions[Index].OptionNumber, LoadOptionTypeBoot); + DEBUG_CODE ( + CHAR16 *DevicePathString; + + DevicePathString = ConvertDevicePathToText(BootOptions[Index].FilePath, + FALSE, FALSE); + DEBUG (( + EFI_ERROR (Status) ? EFI_D_WARN : EFI_D_VERBOSE, + "%a: removing stale Boot#%04x %s: %r\n", + __FUNCTION__, + (UINT32)BootOptions[Index].OptionNumber, + DevicePathString == NULL ? L"<unavailable>" : DevicePathString, + Status + )); + if (DevicePathString != NULL) { + FreePool (DevicePathString); + } + ); + } + + EfiBootManagerFreeLoadOptions (BootOptions, BootOptionCount); +} + VOID PlatformRegisterOptionsAndKeys ( VOID @@ -1342,6 +1471,7 @@ Routine Description: PcdGetPtr (PcdShellFile), L"EFI Internal Shell", LOAD_OPTION_ACTIVE ); + RemoveStaleFvFileOptions (); SetBootOrderFromQemu (NULL); } Index: ovmf-2015+git1462940744.321151f/OvmfPkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf =================================================================== --- ovmf-2015+git1462940744.321151f.orig/OvmfPkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf +++ ovmf-2015+git1462940744.321151f/OvmfPkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf @@ -77,6 +77,7 @@ gEfiDxeSmmReadyToLockProtocolGuid # PROTOCOL SOMETIMES_PRODUCED gEfiOEMBadgingProtocolGuid # PROTOCOL SOMETIMES_PRODUCED gEfiLoadedImageProtocolGuid # PROTOCOL SOMETIMES_PRODUCED + gEfiFirmwareVolume2ProtocolGuid # PROTOCOL SOMETIMES_CONSUMED [Guids] gEfiXenInfoGuid
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor