aboutsummaryrefslogtreecommitdiffstats
path: root/arch/i386
diff options
context:
space:
mode:
Diffstat (limited to 'arch/i386')
-rw-r--r--arch/i386/kernel/crash.c23
-rw-r--r--arch/i386/kernel/machine_kexec.c16
2 files changed, 24 insertions, 15 deletions
diff --git a/arch/i386/kernel/crash.c b/arch/i386/kernel/crash.c
index 8bdb4b6af0ff..e5fab12f7926 100644
--- a/arch/i386/kernel/crash.c
+++ b/arch/i386/kernel/crash.c
@@ -31,10 +31,11 @@ note_buf_t crash_notes[NR_CPUS];
31/* This keeps a track of which one is crashing cpu. */ 31/* This keeps a track of which one is crashing cpu. */
32static int crashing_cpu; 32static int crashing_cpu;
33 33
34static u32 *append_elf_note(u32 *buf, 34static u32 *append_elf_note(u32 *buf, char *name, unsigned type, void *data,
35 char *name, unsigned type, void *data, size_t data_len) 35 size_t data_len)
36{ 36{
37 struct elf_note note; 37 struct elf_note note;
38
38 note.n_namesz = strlen(name) + 1; 39 note.n_namesz = strlen(name) + 1;
39 note.n_descsz = data_len; 40 note.n_descsz = data_len;
40 note.n_type = type; 41 note.n_type = type;
@@ -44,26 +45,28 @@ static u32 *append_elf_note(u32 *buf,
44 buf += (note.n_namesz + 3)/4; 45 buf += (note.n_namesz + 3)/4;
45 memcpy(buf, data, note.n_descsz); 46 memcpy(buf, data, note.n_descsz);
46 buf += (note.n_descsz + 3)/4; 47 buf += (note.n_descsz + 3)/4;
48
47 return buf; 49 return buf;
48} 50}
49 51
50static void final_note(u32 *buf) 52static void final_note(u32 *buf)
51{ 53{
52 struct elf_note note; 54 struct elf_note note;
55
53 note.n_namesz = 0; 56 note.n_namesz = 0;
54 note.n_descsz = 0; 57 note.n_descsz = 0;
55 note.n_type = 0; 58 note.n_type = 0;
56 memcpy(buf, &note, sizeof(note)); 59 memcpy(buf, &note, sizeof(note));
57} 60}
58 61
59
60static void crash_save_this_cpu(struct pt_regs *regs, int cpu) 62static void crash_save_this_cpu(struct pt_regs *regs, int cpu)
61{ 63{
62 struct elf_prstatus prstatus; 64 struct elf_prstatus prstatus;
63 u32 *buf; 65 u32 *buf;
64 if ((cpu < 0) || (cpu >= NR_CPUS)) { 66
67 if ((cpu < 0) || (cpu >= NR_CPUS))
65 return; 68 return;
66 } 69
67 /* Using ELF notes here is opportunistic. 70 /* Using ELF notes here is opportunistic.
68 * I need a well defined structure format 71 * I need a well defined structure format
69 * for the data I pass, and I need tags 72 * for the data I pass, and I need tags
@@ -75,9 +78,8 @@ static void crash_save_this_cpu(struct pt_regs *regs, int cpu)
75 memset(&prstatus, 0, sizeof(prstatus)); 78 memset(&prstatus, 0, sizeof(prstatus));
76 prstatus.pr_pid = current->pid; 79 prstatus.pr_pid = current->pid;
77 elf_core_copy_regs(&prstatus.pr_reg, regs); 80 elf_core_copy_regs(&prstatus.pr_reg, regs);
78 buf = append_elf_note(buf, "CORE", NT_PRSTATUS, 81 buf = append_elf_note(buf, "CORE", NT_PRSTATUS, &prstatus,
79 &prstatus, sizeof(prstatus)); 82 sizeof(prstatus));
80
81 final_note(buf); 83 final_note(buf);
82} 84}
83 85
@@ -119,8 +121,8 @@ static void crash_save_self(struct pt_regs *saved_regs)
119{ 121{
120 struct pt_regs regs; 122 struct pt_regs regs;
121 int cpu; 123 int cpu;
122 cpu = smp_processor_id();
123 124
125 cpu = smp_processor_id();
124 if (saved_regs) 126 if (saved_regs)
125 crash_setup_regs(&regs, saved_regs); 127 crash_setup_regs(&regs, saved_regs);
126 else 128 else
@@ -153,6 +155,7 @@ static int crash_nmi_callback(struct pt_regs *regs, int cpu)
153 /* Assume hlt works */ 155 /* Assume hlt works */
154 __asm__("hlt"); 156 __asm__("hlt");
155 for(;;); 157 for(;;);
158
156 return 1; 159 return 1;
157} 160}
158 161
@@ -169,8 +172,8 @@ static void smp_send_nmi_allbutself(void)
169static void nmi_shootdown_cpus(void) 172static void nmi_shootdown_cpus(void)
170{ 173{
171 unsigned long msecs; 174 unsigned long msecs;
172 atomic_set(&waiting_for_crash_ipi, num_online_cpus() - 1);
173 175
176 atomic_set(&waiting_for_crash_ipi, num_online_cpus() - 1);
174 /* Would it be better to replace the trap vector here? */ 177 /* Would it be better to replace the trap vector here? */
175 set_nmi_callback(crash_nmi_callback); 178 set_nmi_callback(crash_nmi_callback);
176 /* Ensure the new callback function is set before sending 179 /* Ensure the new callback function is set before sending
diff --git a/arch/i386/kernel/machine_kexec.c b/arch/i386/kernel/machine_kexec.c
index 671880415d1c..52ed18d8b511 100644
--- a/arch/i386/kernel/machine_kexec.c
+++ b/arch/i386/kernel/machine_kexec.c
@@ -80,7 +80,8 @@ static void identity_map_page(unsigned long address)
80 /* Identity map the page table entry */ 80 /* Identity map the page table entry */
81 pgtable_level1[level1_index] = address | L0_ATTR; 81 pgtable_level1[level1_index] = address | L0_ATTR;
82 pgtable_level2[level2_index] = __pa(pgtable_level1) | L1_ATTR; 82 pgtable_level2[level2_index] = __pa(pgtable_level1) | L1_ATTR;
83 set_64bit(&pgtable_level3[level3_index], __pa(pgtable_level2) | L2_ATTR); 83 set_64bit(&pgtable_level3[level3_index],
84 __pa(pgtable_level2) | L2_ATTR);
84 85
85 /* Flush the tlb so the new mapping takes effect. 86 /* Flush the tlb so the new mapping takes effect.
86 * Global tlb entries are not flushed but that is not an issue. 87 * Global tlb entries are not flushed but that is not an issue.
@@ -139,8 +140,10 @@ static void load_segments(void)
139} 140}
140 141
141typedef asmlinkage NORET_TYPE void (*relocate_new_kernel_t)( 142typedef asmlinkage NORET_TYPE void (*relocate_new_kernel_t)(
142 unsigned long indirection_page, unsigned long reboot_code_buffer, 143 unsigned long indirection_page,
143 unsigned long start_address, unsigned int has_pae) ATTRIB_NORET; 144 unsigned long reboot_code_buffer,
145 unsigned long start_address,
146 unsigned int has_pae) ATTRIB_NORET;
144 147
145const extern unsigned char relocate_new_kernel[]; 148const extern unsigned char relocate_new_kernel[];
146extern void relocate_new_kernel_end(void); 149extern void relocate_new_kernel_end(void);
@@ -180,20 +183,23 @@ NORET_TYPE void machine_kexec(struct kimage *image)
180{ 183{
181 unsigned long page_list; 184 unsigned long page_list;
182 unsigned long reboot_code_buffer; 185 unsigned long reboot_code_buffer;
186
183 relocate_new_kernel_t rnk; 187 relocate_new_kernel_t rnk;
184 188
185 /* Interrupts aren't acceptable while we reboot */ 189 /* Interrupts aren't acceptable while we reboot */
186 local_irq_disable(); 190 local_irq_disable();
187 191
188 /* Compute some offsets */ 192 /* Compute some offsets */
189 reboot_code_buffer = page_to_pfn(image->control_code_page) << PAGE_SHIFT; 193 reboot_code_buffer = page_to_pfn(image->control_code_page)
194 << PAGE_SHIFT;
190 page_list = image->head; 195 page_list = image->head;
191 196
192 /* Set up an identity mapping for the reboot_code_buffer */ 197 /* Set up an identity mapping for the reboot_code_buffer */
193 identity_map_page(reboot_code_buffer); 198 identity_map_page(reboot_code_buffer);
194 199
195 /* copy it out */ 200 /* copy it out */
196 memcpy((void *)reboot_code_buffer, relocate_new_kernel, relocate_new_kernel_size); 201 memcpy((void *)reboot_code_buffer, relocate_new_kernel,
202 relocate_new_kernel_size);
197 203
198 /* The segment registers are funny things, they are 204 /* The segment registers are funny things, they are
199 * automatically loaded from a table, in memory wherever you 205 * automatically loaded from a table, in memory wherever you