diff options
Diffstat (limited to 'arch/x86_64/kernel/crash.c')
-rw-r--r-- | arch/x86_64/kernel/crash.c | 69 |
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. */ |
29 | static int crashing_cpu; | 29 | static int crashing_cpu; |
30 | 30 | ||
31 | static 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, ¬e, 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 | |||
49 | static 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, ¬e, sizeof(note)); | ||
57 | } | ||
58 | |||
59 | static 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 | |||
88 | static 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 |
97 | static atomic_t waiting_for_crash_ipi; | 32 | static 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 | } |