1 // SPDX-License-Identifier: GPL-2.0
3 #include <linux/kernel.h>
4 #include <linux/console.h>
5 #include <linux/kexec.h>
6 #include <linux/delay.h>
7 #include <asm/cacheflush.h>
8 #include <asm/sections.h>
10 extern void relocate_new_kernel(unsigned long head
,
14 extern const unsigned int relocate_new_kernel_size
;
15 extern unsigned int kexec_initrd_start_offset
;
16 extern unsigned int kexec_initrd_end_offset
;
17 extern unsigned int kexec_cmdline_offset
;
18 extern unsigned int kexec_free_mem_offset
;
20 static void kexec_show_segment_info(const struct kimage
*kimage
,
23 pr_debug(" segment[%lu]: %016lx - %016lx, 0x%lx bytes, %lu pages\n",
25 kimage
->segment
[n
].mem
,
26 kimage
->segment
[n
].mem
+ kimage
->segment
[n
].memsz
,
27 (unsigned long)kimage
->segment
[n
].memsz
,
28 (unsigned long)kimage
->segment
[n
].memsz
/ PAGE_SIZE
);
31 static void kexec_image_info(const struct kimage
*kimage
)
35 pr_debug("kexec kimage info:\n");
36 pr_debug(" type: %d\n", kimage
->type
);
37 pr_debug(" start: %lx\n", kimage
->start
);
38 pr_debug(" head: %lx\n", kimage
->head
);
39 pr_debug(" nr_segments: %lu\n", kimage
->nr_segments
);
41 for (i
= 0; i
< kimage
->nr_segments
; i
++)
42 kexec_show_segment_info(kimage
, i
);
44 #ifdef CONFIG_KEXEC_FILE
45 if (kimage
->file_mode
) {
46 pr_debug("cmdline: %.*s\n", (int)kimage
->cmdline_buf_len
,
52 void machine_kexec_cleanup(struct kimage
*kimage
)
56 void machine_crash_shutdown(struct pt_regs
*regs
)
60 void machine_shutdown(void)
63 while (num_online_cpus() > 1) {
69 void machine_kexec(struct kimage
*image
)
74 void (*reloc
)(unsigned long head
,
78 unsigned long phys
= page_to_phys(image
->control_code_page
);
79 void *virt
= (void *)__fix_to_virt(FIX_TEXT_KEXEC
);
80 struct kimage_arch
*arch
= &image
->arch
;
82 set_fixmap(FIX_TEXT_KEXEC
, phys
);
87 reloc
= (void *)&desc
;
88 desc
.addr
= (long long)virt
;
93 memcpy(virt
, dereference_function_descriptor(relocate_new_kernel
),
94 relocate_new_kernel_size
);
96 *(unsigned long *)(virt
+ kexec_cmdline_offset
) = arch
->cmdline
;
97 *(unsigned long *)(virt
+ kexec_initrd_start_offset
) = arch
->initrd_start
;
98 *(unsigned long *)(virt
+ kexec_initrd_end_offset
) = arch
->initrd_end
;
99 *(unsigned long *)(virt
+ kexec_free_mem_offset
) = PAGE0
->mem_free
;
105 reloc(image
->head
& PAGE_MASK
, image
->start
, phys
);
108 int machine_kexec_prepare(struct kimage
*image
)
110 kexec_image_info(image
);