Revert "efi_loader: remove efi_exit_caches()"
authorAlexander Graf <agraf@suse.de>
Thu, 15 Nov 2018 20:23:47 +0000 (21:23 +0100)
committerAlexander Graf <agraf@suse.de>
Sun, 2 Dec 2018 20:59:37 +0000 (21:59 +0100)
This reverts commit 3170db63c41a2eda6ee6573353bb4de8c7c1b9d5.

It reportedly breaks OpenBSD/armv7 booting and I've already received
complaints from people that it breaks some Linux armv7 systems as well.

We'll have to give this whole caching story a good bit more thought.

Reported-by: Jonathan Gray <jsg@jsg.id.au>
Signed-off-by: Alexander Graf <agraf@suse.de>
lib/efi_loader/efi_boottime.c

index eb652e8348562ba6a2b1ab59149db386b3bb0bb4..cc9efbb0cbfd9f2c041c5339aa5a7f2ce13cc110 100644 (file)
@@ -26,6 +26,14 @@ LIST_HEAD(efi_obj_list);
 /* List of all events */
 LIST_HEAD(efi_events);
 
+/*
+ * If we're running on nasty systems (32bit ARM booting into non-EFI Linux)
+ * we need to do trickery with caches. Since we don't want to break the EFI
+ * aware boot path, only apply hacks when loading exiting directly (breaking
+ * direct Linux EFI booting along the way - oh well).
+ */
+static bool efi_is_direct_boot = true;
+
 #ifdef CONFIG_ARM
 /*
  * The "gd" pointer lives in a register on ARM and AArch64 that we declare
@@ -1707,6 +1715,8 @@ static efi_status_t EFIAPI efi_start_image(efi_handle_t image_handle,
 
        EFI_ENTRY("%p, %p, %p", image_handle, exit_data_size, exit_data);
 
+       efi_is_direct_boot = false;
+
        /* call the image! */
        if (setjmp(&image_obj->exit_jmp)) {
                /*
@@ -1814,6 +1824,21 @@ static efi_status_t EFIAPI efi_unload_image(efi_handle_t image_handle)
        return EFI_EXIT(EFI_SUCCESS);
 }
 
+/**
+ * efi_exit_caches() - fix up caches for EFI payloads if necessary
+ */
+static void efi_exit_caches(void)
+{
+#if defined(CONFIG_ARM) && !defined(CONFIG_ARM64)
+       /*
+        * Grub on 32bit ARM needs to have caches disabled before jumping into
+        * a zImage, but does not know of all cache layers. Give it a hand.
+        */
+       if (efi_is_direct_boot)
+               cleanup_before_linux();
+#endif
+}
+
 /**
  * efi_exit_boot_services() - stop all boot services
  * @image_handle: handle of the loaded image
@@ -1867,6 +1892,9 @@ static efi_status_t EFIAPI efi_exit_boot_services(efi_handle_t image_handle,
 
        board_quiesce_devices();
 
+       /* Fix up caches for EFI payloads if necessary */
+       efi_exit_caches();
+
        /* This stops all lingering devices */
        bootm_disable_interrupts();