aboutsummaryrefslogtreecommitdiffstats
path: root/arch/i386/kernel/crash.c
diff options
context:
space:
mode:
authorAlexander Nyberg <alexn@telia.com>2005-06-25 17:58:26 -0400
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-06-25 19:24:54 -0400
commit6e274d144302068a00794ec22e73520c0615cb6f (patch)
treef7ea59ea47d3c5676fbac8d39e8deaa1f94146ae /arch/i386/kernel/crash.c
parent86b1ae38c0a62409dc862a28e3f08920f55f944b (diff)
[PATCH] kdump: Use real pt_regs from exception
Makes kexec_crashdump() take a pt_regs * as an argument. This allows to get exact register state at the point of the crash. If we come from direct panic assertion NULL will be passed and the current registers saved before crashdump. This hooks into two places: die(): check the conditions under which we will panic when calling do_exit and go there directly with the pt_regs that caused the fatal fault. die_nmi(): If we receive an NMI lockup while in the kernel use the pt_regs and go directly to crash_kexec(). We're probably nested up badly at this point so this might be the only chance to escape with proper information. Signed-off-by: Alexander Nyberg <alexn@telia.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'arch/i386/kernel/crash.c')
-rw-r--r--arch/i386/kernel/crash.c36
1 files changed, 24 insertions, 12 deletions
diff --git a/arch/i386/kernel/crash.c b/arch/i386/kernel/crash.c
index a021681d21f8..8bdb4b6af0ff 100644
--- a/arch/i386/kernel/crash.c
+++ b/arch/i386/kernel/crash.c
@@ -100,12 +100,31 @@ static void crash_get_current_regs(struct pt_regs *regs)
100 regs->eip = (unsigned long)current_text_addr(); 100 regs->eip = (unsigned long)current_text_addr();
101} 101}
102 102
103static void crash_save_self(void) 103/* CPU does not save ss and esp on stack if execution is already
104 * running in kernel mode at the time of NMI occurrence. This code
105 * fixes it.
106 */
107static void crash_setup_regs(struct pt_regs *newregs, struct pt_regs *oldregs)
108{
109 memcpy(newregs, oldregs, sizeof(*newregs));
110 newregs->esp = (unsigned long)&(oldregs->esp);
111 __asm__ __volatile__("xorl %eax, %eax;");
112 __asm__ __volatile__ ("movw %%ss, %%ax;" :"=a"(newregs->xss));
113}
114
115/* We may have saved_regs from where the error came from
116 * or it is NULL if via a direct panic().
117 */
118static void crash_save_self(struct pt_regs *saved_regs)
104{ 119{
105 struct pt_regs regs; 120 struct pt_regs regs;
106 int cpu; 121 int cpu;
107 cpu = smp_processor_id(); 122 cpu = smp_processor_id();
108 crash_get_current_regs(&regs); 123
124 if (saved_regs)
125 crash_setup_regs(&regs, saved_regs);
126 else
127 crash_get_current_regs(&regs);
109 crash_save_this_cpu(&regs, cpu); 128 crash_save_this_cpu(&regs, cpu);
110} 129}
111 130
@@ -124,15 +143,8 @@ static int crash_nmi_callback(struct pt_regs *regs, int cpu)
124 return 1; 143 return 1;
125 local_irq_disable(); 144 local_irq_disable();
126 145
127 /* CPU does not save ss and esp on stack if execution is already
128 * running in kernel mode at the time of NMI occurrence. This code
129 * fixes it.
130 */
131 if (!user_mode(regs)) { 146 if (!user_mode(regs)) {
132 memcpy(&fixed_regs, regs, sizeof(*regs)); 147 crash_setup_regs(&fixed_regs, regs);
133 fixed_regs.esp = (unsigned long)&(regs->esp);
134 __asm__ __volatile__("xorl %eax, %eax;");
135 __asm__ __volatile__ ("movw %%ss, %%ax;" :"=a"(fixed_regs.xss));
136 regs = &fixed_regs; 148 regs = &fixed_regs;
137 } 149 }
138 crash_save_this_cpu(regs, cpu); 150 crash_save_this_cpu(regs, cpu);
@@ -184,7 +196,7 @@ static void nmi_shootdown_cpus(void)
184} 196}
185#endif 197#endif
186 198
187void machine_crash_shutdown(void) 199void machine_crash_shutdown(struct pt_regs *regs)
188{ 200{
189 /* This function is only called after the system 201 /* This function is only called after the system
190 * has paniced or is otherwise in a critical state. 202 * has paniced or is otherwise in a critical state.
@@ -204,5 +216,5 @@ void machine_crash_shutdown(void)
204#if defined(CONFIG_X86_IO_APIC) 216#if defined(CONFIG_X86_IO_APIC)
205 disable_IO_APIC(); 217 disable_IO_APIC();
206#endif 218#endif
207 crash_save_self(); 219 crash_save_self(regs);
208} 220}