kdump/kexec: calculate note size at compile time
authorSimon Horman <horms@verge.net.au>
Tue, 8 May 2007 07:28:22 +0000 (00:28 -0700)
committerLinus Torvalds <torvalds@woody.linux-foundation.org>
Tue, 8 May 2007 18:15:07 +0000 (11:15 -0700)
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>
arch/ia64/kernel/crash.c
include/asm-arm/kexec.h
include/asm-i386/kexec.h
include/asm-ia64/kexec.h
include/asm-mips/kexec.h
include/asm-powerpc/kexec.h
include/asm-s390/kexec.h
include/asm-sh/kexec.h
include/asm-x86_64/kexec.h
include/linux/kexec.h
kernel/kexec.c

index 3d51a3f77017b0c345bc1dd44f928a6600aaf513..aeb79fb28f0bbd56672ea1c4b1e33bf7f58f33ec 100644 (file)
@@ -74,7 +74,7 @@ crash_save_this_cpu(void)
        buf = (u64 *) per_cpu_ptr(crash_notes, cpu);
        if (!buf)
                return;
-       buf = append_elf_note(buf, "CORE", NT_PRSTATUS, prstatus,
+       buf = append_elf_note(buf, KEXEC_CORE_NOTE_NAME, NT_PRSTATUS, prstatus,
                        sizeof(*prstatus));
        final_note(buf);
 }
index 8c1c6162a80c1595c7b314bd752390dc7b824bde..b5b030ef633d67d0fc254fcefea1d110687ab775 100644 (file)
@@ -16,8 +16,6 @@
 
 #ifndef __ASSEMBLY__
 
