aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSimon Horman <horms@verge.net.au>2007-05-08 03:28:22 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-05-08 14:15:07 -0400
commit6672f76a5a1878d42264c1deba8f1ab52b4618d9 (patch)
tree77396eefed3548183c1f0c3d1dc38f034d8fc429
parent73285082745045bcd64333c1fbaa88f8490f2626 (diff)
kdump/kexec: calculate note size at compile time
Currently the size of the per-cpu region reserved to save crash notes is set by the per-architecture value MAX_NOTE_BYTES. Which in turn is currently set to 1024 on all supported architectures. While testing ia64 I recently discovered that this value is in fact too small. The particular setup I was using actually needs 1172 bytes. This lead to very tedious failure mode where the tail of one elf note would overwrite the head of another if they ended up being alocated sequentially by kmalloc, which was often the case. It seems to me that a far better approach is to caclculate the size that the area needs to be. This patch does just that. If a simpler stop-gap patch for ia64 to be squeezed into 2.6.21(.X) is needed then this should be as easy as making MAX_NOTE_BYTES larger in arch/asm-ia64/kexec.h. Perhaps 2048 would be a good choice. However, I think that the approach in this patch is a much more robust idea. Acked-by: Vivek Goyal <vgoyal@in.ibm.com> Signed-off-by: Simon Horman <horms@verge.net.au> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--arch/ia64/kernel/crash.c2
-rw-r--r--include/asm-arm/kexec.h2
-rw-r--r--include/asm-i386/kexec.h2
-rw-r--r--include/asm-ia64/kexec.h2
-rw-r--r--include/asm-mips/kexec.h2
-rw-r--r--include/asm-powerpc/kexec.h2
-rw-r--r--include/asm-s390/kexec.h2
-rw-r--r--include/asm-sh/kexec.h2
-rw-r--r--include/asm-x86_64/kexec.h2
-rw-r--r--include/linux/kexec.h17
-rw-r--r--kernel/kexec.c4
11 files changed, 19 insertions, 20 deletions
diff --git a/arch/ia64/kernel/crash.c b/arch/ia64/kernel/crash.c
index 3d51a3f77017..aeb79fb28f0b 100644
--- a/arch/ia64/kernel/crash.c
+++ b/arch/ia64/kernel/crash.c
@@ -74,7 +74,7 @@ crash_save_this_cpu(void)
74 buf = (u64 *) per_cpu_ptr(crash_notes, cpu); 74 buf = (u64 *) per_cpu_ptr(crash_notes, cpu);
75 if (!buf) 75 if (!buf)
76 return; 76 return;
77 buf = append_elf_note(buf, "CORE", NT_PRSTATUS, prstatus, 77 buf = append_elf_note(buf, KEXEC_CORE_NOTE_NAME, NT_PRSTATUS, prstatus,
78 sizeof(*prstatus)); 78 sizeof(*prstatus));
79 final_note(buf); 79 final_note(buf);
80} 80}
diff --git a/include/asm-arm/kexec.h b/include/asm-arm/kexec.h
index 8c1c6162a80c..b5b030ef633d 100644
--- a/include/asm-arm/kexec.h
+++ b/include/asm-arm/kexec.h
@@ -16,8 +16,6 @@
16 16
17#ifndef __ASSEMBLY__ 17#ifndef __ASSEMBLY__
18 18
19#define MAX_NOTE_BYTES 1024
20
21struct kimage; 19struct kimage;
22/* Provide a dummy definition to avoid build failures. */ 20/* Provide a dummy definition to avoid build failures. */
23static inline void crash_setup_regs(struct pt_regs *newregs, 21static inline void crash_setup_regs(struct pt_regs *newregs,
diff --git a/include/asm-i386/kexec.h b/include/asm-i386/kexec.h
index bcb5b21de2d2..4b9dc9e6b701 100644
--- a/include/asm-i386/kexec.h
+++ b/include/asm-i386/kexec.h
@@ -45,8 +45,6 @@
45/* We can also handle crash dumps from 64 bit kernel. */ 45/* We can also handle crash dumps from 64 bit kernel. */
46#define vmcore_elf_check_arch_cross(x) ((x)->e_machine == EM_X86_64) 46#define vmcore_elf_check_arch_cross(x) ((x)->e_machine == EM_X86_64)
47 47
48#define MAX_NOTE_BYTES 1024
49
50/* CPU does not save ss and esp on stack if execution is already 48/* CPU does not save ss and esp on stack if execution is already
51 * running in kernel mode at the time of NMI occurrence. This code 49 * running in kernel mode at the time of NMI occurrence. This code
52 * fixes it. 50 * fixes it.
diff --git a/include/asm-ia64/kexec.h b/include/asm-ia64/kexec.h
index 41299ddfee30..541be835fc5a 100644
--- a/include/asm-ia64/kexec.h
+++ b/include/asm-ia64/kexec.h
@@ -14,8 +14,6 @@
14/* The native architecture */ 14/* The native architecture */
15#define KEXEC_ARCH KEXEC_ARCH_IA_64 15#define KEXEC_ARCH KEXEC_ARCH_IA_64
16 16
17#define MAX_NOTE_BYTES 1024
18
19#define kexec_flush_icache_page(page) do { \ 17#define kexec_flush_icache_page(page) do { \
20 unsigned long page_addr = (unsigned long)page_address(page); \ 18 unsigned long page_addr = (unsigned long)page_address(page); \
21 flush_icache_range(page_addr, page_addr + PAGE_SIZE); \ 19 flush_icache_range(page_addr, page_addr + PAGE_SIZE); \
diff --git a/include/asm-mips/kexec.h b/include/asm-mips/kexec.h
index b25267ebcb09..cdbab43b7d3a 100644
--- a/include/asm-mips/kexec.h
+++ b/include/asm-mips/kexec.h
@@ -21,8 +21,6 @@
21/* The native architecture */ 21/* The native architecture */
22#define KEXEC_ARCH KEXEC_ARCH_MIPS 22#define KEXEC_ARCH KEXEC_ARCH_MIPS
23 23
24#define MAX_NOTE_BYTES 1024
25
26static inline void crash_setup_regs(struct pt_regs *newregs, 24static inline void crash_setup_regs(struct pt_regs *newregs,
27 struct pt_regs *oldregs) 25 struct pt_regs *oldregs)
28{ 26{
diff --git a/include/asm-powerpc/kexec.h b/include/asm-powerpc/kexec.h
index 11cbdf81fd2e..b6f817b8ba3d 100644
--- a/include/asm-powerpc/kexec.h
+++ b/include/asm-powerpc/kexec.h
@@ -108,8 +108,6 @@ static inline void crash_setup_regs(struct pt_regs *newregs,
108 struct pt_regs *oldregs) { } 108 struct pt_regs *oldregs) { }
109#endif /* !__powerpc64 __ */ 109#endif /* !__powerpc64 __ */
110 110
111#define MAX_NOTE_BYTES 1024
112
113extern void kexec_smp_wait(void); /* get and clear naca physid, wait for 111extern void kexec_smp_wait(void); /* get and clear naca physid, wait for
114 master to copy new code to 0 */ 112 master to copy new code to 0 */
115extern int crashing_cpu; 113extern int crashing_cpu;
diff --git a/include/asm-s390/kexec.h b/include/asm-s390/kexec.h
index 9c35c8ad1afd..7592af708b41 100644
--- a/include/asm-s390/kexec.h
+++ b/include/asm-s390/kexec.h
@@ -34,8 +34,6 @@
34/* The native architecture */ 34/* The native architecture */
35#define KEXEC_ARCH KEXEC_ARCH_S390 35#define KEXEC_ARCH KEXEC_ARCH_S390
36 36
37#define MAX_NOTE_BYTES 1024
38
39/* Provide a dummy definition to avoid build failures. */ 37/* Provide a dummy definition to avoid build failures. */
40static inline void crash_setup_regs(struct pt_regs *newregs, 38static inline void crash_setup_regs(struct pt_regs *newregs,
41 struct pt_regs *oldregs) { } 39 struct pt_regs *oldregs) { }
diff --git a/include/asm-sh/kexec.h b/include/asm-sh/kexec.h
index da36a7548601..00f4260ef09b 100644
--- a/include/asm-sh/kexec.h
+++ b/include/asm-sh/kexec.h
@@ -26,8 +26,6 @@
26/* The native architecture */ 26/* The native architecture */
27#define KEXEC_ARCH KEXEC_ARCH_SH 27#define KEXEC_ARCH KEXEC_ARCH_SH
28 28
29#define MAX_NOTE_BYTES 1024
30
31static inline void crash_setup_regs(struct pt_regs *newregs, 29static inline void crash_setup_regs(struct pt_regs *newregs,
32 struct pt_regs *oldregs) 30 struct pt_regs *oldregs)
33{ 31{
diff --git a/include/asm-x86_64/kexec.h b/include/asm-x86_64/kexec.h
index 5fab957e1091..738e581b67f8 100644
--- a/include/asm-x86_64/kexec.h
+++ b/include/asm-x86_64/kexec.h
@@ -48,8 +48,6 @@
48/* The native architecture */ 48/* The native architecture */
49#define KEXEC_ARCH KEXEC_ARCH_X86_64 49#define KEXEC_ARCH KEXEC_ARCH_X86_64
50 50
51#define MAX_NOTE_BYTES 1024
52
53/* 51/*
54 * Saving the registers of the cpu on which panic occured in 52 * Saving the registers of the cpu on which panic occured in
55 * crash_kexec to save a valid sp. The registers of other cpus 53 * crash_kexec to save a valid sp. The registers of other cpus
diff --git a/include/linux/kexec.h b/include/linux/kexec.h
index 696e5ec63f77..8c2c7fcd58ce 100644
--- a/include/linux/kexec.h
+++ b/include/linux/kexec.h
@@ -7,6 +7,8 @@
7#include <linux/linkage.h> 7#include <linux/linkage.h>
8#include <linux/compat.h> 8#include <linux/compat.h>
9#include <linux/ioport.h> 9#include <linux/ioport.h>
10#include <linux/elfcore.h>
11#include <linux/elf.h>
10#include <asm/kexec.h> 12#include <asm/kexec.h>
11 13
12/* Verify architecture specific macros are defined */ 14/* Verify architecture specific macros are defined */
@@ -31,6 +33,19 @@
31#error KEXEC_ARCH not defined 33#error KEXEC_ARCH not defined
32#endif 34#endif
33 35
36#define KEXEC_NOTE_HEAD_BYTES ALIGN(sizeof(struct elf_note), 4)
37#define KEXEC_CORE_NOTE_NAME "CORE"
38#define KEXEC_CORE_NOTE_NAME_BYTES ALIGN(sizeof(KEXEC_CORE_NOTE_NAME), 4)
39#define KEXEC_CORE_NOTE_DESC_BYTES ALIGN(sizeof(struct elf_prstatus), 4)
40/*
41 * The per-cpu notes area is a list of notes terminated by a "NULL"
42 * note header. For kdump, the code in vmcore.c runs in the context
43 * of the second kernel to combine them into one note.
44 */
45#define KEXEC_NOTE_BYTES ( (KEXEC_NOTE_HEAD_BYTES * 2) + \
46 KEXEC_CORE_NOTE_NAME_BYTES + \
47 KEXEC_CORE_NOTE_DESC_BYTES )
48
34/* 49/*
35 * This structure is used to hold the arguments that are used when loading 50 * This structure is used to hold the arguments that are used when loading
36 * kernel binaries. 51 * kernel binaries.
@@ -136,7 +151,7 @@ extern struct kimage *kexec_crash_image;
136/* Location of a reserved region to hold the crash kernel. 151/* Location of a reserved region to hold the crash kernel.
137 */ 152 */
138extern struct resource crashk_res; 153extern struct resource crashk_res;
139typedef u32 note_buf_t[MAX_NOTE_BYTES/4]; 154typedef u32 note_buf_t[KEXEC_NOTE_BYTES/4];
140extern note_buf_t *crash_notes; 155extern note_buf_t *crash_notes;
141 156
142 157
diff --git a/kernel/kexec.c b/kernel/kexec.c
index 2a59c8a01ae0..25db14b89e82 100644
--- a/kernel/kexec.c
+++ b/kernel/kexec.c
@@ -1118,8 +1118,8 @@ void crash_save_cpu(struct pt_regs *regs, int cpu)
1118 memset(&prstatus, 0, sizeof(prstatus)); 1118 memset(&prstatus, 0, sizeof(prstatus));
1119 prstatus.pr_pid = current->pid; 1119 prstatus.pr_pid = current->pid;
1120 elf_core_copy_regs(&prstatus.pr_reg, regs); 1120 elf_core_copy_regs(&prstatus.pr_reg, regs);
1121 buf = append_elf_note(buf, "CORE", NT_PRSTATUS, &prstatus, 1121 buf = append_elf_note(buf, KEXEC_CORE_NOTE_NAME, NT_PRSTATUS,
1122 sizeof(prstatus)); 1122 &prstatus, sizeof(prstatus));
1123 final_note(buf); 1123 final_note(buf);
1124} 1124}
1125 1125