diff options
Diffstat (limited to 'arch/i386')
-rw-r--r-- | arch/i386/kernel/crash.c | 23 | ||||
-rw-r--r-- | arch/i386/kernel/machine_kexec.c | 16 |
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. */ |
32 | static int crashing_cpu; | 32 | static int crashing_cpu; |
33 | 33 | ||
34 | static u32 *append_elf_note(u32 *buf, | 34 | static 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 | ||
50 | static void final_note(u32 *buf) | 52 | static 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, ¬e, sizeof(note)); | 59 | memcpy(buf, ¬e, sizeof(note)); |
57 | } | 60 | } |
58 | 61 | ||
59 | |||
60 | static void crash_save_this_cpu(struct pt_regs *regs, int cpu) | 62 | static 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(®s, saved_regs); | 127 | crash_setup_regs(®s, 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) | |||
169 | static void nmi_shootdown_cpus(void) | 172 | static 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 | ||
141 | typedef asmlinkage NORET_TYPE void (*relocate_new_kernel_t)( | 142 | typedef 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 | ||
145 | const extern unsigned char relocate_new_kernel[]; | 148 | const extern unsigned char relocate_new_kernel[]; |
146 | extern void relocate_new_kernel_end(void); | 149 | extern 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 |