return ~0UL;
 }
 #endif
+
+#ifdef CONFIG_PROC_VMCORE
+/* locate the size find a the descriptor at a certain address */
+unsigned long
+vmcore_find_descriptor_size (unsigned long address)
+{
+       void *efi_map_start, *efi_map_end, *p;
+       efi_memory_desc_t *md;
+       u64 efi_desc_size;
+       unsigned long ret = 0;
+
+       efi_map_start = __va(ia64_boot_param->efi_memmap);
+       efi_map_end   = efi_map_start + ia64_boot_param->efi_memmap_size;
+       efi_desc_size = ia64_boot_param->efi_memdesc_size;
+
+       for (p = efi_map_start; p < efi_map_end; p += efi_desc_size) {
+               md = p;
+               if (efi_wb(md) && md->type == EFI_LOADER_DATA
+                   && md->phys_addr == address) {
+                       ret = efi_md_size(md);
+                       break;
+               }
+       }
+
+       if (ret == 0)
+               printk(KERN_WARNING "Cannot locate EFI vmcore descriptor\n");
+
+       return ret;
+}
+#endif
 
        }
 #endif
 
+#ifdef CONFIG_PROC_VMCORE
+       if (reserve_elfcorehdr(&rsvd_region[n].start,
+                              &rsvd_region[n].end) == 0)
+               n++;
+#endif
+
        efi_memmap_init(&rsvd_region[n].start, &rsvd_region[n].end);
        n++;
 
        return 0;
 }
 early_param("elfcorehdr", parse_elfcorehdr);
+
+int __init reserve_elfcorehdr(unsigned long *start, unsigned long *end)
+{
+       unsigned long length;
+
+       /* We get the address using the kernel command line,
+        * but the size is extracted from the EFI tables.
+        * Both address and size are required for reservation
+        * to work properly.
+        */
+
+       if (elfcorehdr_addr >= ELFCORE_ADDR_MAX)
+               return -EINVAL;
+
+       if ((length = vmcore_find_descriptor_size(elfcorehdr_addr)) == 0) {
+               elfcorehdr_addr = ELFCORE_ADDR_MAX;
+               return -EINVAL;
+       }
+
+       *start = (unsigned long)__va(elfcorehdr_addr);
+       *end = *start + length;
+       return 0;
+}
+
 #endif /* CONFIG_PROC_VMCORE */
 
 void __init
 
  *     - kernel code & data
  *     - crash dumping code reserved region
  *     - Kernel memory map built from EFI memory map
+ *     - ELF core header
  *
  * More could be added if necessary
  */
-#define IA64_MAX_RSVD_REGIONS 7
+#define IA64_MAX_RSVD_REGIONS 8
 
 struct rsvd_region {
        unsigned long start;    /* virtual address of beginning of element */
 extern int filter_rsvd_memory (unsigned long start, unsigned long end, void *arg);
 extern void efi_memmap_init(unsigned long *, unsigned long *);
 
+extern unsigned long vmcore_find_descriptor_size(unsigned long address);
+extern int reserve_elfcorehdr(unsigned long *start, unsigned long *end);
+
 /*
  * For rounding an address to the next IA64_GRANULE_SIZE or order
  */