diff --git a/.gitignore b/.gitignore
index 618dc68..0342d81 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,4 +1,3 @@
 SOURCES/grub-2.02~beta2.tar.xz
 SOURCES/theme.tar.bz2
 SOURCES/unifont-5.1.20080820.pcf.gz
-SOURCES/centos.cer
diff --git a/.grub2.metadata b/.grub2.metadata
index a5c2c6a..261f908 100644
--- a/.grub2.metadata
+++ b/.grub2.metadata
@@ -1,4 +1,3 @@
 1bf580f1e8bce4909a7ac7ca485cee02b00ed383 SOURCES/grub-2.02~beta2.tar.xz
 cf0b7763c528902da7e8b05cfa248f20c8825ce5 SOURCES/theme.tar.bz2
 87f8600ba24e521b5d20bdf6c4b71af8ae861e3a SOURCES/unifont-5.1.20080820.pcf.gz
-6e9105eb51e55a46761838f289a917611cad8091 SOURCES/centos.cer
diff --git a/SOURCES/0001-Try-to-make-sure-configure.ac-and-grub-rpm-sort-play.patch b/SOURCES/0001-Try-to-make-sure-configure.ac-and-grub-rpm-sort-play.patch
deleted file mode 100644
index 47e99ce..0000000
--- a/SOURCES/0001-Try-to-make-sure-configure.ac-and-grub-rpm-sort-play.patch
+++ /dev/null
@@ -1,60 +0,0 @@
-From 0576c43a727f095caac0b04b551ebdb66adf616a Mon Sep 17 00:00:00 2001
-From: Peter Jones <pjones@redhat.com>
-Date: Mon, 3 Aug 2015 11:46:42 -0400
-Subject: [PATCH] Try to make sure configure.ac and grub-rpm-sort play nice.
-
-Apparently the test for whether to use grub-rpm-sort and also the
-renaming of it to grub2-rpm-sort on the runtime side weren't right.
-
-Related: rhbz#1124074
-
-Signed-off-by: Peter Jones <pjones@redhat.com>
----
- configure.ac              | 2 +-
- util/grub-mkconfig_lib.in | 9 ++++++---
- 2 files changed, 7 insertions(+), 4 deletions(-)
-
-diff --git a/configure.ac b/configure.ac
-index 273da6c..04c052d 100644
---- a/configure.ac
-+++ b/configure.ac
-@@ -1549,7 +1549,7 @@ AC_SUBST([LIBDEVMAPPER])
- AC_ARG_ENABLE([rpm-sort],
-               [AS_HELP_STRING([--enable-rpm-sort],
-                               [enable native rpm sorting of kernels in grub (default=guessed)])])
--if test x"$enable_rpm-sort" = xno ; then
-+if test x"$enable_rpm_sort" = xno ; then
-   rpm_sort_excuse="explicitly disabled"
- fi
- 
-diff --git a/util/grub-mkconfig_lib.in b/util/grub-mkconfig_lib.in
-index e85b60c..c67a319 100644
---- a/util/grub-mkconfig_lib.in
-+++ b/util/grub-mkconfig_lib.in
-@@ -33,6 +33,9 @@ fi
- if test "x$grub_mkrelpath" = x; then
-   grub_mkrelpath="${bindir}/@grub_mkrelpath@"
- fi
-+if test "x$grub_rpm_sort" = x; then
-+  grub_rpm_sort="${sbindir}/@grub_rpm_sort@"
-+fi
- 
- if which gettext >/dev/null 2>/dev/null; then
-   :
-@@ -213,10 +216,10 @@ version_sort ()
-    esac
- }
- 
--if [ "x$RPMLIB" = x ]; then
--  kernel_sort=version_sort
-+if [ "x$grub_rpm_sort" != x -a -x "$grub_rpm_sort" ]; then
-+  kernel_sort="$grub_rpm_sort"
- else
--  kernel_sort="${sbindir}/grub-rpm-sort"
-+  kernel_sort=version_sort
- fi
- 
- version_test_numeric ()
--- 
-2.4.3
-
diff --git a/SOURCES/0001-Update-info-with-grub.cfg-netboot-selection-order-11.patch b/SOURCES/0001-Update-info-with-grub.cfg-netboot-selection-order-11.patch
new file mode 100644
index 0000000..538f9f9
--- /dev/null
+++ b/SOURCES/0001-Update-info-with-grub.cfg-netboot-selection-order-11.patch
@@ -0,0 +1,70 @@
+From 24f034631df06b2f33d0721b8cd5126906aa7b34 Mon Sep 17 00:00:00 2001
+From: Robert Marshall <rmarshall@redhat.com>
+Date: Mon, 16 Mar 2015 16:34:51 -0400
+Subject: [PATCH 1/2] Update info with grub.cfg netboot selection order
+ (#1148650)
+
+Added documentation to the grub info page that specifies the order
+netboot clients will use to select a grub configuration file.
+
+Resolves rhbz#1148650
+---
+ docs/grub.texi | 42 ++++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 42 insertions(+)
+
+diff --git a/docs/grub.texi b/docs/grub.texi
+index 6b112c1..ef09c83 100644
+--- a/docs/grub.texi
++++ b/docs/grub.texi
+@@ -2414,6 +2414,48 @@ grub-mknetdir --net-directory=/srv/tftp --subdir=/boot/grub -d /usr/lib/grub/i38
+ Then follow instructions printed out by grub-mknetdir on configuring your DHCP
+ server.
+ 
++The grub.cfg file is placed in the same directory as the path output by
++grub-mknetdir hereafter referred to as FWPATH. GRUB will search for its 
++configuration files in order using the following rules where the appended
++value corresponds to a value on the client machine.
++
++@example
++@group
++@samp{(FWPATH)}/grub.cfg-@samp{(UUID OF NIC)}
++@samp{(FWPATH)}/grub.cfg-@samp{(MAC ADDRESS OF NIC)}
++@samp{(FWPATH)}/grub.cfg-@samp{(IPv4 OR IPv6 ADDRESS)}
++@samp{(FWPATH)}/grub.cfg
++@end group
++@end example
++
++The client will only attempt to look up an IPv6 address config once, however,
++it will try the IPv4 multiple times. The concrete example below shows what
++would happen under the IPv4 case.
++
++@example
++@group
++UUID: 7726a678-7fc0-4853-a4f6-c85ac36a120a
++MAC:  52:54:00:ec:33:81
++IPV4: 10.0.0.130 (0A000082)
++@end group
++@end example
++
++@example
++@group
++@samp{(FWPATH)}/grub.cfg-7726a678-7fc0-4853-a4f6-c85ac36a120a
++@samp{(FWPATH)}/grub.cfg-52-54-00-ec-33-81
++@samp{(FWPATH)}/grub.cfg-0A000082
++@samp{(FWPATH)}/grub.cfg-0A00008
++@samp{(FWPATH)}/grub.cfg-0A0000
++@samp{(FWPATH)}/grub.cfg-0A000
++@samp{(FWPATH)}/grub.cfg-0A00
++@samp{(FWPATH)}/grub.cfg-0A0
++@samp{(FWPATH)}/grub.cfg-0A
++@samp{(FWPATH)}/grub.cfg-0
++@samp{(FWPATH)}/grub.cfg
++@end group
++@end example
++
+ After GRUB has started, files on the TFTP server will be accessible via the
+ @samp{(tftp)} device.
+ 
+-- 
+2.4.3
+
diff --git a/SOURCES/0001-efidisk-move-device-path-helpers-in-core-for-efinet.patch b/SOURCES/0001-efidisk-move-device-path-helpers-in-core-for-efinet.patch
new file mode 100644
index 0000000..90de69d
--- /dev/null
+++ b/SOURCES/0001-efidisk-move-device-path-helpers-in-core-for-efinet.patch
@@ -0,0 +1,207 @@
+From 559b04c2e29643b73f238cf95add8cef9a192a00 Mon Sep 17 00:00:00 2001
+From: Andrei Borzenkov <arvidjaar@gmail.com>
+Date: Thu, 7 May 2015 20:37:16 +0300
+Subject: [PATCH 01/17] efidisk: move device path helpers in core for efinet
+
+---
+ grub-core/disk/efi/efidisk.c | 61 ++++++++------------------------------------
+ grub-core/kern/efi/efi.c     | 41 +++++++++++++++++++++++++++++
+ include/grub/efi/efi.h       |  4 +++
+ 3 files changed, 55 insertions(+), 51 deletions(-)
+
+diff --git a/grub-core/disk/efi/efidisk.c b/grub-core/disk/efi/efidisk.c
+index 3b12c34..845c66f 100644
+--- a/grub-core/disk/efi/efidisk.c
++++ b/grub-core/disk/efi/efidisk.c
+@@ -43,47 +43,6 @@ static struct grub_efidisk_data *fd_devices;
+ static struct grub_efidisk_data *hd_devices;
+ static struct grub_efidisk_data *cd_devices;
+ 
+-/* Duplicate a device path.  */
+-static grub_efi_device_path_t *
+-duplicate_device_path (const grub_efi_device_path_t *dp)
+-{
+-  grub_efi_device_path_t *p;
+-  grub_size_t total_size = 0;
+-
+-  for (p = (grub_efi_device_path_t *) dp;
+-       ;
+-       p = GRUB_EFI_NEXT_DEVICE_PATH (p))
+-    {
+-      total_size += GRUB_EFI_DEVICE_PATH_LENGTH (p);
+-      if (GRUB_EFI_END_ENTIRE_DEVICE_PATH (p))
+-	break;
+-    }
+-
+-  p = grub_malloc (total_size);
+-  if (! p)
+-    return 0;
+-
+-  grub_memcpy (p, dp, total_size);
+-  return p;
+-}
+-
+-/* Return the device path node right before the end node.  */
+-static grub_efi_device_path_t *
+-find_last_device_path (const grub_efi_device_path_t *dp)
+-{
+-  grub_efi_device_path_t *next, *p;
+-
+-  if (GRUB_EFI_END_ENTIRE_DEVICE_PATH (dp))
+-    return 0;
+-
+-  for (p = (grub_efi_device_path_t *) dp, next = GRUB_EFI_NEXT_DEVICE_PATH (p);
+-       ! GRUB_EFI_END_ENTIRE_DEVICE_PATH (next);
+-       p = next, next = GRUB_EFI_NEXT_DEVICE_PATH (next))
+-    ;
+-
+-  return p;
+-}
+-
+ static struct grub_efidisk_data *
+ make_devices (void)
+ {
+@@ -110,7 +69,7 @@ make_devices (void)
+       if (! dp)
+ 	continue;
+ 
+-      ldp = find_last_device_path (dp);
++      ldp = grub_efi_find_last_device_path (dp);
+       if (! ldp)
+ 	/* This is empty. Why?  */
+ 	continue;
+@@ -150,11 +109,11 @@ find_parent_device (struct grub_efidisk_data *devices,
+   grub_efi_device_path_t *dp, *ldp;
+   struct grub_efidisk_data *parent;
+ 
+-  dp = duplicate_device_path (d->device_path);
++  dp = grub_efi_duplicate_device_path (d->device_path);
+   if (! dp)
+     return 0;
+ 
+-  ldp = find_last_device_path (dp);
++  ldp = grub_efi_find_last_device_path (dp);
+   ldp->type = GRUB_EFI_END_DEVICE_PATH_TYPE;
+   ldp->subtype = GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE;
+   ldp->length = sizeof (*ldp);
+@@ -180,11 +139,11 @@ is_child (struct grub_efidisk_data *child,
+   grub_efi_device_path_t *dp, *ldp;
+   int ret;
+ 
+-  dp = duplicate_device_path (child->device_path);
++  dp = grub_efi_duplicate_device_path (child->device_path);
+   if (! dp)
+     return 0;
+ 
+-  ldp = find_last_device_path (dp);
++  ldp = grub_efi_find_last_device_path (dp);
+   ldp->type = GRUB_EFI_END_DEVICE_PATH_TYPE;
+   ldp->subtype = GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE;
+   ldp->length = sizeof (*ldp);
+@@ -207,8 +166,8 @@ add_device (struct grub_efidisk_data **devices, struct grub_efidisk_data *d)
+     {
+       int ret;
+ 
+-      ret = grub_efi_compare_device_paths (find_last_device_path ((*p)->device_path),
+-					   find_last_device_path (d->device_path));
++      ret = grub_efi_compare_device_paths (grub_efi_find_last_device_path ((*p)->device_path),
++					   grub_efi_find_last_device_path (d->device_path));
+       if (ret == 0)
+ 	ret = grub_efi_compare_device_paths ((*p)->device_path,
+ 					     d->device_path);
+@@ -795,7 +754,7 @@ grub_efidisk_get_device_name (grub_efi_handle_t *handle)
+   if (! dp)
+     return 0;
+ 
+-  ldp = find_last_device_path (dp);
++  ldp = grub_efi_find_last_device_path (dp);
+   if (! ldp)
+     return 0;
+ 
+@@ -811,14 +770,14 @@ grub_efidisk_get_device_name (grub_efi_handle_t *handle)
+ 
+       /* It is necessary to duplicate the device path so that GRUB
+ 	 can overwrite it.  */
+-      dup_dp = duplicate_device_path (dp);
++      dup_dp = grub_efi_duplicate_device_path (dp);
+       if (! dup_dp)
+ 	return 0;
+ 
+       while (1)
+ 	{
+ 	  grub_efi_device_path_t *dup_ldp;
+-	  dup_ldp = find_last_device_path (dup_dp);
++	  dup_ldp = grub_efi_find_last_device_path (dup_dp);
+ 	  if (!(GRUB_EFI_DEVICE_PATH_TYPE (dup_ldp) == GRUB_EFI_MEDIA_DEVICE_PATH_TYPE
+ 		&& (GRUB_EFI_DEVICE_PATH_SUBTYPE (dup_ldp) == GRUB_EFI_CDROM_DEVICE_PATH_SUBTYPE
+ 		    || GRUB_EFI_DEVICE_PATH_SUBTYPE (dup_ldp) == GRUB_EFI_HARD_DRIVE_DEVICE_PATH_SUBTYPE)))
+diff --git a/grub-core/kern/efi/efi.c b/grub-core/kern/efi/efi.c
+index d99a6fb..c80d85b 100644
+--- a/grub-core/kern/efi/efi.c
++++ b/grub-core/kern/efi/efi.c
+@@ -423,6 +423,47 @@ grub_efi_get_device_path (grub_efi_handle_t handle)
+ 				 GRUB_EFI_OPEN_PROTOCOL_GET_PROTOCOL);
+ }
+ 
++/* Return the device path node right before the end node.  */
++grub_efi_device_path_t *
++grub_efi_find_last_device_path (const grub_efi_device_path_t *dp)
++{
++  grub_efi_device_path_t *next, *p;
++
++  if (GRUB_EFI_END_ENTIRE_DEVICE_PATH (dp))
++    return 0;
++
++  for (p = (grub_efi_device_path_t *) dp, next = GRUB_EFI_NEXT_DEVICE_PATH (p);
++       ! GRUB_EFI_END_ENTIRE_DEVICE_PATH (next);
++       p = next, next = GRUB_EFI_NEXT_DEVICE_PATH (next))
++    ;
++
++  return p;
++}
++
++/* Duplicate a device path.  */
++grub_efi_device_path_t *
++grub_efi_duplicate_device_path (const grub_efi_device_path_t *dp)
++{
++  grub_efi_device_path_t *p;
++  grub_size_t total_size = 0;
++
++  for (p = (grub_efi_device_path_t *) dp;
++       ;
++       p = GRUB_EFI_NEXT_DEVICE_PATH (p))
++    {
++      total_size += GRUB_EFI_DEVICE_PATH_LENGTH (p);
++      if (GRUB_EFI_END_ENTIRE_DEVICE_PATH (p))
++	break;
++    }
++
++  p = grub_malloc (total_size);
++  if (! p)
++    return 0;
++
++  grub_memcpy (p, dp, total_size);
++  return p;
++}
++
+ static void
+ dump_vendor_path (const char *type, grub_efi_vendor_device_path_t *vendor)
+ {
+diff --git a/include/grub/efi/efi.h b/include/grub/efi/efi.h
+index a000c38..2245632 100644
+--- a/include/grub/efi/efi.h
++++ b/include/grub/efi/efi.h
+@@ -56,6 +56,10 @@ 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);
+ grub_efi_device_path_t *
+ EXPORT_FUNC(grub_efi_get_device_path) (grub_efi_handle_t handle);
++grub_efi_device_path_t *
++EXPORT_FUNC(grub_efi_find_last_device_path) (const grub_efi_device_path_t *dp);
++grub_efi_device_path_t *
++EXPORT_FUNC(grub_efi_duplicate_device_path) (const grub_efi_device_path_t *dp);
+ grub_err_t EXPORT_FUNC (grub_efi_finish_boot_services) (grub_efi_uintn_t *outbuf_size, void *outbuf,
+ 							grub_efi_uintn_t *map_key,
+ 							grub_efi_uintn_t *efi_desc_size,
+-- 
+2.4.3
+
diff --git a/SOURCES/0158-efinet-Check-for-immediate-completition.patch b/SOURCES/0158-efinet-Check-for-immediate-completition.patch
new file mode 100644
index 0000000..cfd04c1
--- /dev/null
+++ b/SOURCES/0158-efinet-Check-for-immediate-completition.patch
@@ -0,0 +1,51 @@
+From 763eff26748ca3d2ae8b178aef15da54a70527a5 Mon Sep 17 00:00:00 2001
+From: Martin Wilck <martin.wilck@ts.fujitsu.com>
+Date: Fri, 27 Mar 2015 14:27:56 +0100
+Subject: [PATCH 01/23] efinet: Check for immediate completition.
+
+This both speeds GRUB up and workarounds unexpected EFI behaviour.
+---
+ grub-core/net/drivers/efi/efinet.c | 16 ++++++++++++++--
+ 1 file changed, 14 insertions(+), 2 deletions(-)
+
+diff --git a/grub-core/net/drivers/efi/efinet.c b/grub-core/net/drivers/efi/efinet.c
+index a6e4c79..78df215 100644
+--- a/grub-core/net/drivers/efi/efinet.c
++++ b/grub-core/net/drivers/efi/efinet.c
+@@ -37,11 +37,12 @@ send_card_buffer (struct grub_net_card *dev,
+   grub_efi_status_t st;
+   grub_efi_simple_network_t *net = dev->efi_net;
+   grub_uint64_t limit_time = grub_get_time_ms () + 4000;
++  void *txbuf;
+ 
+   if (dev->txbusy)
+     while (1)
+       {
+-	void *txbuf = NULL;
++	txbuf = NULL;
+ 	st = efi_call_3 (net->get_status, net, 0, &txbuf);
+ 	if (st != GRUB_EFI_SUCCESS)
+ 	  return grub_error (GRUB_ERR_IO,
+@@ -74,7 +75,18 @@ send_card_buffer (struct grub_net_card *dev,
+ 		   dev->txbuf, NULL, NULL, NULL);
+   if (st != GRUB_EFI_SUCCESS)
+     return grub_error (GRUB_ERR_IO, N_("couldn't send network packet"));
+-  dev->txbusy = 1;
++
++  /*
++     The card may have sent out the packet immediately - set txbusy
++     to 0 in this case.
++     Cases were observed where checking txbuf at the next call
++     of send_card_buffer() is too late: 0 is returned in txbuf and
++     we run in the GRUB_ERR_TIMEOUT case above.
++     Perhaps a timeout in the FW has discarded the recycle buffer.
++   */
++  st = efi_call_3 (net->get_status, net, 0, &txbuf);
++  dev->txbusy = !(st == GRUB_EFI_SUCCESS && txbuf == dev->txbuf);
++
+   return GRUB_ERR_NONE;
+ }
+ 
+-- 
+2.4.3
+
diff --git a/SOURCES/0159-efinet-memory-leak-on-module-removal.patch b/SOURCES/0159-efinet-memory-leak-on-module-removal.patch
new file mode 100644
index 0000000..7eec92a
--- /dev/null
+++ b/SOURCES/0159-efinet-memory-leak-on-module-removal.patch
@@ -0,0 +1,30 @@
+From 8471c374d9379ba80e4b3bbcacb4813a2d04f008 Mon Sep 17 00:00:00 2001
+From: Andrei Borzenkov <arvidjaar@gmail.com>
+Date: Mon, 4 May 2015 08:08:57 +0300
+Subject: [PATCH 02/23] efinet: memory leak on module removal
+
+---
+ grub-core/net/drivers/efi/efinet.c | 8 +++++++-
+ 1 file changed, 7 insertions(+), 1 deletion(-)
+
+diff --git a/grub-core/net/drivers/efi/efinet.c b/grub-core/net/drivers/efi/efinet.c
+index 78df215..810adf3 100644
+--- a/grub-core/net/drivers/efi/efinet.c
++++ b/grub-core/net/drivers/efi/efinet.c
+@@ -294,6 +294,12 @@ GRUB_MOD_FINI(efinet)
+ 
+   FOR_NET_CARDS_SAFE (card, next) 
+     if (card->driver == &efidriver)
+-      grub_net_card_unregister (card);
++      {
++	grub_net_card_unregister (card);
++	grub_free (card->txbuf);
++	grub_free (card->rcvbuf);
++	grub_free (card->name);
++	grub_free (card);
++      }
+ }
+ 
+-- 
+2.4.3
+
diff --git a/SOURCES/0160-efinet-cannot-free-const-char-pointer.patch b/SOURCES/0160-efinet-cannot-free-const-char-pointer.patch
new file mode 100644
index 0000000..cdc8b49
--- /dev/null
+++ b/SOURCES/0160-efinet-cannot-free-const-char-pointer.patch
@@ -0,0 +1,25 @@
+From fe8c0ca495c7225682e2af47d0d77b4ad0077f34 Mon Sep 17 00:00:00 2001
+From: Andrei Borzenkov <arvidjaar@gmail.com>
+Date: Mon, 4 May 2015 08:39:29 +0300
+Subject: [PATCH 03/23] efinet: cannot free const char * pointer
+
+---
+ grub-core/net/drivers/efi/efinet.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/grub-core/net/drivers/efi/efinet.c b/grub-core/net/drivers/efi/efinet.c
+index 810adf3..bb863e6 100644
+--- a/grub-core/net/drivers/efi/efinet.c
++++ b/grub-core/net/drivers/efi/efinet.c
+@@ -298,7 +298,7 @@ GRUB_MOD_FINI(efinet)
+ 	grub_net_card_unregister (card);
+ 	grub_free (card->txbuf);
+ 	grub_free (card->rcvbuf);
+-	grub_free (card->name);
++	grub_free ((char *)card->name);
+ 	grub_free (card);
+       }
+ }
+-- 
+2.4.3
+
diff --git a/SOURCES/0161-Revert-efinet-memory-leak-on-module-removal.patch b/SOURCES/0161-Revert-efinet-memory-leak-on-module-removal.patch
new file mode 100644
index 0000000..284c4b5
--- /dev/null
+++ b/SOURCES/0161-Revert-efinet-memory-leak-on-module-removal.patch
@@ -0,0 +1,34 @@
+From 41772bb7633fab5e38f0dac90e1e04538a066a3d Mon Sep 17 00:00:00 2001
+From: Andrei Borzenkov <arvidjaar@gmail.com>
+Date: Mon, 4 May 2015 09:13:53 +0300
+Subject: [PATCH 04/23] Revert "efinet: memory leak on module removal"
+
+This reverts commits 47b2bee3ef0ea60fc3f5bfc37f3784e559385297
+and 8d3c4544ffdd0289a4b0bdeb0cdc6355f801a4b3. It is not safe
+to free allocated cards, dangling pointers main remain. Such
+cleanup requires more changes in net core.
+---
+ grub-core/net/drivers/efi/efinet.c | 8 +-------
+ 1 file changed, 1 insertion(+), 7 deletions(-)
+
+diff --git a/grub-core/net/drivers/efi/efinet.c b/grub-core/net/drivers/efi/efinet.c
+index bb863e6..78df215 100644
+--- a/grub-core/net/drivers/efi/efinet.c
++++ b/grub-core/net/drivers/efi/efinet.c
+@@ -294,12 +294,6 @@ GRUB_MOD_FINI(efinet)
+ 
+   FOR_NET_CARDS_SAFE (card, next) 
+     if (card->driver == &efidriver)
+-      {
+-	grub_net_card_unregister (card);
+-	grub_free (card->txbuf);
+-	grub_free (card->rcvbuf);
+-	grub_free ((char *)card->name);
+-	grub_free (card);
+-      }
++      grub_net_card_unregister (card);
+ }
+ 
+-- 
+2.4.3
+
diff --git a/SOURCES/0162-efinet-skip-virtual-IPv4-and-IPv6-devices-when-enume.patch b/SOURCES/0162-efinet-skip-virtual-IPv4-and-IPv6-devices-when-enume.patch
new file mode 100644
index 0000000..f280428
--- /dev/null
+++ b/SOURCES/0162-efinet-skip-virtual-IPv4-and-IPv6-devices-when-enume.patch
@@ -0,0 +1,97 @@
+From 0faa80b06bc1e9956d7ee6aa3b23574b7c4c18c8 Mon Sep 17 00:00:00 2001
+From: Andrei Borzenkov <arvidjaar@gmail.com>
+Date: Thu, 7 May 2015 20:37:17 +0300
+Subject: [PATCH 05/23] efinet: skip virtual IPv4 and IPv6 devices when
+ enumerating cards
+
+EDK2 PXE driver creates two child devices - IPv4 and IPv6 - with
+bound SNP instance. This means we get three cards for every physical
+adapter when enumerating. Not only is this confusing, this may result
+in grub ignoring packets that come in via the "wrong" card.
+
+Example of device hierarchy is
+
+ Ctrl[91] PciRoot(0x0)/Pci(0x3,0x0)
+   Ctrl[95] PciRoot(0x0)/Pci(0x3,0x0)/MAC(525400123456,0x1)
+     Ctrl[B4] PciRoot(0x0)/Pci(0x3,0x0)/MAC(525400123456,0x1)/IPv4(0.0.0.0)
+     Ctrl[BC] PciRoot(0x0)/Pci(0x3,0x0)/MAC(525400123456,0x1)/IPv6(0000:0000:0000:0000:0000:0000:0000:0000)
+
+Skip PXE created virtual devices when enumerating cards. Make sure to
+find real card when applying initial autoconfiguration during PXE boot,
+this information is associated with one of child devices.
+---
+ grub-core/net/drivers/efi/efinet.c | 51 +++++++++++++++++++++++++++++++++++++-
+ 1 file changed, 50 insertions(+), 1 deletion(-)
+
+diff --git a/grub-core/net/drivers/efi/efinet.c b/grub-core/net/drivers/efi/efinet.c
+index 78df215..caa7b50 100644
+--- a/grub-core/net/drivers/efi/efinet.c
++++ b/grub-core/net/drivers/efi/efinet.c
+@@ -174,6 +174,29 @@ grub_efinet_findcards (void)
+     {
+       grub_efi_simple_network_t *net;
+       struct grub_net_card *card;
++      grub_efi_device_path_t *dp, *parent = NULL, *child = NULL;
++
++      /* EDK2 UEFI PXE driver creates IPv4 and IPv6 messaging devices as
++	 children of main MAC messaging device. We only need one device with
++	 bound SNP per physical card, otherwise they compete with each other
++	 when polling for incoming packets.
++       */
++      dp = grub_efi_get_device_path (*handle);
++      if (!dp)
++	continue;
++      for (; ! GRUB_EFI_END_ENTIRE_DEVICE_PATH (dp); dp = GRUB_EFI_NEXT_DEVICE_PATH (dp))
++	{
++	  parent = child;
++	  child = dp;
++	}
++      if (child
++	  && GRUB_EFI_DEVICE_PATH_TYPE (child) == GRUB_EFI_MESSAGING_DEVICE_PATH_TYPE
++	  && (GRUB_EFI_DEVICE_PATH_SUBTYPE (child) == GRUB_EFI_IPV4_DEVICE_PATH_SUBTYPE
++	      || GRUB_EFI_DEVICE_PATH_SUBTYPE (child) == GRUB_EFI_IPV6_DEVICE_PATH_SUBTYPE)
++	  && parent
++	  && GRUB_EFI_DEVICE_PATH_TYPE (parent) == GRUB_EFI_MESSAGING_DEVICE_PATH_TYPE
++	  && GRUB_EFI_DEVICE_PATH_SUBTYPE (parent) == GRUB_EFI_MAC_ADDRESS_DEVICE_PATH_SUBTYPE)
++	continue;
+ 
+       net = grub_efi_open_protocol (*handle, &net_io_guid,
+ 				    GRUB_EFI_OPEN_PROTOCOL_GET_PROTOCOL);
+@@ -252,7 +275,33 @@ grub_efi_net_config_real (grub_efi_handle_t hnd, char **device,
+     if (! cdp)
+       continue;
+     if (grub_efi_compare_device_paths (dp, cdp) != 0)
+-      continue;
++      {
++	grub_efi_device_path_t *ldp, *dup_dp, *dup_ldp;
++	int match;
++
++	/* EDK2 UEFI PXE driver creates pseudo devices with type IPv4/IPv6
++	   as children of Ethernet card and binds PXE and Load File protocols
++	   to it. Loaded Image Device Path protocol will point to these pseudo
++	   devices. We skip them when enumerating cards, so here we need to
++	   find matching MAC device.
++         */
++	ldp = grub_efi_find_last_device_path (dp);
++	if (GRUB_EFI_DEVICE_PATH_TYPE (ldp) != GRUB_EFI_MESSAGING_DEVICE_PATH_TYPE
++	    || (GRUB_EFI_DEVICE_PATH_SUBTYPE (ldp) != GRUB_EFI_IPV4_DEVICE_PATH_SUBTYPE
++		&& GRUB_EFI_DEVICE_PATH_SUBTYPE (ldp) != GRUB_EFI_IPV6_DEVICE_PATH_SUBTYPE))
++	  continue;
++	dup_dp = grub_efi_duplicate_device_path (dp);
++	if (!dup_dp)
++	  continue;
++	dup_ldp = grub_efi_find_last_device_path (dup_dp);
++	dup_ldp->type = GRUB_EFI_END_DEVICE_PATH_TYPE;
++	dup_ldp->subtype = GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE;
++	dup_ldp->length = sizeof (*dup_ldp);
++	match = grub_efi_compare_device_paths (dup_dp, cdp) == 0;
++	grub_free (dup_dp);
++	if (!match)
++	  continue;
++      }
+     pxe = grub_efi_open_protocol (hnd, &pxe_io_guid,
+ 				  GRUB_EFI_OPEN_PROTOCOL_GET_PROTOCOL);
+     if (! pxe)
+-- 
+2.4.3
+
diff --git a/SOURCES/0163-efinet-open-Simple-Network-Protocol-exclusively.patch b/SOURCES/0163-efinet-open-Simple-Network-Protocol-exclusively.patch
new file mode 100644
index 0000000..608f8cb
--- /dev/null
+++ b/SOURCES/0163-efinet-open-Simple-Network-Protocol-exclusively.patch
@@ -0,0 +1,89 @@
+From 0a84c5c3f0a50115372a61c68cc752367d669b07 Mon Sep 17 00:00:00 2001
+From: Andrei Borzenkov <arvidjaar@gmail.com>
+Date: Thu, 7 May 2015 20:37:17 +0300
+Subject: [PATCH 06/23] efinet: open Simple Network Protocol exclusively
+
+EDK2 network stack is based on Managed Network Protocol which is layered
+on top of Simple Management Protocol and does background polling. This
+polling races with grub for received (and probably trasmitted) packets
+which causes either serious slowdown or complete failure to load files.
+
+Open SNP device exclusively.  This destroys all child MNP instances and
+stops background polling.
+
+Exclusive open cannot be done when enumerating cards, as it would destroy
+PXE information we need to autoconfigure interface; and it cannot be done
+during autoconfiguration as we need to do it for non-PXE boot as well. So
+move SNP open to card ->open method and add matching ->close to clean up.
+
+Based on patch from Mark Salter <msalter@redhat.com>
+
+Also-By: Mark Salter <msalter@redhat.com>
+Closes: 41731
+---
+ grub-core/net/drivers/efi/efinet.c | 46 ++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 46 insertions(+)
+
+diff --git a/grub-core/net/drivers/efi/efinet.c b/grub-core/net/drivers/efi/efinet.c
+index caa7b50..6a1dd1f 100644
+--- a/grub-core/net/drivers/efi/efinet.c
++++ b/grub-core/net/drivers/efi/efinet.c
+@@ -142,9 +142,55 @@ get_card_packet (struct grub_net_card *dev)
+   return nb;
+ }
+ 
++static grub_err_t
++open_card (struct grub_net_card *dev)
++{
++  grub_efi_simple_network_t *net;
++
++  /* Try to reopen SNP exlusively to close any active MNP protocol instance
++     that may compete for packet polling
++   */
++  net = grub_efi_open_protocol (dev->efi_handle, &net_io_guid,
++				GRUB_EFI_OPEN_PROTOCOL_BY_EXCLUSIVE);
++  if (net)
++    {
++      if (net->mode->state == GRUB_EFI_NETWORK_STOPPED
++	  && efi_call_1 (net->start, net) != GRUB_EFI_SUCCESS)
++	return grub_error (GRUB_ERR_NET_NO_CARD, "%s: net start failed",
++			   dev->name);
++
++      if (net->mode->state == GRUB_EFI_NETWORK_STOPPED)
++	return grub_error (GRUB_ERR_NET_NO_CARD, "%s: card stopped",
++			   dev->name);
++
++      if (net->mode->state == GRUB_EFI_NETWORK_STARTED
++	  && efi_call_3 (net->initialize, net, 0, 0) != GRUB_EFI_SUCCESS)
++	return grub_error (GRUB_ERR_NET_NO_CARD, "%s: net initialize failed",
++			   dev->name);
++
++      efi_call_4 (grub_efi_system_table->boot_services->close_protocol,
++		  dev->efi_net, &net_io_guid,
++		  grub_efi_image_handle, dev->efi_handle);
++      dev->efi_net = net;
++    }
++
++  /* If it failed we just try to run as best as we can */
++  return GRUB_ERR_NONE;
++}
++
++static void
++close_card (struct grub_net_card *dev)
++{
++  efi_call_4 (grub_efi_system_table->boot_services->close_protocol,
++	      dev->efi_net, &net_io_guid,
++	      grub_efi_image_handle, dev->efi_handle);
++}
++
+ static struct grub_net_card_driver efidriver =
+   {
+     .name = "efinet",
++    .open = open_card,
++    .close = close_card,
+     .send = send_card_buffer,
+     .recv = get_card_packet
+   };
+-- 
+2.4.3
+
diff --git a/SOURCES/0164-efinet-enable-hardware-filters-when-opening-interfac.patch b/SOURCES/0164-efinet-enable-hardware-filters-when-opening-interfac.patch
new file mode 100644
index 0000000..4c91618
--- /dev/null
+++ b/SOURCES/0164-efinet-enable-hardware-filters-when-opening-interfac.patch
@@ -0,0 +1,107 @@
+From 2c38daa48daebd9b5ebfbb94a9c451b00c9f251c Mon Sep 17 00:00:00 2001
+From: Andrei Borzenkov <arvidjaar@gmail.com>
+Date: Tue, 16 Jun 2015 19:52:45 +0300
+Subject: [PATCH 07/23] efinet: enable hardware filters when opening interface
+
+Exclusive open on SNP will close all existing protocol instances which
+may disable all receive filters on interface. Reinstall them after we
+opened protocol exclusively.
+
+Also follow UEFI specification recommendation and stop interfaces when
+closing them:
+
+Unexpected system errors, reboots and hangs can occur if an OS is loaded
+and the network devices are not Shutdown() and Stopped().
+
+Also by: Mark Salter <msalter@redhat.com>
+Closes: 45204
+---
+ grub-core/net/drivers/efi/efinet.c | 25 +++++++++++++++++++++++++
+ include/grub/efi/api.h             | 20 +++++++++++++++++---
+ 2 files changed, 42 insertions(+), 3 deletions(-)
+
+diff --git a/grub-core/net/drivers/efi/efinet.c b/grub-core/net/drivers/efi/efinet.c
+index 6a1dd1f..7b8c4a5 100644
+--- a/grub-core/net/drivers/efi/efinet.c
++++ b/grub-core/net/drivers/efi/efinet.c
+@@ -168,6 +168,29 @@ open_card (struct grub_net_card *dev)
+ 	return grub_error (GRUB_ERR_NET_NO_CARD, "%s: net initialize failed",
+ 			   dev->name);
+ 
++      /* Enable hardware receive filters if driver declares support for it.
++	 We need unicast and broadcast and additionaly all nodes and
++	 solicited multicast for IPv6. Solicited multicast is per-IPv6
++	 address and we currently do not have API to do it so simply
++	 try to enable receive of all multicast packets or evertyhing in
++	 the worst case (i386 PXE driver always enables promiscuous too).
++
++	 This does trust firmware to do what it claims to do.
++       */
++      if (net->mode->receive_filter_mask)
++	{
++	  grub_uint32_t filters = GRUB_EFI_SIMPLE_NETWORK_RECEIVE_UNICAST   |
++				  GRUB_EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST |
++				  GRUB_EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST;
++
++	  filters &= net->mode->receive_filter_mask;
++	  if (!(filters & GRUB_EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST))
++	    filters |= (net->mode->receive_filter_mask &
++			GRUB_EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS);
++
++	  efi_call_6 (net->receive_filters, net, filters, 0, 0, 0, NULL);
++	}
++
+       efi_call_4 (grub_efi_system_table->boot_services->close_protocol,
+ 		  dev->efi_net, &net_io_guid,
+ 		  grub_efi_image_handle, dev->efi_handle);
+@@ -181,6 +204,8 @@ open_card (struct grub_net_card *dev)
+ static void
+ close_card (struct grub_net_card *dev)
+ {
++  efi_call_1 (dev->efi_net->shutdown, dev->efi_net);
++  efi_call_1 (dev->efi_net->stop, dev->efi_net);
+   efi_call_4 (grub_efi_system_table->boot_services->close_protocol,
+ 	      dev->efi_net, &net_io_guid,
+ 	      grub_efi_image_handle, dev->efi_handle);
+diff --git a/include/grub/efi/api.h b/include/grub/efi/api.h
+index 1423403..029ee92 100644
+--- a/include/grub/efi/api.h
++++ b/include/grub/efi/api.h
+@@ -1564,17 +1564,31 @@ enum
+     GRUB_EFI_NETWORK_INITIALIZED,
+   };
+ 
++enum
++  {
++    GRUB_EFI_SIMPLE_NETWORK_RECEIVE_UNICAST		  = 0x01,
++    GRUB_EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST		  = 0x02,
++    GRUB_EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST		  = 0x04,
++    GRUB_EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS		  = 0x08,
++    GRUB_EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST = 0x10,
++  };
++
+ struct grub_efi_simple_network
+ {
+   grub_uint64_t revision;
+   grub_efi_status_t (*start) (struct grub_efi_simple_network *this);
+-  void (*stop) (void);
++  grub_efi_status_t (*stop) (struct grub_efi_simple_network *this);
+   grub_efi_status_t (*initialize) (struct grub_efi_simple_network *this,
+ 				   grub_efi_uintn_t extra_rx,
+ 				   grub_efi_uintn_t extra_tx);
+   void (*reset) (void);
+-  void (*shutdown) (void);
+-  void (*receive_filters) (void);
++  grub_efi_status_t (*shutdown) (struct grub_efi_simple_network *this);
++  grub_efi_status_t (*receive_filters) (struct grub_efi_simple_network *this,
++					grub_uint32_t enable,
++					grub_uint32_t disable,
++					grub_efi_boolean_t reset_mcast_filter,
++					grub_efi_uintn_t mcast_filter_count,
++					grub_efi_mac_address_t *mcast_filter);
+   void (*station_address) (void);
+   void (*statistics) (void);
+   void (*mcastiptomac) (void);
+-- 
+2.4.3
+
diff --git a/SOURCES/0165-efinet-handle-get_status-on-buggy-firmware-properly.patch b/SOURCES/0165-efinet-handle-get_status-on-buggy-firmware-properly.patch
new file mode 100644
index 0000000..803a5ab
--- /dev/null
+++ b/SOURCES/0165-efinet-handle-get_status-on-buggy-firmware-properly.patch
@@ -0,0 +1,66 @@
+From 17bd27e298d2b27859c8c6ee2e654d8f03988c42 Mon Sep 17 00:00:00 2001
+From: Josef Bacik <jbacik@fb.com>
+Date: Thu, 6 Aug 2015 10:49:46 -0700
+Subject: [PATCH 08/23] efinet: handle get_status() on buggy firmware properly
+
+The EFI spec indicates that get_status() should return the address of the buffer
+we passed into transmit to indicate the the buffer was transmitted.  However we
+have boxes where the firmware returns some arbitrary address instead, which
+makes grub think that we've not sent anything.  So since we have the SNP stuff
+opened in exclusive mode just assume any non-NULL txbuf means that our transmit
+occurred properly.  This makes grub able to do its networking stuff properly on
+our broken firmware.  Thanks,
+
+cc: Peter Jones <pjones@redhat.com>
+Signed-off-by: Josef Bacik <jbacik@fb.com>
+---
+ grub-core/net/drivers/efi/efinet.c | 21 +++++++++++----------
+ 1 file changed, 11 insertions(+), 10 deletions(-)
+
+diff --git a/grub-core/net/drivers/efi/efinet.c b/grub-core/net/drivers/efi/efinet.c
+index 7b8c4a5..ea0e0ca 100644
+--- a/grub-core/net/drivers/efi/efinet.c
++++ b/grub-core/net/drivers/efi/efinet.c
+@@ -47,19 +47,19 @@ send_card_buffer (struct grub_net_card *dev,
+ 	if (st != GRUB_EFI_SUCCESS)
+ 	  return grub_error (GRUB_ERR_IO,
+ 			     N_("couldn't send network packet"));
+-	if (txbuf == dev->txbuf)
++	/*
++	   Some buggy firmware could return an arbitrary address instead of the
++	   txbuf address we trasmitted, so just check that txbuf is non NULL
++	   for success.  This is ok because we open the SNP protocol in
++	   exclusive mode so we know we're the only ones transmitting on this
++	   box and since we only transmit one packet at a time we know our
++	   transmit was successfull.
++	 */
++	if (txbuf)
+ 	  {
+ 	    dev->txbusy = 0;
+ 	    break;
+ 	  }
+-	if (txbuf)
+-	  {
+-	    st = efi_call_7 (net->transmit, net, 0, dev->last_pkt_size,
+-			     dev->txbuf, NULL, NULL, NULL);
+-	    if (st != GRUB_EFI_SUCCESS)
+-	      return grub_error (GRUB_ERR_IO,
+-				 N_("couldn't send network packet"));
+-	  }
+ 	if (limit_time < grub_get_time_ms ())
+ 	  return grub_error (GRUB_ERR_TIMEOUT,
+ 			     N_("couldn't send network packet"));
+@@ -84,8 +84,9 @@ send_card_buffer (struct grub_net_card *dev,
+      we run in the GRUB_ERR_TIMEOUT case above.
+      Perhaps a timeout in the FW has discarded the recycle buffer.
+    */
++  txbuf = NULL;
+   st = efi_call_3 (net->get_status, net, 0, &txbuf);
+-  dev->txbusy = !(st == GRUB_EFI_SUCCESS && txbuf == dev->txbuf);
++  dev->txbusy = !(st == GRUB_EFI_SUCCESS && txbuf);
+ 
+   return GRUB_ERR_NONE;
+ }
+-- 
+2.4.3
+
diff --git a/SOURCES/0166-Handle-rssd-storage-devices.patch b/SOURCES/0166-Handle-rssd-storage-devices.patch
new file mode 100644
index 0000000..14754c7
--- /dev/null
+++ b/SOURCES/0166-Handle-rssd-storage-devices.patch
@@ -0,0 +1,39 @@
+From 1ab087435c259702c62fdfe85e28f3e3f2459266 Mon Sep 17 00:00:00 2001
+From: Peter Jones <pjones@redhat.com>
+Date: Tue, 30 Jun 2015 15:50:41 -0400
+Subject: [PATCH 09/23] Handle rssd storage devices.
+
+Resolves: rhbz#1087962
+
+Signed-off-by: Peter Jones <pjones@redhat.com>
+---
+ grub-core/osdep/linux/getroot.c | 13 +++++++++++++
+ 1 file changed, 13 insertions(+)
+
+diff --git a/grub-core/osdep/linux/getroot.c b/grub-core/osdep/linux/getroot.c
+index 7007193..5987d07 100644
+--- a/grub-core/osdep/linux/getroot.c
++++ b/grub-core/osdep/linux/getroot.c
+@@ -884,6 +884,19 @@ grub_util_part_to_disk (const char *os_dev, struct stat *st,
+ 	  return path;
+ 	}
+ 
++      /* If this is an rssd device. */
++      if ((strncmp ("rssd", p, 4) == 0) && p[4] >= 'a' && p[4] <= 'z')
++	{
++	  char *pp = p + 4;
++	  while (*pp >= 'a' && *pp <= 'z')
++	    pp++;
++	  if (*pp)
++	    *is_part = 1;
++	  /* /dev/rssd[a-z]+[0-9]* */
++	  *pp = '\0';
++	  return path;
++	}
++
+       /* If this is a loop device */
+       if ((strncmp ("loop", p, 4) == 0) && p[4] >= '0' && p[4] <= '9')
+ 	{
+-- 
+2.4.3
+
diff --git a/SOURCES/0167-xfs-Fix-termination-loop-for-directory-iteration.patch b/SOURCES/0167-xfs-Fix-termination-loop-for-directory-iteration.patch
new file mode 100644
index 0000000..6f4521b
--- /dev/null
+++ b/SOURCES/0167-xfs-Fix-termination-loop-for-directory-iteration.patch
@@ -0,0 +1,32 @@
+From 6afb93f24d48ff10d4266396b079b79033e05b0a Mon Sep 17 00:00:00 2001
+From: Jan Kara <jack@suse.cz>
+Date: Mon, 14 Jul 2014 17:21:29 +0200
+Subject: [PATCH 10/23] xfs: Fix termination loop for directory iteration
+
+Directory iteration used wrong position (sizeof wrong structure) for
+termination of iteration inside a directory block. Luckily the position
+ended up being wrong by just 1 byte and directory entries are larger so
+things worked out fine in practice. But fix the problem anyway.
+
+Signed-off-by: Jan Kara <jack@suse.cz>
+---
+ grub-core/fs/xfs.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/grub-core/fs/xfs.c b/grub-core/fs/xfs.c
+index 16ffd3f..4bd52d1 100644
+--- a/grub-core/fs/xfs.c
++++ b/grub-core/fs/xfs.c
+@@ -603,8 +603,7 @@ grub_xfs_iterate_dir (grub_fshelp_node_t dir,
+ 		       - grub_be_to_cpu32 (tail->leaf_stale));
+ 
+ 	    /* Iterate over all entries within this block.  */
+-	    while (pos < (dirblk_size
+-			  - (int) sizeof (struct grub_xfs_dir2_entry)))
++	    while (pos < tail_start)
+ 	      {
+ 		struct grub_xfs_dir2_entry *direntry;
+ 		grub_uint8_t *freetag;
+-- 
+2.4.3
+
diff --git a/SOURCES/0168-xfs-Convert-inode-numbers-to-cpu-endianity-immediate.patch b/SOURCES/0168-xfs-Convert-inode-numbers-to-cpu-endianity-immediate.patch
new file mode 100644
index 0000000..01dbad0
--- /dev/null
+++ b/SOURCES/0168-xfs-Convert-inode-numbers-to-cpu-endianity-immediate.patch
@@ -0,0 +1,82 @@
+From 54a4f53f9ecae2378195e4e66a8410d3862a0be2 Mon Sep 17 00:00:00 2001
+From: Jan Kara <jack@suse.cz>
+Date: Mon, 14 Jul 2014 17:21:30 +0200
+Subject: [PATCH 11/23] xfs: Convert inode numbers to cpu endianity immediately
+ after reading
+
+Currently XFS driver converted inode numbers to native endianity only
+when using them to compute inode position. Although this works, it is
+somewhat confusing. So convert inode numbers when reading them from disk
+structures as every other field.
+
+Signed-off-by: Jan Kara <jack@suse.cz>
+---
+ grub-core/fs/xfs.c | 13 ++++++-------
+ 1 file changed, 6 insertions(+), 7 deletions(-)
+
+diff --git a/grub-core/fs/xfs.c b/grub-core/fs/xfs.c
+index 4bd52d1..0d704e9 100644
+--- a/grub-core/fs/xfs.c
++++ b/grub-core/fs/xfs.c
+@@ -180,14 +180,14 @@ static inline grub_uint64_t
+ GRUB_XFS_INO_INOINAG (struct grub_xfs_data *data,
+ 		      grub_uint64_t ino)
+ {
+-  return (grub_be_to_cpu64 (ino) & ((1LL << GRUB_XFS_INO_AGBITS (data)) - 1));
++  return (ino & ((1LL << GRUB_XFS_INO_AGBITS (data)) - 1));
+ }
+ 
+ static inline grub_uint64_t
+ GRUB_XFS_INO_AG (struct grub_xfs_data *data,
+ 		 grub_uint64_t ino)
+ {
+-  return (grub_be_to_cpu64 (ino) >> GRUB_XFS_INO_AGBITS (data));
++  return (ino >> GRUB_XFS_INO_AGBITS (data));
+ }
+ 
+ static inline grub_disk_addr_t
+@@ -506,13 +506,12 @@ grub_xfs_iterate_dir (grub_fshelp_node_t dir,
+ 	if (smallino)
+ 	  {
+ 	    parent = grub_be_to_cpu32 (diro->inode.data.dir.dirhead.parent.i4);
+-	    parent = grub_cpu_to_be64 (parent);
+ 	    /* The header is a bit smaller than usual.  */
+ 	    de = (struct grub_xfs_dir_entry *) ((char *) de - 4);
+ 	  }
+ 	else
+ 	  {
+-	    parent = diro->inode.data.dir.dirhead.parent.i8;
++	    parent = grub_be_to_cpu64(diro->inode.data.dir.dirhead.parent.i8);
+ 	  }
+ 
+ 	/* Synthesize the direntries for `.' and `..'.  */
+@@ -545,7 +544,6 @@ grub_xfs_iterate_dir (grub_fshelp_node_t dir,
+ 		| (((grub_uint64_t) inopos[5]) << 16)
+ 		| (((grub_uint64_t) inopos[6]) << 8)
+ 		| (((grub_uint64_t) inopos[7]) << 0);
+-	    ino = grub_cpu_to_be64 (ino);
+ 
+ 	    c = de->name[de->len];
+ 	    de->name[de->len] = '\0';
+@@ -627,7 +625,8 @@ grub_xfs_iterate_dir (grub_fshelp_node_t dir,
+ 		   is not used by GRUB.  So it can be overwritten.  */
+ 		filename[direntry->len] = '\0';
+ 
+-		if (iterate_dir_call_hook (direntry->inode, filename, &ctx))
++		if (iterate_dir_call_hook (grub_be_to_cpu64(direntry->inode), 
++					   filename, &ctx))
+ 		  {
+ 		    grub_free (dirblock);
+ 		    return 1;
+@@ -689,7 +688,7 @@ grub_xfs_mount (grub_disk_t disk)
+     goto fail;
+ 
+   data->diropen.data = data;
+-  data->diropen.ino = data->sblock.rootino;
++  data->diropen.ino = grub_be_to_cpu64(data->sblock.rootino);
+   data->diropen.inode_read = 1;
+   data->bsize = grub_be_to_cpu32 (data->sblock.bsize);
+   data->agsize = grub_be_to_cpu32 (data->sblock.agsize);
+-- 
+2.4.3
+
diff --git a/SOURCES/0169-xfs-Add-helpers-for-inode-size.patch b/SOURCES/0169-xfs-Add-helpers-for-inode-size.patch
new file mode 100644
index 0000000..89b1257
--- /dev/null
+++ b/SOURCES/0169-xfs-Add-helpers-for-inode-size.patch
@@ -0,0 +1,97 @@
+From bc7e3f1e508c91b9ad7d3459998c5cd31d1caca0 Mon Sep 17 00:00:00 2001
+From: Jan Kara <jack@suse.cz>
+Date: Mon, 1 Jun 2015 14:28:45 +0200
+Subject: [PATCH 12/23] xfs: Add helpers for inode size
+
+Add helpers to return size of XFS inode on disk and when loaded in
+memory.
+
+Signed-off-by: Jan Kara <jack@suse.cz>
+---
+ grub-core/fs/xfs.c | 35 ++++++++++++++++++++++++-----------
+ 1 file changed, 24 insertions(+), 11 deletions(-)
+
+diff --git a/grub-core/fs/xfs.c b/grub-core/fs/xfs.c
+index 0d704e9..26d8147 100644
+--- a/grub-core/fs/xfs.c
++++ b/grub-core/fs/xfs.c
+@@ -255,6 +255,24 @@ grub_xfs_inode_offset (struct grub_xfs_data *data,
+ 	  data->sblock.log2_inode);
+ }
+ 
++static inline grub_size_t
++grub_xfs_inode_size(struct grub_xfs_data *data)
++{
++  return 1 << data->sblock.log2_inode;
++}
++
++/*
++ * Returns size occupied by XFS inode stored in memory - we store struct
++ * grub_fshelp_node there but on disk inode size may be actually larger than
++ * struct grub_xfs_inode so we need to account for that so that we can read
++ * from disk directly into in-memory structure.
++ */
++static inline grub_size_t
++grub_xfs_fshelp_size(struct grub_xfs_data *data)
++{
++  return sizeof (struct grub_fshelp_node) - sizeof (struct grub_xfs_inode)
++	       + grub_xfs_inode_size(data);
++}
+ 
+ static grub_err_t
+ grub_xfs_read_inode (struct grub_xfs_data *data, grub_uint64_t ino,
+@@ -264,8 +282,8 @@ grub_xfs_read_inode (struct grub_xfs_data *data, grub_uint64_t ino,
+   int offset = grub_xfs_inode_offset (data, ino);
+ 
+   /* Read the inode.  */
+-  if (grub_disk_read (data->disk, block, offset,
+-		      1 << data->sblock.log2_inode, inode))
++  if (grub_disk_read (data->disk, block, offset, grub_xfs_inode_size(data),
++		      inode))
+     return grub_errno;
+ 
+   if (grub_strncmp ((char *) inode->magic, "IN", 2))
+@@ -297,7 +315,7 @@ grub_xfs_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock)
+       if (node->inode.fork_offset)
+ 	recoffset = (node->inode.fork_offset - 1) / 2;
+       else
+-	recoffset = ((1 << node->data->sblock.log2_inode)
++	recoffset = (grub_xfs_inode_size(node->data)
+ 		     - ((char *) &node->inode.data.btree.keys
+ 			- (char *) &node->inode))
+ 	  / (2 * sizeof (grub_uint64_t));
+@@ -456,9 +474,7 @@ static int iterate_dir_call_hook (grub_uint64_t ino, const char *filename,
+   struct grub_fshelp_node *fdiro;
+   grub_err_t err;
+ 
+-  fdiro = grub_malloc (sizeof (struct grub_fshelp_node)
+-		       - sizeof (struct grub_xfs_inode)
+-		       + (1 << ctx->diro->data->sblock.log2_inode) + 1);
++  fdiro = grub_malloc (grub_xfs_fshelp_size(ctx->diro->data) + 1);
+   if (!fdiro)
+     {
+       grub_print_error ();
+@@ -682,7 +698,7 @@ grub_xfs_mount (grub_disk_t disk)
+   data = grub_realloc (data,
+ 		       sizeof (struct grub_xfs_data)
+ 		       - sizeof (struct grub_xfs_inode)
+-		       + (1 << data->sblock.log2_inode) + 1);
++		       + grub_xfs_inode_size(data) + 1);
+ 
+   if (! data)
+     goto fail;
+@@ -797,10 +813,7 @@ grub_xfs_open (struct grub_file *file, const char *name)
+ 
+   if (fdiro != &data->diropen)
+     {
+-      grub_memcpy (&data->diropen, fdiro,
+-		   sizeof (struct grub_fshelp_node)
+-		   - sizeof (struct grub_xfs_inode)
+-		   + (1 << data->sblock.log2_inode));
++      grub_memcpy (&data->diropen, fdiro, grub_xfs_fshelp_size(data));
+       grub_free (fdiro);
+     }
+ 
+-- 
+2.4.3
+
diff --git a/SOURCES/0170-xfs-V5-filesystem-format-support.patch b/SOURCES/0170-xfs-V5-filesystem-format-support.patch
new file mode 100644
index 0000000..36d6a39
--- /dev/null
+++ b/SOURCES/0170-xfs-V5-filesystem-format-support.patch
@@ -0,0 +1,579 @@
+From f9187f5eef9776ba51dca88e347bfd6675787cb6 Mon Sep 17 00:00:00 2001
+From: Jan Kara <jack@suse.cz>
+Date: Mon, 1 Jun 2015 14:28:46 +0200
+Subject: [PATCH 13/23] xfs: V5 filesystem format support
+
+Add support for new XFS on disk format. We have to handle optional
+filetype fields in directory entries, additional CRC, LSN, UUID entries
+in some structures, etc.
+
+Signed-off-by: Jan Kara <jack@suse.cz>
+---
+ grub-core/fs/xfs.c | 332 ++++++++++++++++++++++++++++++++++++++++-------------
+ 1 file changed, 252 insertions(+), 80 deletions(-)
+
+diff --git a/grub-core/fs/xfs.c b/grub-core/fs/xfs.c
+index 26d8147..f00e43e 100644
+--- a/grub-core/fs/xfs.c
++++ b/grub-core/fs/xfs.c
+@@ -34,6 +34,50 @@ GRUB_MOD_LICENSE ("GPLv3+");
+ #define XFS_INODE_FORMAT_EXT	2
+ #define XFS_INODE_FORMAT_BTREE	3
+ 
++/* Superblock version field flags */
++#define XFS_SB_VERSION_NUMBITS		0x000f
++#define	XFS_SB_VERSION_ATTRBIT		0x0010
++#define	XFS_SB_VERSION_NLINKBIT		0x0020
++#define	XFS_SB_VERSION_QUOTABIT		0x0040
++#define	XFS_SB_VERSION_ALIGNBIT		0x0080
++#define	XFS_SB_VERSION_DALIGNBIT	0x0100
++#define	XFS_SB_VERSION_LOGV2BIT		0x0400
++#define	XFS_SB_VERSION_SECTORBIT	0x0800
++#define	XFS_SB_VERSION_EXTFLGBIT	0x1000
++#define	XFS_SB_VERSION_DIRV2BIT		0x2000
++#define XFS_SB_VERSION_MOREBITSBIT	0x8000
++#define XFS_SB_VERSION_BITS_SUPPORTED \
++	(XFS_SB_VERSION_NUMBITS | \
++	 XFS_SB_VERSION_ATTRBIT | \
++	 XFS_SB_VERSION_NLINKBIT | \
++	 XFS_SB_VERSION_QUOTABIT | \
++	 XFS_SB_VERSION_ALIGNBIT | \
++	 XFS_SB_VERSION_DALIGNBIT | \
++	 XFS_SB_VERSION_LOGV2BIT | \
++	 XFS_SB_VERSION_SECTORBIT | \
++	 XFS_SB_VERSION_EXTFLGBIT | \
++	 XFS_SB_VERSION_DIRV2BIT | \
++	 XFS_SB_VERSION_MOREBITSBIT)
++
++/* Recognized xfs format versions */
++#define XFS_SB_VERSION_4		4	/* Good old XFS filesystem */
++#define XFS_SB_VERSION_5		5	/* CRC enabled filesystem */
++
++/* features2 field flags */
++#define XFS_SB_VERSION2_LAZYSBCOUNTBIT	0x00000002	/* Superblk counters */
++#define XFS_SB_VERSION2_ATTR2BIT	0x00000008	/* Inline attr rework */
++#define XFS_SB_VERSION2_PROJID32BIT	0x00000080	/* 32-bit project ids */
++#define XFS_SB_VERSION2_FTYPE		0x00000200	/* inode type in dir */
++#define XFS_SB_VERSION2_BITS_SUPPORTED \
++	(XFS_SB_VERSION2_LAZYSBCOUNTBIT | \
++	 XFS_SB_VERSION2_ATTR2BIT | \
++	 XFS_SB_VERSION2_PROJID32BIT | \
++	 XFS_SB_VERSION2_FTYPE)
++
++/* incompat feature flags */
++#define XFS_SB_FEAT_INCOMPAT_FTYPE      (1 << 0)        /* filetype in dirent */
++#define XFS_SB_FEAT_INCOMPAT_SUPPORTED \
++	(XFS_SB_FEAT_INCOMPAT_FTYPE)
+ 
+ struct grub_xfs_sblock
+ {
+@@ -45,7 +89,9 @@ struct grub_xfs_sblock
+   grub_uint64_t rootino;
+   grub_uint8_t unused3[20];
+   grub_uint32_t agsize;
+-  grub_uint8_t unused4[20];
++  grub_uint8_t unused4[12];
++  grub_uint16_t version;
++  grub_uint8_t unused5[6];
+   grub_uint8_t label[12];
+   grub_uint8_t log2_bsize;
+   grub_uint8_t log2_sect;
+@@ -54,12 +100,19 @@ struct grub_xfs_sblock
+   grub_uint8_t log2_agblk;
+   grub_uint8_t unused6[67];
+   grub_uint8_t log2_dirblk;
++  grub_uint8_t unused7[7];
++  grub_uint32_t features2;
++  grub_uint8_t unused8[4];
++  grub_uint32_t sb_features_compat;
++  grub_uint32_t sb_features_ro_compat;
++  grub_uint32_t sb_features_incompat;
++  grub_uint32_t sb_features_log_incompat;
+ } GRUB_PACKED;
+ 
+ struct grub_xfs_dir_header
+ {
+   grub_uint8_t count;
+-  grub_uint8_t smallino;
++  grub_uint8_t largeino;
+   union
+   {
+     grub_uint32_t i4;
+@@ -67,14 +120,16 @@ struct grub_xfs_dir_header
+   } GRUB_PACKED parent;
+ } GRUB_PACKED;
+ 
++/* Structure for directory entry inlined in the inode */
+ struct grub_xfs_dir_entry
+ {
+   grub_uint8_t len;
+   grub_uint16_t offset;
+   char name[1];
+-  /* Inode number follows, 32 bits.  */
++  /* Inode number follows, 32 / 64 bits.  */
+ } GRUB_PACKED;
+ 
++/* Structure for directory entry in a block */
+ struct grub_xfs_dir2_entry
+ {
+   grub_uint64_t inode;
+@@ -90,7 +145,8 @@ struct grub_xfs_btree_node
+   grub_uint16_t numrecs;
+   grub_uint64_t left;
+   grub_uint64_t right;
+-  grub_uint64_t keys[1];
++  /* In V5 here follow crc, uuid, etc. */
++  /* Then follow keys and block pointers */
+ }  GRUB_PACKED;
+ 
+ struct grub_xfs_btree_root
+@@ -123,19 +179,11 @@ struct grub_xfs_inode
+   grub_uint16_t unused3;
+   grub_uint8_t fork_offset;
+   grub_uint8_t unused4[17];
+-  union
+-  {
+-    char raw[156];
+-    struct dir
+-    {
+-      struct grub_xfs_dir_header dirhead;
+-      struct grub_xfs_dir_entry direntry[1];
+-    } dir;
+-    grub_xfs_extent extents[XFS_INODE_EXTENTS];
+-    struct grub_xfs_btree_root btree;
+-  } GRUB_PACKED data;
+ } GRUB_PACKED;
+ 
++#define XFS_V2_INODE_SIZE sizeof(struct grub_xfs_inode)
++#define XFS_V3_INODE_SIZE (XFS_V2_INODE_SIZE + 76)
++
+ struct grub_xfs_dirblock_tail
+ {
+   grub_uint32_t leaf_count;
+@@ -157,6 +205,8 @@ struct grub_xfs_data
+   int pos;
+   int bsize;
+   grub_uint32_t agsize;
++  unsigned int hasftype:1;
++  unsigned int hascrc:1;
+   struct grub_fshelp_node diropen;
+ };
+ 
+@@ -164,6 +214,71 @@ static grub_dl_t my_mod;
+ 
+ 
+ 
++static int grub_xfs_sb_hascrc(struct grub_xfs_data *data)
++{
++  return (data->sblock.version & grub_cpu_to_be16_compile_time(XFS_SB_VERSION_NUMBITS)) ==
++	  grub_cpu_to_be16_compile_time(XFS_SB_VERSION_5);
++}
++
++static int grub_xfs_sb_hasftype(struct grub_xfs_data *data)
++{
++  if ((data->sblock.version & grub_cpu_to_be16_compile_time(XFS_SB_VERSION_NUMBITS)) ==
++	grub_cpu_to_be16_compile_time(XFS_SB_VERSION_5) &&
++      data->sblock.sb_features_incompat & grub_cpu_to_be32_compile_time(XFS_SB_FEAT_INCOMPAT_FTYPE))
++    return 1;
++  if (data->sblock.version & grub_cpu_to_be16_compile_time(XFS_SB_VERSION_MOREBITSBIT) &&
++      data->sblock.features2 & grub_cpu_to_be32_compile_time(XFS_SB_VERSION2_FTYPE))
++    return 1;
++  return 0;
++}
++
++static int grub_xfs_sb_valid(struct grub_xfs_data *data)
++{
++  grub_dprintf("xfs", "Validating superblock\n");
++  if (grub_strncmp ((char *) (data->sblock.magic), "XFSB", 4)
++      || data->sblock.log2_bsize < GRUB_DISK_SECTOR_BITS
++      || ((int) data->sblock.log2_bsize
++	  + (int) data->sblock.log2_dirblk) >= 27)
++    {
++      grub_error (GRUB_ERR_BAD_FS, "not a XFS filesystem");
++      return 0;
++    }
++  if ((data->sblock.version & grub_cpu_to_be16_compile_time(XFS_SB_VERSION_NUMBITS)) ==
++       grub_cpu_to_be16_compile_time(XFS_SB_VERSION_5))
++    {
++      grub_dprintf("xfs", "XFS v5 superblock detected\n");
++      if (data->sblock.sb_features_incompat &
++          grub_cpu_to_be32_compile_time(~XFS_SB_FEAT_INCOMPAT_SUPPORTED))
++        {
++	  grub_error (GRUB_ERR_BAD_FS, "XFS filesystem has unsupported "
++		      "incompatible features");
++	  return 0;
++        }
++      return 1;
++    }
++  else if ((data->sblock.version & grub_cpu_to_be16_compile_time(XFS_SB_VERSION_NUMBITS)) ==
++	   grub_cpu_to_be16_compile_time(XFS_SB_VERSION_4))
++    {
++      grub_dprintf("xfs", "XFS v4 superblock detected\n");
++      if (!(data->sblock.version & grub_cpu_to_be16_compile_time(XFS_SB_VERSION_DIRV2BIT)))
++	{
++	  grub_error (GRUB_ERR_BAD_FS, "XFS filesystem without V2 directories "
++		      "is unsupported");
++	  return 0;
++	}
++      if (data->sblock.version & grub_cpu_to_be16_compile_time(~XFS_SB_VERSION_BITS_SUPPORTED) ||
++	  (data->sblock.version & grub_cpu_to_be16_compile_time(XFS_SB_VERSION_MOREBITSBIT) &&
++	   data->sblock.features2 & grub_cpu_to_be16_compile_time(~XFS_SB_VERSION2_BITS_SUPPORTED)))
++	{
++	  grub_error (GRUB_ERR_BAD_FS, "XFS filesystem has unsupported version "
++		      "bits");
++	  return 0;
++	}
++      return 1;
++    }
++  return 0;
++}
++
+ /* Filetype information as used in inodes.  */
+ #define FILETYPE_INO_MASK	0170000
+ #define FILETYPE_INO_REG	0100000
+@@ -219,18 +334,6 @@ GRUB_XFS_EXTENT_SIZE (grub_xfs_extent *exts, int ex)
+   return (grub_be_to_cpu32 (exts[ex][3]) & ((1 << 21) - 1));
+ }
+ 
+-static inline int
+-GRUB_XFS_ROUND_TO_DIRENT (int pos)
+-{
+-  return ((((pos) + 8 - 1) / 8) * 8);
+-}
+-
+-static inline int
+-GRUB_XFS_NEXT_DIRENT (int pos, int len)
+-{
+-  return (pos) + GRUB_XFS_ROUND_TO_DIRENT (8 + 1 + len + 2);
+-}
+-
+ 
+ static inline grub_uint64_t
+ grub_xfs_inode_block (struct grub_xfs_data *data,
+@@ -274,6 +377,85 @@ grub_xfs_fshelp_size(struct grub_xfs_data *data)
+ 	       + grub_xfs_inode_size(data);
+ }
+ 
++static void *
++grub_xfs_inode_data(struct grub_xfs_inode *inode)
++{
++	if (inode->version <= 2)
++		return ((char *)inode) + XFS_V2_INODE_SIZE;
++	return ((char *)inode) + XFS_V3_INODE_SIZE;
++}
++
++static struct grub_xfs_dir_entry *
++grub_xfs_inline_de(struct grub_xfs_dir_header *head)
++{
++	/*
++	 * With small inode numbers the header is 4 bytes smaller because of
++	 * smaller parent pointer
++	 */
++	return (void *)(((char *)head) + sizeof(struct grub_xfs_dir_header) -
++		(head->largeino ? 0 : sizeof(grub_uint32_t)));
++}
++
++static grub_uint8_t *
++grub_xfs_inline_de_inopos(struct grub_xfs_data *data,
++			  struct grub_xfs_dir_entry *de)
++{
++	return ((grub_uint8_t *)(de + 1)) + de->len - 1 +
++		 (data->hasftype ? 1 : 0);
++}
++
++static struct grub_xfs_dir_entry *
++grub_xfs_inline_next_de(struct grub_xfs_data *data,
++			struct grub_xfs_dir_header *head,
++			struct grub_xfs_dir_entry *de)
++{
++  char *p = (char *)de + sizeof(struct grub_xfs_dir_entry) - 1 + de->len;
++
++  p += head->largeino ? sizeof(grub_uint64_t) : sizeof(grub_uint32_t);
++  if (data->hasftype)
++    p++;
++
++  return (struct grub_xfs_dir_entry *)p;
++}
++
++static struct grub_xfs_dirblock_tail *
++grub_xfs_dir_tail(struct grub_xfs_data *data, void *dirblock)
++{
++  int dirblksize = 1 << (data->sblock.log2_bsize + data->sblock.log2_dirblk);
++
++  return (struct grub_xfs_dirblock_tail *)
++    ((char *)dirblock + dirblksize - sizeof (struct grub_xfs_dirblock_tail));
++}
++
++static struct grub_xfs_dir2_entry *
++grub_xfs_first_de(struct grub_xfs_data *data, void *dirblock)
++{
++  if (data->hascrc)
++    return (struct grub_xfs_dir2_entry *)((char *)dirblock + 64);
++  return (struct grub_xfs_dir2_entry *)((char *)dirblock + 16);
++}
++
++static struct grub_xfs_dir2_entry *
++grub_xfs_next_de(struct grub_xfs_data *data, struct grub_xfs_dir2_entry *de)
++{
++  int size = sizeof (struct grub_xfs_dir2_entry) + de->len + 2 /* Tag */;
++
++  if (data->hasftype)
++    size++;		/* File type */
++  return (struct grub_xfs_dir2_entry *)(((char *)de) + ALIGN_UP(size, 8));
++}
++
++static grub_uint64_t *
++grub_xfs_btree_keys(struct grub_xfs_data *data,
++		    struct grub_xfs_btree_node *leaf)
++{
++  grub_uint64_t *keys = (grub_uint64_t *)(leaf + 1);
++
++  if (data->hascrc)
++    keys += 6;	/* skip crc, uuid, ... */
++  return keys;
++}
++
+ static grub_err_t
+ grub_xfs_read_inode (struct grub_xfs_data *data, grub_uint64_t ino,
+ 		     struct grub_xfs_inode *inode)
+@@ -281,6 +463,8 @@ grub_xfs_read_inode (struct grub_xfs_data *data, grub_uint64_t ino,
+   grub_uint64_t block = grub_xfs_inode_block (data, ino);
+   int offset = grub_xfs_inode_offset (data, ino);
+ 
++  grub_dprintf("xfs", "Reading inode (%"PRIuGRUB_UINT64_T") - %"PRIuGRUB_UINT64_T", %d\n",
++	       ino, block, offset);
+   /* Read the inode.  */
+   if (grub_disk_read (data->disk, block, offset, grub_xfs_inode_size(data),
+ 		      inode))
+@@ -303,6 +487,7 @@ grub_xfs_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock)
+ 
+   if (node->inode.format == XFS_INODE_FORMAT_BTREE)
+     {
++      struct grub_xfs_btree_root *root;
+       const grub_uint64_t *keys;
+       int recoffset;
+ 
+@@ -310,15 +495,15 @@ grub_xfs_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock)
+       if (leaf == 0)
+         return 0;
+ 
+-      nrec = grub_be_to_cpu16 (node->inode.data.btree.numrecs);
+-      keys = &node->inode.data.btree.keys[0];
++      root = grub_xfs_inode_data(&node->inode);
++      nrec = grub_be_to_cpu16 (root->numrecs);
++      keys = &root->keys[0];
+       if (node->inode.fork_offset)
+ 	recoffset = (node->inode.fork_offset - 1) / 2;
+       else
+ 	recoffset = (grub_xfs_inode_size(node->data)
+-		     - ((char *) &node->inode.data.btree.keys
+-			- (char *) &node->inode))
+-	  / (2 * sizeof (grub_uint64_t));
++		     - ((char *) keys - (char *) &node->inode))
++				/ (2 * sizeof (grub_uint64_t));
+       do
+         {
+           int i;
+@@ -340,7 +525,10 @@ grub_xfs_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock)
+                               0, node->data->bsize, leaf))
+             return 0;
+ 
+-          if (grub_strncmp ((char *) leaf->magic, "BMAP", 4))
++	  if ((!node->data->hascrc &&
++	       grub_strncmp ((char *) leaf->magic, "BMAP", 4)) ||
++	      (node->data->hascrc &&
++	       grub_strncmp ((char *) leaf->magic, "BMA3", 4)))
+             {
+               grub_free (leaf);
+               grub_error (GRUB_ERR_BAD_FS, "not a correct XFS BMAP node");
+@@ -348,8 +536,8 @@ grub_xfs_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock)
+             }
+ 
+           nrec = grub_be_to_cpu16 (leaf->numrecs);
+-          keys = &leaf->keys[0];
+-	  recoffset = ((node->data->bsize - ((char *) &leaf->keys
++          keys = grub_xfs_btree_keys(node->data, leaf);
++	  recoffset = ((node->data->bsize - ((char *) keys
+ 					     - (char *) leaf))
+ 		       / (2 * sizeof (grub_uint64_t)));
+ 	}
+@@ -359,7 +547,7 @@ grub_xfs_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock)
+   else if (node->inode.format == XFS_INODE_FORMAT_EXT)
+     {
+       nrec = grub_be_to_cpu32 (node->inode.nextents);
+-      exts = &node->inode.data.extents[0];
++      exts = grub_xfs_inode_data(&node->inode);
+     }
+   else
+     {
+@@ -417,7 +605,7 @@ grub_xfs_read_symlink (grub_fshelp_node_t node)
+   switch (node->inode.format)
+     {
+     case XFS_INODE_FORMAT_INO:
+-      return grub_strndup (node->inode.data.raw, size);
++      return grub_strndup (grub_xfs_inode_data(&node->inode), size);
+ 
+     case XFS_INODE_FORMAT_EXT:
+       {
+@@ -512,23 +700,18 @@ grub_xfs_iterate_dir (grub_fshelp_node_t dir,
+     {
+     case XFS_INODE_FORMAT_INO:
+       {
+-	struct grub_xfs_dir_entry *de = &diro->inode.data.dir.direntry[0];
+-	int smallino = !diro->inode.data.dir.dirhead.smallino;
++	struct grub_xfs_dir_header *head = grub_xfs_inode_data(&diro->inode);
++	struct grub_xfs_dir_entry *de = grub_xfs_inline_de(head);
++	int smallino = !head->largeino;
+ 	int i;
+ 	grub_uint64_t parent;
+ 
+ 	/* If small inode numbers are used to pack the direntry, the
+ 	   parent inode number is small too.  */
+ 	if (smallino)
+-	  {
+-	    parent = grub_be_to_cpu32 (diro->inode.data.dir.dirhead.parent.i4);
+-	    /* The header is a bit smaller than usual.  */
+-	    de = (struct grub_xfs_dir_entry *) ((char *) de - 4);
+-	  }
++	  parent = grub_be_to_cpu32 (head->parent.i4);
+ 	else
+-	  {
+-	    parent = grub_be_to_cpu64(diro->inode.data.dir.dirhead.parent.i8);
+-	  }
++	  parent = grub_be_to_cpu64 (head->parent.i8);
+ 
+ 	/* Synthesize the direntries for `.' and `..'.  */
+ 	if (iterate_dir_call_hook (diro->ino, ".", &ctx))
+@@ -537,12 +720,10 @@ grub_xfs_iterate_dir (grub_fshelp_node_t dir,
+ 	if (iterate_dir_call_hook (parent, "..", &ctx))
+ 	  return 1;
+ 
+-	for (i = 0; i < diro->inode.data.dir.dirhead.count; i++)
++	for (i = 0; i < head->count; i++)
+ 	  {
+ 	    grub_uint64_t ino;
+-	    grub_uint8_t *inopos = (((grub_uint8_t *) de)
+-			    + sizeof (struct grub_xfs_dir_entry)
+-			    + de->len - 1);
++	    grub_uint8_t *inopos = grub_xfs_inline_de_inopos(dir->data, de);
+ 	    grub_uint8_t c;
+ 
+ 	    /* inopos might be unaligned.  */
+@@ -567,10 +748,7 @@ grub_xfs_iterate_dir (grub_fshelp_node_t dir,
+ 	      return 1;
+ 	    de->name[de->len] = c;
+ 
+-	    de = ((struct grub_xfs_dir_entry *)
+-		  (((char *) de)+ sizeof (struct grub_xfs_dir_entry) + de->len
+-		   + ((smallino ? sizeof (grub_uint32_t)
+-		       : sizeof (grub_uint64_t))) - 1));
++	    de = grub_xfs_inline_next_de(dir->data, head, de);
+ 	  }
+ 	break;
+       }
+@@ -597,15 +775,11 @@ grub_xfs_iterate_dir (grub_fshelp_node_t dir,
+ 		    >> dirblk_log2);
+ 	     blk++)
+ 	  {
+-	    /* The header is skipped, the first direntry is stored
+-	       from byte 16.  */
+-	    int pos = 16;
++	    struct grub_xfs_dir2_entry *direntry =
++					grub_xfs_first_de(dir->data, dirblock);
+ 	    int entries;
+-	    int tail_start = (dirblk_size
+-			      - sizeof (struct grub_xfs_dirblock_tail));
+-
+-	    struct grub_xfs_dirblock_tail *tail;
+-	    tail = (struct grub_xfs_dirblock_tail *) &dirblock[tail_start];
++	    struct grub_xfs_dirblock_tail *tail =
++					grub_xfs_dir_tail(dir->data, dirblock);
+ 
+ 	    numread = grub_xfs_read_file (dir, 0, 0,
+ 					  blk << dirblk_log2,
+@@ -617,13 +791,11 @@ grub_xfs_iterate_dir (grub_fshelp_node_t dir,
+ 		       - grub_be_to_cpu32 (tail->leaf_stale));
+ 
+ 	    /* Iterate over all entries within this block.  */
+-	    while (pos < tail_start)
++	    while ((char *)direntry < (char *)tail)
+ 	      {
+-		struct grub_xfs_dir2_entry *direntry;
+ 		grub_uint8_t *freetag;
+ 		char *filename;
+ 
+-		direntry = (struct grub_xfs_dir2_entry *) &dirblock[pos];
+ 		freetag = (grub_uint8_t *) direntry;
+ 
+ 		if (grub_get_unaligned16 (freetag) == 0XFFFF)
+@@ -631,14 +803,16 @@ grub_xfs_iterate_dir (grub_fshelp_node_t dir,
+ 		    grub_uint8_t *skip = (freetag + sizeof (grub_uint16_t));
+ 
+ 		    /* This entry is not used, go to the next one.  */
+-		    pos += grub_be_to_cpu16 (grub_get_unaligned16 (skip));
++		    direntry = (struct grub_xfs_dir2_entry *)
++				(((char *)direntry) +
++				grub_be_to_cpu16 (grub_get_unaligned16 (skip)));
+ 
+ 		    continue;
+ 		  }
+ 
+-		filename = &dirblock[pos + sizeof (*direntry)];
+-		/* The byte after the filename is for the tag, which
+-		   is not used by GRUB.  So it can be overwritten.  */
++		filename = (char *)(direntry + 1);
++		/* The byte after the filename is for the filetype, padding, or
++		   tag, which is not used by GRUB.  So it can be overwritten. */
+ 		filename[direntry->len] = '\0';
+ 
+ 		if (iterate_dir_call_hook (grub_be_to_cpu64(direntry->inode), 
+@@ -655,8 +829,7 @@ grub_xfs_iterate_dir (grub_fshelp_node_t dir,
+ 		  break;
+ 
+ 		/* Select the next directory entry.  */
+-		pos = GRUB_XFS_NEXT_DIRENT (pos, direntry->len);
+-		pos = GRUB_XFS_ROUND_TO_DIRENT (pos);
++		direntry = grub_xfs_next_de(dir->data, direntry);
+ 	      }
+ 	  }
+ 	grub_free (dirblock);
+@@ -681,19 +854,14 @@ grub_xfs_mount (grub_disk_t disk)
+   if (!data)
+     return 0;
+ 
++  grub_dprintf("xfs", "Reading sb\n");
+   /* Read the superblock.  */
+   if (grub_disk_read (disk, 0, 0,
+ 		      sizeof (struct grub_xfs_sblock), &data->sblock))
+     goto fail;
+ 
+-  if (grub_strncmp ((char *) (data->sblock.magic), "XFSB", 4)
+-      || data->sblock.log2_bsize < GRUB_DISK_SECTOR_BITS
+-      || ((int) data->sblock.log2_bsize
+-	  + (int) data->sblock.log2_dirblk) >= 27)
+-    {
+-      grub_error (GRUB_ERR_BAD_FS, "not a XFS filesystem");
+-      goto fail;
+-    }
++  if (!grub_xfs_sb_valid(data))
++    goto fail;
+ 
+   data = grub_realloc (data,
+ 		       sizeof (struct grub_xfs_data)
+@@ -708,9 +876,13 @@ grub_xfs_mount (grub_disk_t disk)
+   data->diropen.inode_read = 1;
+   data->bsize = grub_be_to_cpu32 (data->sblock.bsize);
+   data->agsize = grub_be_to_cpu32 (data->sblock.agsize);
++  data->hasftype = grub_xfs_sb_hasftype(data);
++  data->hascrc = grub_xfs_sb_hascrc(data);
+ 
+   data->disk = disk;
+   data->pos = 0;
++  grub_dprintf("xfs", "Reading root ino %"PRIuGRUB_UINT64_T"\n",
++	       grub_cpu_to_be64(data->sblock.rootino));
+ 
+   grub_xfs_read_inode (data, data->diropen.ino, &data->diropen.inode);
+ 
+-- 
+2.4.3
+
diff --git a/SOURCES/0171-xfs-silence-Coverity-overflow-warning.patch b/SOURCES/0171-xfs-silence-Coverity-overflow-warning.patch
new file mode 100644
index 0000000..5f5ae3e
--- /dev/null
+++ b/SOURCES/0171-xfs-silence-Coverity-overflow-warning.patch
@@ -0,0 +1,27 @@
+From 4ac2b84fea9a90d68970c0729a02895d47a8b40c Mon Sep 17 00:00:00 2001
+From: Andrei Borzenkov <arvidjaar@gmail.com>
+Date: Fri, 19 Jun 2015 18:38:25 +0300
+Subject: [PATCH 14/23] xfs: silence Coverity overflow warning
+
+inode size cannot really overflow integer, but Coverity does not know it.
+CID: 96602
+---
+ grub-core/fs/xfs.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/grub-core/fs/xfs.c b/grub-core/fs/xfs.c
+index f00e43e..7249291 100644
+--- a/grub-core/fs/xfs.c
++++ b/grub-core/fs/xfs.c
+@@ -361,7 +361,7 @@ grub_xfs_inode_offset (struct grub_xfs_data *data,
+ static inline grub_size_t
+ grub_xfs_inode_size(struct grub_xfs_data *data)
+ {
+-  return 1 << data->sblock.log2_inode;
++  return (grub_size_t)1 << data->sblock.log2_inode;
+ }
+ 
+ /*
+-- 
+2.4.3
+
diff --git a/SOURCES/0172-send-router-solicitation-for-ipv6-address-autoconf-v.patch b/SOURCES/0172-send-router-solicitation-for-ipv6-address-autoconf-v.patch
new file mode 100644
index 0000000..c2d3385
--- /dev/null
+++ b/SOURCES/0172-send-router-solicitation-for-ipv6-address-autoconf-v.patch
@@ -0,0 +1,163 @@
+From a1f8402056e13cadab252dd64d7dc28ccdf6fda0 Mon Sep 17 00:00:00 2001
+From: Michael Chang <mchang@suse.com>
+Date: Tue, 18 Nov 2014 16:03:08 +0800
+Subject: [PATCH 15/23] send router solicitation for ipv6 address autoconf v2
+
+Many routers have long router advertisment interval configured by
+default. The Neighbor Discovery protocol (RFC4861) has defined default
+MaxRtrAdvInterval value as 600 seconds and
+MinRtrAdvInterval as 0.33*MaxRtrAdvInterval. This makes
+net_ipv6_autoconf fails more often than not as currently it passively
+listens the RA message to perfom address autoconfiguration.
+
+This patch tries to send router solicitation to overcome the problem of
+long RA interval.
+
+v2:
+use cpu_to_be macro for network byte order conversion
+add missing error handling
+---
+ grub-core/net/icmp6.c | 83 +++++++++++++++++++++++++++++++++++++++++++++++++++
+ grub-core/net/net.c   |  4 ++-
+ include/grub/net/ip.h |  2 ++
+ 3 files changed, 88 insertions(+), 1 deletion(-)
+
+diff --git a/grub-core/net/icmp6.c b/grub-core/net/icmp6.c
+index bbc9020..0843a15 100644
+--- a/grub-core/net/icmp6.c
++++ b/grub-core/net/icmp6.c
+@@ -72,6 +72,11 @@ struct neighbour_advertise
+   grub_uint64_t target[2];
+ } GRUB_PACKED;
+ 
++struct router_solicit
++{
++  grub_uint32_t reserved;
++} GRUB_PACKED;
++
+ enum
+   {
+     FLAG_SLAAC = 0x40
+@@ -81,6 +86,7 @@ enum
+   {
+     ICMP6_ECHO = 128,
+     ICMP6_ECHO_REPLY = 129,
++    ICMP6_ROUTER_SOLICIT = 133,
+     ICMP6_ROUTER_ADVERTISE = 134,
+     ICMP6_NEIGHBOUR_SOLICIT = 135,
+     ICMP6_NEIGHBOUR_ADVERTISE = 136,
+@@ -533,3 +539,80 @@ grub_net_icmp6_send_request (struct grub_net_network_level_interface *inf,
+   grub_netbuff_free (nb);
+   return err;
+ }
++
++grub_err_t
++grub_net_icmp6_send_router_solicit (struct grub_net_network_level_interface *inf)
++{
++  struct grub_net_buff *nb;
++  grub_err_t err = GRUB_ERR_NONE;
++  grub_net_network_level_address_t multicast;
++  grub_net_link_level_address_t ll_multicast;
++  struct option_header *ohdr;
++  struct router_solicit *sol;
++  struct icmp_header *icmphr;
++
++  multicast.type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV6;
++  multicast.ipv6[0] = grub_cpu_to_be64 (0xff02ULL << 48);
++  multicast.ipv6[1] = grub_cpu_to_be64 (0x02ULL);
++
++  err = grub_net_link_layer_resolve (inf, &multicast, &ll_multicast);
++  if (err)
++    return err;
++
++  nb = grub_netbuff_alloc (sizeof (struct router_solicit)
++			   + sizeof (struct option_header)
++			   + 6
++			   + sizeof (struct icmp_header)
++			   + GRUB_NET_OUR_IPV6_HEADER_SIZE
++			   + GRUB_NET_MAX_LINK_HEADER_SIZE);
++  if (!nb)
++    return grub_errno;
++  err = grub_netbuff_reserve (nb,
++			      sizeof (struct router_solicit)
++			      + sizeof (struct option_header)
++			      + 6
++			      + sizeof (struct icmp_header)
++			      + GRUB_NET_OUR_IPV6_HEADER_SIZE
++			      + GRUB_NET_MAX_LINK_HEADER_SIZE);
++  if (err)
++    goto fail;
++
++  err = grub_netbuff_push (nb, 6);
++  if (err)
++    goto fail;
++
++  grub_memcpy (nb->data, inf->hwaddress.mac, 6);
++
++  err = grub_netbuff_push (nb, sizeof (*ohdr));
++  if (err)
++    goto fail;
++
++  ohdr = (struct option_header *) nb->data;
++  ohdr->type = OPTION_SOURCE_LINK_LAYER_ADDRESS;
++  ohdr->len = 1;
++
++  err = grub_netbuff_push (nb, sizeof (*sol));
++  if (err)
++    goto fail;
++
++  sol = (struct router_solicit *) nb->data;
++  sol->reserved = 0;
++
++  err = grub_netbuff_push (nb, sizeof (*icmphr));
++  if (err)
++    goto fail;
++
++  icmphr = (struct icmp_header *) nb->data;
++  icmphr->type = ICMP6_ROUTER_SOLICIT;
++  icmphr->code = 0;
++  icmphr->checksum = 0;
++  icmphr->checksum = grub_net_ip_transport_checksum (nb,
++						     GRUB_NET_IP_ICMPV6,
++						     &inf->address,
++						     &multicast);
++  err = grub_net_send_ip_packet (inf, &multicast, &ll_multicast, nb,
++				 GRUB_NET_IP_ICMPV6);
++ fail:
++  grub_netbuff_free (nb);
++  return err;
++}
+diff --git a/grub-core/net/net.c b/grub-core/net/net.c
+index 10bfed3..b10addb 100644
+--- a/grub-core/net/net.c
++++ b/grub-core/net/net.c
+@@ -380,12 +380,14 @@ grub_cmd_ipv6_autoconf (struct grub_command *cmd __attribute__ ((unused)),
+ 
+   for (interval = 200; interval < 10000; interval *= 2)
+     {
+-      /* FIXME: send router solicitation.  */
+       int done = 1;
+       for (j = 0; j < ncards; j++)
+ 	{
+ 	  if (slaacs[j]->slaac_counter)
+ 	    continue;
++	  err = grub_net_icmp6_send_router_solicit (ifaces[j]);
++	  if (err)
++	    err = GRUB_ERR_NONE;
+ 	  done = 0;
+ 	}
+       if (done)
+diff --git a/include/grub/net/ip.h b/include/grub/net/ip.h
+index 7a8e614..dcceaa5 100644
+--- a/include/grub/net/ip.h
++++ b/include/grub/net/ip.h
+@@ -92,4 +92,6 @@ grub_err_t
+ grub_net_icmp6_send_request (struct grub_net_network_level_interface *inf,
+ 			     const grub_net_network_level_address_t *proto_addr);
+ 
++grub_err_t
++grub_net_icmp6_send_router_solicit (struct grub_net_network_level_interface *inf);
+ #endif 
+-- 
+2.4.3
+
diff --git a/SOURCES/0173-icmp6-fix-no-respond-to-neighbor-solicit-message.patch b/SOURCES/0173-icmp6-fix-no-respond-to-neighbor-solicit-message.patch
new file mode 100644
index 0000000..b8be36e
--- /dev/null
+++ b/SOURCES/0173-icmp6-fix-no-respond-to-neighbor-solicit-message.patch
@@ -0,0 +1,29 @@
+From 70717c72f114860c25908eabc4cb18a15ed2680e Mon Sep 17 00:00:00 2001
+From: Michael Chang <mchang@suse.com>
+Date: Mon, 3 Nov 2014 16:27:45 +0800
+Subject: [PATCH 16/23] icmp6 fix no respond to neighbor solicit message
+
+The structure size used in grub_netbuff_pull to get the pointer to
+option header is apparently wrong, which leads to subsequent range check
+failed and therefore not responding to any neighbor solicit message in my
+testing.
+---
+ grub-core/net/icmp6.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/grub-core/net/icmp6.c b/grub-core/net/icmp6.c
+index 0843a15..7822394 100644
+--- a/grub-core/net/icmp6.c
++++ b/grub-core/net/icmp6.c
+@@ -211,7 +211,7 @@ grub_net_recv_icmp6_packet (struct grub_net_buff *nb,
+ 	if (ttl != 0xff)
+ 	  break;
+ 	nbh = (struct neighbour_solicit *) nb->data;
+-	err = grub_netbuff_pull (nb, sizeof (struct router_adv));
++	err = grub_netbuff_pull (nb, sizeof (*nbh));
+ 	if (err)
+ 	  {
+ 	    grub_netbuff_free (nb);
+-- 
+2.4.3
+
diff --git a/SOURCES/0174-calibrate_tsc-use-the-Stall-EFI-boot-service-on-GRUB.patch b/SOURCES/0174-calibrate_tsc-use-the-Stall-EFI-boot-service-on-GRUB.patch
new file mode 100644
index 0000000..94346e9
--- /dev/null
+++ b/SOURCES/0174-calibrate_tsc-use-the-Stall-EFI-boot-service-on-GRUB.patch
@@ -0,0 +1,73 @@
+From af355a7fe160c6c798e416f8f14e059aaf16ea13 Mon Sep 17 00:00:00 2001
+From: Laszlo Ersek <lersek@redhat.com>
+Date: Fri, 10 Oct 2014 11:11:09 +0200
+Subject: [PATCH 17/23] calibrate_tsc(): use the Stall() EFI boot service on
+ GRUB_MACHINE_EFI
+
+Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1150698
+
+HyperV Gen2 virtual machines have no PIT; guest code should rely on UEFI
+services instead.
+
+Signed-off-by: RHEL Ninjas <example@example.com>
+---
+ grub-core/kern/i386/tsc.c | 20 ++++++++++++++++----
+ 1 file changed, 16 insertions(+), 4 deletions(-)
+
+diff --git a/grub-core/kern/i386/tsc.c b/grub-core/kern/i386/tsc.c
+index 3a4cae6..e499648 100644
+--- a/grub-core/kern/i386/tsc.c
++++ b/grub-core/kern/i386/tsc.c
+@@ -26,9 +26,14 @@
+ #include <grub/i386/tsc.h>
+ #include <grub/i386/cpuid.h>
+ #ifdef GRUB_MACHINE_XEN
+-#include <grub/xen.h>
++# include <grub/xen.h>
+ #else
+-#include <grub/i386/pit.h>
++# ifdef GRUB_MACHINE_EFI
++#  include <grub/efi/efi.h>
++#  include <grub/efi/api.h>
++# else
++#  include <grub/i386/pit.h>
++# endif
+ #endif
+ #include <grub/cpu/io.h>
+ 
+@@ -72,8 +77,14 @@ grub_cpu_is_tsc_supported (void)
+ #ifndef GRUB_MACHINE_XEN
+ 
+ static void
+-grub_pit_wait (grub_uint16_t tics)
++grub_stall (grub_uint16_t tics)
+ {
++# ifdef GRUB_MACHINE_EFI
++  grub_uint64_t microseconds;
++
++  microseconds = (grub_uint64_t)tics * 1000 * 1000 * 3 / 3579545;
++  efi_call_1 (grub_efi_system_table->boot_services->stall, microseconds);
++# else
+   /* Disable timer2 gate and speaker.  */
+   grub_outb (grub_inb (GRUB_PIT_SPEAKER_PORT)
+ 	     & ~ (GRUB_PIT_SPK_DATA | GRUB_PIT_SPK_TMR2),
+@@ -97,6 +108,7 @@ grub_pit_wait (grub_uint16_t tics)
+   grub_outb (grub_inb (GRUB_PIT_SPEAKER_PORT)
+ 	     & ~ (GRUB_PIT_SPK_DATA | GRUB_PIT_SPK_TMR2),
+              GRUB_PIT_SPEAKER_PORT);
++# endif
+ }
+ #endif
+ 
+@@ -119,7 +131,7 @@ calibrate_tsc (void)
+   grub_uint64_t end_tsc;
+ 
+   tsc_boot_time = grub_get_tsc ();
+-  grub_pit_wait (0xffff);
++  grub_stall (0xffff);
+   end_tsc = grub_get_tsc ();
+ 
+   grub_tsc_rate = grub_divmod64 ((55ULL << 32), end_tsc - tsc_boot_time, 0);
+-- 
+2.4.3
+
diff --git a/SOURCES/0175-fix-memory-corruption-in-pubkey-filter-over-network.patch b/SOURCES/0175-fix-memory-corruption-in-pubkey-filter-over-network.patch
new file mode 100644
index 0000000..2774ff0
--- /dev/null
+++ b/SOURCES/0175-fix-memory-corruption-in-pubkey-filter-over-network.patch
@@ -0,0 +1,167 @@
+From 27d2434ea9aed09b6cefdcc8600e191fa6d1c2fb Mon Sep 17 00:00:00 2001
+From: Andrei Borzenkov <arvidjaar@gmail.com>
+Date: Fri, 5 Dec 2014 21:17:08 +0300
+Subject: [PATCH 18/23] fix memory corruption in pubkey filter over network
+
+grub_pubkey_open closed original file after it was read; it set
+io->device to NULL to prevent grub_file_close from trying to close device.
+But network device itself is stacked (net -> bufio); and bufio preserved
+original netfs file which hold reference to device. grub_file_close(io)
+called grub_bufio_close which called grub_file_close for original file.
+grub_file_close(netfs-file) now also called grub_device_close which
+freed file->device->net. So file structure returned by grub_pubkey_open
+now had device->net pointed to freed memory. When later file was closed,
+it was attempted to be freed again.
+
+Change grub_pubkey_open to behave like other filters - preserve original
+parent file and pass grub_file_close down to parent. In this way only the
+original file will close device. We really need to move this logic into
+core instead.
+
+Also plug memory leaks in error paths on the way.
+
+Reported-By: Robert Kliewer <robert.kliewer@gmail.com>
+Closes: bug #43601
+---
+ grub-core/commands/verify.c | 72 +++++++++++++++++++++++++++++++++++++--------
+ 1 file changed, 60 insertions(+), 12 deletions(-)
+
+diff --git a/grub-core/commands/verify.c b/grub-core/commands/verify.c
+index 525bdd1..d599576 100644
+--- a/grub-core/commands/verify.c
++++ b/grub-core/commands/verify.c
+@@ -33,6 +33,13 @@
+ 
+ GRUB_MOD_LICENSE ("GPLv3+");
+ 
++struct grub_verified
++{
++  grub_file_t file;
++  void *buf;
++};
++typedef struct grub_verified *grub_verified_t;
++
+ enum
+   {
+     OPTION_SKIP_SIG = 0
+@@ -802,19 +809,39 @@ grub_cmd_verify_signature (grub_extcmd_context_t ctxt,
+ 
+ static int sec = 0;
+ 
++static void
++verified_free (grub_verified_t verified)
++{
++  if (verified)
++    {
++      grub_free (verified->buf);
++      grub_free (verified);
++    }
++}
++
+ static grub_ssize_t
+ verified_read (struct grub_file *file, char *buf, grub_size_t len)
+ {
+-  grub_memcpy (buf, (char *) file->data + file->offset, len);
++  grub_verified_t verified = file->data;
++
++  grub_memcpy (buf, (char *) verified->buf + file->offset, len);
+   return len;
+ }
+ 
+ static grub_err_t
+ verified_close (struct grub_file *file)
+ {
+-  grub_free (file->data);
++  grub_verified_t verified = file->data;
++
++  grub_file_close (verified->file);
++  verified_free (verified);
+   file->data = 0;
+-  return GRUB_ERR_NONE;
++
++  /* device and name are freed by parent */
++  file->device = 0;
++  file->name = 0;
++
++  return grub_errno;
+ }
+ 
+ struct grub_fs verified_fs =
+@@ -832,6 +859,7 @@ grub_pubkey_open (grub_file_t io, const char *filename)
+   grub_err_t err;
+   grub_file_filter_t curfilt[GRUB_FILE_FILTER_MAX];
+   grub_file_t ret;
++  grub_verified_t verified;
+ 
+   if (!sec)
+     return io;
+@@ -857,7 +885,10 @@ grub_pubkey_open (grub_file_t io, const char *filename)
+ 
+   ret = grub_malloc (sizeof (*ret));
+   if (!ret)
+-    return NULL;
++    {
++      grub_file_close (sig);
++      return NULL;
++    }
+   *ret = *io;
+ 
+   ret->fs = &verified_fs;
+@@ -866,29 +897,46 @@ grub_pubkey_open (grub_file_t io, const char *filename)
+     {
+       grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
+ 		  "big file signature isn't implemented yet");
++      grub_file_close (sig);
++      grub_free (ret);
++      return NULL;
++    }
++  verified = grub_malloc (sizeof (*verified));
++  if (!verified)
++    {
++      grub_file_close (sig);
++      grub_free (ret);
+       return NULL;
+     }
+-  ret->data = grub_malloc (ret->size);
+-  if (!ret->data)
++  verified->buf = grub_malloc (ret->size);
++  if (!verified->buf)
+     {
++      grub_file_close (sig);
++      grub_free (verified);
+       grub_free (ret);
+       return NULL;
+     }
+-  if (grub_file_read (io, ret->data, ret->size) != (grub_ssize_t) ret->size)
++  if (grub_file_read (io, verified->buf, ret->size) != (grub_ssize_t) ret->size)
+     {
+       if (!grub_errno)
+ 	grub_error (GRUB_ERR_FILE_READ_ERROR, N_("premature end of file %s"),
+ 		    filename);
++      grub_file_close (sig);
++      verified_free (verified);
++      grub_free (ret);
+       return NULL;
+     }
+ 
+-  err = grub_verify_signature_real (ret->data, ret->size, 0, sig, NULL);
++  err = grub_verify_signature_real (verified->buf, ret->size, 0, sig, NULL);
+   grub_file_close (sig);
+   if (err)
+-    return NULL;
+-  io->device = 0;
+-  io->name = 0;
+-  grub_file_close (io);
++    {
++      verified_free (verified);
++      grub_free (ret);
++      return NULL;
++    }
++  verified->file = io;
++  ret->data = verified;
+   return ret;
+ }
+ 
+-- 
+2.4.3
+
diff --git a/SOURCES/0176-Make-grub2-mkconfig-construct-titles-that-look-like-.patch b/SOURCES/0176-Make-grub2-mkconfig-construct-titles-that-look-like-.patch
new file mode 100644
index 0000000..bca5e11
--- /dev/null
+++ b/SOURCES/0176-Make-grub2-mkconfig-construct-titles-that-look-like-.patch
@@ -0,0 +1,72 @@
+From 204d0616ba497656d21e65f1b26561c539ea1a21 Mon Sep 17 00:00:00 2001
+From: Peter Jones <pjones@redhat.com>
+Date: Tue, 28 Apr 2015 11:15:03 -0400
+Subject: [PATCH 19/23] Make grub2-mkconfig construct titles that look like the
+ ones we want elsewhere.
+
+Resolves: rhbz#1215839
+
+Signed-off-by: Peter Jones <pjones@redhat.com>
+---
+ util/grub.d/10_linux.in | 34 +++++++++++++++++++++++++++-------
+ 1 file changed, 27 insertions(+), 7 deletions(-)
+
+diff --git a/util/grub.d/10_linux.in b/util/grub.d/10_linux.in
+index e8088a1..b3c460c 100644
+--- a/util/grub.d/10_linux.in
++++ b/util/grub.d/10_linux.in
+@@ -66,6 +66,32 @@ case x"$GRUB_FS" in
+ 	;;
+ esac
+ 
++mktitle ()
++{
++  local title_type
++  local version
++  local OS_NAME
++  local OS_VERS
++
++  title_type=$1 && shift
++  version=$1 && shift
++
++  OS_NAME="$(eval $(grep ^NAME= /etc/os-release) ; echo ${NAME})"
++  OS_VERS="$(eval $(grep ^VERSION= /etc/os-release) ; echo ${VERSION})"
++
++  case $title_type in
++    recovery)
++      title=$(printf '%s (%s) %s (recovery mode)' \
++                     "${OS_NAME}" "${version}" "${OS_VERS}")
++      ;;
++    *)
++      title=$(printf '%s (%s) %s' \
++                     "${OS_NAME}" "${version}" "${OS_VERS}")
++      ;;
++  esac
++  echo -n ${title}
++}
++
+ title_correction_code=
+ 
+ linux_entry ()
+@@ -94,17 +120,11 @@ linux_entry ()
+       boot_device_id="$(grub_get_device_id "${GRUB_DEVICE}")"
+   fi
+   if [ x$type != xsimple ] ; then
+-      case $type in
+-	  recovery)
+-	      title="$(gettext_printf "%s, with Linux %s (recovery mode)" "${os}" "${version}")" ;;
+-	  *)
+-	      title="$(gettext_printf "%s, with Linux %s" "${os}" "${version}")" ;;
+-      esac
++      title=$(mktitle "$type" "$version")
+       if [ x"$title" = x"$GRUB_ACTUAL_DEFAULT" ] || [ x"Previous Linux versions>$title" = x"$GRUB_ACTUAL_DEFAULT" ]; then
+ 	  replacement_title="$(echo "Advanced options for ${OS}" | sed 's,>,>>,g')>$(echo "$title" | sed 's,>,>>,g')"
+ 	  quoted="$(echo "$GRUB_ACTUAL_DEFAULT" | grub_quote)"
+ 	  title_correction_code="${title_correction_code}if [ \"x\$default\" = '$quoted' ]; then default='$(echo "$replacement_title" | grub_quote)'; fi;"
+-	  grub_warn "$(gettext_printf "Please don't use old title \`%s' for GRUB_DEFAULT, use \`%s' (for versions before 2.00) or \`%s' (for 2.00 or later)" "$GRUB_ACTUAL_DEFAULT" "$replacement_title" "gnulinux-advanced-$boot_device_id>gnulinux-$version-$type-$boot_device_id")"
+       fi
+       echo "menuentry '$(echo "$title" | grub_quote)' ${CLASS} \$menuentry_id_option 'gnulinux-$version-$type-$boot_device_id' {" | sed "s/^/$submenu_indentation/"
+   else
+-- 
+2.4.3
+
diff --git a/SOURCES/0177-don-t-strip-fw_path-twice-for-EFI-network-boot.patch b/SOURCES/0177-don-t-strip-fw_path-twice-for-EFI-network-boot.patch
new file mode 100644
index 0000000..d95749f
--- /dev/null
+++ b/SOURCES/0177-don-t-strip-fw_path-twice-for-EFI-network-boot.patch
@@ -0,0 +1,30 @@
+From 224bdbee2e9cc9a9aaa198cec9b984bb1fa0ee73 Mon Sep 17 00:00:00 2001
+From: RHEL Ninjas <example@example.com>
+Date: Mon, 13 Apr 2015 12:42:53 +1000
+Subject: [PATCH 20/23] don't strip fw_path twice for EFI network boot
+
+---
+ grub-core/kern/efi/init.c | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+diff --git a/grub-core/kern/efi/init.c b/grub-core/kern/efi/init.c
+index 942ab02..c391df4 100644
+--- a/grub-core/kern/efi/init.c
++++ b/grub-core/kern/efi/init.c
+@@ -61,7 +61,12 @@ grub_machine_get_bootlocation (char **device, char **path)
+   *device = grub_efidisk_get_device_name (image->device_handle);
+   *path = grub_efi_get_filename (image->file_path);
+   if (!*device && grub_efi_net_config)
+-    grub_efi_net_config (image->device_handle, device, path);
++    {
++      grub_efi_net_config (image->device_handle, device, path);
++      /* grub_efi_net_config returns the directory path, not the boot filename,
++         so don't strip any further. */
++      return;
++    }
+ 
+   /* Get the directory.  */
+   p = grub_strrchr (*path, '/');
+-- 
+2.4.3
+
diff --git a/SOURCES/0178-Add-friendly-grub2-password-config-tool-985962.patch b/SOURCES/0178-Add-friendly-grub2-password-config-tool-985962.patch
new file mode 100644
index 0000000..a4d289e
--- /dev/null
+++ b/SOURCES/0178-Add-friendly-grub2-password-config-tool-985962.patch
@@ -0,0 +1,282 @@
+From bde7036b706857aff32a025e82da5bc32473e439 Mon Sep 17 00:00:00 2001
+From: Robert Marshall <rmarshall@redhat.com>
+Date: Thu, 25 Jun 2015 11:13:11 -0400
+Subject: [PATCH 21/23] Add friendly grub2 password config tool (#985962)
+
+Provided a tool for users to reset the grub2 root user password
+without having to alter the grub.cfg. The hashed password now
+lives in a root-only-readable configuration file.
+
+Resolves: rhbz#985962
+---
+ .gitignore               |  12 ++---
+ Makefile.util.def        |  13 +++++
+ configure.ac             |   1 +
+ util/grub-mkconfig.in    |   2 +
+ util/grub-setpassword.8  |  28 +++++++++++
+ util/grub-setpassword.in | 123 +++++++++++++++++++++++++++++++++++++++++++++++
+ util/grub.d/01_users.in  |  11 +++++
+ 7 files changed, 182 insertions(+), 8 deletions(-)
+ create mode 100644 util/grub-setpassword.8
+ create mode 100755 util/grub-setpassword.in
+ create mode 100644 util/grub.d/01_users.in
+
+diff --git a/.gitignore b/.gitignore
+index b6c4577..e49f76b 100644
+--- a/.gitignore
++++ b/.gitignore
+@@ -1,11 +1,7 @@
+-00_header
+-10_*
+-20_linux_xen
+-30_os-prober
+-40_custom
+-41_custom
+-*.1
+-*.8
++[[:digit:]][[:digit:]]_*
++!util/[[:digit:]][[:digit:]]_*.in
++*.[[:digit:]]
++!util/*.[[:digit:]]
+ aclocal.m4
+ ahci_test
+ ascii.bitmaps
+diff --git a/Makefile.util.def b/Makefile.util.def
+index 3ac7572..e2821a2 100644
+--- a/Makefile.util.def
++++ b/Makefile.util.def
+@@ -438,6 +438,12 @@ script = {
+ };
+ 
+ script = {
++  name = '01_users';
++  common = util/grub.d/01_users.in;
++  installdir = grubconf;
++};
++
++script = {
+   name = '10_windows';
+   common = util/grub.d/10_windows.in;
+   installdir = grubconf;
+@@ -713,6 +719,13 @@ script = {
+ };
+ 
+ script = {
++  name = grub-setpassword;
++  common = util/grub-setpassword.in;
++  mansection = 8;
++  installdir = sbin;
++};
++
++script = {
+   name = grub-mkconfig_lib;
+   common = util/grub-mkconfig_lib.in;
+   installdir = noinst;
+diff --git a/configure.ac b/configure.ac
+index de17e65..273da6c 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -65,6 +65,7 @@ grub_TRANSFORM([grub-mkrelpath])
+ grub_TRANSFORM([grub-mkrescue])
+ grub_TRANSFORM([grub-probe])
+ grub_TRANSFORM([grub-reboot])
++grub_TRANSFORM([grub-setpassword])
+ grub_TRANSFORM([grub-rpm-sort])
+ grub_TRANSFORM([grub-script-check])
+ grub_TRANSFORM([grub-set-default])
+diff --git a/util/grub-mkconfig.in b/util/grub-mkconfig.in
+index bc26e7c..e029d0d 100644
+--- a/util/grub-mkconfig.in
++++ b/util/grub-mkconfig.in
+@@ -260,6 +260,8 @@ for i in "${grub_mkconfig_dir}"/* ; do
+     *~) ;;
+     # emacsen autosave files. FIXME: support other editors
+     */\#*\#) ;;
++    # rpm config files of yore.
++    *.rpmsave|*.rpmnew|*.rpmorig) ;;
+     *)
+       if grub_file_is_not_garbage "$i" && test -x "$i" ; then
+         echo
+diff --git a/util/grub-setpassword.8 b/util/grub-setpassword.8
+new file mode 100644
+index 0000000..5973abe
+--- /dev/null
++++ b/util/grub-setpassword.8
+@@ -0,0 +1,28 @@
++.TH GRUB-SETPASSWORD 3 "Thu Jun 25 2015"
++.SH NAME
++\fBgrub-setpassword\fR \(em Generate the user.cfg file containing the hashed grub bootloader password.
++
++.SH SYNOPSIS
++\fBgrub-setpassword\fR [OPTION]
++
++.SH DESCRIPTION
++\fBgrub-setpassword\fR outputs the user.cfg file which contains the hashed GRUB bootloader password. This utility only supports configurations where there is a single root user.
++
++The file has the format:
++GRUB_2PASSWORD=<\fIhashed password\fR>.
++
++.SH OPTIONS
++.TP
++-h, --help
++Display program usage and exit.
++.TP
++-v, --version
++Display the current version.
++.TP
++-o, --output[=\fIDIRECTORY PATH\fR]
++Choose the file path to which user.cfg will be written.
++
++.SH SEE ALSO
++.BR "info grub"
++
++.BR "info grub2-mkpasswd-pbkdf2"
+diff --git a/util/grub-setpassword.in b/util/grub-setpassword.in
+new file mode 100755
+index 0000000..dd76f00
+--- /dev/null
++++ b/util/grub-setpassword.in
+@@ -0,0 +1,123 @@
++#!/bin/sh -e
++
++if [ -d /sys/firmware/efi/efivars/ ]; then
++    grubdir=`echo "/@bootdirname@/efi/EFI/redhat/" | sed 's,//*,/,g'`
++else
++    grubdir=`echo "/@bootdirname@/@grubdirname@" | sed 's,//*,/,g'`
++fi
++
++PACKAGE_VERSION="@PACKAGE_VERSION@"
++PACKAGE_NAME="@PACKAGE_NAME@"
++self=`basename $0`
++bindir="@bindir@"
++grub_mkpasswd="${bindir}/@grub_mkpasswd_pbkdf2@"
++
++# Usage: usage
++# Print the usage.
++usage () {
++    cat <<EOF
++Usage: $0 [OPTION] [SOURCE]
++Run GRUB script in a Qemu instance.
++
++  -h, --help              print this message and exit
++  -v, --version           print the version information and exit
++  -o, --output_path       choose a custom output path for user.cfg
++
++$0 prompts the user to set a password on the grub bootloader. The password
++is written to a file named user.cfg.
++
++Report bugs at https://bugzilla.redhat.com.
++EOF
++}
++
++argument () {
++    opt=$1
++    shift
++
++    if test $# -eq 0; then
++        gettext_printf "%s: option requires an argument -- \`%s'\n" "$self" "$opt" 1>&2
++        exit 1
++    fi
++    echo $1
++}
++
++# Ensure that it's the root user running this script
++if [ "${EUID}" -ne 0 ]; then
++    echo "The grub bootloader password may only be set by root."
++    usage
++    exit 2
++fi
++
++# Check the arguments.
++while test $# -gt 0
++do
++    option=$1
++    shift
++
++    case "$option" in
++    -h | --help)
++	usage
++	exit 0 ;;
++    -v | --version)
++	echo "$self (${PACKAGE_NAME}) ${PACKAGE_VERSION}"
++	exit 0 ;;
++    -o | --output)
++        OUTPUT_PATH=`argument $option "$@"`; shift ;;
++    --output=*)
++        OUTPUT_PATH=`echo "$option" | sed 's/--output=//'` ;;
++    -o=*)
++        OUTPUT_PATH=`echo "$option" | sed 's/-o=//'` ;;
++    esac
++done
++
++# set user input or default path for user.cfg file
++if [ -z "${OUTPUT_PATH}" ]; then
++    OUTPUT_PATH="${grubdir}"
++fi
++
++if [ ! -d "${OUTPUT_PATH}" ]; then
++    echo "${OUTPUT_PATH} does not exist."
++    usage
++    exit 2;
++fi
++
++ttyopt=$(stty -g)
++fixtty() {
++      stty ${ttyopt}
++}
++
++trap fixtty EXIT
++stty -echo
++
++# prompt & confirm new grub2 root user password
++echo -n "Enter password: "
++read PASSWORD
++echo
++echo -n "Confirm password: "
++read PASSWORD_CONFIRM
++echo
++stty ${ttyopt}
++
++getpass() {
++    local P0
++    local P1
++    P0="$1" && shift
++    P1="$1" && shift
++
++    ( echo ${P0} ; echo ${P1} ) | \
++        ${grub_mkpasswd} | \
++        grep -v '[eE]nter password:' | \
++        sed -e "s/PBKDF2 hash of your password is //"
++}
++
++MYPASS="$(getpass "${PASSWORD}" "${PASSWORD_CONFIRM}")"
++if [ -z "${MYPASS}" ]; then
++      echo "${self}: error: empty password" 1>&2
++      exit 1
++fi
++
++# on the ESP, these will fail to set the permissions, but it's okay because
++# the directory is protected.
++install -m 0600 /dev/null "${grubdir}/user.cfg" 2>/dev/null || :
++chmod 0600 "${grubdir}/user.cfg" 2>/dev/null || :
++echo "GRUB2_PASSWORD=${MYPASS}" > "${grubdir}/user.cfg"
+diff --git a/util/grub.d/01_users.in b/util/grub.d/01_users.in
+new file mode 100644
+index 0000000..facd409
+--- /dev/null
++++ b/util/grub.d/01_users.in
+@@ -0,0 +1,11 @@
++#!/bin/sh -e
++cat << EOF
++if [ -f \${prefix}/user.cfg ]; then
++  source \${prefix}/user.cfg
++  if [ -n \${GRUB2_PASSWORD} ]; then
++    set superusers="root"
++    export superusers
++    password_pbkdf2 root \${GRUB2_PASSWORD}
++  fi
++fi
++EOF
+-- 
+2.4.3
+
diff --git a/SOURCES/0179-Try-to-make-sure-configure.ac-and-grub-rpm-sort-play.patch b/SOURCES/0179-Try-to-make-sure-configure.ac-and-grub-rpm-sort-play.patch
new file mode 100644
index 0000000..05bc86a
--- /dev/null
+++ b/SOURCES/0179-Try-to-make-sure-configure.ac-and-grub-rpm-sort-play.patch
@@ -0,0 +1,61 @@
+From f742724d51dc84b32a1298cd6bab62f12d887052 Mon Sep 17 00:00:00 2001
+From: Peter Jones <pjones@redhat.com>
+Date: Mon, 3 Aug 2015 11:46:42 -0400
+Subject: [PATCH 22/23] Try to make sure configure.ac and grub-rpm-sort play
+ nice.
+
+Apparently the test for whether to use grub-rpm-sort and also the
+renaming of it to grub2-rpm-sort on the runtime side weren't right.
+
+Related: rhbz#1124074
+
+Signed-off-by: Peter Jones <pjones@redhat.com>
+---
+ configure.ac              | 2 +-
+ util/grub-mkconfig_lib.in | 9 ++++++---
+ 2 files changed, 7 insertions(+), 4 deletions(-)
+
+diff --git a/configure.ac b/configure.ac
+index 273da6c..04c052d 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -1549,7 +1549,7 @@ AC_SUBST([LIBDEVMAPPER])
+ AC_ARG_ENABLE([rpm-sort],
+               [AS_HELP_STRING([--enable-rpm-sort],
+                               [enable native rpm sorting of kernels in grub (default=guessed)])])
+-if test x"$enable_rpm-sort" = xno ; then
++if test x"$enable_rpm_sort" = xno ; then
+   rpm_sort_excuse="explicitly disabled"
+ fi
+ 
+diff --git a/util/grub-mkconfig_lib.in b/util/grub-mkconfig_lib.in
+index e85b60c..c67a319 100644
+--- a/util/grub-mkconfig_lib.in
++++ b/util/grub-mkconfig_lib.in
+@@ -33,6 +33,9 @@ fi
+ if test "x$grub_mkrelpath" = x; then
+   grub_mkrelpath="${bindir}/@grub_mkrelpath@"
+ fi
++if test "x$grub_rpm_sort" = x; then
++  grub_rpm_sort="${sbindir}/@grub_rpm_sort@"
++fi
+ 
+ if which gettext >/dev/null 2>/dev/null; then
+   :
+@@ -213,10 +216,10 @@ version_sort ()
+    esac
+ }
+ 
+-if [ "x$RPMLIB" = x ]; then
+-  kernel_sort=version_sort
++if [ "x$grub_rpm_sort" != x -a -x "$grub_rpm_sort" ]; then
++  kernel_sort="$grub_rpm_sort"
+ else
+-  kernel_sort="${sbindir}/grub-rpm-sort"
++  kernel_sort=version_sort
+ fi
+ 
+ version_test_numeric ()
+-- 
+2.4.3
+
diff --git a/SOURCES/0180-ppc64le-sync-mkconfig-to-disk-1212114.patch b/SOURCES/0180-ppc64le-sync-mkconfig-to-disk-1212114.patch
new file mode 100644
index 0000000..e1fcab3
--- /dev/null
+++ b/SOURCES/0180-ppc64le-sync-mkconfig-to-disk-1212114.patch
@@ -0,0 +1,42 @@
+From f1edaeeeffdfc291e0b17d87f8727baaecbfaf63 Mon Sep 17 00:00:00 2001
+From: Don Zickus <dzickus@redhat.com>
+Date: Wed, 22 Jul 2015 13:59:55 -0400
+Subject: [PATCH 23/23] ppc64le sync mkconfig to disk (#1212114)
+
+If creating a new grub2 entry using grub2-mkconfig, the entry is not
+immediately sync'd to disk.  If a crash happens before the writeback,
+the subsequent reboot fails because the grub2.cfg is corrupted.
+
+Address this by forcing all the changes (mainly the fs meta data) to disk
+before finishing the grub2 conf changes.
+
+Tested by 'grub2-mkconfig -o /etc/grub22.cfg; echo c > /proc/sysrq-trigger'.
+
+Before, the machine would panic and on reboot be stuck without a grub.cfg
+to read.  After, works as expected.
+
+Resolves: rhbz#1212114
+---
+ util/grub-mkconfig.in | 9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+diff --git a/util/grub-mkconfig.in b/util/grub-mkconfig.in
+index e029d0d..cf315e2 100644
+--- a/util/grub-mkconfig.in
++++ b/util/grub-mkconfig.in
+@@ -290,3 +290,12 @@ fi
+ 
+ gettext "done" >&2
+ echo >&2
++
++# make sure changes make it to the disk.
++# if /boot is a mountpoint, force the meta data on disk
++# to by-pass writeback delay.
++# PPC64LE-only to deal with Petitboot issues
++ARCH=$(uname -m)
++if [ "${ARCH}" = "ppc64le" ]; then
++    sync && mountpoint -q /boot &&fsfreeze -f /boot && fsfreeze -u /boot
++fi
+-- 
+2.4.3
+
diff --git a/SOURCES/0181-tcp-ack-when-we-get-an-OOO-lost-packet.patch b/SOURCES/0181-tcp-ack-when-we-get-an-OOO-lost-packet.patch
new file mode 100644
index 0000000..dbde843
--- /dev/null
+++ b/SOURCES/0181-tcp-ack-when-we-get-an-OOO-lost-packet.patch
@@ -0,0 +1,37 @@
+From 66804a1e21978713902da654ec890574efe25e7d Mon Sep 17 00:00:00 2001
+From: Josef Bacik <jbacik@fb.com>
+Date: Wed, 12 Aug 2015 08:16:22 -0700
+Subject: [PATCH 1/3] tcp: ack when we get an OOO/lost packet
+
+While adding tcp window scaling support I was finding that I'd get some packet
+loss or reordering when transferring from large distances and grub would just
+timeout.  This is because we weren't ack'ing when we got our OOO packet, so the
+sender didn't know it needed to retransmit anything, so eventually it would fill
+the window and stop transmitting, and we'd time out.  Fix this by ACK'ing when
+we don't find our next sequence numbered packet.  With this fix I no longer time
+out.  Thanks,
+
+Signed-off-by: Josef Bacik <jbacik@fb.com>
+---
+ grub-core/net/tcp.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/grub-core/net/tcp.c b/grub-core/net/tcp.c
+index 2077f55..fa29a2a 100644
+--- a/grub-core/net/tcp.c
++++ b/grub-core/net/tcp.c
+@@ -882,7 +882,10 @@ grub_net_recv_tcp_packet (struct grub_net_buff *nb,
+ 	  grub_priority_queue_pop (sock->pq);
+ 	}
+       if (grub_be_to_cpu32 (tcph->seqnr) != sock->their_cur_seq)
+-	return GRUB_ERR_NONE;
++	{
++	  ack (sock);
++	  return GRUB_ERR_NONE;
++	}
+       while (1)
+ 	{
+ 	  nb_top_p = grub_priority_queue_top (sock->pq);
+-- 
+2.4.3
+
diff --git a/SOURCES/0182-tcp-add-window-scaling-support.patch b/SOURCES/0182-tcp-add-window-scaling-support.patch
new file mode 100644
index 0000000..b91ce62
--- /dev/null
+++ b/SOURCES/0182-tcp-add-window-scaling-support.patch
@@ -0,0 +1,90 @@
+From 8e86a32160008b34796f597016cc335680bb3486 Mon Sep 17 00:00:00 2001
+From: Josef Bacik <jbacik@fb.com>
+Date: Wed, 12 Aug 2015 08:57:55 -0700
+Subject: [PATCH 2/3] tcp: add window scaling support
+
+Sometimes we have to provision boxes across regions, such as California to
+Sweden.  The http server has a 10 minute timeout, so if we can't get our 250mb
+image transferred fast enough our provisioning fails, which is not ideal.  So
+add tcp window scaling on open connections and set the window size to 1mb.  With
+this change we're able to get higher sustained transfers between regions and can
+transfer our image in well below 10 minutes.  Without this patch we'd time out
+every time halfway through the transfer.  Thanks,
+
+Signed-off-by: Josef Bacik <jbacik@fb.com>
+---
+ grub-core/net/tcp.c | 42 +++++++++++++++++++++++++++++-------------
+ 1 file changed, 29 insertions(+), 13 deletions(-)
+
+diff --git a/grub-core/net/tcp.c b/grub-core/net/tcp.c
+index fa29a2a..c22ef03 100644
+--- a/grub-core/net/tcp.c
++++ b/grub-core/net/tcp.c
+@@ -106,6 +106,18 @@ struct tcphdr
+   grub_uint16_t urgent;
+ } GRUB_PACKED;
+ 
++struct tcp_scale_opt {
++  grub_uint8_t kind;
++  grub_uint8_t length;
++  grub_uint8_t scale;
++} GRUB_PACKED;
++
++struct tcp_synhdr {
++  struct tcphdr tcphdr;
++  struct tcp_scale_opt scale_opt;
++  grub_uint8_t padding;
++};
++
+ struct tcp_pseudohdr
+ {
+   grub_uint32_t src;
+@@ -555,7 +567,7 @@ grub_net_tcp_open (char *server,
+   grub_net_tcp_socket_t socket;
+   static grub_uint16_t in_port = 21550;
+   struct grub_net_buff *nb;
+-  struct tcphdr *tcph;
++  struct tcp_synhdr *tcph;
+   int i;
+   grub_uint8_t *nbd;
+   grub_net_link_level_address_t ll_target_addr;
+@@ -617,20 +629,24 @@ grub_net_tcp_open (char *server,
+     }
+ 
+   tcph = (void *) nb->data;
++  grub_memset(tcph, 0, sizeof (*tcph));
+   socket->my_start_seq = grub_get_time_ms ();
+   socket->my_cur_seq = socket->my_start_seq + 1;
+-  socket->my_window = 8192;
+-  tcph->seqnr = grub_cpu_to_be32 (socket->my_start_seq);
+-  tcph->ack = grub_cpu_to_be32_compile_time (0);
+-  tcph->flags = grub_cpu_to_be16_compile_time ((5 << 12) | TCP_SYN);
+-  tcph->window = grub_cpu_to_be16 (socket->my_window);
+-  tcph->urgent = 0;
+-  tcph->src = grub_cpu_to_be16 (socket->in_port);
+-  tcph->dst = grub_cpu_to_be16 (socket->out_port);
+-  tcph->checksum = 0;
+-  tcph->checksum = grub_net_ip_transport_checksum (nb, GRUB_NET_IP_TCP,
+-						   &socket->inf->address,
+-						   &socket->out_nla);
++  socket->my_window = 32768;
++  tcph->tcphdr.seqnr = grub_cpu_to_be32 (socket->my_start_seq);
++  tcph->tcphdr.ack = grub_cpu_to_be32_compile_time (0);
++  tcph->tcphdr.flags = grub_cpu_to_be16_compile_time ((6 << 12) | TCP_SYN);
++  tcph->tcphdr.window = grub_cpu_to_be16 (socket->my_window);
++  tcph->tcphdr.urgent = 0;
++  tcph->tcphdr.src = grub_cpu_to_be16 (socket->in_port);
++  tcph->tcphdr.dst = grub_cpu_to_be16 (socket->out_port);
++  tcph->tcphdr.checksum = 0;
++  tcph->scale_opt.kind = 3;
++  tcph->scale_opt.length = 3;
++  tcph->scale_opt.scale = 5;
++  tcph->tcphdr.checksum = grub_net_ip_transport_checksum (nb, GRUB_NET_IP_TCP,
++							  &socket->inf->address,
++							  &socket->out_nla);
+ 
+   tcp_socket_register (socket);
+ 
+-- 
+2.4.3
+
diff --git a/SOURCES/0183-efinet-retransmit-if-our-device-is-busy.patch b/SOURCES/0183-efinet-retransmit-if-our-device-is-busy.patch
new file mode 100644
index 0000000..7fbddc2
--- /dev/null
+++ b/SOURCES/0183-efinet-retransmit-if-our-device-is-busy.patch
@@ -0,0 +1,48 @@
+From 1b9767c1360827639927ab9bd337d1344d3b2d68 Mon Sep 17 00:00:00 2001
+From: Josef Bacik <jbacik@fb.com>
+Date: Mon, 31 Aug 2015 13:34:35 -0400
+Subject: [PATCH 3/3] efinet: retransmit if our device is busy
+
+When I fixed the txbuf handling I ripped out the retransmission code since it
+was flooding our network when we had the buggy behavior.  Turns out this was too
+heavy handed as we can still have transient tx timeouts.  So instead make sure
+we retry our transmission once per timeout.  This way we can deal with transient
+transmission problems without flooding the box.  This fixes an issue we were
+seeing in production.  Thanks,
+
+Signed-off-by: Josef Bacik <jbacik@fb.com>
+---
+ grub-core/net/drivers/efi/efinet.c | 10 ++++++++++
+ 1 file changed, 10 insertions(+)
+
+diff --git a/grub-core/net/drivers/efi/efinet.c b/grub-core/net/drivers/efi/efinet.c
+index ea0e0ca..c3a128c 100644
+--- a/grub-core/net/drivers/efi/efinet.c
++++ b/grub-core/net/drivers/efi/efinet.c
+@@ -38,6 +38,7 @@ send_card_buffer (struct grub_net_card *dev,
+   grub_efi_simple_network_t *net = dev->efi_net;
+   grub_uint64_t limit_time = grub_get_time_ms () + 4000;
+   void *txbuf;
++  int retry = 0;
+ 
+   if (dev->txbusy)
+     while (1)
+@@ -60,6 +61,15 @@ send_card_buffer (struct grub_net_card *dev,
+ 	    dev->txbusy = 0;
+ 	    break;
+ 	  }
++	if (!retry)
++	  {
++	    st = efi_call_7 (net->transmit, net, 0, dev->last_pkt_size,
++			     dev->txbuf, NULL, NULL, NULL);
++	    if (st != GRUB_EFI_SUCCESS)
++	      return grub_error (GRUB_ERR_IO,
++				 N_("couldn't send network packet"));
++	    retry = 1;
++	  }
+ 	if (limit_time < grub_get_time_ms ())
+ 	  return grub_error (GRUB_ERR_TIMEOUT,
+ 			     N_("couldn't send network packet"));
+-- 
+2.4.3
+
diff --git a/SOURCES/0184-Be-more-aggro-about-actually-using-the-configured-ne.patch b/SOURCES/0184-Be-more-aggro-about-actually-using-the-configured-ne.patch
new file mode 100644
index 0000000..ee62a3c
--- /dev/null
+++ b/SOURCES/0184-Be-more-aggro-about-actually-using-the-configured-ne.patch
@@ -0,0 +1,224 @@
+From 46d5b1ccce248a275b1dcf15824fb3501a32d9dc Mon Sep 17 00:00:00 2001
+From: Peter Jones <pjones@redhat.com>
+Date: Fri, 11 Sep 2015 17:30:49 -0400
+Subject: [PATCH] Be more aggro about actually using the *configured* network
+ device.
+
+Right now we use any SNP device with the same mac+IP block, but when
+it's discovered there will be more than one of them.  We need to pick
+the same one we were loaded with, so that  it'll be configured the same
+way as it was before, and won't be re-used by the system firmware later.
+
+Resolves: rhbz#1257475
+
+Signed-off-by: Peter Jones <example@example.com>
+---
+ grub-core/net/drivers/efi/efinet.c | 124 +++++++++++++++++++++++++++++--------
+ include/grub/efi/api.h             |   4 ++
+ 2 files changed, 102 insertions(+), 26 deletions(-)
+
+diff --git a/grub-core/net/drivers/efi/efinet.c b/grub-core/net/drivers/efi/efinet.c
+index c3a128c..fd47b8a 100644
+--- a/grub-core/net/drivers/efi/efinet.c
++++ b/grub-core/net/drivers/efi/efinet.c
+@@ -239,46 +239,85 @@ grub_efinet_get_device_handle (struct grub_net_card *card)
+   return card->efi_handle;
+ }
+ 
+-static void
+-grub_efinet_findcards (void)
++static int
++grub_efinet_find_snp_cards (int preferred_only, grub_efi_handle_t preferred,
++			    int *i)
+ {
+-  grub_efi_uintn_t num_handles;
+-  grub_efi_handle_t *handles;
++  grub_efi_uintn_t num_handles = 0;
++  grub_efi_handle_t *handles = NULL;
+   grub_efi_handle_t *handle;
+-  int i = 0;
++  grub_efi_device_path_t *pdp = NULL, *pp = NULL, *pc = NULL;
++  int ret = 0;
++
++  if (preferred)
++    {
++      grub_efi_device_path_t *pdpc;
++      pdpc = pdp = grub_efi_get_device_path (preferred);
++      if (pdp == NULL)
++	{
++	  grub_print_error ();
++	  return -1;
++	}
+ 
+-  /* Find handles which support the disk io interface.  */
++      for (; ! GRUB_EFI_END_ENTIRE_DEVICE_PATH (pdpc);
++	   pdpc = GRUB_EFI_NEXT_DEVICE_PATH (pdpc))
++	{
++	  pp = pc;
++	  pc = pdpc;
++	}
++    }
++
++  /* Find handles which support the SNP interface.  */
+   handles = grub_efi_locate_handle (GRUB_EFI_BY_PROTOCOL, &net_io_guid,
+ 				    0, &num_handles);
+-  if (! handles)
+-    return;
+-  for (handle = handles; num_handles--; handle++)
++
++  for (handle = handles; handle && num_handles--; handle++)
+     {
+       grub_efi_simple_network_t *net;
+       struct grub_net_card *card;
+       grub_efi_device_path_t *dp, *parent = NULL, *child = NULL;
+ 
+-      /* EDK2 UEFI PXE driver creates IPv4 and IPv6 messaging devices as
+-	 children of main MAC messaging device. We only need one device with
+-	 bound SNP per physical card, otherwise they compete with each other
+-	 when polling for incoming packets.
+-       */
++      /* if we're looking for only the preferred handle, skip anything that
++	 isn't it. */
++      if (preferred_only && preferred != NULL && *handle != preferred)
++	continue;
++
++      /* if we're not looking for the preferred handle, skip it if it's
++	 found. */
++      if (!preferred_only && *handle == preferred)
++	continue;
++
+       dp = grub_efi_get_device_path (*handle);
+       if (!dp)
+ 	continue;
+-      for (; ! GRUB_EFI_END_ENTIRE_DEVICE_PATH (dp); dp = GRUB_EFI_NEXT_DEVICE_PATH (dp))
++
++      for (; ! GRUB_EFI_END_ENTIRE_DEVICE_PATH (dp);
++	   dp = GRUB_EFI_NEXT_DEVICE_PATH (dp))
+ 	{
+ 	  parent = child;
+ 	  child = dp;
+ 	}
+-      if (child
+-	  && GRUB_EFI_DEVICE_PATH_TYPE (child) == GRUB_EFI_MESSAGING_DEVICE_PATH_TYPE
+-	  && (GRUB_EFI_DEVICE_PATH_SUBTYPE (child) == GRUB_EFI_IPV4_DEVICE_PATH_SUBTYPE
+-	      || GRUB_EFI_DEVICE_PATH_SUBTYPE (child) == GRUB_EFI_IPV6_DEVICE_PATH_SUBTYPE)
+-	  && parent
+-	  && GRUB_EFI_DEVICE_PATH_TYPE (parent) == GRUB_EFI_MESSAGING_DEVICE_PATH_TYPE
+-	  && GRUB_EFI_DEVICE_PATH_SUBTYPE (parent) == GRUB_EFI_MAC_ADDRESS_DEVICE_PATH_SUBTYPE)
+-	continue;
++
++      if (!preferred_only)
++	{
++	  if (pp && pc
++	      && grub_efi_compare_device_paths (pp, parent) == 0
++	      && grub_efi_compare_device_paths (pc, child) == 0)
++	    continue;
++
++	  if (child
++	      && (GRUB_EFI_DEVICE_PATH_IS_TYPE(child,
++					  GRUB_EFI_MESSAGING_DEVICE_PATH_TYPE,
++					  GRUB_EFI_IPV6_DEVICE_PATH_SUBTYPE) ||
++		  GRUB_EFI_DEVICE_PATH_IS_TYPE(child,
++					  GRUB_EFI_MESSAGING_DEVICE_PATH_TYPE,
++					  GRUB_EFI_IPV4_DEVICE_PATH_SUBTYPE))
++	      && parent
++	      && (GRUB_EFI_DEVICE_PATH_IS_TYPE(parent,
++				    GRUB_EFI_MESSAGING_DEVICE_PATH_TYPE,
++				    GRUB_EFI_MAC_ADDRESS_DEVICE_PATH_SUBTYPE)))
++	    continue;
++	}
+ 
+       net = grub_efi_open_protocol (*handle, &net_io_guid,
+ 				    GRUB_EFI_OPEN_PROTOCOL_GET_PROTOCOL);
+@@ -302,7 +341,7 @@ grub_efinet_findcards (void)
+ 	{
+ 	  grub_print_error ();
+ 	  grub_free (handles);
+-	  return;
++	  return -1;
+ 	}
+ 
+       card->mtu = net->mode->max_packet_size;
+@@ -313,13 +352,14 @@ grub_efinet_findcards (void)
+ 	  grub_print_error ();
+ 	  grub_free (handles);
+ 	  grub_free (card);
+-	  return;
++	  return -1;
+ 	}
+       card->txbusy = 0;
+ 
+       card->rcvbufsize = ALIGN_UP (card->mtu, 64) + 256;
+ 
+-      card->name = grub_xasprintf ("efinet%d", i++);
++      card->name = grub_xasprintf ("efinet%d", *i);
++      *i = (*i)+1;
+       card->driver = &efidriver;
+       card->flags = 0;
+       card->default_address.type = GRUB_NET_LINK_LEVEL_PROTOCOL_ETHERNET;
+@@ -330,8 +370,38 @@ grub_efinet_findcards (void)
+       card->efi_handle = *handle;
+ 
+       grub_net_card_register (card);
++      ret++;
+     }
+   grub_free (handles);
++
++  return ret;
++}
++
++static void
++grub_efinet_findcards (void)
++{
++  grub_efi_loaded_image_t *image = NULL;
++  int rc;
++  int efinet_number = 0;
++
++  image = grub_efi_get_loaded_image (grub_efi_image_handle);
++
++  if (image && image->device_handle)
++    {
++      rc = grub_efinet_find_snp_cards (1, image->device_handle, &efinet_number);
++      if (rc < 0)
++	return;
++
++      rc = grub_efinet_find_snp_cards (0, image->device_handle, &efinet_number);
++      if (rc < 0)
++	return;
++    }
++  else
++    {
++      rc = grub_efinet_find_snp_cards (0, NULL, &efinet_number);
++      if (rc < 0)
++	return;
++    }
+ }
+ 
+ static void
+@@ -353,6 +423,8 @@ grub_efi_net_config_real (grub_efi_handle_t hnd, char **device,
+     struct grub_efi_pxe_mode *pxe_mode;
+     if (card->driver != &efidriver)
+       continue;
++    if (hnd != card->efi_handle)
++      continue;
+     cdp = grub_efi_get_device_path (card->efi_handle);
+     if (! cdp)
+       continue;
+diff --git a/include/grub/efi/api.h b/include/grub/efi/api.h
+index 029ee92..f0640c2 100644
+--- a/include/grub/efi/api.h
++++ b/include/grub/efi/api.h
+@@ -573,6 +573,10 @@ typedef struct grub_efi_device_path grub_efi_device_path_t;
+    It seems to be identical to EFI_DEVICE_PATH.  */
+ typedef struct grub_efi_device_path grub_efi_device_path_protocol_t;
+ 
++#define GRUB_EFI_DEVICE_PATH_IS_TYPE(dp, type, subtype) \
++	((GRUB_EFI_DEVICE_PATH_TYPE(dp) == (type)) && \
++	 (GRUB_EFI_DEVICE_PATH_SUBTYPE(dp) == (subtype)))
++
+ #define GRUB_EFI_DEVICE_PATH_TYPE(dp)		((dp)->type & 0x7f)
+ #define GRUB_EFI_DEVICE_PATH_SUBTYPE(dp)	((dp)->subtype)
+ #define GRUB_EFI_DEVICE_PATH_LENGTH(dp)		((dp)->length)
+-- 
+2.4.3
+
diff --git a/SOURCES/0185-efinet-add-filter-for-the-first-exclusive-reopen-of-.patch b/SOURCES/0185-efinet-add-filter-for-the-first-exclusive-reopen-of-.patch
new file mode 100644
index 0000000..aeb5543
--- /dev/null
+++ b/SOURCES/0185-efinet-add-filter-for-the-first-exclusive-reopen-of-.patch
@@ -0,0 +1,47 @@
+From 2cdea5ad6c34d04e0a2a833fc010618d3e6bddac Mon Sep 17 00:00:00 2001
+From: RHEL Ninjas <example@example.com>
+Date: Fri, 25 Sep 2015 16:24:23 +0900
+Subject: [PATCH] efinet: add filter for the first exclusive reopen of SNP
+
+---
+ grub-core/net/drivers/efi/efinet.c | 24 ++++++++++++++++++++++++
+ 1 file changed, 24 insertions(+)
+
+diff --git a/grub-core/net/drivers/efi/efinet.c b/grub-core/net/drivers/efi/efinet.c
+index fd47b8a..b6b5187 100644
+--- a/grub-core/net/drivers/efi/efinet.c
++++ b/grub-core/net/drivers/efi/efinet.c
+@@ -479,6 +479,30 @@ grub_efi_net_config_real (grub_efi_handle_t hnd, char **device,
+       if (net->mode->state == GRUB_EFI_NETWORK_STARTED
+ 	  && efi_call_3 (net->initialize, net, 0, 0) != GRUB_EFI_SUCCESS)
+ 	continue;
++
++      /* Enable hardware receive filters if driver declares support for it.
++	 We need unicast and broadcast and additionaly all nodes and
++	 solicited multicast for IPv6. Solicited multicast is per-IPv6
++	 address and we currently do not have API to do it so simply
++	 try to enable receive of all multicast packets or evertyhing in
++	 the worst case (i386 PXE driver always enables promiscuous too).
++
++	 This does trust firmware to do what it claims to do.
++       */
++      if (net->mode->receive_filter_mask)
++	{
++	  grub_uint32_t filters = GRUB_EFI_SIMPLE_NETWORK_RECEIVE_UNICAST   |
++				  GRUB_EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST |
++				  GRUB_EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST;
++
++	  filters &= net->mode->receive_filter_mask;
++	  if (!(filters & GRUB_EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST))
++	    filters |= (net->mode->receive_filter_mask &
++			GRUB_EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS);
++
++	  efi_call_6 (net->receive_filters, net, filters, 0, 0, 0, NULL);
++	}
++
+       card->efi_net = net;
+     }
+     return;
+-- 
+2.5.0
+
diff --git a/SOURCES/gitignore b/SOURCES/gitignore
index c21ee5f..f318bf1 100644
--- a/SOURCES/gitignore
+++ b/SOURCES/gitignore
@@ -1,12 +1,11 @@
 00_header
 10_*
-!10_*.in
 20_linux_xen
 30_os-prober
 40_custom
 41_custom
-*.[[:digit:]]
-!util/*.[[:digit:]]
+*.1
+*.8
 aclocal.m4
 ahci_test
 ascii.bitmaps
@@ -240,3 +239,5 @@ build-aux/test-driver
 /garbage-gen
 /garbage-gen.exe
 /grub-fs-tester
+!util/grub.d/[[:digit:]][[:digit:]]*.in
+!util/*.[[:digit:]]
diff --git a/SPECS/grub2.spec b/SPECS/grub2.spec
index 5f3de40..aafba13 100644
--- a/SPECS/grub2.spec
+++ b/SPECS/grub2.spec
@@ -33,9 +33,6 @@
 %if 0%{?fedora}
 %global efidir fedora
 %endif
-%if 0%{?centos}
-%global efidir centos
-%endif
 
 %endif
 
@@ -45,7 +42,7 @@
 Name:           grub2
 Epoch:          1
 Version:        2.02
-Release:        0.17%{?dist}.4
+Release:        0.29%{?dist}
 Summary:        Bootloader with support for Linux, Multiboot and more
 
 Group:          System Environment/Base
@@ -54,8 +51,8 @@ URL:            http://www.gnu.org/software/grub/
 Obsoletes:	grub < 1:0.98
 Source0:        ftp://alpha.gnu.org/gnu/grub/grub-%{tarversion}.tar.xz
 #Source0:	ftp://ftp.gnu.org/gnu/grub/grub-%{tarversion}.tar.xz
-Source1:	centos.cer
-#(source removed)
+Source1:	securebootca.cer
+Source2:	secureboot.cer
 Source4:	http://unifoundry.com/unifont-5.1.20080820.pcf.gz
 Source5:	theme.tar.bz2
 Source6:	gitignore
@@ -215,8 +212,39 @@ Patch0151: 0001-Initialized-initrd_ctx-so-we-don-t-free-a-random-poi.patch
 Patch0152: 0002-Load-arm-with-SB-enabled.patch
 Patch0153: 0001-Fix-up-some-man-pages-rpmdiff-noticed.patch
 Patch0154: 0001-Try-prefix-if-fw_path-doesn-t-work.patch
-Patch0155: 0002-Use-Distribution-Package-Sort-for-grub2-mkconfig-112.patch
-Patch0156: 0001-Try-to-make-sure-configure.ac-and-grub-rpm-sort-play.patch
+Patch0155: 0001-Update-info-with-grub.cfg-netboot-selection-order-11.patch
+Patch0156: 0002-Use-Distribution-Package-Sort-for-grub2-mkconfig-112.patch
+Patch0157: 0001-efidisk-move-device-path-helpers-in-core-for-efinet.patch
+Patch0158: 0158-efinet-Check-for-immediate-completition.patch
+Patch0159: 0159-efinet-memory-leak-on-module-removal.patch
+Patch0160: 0160-efinet-cannot-free-const-char-pointer.patch
+Patch0161: 0161-Revert-efinet-memory-leak-on-module-removal.patch
+Patch0162: 0162-efinet-skip-virtual-IPv4-and-IPv6-devices-when-enume.patch
+Patch0163: 0163-efinet-open-Simple-Network-Protocol-exclusively.patch
+Patch0164: 0164-efinet-enable-hardware-filters-when-opening-interfac.patch
+Patch0165: 0165-efinet-handle-get_status-on-buggy-firmware-properly.patch
+Patch0166: 0166-Handle-rssd-storage-devices.patch
+Patch0167: 0167-xfs-Fix-termination-loop-for-directory-iteration.patch
+Patch0168: 0168-xfs-Convert-inode-numbers-to-cpu-endianity-immediate.patch
+Patch0169: 0169-xfs-Add-helpers-for-inode-size.patch
+Patch0170: 0170-xfs-V5-filesystem-format-support.patch
+Patch0171: 0171-xfs-silence-Coverity-overflow-warning.patch
+Patch0172: 0172-send-router-solicitation-for-ipv6-address-autoconf-v.patch
+Patch0173: 0173-icmp6-fix-no-respond-to-neighbor-solicit-message.patch
+Patch0174: 0174-calibrate_tsc-use-the-Stall-EFI-boot-service-on-GRUB.patch
+Patch0175: 0175-fix-memory-corruption-in-pubkey-filter-over-network.patch
+Patch0176: 0176-Make-grub2-mkconfig-construct-titles-that-look-like-.patch
+Patch0177: 0177-don-t-strip-fw_path-twice-for-EFI-network-boot.patch
+Patch0178: 0178-Add-friendly-grub2-password-config-tool-985962.patch
+Patch0179: 0179-Try-to-make-sure-configure.ac-and-grub-rpm-sort-play.patch
+Patch0180: 0180-ppc64le-sync-mkconfig-to-disk-1212114.patch
+Patch0181: 0181-tcp-ack-when-we-get-an-OOO-lost-packet.patch
+Patch0182: 0182-tcp-add-window-scaling-support.patch
+Patch0183: 0183-efinet-retransmit-if-our-device-is-busy.patch
+Patch0184: 0184-Be-more-aggro-about-actually-using-the-configured-ne.patch
+Patch0185: 0185-efinet-add-filter-for-the-first-exclusive-reopen-of-.patch
+
+
 
 BuildRequires:  flex bison binutils python
 BuildRequires:  ncurses-devel xz-devel bzip2-devel
@@ -284,6 +312,7 @@ provides support for rebuilding your own grub.efi on EFI systems.
 Summary:	Support tools for GRUB.
 Group:		System Environment/Base
 Requires:	gettext os-prober which file system-logos
+Requires(pre):	sed grep coreutils
 
 %description tools
 The GRand Unified Bootloader (GRUB) is a highly configurable and customizable
@@ -337,7 +366,7 @@ cd grub-efi-%{tarversion}
 		-e 's/-mregparm=3/-mregparm=4/g'		\
 		-e 's/-fexceptions//g'				\
 		-e 's/-fasynchronous-unwind-tables//g'		\
-		-e 's/^/ -fno-strict-aliasing /' )"		\
+		-e 's/^/ -fno-strict-aliasing -std=gnu99 /' )"	\
 	TARGET_LDFLAGS=-static					\
         --with-platform=efi					\
 	--with-grubdir=%{name}					\
@@ -355,7 +384,7 @@ GRUB_MODULES="	all_video boot btrfs cat chain configfile echo efifwsetup \
 %ifarch aarch64
 GRUB_MODULES="${GRUB_MODULES} linux"
 %else
-GRUB_MODULES="${GRUB_MODULES} linuxefi multiboot2 multiboot"
+GRUB_MODULES="${GRUB_MODULES} linuxefi"
 %endif
 ./grub-mkimage -O %{grubefiarch} -o %{grubefiname}.orig -p /EFI/%{efidir} \
 		-d grub-core ${GRUB_MODULES}
@@ -365,8 +394,8 @@ GRUB_MODULES="${GRUB_MODULES} linuxefi multiboot2 multiboot"
 mv %{grubefiname}.orig %{grubefiname}
 mv %{grubeficdname}.orig %{grubeficdname}
 %else
-%pesign -s -i %{grubefiname}.orig -o %{grubefiname} -a %{SOURCE1} -c %{SOURCE1} -n redhatsecureboot301
-%pesign -s -i %{grubeficdname}.orig -o %{grubeficdname} -a %{SOURCE1} -c %{SOURCE1} -n redhatsecureboot301
+%pesign -s -i %{grubefiname}.orig -o %{grubefiname} -a %{SOURCE1} -c %{SOURCE2} -n redhatsecureboot301
+%pesign -s -i %{grubeficdname}.orig -o %{grubeficdname} -a %{SOURCE1} -c %{SOURCE2} -n redhatsecureboot301
 %endif
 cd ..
 %endif
@@ -391,7 +420,7 @@ cd grub-%{tarversion}
 		-e 's/-m64//g'					\
 		-e 's/-fasynchronous-unwind-tables//g'		\
 		-e 's/-mcpu=power7/-mcpu=power6/g'		\
-		-e 's/^/ -fno-strict-aliasing /' )"		\
+		-e 's/^/ -fno-strict-aliasing -std=gnu99 /' )"	\
 	TARGET_LDFLAGS=-static					\
         --with-platform=%{platform}				\
 	--with-grubdir=%{name}					\
@@ -516,7 +545,28 @@ ln -s /boot/efi/EFI/%{efidir}/grubenv boot/grub2/grubenv
 %clean    
 rm -rf $RPM_BUILD_ROOT
 
-%post
+%pre tools
+if [ $1 -gt 1 ]; then
+    if [ -f /etc/grub.d/01_users ] && \
+	    grep -c -q '^password_pbkdf2 root' /etc/grub.d/01_users ; then
+	if [ -f /boot/efi/EFI/%{efidir}/grub.cfg ]; then
+	    # on EFI we don't get permissions on the file, but
+	    # the directory is protected.
+	    grep '^password_pbkdf2 root' /etc/grub.d/01_users | \
+		sed 's/^password_pbkdf2 root \(.*\)$/GRUB_PASSWORD=\1/' \
+		> /boot/efi/EFI/%{efidir}/user.cfg
+	fi
+	if [ -f /boot/grub2/grub.cfg ]; then
+	    install -m 0600 /dev/null /boot/grub2/user.cfg
+	    chmod 0600 /boot/grub2/user.cfg
+	    grep '^password_pbkdf2 root' /etc/grub.d/01_users | \
+		sed 's/^password_pbkdf2 root \(.*\)$/GRUB_PASSWORD=\1/' \
+		> /boot/grub2/user.cfg
+	fi
+    fi
+fi
+
+%post tools
 if [ "$1" = 1 ]; then
 	/sbin/install-info --info-dir=%{_infodir} %{_infodir}/%{name}.info.gz || :
 	/sbin/install-info --info-dir=%{_infodir} %{_infodir}/%{name}-dev.info.gz || :
@@ -547,7 +597,7 @@ mv -f /boot/grub2.tmp/*.mod \
       /boot/grub2/ &&
 rm -r /boot/grub2.tmp/ || :
 
-%preun
+%preun tools
 if [ "$1" = 0 ]; then
 	/sbin/install-info --delete --info-dir=%{_infodir} %{_infodir}/%{name}.info.gz || :
 	/sbin/install-info --delete --info-dir=%{_infodir} %{_infodir}/%{name}-dev.info.gz || :
@@ -596,6 +646,7 @@ fi
 %{_sbindir}/%{name}-reboot
 %{_sbindir}/%{name}-rpm-sort
 %{_sbindir}/%{name}-set-default
+%{_sbindir}/%{name}-setpassword
 %{_sbindir}/%{name}-sparc64-setup
 %{_bindir}/%{name}-editenv
 %{_bindir}/%{name}-file
@@ -623,7 +674,7 @@ fi
 %{_sysconfdir}/grub.d/README
 %attr(0644,root,root) %ghost %config(noreplace) %{_sysconfdir}/default/grub
 %{_sysconfdir}/sysconfig/grub
-%dir /boot/%{name}
+%attr(0700,root,root) %dir /boot/%{name}
 %dir /boot/%{name}/themes/
 %dir /boot/%{name}/themes/system
 %exclude /boot/%{name}/themes/system/*
@@ -641,29 +692,83 @@ fi
 %exclude %{_datarootdir}/grub/themes/starfield
 
 %changelog
-* Tue Sep 15 2015 CentOS Sources <bugs@centos.org> - 2.02-0.17.el7.centos.4
-- Roll in CentOS Secureboot keys
-- Move the edidir to be CentOS, so people can co-install fedora, rhel and centos
-
-* Mon Aug 03 2015 Robert Marshall <rmarshall@redhat.com> - 2.02-0.17.4
-- Reversed .17.2 and changed how rpm-sort availability is verified.
-  Resolves: rhbz#1229329
-
-* Fri Jul 31 2015 Robert Marshall <rmarshall@redhat.com> = 2.02.0.17.3
-- Built again with proper build target and updates rhbz# to be zstream.
-  Resolves: rhbz#1229329
-
-* Thu Jul 30 2015 Robert Marshall <rmarshall@redhat.com> - 2.02.0.17.2
-- Reversed order of kernel sorting.
-  Resolves: rhbz#1229329
-
-* Tue Jul 14 2015 Robert Marshall <rmarshall@redhat.com> - 2.02-0.17.1
-- Fixed rpmdiff issues.
-  Resolves: rhbz#1229329
-
-* Mon Jul 13 2015 Robert Marshall <rmarshall@redhat.com> - 2.02.0.17
+* Fri Oct 09 2015 Peter Jones <pjones@redhat.com> - 2.02-0.29
+- Fix DHCP6 timeouts due to failed network stack once more.
+  Resolves: rhbz#1267139
+
+* Thu Sep 17 2015 Peter Jones <pjones@redhat.com> - 2.02-0.28
+- Once again, rebuild for the right build target.
+  Resolves: CVE-2015-5281
+
+* Thu Sep 17 2015 Peter Jones <pjones@redhat.com> - 2.02-0.27
+- Remove multiboot and multiboot2 modules from the .efi builds; they
+  should never have been there.
+  Resolves: CVE-2015-5281
+
+* Mon Sep 14 2015 Peter Jones <pjones@redhat.com> - 2.02-0.26
+- Be more aggressive about trying to make sure we use the configured SNP
+  device in UEFI.
+  Resolves: rhbz#1257475
+
+* Wed Aug 05 2015 Robert Marshall <rmarshall@redhat.com> - 2.02-0.25
+- Force file sync to disk on ppc64le machines.
+  Resolves: rhbz#1212114
+
+* Mon Aug 03 2015 Peter Jones <pjones@redhat.com> - 2.02-0.24
+- Undo 0.23 and fix it a different way.
+  Resolves: rhbz#1124074
+
+* Thu Jul 30 2015 Peter Jones <pjones@redhat.com> - 2.02-0.23
+- Reverse kernel sort order so they're displayed correctly.
+  Resolves: rhbz#1124074
+
+* Wed Jul 08 2015 Peter Jones <pjones@redhat.com> - 2.02-0.22
+- Make upgrades work reasonably well with grub2-setpassword .
+  Related: rhbz#985962
+
+* Tue Jul 07 2015 Peter Jones <pjones@redhat.com> - 2.02-0.21
+- Add a simpler grub2 password config tool
+  Related: rhbz#985962
+- Some more coverity nits.
+
+* Mon Jul 06 2015 Peter Jones <pjones@redhat.com> - 2.02-0.20
+- Deal with some coverity nits.
+  Related: rhbz#1215839
+  Related: rhbz#1124074
+
+* Mon Jul 06 2015 Peter Jones <pjones@redhat.com> - 2.02-0.19
+- Rebuild for Aarch64
+- Deal with some coverity nits.
+  Related: rhbz#1215839
+  Related: rhbz#1124074
+
+* Thu Jul 02 2015 Peter Jones <pjones@redhat.com> - 2.02-0.18
+- Update for an rpmdiff problem with one of the man pages.
+  Related: rhbz#1124074
+
+* Tue Jun 30 2015 Peter Jones <pjones@redhat.com> - 2.02-0.17
+- Handle ipv6 better
+  Resolves: rhbz#1154226
+- On UEFI, use SIMPLE_NETWORK_PROTOCOL when we can.
+  Resolves: rhbz#1233378
+- Handle rssd disk drives in grub2 utilities.
+  Resolves: rhbz#1087962
+- Handle xfs CRC disk format.
+  Resolves: rhbz#1001279
+- Calibrate TCS using the EFI Stall service
+  Resolves: rhbz#1150698
+- Fix built-in gpg verification when using TFTP
+  Resolves: rhbz#1167977
+- Generate better stanza titles so grubby can find them easier.
+  Resolves: rhbz#1177003
+- Don't strip the fw_path variable twice when we're using EFI networking.
+  Resolves: rhbz#1211101
+
+* Mon May 11 2015 Peter Jones <pjones@redhat.com> - 2.02-0.17
+- Document network boot paths better
+  Resolves: rhbz#1148650
 - Use an rpm-based version sorted in grub2-mkconfig
-  Resolves: rhbz#1229329
+  Resolves: rhbz#1124074
 
 * Thu Oct 09 2014 Peter Jones <pjones@redhat.com> - 2.02-0.16
 - ... and build it on the right target.