return read;
 }
 
+/*
+ * Architectures may override this function to allocate ELF header in 2nd kernel
+ */
+int __weak elfcorehdr_alloc(unsigned long long *addr, unsigned long long *size)
+{
+       return 0;
+}
+
+/*
+ * Architectures may override this function to free header
+ */
+void __weak elfcorehdr_free(unsigned long long addr)
+{}
+
+/*
+ * Architectures may override this function to read from ELF header
+ */
+ssize_t __weak elfcorehdr_read(char *buf, size_t count, u64 *ppos)
+{
+       return read_from_oldmem(buf, count, ppos, 0);
+}
+
+/*
+ * Architectures may override this function to read from notes sections
+ */
+ssize_t __weak elfcorehdr_read_notes(char *buf, size_t count, u64 *ppos)
+{
+       return read_from_oldmem(buf, count, ppos, 0);
+}
+
 /* Read from the ELF header and then the crash dump. On error, negative value is
  * returned otherwise number of bytes read are returned.
  */
                notes_section = kmalloc(max_sz, GFP_KERNEL);
                if (!notes_section)
                        return -ENOMEM;
-               rc = read_from_oldmem(notes_section, max_sz, &offset, 0);
+               rc = elfcorehdr_read_notes(notes_section, max_sz, &offset);
                if (rc < 0) {
                        kfree(notes_section);
                        return rc;
                if (phdr_ptr->p_type != PT_NOTE)
                        continue;
                offset = phdr_ptr->p_offset;
-               rc = read_from_oldmem(notes_buf, phdr_ptr->p_memsz, &offset, 0);
+               rc = elfcorehdr_read_notes(notes_buf, phdr_ptr->p_memsz,
+                                          &offset);
                if (rc < 0)
                        return rc;
                notes_buf += phdr_ptr->p_memsz;
                notes_section = kmalloc(max_sz, GFP_KERNEL);
                if (!notes_section)
                        return -ENOMEM;
-               rc = read_from_oldmem(notes_section, max_sz, &offset, 0);
+               rc = elfcorehdr_read_notes(notes_section, max_sz, &offset);
                if (rc < 0) {
                        kfree(notes_section);
                        return rc;
                if (phdr_ptr->p_type != PT_NOTE)
                        continue;
                offset = phdr_ptr->p_offset;
-               rc = read_from_oldmem(notes_buf, phdr_ptr->p_memsz, &offset, 0);
+               rc = elfcorehdr_read_notes(notes_buf, phdr_ptr->p_memsz,
+                                          &offset);
                if (rc < 0)
                        return rc;
                notes_buf += phdr_ptr->p_memsz;
        addr = elfcorehdr_addr;
 
        /* Read Elf header */
-       rc = read_from_oldmem((char*)&ehdr, sizeof(Elf64_Ehdr), &addr, 0);
+       rc = elfcorehdr_read((char *)&ehdr, sizeof(Elf64_Ehdr), &addr);
        if (rc < 0)
                return rc;
 
        if (!elfcorebuf)
                return -ENOMEM;
        addr = elfcorehdr_addr;
-       rc = read_from_oldmem(elfcorebuf, elfcorebuf_sz_orig, &addr, 0);
+       rc = elfcorehdr_read(elfcorebuf, elfcorebuf_sz_orig, &addr);
        if (rc < 0)
                goto fail;
 
        addr = elfcorehdr_addr;
 
        /* Read Elf header */
-       rc = read_from_oldmem((char*)&ehdr, sizeof(Elf32_Ehdr), &addr, 0);
+       rc = elfcorehdr_read((char *)&ehdr, sizeof(Elf32_Ehdr), &addr);
        if (rc < 0)
                return rc;
 
        if (!elfcorebuf)
                return -ENOMEM;
        addr = elfcorehdr_addr;
-       rc = read_from_oldmem(elfcorebuf, elfcorebuf_sz_orig, &addr, 0);
+       rc = elfcorehdr_read(elfcorebuf, elfcorebuf_sz_orig, &addr);
        if (rc < 0)
                goto fail;
 
        int rc=0;
 
        addr = elfcorehdr_addr;
-       rc = read_from_oldmem(e_ident, EI_NIDENT, &addr, 0);
+       rc = elfcorehdr_read(e_ident, EI_NIDENT, &addr);
        if (rc < 0)
                return rc;
        if (memcmp(e_ident, ELFMAG, SELFMAG) != 0) {
 {
        int rc = 0;
 
-       /* If elfcorehdr= has been passed in cmdline, then capture the dump.*/
+       /* Allow architectures to allocate ELF header in 2nd kernel */
+       rc = elfcorehdr_alloc(&elfcorehdr_addr, &elfcorehdr_size);
+       if (rc)
+               return rc;
+       /*
+        * If elfcorehdr= has been passed in cmdline or created in 2nd kernel,
+        * then capture the dump.
+        */
        if (!(is_vmcore_usable()))
                return rc;
        rc = parse_crash_elf_headers();
                pr_warn("Kdump: vmcore not initialized\n");
                return rc;
        }
+       elfcorehdr_free(elfcorehdr_addr);
+       elfcorehdr_addr = ELFCORE_ADDR_ERR;
 
        proc_vmcore = proc_create("vmcore", S_IRUSR, NULL, &proc_vmcore_operations);
        if (proc_vmcore)