kexec.c (2757B)
1// SPDX-License-Identifier: GPL-2.0 2 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> 9 10extern void relocate_new_kernel(unsigned long head, 11 unsigned long start, 12 unsigned long phys); 13 14extern const unsigned int relocate_new_kernel_size; 15extern unsigned int kexec_initrd_start_offset; 16extern unsigned int kexec_initrd_end_offset; 17extern unsigned int kexec_cmdline_offset; 18extern unsigned int kexec_free_mem_offset; 19 20static void kexec_show_segment_info(const struct kimage *kimage, 21 unsigned long n) 22{ 23 pr_debug(" segment[%lu]: %016lx - %016lx, 0x%lx bytes, %lu pages\n", 24 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); 29} 30 31static void kexec_image_info(const struct kimage *kimage) 32{ 33 unsigned long i; 34 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); 40 41 for (i = 0; i < kimage->nr_segments; i++) 42 kexec_show_segment_info(kimage, i); 43 44#ifdef CONFIG_KEXEC_FILE 45 if (kimage->file_mode) { 46 pr_debug("cmdline: %.*s\n", (int)kimage->cmdline_buf_len, 47 kimage->cmdline_buf); 48 } 49#endif 50} 51 52void machine_kexec_cleanup(struct kimage *kimage) 53{ 54} 55 56void machine_crash_shutdown(struct pt_regs *regs) 57{ 58} 59 60void machine_shutdown(void) 61{ 62 smp_send_stop(); 63 while (num_online_cpus() > 1) { 64 cpu_relax(); 65 mdelay(1); 66 } 67} 68 69void machine_kexec(struct kimage *image) 70{ 71#ifdef CONFIG_64BIT 72 Elf64_Fdesc desc; 73#endif 74 void (*reloc)(unsigned long head, 75 unsigned long start, 76 unsigned long phys); 77 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; 81 82 set_fixmap(FIX_TEXT_KEXEC, phys); 83 84 flush_cache_all(); 85 86#ifdef CONFIG_64BIT 87 reloc = (void *)&desc; 88 desc.addr = (long long)virt; 89#else 90 reloc = (void *)virt; 91#endif 92 93 memcpy(virt, dereference_function_descriptor(relocate_new_kernel), 94 relocate_new_kernel_size); 95 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; 100 101 flush_cache_all(); 102 flush_tlb_all(); 103 local_irq_disable(); 104 105 reloc(image->head & PAGE_MASK, image->start, phys); 106} 107 108int machine_kexec_prepare(struct kimage *image) 109{ 110 kexec_image_info(image); 111 return 0; 112}