This patch now exchanges the old relocate mechanism with the new
arch function call override mechanism that allows to create the ELF
core header in the 2nd kernel.

Signed-off-by: Michael Holzheu <[email protected]>
---
 arch/s390/kernel/crash_dump.c | 64 ++++++++++++++++++++++++++++++-------------
 1 file changed, 45 insertions(+), 19 deletions(-)

diff --git a/arch/s390/kernel/crash_dump.c b/arch/s390/kernel/crash_dump.c
index f703d91..aeb1207 100644
--- a/arch/s390/kernel/crash_dump.c
+++ b/arch/s390/kernel/crash_dump.c
@@ -21,6 +21,9 @@
 #define PTR_SUB(x, y) (((char *) (x)) - ((unsigned long) (y)))
 #define PTR_DIFF(x, y) ((unsigned long)(((char *) (x)) - ((unsigned long) 
(y))))
 
+static size_t elfcorebuf_sz;
+static char *elfcorebuf;
+
 /*
  * Copy one page from "oldmem"
  *
@@ -325,14 +328,6 @@ static int get_mem_chunk_cnt(void)
 }
 
 /*
- * Relocate pointer in order to allow vmcore code access the data
- */
-static inline unsigned long relocate(unsigned long addr)
-{
-       return OLDMEM_BASE + addr;
-}
-
-/*
  * Initialize ELF loads (new kernel)
  */
 static int loads_init(Elf64_Phdr *phdr, u64 loads_offset)
@@ -383,7 +378,7 @@ static void *notes_init(Elf64_Phdr *phdr, void *ptr, u64 
notes_offset)
        ptr = nt_vmcoreinfo(ptr);
        memset(phdr, 0, sizeof(*phdr));
        phdr->p_type = PT_NOTE;
-       phdr->p_offset = relocate(notes_offset);
+       phdr->p_offset = notes_offset;
        phdr->p_filesz = (unsigned long) PTR_SUB(ptr, ptr_start);
        phdr->p_memsz = phdr->p_filesz;
        return ptr;
@@ -392,7 +387,7 @@ static void *notes_init(Elf64_Phdr *phdr, void *ptr, u64 
notes_offset)
 /*
  * Create ELF core header (new kernel)
  */
-static void s390_elf_corehdr_create(char **elfcorebuf, size_t *elfcorebuf_sz)
+static int s390_elf_corehdr_create(char **elfcorebuf, size_t *elfcorebuf_sz)
 {
        Elf64_Phdr *phdr_notes, *phdr_loads;
        int mem_chunk_cnt;
@@ -414,28 +409,59 @@ static void s390_elf_corehdr_create(char **elfcorebuf, 
size_t *elfcorebuf_sz)
        ptr = PTR_ADD(ptr, sizeof(Elf64_Phdr) * mem_chunk_cnt);
        /* Init notes */
        hdr_off = PTR_DIFF(ptr, hdr);
-       ptr = notes_init(phdr_notes, ptr, ((unsigned long) hdr) + hdr_off);
+       ptr = notes_init(phdr_notes, ptr, (unsigned long) hdr + hdr_off);
        /* Init loads */
        hdr_off = PTR_DIFF(ptr, hdr);
-       loads_init(phdr_loads, ((unsigned long) hdr) + hdr_off);
+       loads_init(phdr_loads, hdr_off);
        *elfcorebuf_sz = hdr_off;
-       *elfcorebuf = (void *) relocate((unsigned long) hdr);
+       *elfcorebuf = hdr;
        BUG_ON(*elfcorebuf_sz > alloc_size);
+       return 0;
 }
 
 /*
- * Create kdump ELF core header in new kernel, if it has not been passed via
- * the "elfcorehdr" kernel parameter
+ * Return address of ELF core header (new or old memory)
  */
-static int setup_kdump_elfcorehdr(void)
+unsigned long long arch_get_crash_header(void)
 {
-       size_t elfcorebuf_sz;
-       char *elfcorebuf;
+       if (elfcorebuf)
+               return elfcorehdr_addr;
+       else
+               return __pa(elfcorebuf);
+}
 
+/*
+ * Free crash header
+ */
+void arch_free_crash_header(void)
+{
+       kfree(elfcorebuf);
+       elfcorebuf = 0;
+}
+
+/*
+ * Read from crash header (new or old memory)
+ */
+ssize_t arch_read_from_crash_header(char *buf, size_t count, u64 *ppos)
+{
+       if (elfcorebuf)
+               memcpy(buf, (void *)*ppos, count);
+       else
+               copy_from_oldmem(buf, (void *)*ppos, count);
+       *ppos += count;
+       return count;
+}
+
+/*
+ * Create kdump ELF core header in new kernel if it has not been passed via
+ * the "elfcorehdr=" kernel parameter
+ */
+static int setup_kdump_elfcorehdr(void)
+{
        if (!OLDMEM_BASE || is_kdump_kernel())
                return -EINVAL;
        s390_elf_corehdr_create(&elfcorebuf, &elfcorebuf_sz);
-       elfcorehdr_addr = (unsigned long long) elfcorebuf;
+       elfcorehdr_addr = __pa(elfcorebuf);
        elfcorehdr_size = elfcorebuf_sz;
        return 0;
 }
-- 
1.8.1.6

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to