arrfab / rpms / shim

Forked from rpms/shim 4 years ago
Clone

Blame SOURCES/0029-Fetch-the-netboot-image-from-the-same-device.patch

e97c83
From f500a8742c19be604d33907b56ab9597fe448b65 Mon Sep 17 00:00:00 2001
e97c83
From: Gary Ching-Pang Lin <glin@suse.com>
e97c83
Date: Tue, 27 May 2014 14:12:32 +0800
e97c83
Subject: [PATCH 29/74] Fetch the netboot image from the same device
e97c83
e97c83
The previous strategy is to locate the first available PXE_BASE_CODE
e97c83
protocol and to fetch the second stage image from it, and this may
e97c83
cause shim to fetch the wrong second stage image, i.e. grub.efi.
e97c83
e97c83
Consider the machine with the following boot order:
e97c83
1. PXE Boot
e97c83
2. Hard Drive
e97c83
e97c83
Assume that the EFI image, e.g. bootx64.efi, in the PXE server is
e97c83
broken, then "PXE Boot" will fail and fallback to "Hard Drive". While
e97c83
shim.efi in "Hard Drive" is loaded, it will find the PXE protocol is
e97c83
available and fetch grub.efi from the PXE server, not grub.efi in the
e97c83
disk.
e97c83
e97c83
This commit checks the DeviceHandle from Loaded Image. If the device
e97c83
supports PXE, then shim fetches grub.efi with the PXE protocol. Otherwise,
e97c83
shim loads grub.efi from the disk.
e97c83
e97c83
Signed-off-by: Gary Ching-Pang Lin <glin@suse.com>
e97c83
---
e97c83
 netboot.c | 77 +++++++++++++--------------------------------------------------
e97c83
 shim.c    |  2 +-
e97c83
 2 files changed, 17 insertions(+), 62 deletions(-)
e97c83
e97c83
diff --git a/netboot.c b/netboot.c
e97c83
index 07e2773..5ef53f7 100644
e97c83
--- a/netboot.c
e97c83
+++ b/netboot.c
e97c83
@@ -85,78 +85,33 @@ translate_slashes(char *str)
e97c83
  * Returns TRUE if we identify a protocol that is enabled and Providing us with
e97c83
  * the needed information to fetch a grubx64.efi image
e97c83
  */
e97c83
-BOOLEAN findNetboot(EFI_HANDLE image_handle)
e97c83
+BOOLEAN findNetboot(EFI_HANDLE device)
e97c83
 {
e97c83
-	UINTN bs = sizeof(EFI_HANDLE);
e97c83
-	EFI_GUID pxe_base_code_protocol = EFI_PXE_BASE_CODE_PROTOCOL;
e97c83
-	EFI_HANDLE *hbuf;
e97c83
-	BOOLEAN rc = FALSE;
e97c83
-	void *buffer = AllocatePool(bs);
e97c83
-	UINTN errcnt = 0;
e97c83
-	UINTN i;
e97c83
 	EFI_STATUS status;
e97c83
 
e97c83
-	if (!buffer)
e97c83
+	status = uefi_call_wrapper(BS->HandleProtocol, 3, device,
e97c83
+				   &PxeBaseCodeProtocol, (VOID **)&pxe);
e97c83
+	if (status != EFI_SUCCESS) {
e97c83
+		pxe = NULL;
e97c83
 		return FALSE;
e97c83
-
e97c83
-try_again:
e97c83
-	status = uefi_call_wrapper(BS->LocateHandle,5, ByProtocol, 
e97c83
-				   &pxe_base_code_protocol, NULL, &bs,
e97c83
-				   buffer);
e97c83
-
e97c83
-	if (status == EFI_BUFFER_TOO_SMALL) {
e97c83
-		errcnt++;
e97c83
-		FreePool(buffer);
e97c83
-		if (errcnt > 1)
e97c83
-			return FALSE;
e97c83
-		buffer = AllocatePool(bs);
e97c83
-		if (!buffer)
e97c83
-			return FALSE;
e97c83
-		goto try_again;
e97c83
 	}
e97c83
 
e97c83
-	if (status == EFI_NOT_FOUND) {
e97c83
-		FreePool(buffer);
e97c83
+	if (!pxe || !pxe->Mode) {
e97c83
+		pxe = NULL;
e97c83
 		return FALSE;
e97c83
 	}
e97c83
 
e97c83
-	/*
e97c83
- 	 * We have a list of pxe supporting protocols, lets see if any are
e97c83
- 	 * active
e97c83
- 	 */
e97c83
-	hbuf = buffer;
e97c83
-	pxe = NULL;
e97c83
-	for (i=0; i < (bs / sizeof(EFI_HANDLE)); i++) {
e97c83
-		status = uefi_call_wrapper(BS->OpenProtocol, 6, hbuf[i],
e97c83
-					   &pxe_base_code_protocol,
e97c83
-					   (void **)&pxe, image_handle, NULL,
e97c83
-					   EFI_OPEN_PROTOCOL_GET_PROTOCOL);
e97c83
-
e97c83
-		if (status != EFI_SUCCESS) {
e97c83
-			pxe = NULL;
e97c83
-			continue;
e97c83
-		}
e97c83
-
e97c83
-		if (!pxe || !pxe->Mode) {
e97c83
-			pxe = NULL;
e97c83
-			continue;
e97c83
-		}
e97c83
-
e97c83
-		if (pxe->Mode->Started && pxe->Mode->DhcpAckReceived) {
e97c83
-			/*
e97c83
- 			 * We've located a pxe protocol handle thats been 
e97c83
- 			 * started and has received an ACK, meaning its
e97c83
- 			 * something we'll be able to get tftp server info
e97c83
- 			 * out of
e97c83
- 			 */
e97c83
-			rc = TRUE;
e97c83
-			break;
e97c83
-		}
e97c83
-			
e97c83
+	if (!pxe->Mode->Started || !pxe->Mode->DhcpAckReceived) {
e97c83
+		pxe = NULL;
e97c83
+		return FALSE;
e97c83
 	}
e97c83
 
e97c83
-	FreePool(buffer);
e97c83
-	return rc;
e97c83
+	/*
e97c83
+	 * We've located a pxe protocol handle thats been started and has
e97c83
+	 * received an ACK, meaning its something we'll be able to get
e97c83
+	 * tftp server info out of
e97c83
+	 */
e97c83
+	return TRUE;
e97c83
 }
e97c83
 
e97c83
 static CHAR8 *get_v6_bootfile_url(EFI_PXE_BASE_CODE_DHCPV6_PACKET *pkt)
e97c83
diff --git a/shim.c b/shim.c
e97c83
index 48a6f2f..d8699f9 100644
e97c83
--- a/shim.c
e97c83
+++ b/shim.c
e97c83
@@ -1373,7 +1373,7 @@ EFI_STATUS start_image(EFI_HANDLE image_handle, CHAR16 *ImagePath)
e97c83
 		goto done;
e97c83
 	}
e97c83
 
e97c83
-	if (findNetboot(image_handle)) {
e97c83
+	if (findNetboot(li->DeviceHandle)) {
e97c83
 		efi_status = parseNetbootinfo(image_handle);
e97c83
 		if (efi_status != EFI_SUCCESS) {
e97c83
 			Print(L"Netboot parsing failed: %r\n", efi_status);
e97c83
-- 
e97c83
1.9.3
e97c83