-#define MAX_NOTE_BYTES 1024
-
 struct kimage;
 /* Provide a dummy definition to avoid build failures. */
 static inline void crash_setup_regs(struct pt_regs *newregs,
index bcb5b21de2d2dc27107a2bf6d743f5fcd1b73384..4b9dc9e6b701de5987d3ffe4f1d2709af183695d 100644 (file)
@@ -45,8 +45,6 @@
 /* We can also handle crash dumps from 64 bit kernel. */
 #define vmcore_elf_check_arch_cross(x) ((x)->e_machine == EM_X86_64)
 
-#define MAX_NOTE_BYTES 1024
-
 /* CPU does not save ss and esp on stack if execution is already
  * running in kernel mode at the time of NMI occurrence. This code
  * fixes it.
index 41299ddfee30e0c742102420725e3645bd711999..541be835fc5a16f7ee6019fa6f2812f3e310a1cb 100644 (file)
@@ -14,8 +14,6 @@
 /* The native architecture */
 #define KEXEC_ARCH KEXEC_ARCH_IA_64
 
-#define MAX_NOTE_BYTES 1024
-
 #define kexec_flush_icache_page(page) do { \
                 unsigned long page_addr = (unsigned long)page_address(page); \
                 flush_icache_range(page_addr, page_addr + PAGE_SIZE); \
index b25267ebcb095c017f956ddcc9dda30025ea1e5b..cdbab43b7d3a6c3b98f0cfd330435148617c4f85 100644 (file)
@@ -21,8 +21,6 @@
 /* The native architecture */
 #define KEXEC_ARCH KEXEC_ARCH_MIPS
 
-#define MAX_NOTE_BYTES 1024
-
 static inline void crash_setup_regs(struct pt_regs *newregs,
                                    struct pt_regs *oldregs)
 {
index 11cbdf81fd2e8f5113f1359660ce1f16eb1add91..b6f817b8ba3d3528cb500ffeed16879bcc5fcb2c 100644 (file)
@@ -108,8 +108,6 @@ static inline void crash_setup_regs(struct pt_regs *newregs,
                                        struct pt_regs *oldregs) { }
 #endif /* !__powerpc64 __ */
 
-#define MAX_NOTE_BYTES 1024
-
 extern void kexec_smp_wait(void);      /* get and clear naca physid, wait for
                                          master to copy new code to 0 */
 extern int crashing_cpu;
index 9c35c8ad1afd63ab8b8519a9594cc813f62fa9fd..7592af708b4153975ac3cfc4cc8b1acef19c9c8d 100644 (file)
@@ -34,8 +34,6 @@
 /* The native architecture */
 #define KEXEC_ARCH KEXEC_ARCH_S390
 
-#define MAX_NOTE_BYTES 1024
-
 /* Provide a dummy definition to avoid build failures. */
 static inline void crash_setup_regs(struct pt_regs *newregs,
                                        struct pt_regs *oldregs) { }
index da36a7548601824f1ea4e3d6f5a55a95b046ece7..00f4260ef09b5cbeb0547d7b4daca53ccf407af1 100644 (file)
@@ -26,8 +26,6 @@
 /* The native architecture */
 #define KEXEC_ARCH KEXEC_ARCH_SH
 
-#define MAX_NOTE_BYTES 1024
-
 static inline void crash_setup_regs(struct pt_regs *newregs,
                                    struct pt_regs *oldregs)
 {
index 5fab957e10918425044a760578030632d478ac87..738e581b67f8f41e198bd87e49fdffcd1d1e4ae1 100644 (file)
@@ -48,8 +48,6 @@
 /* The native architecture */
 #define KEXEC_ARCH KEXEC_ARCH_X86_64
 
-#define MAX_NOTE_BYTES 1024
-
 /*
  * Saving the registers of the cpu on which panic occured in
  * crash_kexec to save a valid sp. The registers of other cpus
index 696e5ec63f77b83fdb81cf35299783633637736a..8c2c7fcd58ceab1937e8d20f4ac0da0c0940b404 100644 (file)
@@ -7,6 +7,8 @@
 #include <linux/linkage.h>
 #include <linux/compat.h>
 #include <linux/ioport.h>
+#include <linux/elfcore.h>
+#include <linux/elf.h>
 #include <asm/kexec.h>
 
 /* Verify architecture specific macros are defined */
 #error KEXEC_ARCH not defined
 #endif
 
+#define KEXEC_NOTE_HEAD_BYTES ALIGN(sizeof(struct elf_note), 4)
+#define KEXEC_CORE_NOTE_NAME "CORE"
+#define KEXEC_CORE_NOTE_NAME_BYTES ALIGN(sizeof(KEXEC_CORE_NOTE_NAME), 4)
+#define KEXEC_CORE_NOTE_DESC_BYTES ALIGN(sizeof(struct elf_prstatus), 4)
+/*
+ * The per-cpu notes area is a list of notes terminated by a "NULL"
+ * note header.  For kdump, the code in vmcore.c runs in the context
+ * of the second kernel to combine them into one note.
+ */
+#define KEXEC_NOTE_BYTES ( (KEXEC_NOTE_HEAD_BYTES * 2) +               \
+                           KEXEC_CORE_NOTE_NAME_BYTES +                \
+                           KEXEC_CORE_NOTE_DESC_BYTES )
+
 /*
  * This structure is used to hold the arguments that are used when loading
  * kernel binaries.
@@ -136,7 +151,7 @@ extern struct kimage *kexec_crash_image;
 /* Location of a reserved region to hold the crash kernel.
  */
 extern struct resource crashk_res;
-typedef u32 note_buf_t[MAX_NOTE_BYTES/4];
+typedef u32 note_buf_t[KEXEC_NOTE_BYTES/4];
 extern note_buf_t *crash_notes;
 
 
index 2a59c8a01ae0010da5ef5b80b39fad2ec1da14ae..25db14b89e82c529fcb217e311fbebf66c440c60 100644 (file)
@@ -1118,8 +1118,8 @@ void crash_save_cpu(struct pt_regs *regs, int cpu)
        memset(&prstatus, 0, sizeof(prstatus));
        prstatus.pr_pid = current->pid;
        elf_core_copy_regs(&prstatus.pr_reg, regs);
-       buf = append_elf_note(buf, "CORE", NT_PRSTATUS, &prstatus,
-                               sizeof(prstatus));
+       buf = append_elf_note(buf, KEXEC_CORE_NOTE_NAME, NT_PRSTATUS,
+                             &prstatus, sizeof(prstatus));
        final_note(buf);
 }