// SPDX-License-Identifier: GPL-2.01/*2* Copyright (C) 2019 FORTH-ICS/CARV3* Nick Kossifidis <[email protected]>4*/56#include <linux/kexec.h>7#include <asm/kexec.h> /* For riscv_kexec_* symbol defines */8#include <linux/smp.h> /* For smp_send_stop () */9#include <asm/cacheflush.h> /* For local_flush_icache_all() */10#include <asm/barrier.h> /* For smp_wmb() */11#include <asm/page.h> /* For PAGE_MASK */12#include <linux/libfdt.h> /* For fdt_check_header() */13#include <asm/set_memory.h> /* For set_memory_x() */14#include <linux/compiler.h> /* For unreachable() */15#include <linux/cpu.h> /* For cpu_down() */16#include <linux/reboot.h>17#include <linux/interrupt.h>18#include <linux/irq.h>1920/*21* machine_kexec_prepare - Initialize kexec22*23* This function is called from do_kexec_load, when the user has24* provided us with an image to be loaded. Its goal is to validate25* the image and prepare the control code buffer as needed.26* Note that kimage_alloc_init has already been called and the27* control buffer has already been allocated.28*/29int30machine_kexec_prepare(struct kimage *image)31{32struct kimage_arch *internal = &image->arch;33struct fdt_header fdt = {0};34void *control_code_buffer = NULL;35unsigned int control_code_buffer_sz = 0;36int i = 0;3738/* Find the Flattened Device Tree and save its physical address */39for (i = 0; i < image->nr_segments; i++) {40if (image->segment[i].memsz <= sizeof(fdt))41continue;4243if (image->file_mode)44memcpy(&fdt, image->segment[i].buf, sizeof(fdt));45else if (copy_from_user(&fdt, image->segment[i].buf, sizeof(fdt)))46continue;4748if (fdt_check_header(&fdt))49continue;5051internal->fdt_addr = (unsigned long) image->segment[i].mem;52break;53}5455if (!internal->fdt_addr) {56pr_err("Device tree not included in the provided image\n");57return -EINVAL;58}5960/* Copy the assembler code for relocation to the control page */61if (image->type != KEXEC_TYPE_CRASH) {62control_code_buffer = page_address(image->control_code_page);63control_code_buffer_sz = page_size(image->control_code_page);6465if (unlikely(riscv_kexec_relocate_size > control_code_buffer_sz)) {66pr_err("Relocation code doesn't fit within a control page\n");67return -EINVAL;68}6970memcpy(control_code_buffer, riscv_kexec_relocate,71riscv_kexec_relocate_size);7273/* Mark the control page executable */74set_memory_x((unsigned long) control_code_buffer, 1);75}7677return 0;78}798081/*82* machine_kexec_cleanup - Cleanup any leftovers from83* machine_kexec_prepare84*85* This function is called by kimage_free to handle any arch-specific86* allocations done on machine_kexec_prepare. Since we didn't do any87* allocations there, this is just an empty function. Note that the88* control buffer is freed by kimage_free.89*/90void91machine_kexec_cleanup(struct kimage *image)92{93}949596/*97* machine_shutdown - Prepare for a kexec reboot98*99* This function is called by kernel_kexec just before machine_kexec100* below. Its goal is to prepare the rest of the system (the other101* harts and possibly devices etc) for a kexec reboot.102*/103void machine_shutdown(void)104{105/*106* No more interrupts on this hart107* until we are back up.108*/109local_irq_disable();110111#if defined(CONFIG_HOTPLUG_CPU)112smp_shutdown_nonboot_cpus(smp_processor_id());113#endif114}115116/*117* machine_crash_shutdown - Prepare to kexec after a kernel crash118*119* This function is called by crash_kexec just before machine_kexec120* and its goal is to shutdown non-crashing cpus and save registers.121*/122void123machine_crash_shutdown(struct pt_regs *regs)124{125local_irq_disable();126127/* shutdown non-crashing cpus */128crash_smp_send_stop();129130crash_save_cpu(regs, smp_processor_id());131machine_kexec_mask_interrupts();132133pr_info("Starting crashdump kernel...\n");134}135136/*137* machine_kexec - Jump to the loaded kimage138*139* This function is called by kernel_kexec which is called by the140* reboot system call when the reboot cmd is LINUX_REBOOT_CMD_KEXEC,141* or by crash_kernel which is called by the kernel's arch-specific142* trap handler in case of a kernel panic. It's the final stage of143* the kexec process where the pre-loaded kimage is ready to be144* executed. We assume at this point that all other harts are145* suspended and this hart will be the new boot hart.146*/147void __noreturn148machine_kexec(struct kimage *image)149{150struct kimage_arch *internal = &image->arch;151unsigned long jump_addr = (unsigned long) image->start;152unsigned long first_ind_entry = (unsigned long) &image->head;153unsigned long this_cpu_id = __smp_processor_id();154unsigned long this_hart_id = cpuid_to_hartid_map(this_cpu_id);155unsigned long fdt_addr = internal->fdt_addr;156void *control_code_buffer = page_address(image->control_code_page);157riscv_kexec_method kexec_method = NULL;158159#ifdef CONFIG_SMP160WARN(smp_crash_stop_failed(),161"Some CPUs may be stale, kdump will be unreliable.\n");162#endif163164if (image->type != KEXEC_TYPE_CRASH)165kexec_method = control_code_buffer;166else167kexec_method = (riscv_kexec_method) &riscv_kexec_norelocate;168169pr_notice("Will call new kernel at %08lx from hart id %lx\n",170jump_addr, this_hart_id);171pr_notice("FDT image at %08lx\n", fdt_addr);172173/* Make sure the relocation code is visible to the hart */174local_flush_icache_all();175176/* Jump to the relocation code */177pr_notice("Bye...\n");178kexec_method(first_ind_entry, jump_addr, fdt_addr,179this_hart_id, kernel_map.va_pa_offset);180unreachable();181}182183184