aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86_64/kernel/crash.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86_64/kernel/crash.c')
-rw-r--r--arch/x86_64/kernel/crash.c69
1 files changed, 2 insertions, 67 deletions
diff --git a/arch/x86_64/kernel/crash.c b/arch/x86_64/kernel/crash.c
index 3525f884af82..95a7a2c13131 100644
--- a/arch/x86_64/kernel/crash.c
+++ b/arch/x86_64/kernel/crash.c
@@ -28,71 +28,6 @@
28/* This keeps a track of which one is crashing cpu. */ 28/* This keeps a track of which one is crashing cpu. */
29static int crashing_cpu; 29static int crashing_cpu;
30 30
31static u32 *append_elf_note(u32 *buf, char *name, unsigned type,
32 void *data, size_t data_len)
33{
34 struct elf_note note;
35
36 note.n_namesz = strlen(name) + 1;
37 note.n_descsz = data_len;
38 note.n_type = type;
39 memcpy(buf, &note, sizeof(note));
40 buf += (sizeof(note) +3)/4;
41 memcpy(buf, name, note.n_namesz);
42 buf += (note.n_namesz + 3)/4;
43 memcpy(buf, data, note.n_descsz);
44 buf += (note.n_descsz + 3)/4;
45
46 return buf;
47}
48
49static void final_note(u32 *buf)
50{
51 struct elf_note note;
52
53 note.n_namesz = 0;
54 note.n_descsz = 0;
55 note.n_type = 0;
56 memcpy(buf, &note, sizeof(note));
57}
58
59static void crash_save_this_cpu(struct pt_regs *regs, int cpu)
60{
61 struct elf_prstatus prstatus;
62 u32 *buf;
63
64 if ((cpu < 0) || (cpu >= NR_CPUS))
65 return;
66
67 /* Using ELF notes here is opportunistic.
68 * I need a well defined structure format
69 * for the data I pass, and I need tags
70 * on the data to indicate what information I have
71 * squirrelled away. ELF notes happen to provide
72 * all of that, no need to invent something new.
73 */
74
75 buf = (u32*)per_cpu_ptr(crash_notes, cpu);
76
77 if (!buf)
78 return;
79
80 memset(&prstatus, 0, sizeof(prstatus));
81 prstatus.pr_pid = current->pid;
82 elf_core_copy_regs(&prstatus.pr_reg, regs);
83 buf = append_elf_note(buf, "CORE", NT_PRSTATUS, &prstatus,
84 sizeof(prstatus));
85 final_note(buf);
86}
87
88static void crash_save_self(struct pt_regs *regs)
89{
90 int cpu;
91
92 cpu = smp_processor_id();
93 crash_save_this_cpu(regs, cpu);
94}
95
96#ifdef CONFIG_SMP 31#ifdef CONFIG_SMP
97static atomic_t waiting_for_crash_ipi; 32static atomic_t waiting_for_crash_ipi;
98 33
@@ -117,7 +52,7 @@ static int crash_nmi_callback(struct notifier_block *self,
117 return NOTIFY_STOP; 52 return NOTIFY_STOP;
118 local_irq_disable(); 53 local_irq_disable();
119 54
120 crash_save_this_cpu(regs, cpu); 55 crash_save_cpu(regs, cpu);
121 disable_local_APIC(); 56 disable_local_APIC();
122 atomic_dec(&waiting_for_crash_ipi); 57 atomic_dec(&waiting_for_crash_ipi);
123 /* Assume hlt works */ 58 /* Assume hlt works */
@@ -196,5 +131,5 @@ void machine_crash_shutdown(struct pt_regs *regs)
196 131
197 disable_IO_APIC(); 132 disable_IO_APIC();
198 133
199 crash_save_self(regs); 134 crash_save_cpu(regs, smp_processor_id());
200} 135}