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 <linux/reboot.h>
9 #include <asm/cacheflush.h>
10 #include <asm/sections.h>
12 extern void relocate_new_kernel(unsigned long head
,
16 extern const unsigned int relocate_new_kernel_size
;
17 extern unsigned int kexec_initrd_start_offset
;
18 extern unsigned int kexec_initrd_end_offset
;
19 extern unsigned int kexec_cmdline_offset
;
20 extern unsigned int kexec_free_mem_offset
;
22 static void kexec_show_segment_info(const struct kimage
*kimage
,
25 pr_debug(" segment[%lu]: %016lx - %016lx, 0x%lx bytes, %lu pages\n",
27 kimage
->segment
[n
].mem
,
28 kimage
->segment
[n
].mem
+ kimage
->segment
[n
].memsz
,
29 (unsigned long)kimage
->segment
[n
].memsz
,
30 (unsigned long)kimage
->segment
[n
].memsz
/ PAGE_SIZE
);
33 static void kexec_image_info(const struct kimage
*kimage
)
37 pr_debug("kexec kimage info:\n");
38 pr_debug(" type: %d\n", kimage
->type
);
39 pr_debug(" start: %lx\n", kimage
->start
);
40 pr_debug(" head: %lx\n", kimage
->head
);
41 pr_debug(" nr_segments: %lu\n", kimage
->nr_segments
);
43 for (i
= 0; i
< kimage
->nr_segments
; i
++)
44 kexec_show_segment_info(kimage
, i
);
46 #ifdef CONFIG_KEXEC_FILE
47 if (kimage
->file_mode
) {
48 pr_debug("cmdline: %.*s\n", (int)kimage
->cmdline_buf_len
,
54 void machine_kexec_cleanup(struct kimage
*kimage
)
58 void machine_crash_shutdown(struct pt_regs
*regs
)
62 void machine_shutdown(void)
65 while (num_online_cpus() > 1) {
71 void machine_kexec(struct kimage
*image
)
76 void (*reloc
)(unsigned long head
,
80 unsigned long phys
= page_to_phys(image
->control_code_page
);
81 void *virt
= (void *)__fix_to_virt(FIX_TEXT_KEXEC
);
82 struct kimage_arch
*arch
= &image
->arch
;
84 set_fixmap(FIX_TEXT_KEXEC
, phys
);
89 reloc
= (void *)&desc
;
90 desc
.addr
= (long long)virt
;
95 memcpy(virt
, dereference_function_descriptor(relocate_new_kernel
),
96 relocate_new_kernel_size
);
98 *(unsigned long *)(virt
+ kexec_cmdline_offset
) = arch
->cmdline
;
99 *(unsigned long *)(virt
+ kexec_initrd_start_offset
) = arch
->initrd_start
;
100 *(unsigned long *)(virt
+ kexec_initrd_end_offset
) = arch
->initrd_end
;
101 *(unsigned long *)(virt
+ kexec_free_mem_offset
) = PAGE0
->mem_free
;
107 reloc(image
->head
& PAGE_MASK
, image
->start
, phys
);
110 int machine_kexec_prepare(struct kimage
*image
)
112 kexec_image_info(image
);