aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/kexec.c
diff options
context:
space:
mode:
authorMagnus Damm <magnus@valinux.co.jp>2006-12-06 23:40:41 -0500
committerLinus Torvalds <torvalds@woody.osdl.org>2006-12-07 11:39:46 -0500
commit85916f8166b59eeac63d2b4f7f1df8de849334b4 (patch)
tree176176a0a75cfe42043c463a4391dd9f7975a69c /kernel/kexec.c
parent6d4df677f8a60ea6bc0ef1a596c1a3a79b1d4882 (diff)
[PATCH] Kexec / Kdump: Unify elf note code
The elf note saving code is currently duplicated over several architectures. This cleanup patch simply adds code to a common file and then replaces the arch-specific code with calls to the newly added code. The only drawback with this approach is that s390 doesn't fully support kexec-on-panic which for that arch leads to introduction of unused code. Signed-off-by: Magnus Damm <magnus@valinux.co.jp> Cc: Vivek Goyal <vgoyal@in.ibm.com> Cc: Andi Kleen <ak@suse.de> Cc: Paul Mackerras <paulus@samba.org> Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'kernel/kexec.c')
-rw-r--r--kernel/kexec.c56
1 files changed, 56 insertions, 0 deletions
diff --git a/kernel/kexec.c b/kernel/kexec.c
index d43692cf2321..afbbbe981be2 100644
--- a/kernel/kexec.c
+++ b/kernel/kexec.c
@@ -20,6 +20,8 @@
20#include <linux/syscalls.h> 20#include <linux/syscalls.h>
21#include <linux/ioport.h> 21#include <linux/ioport.h>
22#include <linux/hardirq.h> 22#include <linux/hardirq.h>
23#include <linux/elf.h>
24#include <linux/elfcore.h>
23 25
24#include <asm/page.h> 26#include <asm/page.h>
25#include <asm/uaccess.h> 27#include <asm/uaccess.h>
@@ -1066,6 +1068,60 @@ void crash_kexec(struct pt_regs *regs)
1066 } 1068 }
1067} 1069}
1068 1070
1071static u32 *append_elf_note(u32 *buf, char *name, unsigned type, void *data,
1072 size_t data_len)
1073{
1074 struct elf_note note;
1075
1076 note.n_namesz = strlen(name) + 1;
1077 note.n_descsz = data_len;
1078 note.n_type = type;
1079 memcpy(buf, &note, sizeof(note));
1080 buf += (sizeof(note) + 3)/4;
1081 memcpy(buf, name, note.n_namesz);
1082 buf += (note.n_namesz + 3)/4;
1083 memcpy(buf, data, note.n_descsz);
1084 buf += (note.n_descsz + 3)/4;
1085
1086 return buf;
1087}
1088
1089static void final_note(u32 *buf)
1090{
1091 struct elf_note note;
1092
1093 note.n_namesz = 0;
1094 note.n_descsz = 0;
1095 note.n_type = 0;
1096 memcpy(buf, &note, sizeof(note));
1097}
1098
1099void crash_save_cpu(struct pt_regs *regs, int cpu)
1100{
1101 struct elf_prstatus prstatus;
1102 u32 *buf;
1103
1104 if ((cpu < 0) || (cpu >= NR_CPUS))
1105 return;
1106
1107 /* Using ELF notes here is opportunistic.
1108 * I need a well defined structure format
1109 * for the data I pass, and I need tags
1110 * on the data to indicate what information I have
1111 * squirrelled away. ELF notes happen to provide
1112 * all of that, so there is no need to invent something new.
1113 */
1114 buf = (u32*)per_cpu_ptr(crash_notes, cpu);
1115 if (!buf)
1116 return;
1117 memset(&prstatus, 0, sizeof(prstatus));
1118 prstatus.pr_pid = current->pid;
1119 elf_core_copy_regs(&prstatus.pr_reg, regs);
1120 buf = append_elf_note(buf, "CORE", NT_PRSTATUS, &prstatus,
1121 sizeof(prstatus));
1122 final_note(buf);
1123}
1124
1069static int __init crash_notes_memory_init(void) 1125static int __init crash_notes_memory_init(void)
1070{ 1126{
1071 /* Allocate memory for saving cpu registers. */ 1127 /* Allocate memory for saving cpu registers. */