diff options
| author | Haren Myneni <haren@us.ibm.com> | 2006-01-13 22:15:36 -0500 |
|---|---|---|
| committer | Paul Mackerras <paulus@samba.org> | 2006-01-14 21:14:42 -0500 |
| commit | 8385a6a3acfbb4b68150c25cfe9084b6c4f501cf (patch) | |
| tree | 9985155527550b8025603515e4ba96d5c24e6072 | |
| parent | 9216ad8cb7849d88b6d8e9f097718de4f25d4121 (diff) | |
[PATCH] powerpc: Fix kdump copy regs and dynamic allocate per-cpu crash notes
- This contains the arch specific changes for the following the
kdump generic fixes which were already accepted in the upstream.
. Capturing CPU registers (for the case of 'panic' and invoking
the dump using 'sysrq-trigger') from a function (stack frame) which will
be not be available during the kdump boot. Hence, might result in
invalid stack trace.
. Dynamically allocating per cpu ELF notes section instead of
statically for NR_CPUS.
- Fix the compiler warning in prom_init.c.
Signed-off-by: Haren Myneni <haren@us.ibm.com>
Signed-off-by: Paul Mackerras <paulus@samba.org>
| -rw-r--r-- | arch/powerpc/kernel/crash.c | 77 | ||||
| -rw-r--r-- | arch/powerpc/kernel/prom_init.c | 3 | ||||
| -rw-r--r-- | include/asm-powerpc/kexec.h | 85 |
3 files changed, 80 insertions, 85 deletions
diff --git a/arch/powerpc/kernel/crash.c b/arch/powerpc/kernel/crash.c index 5f248e3fdf82..8c21d378f5d2 100644 --- a/arch/powerpc/kernel/crash.c +++ b/arch/powerpc/kernel/crash.c | |||
| @@ -84,7 +84,10 @@ static void crash_save_this_cpu(struct pt_regs *regs, int cpu) | |||
| 84 | * squirrelled away. ELF notes happen to provide | 84 | * squirrelled away. ELF notes happen to provide |
| 85 | * all of that that no need to invent something new. | 85 | * all of that that no need to invent something new. |
| 86 | */ | 86 | */ |
| 87 | buf = &crash_notes[cpu][0]; | 87 | buf = (u32*)per_cpu_ptr(crash_notes, cpu); |
| 88 | if (!buf) | ||
| 89 | return; | ||
| 90 | |||
| 88 | memset(&prstatus, 0, sizeof(prstatus)); | 91 | memset(&prstatus, 0, sizeof(prstatus)); |
| 89 | prstatus.pr_pid = current->pid; | 92 | prstatus.pr_pid = current->pid; |
| 90 | elf_core_copy_regs(&prstatus.pr_reg, regs); | 93 | elf_core_copy_regs(&prstatus.pr_reg, regs); |
| @@ -93,76 +96,6 @@ static void crash_save_this_cpu(struct pt_regs *regs, int cpu) | |||
| 93 | final_note(buf); | 96 | final_note(buf); |
| 94 | } | 97 | } |
| 95 | 98 | ||
| 96 | /* FIXME Merge this with xmon_save_regs ?? */ | ||
| 97 | static inline void crash_get_current_regs(struct pt_regs *regs) | ||
| 98 | { | ||
| 99 | unsigned long tmp1, tmp2; | ||
| 100 | |||
| 101 | __asm__ __volatile__ ( | ||
| 102 | "std 0,0(%2)\n" | ||
| 103 | "std 1,8(%2)\n" | ||
| 104 | "std 2,16(%2)\n" | ||
| 105 | "std 3,24(%2)\n" | ||
| 106 | "std 4,32(%2)\n" | ||
| 107 | "std 5,40(%2)\n" | ||
| 108 | "std 6,48(%2)\n" | ||
| 109 | "std 7,56(%2)\n" | ||
| 110 | "std 8,64(%2)\n" | ||
| 111 | "std 9,72(%2)\n" | ||
| 112 | "std 10,80(%2)\n" | ||
| 113 | "std 11,88(%2)\n" | ||
| 114 | "std 12,96(%2)\n" | ||
| 115 | "std 13,104(%2)\n" | ||
| 116 | "std 14,112(%2)\n" | ||
| 117 | "std 15,120(%2)\n" | ||
| 118 | "std 16,128(%2)\n" | ||
| 119 | "std 17,136(%2)\n" | ||
| 120 | "std 18,144(%2)\n" | ||
| 121 | "std 19,152(%2)\n" | ||
| 122 | "std 20,160(%2)\n" | ||
| 123 | "std 21,168(%2)\n" | ||
| 124 | "std 22,176(%2)\n" | ||
| 125 | "std 23,184(%2)\n" | ||
| 126 | "std 24,192(%2)\n" | ||
| 127 | "std 25,200(%2)\n" | ||
| 128 | "std 26,208(%2)\n" | ||
| 129 | "std 27,216(%2)\n" | ||
| 130 | "std 28,224(%2)\n" | ||
| 131 | "std 29,232(%2)\n" | ||
| 132 | "std 30,240(%2)\n" | ||
| 133 | "std 31,248(%2)\n" | ||
| 134 | "mfmsr %0\n" | ||
| 135 | "std %0, 264(%2)\n" | ||
| 136 | "mfctr %0\n" | ||
| 137 | "std %0, 280(%2)\n" | ||
| 138 | "mflr %0\n" | ||
| 139 | "std %0, 288(%2)\n" | ||
| 140 | "bl 1f\n" | ||
| 141 | "1: mflr %1\n" | ||
| 142 | "std %1, 256(%2)\n" | ||
| 143 | "mtlr %0\n" | ||
| 144 | "mfxer %0\n" | ||
| 145 | "std %0, 296(%2)\n" | ||
| 146 | : "=&r" (tmp1), "=&r" (tmp2) | ||
| 147 | : "b" (regs)); | ||
| 148 | } | ||
| 149 | |||
| 150 | /* We may have saved_regs from where the error came from | ||
| 151 | * or it is NULL if via a direct panic(). | ||
| 152 | */ | ||
| 153 | static void crash_save_self(struct pt_regs *saved_regs) | ||
| 154 | { | ||
| 155 | struct pt_regs regs; | ||
| 156 | int cpu; | ||
| 157 | |||
| 158 | cpu = smp_processor_id(); | ||
| 159 | if (saved_regs) | ||
| 160 | memcpy(®s, saved_regs, sizeof(regs)); | ||
| 161 | else | ||
| 162 | crash_get_current_regs(®s); | ||
| 163 | crash_save_this_cpu(®s, cpu); | ||
| 164 | } | ||
| 165 | |||
| 166 | #ifdef CONFIG_SMP | 99 | #ifdef CONFIG_SMP |
| 167 | static atomic_t waiting_for_crash_ipi; | 100 | static atomic_t waiting_for_crash_ipi; |
| 168 | 101 | ||
| @@ -260,5 +193,5 @@ void default_machine_crash_shutdown(struct pt_regs *regs) | |||
| 260 | */ | 193 | */ |
| 261 | crashing_cpu = smp_processor_id(); | 194 | crashing_cpu = smp_processor_id(); |
| 262 | crash_kexec_prepare_cpus(); | 195 | crash_kexec_prepare_cpus(); |
| 263 | crash_save_self(regs); | 196 | crash_save_this_cpu(regs, crashing_cpu); |
| 264 | } | 197 | } |
diff --git a/arch/powerpc/kernel/prom_init.c b/arch/powerpc/kernel/prom_init.c index d963a12ec640..7881ec96ef11 100644 --- a/arch/powerpc/kernel/prom_init.c +++ b/arch/powerpc/kernel/prom_init.c | |||
| @@ -605,7 +605,8 @@ static void __init early_cmdline_parse(void) | |||
| 605 | opt = strstr(RELOC(prom_cmd_line), RELOC("crashkernel=")); | 605 | opt = strstr(RELOC(prom_cmd_line), RELOC("crashkernel=")); |
| 606 | if (opt) { | 606 | if (opt) { |
| 607 | opt += 12; | 607 | opt += 12; |
| 608 | RELOC(prom_crashk_size) = prom_memparse(opt, &opt); | 608 | RELOC(prom_crashk_size) = |
| 609 | prom_memparse(opt, (const char **)&opt); | ||
| 609 | 610 | ||
| 610 | if (ALIGN(RELOC(prom_crashk_size), 0x1000000) != | 611 | if (ALIGN(RELOC(prom_crashk_size), 0x1000000) != |
| 611 | RELOC(prom_crashk_size)) { | 612 | RELOC(prom_crashk_size)) { |
diff --git a/include/asm-powerpc/kexec.h b/include/asm-powerpc/kexec.h index fffdf690b840..640a6459f2f4 100644 --- a/include/asm-powerpc/kexec.h +++ b/include/asm-powerpc/kexec.h | |||
| @@ -31,12 +31,80 @@ | |||
| 31 | #define KEXEC_ARCH KEXEC_ARCH_PPC | 31 | #define KEXEC_ARCH KEXEC_ARCH_PPC |
| 32 | #endif | 32 | #endif |
| 33 | 33 | ||
| 34 | #define HAVE_ARCH_COPY_OLDMEM_PAGE | ||
| 35 | |||
| 36 | #ifndef __ASSEMBLY__ | ||
| 37 | |||
| 38 | #ifdef CONFIG_KEXEC | 34 | #ifdef CONFIG_KEXEC |
| 39 | 35 | ||
| 36 | #ifdef __powerpc64__ | ||
| 37 | /* | ||
| 38 | * This function is responsible for capturing register states if coming | ||
| 39 | * via panic or invoking dump using sysrq-trigger. | ||
| 40 | */ | ||
| 41 | static inline void crash_setup_regs(struct pt_regs *newregs, | ||
| 42 | struct pt_regs *oldregs) | ||
| 43 | { | ||
| 44 | if (oldregs) | ||
| 45 | memcpy(newregs, oldregs, sizeof(*newregs)); | ||
| 46 | else { | ||
| 47 | /* FIXME Merge this with xmon_save_regs ?? */ | ||
| 48 | unsigned long tmp1, tmp2; | ||
| 49 | __asm__ __volatile__ ( | ||
| 50 | "std 0,0(%2)\n" | ||
| 51 | "std 1,8(%2)\n" | ||
| 52 | "std 2,16(%2)\n" | ||
| 53 | "std 3,24(%2)\n" | ||
| 54 | "std 4,32(%2)\n" | ||
| 55 | "std 5,40(%2)\n" | ||
| 56 | "std 6,48(%2)\n" | ||
| 57 | "std 7,56(%2)\n" | ||
| 58 | "std 8,64(%2)\n" | ||
| 59 | "std 9,72(%2)\n" | ||
| 60 | "std 10,80(%2)\n" | ||
| 61 | "std 11,88(%2)\n" | ||
| 62 | "std 12,96(%2)\n" | ||
| 63 | "std 13,104(%2)\n" | ||
| 64 | "std 14,112(%2)\n" | ||
| 65 | "std 15,120(%2)\n" | ||
| 66 | "std 16,128(%2)\n" | ||
| 67 | "std 17,136(%2)\n" | ||
| 68 | "std 18,144(%2)\n" | ||
| 69 | "std 19,152(%2)\n" | ||
| 70 | "std 20,160(%2)\n" | ||
| 71 | "std 21,168(%2)\n" | ||
| 72 | "std 22,176(%2)\n" | ||
| 73 | "std 23,184(%2)\n" | ||
| 74 | "std 24,192(%2)\n" | ||
| 75 | "std 25,200(%2)\n" | ||
| 76 | "std 26,208(%2)\n" | ||
| 77 | "std 27,216(%2)\n" | ||
| 78 | "std 28,224(%2)\n" | ||
| 79 | "std 29,232(%2)\n" | ||
| 80 | "std 30,240(%2)\n" | ||
| 81 | "std 31,248(%2)\n" | ||
| 82 | "mfmsr %0\n" | ||
| 83 | "std %0, 264(%2)\n" | ||
| 84 | "mfctr %0\n" | ||
| 85 | "std %0, 280(%2)\n" | ||
| 86 | "mflr %0\n" | ||
| 87 | "std %0, 288(%2)\n" | ||
| 88 | "bl 1f\n" | ||
| 89 | "1: mflr %1\n" | ||
| 90 | "std %1, 256(%2)\n" | ||
| 91 | "mtlr %0\n" | ||
| 92 | "mfxer %0\n" | ||
| 93 | "std %0, 296(%2)\n" | ||
| 94 | : "=&r" (tmp1), "=&r" (tmp2) | ||
| 95 | : "b" (newregs)); | ||
| 96 | } | ||
| 97 | } | ||
| 98 | #else | ||
| 99 | /* | ||
| 100 | * Provide a dummy definition to avoid build failures. Will remain | ||
| 101 | * empty till crash dump support is enabled. | ||
| 102 | */ | ||
| 103 | static inline void crash_setup_regs(struct pt_regs *newregs, | ||
| 104 | struct pt_regs *oldregs) { } | ||
| 105 | #endif /* !__powerpc64 __ */ | ||
| 106 | |||
| 107 | #ifndef __ASSEMBLY__ | ||
| 40 | #define MAX_NOTE_BYTES 1024 | 108 | #define MAX_NOTE_BYTES 1024 |
| 41 | 109 | ||
| 42 | #ifdef __powerpc64__ | 110 | #ifdef __powerpc64__ |
| @@ -53,14 +121,7 @@ extern void default_machine_kexec(struct kimage *image); | |||
| 53 | extern int default_machine_kexec_prepare(struct kimage *image); | 121 | extern int default_machine_kexec_prepare(struct kimage *image); |
| 54 | extern void default_machine_crash_shutdown(struct pt_regs *regs); | 122 | extern void default_machine_crash_shutdown(struct pt_regs *regs); |
| 55 | 123 | ||
| 56 | #endif /* !CONFIG_KEXEC */ | ||
| 57 | |||
| 58 | /* | ||
| 59 | * Provide a dummy definition to avoid build failures. Will remain | ||
| 60 | * empty till crash dump support is enabled. | ||
| 61 | */ | ||
| 62 | static inline void crash_setup_regs(struct pt_regs *newregs, | ||
| 63 | struct pt_regs *oldregs) { } | ||
| 64 | #endif /* ! __ASSEMBLY__ */ | 124 | #endif /* ! __ASSEMBLY__ */ |
| 125 | #endif /* CONFIG_KEXEC */ | ||
| 65 | #endif /* __KERNEL__ */ | 126 | #endif /* __KERNEL__ */ |
| 66 | #endif /* _ASM_POWERPC_KEXEC_H */ | 127 | #endif /* _ASM_POWERPC_KEXEC_H */ |
