[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#930420: marked as done (stretch-pu: package grub2/2.02~beta3-5+deb9u2)



Your message dated Sat, 07 Sep 2019 14:37:11 +0100
with message-id <17351b82f829eb6917f78885cb849c4060b0a4a6.camel@adam-barratt.org.uk>
and subject line Closing bugs for fixes included in 9.10 point release
has caused the Debian Bug report #930420,
regarding stretch-pu: package grub2/2.02~beta3-5+deb9u2
to be marked as done.

This means that you claim that the problem has been dealt with.
If this is not the case it is now your responsibility to reopen the
Bug report if necessary, and/or fix the problem forthwith.

(NB: If you are a system administrator and have no idea what this
message is talking about, this may indicate a serious mail system
misconfiguration somewhere. Please contact owner@bugs.debian.org
immediately.)


-- 
930420: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=930420
Debian Bug Tracking System
Contact owner@bugs.debian.org with problems
--- Begin Message ---
Package: release.debian.org
Severity: normal
Tags: stretch
User: release.debian.org@packages.debian.org
Usertags: pu

I'd like to upload an update to stretch's grub2 which adds support for
booting Xen on UEFI hosts.  This consists of four straight cherry-picks
from upstream (somewhat complex, but mostly confined to the multiboot
loader so IMO low-risk for other boot methods) and one cherry-pick of a
an upstream backport that I'd previously done for buster.  It was
requested by and has been tested by an upstream Xen developer.  The
proposed debdiff is attached.

Thanks,

-- 
Colin Watson                                       [cjwatson@debian.org]
diff -Nru grub2-2.02~beta3/debian/.git-dpm grub2-2.02~beta3/debian/.git-dpm
--- grub2-2.02~beta3/debian/.git-dpm	2018-10-28 19:18:13.000000000 +0000
+++ grub2-2.02~beta3/debian/.git-dpm	2019-06-12 12:20:28.000000000 +0100
@@ -1,6 +1,6 @@
 # see git-dpm(1) from git-dpm package
-f088c5a77750ef243888de09fd8cc979da9244bb
-f088c5a77750ef243888de09fd8cc979da9244bb
+23439d60d742949cee70df3c1b84ac61c9ce2c0d
+23439d60d742949cee70df3c1b84ac61c9ce2c0d
 422889f9199d539926099fc5c1ceeeda51ab7f53
 422889f9199d539926099fc5c1ceeeda51ab7f53
 grub2_2.02~beta3.orig.tar.xz
diff -Nru grub2-2.02~beta3/debian/changelog grub2-2.02~beta3/debian/changelog
--- grub2-2.02~beta3/debian/changelog	2018-10-28 19:18:13.000000000 +0000
+++ grub2-2.02~beta3/debian/changelog	2019-06-12 12:20:51.000000000 +0100
@@ -1,3 +1,16 @@
+grub2 (2.02~beta3-5+deb9u2) stable; urgency=medium
+
+  * Cherry-pick upstream patches for Xen UEFI support (closes: #930028):
+    - i386/relocator: Add grub_relocator64_efi relocator
+    - multiboot2: Add tags used to pass ImageHandle to loaded image
+    - multiboot2: Do not pass memory maps to image if EFI boot services are
+      enabled
+    - multiboot2: Add support for relocatable images
+    - Use grub-file to figure out whether multiboot2 should be used for
+      Xen.gz
+
+ -- Colin Watson <cjwatson@debian.org>  Wed, 12 Jun 2019 12:20:51 +0100
+
 grub2 (2.02~beta3-5+deb9u1) stable; urgency=medium
 
   * grub-mknetdir: Add support for ARM64 EFI (closes: #871772).
diff -Nru grub2-2.02~beta3/debian/patches/add-grub_relocator64_efi-relocator.patch grub2-2.02~beta3/debian/patches/add-grub_relocator64_efi-relocator.patch
--- grub2-2.02~beta3/debian/patches/add-grub_relocator64_efi-relocator.patch	1970-01-01 01:00:00.000000000 +0100
+++ grub2-2.02~beta3/debian/patches/add-grub_relocator64_efi-relocator.patch	2019-06-12 12:20:28.000000000 +0100
@@ -0,0 +1,360 @@
+From 94f7fe2201bc37170b7cf4f18378386b15c6955c Mon Sep 17 00:00:00 2001
+From: Daniel Kiper <daniel.kiper@oracle.com>
+Date: Fri, 17 Jul 2015 19:43:42 +0200
+Subject: i386/relocator: Add grub_relocator64_efi relocator
+
+Add grub_relocator64_efi relocator. It will be used on EFI 64-bit platforms
+when multiboot2 compatible image requests MULTIBOOT_TAG_TYPE_EFI_BS. Relocator
+will set lower parts of %rax and %rbx accordingly to multiboot2 specification.
+On the other hand processor mode, just before jumping into loaded image, will
+be set accordingly to Unified Extensible Firmware Interface Specification,
+Version 2.4 Errata B, section 2.3.4, x64 Platforms, boot services. This way
+loaded image will be able to use EFI boot services without any issues.
+
+Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>
+Reviewed-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
+Reviewed-by: Vladimir Serbinenko <phcoder@gmail.com>
+
+Origin: upstream, https://git.savannah.gnu.org/cgit/grub.git/commit/?id=9862b241212b25ee23f60f5bcc4277d2289eaaf9
+Bug-Debian: https://bugs.debian.org/930028
+Last-Update: 2019-06-12
+
+Patch-Name: add-grub_relocator64_efi-relocator.patch
+---
+ grub-core/Makefile.core.def          |  1 +
+ grub-core/lib/i386/relocator64.S     | 11 +++++
+ grub-core/lib/x86_64/efi/relocator.c | 80 ++++++++++++++++++++++++++++++++++++
+ grub-core/loader/multiboot.c         | 51 ++++++++++++++++++++---
+ grub-core/loader/multiboot_mbi2.c    | 19 +++++++--
+ include/grub/i386/multiboot.h        | 11 +++++
+ include/grub/i386/relocator.h        | 21 ++++++++++
+ include/multiboot2.h                 |  1 +
+ 8 files changed, 186 insertions(+), 9 deletions(-)
+ create mode 100644 grub-core/lib/x86_64/efi/relocator.c
+
+diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def
+index 6b047109b..8052f68d3 100644
+--- a/grub-core/Makefile.core.def
++++ b/grub-core/Makefile.core.def
+@@ -1540,6 +1540,7 @@ module = {
+   i386_xen = lib/i386/xen/relocator.S;
+   x86_64_xen = lib/x86_64/xen/relocator.S;
+   xen = lib/i386/relocator_common_c.c;
++  x86_64_efi = lib/x86_64/efi/relocator.c;
+ 
+   extra_dist = lib/i386/relocator_common.S;
+   extra_dist = kern/powerpc/cache_flush.S;
+diff --git a/grub-core/lib/i386/relocator64.S b/grub-core/lib/i386/relocator64.S
+index e4648d818..75725cf75 100644
+--- a/grub-core/lib/i386/relocator64.S
++++ b/grub-core/lib/i386/relocator64.S
+@@ -73,6 +73,14 @@ VARIABLE(grub_relocator64_rsp)
+ 
+ 	movq	%rax, %rsp
+ 
++	/*
++	 * Here is grub_relocator64_efi_start() entry point.
++	 * Following code is shared between grub_relocator64_efi_start()
++	 * and grub_relocator64_start().
++	 *
++	 * Think twice before changing anything below!!!
++	 */
++VARIABLE(grub_relocator64_efi_start)
+ 	/* mov imm64, %rax */
+ 	.byte 	0x48
+ 	.byte	0xb8
+@@ -120,6 +128,9 @@ LOCAL(jump_addr):
+ VARIABLE(grub_relocator64_rip)
+ 	.quad	0
+ 
++	/* Here grub_relocator64_efi_start() ends. Ufff... */
++VARIABLE(grub_relocator64_efi_end)
++
+ #ifndef __x86_64__
+ 	.p2align	4
+ LOCAL(gdt):
+diff --git a/grub-core/lib/x86_64/efi/relocator.c b/grub-core/lib/x86_64/efi/relocator.c
+new file mode 100644
+index 000000000..3caef7a40
+--- /dev/null
++++ b/grub-core/lib/x86_64/efi/relocator.c
+@@ -0,0 +1,80 @@
++/*
++ *  GRUB  --  GRand Unified Bootloader
++ *  Copyright (C) 2009  Free Software Foundation, Inc.
++ *  Copyright (C) 2016  Oracle and/or its affiliates. All rights reserved.
++ *
++ *  GRUB is free software: you can redistribute it and/or modify
++ *  it under the terms of the GNU General Public License as published by
++ *  the Free Software Foundation, either version 3 of the License, or
++ *  (at your option) any later version.
++ *
++ *  GRUB is distributed in the hope that it will be useful,
++ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ *  GNU General Public License for more details.
++ *
++ *  You should have received a copy of the GNU General Public License
++ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
++ */
++
++#include <grub/mm.h>
++#include <grub/misc.h>
++
++#include <grub/types.h>
++#include <grub/err.h>
++
++#include <grub/i386/relocator.h>
++#include <grub/relocator_private.h>
++
++extern grub_uint64_t grub_relocator64_rax;
++extern grub_uint64_t grub_relocator64_rbx;
++extern grub_uint64_t grub_relocator64_rcx;
++extern grub_uint64_t grub_relocator64_rdx;
++extern grub_uint64_t grub_relocator64_rip;
++extern grub_uint64_t grub_relocator64_rsi;
++
++extern grub_uint8_t grub_relocator64_efi_start;
++extern grub_uint8_t grub_relocator64_efi_end;
++
++#define RELOCATOR_SIZEOF(x)	(&grub_relocator##x##_end - &grub_relocator##x##_start)
++
++grub_err_t
++grub_relocator64_efi_boot (struct grub_relocator *rel,
++			   struct grub_relocator64_efi_state state)
++{
++  grub_err_t err;
++  void *relst;
++  grub_relocator_chunk_t ch;
++
++  /*
++   * 64-bit relocator code may live above 4 GiB quite well.
++   * However, I do not want ask for problems. Just in case.
++   */
++  err = grub_relocator_alloc_chunk_align (rel, &ch, 0,
++					  0x100000000 - RELOCATOR_SIZEOF (64_efi),
++					  RELOCATOR_SIZEOF (64_efi), 16,
++					  GRUB_RELOCATOR_PREFERENCE_NONE, 1);
++  if (err)
++    return err;
++
++  /* Do not touch %rsp! It points to EFI created stack. */
++  grub_relocator64_rax = state.rax;
++  grub_relocator64_rbx = state.rbx;
++  grub_relocator64_rcx = state.rcx;
++  grub_relocator64_rdx = state.rdx;
++  grub_relocator64_rip = state.rip;
++  grub_relocator64_rsi = state.rsi;
++
++  grub_memmove (get_virtual_current_address (ch), &grub_relocator64_efi_start,
++		RELOCATOR_SIZEOF (64_efi));
++
++  err = grub_relocator_prepare_relocs (rel, get_physical_target_address (ch),
++				       &relst, NULL);
++  if (err)
++    return err;
++
++  ((void (*) (void)) relst) ();
++
++  /* Not reached.  */
++  return GRUB_ERR_NONE;
++}
+diff --git a/grub-core/loader/multiboot.c b/grub-core/loader/multiboot.c
+index 73aa0aa12..18038fd31 100644
+--- a/grub-core/loader/multiboot.c
++++ b/grub-core/loader/multiboot.c
+@@ -118,6 +118,48 @@ grub_multiboot_set_video_mode (void)
+   return err;
+ }
+ 
++#ifdef GRUB_MACHINE_EFI
++#ifdef __x86_64__
++#define grub_relocator_efi_boot		grub_relocator64_efi_boot
++#define grub_relocator_efi_state	grub_relocator64_efi_state
++#endif
++#endif
++
++#ifdef grub_relocator_efi_boot
++static void
++efi_boot (struct grub_relocator *rel,
++	  grub_uint32_t target)
++{
++  struct grub_relocator_efi_state state_efi = MULTIBOOT_EFI_INITIAL_STATE;
++
++  state_efi.MULTIBOOT_EFI_ENTRY_REGISTER = grub_multiboot_payload_eip;
++  state_efi.MULTIBOOT_EFI_MBI_REGISTER = target;
++
++  grub_relocator_efi_boot (rel, state_efi);
++}
++#else
++#define grub_efi_is_finished	1
++static void
++efi_boot (struct grub_relocator *rel __attribute__ ((unused)),
++	  grub_uint32_t target __attribute__ ((unused)))
++{
++}
++#endif
++
++#if defined (__i386__) || defined (__x86_64__)
++static void
++normal_boot (struct grub_relocator *rel, struct grub_relocator32_state state)
++{
++  grub_relocator32_boot (rel, state, 0);
++}
++#else
++static void
++normal_boot (struct grub_relocator *rel, struct grub_relocator32_state state)
++{
++  grub_relocator32_boot (rel, state);
++}
++#endif
++
+ static grub_err_t
+ grub_multiboot_boot (void)
+ {
+@@ -131,11 +173,10 @@ grub_multiboot_boot (void)
+   if (err)
+     return err;
+ 
+-#if defined (__i386__) || defined (__x86_64__)
+-  grub_relocator32_boot (grub_multiboot_relocator, state, 0);
+-#else
+-  grub_relocator32_boot (grub_multiboot_relocator, state);
+-#endif
++  if (grub_efi_is_finished)
++    normal_boot (grub_multiboot_relocator, state);
++  else
++    efi_boot (grub_multiboot_relocator, state.MULTIBOOT_MBI_REGISTER);
+ 
+   /* Not reached.  */
+   return GRUB_ERR_NONE;
+diff --git a/grub-core/loader/multiboot_mbi2.c b/grub-core/loader/multiboot_mbi2.c
+index f147d674d..a3dca9011 100644
+--- a/grub-core/loader/multiboot_mbi2.c
++++ b/grub-core/loader/multiboot_mbi2.c
+@@ -107,8 +107,8 @@ grub_multiboot_load (grub_file_t file, const char *filename)
+   grub_err_t err;
+   struct multiboot_header_tag *tag;
+   struct multiboot_header_tag_address *addr_tag = NULL;
+-  int entry_specified = 0;
+-  grub_addr_t entry = 0;
++  int entry_specified = 0, efi_entry_specified = 0;
++  grub_addr_t entry = 0, efi_entry = 0;
+   grub_uint32_t console_required = 0;
+   struct multiboot_header_tag_framebuffer *fbtag = NULL;
+   int accepted_consoles = GRUB_MULTIBOOT_CONSOLE_EGA_TEXT;
+@@ -192,6 +192,13 @@ grub_multiboot_load (grub_file_t file, const char *filename)
+ 	entry = ((struct multiboot_header_tag_entry_address *) tag)->entry_addr;
+ 	break;
+ 
++      case MULTIBOOT_HEADER_TAG_ENTRY_ADDRESS_EFI64:
++#if defined (GRUB_MACHINE_EFI) && defined (__x86_64__)
++	efi_entry_specified = 1;
++	efi_entry = ((struct multiboot_header_tag_entry_address *) tag)->entry_addr;
++#endif
++	break;
++
+       case MULTIBOOT_HEADER_TAG_CONSOLE_FLAGS:
+ 	if (!(((struct multiboot_header_tag_console_flags *) tag)->console_flags
+ 	    & MULTIBOOT_CONSOLE_FLAGS_EGA_TEXT_SUPPORTED))
+@@ -211,7 +218,9 @@ grub_multiboot_load (grub_file_t file, const char *filename)
+ 	break;
+ 
+       case MULTIBOOT_HEADER_TAG_EFI_BS:
++#ifdef GRUB_MACHINE_EFI
+ 	keep_bs = 1;
++#endif
+ 	break;
+ 
+       default:
+@@ -224,7 +233,7 @@ grub_multiboot_load (grub_file_t file, const char *filename)
+ 	break;
+       }
+ 
+-  if (addr_tag && !entry_specified)
++  if (addr_tag && !entry_specified && !(keep_bs && efi_entry_specified))
+     {
+       grub_free (buffer);
+       return grub_error (GRUB_ERR_UNKNOWN_OS,
+@@ -287,7 +296,9 @@ grub_multiboot_load (grub_file_t file, const char *filename)
+ 	}
+     }
+ 
+-  if (entry_specified)
++  if (keep_bs && efi_entry_specified)
++    grub_multiboot_payload_eip = efi_entry;
++  else if (entry_specified)
+     grub_multiboot_payload_eip = entry;
+ 
+   if (fbtag)
+diff --git a/include/grub/i386/multiboot.h b/include/grub/i386/multiboot.h
+index a1b94883d..807a1de27 100644
+--- a/include/grub/i386/multiboot.h
++++ b/include/grub/i386/multiboot.h
+@@ -30,6 +30,17 @@
+ #define MULTIBOOT_MBI_REGISTER ebx
+ #define MULTIBOOT_ARCHITECTURE_CURRENT MULTIBOOT_ARCHITECTURE_I386
+ 
++#ifdef GRUB_MACHINE_EFI
++#ifdef __x86_64__
++#define MULTIBOOT_EFI_INITIAL_STATE  { .rax = MULTIBOOT_BOOTLOADER_MAGIC,	\
++    .rcx = 0,									\
++    .rdx = 0,									\
++      }
++#define MULTIBOOT_EFI_ENTRY_REGISTER rip
++#define MULTIBOOT_EFI_MBI_REGISTER rbx
++#endif
++#endif
++
+ #define MULTIBOOT_ELF32_MACHINE EM_386
+ #define MULTIBOOT_ELF64_MACHINE EM_X86_64
+ 
+diff --git a/include/grub/i386/relocator.h b/include/grub/i386/relocator.h
+index 5f89a7ec8..2a56c3b54 100644
+--- a/include/grub/i386/relocator.h
++++ b/include/grub/i386/relocator.h
+@@ -65,6 +65,20 @@ struct grub_relocator64_state
+   grub_addr_t cr3;
+ };
+ 
++#ifdef GRUB_MACHINE_EFI
++#ifdef __x86_64__
++struct grub_relocator64_efi_state
++{
++  grub_uint64_t rax;
++  grub_uint64_t rbx;
++  grub_uint64_t rcx;
++  grub_uint64_t rdx;
++  grub_uint64_t rip;
++  grub_uint64_t rsi;
++};
++#endif
++#endif
++
+ grub_err_t grub_relocator16_boot (struct grub_relocator *rel,
+ 				  struct grub_relocator16_state state);
+ 
+@@ -76,4 +90,11 @@ grub_err_t grub_relocator64_boot (struct grub_relocator *rel,
+ 				  struct grub_relocator64_state state,
+ 				  grub_addr_t min_addr, grub_addr_t max_addr);
+ 
++#ifdef GRUB_MACHINE_EFI
++#ifdef __x86_64__
++grub_err_t grub_relocator64_efi_boot (struct grub_relocator *rel,
++				      struct grub_relocator64_efi_state state);
++#endif
++#endif
++
+ #endif /* ! GRUB_RELOCATOR_CPU_HEADER */
+diff --git a/include/multiboot2.h b/include/multiboot2.h
+index 9d4862759..d96aa4041 100644
+--- a/include/multiboot2.h
++++ b/include/multiboot2.h
+@@ -69,6 +69,7 @@
+ #define MULTIBOOT_HEADER_TAG_FRAMEBUFFER  5
+ #define MULTIBOOT_HEADER_TAG_MODULE_ALIGN  6
+ #define MULTIBOOT_HEADER_TAG_EFI_BS  7
++#define MULTIBOOT_HEADER_TAG_ENTRY_ADDRESS_EFI64  9
+ 
+ #define MULTIBOOT_ARCHITECTURE_I386  0
+ #define MULTIBOOT_ARCHITECTURE_MIPS32  4
diff -Nru grub2-2.02~beta3/debian/patches/multiboot2-add-ImageHandle-tags.patch grub2-2.02~beta3/debian/patches/multiboot2-add-ImageHandle-tags.patch
--- grub2-2.02~beta3/debian/patches/multiboot2-add-ImageHandle-tags.patch	1970-01-01 01:00:00.000000000 +0100
+++ grub2-2.02~beta3/debian/patches/multiboot2-add-ImageHandle-tags.patch	2019-06-12 12:20:28.000000000 +0100
@@ -0,0 +1,128 @@
+From e5f294327082bb3990e81bb6e9a7f64316c7a1ac Mon Sep 17 00:00:00 2001
+From: Daniel Kiper <daniel.kiper@oracle.com>
+Date: Thu, 20 Nov 2014 00:09:54 +0100
+Subject: multiboot2: Add tags used to pass ImageHandle to loaded image
+
+Add tags used to pass ImageHandle to loaded image if requested.
+It is used by at least ExitBootServices() function.
+
+Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>
+Reviewed-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
+Reviewed-by: Vladimir Serbinenko <phcoder@gmail.com>
+
+Origin: upstream, https://git.savannah.gnu.org/cgit/grub.git/commit/?id=ba89c19f4995e01e3b84c6680f12f14bf0f6a38b
+Bug-Debian: https://bugs.debian.org/930028
+Last-Update: 2019-06-12
+
+Patch-Name: multiboot2-add-ImageHandle-tags.patch
+---
+ grub-core/loader/multiboot_mbi2.c | 42 ++++++++++++++++++++++++++++++++-------
+ include/multiboot2.h              | 16 +++++++++++++++
+ 2 files changed, 51 insertions(+), 7 deletions(-)
+
+diff --git a/grub-core/loader/multiboot_mbi2.c b/grub-core/loader/multiboot_mbi2.c
+index a3dca9011..6c044024e 100644
+--- a/grub-core/loader/multiboot_mbi2.c
++++ b/grub-core/loader/multiboot_mbi2.c
+@@ -172,6 +172,8 @@ grub_multiboot_load (grub_file_t file, const char *filename)
+ 	      case MULTIBOOT_TAG_TYPE_NETWORK:
+ 	      case MULTIBOOT_TAG_TYPE_EFI_MMAP:
+ 	      case MULTIBOOT_TAG_TYPE_EFI_BS:
++	      case MULTIBOOT_TAG_TYPE_EFI32_IH:
++	      case MULTIBOOT_TAG_TYPE_EFI64_IH:
+ 		break;
+ 
+ 	      default:
+@@ -407,13 +409,15 @@ grub_multiboot_get_mbi_size (void)
+ 		 + grub_get_multiboot_mmap_count ()
+ 		 * sizeof (struct multiboot_mmap_entry)), MULTIBOOT_TAG_ALIGN)
+     + ALIGN_UP (sizeof (struct multiboot_tag_framebuffer), MULTIBOOT_TAG_ALIGN)
+-    + ALIGN_UP (sizeof (struct multiboot_tag_efi32), MULTIBOOT_TAG_ALIGN)
+-    + ALIGN_UP (sizeof (struct multiboot_tag_efi64), MULTIBOOT_TAG_ALIGN)
+     + ALIGN_UP (sizeof (struct multiboot_tag_old_acpi)
+ 		+ sizeof (struct grub_acpi_rsdp_v10), MULTIBOOT_TAG_ALIGN)
+     + acpiv2_size ()
+     + net_size ()
+ #ifdef GRUB_MACHINE_EFI
++    + ALIGN_UP (sizeof (struct multiboot_tag_efi32), MULTIBOOT_TAG_ALIGN)
++    + ALIGN_UP (sizeof (struct multiboot_tag_efi32_ih), MULTIBOOT_TAG_ALIGN)
++    + ALIGN_UP (sizeof (struct multiboot_tag_efi64), MULTIBOOT_TAG_ALIGN)
++    + ALIGN_UP (sizeof (struct multiboot_tag_efi64_ih), MULTIBOOT_TAG_ALIGN)
+     + ALIGN_UP (sizeof (struct multiboot_tag_efi_mmap)
+ 		+ efi_mmap_size, MULTIBOOT_TAG_ALIGN)
+ #endif
+@@ -907,11 +911,35 @@ grub_multiboot_make_mbi (grub_uint32_t *target)
+ 
+   if (keep_bs)
+     {
+-      struct multiboot_tag *tag = (struct multiboot_tag *) ptrorig;
+-      tag->type = MULTIBOOT_TAG_TYPE_EFI_BS;
+-      tag->size = sizeof (struct multiboot_tag);
+-      ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN)
+-	/ sizeof (grub_properly_aligned_t);
++      {
++	struct multiboot_tag *tag = (struct multiboot_tag *) ptrorig;
++	tag->type = MULTIBOOT_TAG_TYPE_EFI_BS;
++	tag->size = sizeof (struct multiboot_tag);
++	ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN)
++	  / sizeof (grub_properly_aligned_t);
++      }
++
++#ifdef __i386__
++      {
++	struct multiboot_tag_efi32_ih *tag = (struct multiboot_tag_efi32_ih *) ptrorig;
++	tag->type = MULTIBOOT_TAG_TYPE_EFI32_IH;
++	tag->size = sizeof (struct multiboot_tag_efi32_ih);
++	tag->pointer = (grub_addr_t) grub_efi_image_handle;
++	ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN)
++	  / sizeof (grub_properly_aligned_t);
++      }
++#endif
++
++#ifdef __x86_64__
++      {
++	struct multiboot_tag_efi64_ih *tag = (struct multiboot_tag_efi64_ih *) ptrorig;
++	tag->type = MULTIBOOT_TAG_TYPE_EFI64_IH;
++	tag->size = sizeof (struct multiboot_tag_efi64_ih);
++	tag->pointer = (grub_addr_t) grub_efi_image_handle;
++	ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN)
++	  / sizeof (grub_properly_aligned_t);
++      }
++#endif
+     }
+ #endif
+ 
+diff --git a/include/multiboot2.h b/include/multiboot2.h
+index d96aa4041..36a174fd0 100644
+--- a/include/multiboot2.h
++++ b/include/multiboot2.h
+@@ -60,6 +60,8 @@
+ #define MULTIBOOT_TAG_TYPE_NETWORK           16
+ #define MULTIBOOT_TAG_TYPE_EFI_MMAP          17
+ #define MULTIBOOT_TAG_TYPE_EFI_BS            18
++#define MULTIBOOT_TAG_TYPE_EFI32_IH          19
++#define MULTIBOOT_TAG_TYPE_EFI64_IH          20
+ 
+ #define MULTIBOOT_HEADER_TAG_END  0
+ #define MULTIBOOT_HEADER_TAG_INFORMATION_REQUEST  1
+@@ -371,6 +373,20 @@ struct multiboot_tag_efi_mmap
+   multiboot_uint8_t efi_mmap[0];
+ }; 
+ 
++struct multiboot_tag_efi32_ih
++{
++  multiboot_uint32_t type;
++  multiboot_uint32_t size;
++  multiboot_uint32_t pointer;
++};
++
++struct multiboot_tag_efi64_ih
++{
++  multiboot_uint32_t type;
++  multiboot_uint32_t size;
++  multiboot_uint64_t pointer;
++};
++
+ #endif /* ! ASM_FILE */
+ 
+ #endif /* ! MULTIBOOT_HEADER */
diff -Nru grub2-2.02~beta3/debian/patches/multiboot2-do-not-pass-mmaps-if-efi-boot-services.patch grub2-2.02~beta3/debian/patches/multiboot2-do-not-pass-mmaps-if-efi-boot-services.patch
--- grub2-2.02~beta3/debian/patches/multiboot2-do-not-pass-mmaps-if-efi-boot-services.patch	1970-01-01 01:00:00.000000000 +0100
+++ grub2-2.02~beta3/debian/patches/multiboot2-do-not-pass-mmaps-if-efi-boot-services.patch	2019-06-12 12:20:28.000000000 +0100
@@ -0,0 +1,135 @@
+From be9fee51de2cff287aeff055e2eb2fd98a0d187e Mon Sep 17 00:00:00 2001
+From: Daniel Kiper <daniel.kiper@oracle.com>
+Date: Sat, 18 Jul 2015 00:09:31 +0200
+Subject: multiboot2: Do not pass memory maps to image if EFI boot services are
+ enabled
+
+If image requested EFI boot services then skip multiboot2 memory maps.
+Main reason for not providing maps is because they will likely be
+invalid. We do a few allocations after filling them, e.g. for relocator
+needs. Usually we do not care as we would have finished boot services.
+If we keep boot services then it is easier/safer to not provide maps.
+However, if image needs memory maps and they are not provided by bootloader
+then it should get itself just before ExitBootServices() call.
+
+Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>
+Reviewed-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
+Reviewed-by: Vladimir Serbinenko <phcoder@gmail.com>
+
+Origin: upstream, https://git.savannah.gnu.org/cgit/grub.git/commit/?id=f2b6c20a258b328ae8717cd5624d7b039328bcc0
+Bug-Debian: https://bugs.debian.org/930028
+Last-Update: 2019-06-12
+
+Patch-Name: multiboot2-do-not-pass-mmaps-if-efi-boot-services.patch
+---
+ grub-core/loader/multiboot_mbi2.c | 73 +++++++++++++++++++--------------------
+ 1 file changed, 36 insertions(+), 37 deletions(-)
+
+diff --git a/grub-core/loader/multiboot_mbi2.c b/grub-core/loader/multiboot_mbi2.c
+index 6c044024e..ad1553ba7 100644
+--- a/grub-core/loader/multiboot_mbi2.c
++++ b/grub-core/loader/multiboot_mbi2.c
+@@ -390,7 +390,7 @@ static grub_size_t
+ grub_multiboot_get_mbi_size (void)
+ {
+ #ifdef GRUB_MACHINE_EFI
+-  if (!efi_mmap_size)
++  if (!keep_bs && !efi_mmap_size)
+     find_efi_mmap_size ();    
+ #endif
+   return 2 * sizeof (grub_uint32_t) + sizeof (struct multiboot_tag)
+@@ -755,12 +755,13 @@ grub_multiboot_make_mbi (grub_uint32_t *target)
+       }
+   }
+ 
+-  {
+-    struct multiboot_tag_mmap *tag = (struct multiboot_tag_mmap *) ptrorig;
+-    grub_fill_multiboot_mmap (tag);
+-    ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN)
+-      / sizeof (grub_properly_aligned_t);
+-  }
++  if (!keep_bs)
++    {
++      struct multiboot_tag_mmap *tag = (struct multiboot_tag_mmap *) ptrorig;
++      grub_fill_multiboot_mmap (tag);
++      ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN)
++	/ sizeof (grub_properly_aligned_t);
++    }
+ 
+   {
+     struct multiboot_tag_elf_sections *tag
+@@ -776,18 +777,19 @@ grub_multiboot_make_mbi (grub_uint32_t *target)
+       / sizeof (grub_properly_aligned_t);
+   }
+ 
+-  {
+-    struct multiboot_tag_basic_meminfo *tag
+-      = (struct multiboot_tag_basic_meminfo *) ptrorig;
+-    tag->type = MULTIBOOT_TAG_TYPE_BASIC_MEMINFO;
+-    tag->size = sizeof (struct multiboot_tag_basic_meminfo); 
+-
+-    /* Convert from bytes to kilobytes.  */
+-    tag->mem_lower = grub_mmap_get_lower () / 1024;
+-    tag->mem_upper = grub_mmap_get_upper () / 1024;
+-    ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN)
+-       / sizeof (grub_properly_aligned_t);
+-  }
++  if (!keep_bs)
++    {
++      struct multiboot_tag_basic_meminfo *tag
++	= (struct multiboot_tag_basic_meminfo *) ptrorig;
++      tag->type = MULTIBOOT_TAG_TYPE_BASIC_MEMINFO;
++      tag->size = sizeof (struct multiboot_tag_basic_meminfo);
++
++      /* Convert from bytes to kilobytes.  */
++      tag->mem_lower = grub_mmap_get_lower () / 1024;
++      tag->mem_upper = grub_mmap_get_upper () / 1024;
++      ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN)
++	/ sizeof (grub_properly_aligned_t);
++    }
+ 
+   {
+     struct grub_net_network_level_interface *net;
+@@ -886,27 +888,24 @@ grub_multiboot_make_mbi (grub_uint32_t *target)
+     grub_efi_uintn_t efi_desc_size;
+     grub_efi_uint32_t efi_desc_version;
+ 
+-    tag->type = MULTIBOOT_TAG_TYPE_EFI_MMAP;
+-    tag->size = sizeof (*tag) + efi_mmap_size;
+-
+     if (!keep_bs)
+-      err = grub_efi_finish_boot_services (&efi_mmap_size, tag->efi_mmap, NULL,
+-					   &efi_desc_size, &efi_desc_version);
+-    else
+       {
+-	if (grub_efi_get_memory_map (&efi_mmap_size, (void *) tag->efi_mmap,
+-				     NULL,
+-				     &efi_desc_size, &efi_desc_version) <= 0)
+-	  err = grub_error (GRUB_ERR_IO, "couldn't retrieve memory map");
+-      }
+-    if (err)
+-      return err;
+-    tag->descr_size = efi_desc_size;
+-    tag->descr_vers = efi_desc_version;
+-    tag->size = sizeof (*tag) + efi_mmap_size;
++	tag->type = MULTIBOOT_TAG_TYPE_EFI_MMAP;
++	tag->size = sizeof (*tag) + efi_mmap_size;
+ 
+-    ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN)
+-      / sizeof (grub_properly_aligned_t);
++	err = grub_efi_finish_boot_services (&efi_mmap_size, tag->efi_mmap, NULL,
++					     &efi_desc_size, &efi_desc_version);
++
++	if (err)
++	  return err;
++
++	tag->descr_size = efi_desc_size;
++	tag->descr_vers = efi_desc_version;
++	tag->size = sizeof (*tag) + efi_mmap_size;
++
++	ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN)
++	  / sizeof (grub_properly_aligned_t);
++      }
+   }
+ 
+   if (keep_bs)
diff -Nru grub2-2.02~beta3/debian/patches/multiboot2-relocatable-images.patch grub2-2.02~beta3/debian/patches/multiboot2-relocatable-images.patch
--- grub2-2.02~beta3/debian/patches/multiboot2-relocatable-images.patch	1970-01-01 01:00:00.000000000 +0100
+++ grub2-2.02~beta3/debian/patches/multiboot2-relocatable-images.patch	2019-06-12 12:20:28.000000000 +0100
@@ -0,0 +1,683 @@
+From 87c062a404117dfdca46a2210e6791012199a25b Mon Sep 17 00:00:00 2001
+From: Daniel Kiper <daniel.kiper@oracle.com>
+Date: Fri, 17 Jul 2015 21:02:09 +0200
+Subject: multiboot2: Add support for relocatable images
+
+Currently multiboot2 protocol loads image exactly at address specified in
+ELF or multiboot2 header. This solution works quite well on legacy BIOS
+platforms. It is possible because memory regions are placed at predictable
+addresses (though I was not able to find any spec which says that it is
+strong requirement, so, it looks that it is just a goodwill of hardware
+designers). However, EFI platforms are more volatile. Even if required
+memory regions live at specific addresses then they are sometimes simply
+not free (e.g. used by boot/runtime services on Dell PowerEdge R820 and
+OVMF). This means that you are not able to just set up final image
+destination on build time. You have to provide method to relocate image
+contents to real load address which is usually different than load address
+specified in ELF and multiboot2 headers.
+
+This patch provides all needed machinery to do self relocation in image code.
+First of all GRUB2 reads min_addr (min. load addr), max_addr (max. load addr),
+align (required image alignment), preference (it says which memory regions are
+preferred by image, e.g. none, low, high) from multiboot_header_tag_relocatable
+header tag contained in binary (at this stage load addresses from multiboot2
+and/or ELF headers are ignored). Later loader tries to fulfill request (not only
+that one) and if it succeeds then it informs image about real load address via
+multiboot_tag_load_base_addr tag. At this stage GRUB2 role is finished. Starting
+from now executable must cope with relocations itself using whole static and
+dynamic knowledge provided by boot loader.
+
+This patch does not provide functionality which could do relocations using
+ELF relocation data. However, I was asked by Konrad Rzeszutek Wilk and Vladimir
+'phcoder' Serbinenko to investigate that thing. It looks that relevant machinery
+could be added to existing code (including this patch) without huge effort.
+Additionally, ELF relocation could live in parallel with self relocation provided
+by this patch. However, during research I realized that first of all we should
+establish the details how ELF relocatable image should look like and how it should
+be build. At least to build proper test/example files.
+
+So, this patch just provides support for self relocatable images. If ELF file
+with relocs is loaded then GRUB2 complains loudly and ignores it. Support for
+such files will be added later.
+
+This patch was tested with Xen image which uses that functionality. However, this Xen
+feature is still under development and new patchset will be released in about 2-3 weeks.
+
+Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>
+Reviewed-by: Vladimir Serbinenko <phcoder@gmail.com>
+
+Origin: upstream, https://git.savannah.gnu.org/cgit/grub.git/commit/?id=a620876e3b32e4ea0c9a7b3541fcb9a4dd4fb9eb
+Bug-Debian: https://bugs.debian.org/930028
+Last-Update: 2019-06-12
+
+Patch-Name: multiboot2-relocatable-images.patch
+---
+ grub-core/loader/i386/multiboot_mbi.c |  13 +++-
+ grub-core/loader/multiboot.c          |  11 ++-
+ grub-core/loader/multiboot_elfxx.c    | 131 +++++++++++++++++++++-------------
+ grub-core/loader/multiboot_mbi2.c     | 122 +++++++++++++++++++++++++------
+ include/grub/multiboot.h              |  22 +++++-
+ include/multiboot2.h                  |  24 +++++++
+ 6 files changed, 244 insertions(+), 79 deletions(-)
+
+diff --git a/grub-core/loader/i386/multiboot_mbi.c b/grub-core/loader/i386/multiboot_mbi.c
+index f60b70234..fd7b41b0c 100644
+--- a/grub-core/loader/i386/multiboot_mbi.c
++++ b/grub-core/loader/i386/multiboot_mbi.c
+@@ -70,9 +70,18 @@ load_kernel (grub_file_t file, const char *filename,
+ 	     char *buffer, struct multiboot_header *header)
+ {
+   grub_err_t err;
++  mbi_load_data_t mld;
++
++  mld.file = file;
++  mld.filename = filename;
++  mld.buffer = buffer;
++  mld.mbi_ver = 1;
++  mld.relocatable = 0;
++  mld.avoid_efi_boot_services = 0;
++
+   if (grub_multiboot_quirks & GRUB_MULTIBOOT_QUIRK_BAD_KLUDGE)
+     {
+-      err = grub_multiboot_load_elf (file, filename, buffer);
++      err = grub_multiboot_load_elf (&mld);
+       if (err == GRUB_ERR_NONE) {
+ 	return GRUB_ERR_NONE;
+       }
+@@ -121,7 +130,7 @@ load_kernel (grub_file_t file, const char *filename,
+       return GRUB_ERR_NONE;
+     }
+ 
+-  return grub_multiboot_load_elf (file, filename, buffer);
++  return grub_multiboot_load_elf (&mld);
+ }
+ 
+ static struct multiboot_header *
+diff --git a/grub-core/loader/multiboot.c b/grub-core/loader/multiboot.c
+index 18038fd31..bd9d5b3e6 100644
+--- a/grub-core/loader/multiboot.c
++++ b/grub-core/loader/multiboot.c
+@@ -207,13 +207,12 @@ static grub_uint64_t highest_load;
+ 
+ /* Load ELF32 or ELF64.  */
+ grub_err_t
+-grub_multiboot_load_elf (grub_file_t file, const char *filename,
+-			 void *buffer)
++grub_multiboot_load_elf (mbi_load_data_t *mld)
+ {
+-  if (grub_multiboot_is_elf32 (buffer))
+-    return grub_multiboot_load_elf32 (file, filename, buffer);
+-  else if (grub_multiboot_is_elf64 (buffer))
+-    return grub_multiboot_load_elf64 (file, filename, buffer);
++  if (grub_multiboot_is_elf32 (mld->buffer))
++    return grub_multiboot_load_elf32 (mld);
++  else if (grub_multiboot_is_elf64 (mld->buffer))
++    return grub_multiboot_load_elf64 (mld);
+ 
+   return grub_error (GRUB_ERR_UNKNOWN_OS, N_("invalid arch-dependent ELF magic"));
+ }
+diff --git a/grub-core/loader/multiboot_elfxx.c b/grub-core/loader/multiboot_elfxx.c
+index e3a39b609..5e649ed25 100644
+--- a/grub-core/loader/multiboot_elfxx.c
++++ b/grub-core/loader/multiboot_elfxx.c
+@@ -51,11 +51,15 @@ CONCAT(grub_multiboot_is_elf, XX) (void *buffer)
+ }
+ 
+ static grub_err_t
+-CONCAT(grub_multiboot_load_elf, XX) (grub_file_t file, const char *filename, void *buffer)
++CONCAT(grub_multiboot_load_elf, XX) (mbi_load_data_t *mld)
+ {
+-  Elf_Ehdr *ehdr = (Elf_Ehdr *) buffer;
++  Elf_Ehdr *ehdr = (Elf_Ehdr *) mld->buffer;
+   char *phdr_base;
++  grub_err_t err;
++  grub_relocator_chunk_t ch;
++  grub_uint32_t load_offset, load_size;
+   int i;
++  void *source;
+ 
+   if (ehdr->e_ident[EI_MAG0] != ELFMAG0
+       || ehdr->e_ident[EI_MAG1] != ELFMAG1
+@@ -75,54 +79,86 @@ CONCAT(grub_multiboot_load_elf, XX) (grub_file_t file, const char *filename, voi
+   if (ehdr->e_phoff + (grub_uint32_t) ehdr->e_phnum * ehdr->e_phentsize > MULTIBOOT_SEARCH)
+     return grub_error (GRUB_ERR_BAD_OS, "program header at a too high offset");
+ 
+-  phdr_base = (char *) buffer + ehdr->e_phoff;
++  phdr_base = (char *) mld->buffer + ehdr->e_phoff;
+ #define phdr(i)			((Elf_Phdr *) (phdr_base + (i) * ehdr->e_phentsize))
+ 
++  mld->link_base_addr = ~0;
++
++  /* Calculate lowest and highest load address.  */
++  for (i = 0; i < ehdr->e_phnum; i++)
++    if (phdr(i)->p_type == PT_LOAD)
++      {
++	mld->link_base_addr = grub_min (mld->link_base_addr, phdr(i)->p_paddr);
++	highest_load = grub_max (highest_load, phdr(i)->p_paddr + phdr(i)->p_memsz);
++      }
++
++#ifdef MULTIBOOT_LOAD_ELF64
++  if (highest_load >= 0x100000000)
++    return grub_error (GRUB_ERR_BAD_OS, "segment crosses 4 GiB border");
++#endif
++
++  load_size = highest_load - mld->link_base_addr;
++
++  if (mld->relocatable)
++    {
++      if (load_size > mld->max_addr || mld->min_addr > mld->max_addr - load_size)
++	return grub_error (GRUB_ERR_BAD_OS, "invalid min/max address and/or load size");
++
++      err = grub_relocator_alloc_chunk_align (grub_multiboot_relocator, &ch,
++					      mld->min_addr, mld->max_addr - load_size,
++					      load_size, mld->align ? mld->align : 1,
++					      mld->preference, mld->avoid_efi_boot_services);
++    }
++  else
++    err = grub_relocator_alloc_chunk_addr (grub_multiboot_relocator, &ch,
++					   mld->link_base_addr, load_size);
++
++  if (err)
++    {
++      grub_dprintf ("multiboot_loader", "Cannot allocate memory for OS image\n");
++      return err;
++    }
++
++  mld->load_base_addr = get_physical_target_address (ch);
++  source = get_virtual_current_address (ch);
++
++  grub_dprintf ("multiboot_loader", "link_base_addr=0x%x, load_base_addr=0x%x, "
++		"load_size=0x%x, relocatable=%d\n", mld->link_base_addr,
++		mld->load_base_addr, load_size, mld->relocatable);
++
++  if (mld->relocatable)
++    grub_dprintf ("multiboot_loader", "align=0x%lx, preference=0x%x, avoid_efi_boot_services=%d\n",
++		  (long) mld->align, mld->preference, mld->avoid_efi_boot_services);
++
+   /* Load every loadable segment in memory.  */
+   for (i = 0; i < ehdr->e_phnum; i++)
+     {
+       if (phdr(i)->p_type == PT_LOAD)
+         {
+-	  grub_err_t err;
+-	  void *source;
+-
+-	  if (phdr(i)->p_paddr + phdr(i)->p_memsz > highest_load)
+-	    highest_load = phdr(i)->p_paddr + phdr(i)->p_memsz;
+ 
+ 	  grub_dprintf ("multiboot_loader", "segment %d: paddr=0x%lx, memsz=0x%lx, vaddr=0x%lx\n",
+ 			i, (long) phdr(i)->p_paddr, (long) phdr(i)->p_memsz, (long) phdr(i)->p_vaddr);
+ 
+-	  {
+-	    grub_relocator_chunk_t ch;
+-	    err = grub_relocator_alloc_chunk_addr (grub_multiboot_relocator, 
+-						   &ch, phdr(i)->p_paddr,
+-						   phdr(i)->p_memsz);
+-	    if (err)
+-	      {
+-		grub_dprintf ("multiboot_loader", "Error loading phdr %d\n", i);
+-		return err;
+-	      }
+-	    source = get_virtual_current_address (ch);
+-	  }
++	  load_offset = phdr(i)->p_paddr - mld->link_base_addr;
+ 
+ 	  if (phdr(i)->p_filesz != 0)
+ 	    {
+-	      if (grub_file_seek (file, (grub_off_t) phdr(i)->p_offset)
++	      if (grub_file_seek (mld->file, (grub_off_t) phdr(i)->p_offset)
+ 		  == (grub_off_t) -1)
+ 		return grub_errno;
+ 
+-	      if (grub_file_read (file, source, phdr(i)->p_filesz)
++	      if (grub_file_read (mld->file, (grub_uint8_t *) source + load_offset, phdr(i)->p_filesz)
+ 		  != (grub_ssize_t) phdr(i)->p_filesz)
+ 		{
+ 		  if (!grub_errno)
+ 		    grub_error (GRUB_ERR_FILE_READ_ERROR, N_("premature end of file %s"),
+-				filename);
++				mld->filename);
+ 		  return grub_errno;
+ 		}
+ 	    }
+ 
+           if (phdr(i)->p_filesz < phdr(i)->p_memsz)
+-            grub_memset ((grub_uint8_t *) source + phdr(i)->p_filesz, 0,
++            grub_memset ((grub_uint8_t *) source + load_offset + phdr(i)->p_filesz, 0,
+ 			 phdr(i)->p_memsz - phdr(i)->p_filesz);
+         }
+     }
+@@ -168,18 +204,18 @@ CONCAT(grub_multiboot_load_elf, XX) (grub_file_t file, const char *filename, voi
+       if (!shdr)
+ 	return grub_errno;
+       
+-      if (grub_file_seek (file, ehdr->e_shoff) == (grub_off_t) -1)
++      if (grub_file_seek (mld->file, ehdr->e_shoff) == (grub_off_t) -1)
+ 	{
+ 	  grub_free (shdr);
+ 	  return grub_errno;
+ 	}
+ 
+-      if (grub_file_read (file, shdr, (grub_uint32_t) ehdr->e_shnum * ehdr->e_shentsize)
++      if (grub_file_read (mld->file, shdr, (grub_uint32_t) ehdr->e_shnum * ehdr->e_shentsize)
+               != (grub_ssize_t) ehdr->e_shnum * ehdr->e_shentsize)
+ 	{
+ 	  if (!grub_errno)
+ 	    grub_error (GRUB_ERR_FILE_READ_ERROR, N_("premature end of file %s"),
+-			filename);
++			mld->filename);
+ 	  return grub_errno;
+ 	}
+       
+@@ -189,7 +225,9 @@ CONCAT(grub_multiboot_load_elf, XX) (grub_file_t file, const char *filename, voi
+ 	  Elf_Shdr *sh = (Elf_Shdr *) shdrptr;
+ 	  void *src;
+ 	  grub_addr_t target;
+-	  grub_err_t err;
++
++	  if (mld->mbi_ver >= 2 && (sh->sh_type == SHT_REL || sh->sh_type == SHT_RELA))
++	    return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, "ELF files with relocs are not supported yet");
+ 
+ 	  /* This section is a loaded section,
+ 	     so we don't care.  */
+@@ -200,33 +238,28 @@ CONCAT(grub_multiboot_load_elf, XX) (grub_file_t file, const char *filename, voi
+ 	  if (sh->sh_size == 0)
+ 	    continue;
+ 
+-	  {
+-	    grub_relocator_chunk_t ch;
+-	    err = grub_relocator_alloc_chunk_align (grub_multiboot_relocator,
+-						    &ch, 0,
+-						    (0xffffffff - sh->sh_size)
+-						    + 1, sh->sh_size,
+-						    sh->sh_addralign,
+-						    GRUB_RELOCATOR_PREFERENCE_NONE,
+-						    0);
+-	    if (err)
+-	      {
+-		grub_dprintf ("multiboot_loader", "Error loading shdr %d\n", i);
+-		return err;
+-	      }
+-	    src = get_virtual_current_address (ch);
+-	    target = get_physical_target_address (ch);
+-	  }
+-
+-	  if (grub_file_seek (file, sh->sh_offset) == (grub_off_t) -1)
++	  err = grub_relocator_alloc_chunk_align (grub_multiboot_relocator, &ch, 0,
++						  (0xffffffff - sh->sh_size) + 1,
++						  sh->sh_size, sh->sh_addralign,
++						  GRUB_RELOCATOR_PREFERENCE_NONE,
++						  mld->avoid_efi_boot_services);
++	  if (err)
++	    {
++	      grub_dprintf ("multiboot_loader", "Error loading shdr %d\n", i);
++	      return err;
++	    }
++	  src = get_virtual_current_address (ch);
++	  target = get_physical_target_address (ch);
++
++	  if (grub_file_seek (mld->file, sh->sh_offset) == (grub_off_t) -1)
+ 	    return grub_errno;
+ 
+-          if (grub_file_read (file, src, sh->sh_size)
++          if (grub_file_read (mld->file, src, sh->sh_size)
+               != (grub_ssize_t) sh->sh_size)
+ 	    {
+ 	      if (!grub_errno)
+ 		grub_error (GRUB_ERR_FILE_READ_ERROR, N_("premature end of file %s"),
+-			    filename);
++			    mld->filename);
+ 	      return grub_errno;
+ 	    }
+ 	  sh->sh_addr = target;
+diff --git a/grub-core/loader/multiboot_mbi2.c b/grub-core/loader/multiboot_mbi2.c
+index ad1553ba7..b0679a9f6 100644
+--- a/grub-core/loader/multiboot_mbi2.c
++++ b/grub-core/loader/multiboot_mbi2.c
+@@ -68,6 +68,7 @@ static grub_size_t elf_sec_num, elf_sec_entsize;
+ static unsigned elf_sec_shstrndx;
+ static void *elf_sections;
+ static int keep_bs = 0;
++static grub_uint32_t load_base_addr;
+ 
+ void
+ grub_multiboot_add_elfsyms (grub_size_t num, grub_size_t entsize,
+@@ -101,36 +102,40 @@ find_header (grub_properly_aligned_t *buffer, grub_ssize_t len)
+ grub_err_t
+ grub_multiboot_load (grub_file_t file, const char *filename)
+ {
+-  grub_properly_aligned_t *buffer;
+   grub_ssize_t len;
+   struct multiboot_header *header;
+   grub_err_t err;
+   struct multiboot_header_tag *tag;
+   struct multiboot_header_tag_address *addr_tag = NULL;
++  struct multiboot_header_tag_relocatable *rel_tag;
+   int entry_specified = 0, efi_entry_specified = 0;
+   grub_addr_t entry = 0, efi_entry = 0;
+   grub_uint32_t console_required = 0;
+   struct multiboot_header_tag_framebuffer *fbtag = NULL;
+   int accepted_consoles = GRUB_MULTIBOOT_CONSOLE_EGA_TEXT;
++  mbi_load_data_t mld;
+ 
+-  buffer = grub_malloc (MULTIBOOT_SEARCH);
+-  if (!buffer)
++  mld.mbi_ver = 2;
++  mld.relocatable = 0;
++
++  mld.buffer = grub_malloc (MULTIBOOT_SEARCH);
++  if (!mld.buffer)
+     return grub_errno;
+ 
+-  len = grub_file_read (file, buffer, MULTIBOOT_SEARCH);
++  len = grub_file_read (file, mld.buffer, MULTIBOOT_SEARCH);
+   if (len < 32)
+     {
+-      grub_free (buffer);
++      grub_free (mld.buffer);
+       return grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"), filename);
+     }
+ 
+   COMPILE_TIME_ASSERT (MULTIBOOT_HEADER_ALIGN % 4 == 0);
+ 
+-  header = find_header (buffer, len);
++  header = find_header (mld.buffer, len);
+ 
+   if (header == 0)
+     {
+-      grub_free (buffer);
++      grub_free (mld.buffer);
+       return grub_error (GRUB_ERR_BAD_ARGUMENT, "no multiboot header found");
+     }
+ 
+@@ -174,10 +179,11 @@ grub_multiboot_load (grub_file_t file, const char *filename)
+ 	      case MULTIBOOT_TAG_TYPE_EFI_BS:
+ 	      case MULTIBOOT_TAG_TYPE_EFI32_IH:
+ 	      case MULTIBOOT_TAG_TYPE_EFI64_IH:
++	      case MULTIBOOT_TAG_TYPE_LOAD_BASE_ADDR:
+ 		break;
+ 
+ 	      default:
+-		grub_free (buffer);
++		grub_free (mld.buffer);
+ 		return grub_error (GRUB_ERR_UNKNOWN_OS,
+ 				   "unsupported information tag: 0x%x",
+ 				   request_tag->requests[i]);
+@@ -215,6 +221,27 @@ grub_multiboot_load (grub_file_t file, const char *filename)
+ 	accepted_consoles |= GRUB_MULTIBOOT_CONSOLE_FRAMEBUFFER;
+ 	break;
+ 
++      case MULTIBOOT_HEADER_TAG_RELOCATABLE:
++	mld.relocatable = 1;
++	rel_tag = (struct multiboot_header_tag_relocatable *) tag;
++	mld.min_addr = rel_tag->min_addr;
++	mld.max_addr = rel_tag->max_addr;
++	mld.align = rel_tag->align;
++	switch (rel_tag->preference)
++	  {
++	  case MULTIBOOT_LOAD_PREFERENCE_LOW:
++	    mld.preference = GRUB_RELOCATOR_PREFERENCE_LOW;
++	    break;
++
++	  case MULTIBOOT_LOAD_PREFERENCE_HIGH:
++	    mld.preference = GRUB_RELOCATOR_PREFERENCE_HIGH;
++	    break;
++
++	  default:
++	    mld.preference = GRUB_RELOCATOR_PREFERENCE_NONE;
++	  }
++	break;
++
+ 	/* GRUB always page-aligns modules.  */
+       case MULTIBOOT_HEADER_TAG_MODULE_ALIGN:
+ 	break;
+@@ -228,7 +255,7 @@ grub_multiboot_load (grub_file_t file, const char *filename)
+       default:
+ 	if (! (tag->flags & MULTIBOOT_HEADER_TAG_OPTIONAL))
+ 	  {
+-	    grub_free (buffer);
++	    grub_free (mld.buffer);
+ 	    return grub_error (GRUB_ERR_UNKNOWN_OS,
+ 			       "unsupported tag: 0x%x", tag->type);
+ 	  }
+@@ -237,7 +264,7 @@ grub_multiboot_load (grub_file_t file, const char *filename)
+ 
+   if (addr_tag && !entry_specified && !(keep_bs && efi_entry_specified))
+     {
+-      grub_free (buffer);
++      grub_free (mld.buffer);
+       return grub_error (GRUB_ERR_UNKNOWN_OS,
+ 			 "load address tag without entry address tag");
+     }
+@@ -246,8 +273,8 @@ grub_multiboot_load (grub_file_t file, const char *filename)
+     {
+       grub_uint64_t load_addr = (addr_tag->load_addr + 1)
+ 	? addr_tag->load_addr : (addr_tag->header_addr
+-				 - ((char *) header - (char *) buffer));
+-      int offset = ((char *) header - (char *) buffer -
++				 - ((char *) header - (char *) mld.buffer));
++      int offset = ((char *) header - (char *) mld.buffer -
+ 	   (addr_tag->header_addr - load_addr));
+       int load_size = ((addr_tag->load_end_addr == 0) ? file->size - offset :
+ 		       addr_tag->load_end_addr - addr_tag->load_addr);
+@@ -260,27 +287,50 @@ grub_multiboot_load (grub_file_t file, const char *filename)
+       else
+ 	code_size = load_size;
+ 
+-      err = grub_relocator_alloc_chunk_addr (grub_multiboot_relocator, 
+-					     &ch, load_addr,
+-					     code_size);
++      if (mld.relocatable)
++	{
++	  if (code_size > mld.max_addr || mld.min_addr > mld.max_addr - code_size)
++	    {
++	      grub_free (mld.buffer);
++	      return grub_error (GRUB_ERR_BAD_OS, "invalid min/max address and/or load size");
++	    }
++
++	  err = grub_relocator_alloc_chunk_align (grub_multiboot_relocator, &ch,
++						  mld.min_addr, mld.max_addr - code_size,
++						  code_size, mld.align ? mld.align : 1,
++						  mld.preference, keep_bs);
++	}
++      else
++	err = grub_relocator_alloc_chunk_addr (grub_multiboot_relocator,
++					       &ch, load_addr, code_size);
+       if (err)
+ 	{
+ 	  grub_dprintf ("multiboot_loader", "Error loading aout kludge\n");
+-	  grub_free (buffer);
++	  grub_free (mld.buffer);
+ 	  return err;
+ 	}
++      mld.link_base_addr = load_addr;
++      mld.load_base_addr = get_physical_target_address (ch);
+       source = get_virtual_current_address (ch);
+ 
++      grub_dprintf ("multiboot_loader", "link_base_addr=0x%x, load_base_addr=0x%x, "
++		    "load_size=0x%lx, relocatable=%d\n", mld.link_base_addr,
++		    mld.load_base_addr, (long) code_size, mld.relocatable);
++
++      if (mld.relocatable)
++	grub_dprintf ("multiboot_loader", "align=0x%lx, preference=0x%x, avoid_efi_boot_services=%d\n",
++		      (long) mld.align, mld.preference, keep_bs);
++
+       if ((grub_file_seek (file, offset)) == (grub_off_t) -1)
+ 	{
+-	  grub_free (buffer);
++	  grub_free (mld.buffer);
+ 	  return grub_errno;
+ 	}
+ 
+       grub_file_read (file, source, load_size);
+       if (grub_errno)
+ 	{
+-	  grub_free (buffer);
++	  grub_free (mld.buffer);
+ 	  return grub_errno;
+ 	}
+ 
+@@ -290,19 +340,41 @@ grub_multiboot_load (grub_file_t file, const char *filename)
+     }
+   else
+     {
+-      err = grub_multiboot_load_elf (file, filename, buffer);
++      mld.file = file;
++      mld.filename = filename;
++      mld.avoid_efi_boot_services = keep_bs;
++      err = grub_multiboot_load_elf (&mld);
+       if (err)
+ 	{
+-	  grub_free (buffer);
++	  grub_free (mld.buffer);
+ 	  return err;
+ 	}
+     }
+ 
++  load_base_addr = mld.load_base_addr;
++
+   if (keep_bs && efi_entry_specified)
+     grub_multiboot_payload_eip = efi_entry;
+   else if (entry_specified)
+     grub_multiboot_payload_eip = entry;
+ 
++  if (mld.relocatable)
++    {
++      /*
++       * Both branches are mathematically equivalent. However, it looks
++       * that real life (C?) is more complicated. I am trying to avoid
++       * wrap around here if mld.load_base_addr < mld.link_base_addr.
++       * If you look at C operator precedence then everything should work.
++       * However, I am not 100% sure that a given compiler will not
++       * optimize/break this stuff. So, maybe we should use signed
++       * 64-bit int here.
++       */
++      if (mld.load_base_addr >= mld.link_base_addr)
++	grub_multiboot_payload_eip += mld.load_base_addr - mld.link_base_addr;
++      else
++	grub_multiboot_payload_eip -= mld.link_base_addr - mld.load_base_addr;
++    }
++
+   if (fbtag)
+     err = grub_multiboot_set_console (GRUB_MULTIBOOT_CONSOLE_FRAMEBUFFER,
+ 				      accepted_consoles,
+@@ -411,6 +483,7 @@ grub_multiboot_get_mbi_size (void)
+     + ALIGN_UP (sizeof (struct multiboot_tag_framebuffer), MULTIBOOT_TAG_ALIGN)
+     + ALIGN_UP (sizeof (struct multiboot_tag_old_acpi)
+ 		+ sizeof (struct grub_acpi_rsdp_v10), MULTIBOOT_TAG_ALIGN)
++    + ALIGN_UP (sizeof (struct multiboot_tag_load_base_addr), MULTIBOOT_TAG_ALIGN)
+     + acpiv2_size ()
+     + net_size ()
+ #ifdef GRUB_MACHINE_EFI
+@@ -694,6 +767,15 @@ grub_multiboot_make_mbi (grub_uint32_t *target)
+   ptrorig += (2 * sizeof (grub_uint32_t)) / sizeof (grub_properly_aligned_t);
+ 
+   {
++    struct multiboot_tag_load_base_addr *tag = (struct multiboot_tag_load_base_addr *) ptrorig;
++    tag->type = MULTIBOOT_TAG_TYPE_LOAD_BASE_ADDR;
++    tag->size = sizeof (struct multiboot_tag_load_base_addr);
++    tag->load_base_addr = load_base_addr;
++    ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN)
++       / sizeof (grub_properly_aligned_t);
++  }
++
++  {
+     struct multiboot_tag_string *tag = (struct multiboot_tag_string *) ptrorig;
+     tag->type = MULTIBOOT_TAG_TYPE_CMDLINE;
+     tag->size = sizeof (struct multiboot_tag_string) + cmdline_size; 
+diff --git a/include/grub/multiboot.h b/include/grub/multiboot.h
+index e13c0843b..c96492bb5 100644
+--- a/include/grub/multiboot.h
++++ b/include/grub/multiboot.h
+@@ -91,10 +91,28 @@ grub_multiboot_set_console (int console_type, int accepted_consoles,
+ 			    int console_required);
+ grub_err_t
+ grub_multiboot_load (grub_file_t file, const char *filename);
++
++struct mbi_load_data
++{
++  grub_file_t file;
++  const char *filename;
++  void *buffer;
++  unsigned int mbi_ver;
++  int relocatable;
++  grub_uint32_t min_addr;
++  grub_uint32_t max_addr;
++  grub_size_t align;
++  grub_uint32_t preference;
++  grub_uint32_t link_base_addr;
++  grub_uint32_t load_base_addr;
++  int avoid_efi_boot_services;
++};
++typedef struct mbi_load_data mbi_load_data_t;
++
+ /* Load ELF32 or ELF64.  */
+ grub_err_t
+-grub_multiboot_load_elf (grub_file_t file, const char *filename,
+-			 void *buffer);
++grub_multiboot_load_elf (mbi_load_data_t *mld);
++
+ extern grub_size_t grub_multiboot_pure_size;
+ extern grub_size_t grub_multiboot_alloc_mbi;
+ extern grub_uint32_t grub_multiboot_payload_eip;
+diff --git a/include/multiboot2.h b/include/multiboot2.h
+index 36a174fd0..b93fba46d 100644
+--- a/include/multiboot2.h
++++ b/include/multiboot2.h
+@@ -62,6 +62,7 @@
+ #define MULTIBOOT_TAG_TYPE_EFI_BS            18
+ #define MULTIBOOT_TAG_TYPE_EFI32_IH          19
+ #define MULTIBOOT_TAG_TYPE_EFI64_IH          20
++#define MULTIBOOT_TAG_TYPE_LOAD_BASE_ADDR    21
+ 
+ #define MULTIBOOT_HEADER_TAG_END  0
+ #define MULTIBOOT_HEADER_TAG_INFORMATION_REQUEST  1
+@@ -72,11 +73,16 @@
+ #define MULTIBOOT_HEADER_TAG_MODULE_ALIGN  6
+ #define MULTIBOOT_HEADER_TAG_EFI_BS  7
+ #define MULTIBOOT_HEADER_TAG_ENTRY_ADDRESS_EFI64  9
++#define MULTIBOOT_HEADER_TAG_RELOCATABLE  10
+ 
+ #define MULTIBOOT_ARCHITECTURE_I386  0
+ #define MULTIBOOT_ARCHITECTURE_MIPS32  4
+ #define MULTIBOOT_HEADER_TAG_OPTIONAL 1
+ 
++#define MULTIBOOT_LOAD_PREFERENCE_NONE 0
++#define MULTIBOOT_LOAD_PREFERENCE_LOW 1
++#define MULTIBOOT_LOAD_PREFERENCE_HIGH 2
++
+ #define MULTIBOOT_CONSOLE_FLAGS_CONSOLE_REQUIRED 1
+ #define MULTIBOOT_CONSOLE_FLAGS_EGA_TEXT_SUPPORTED 2
+ 
+@@ -161,6 +167,17 @@ struct multiboot_header_tag_module_align
+   multiboot_uint32_t size;
+ };
+ 
++struct multiboot_header_tag_relocatable
++{
++  multiboot_uint16_t type;
++  multiboot_uint16_t flags;
++  multiboot_uint32_t size;
++  multiboot_uint32_t min_addr;
++  multiboot_uint32_t max_addr;
++  multiboot_uint32_t align;
++  multiboot_uint32_t preference;
++};
++
+ struct multiboot_color
+ {
+   multiboot_uint8_t red;
+@@ -387,6 +404,13 @@ struct multiboot_tag_efi64_ih
+   multiboot_uint64_t pointer;
+ };
+ 
++struct multiboot_tag_load_base_addr
++{
++  multiboot_uint32_t type;
++  multiboot_uint32_t size;
++  multiboot_uint32_t load_base_addr;
++};
++
+ #endif /* ! ASM_FILE */
+ 
+ #endif /* ! MULTIBOOT_HEADER */
diff -Nru grub2-2.02~beta3/debian/patches/series grub2-2.02~beta3/debian/patches/series
--- grub2-2.02~beta3/debian/patches/series	2018-10-28 19:18:13.000000000 +0000
+++ grub2-2.02~beta3/debian/patches/series	2019-06-12 12:20:28.000000000 +0100
@@ -59,3 +59,8 @@
 grub-install-efibootmgr-check.patch
 mknetdir_arm64.patch
 tsc_efi_default_to_pmtimer.patch
+add-grub_relocator64_efi-relocator.patch
+multiboot2-add-ImageHandle-tags.patch
+multiboot2-do-not-pass-mmaps-if-efi-boot-services.patch
+multiboot2-relocatable-images.patch
+xen-multiboot2.patch
diff -Nru grub2-2.02~beta3/debian/patches/xen-multiboot2.patch grub2-2.02~beta3/debian/patches/xen-multiboot2.patch
--- grub2-2.02~beta3/debian/patches/xen-multiboot2.patch	1970-01-01 01:00:00.000000000 +0100
+++ grub2-2.02~beta3/debian/patches/xen-multiboot2.patch	2019-06-12 12:20:28.000000000 +0100
@@ -0,0 +1,61 @@
+From 23439d60d742949cee70df3c1b84ac61c9ce2c0d Mon Sep 17 00:00:00 2001
+From: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
+Date: Tue, 29 Aug 2017 16:40:53 -0400
+Subject: Use grub-file to figure out whether multiboot2 should be used for
+ Xen.gz
+
+The multiboot2 is much more preferable than multiboot. Especially
+if booting under EFI where multiboot does not have the functionality
+to pass ImageHandler.
+
+Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
+Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
+
+Origin: backport, https://git.savannah.gnu.org/cgit/grub.git/commit/?id=b4d709b6ee789cdaf3fa7a80fd90c721a16f48c2
+Bug-Debian: https://bugs.debian.org/898947
+Bug-Debian: https://bugs.debian.org/930028
+Last-Update: 2019-06-12
+
+Patch-Name: xen-multiboot2.patch
+---
+ util/grub.d/20_linux_xen.in | 13 ++++++++++---
+ 1 file changed, 10 insertions(+), 3 deletions(-)
+
+diff --git a/util/grub.d/20_linux_xen.in b/util/grub.d/20_linux_xen.in
+index 6fd17f1e9..d726ee7d2 100644
+--- a/util/grub.d/20_linux_xen.in
++++ b/util/grub.d/20_linux_xen.in
+@@ -130,16 +130,16 @@ linux_entry ()
+         else
+             xen_rm_opts="no-real-mode edd=off"
+         fi
+-	multiboot	${rel_xen_dirname}/${xen_basename} placeholder ${xen_args} \${xen_rm_opts}
++	${xen_loader}	${rel_xen_dirname}/${xen_basename} placeholder ${xen_args} \${xen_rm_opts}
+ 	echo	'$(echo "$lmessage" | grub_quote)'
+-	module	${rel_dirname}/${basename} placeholder root=${linux_root_device_thisversion} ro ${args}
++	${module_loader}	${rel_dirname}/${basename} placeholder root=${linux_root_device_thisversion} ro ${args}
+ EOF
+   if test -n "${initrd}" ; then
+     # TRANSLATORS: ramdisk isn't identifier. Should be translated.
+     message="$(gettext_printf "Loading initial ramdisk ...")"
+     sed "s/^/$submenu_indentation/" << EOF
+ 	echo	'$(echo "$message" | grub_quote)'
+-	module	--nounzip   ${rel_dirname}/${initrd}
++	${module_loader}	--nounzip   ${rel_dirname}/${initrd}
+ EOF
+   fi
+   sed "s/^/$submenu_indentation/" << EOF
+@@ -214,6 +214,13 @@ while [ "x${xen_list}" != "x" ] ; do
+     if [ "x$is_top_level" != xtrue ]; then
+ 	echo "	submenu '$(gettext_printf "Xen hypervisor, version %s" "${xen_version}" | grub_quote)' \$menuentry_id_option 'xen-hypervisor-$xen_version-$boot_device_id' {"
+     fi
++    if ($grub_file --is-x86-multiboot2 $current_xen); then
++	xen_loader="multiboot2"
++	module_loader="module2"
++    else
++	xen_loader="multiboot"
++	module_loader="module"
++    fi
+     while [ "x$list" != "x" ] ; do
+ 	linux=`version_find_latest $list`
+ 	gettext_printf "Found linux image: %s\n" "$linux" >&2

--- End Message ---
--- Begin Message ---
Version: 9.10

Hi,

The fixes referenced by each of these bugs were included in today's
stretch point release (9.10).

Regards,

Adam

--- End Message ---

Reply to: