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 */ |