diff -u grub2-1.99/debian/changelog grub2-1.99/debian/changelog
--- grub2-1.99/debian/changelog
+++ grub2-1.99/debian/changelog
@@ -1,3 +1,11 @@
+grub2 (1.99-23.1) unstable; urgency=low
+
+  * Non-maintainer upload.
+  * Apply Ubuntu patch fixing some EFI boot failures (closes: #687320)
+    - Thanks to Colin Watson.
+
+ -- Michael Gilbert <mgilbert@debian.org>  Sun, 14 Oct 2012 04:09:51 -0400
+
 grub2 (1.99-23) unstable; urgency=low
 
   [ Debconf translations ]
diff -u grub2-1.99/debian/patches/series grub2-1.99/debian/patches/series
--- grub2-1.99/debian/patches/series
+++ grub2-1.99/debian/patches/series
@@ -45,0 +46 @@
+ubuntu_efi_device_discovery.patch
only in patch2:
unchanged:
--- grub2-1.99.orig/debian/patches/ubuntu_efi_device_discovery.patch
+++ grub2-1.99/debian/patches/ubuntu_efi_device_discovery.patch
@@ -0,0 +1,390 @@
+Description: Several EFI device discovery patches to fix boot failures
+ Move compare_device_paths to an externally-visible function.
+ .
+ Fix off-by-one error.
+ .
+ Accept whole disk declared as partition.
+ .
+ Fix incorrect memory usage.
+ .
+ Remove unreachable code.
+ .
+ Simplify root device discovery and don't fail when trying to open incorrect
+ devices.
+Author: Vladimir Serbinenko <phcoder@gmail.com>
+Origin: backport, http://bazaar.launchpad.net/~vcs-imports/grub/grub2-bzr/revision/3375
+Origin: upstream, http://bazaar.launchpad.net/~vcs-imports/grub/grub2-bzr/revision/3383
+Origin: backport, http://bazaar.launchpad.net/~vcs-imports/grub/grub2-bzr/revision/3652
+Origin: backport, http://bazaar.launchpad.net/~vcs-imports/grub/grub2-bzr/revision/3781
+Bug-Ubuntu: https://bugs.launchpad.net/bugs/975061
+Forwarded: not-needed
+Last-Update: 2012-04-17
+
+Index: b/grub-core/disk/efi/efidisk.c
+===================================================================
+--- a/grub-core/disk/efi/efidisk.c
++++ b/grub-core/disk/efi/efidisk.c
+@@ -84,54 +84,6 @@
+   return p;
+ }
+ 
+-/* Compare device paths.  */
+-static int
+-compare_device_paths (const grub_efi_device_path_t *dp1,
+-		      const grub_efi_device_path_t *dp2)
+-{
+-  if (! dp1 || ! dp2)
+-    /* Return non-zero.  */
+-    return 1;
+-
+-  while (1)
+-    {
+-      grub_efi_uint8_t type1, type2;
+-      grub_efi_uint8_t subtype1, subtype2;
+-      grub_efi_uint16_t len1, len2;
+-      int ret;
+-
+-      type1 = GRUB_EFI_DEVICE_PATH_TYPE (dp1);
+-      type2 = GRUB_EFI_DEVICE_PATH_TYPE (dp2);
+-
+-      if (type1 != type2)
+-	return (int) type2 - (int) type1;
+-
+-      subtype1 = GRUB_EFI_DEVICE_PATH_SUBTYPE (dp1);
+-      subtype2 = GRUB_EFI_DEVICE_PATH_SUBTYPE (dp2);
+-
+-      if (subtype1 != subtype2)
+-	return (int) subtype1 - (int) subtype2;
+-
+-      len1 = GRUB_EFI_DEVICE_PATH_LENGTH (dp1);
+-      len2 = GRUB_EFI_DEVICE_PATH_LENGTH (dp2);
+-
+-      if (len1 != len2)
+-	return (int) len1 - (int) len2;
+-
+-      ret = grub_memcmp (dp1, dp2, len1);
+-      if (ret != 0)
+-	return ret;
+-
+-      if (GRUB_EFI_END_ENTIRE_DEVICE_PATH (dp1))
+-	break;
+-
+-      dp1 = (grub_efi_device_path_t *) ((char *) dp1 + len1);
+-      dp2 = (grub_efi_device_path_t *) ((char *) dp2 + len2);
+-    }
+-
+-  return 0;
+-}
+-
+ static struct grub_efidisk_data *
+ make_devices (void)
+ {
+@@ -214,7 +166,7 @@
+       if (parent == d)
+ 	continue;
+ 
+-      if (compare_device_paths (parent->device_path, dp) == 0)
++      if (grub_efi_compare_device_paths (parent->device_path, dp) == 0)
+ 	{
+ 	  /* Found.  */
+ 	  if (! parent->last_device_path)
+@@ -249,7 +201,7 @@
+       ldp->length[0] = sizeof (*ldp);
+       ldp->length[1] = 0;
+ 
+-      if (compare_device_paths (dp, d->device_path) == 0)
++      if (grub_efi_compare_device_paths (dp, d->device_path) == 0)
+ 	if (hook (p))
+ 	  {
+ 	    grub_free (dp);
+@@ -273,11 +225,11 @@
+     {
+       int ret;
+ 
+-      ret = compare_device_paths (find_last_device_path ((*p)->device_path),
+-				  find_last_device_path (d->device_path));
++      ret = grub_efi_compare_device_paths (find_last_device_path ((*p)->device_path),
++					   find_last_device_path (d->device_path));
+       if (ret == 0)
+-	ret = compare_device_paths ((*p)->device_path,
+-				    d->device_path);
++	ret = grub_efi_compare_device_paths ((*p)->device_path,
++					     d->device_path);
+       if (ret == 0)
+ 	return;
+       else if (ret > 0)
+@@ -530,7 +482,7 @@
+      and total sectors should be replaced with total blocks.  */
+   grub_dprintf ("efidisk", "m = %p, last block = %llx, block size = %x\n",
+ 		m, (unsigned long long) m->last_block, m->block_size);
+-  disk->total_sectors = m->last_block;
++  disk->total_sectors = m->last_block + 1;
+   if (m->block_size & (m->block_size - 1) || !m->block_size)
+     return grub_error (GRUB_ERR_IO, "invalid sector size %d",
+ 		       m->block_size);
+@@ -703,10 +655,52 @@
+   return 0;
+ }
+ 
++#define NEEDED_BUFLEN sizeof ("XdXXXXXXXXXX")
++static inline int
++get_diskname_from_path_real (const grub_efi_device_path_t *path,
++			     struct grub_efidisk_data *head,
++			     char *buf)
++{
++  int count = 0;
++  struct grub_efidisk_data *d;
++  for (d = head, count = 0; d; d = d->next, count++)
++    if (grub_efi_compare_device_paths (d->device_path, path) == 0)
++      {
++	grub_snprintf (buf, NEEDED_BUFLEN - 1, "d%d", count);
++	return 1;
++      }
++  return 0;
++}
++
++static inline int
++get_diskname_from_path (const grub_efi_device_path_t *path,
++			char *buf)
++{
++  if (get_diskname_from_path_real (path, hd_devices, buf + 1))
++    {
++      buf[0] = 'h';
++      return 1;
++    }
++
++  if (get_diskname_from_path_real (path, fd_devices, buf + 1))
++    {
++      buf[0] = 'f';
++      return 1;
++    }
++
++  if (get_diskname_from_path_real (path, cd_devices, buf + 1))
++    {
++      buf[0] = 'c';
++      return 1;
++    }
++  return 0;
++}
++
+ char *
+ grub_efidisk_get_device_name (grub_efi_handle_t *handle)
+ {
+   grub_efi_device_path_t *dp, *ldp;
++  char device_name[NEEDED_BUFLEN];
+ 
+   dp = grub_efi_get_device_path (handle);
+   if (! dp)
+@@ -720,39 +714,13 @@
+       && (GRUB_EFI_DEVICE_PATH_SUBTYPE (ldp)
+ 	  == GRUB_EFI_HARD_DRIVE_DEVICE_PATH_SUBTYPE))
+     {
+-      /* This is a hard disk partition.  */
+-      grub_disk_t parent = 0;
+-      grub_partition_t tpart = NULL;
+-      char *device_name;
++      char *partition_name = NULL;
++      char *dev_name;
+       grub_efi_device_path_t *dup_dp, *dup_ldp;
+       grub_efi_hard_drive_device_path_t hd;
+-      auto int find_parent_disk (const char *name);
+-      auto int find_partition (grub_disk_t disk, const grub_partition_t part);
+-
+-      /* Find the disk which is the parent of a given hard disk partition.  */
+-      int find_parent_disk (const char *name)
+-	{
+-	  grub_disk_t disk;
+-
+-	  disk = grub_disk_open (name);
+-	  if (! disk)
+-	    return 1;
+-
+-	  if (disk->dev->id == GRUB_DISK_DEVICE_EFIDISK_ID)
+-	    {
+-	      struct grub_efidisk_data *d;
+-
+-	      d = disk->data;
+-	      if (compare_device_paths (d->device_path, dup_dp) == 0)
+-		{
+-		  parent = disk;
+-		  return 1;
+-		}
+-	    }
++      grub_disk_t parent = 0;
+ 
+-	  grub_disk_close (disk);
+-	  return 0;
+-	}
++      auto int find_partition (grub_disk_t disk, const grub_partition_t part);
+ 
+       /* Find the identical partition.  */
+       int find_partition (grub_disk_t disk __attribute__ ((unused)),
+@@ -761,7 +729,7 @@
+ 	  if (grub_partition_get_start (part) == hd.partition_start
+ 	      && grub_partition_get_len (part) == hd.partition_size)
+ 	    {
+-	      tpart = part;
++	      partition_name = grub_partition_get_name (part);
+ 	      return 1;
+ 	    }
+ 
+@@ -780,7 +748,9 @@
+       dup_ldp->length[0] = sizeof (*dup_ldp);
+       dup_ldp->length[1] = 0;
+ 
+-      grub_efidisk_iterate (find_parent_disk);
++      if (!get_diskname_from_path (dup_dp, device_name))
++	return 0;
++      parent = grub_disk_open (device_name);
+       grub_free (dup_dp);
+ 
+       if (! parent)
+@@ -788,58 +758,33 @@
+ 
+       /* Find a partition which matches the hard drive device path.  */
+       grub_memcpy (&hd, ldp, sizeof (hd));
+-      grub_partition_iterate (parent, find_partition);
+-
+-      if (! tpart)
++      if (hd.partition_start == 0
++	  && hd.partition_size == grub_disk_get_size (parent))
+ 	{
+-	  grub_disk_close (parent);
+-	  return 0;
++	  dev_name = grub_strdup (parent->name);
+ 	}
+-
+-      {
+-	char *partition_name = grub_partition_get_name (tpart);
+-	device_name = grub_xasprintf ("%s,%s", parent->name, partition_name);
+-	grub_free (partition_name);
+-      }
+-      grub_disk_close (parent);
+-
+-      return device_name;
+-    }
+-  else
+-    {
+-      /* This should be an entire disk.  */
+-      auto int find_disk (const char *name);
+-      char *device_name = 0;
+-
+-      int find_disk (const char *name)
++      else
+ 	{
+-	  grub_disk_t disk;
+-
+-	  disk = grub_disk_open (name);
+-	  if (! disk)
+-	    return 1;
++	  grub_partition_iterate (parent, find_partition);
+ 
+-	  if (disk->dev->id == GRUB_DISK_DEVICE_EFIDISK_ID)
++	  if (! partition_name)
+ 	    {
+-	      struct grub_efidisk_data *d;
+-
+-	      d = disk->data;
+-	      if (compare_device_paths (d->device_path, dp) == 0)
+-		{
+-		  device_name = grub_strdup (disk->name);
+-		  grub_disk_close (disk);
+-		  return 1;
+-		}
++	      grub_disk_close (parent);
++	      return 0;
+ 	    }
+ 
+-	  grub_disk_close (disk);
+-	  return 0;
+-
++	  dev_name = grub_xasprintf ("%s,%s", parent->name, partition_name);
++	  grub_free (partition_name);
+ 	}
++      grub_disk_close (parent);
+ 
+-      grub_efidisk_iterate (find_disk);
+-      return device_name;
++      return dev_name;
++    }
++  else
++    {
++      /* This should be an entire disk.  */
++      if (!get_diskname_from_path (dp, device_name))
++	return 0;
++      return grub_strdup (device_name);
+     }
+-
+-  return 0;
+ }
+Index: b/grub-core/kern/efi/efi.c
+===================================================================
+--- a/grub-core/kern/efi/efi.c
++++ b/grub-core/kern/efi/efi.c
+@@ -740,3 +740,51 @@
+       dp = (grub_efi_device_path_t *) ((char *) dp + len);
+     }
+ }
++
++/* Compare device paths.  */
++int
++grub_efi_compare_device_paths (const grub_efi_device_path_t *dp1,
++			       const grub_efi_device_path_t *dp2)
++{
++  if (! dp1 || ! dp2)
++    /* Return non-zero.  */
++    return 1;
++
++  while (1)
++    {
++      grub_efi_uint8_t type1, type2;
++      grub_efi_uint8_t subtype1, subtype2;
++      grub_efi_uint16_t len1, len2;
++      int ret;
++
++      type1 = GRUB_EFI_DEVICE_PATH_TYPE (dp1);
++      type2 = GRUB_EFI_DEVICE_PATH_TYPE (dp2);
++
++      if (type1 != type2)
++	return (int) type2 - (int) type1;
++
++      subtype1 = GRUB_EFI_DEVICE_PATH_SUBTYPE (dp1);
++      subtype2 = GRUB_EFI_DEVICE_PATH_SUBTYPE (dp2);
++
++      if (subtype1 != subtype2)
++	return (int) subtype1 - (int) subtype2;
++
++      len1 = GRUB_EFI_DEVICE_PATH_LENGTH (dp1);
++      len2 = GRUB_EFI_DEVICE_PATH_LENGTH (dp2);
++
++      if (len1 != len2)
++	return (int) len1 - (int) len2;
++
++      ret = grub_memcmp (dp1, dp2, len1);
++      if (ret != 0)
++	return ret;
++
++      if (GRUB_EFI_END_ENTIRE_DEVICE_PATH (dp1))
++	break;
++
++      dp1 = (grub_efi_device_path_t *) ((char *) dp1 + len1);
++      dp2 = (grub_efi_device_path_t *) ((char *) dp2 + len2);
++    }
++
++  return 0;
++}
+Index: b/include/grub/efi/efi.h
+===================================================================
+--- a/include/grub/efi/efi.h
++++ b/include/grub/efi/efi.h
+@@ -62,6 +62,10 @@
+ 							   grub_efi_uint32_t descriptor_version,
+ 							   grub_efi_memory_descriptor_t *virtual_map);
+ 
++int
++EXPORT_FUNC (grub_efi_compare_device_paths) (const grub_efi_device_path_t *dp1,
++					     const grub_efi_device_path_t *dp2);
++
+ void grub_efi_mm_init (void);
+ void grub_efi_mm_fini (void);
+ void grub_efi_init (void);
