diff options
Diffstat (limited to 'arch/i386/kernel/machine_kexec.c')
-rw-r--r-- | arch/i386/kernel/machine_kexec.c | 16 |
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 | ||
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 |