diff options
author | Magnus Damm <magnus@valinux.co.jp> | 2006-12-06 23:40:41 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.osdl.org> | 2006-12-07 11:39:46 -0500 |
commit | 85916f8166b59eeac63d2b4f7f1df8de849334b4 (patch) | |
tree | 176176a0a75cfe42043c463a4391dd9f7975a69c /kernel | |
parent | 6d4df677f8a60ea6bc0ef1a596c1a3a79b1d4882 (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')
-rw-r--r-- | kernel/kexec.c | 56 |
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 | ||
1071 | static 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, ¬e, 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 | |||
1089 | static 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, ¬e, sizeof(note)); | ||
1097 | } | ||
1098 | |||
1099 | void 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 | |||
1069 | static int __init crash_notes_memory_init(void) | 1125 | static int __init crash_notes_memory_init(void) |
1070 | { | 1126 | { |
1071 | /* Allocate memory for saving cpu registers. */ | 1127 | /* Allocate memory for saving cpu registers. */ |