From 597bfc56dbed24e82b2dacaaa727d53d8ebb1a218aa81dc8c0b1e13c2a998e3e Mon Sep 17 00:00:00 2001
From: Dominique Leuenberger <dleuenberger@suse.com>
Date: Mon, 23 May 2016 14:37:12 +0000
Subject: [PATCH] Accepting request 396902 from Base:System

1

OBS-URL: https://build.opensuse.org/request/show/396902
OBS-URL: https://build.opensuse.org/package/show/openSUSE:Factory/grub2?expand=0&rev=136
---
 grub2-efi-Free-malloc-regions-on-exit.patch | 88 +++++++++++++++++++++
 grub2.changes                               |  6 ++
 grub2.spec                                  |  3 +
 3 files changed, 97 insertions(+)
 create mode 100644 grub2-efi-Free-malloc-regions-on-exit.patch

diff --git a/grub2-efi-Free-malloc-regions-on-exit.patch b/grub2-efi-Free-malloc-regions-on-exit.patch
new file mode 100644
index 0000000..30f0afa
--- /dev/null
+++ b/grub2-efi-Free-malloc-regions-on-exit.patch
@@ -0,0 +1,88 @@
+From 0c5fbc745846a53cc04ac1052cfbd35c699394c5 Mon Sep 17 00:00:00 2001
+From: Alexander Graf <agraf@suse.de>
+Date: Thu, 19 May 2016 15:01:06 +0200
+Subject: [PATCH] efi: Free malloc regions on exit
+
+When we exit grub, we don't free all the memory that we allocated earlier
+for our heap region. This can cause problems with setups where you try
+to descend the boot order using "exit" entries, such as PXE -> HD boot
+scenarios.
+
+Signed-off-by: Alexander Graf <agraf@suse.de>
+---
+ grub-core/kern/efi/init.c |  1 +
+ grub-core/kern/efi/mm.c   | 24 ++++++++++++++++++++++++
+ include/grub/efi/efi.h    |  1 +
+ 3 files changed, 26 insertions(+)
+
+Index: grub-2.02~beta3/grub-core/kern/efi/init.c
+===================================================================
+--- grub-2.02~beta3.orig/grub-core/kern/efi/init.c
++++ grub-2.02~beta3/grub-core/kern/efi/init.c
+@@ -167,4 +167,5 @@ grub_efi_fini (void)
+ {
+   grub_efidisk_fini ();
+   grub_console_fini ();
++  grub_efi_memory_fini ();
+ }
+Index: grub-2.02~beta3/grub-core/kern/efi/mm.c
+===================================================================
+--- grub-2.02~beta3.orig/grub-core/kern/efi/mm.c
++++ grub-2.02~beta3/grub-core/kern/efi/mm.c
+@@ -49,6 +49,12 @@ static grub_efi_uintn_t finish_desc_size
+ static grub_efi_uint32_t finish_desc_version;
+ int grub_efi_is_finished = 0;
+ 
++struct efi_allocation {
++	grub_uint64_t start_addr;
++	grub_uint64_t pages;
++} efi_allocated_memory[16];
++unsigned int efi_allocated_memory_idx = 0;
++
+ /* Allocate pages below a specified address */
+ void *
+ grub_efi_allocate_pages_max (grub_efi_physical_address_t max,
+@@ -440,6 +446,13 @@ add_memory_regions (grub_efi_memory_desc
+ 		    (void *) ((grub_addr_t) start),
+ 		    (unsigned) pages);
+ 
++      /* Track up to 16 regions that we allocate from */
++      if (efi_allocated_memory_idx < ARRAY_SIZE(efi_allocated_memory)) {
++        efi_allocated_memory[efi_allocated_memory_idx].start_addr = start;
++        efi_allocated_memory[efi_allocated_memory_idx].pages = pages;
++        efi_allocated_memory_idx++;
++      }
++
+       grub_mm_init_region (addr, PAGES_TO_BYTES (pages));
+ 
+       required_pages -= pages;
+@@ -451,6 +464,17 @@ add_memory_regions (grub_efi_memory_desc
+     grub_fatal ("too little memory");
+ }
+ 
++void
++grub_efi_memory_fini (void)
++{
++  unsigned int i;
++
++  for (i = 0; i < efi_allocated_memory_idx; i++) {
++    grub_efi_free_pages (efi_allocated_memory[i].start_addr,
++                         efi_allocated_memory[i].pages);
++  }
++}
++
+ #if 0
+ /* Print the memory map.  */
+ static void
+Index: grub-2.02~beta3/include/grub/efi/efi.h
+===================================================================
+--- grub-2.02~beta3.orig/include/grub/efi/efi.h
++++ grub-2.02~beta3/include/grub/efi/efi.h
+@@ -51,6 +51,7 @@ EXPORT_FUNC(grub_efi_get_memory_map) (gr
+ 				      grub_efi_uintn_t *map_key,
+ 				      grub_efi_uintn_t *descriptor_size,
+ 				      grub_efi_uint32_t *descriptor_version);
++void grub_efi_memory_fini (void);
+ grub_efi_loaded_image_t *EXPORT_FUNC(grub_efi_get_loaded_image) (grub_efi_handle_t image_handle);
+ void EXPORT_FUNC(grub_efi_print_device_path) (grub_efi_device_path_t *dp);
+ char *EXPORT_FUNC(grub_efi_get_filename) (grub_efi_device_path_t *dp);
diff --git a/grub2.changes b/grub2.changes
index de6db49..ee77b17 100644
--- a/grub2.changes
+++ b/grub2.changes
@@ -1,3 +1,9 @@
+-------------------------------------------------------------------
+Thu May 19 14:56:53 UTC 2016 - agraf@suse.com
+
+- Add patch to free memory on exit in efi environments (bsc#980739)
+  * grub2-efi-Free-malloc-regions-on-exit.patch
+
 -------------------------------------------------------------------
 Mon May  2 13:25:02 UTC 2016 - olaf@aepfle.de
 
diff --git a/grub2.spec b/grub2.spec
index f465098..42e9824 100644
--- a/grub2.spec
+++ b/grub2.spec
@@ -203,6 +203,8 @@ Patch131:       0002-arm-efi-Use-fdt-from-firmware-when-available.patch
 # Hidden menu entry and hotkey "t" for text console
 Patch140:       grub2-Add-hidden-menu-entries.patch
 Patch141:       grub2-SUSE-Add-the-t-hotkey.patch
+# EFI free memory on exit fix (bsc#980739)
+Patch150:       grub2-efi-Free-malloc-regions-on-exit.patch
 # PPC64 LE support
 Patch205:       grub2-ppc64le-disable-video.patch
 Patch207:       grub2-ppc64le-memory-map.patch
@@ -426,6 +428,7 @@ mv po/grub.pot po/%{name}.pot
 %patch131 -p1
 %patch140 -p1
 %patch141 -p1
+%patch150 -p1
 %patch205 -p1
 %patch207 -p1
 %patch233 -p1