Message ID | 20180724065759.19186-14-takahiro.akashi@linaro.org (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | arm64: kexec: add kexec_file_load() support | expand |
Hi Akashi, On 24/07/18 07:57, AKASHI Takahiro wrote: > On arm64, purgatory would do almost nothing. So just invoke secondary > kernel directly by jumping into its entry code. > > While, in this case, cpu_soft_restart() must be called with dtb address > in the fifth argument, the behavior still stays compatible with kexec_load > case as long as the argument is null. This patch conflicts with commit 76f4e2da45b4 ("arm64: kexec: always reset to EL2 if present") in the arm64 tree. Thanks, James > diff --git a/arch/arm64/kernel/machine_kexec.c b/arch/arm64/kernel/machine_kexec.c > index f76ea92dff91..830a5063e09d 100644 > --- a/arch/arm64/kernel/machine_kexec.c > +++ b/arch/arm64/kernel/machine_kexec.c > @@ -205,10 +205,18 @@ void machine_kexec(struct kimage *kimage) > * uses physical addressing to relocate the new image to its final > * position and transfers control to the image entry point when the > * relocation is complete. > + * In kexec case, kimage->start points to purgatory assuming that > + * kernel entry and dtb address are embedded in purgatory by > + * userspace (kexec-tools). > + * In kexec_file case, the kernel starts directly without purgatory. > */ > - > cpu_soft_restart(kimage != kexec_crash_image, > - reboot_code_buffer_phys, kimage->head, kimage->start, 0); > + reboot_code_buffer_phys, kimage->head, kimage->start, > +#ifdef CONFIG_KEXEC_FILE > + kimage->arch.dtb_mem); > +#else > + 0); > +#endif > > BUG(); /* Should never get here. */ > }
On Thu, Jul 26, 2018 at 02:36:07PM +0100, James Morse wrote: > Hi Akashi, > > On 24/07/18 07:57, AKASHI Takahiro wrote: > > On arm64, purgatory would do almost nothing. So just invoke secondary > > kernel directly by jumping into its entry code. > > > > While, in this case, cpu_soft_restart() must be called with dtb address > > in the fifth argument, the behavior still stays compatible with kexec_load > > case as long as the argument is null. > > This patch conflicts with commit 76f4e2da45b4 ("arm64: kexec: always reset to > EL2 if present") in the arm64 tree. I haven't noticed Mark's patch. I'm going to have to refresh my memory regarding why I introduced el2_switch when I implemented kdump. According to my current memory, however, I added kvm_arch_hardware_enable/disable(), and associated functions, to gracefully shutdown EL2 in case of kexec. Since we have no chance to call reset function (via notifier) at kdump, I believed that el2_switch was necessary for better chance of successful kdump. Thanks, -Takahiro AKASHI > Thanks, > > James > > > diff --git a/arch/arm64/kernel/machine_kexec.c b/arch/arm64/kernel/machine_kexec.c > > index f76ea92dff91..830a5063e09d 100644 > > --- a/arch/arm64/kernel/machine_kexec.c > > +++ b/arch/arm64/kernel/machine_kexec.c > > @@ -205,10 +205,18 @@ void machine_kexec(struct kimage *kimage) > > * uses physical addressing to relocate the new image to its final > > * position and transfers control to the image entry point when the > > * relocation is complete. > > + * In kexec case, kimage->start points to purgatory assuming that > > + * kernel entry and dtb address are embedded in purgatory by > > + * userspace (kexec-tools). > > + * In kexec_file case, the kernel starts directly without purgatory. > > */ > > - > > cpu_soft_restart(kimage != kexec_crash_image, > > - reboot_code_buffer_phys, kimage->head, kimage->start, 0); > > + reboot_code_buffer_phys, kimage->head, kimage->start, > > +#ifdef CONFIG_KEXEC_FILE > > + kimage->arch.dtb_mem); > > +#else > > + 0); > > +#endif > > > > BUG(); /* Should never get here. */ > > }
diff --git a/arch/arm64/kernel/cpu-reset.S b/arch/arm64/kernel/cpu-reset.S index 8021b46c9743..a2be30275a73 100644 --- a/arch/arm64/kernel/cpu-reset.S +++ b/arch/arm64/kernel/cpu-reset.S @@ -22,11 +22,11 @@ * __cpu_soft_restart(el2_switch, entry, arg0, arg1, arg2) - Helper for * cpu_soft_restart. * - * @el2_switch: Flag to indicate a swich to EL2 is needed. + * @el2_switch: Flag to indicate a switch to EL2 is needed. * @entry: Location to jump to for soft reset. - * arg0: First argument passed to @entry. - * arg1: Second argument passed to @entry. - * arg2: Third argument passed to @entry. + * arg0: First argument passed to @entry. (relocation list) + * arg1: Second argument passed to @entry.(physical kernel entry) + * arg2: Third argument passed to @entry. (physical dtb address) * * Put the CPU into the same state as it would be if it had been reset, and * branch to what would be the reset vector. It must be executed with the diff --git a/arch/arm64/kernel/machine_kexec.c b/arch/arm64/kernel/machine_kexec.c index f76ea92dff91..830a5063e09d 100644 --- a/arch/arm64/kernel/machine_kexec.c +++ b/arch/arm64/kernel/machine_kexec.c @@ -205,10 +205,18 @@ void machine_kexec(struct kimage *kimage) * uses physical addressing to relocate the new image to its final * position and transfers control to the image entry point when the * relocation is complete. + * In kexec case, kimage->start points to purgatory assuming that + * kernel entry and dtb address are embedded in purgatory by + * userspace (kexec-tools). + * In kexec_file case, the kernel starts directly without purgatory. */ - cpu_soft_restart(kimage != kexec_crash_image, - reboot_code_buffer_phys, kimage->head, kimage->start, 0); + reboot_code_buffer_phys, kimage->head, kimage->start, +#ifdef CONFIG_KEXEC_FILE + kimage->arch.dtb_mem); +#else + 0); +#endif BUG(); /* Should never get here. */ } diff --git a/arch/arm64/kernel/relocate_kernel.S b/arch/arm64/kernel/relocate_kernel.S index f407e422a720..95fd94209aae 100644 --- a/arch/arm64/kernel/relocate_kernel.S +++ b/arch/arm64/kernel/relocate_kernel.S @@ -32,6 +32,7 @@ ENTRY(arm64_relocate_new_kernel) /* Setup the list loop variables. */ + mov x18, x2 /* x18 = dtb address */ mov x17, x1 /* x17 = kimage_start */ mov x16, x0 /* x16 = kimage_head */ raw_dcache_line_size x15, x0 /* x15 = dcache line size */ @@ -107,7 +108,7 @@ ENTRY(arm64_relocate_new_kernel) isb /* Start new image. */ - mov x0, xzr + mov x0, x18 mov x1, xzr mov x2, xzr mov x3, xzr