18 #include <linux/kexec.h>
20 #include <linux/reboot.h>
21 #include <linux/errno.h>
24 #include <linux/kernel.h>
25 #include <linux/elf.h>
29 #include <linux/timex.h>
30 #include <asm/pgtable.h>
31 #include <asm/pgalloc.h>
32 #include <asm/cacheflush.h>
33 #include <asm/checksum.h>
34 #include <asm/tlbflush.h>
50 #define ELF_BOOT_MAGIC 0x0E1FB007
51 #define EBN_COMMAND_LINE 0x00000004
52 #define roundupsz(X) (((X) + 3) & ~3)
81 "with num_online_cpus() > 1\n",
85 if (image->type != KEXEC_TYPE_DEFAULT) {
87 "with unsupported type: %d\n",
110 static unsigned char *kexec_bn2cl(
void *
pg)
134 pr_warning(
"%s: bad checksum %#x (size %d)\n",
135 __func__, csum, bhdrp->
b_size);
143 desc = (
unsigned char *) (nhdrp + 1);
149 if ((
unsigned char *) (nhdrp + 1) >
150 ((
unsigned char *)
pg) + bhdrp->
b_size) {
152 pr_info(
"%s: out of bounds\n", __func__);
157 command_line = (
unsigned char *) (nhdrp + 1);
160 while (*desc !=
'\0') {
162 if (((
unsigned long)desc &
PAGE_MASK) != (
unsigned long)pg) {
163 pr_info(
"%s: ran off end of page\n",
172 static void kexec_find_and_set_command_line(
struct kimage *
image)
176 unsigned char *command_line = 0;
180 for (ptr = &image->head;
181 (entry = *ptr) && !(entry & IND_DONE);
182 ptr = (entry & IND_INDIRECTION) ?
185 if ((entry & IND_SOURCE)) {
197 if (command_line != 0) {
198 pr_info(
"setting new command line to \"%s\"\n",
205 pr_info(
"%s: no command line found; making empty\n",
210 pr_warning(
"%s: hv_set_command_line returned error: %d\n",
224 return alloc_pages_node(0, gfp_mask, order);
234 #define QUASI_VA_IS_PA_ADDR_RANGE PAGE_OFFSET
236 #define QUASI_VA_IS_PA_ADDR_RANGE PGDIR_SIZE
239 static void setup_quasi_va_is_pa(
void)
257 for (i = 0; i < (QUASI_VA_IS_PA_ADDR_RANGE >>
HPAGE_SHIFT); i++) {
262 unsigned long pfn = i << (HPAGE_SHIFT -
PAGE_SHIFT);
272 void *reboot_code_buffer;
280 kexec_find_and_set_command_line(image);
289 reboot_code_buffer =
page_address(image->control_code_page);
296 (
unsigned long) reboot_code_buffer,
299 setup_quasi_va_is_pa();
302 rnk = reboot_code_buffer;
303 (*rnk)(image->head, reboot_code_buffer, image->start);