aboutsummaryrefslogtreecommitdiffstats
path: root/arch/i386/kernel/machine_kexec.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/i386/kernel/machine_kexec.c')
-rw-r--r--arch/i386/kernel/machine_kexec.c16
1 files changed, 11 insertions, 5 deletions
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