linux-arm-kernel.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] efi/libstub: arm*: Pass latest memory map to the kernel
@ 2016-12-09 18:24 Ard Biesheuvel
  2016-12-12  9:35 ` James Morse
  0 siblings, 1 reply; 4+ messages in thread
From: Ard Biesheuvel @ 2016-12-09 18:24 UTC (permalink / raw)
  To: linux-arm-kernel

As reported by James, the current libstub code involving the annotated
memory map only works somewhat correctly by accident, due to the fact
that a pool allocation happens to be reused immediately, retaining its
former contents.

Instead of juggling memory maps, which makes the code more complex than
it needs to be, simply put a placholder value into the FDT, and only
write the actual value after ExitBootServices() has been called.

Reported-by: James Morse <james.morse@arm.com>
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
---
 drivers/firmware/efi/libstub/fdt.c | 51 ++++++++++++++++++++++++--------------
 1 file changed, 32 insertions(+), 19 deletions(-)

diff --git a/drivers/firmware/efi/libstub/fdt.c b/drivers/firmware/efi/libstub/fdt.c
index a6a93116a8f0..5d39dff77f17 100644
--- a/drivers/firmware/efi/libstub/fdt.c
+++ b/drivers/firmware/efi/libstub/fdt.c
@@ -101,7 +101,7 @@ efi_status_t update_fdt(efi_system_table_t *sys_table, void *orig_fdt,
 	if (status)
 		goto fdt_set_fail;
 
-	fdt_val64 = cpu_to_fdt64((u64)(unsigned long)memory_map);
+	fdt_val64 = U64_MAX; /* placeholder */
 	status = fdt_setprop(fdt, node, "linux,uefi-mmap-start",
 			     &fdt_val64,  sizeof(fdt_val64));
 	if (status)
@@ -148,6 +148,24 @@ efi_status_t update_fdt(efi_system_table_t *sys_table, void *orig_fdt,
 	return EFI_LOAD_ERROR;
 }
 
+static efi_status_t update_fdt_memmap(void *fdt, u64 memmap)
+{
+	int node = fdt_path_offset(fdt, "/chosen");
+	efi_status_t status;
+
+	if (node < 0)
+		return EFI_LOAD_ERROR;
+
+	memmap = cpu_to_fdt64(memmap);
+	status = fdt_setprop_inplace(fdt, node, "linux,uefi-mmap-start",
+				     &memmap, sizeof(memmap));
+
+	if (status)
+		return EFI_LOAD_ERROR;
+
+	return EFI_SUCCESS;
+}
+
 #ifndef EFI_FDT_ALIGN
 #define EFI_FDT_ALIGN EFI_PAGE_SIZE
 #endif
@@ -243,15 +261,6 @@ efi_status_t allocate_new_fdt_and_exit_boot(efi_system_table_t *sys_table,
 			goto fail;
 		}
 
-		/*
-		 * Now that we have done our final memory allocation (and free)
-		 * we can get the memory map key  needed for
-		 * exit_boot_services().
-		 */
-		status = efi_get_memory_map(sys_table, &map);
-		if (status != EFI_SUCCESS)
-			goto fail_free_new_fdt;
-
 		status = update_fdt(sys_table,
 				    (void *)fdt_addr, fdt_size,
 				    (void *)*new_fdt_addr, new_fdt_size,
@@ -266,20 +275,16 @@ efi_status_t allocate_new_fdt_and_exit_boot(efi_system_table_t *sys_table,
 			/*
 			 * We need to allocate more space for the new
 			 * device tree, so free existing buffer that is
-			 * too small.  Also free memory map, as we will need
-			 * to get new one that reflects the free/alloc we do
-			 * on the device tree buffer.
+			 * too small.
 			 */
 			efi_free(sys_table, new_fdt_size, *new_fdt_addr);
-			sys_table->boottime->free_pool(memory_map);
 			new_fdt_size += EFI_PAGE_SIZE;
 		} else {
 			pr_efi_err(sys_table, "Unable to construct new device tree.\n");
-			goto fail_free_mmap;
+			goto fail_free_new_fdt;
 		}
 	}
 
-	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,
@@ -288,6 +293,17 @@ efi_status_t allocate_new_fdt_and_exit_boot(efi_system_table_t *sys_table,
 	if (status == EFI_SUCCESS) {
 		efi_set_virtual_address_map_t *svam;
 
+		status = update_fdt_memmap((void *)*new_fdt_addr,
+					   (u64)memory_map);
+		if (status != EFI_SUCCESS) {
+			/*
+			 * The kernel won't get far without the memory map, but
+			 * may still be able to print something meaningful so
+			 * return success here.
+			 */
+			return EFI_SUCCESS;
+		}
+
 		/* Install the new virtual address map */
 		svam = sys_table->runtime->set_virtual_address_map;
 		status = svam(runtime_entry_count * desc_size, desc_size,
@@ -319,9 +335,6 @@ efi_status_t allocate_new_fdt_and_exit_boot(efi_system_table_t *sys_table,
 
 	pr_efi_err(sys_table, "Exit boot services failed.\n");
 
-fail_free_mmap:
-	sys_table->boottime->free_pool(memory_map);
-
 fail_free_new_fdt:
 	efi_free(sys_table, new_fdt_size, *new_fdt_addr);
 
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 4+ messages in thread
* [GIT PULL] efi: urgent fix for v4.10 with cc to stable
@ 2016-12-24 13:59 Ard Biesheuvel
  2016-12-24 13:59 ` [PATCH] efi/libstub: arm*: Pass latest memory map to the kernel Ard Biesheuvel
  0 siblings, 1 reply; 4+ messages in thread
From: Ard Biesheuvel @ 2016-12-24 13:59 UTC (permalink / raw)
  To: linux-arm-kernel

The following changes since commit 69973b830859bc6529a7a0468ba0d80ee5117826:

  Linux 4.9 (2016-12-11 11:17:54 -0800)

are available in the git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/efi/efi.git tags/efi-urgent

for you to fetch changes up to bcd5812b8bfb24783f09b53659fae54d1b02d0be:

  efi/libstub: arm*: Pass latest memory map to the kernel (2016-12-24 13:19:28 +0000)

----------------------------------------------------------------
* One patch, addressing a major issue in a bugfix that went into stable,
  where on ARM/arm64 systems, the EFI memory map address passed to the
  kernel via the FDT may be different from the address of the buffer
  containing the annotated EFI memory map.

----------------------------------------------------------------
Ard Biesheuvel (1):
      efi/libstub: arm*: Pass latest memory map to the kernel

 drivers/firmware/efi/libstub/efistub.h |  8 ----
 drivers/firmware/efi/libstub/fdt.c     | 87 ++++++++++++++++++++++------------
 2 files changed, 56 insertions(+), 39 deletions(-)

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2016-12-24 13:59 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2016-12-09 18:24 [PATCH] efi/libstub: arm*: Pass latest memory map to the kernel Ard Biesheuvel
2016-12-12  9:35 ` James Morse
2016-12-12 17:00   ` Jeffrey Hugo
  -- strict thread matches above, loose matches on Subject: below --
2016-12-24 13:59 [GIT PULL] efi: urgent fix for v4.10 with cc to stable Ard Biesheuvel
2016-12-24 13:59 ` [PATCH] efi/libstub: arm*: Pass latest memory map to the kernel Ard Biesheuvel

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).