summaryrefslogtreecommitdiff
path: root/arch/s390/kernel/crash_dump.c
diff options
context:
space:
mode:
authorMichael Holzheu <holzheu@linux.vnet.ibm.com>2012-03-11 11:59:34 -0400
committerMartin Schwidefsky <schwidefsky@de.ibm.com>2012-03-11 11:59:29 -0400
commit4857d4bbe9821c8d732cb84455e18e12b3d79add (patch)
tree54583e3ef5c84c04f92b7b15ea6aad8224781d9b /arch/s390/kernel/crash_dump.c
parentad252ffa2a0fbb1f37e81688322034b3af037cee (diff)
[S390] kernel: Add OS info memory interface
In order to allow kdump based stand-alone dump, some information has to be passed from the old kernel to the new dump kernel. This is done via a the struct "os_info" that contains the following fields: * crashkernel base and size * reipl block * vmcoreinfo * init function A pointer to os_info is stored at a well known storage location and the whole structure as well as all fields are secured with checksums. Signed-off-by: Michael Holzheu <holzheu@linux.vnet.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'arch/s390/kernel/crash_dump.c')
-rw-r--r--arch/s390/kernel/crash_dump.c37
1 files changed, 27 insertions, 10 deletions
diff --git a/arch/s390/kernel/crash_dump.c b/arch/s390/kernel/crash_dump.c
index c383ce440d99..cc1172b26873 100644
--- a/arch/s390/kernel/crash_dump.c
+++ b/arch/s390/kernel/crash_dump.c
@@ -14,6 +14,7 @@
#include <linux/bootmem.h>
#include <linux/elf.h>
#include <asm/ipl.h>
+#include <asm/os_info.h>
#define PTR_ADD(x, y) (((char *) (x)) + ((unsigned long) (y)))
#define PTR_SUB(x, y) (((char *) (x)) - ((unsigned long) (y)))
@@ -51,7 +52,7 @@ ssize_t copy_oldmem_page(unsigned long pfn, char *buf,
/*
* Copy memory from old kernel
*/
-static int copy_from_oldmem(void *dest, void *src, size_t count)
+int copy_from_oldmem(void *dest, void *src, size_t count)
{
unsigned long copied = 0;
int rc;
@@ -224,28 +225,44 @@ static void *nt_prpsinfo(void *ptr)
}
/*
- * Initialize vmcoreinfo note (new kernel)
+ * Get vmcoreinfo using lowcore->vmcore_info (new kernel)
*/
-static void *nt_vmcoreinfo(void *ptr)
+static void *get_vmcoreinfo_old(unsigned long *size)
{
char nt_name[11], *vmcoreinfo;
Elf64_Nhdr note;
void *addr;
if (copy_from_oldmem(&addr, &S390_lowcore.vmcore_info, sizeof(addr)))
- return ptr;
+ return NULL;
memset(nt_name, 0, sizeof(nt_name));
if (copy_from_oldmem(&note, addr, sizeof(note)))
- return ptr;
+ return NULL;
if (copy_from_oldmem(nt_name, addr + sizeof(note), sizeof(nt_name) - 1))
- return ptr;
+ return NULL;
if (strcmp(nt_name, "VMCOREINFO") != 0)
- return ptr;
- vmcoreinfo = kzalloc_panic(note.n_descsz + 1);
+ return NULL;
+ vmcoreinfo = kzalloc_panic(note.n_descsz);
if (copy_from_oldmem(vmcoreinfo, addr + 24, note.n_descsz))
+ return NULL;
+ *size = note.n_descsz;
+ return vmcoreinfo;
+}
+
+/*
+ * Initialize vmcoreinfo note (new kernel)
+ */
+static void *nt_vmcoreinfo(void *ptr)
+{
+ unsigned long size;
+ void *vmcoreinfo;
+
+ vmcoreinfo = os_info_old_entry(OS_INFO_VMCOREINFO, &size);
+ if (!vmcoreinfo)
+ vmcoreinfo = get_vmcoreinfo_old(&size);
+ if (!vmcoreinfo)
return ptr;
- vmcoreinfo[note.n_descsz + 1] = 0;
- return nt_init(ptr, 0, vmcoreinfo, note.n_descsz, "VMCOREINFO");
+ return nt_init(ptr, 0, vmcoreinfo, size, "VMCOREINFO");
}
/*