Skip to contentSkip to conversation

Patch "efi/libstub: Use efi_exit_boot_services() in FDT" has been added to the 4.7-stable tree

PATCH [email protected] 1 participant 1 message Sep 22, 2016

Subsystems (2)
lore
Share & tools
lore

[email protected]

author maintainer Applied
#0 lore raw

This is a note to let you know that I've just added the patch titled

efi/libstub: Use efi_exit_boot_services() in FDT

to the 4.7-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
efi-libstub-use-efi_exit_boot_services-in-fdt.patch
and it can be found in the queue-4.7 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.

Quoted 1 line

From ed9cc156c42ff0c0bf9b1d09df48a12bf0873473 Mon Sep 17 00:00:00 2001

From: Jeffrey Hugo <[email protected]>
Date: Mon, 29 Aug 2016 14:38:53 -0600
Subject: efi/libstub: Use efi_exit_boot_services() in FDT

From: Jeffrey Hugo <[email protected]>

commit ed9cc156c42ff0c0bf9b1d09df48a12bf0873473 upstream.

The FDT code directly calls ExitBootServices. This is inadvisable as the UEFI spec details a complex set of errors, race conditions, and API interactions that the caller of ExitBootServices must get correct. The FDT code does not handle EFI_INVALID_PARAMETER as required by the spec, which causes intermittent boot failures on the Qualcomm Technologies QDF2432. Call the efi_exit_boot_services() helper intead, which handles the EFI_INVALID_PARAMETER scenario properly.

---
 drivers/firmware/efi/libstub/fdt.c |   37 +++++++++++++++++++++++++++----------
 1 file changed, 27 insertions(+), 10 deletions(-)
drivers/firmware/efi/libstub/fdt.c +27 -10
@@ -152,6 +152,27 @@ fdt_set_fail:
 #define EFI_FDT_ALIGN EFI_PAGE_SIZE
 #endif
 
+struct exit_boot_struct {
+	efi_memory_desc_t *runtime_map;
+	int *runtime_entry_count;
+};
+
+static efi_status_t exit_boot_func(efi_system_table_t *sys_table_arg,
+				   struct efi_boot_memmap *map,
+				   void *priv)
+{
+	struct exit_boot_struct *p = priv;
+	/*
+	 * Update the memory map with virtual addresses. The function will also
+	 * populate @runtime_map with copies of just the EFI_MEMORY_RUNTIME
+	 * entries so that we can pass it straight to SetVirtualAddressMap()
+	 */
+	efi_get_virtmap(*map->map, *map->map_size, *map->desc_size,
+			p->runtime_map, p->runtime_entry_count);
+
+	return EFI_SUCCESS;
+}
+
 /*
  * Allocate memory for a new FDT, then add EFI, commandline, and
  * initrd related fields to the FDT.  This routine increases the
@@ -183,6 +204,7 @@ efi_status_t allocate_new_fdt_and_exit_b
 	efi_status_t status;
 	int runtime_entry_count = 0;
 	struct efi_boot_memmap map;
+	struct exit_boot_struct priv;
 
 	map.map =	&runtime_map;
 	map.map_size =	&map_size;
@@ -257,16 +279,11 @@ efi_status_t allocate_new_fdt_and_exit_b
 		}
 	}
 
-	/*
-	 * Update the memory map with virtual addresses. The function will also
-	 * populate @runtime_map with copies of just the EFI_MEMORY_RUNTIME
-	 * entries so that we can pass it straight into SetVirtualAddressMap()
-	 */
-	efi_get_virtmap(memory_map, map_size, desc_size, runtime_map,
-			&runtime_entry_count);
-
-	/* Now we are ready to exit_boot_services.*/
-	status = sys_table->boottime->exit_boot_services(handle, mmap_key);
+	sys_table->boottime->free_pool(memory_map);
+	priv.runtime_map = runtime_map;
+	priv.runtime_entry_count = &runtime_entry_count;
+	status = efi_exit_boot_services(sys_table, handle, &map, &priv,
+					exit_boot_func);
 
 	if (status == EFI_SUCCESS) {
 		efi_set_virtual_address_map_t *svam;

Patches currently in stable-queue which might be from [email protected] are

queue-4.7/efi-libstub-allocate-headspace-in-efi_get_memory_map.patch queue-4.7/x86-efi-use-efi_exit_boot_services.patch queue-4.7/efi-libstub-introduce-exitbootservices-helper.patch queue-4.7/efi-libstub-use-efi_exit_boot_services-in-fdt.patch