Currently, kexec relocation function (arm64_relocate_new_kernel) accepts
the following arguments:
head:		start of array that contains relocation information.
entry:		entry point for new kernel or purgatory.
dtb_mem:	first and only argument to entry.
The number of arguments cannot be easily expended, because this
function is also called from HVC_SOFT_RESTART, which preserves only
three arguments. And, also arm64_relocate_new_kernel is written in
assembly but called without stack, thus no place to move extra arguments
to free registers.
Soon, we will need to pass more arguments: once we enable MMU we
will need to pass information about page tables.
Pass kimage to arm64_relocate_new_kernel, and teach it to get the
required fields from kimage.
Signed-off-by: Pasha Tatashin <pasha.tatashin@soleen.com>
Acked-by: Catalin Marinas <catalin.marinas@arm.com>
Link: https://lore.kernel.org/r/20210930143113.1502553-8-pasha.tatashin@soleen.com
Signed-off-by: Will Deacon <will@kernel.org>
 
 #include <linux/arm_sdei.h>
 #include <linux/sched.h>
+#include <linux/kexec.h>
 #include <linux/mm.h>
 #include <linux/dma-mapping.h>
 #include <linux/kvm_host.h>
   DEFINE(PTRAUTH_KERNEL_KEY_APIA,      offsetof(struct ptrauth_keys_kernel, apia));
 #endif
   BLANK();
+#endif
+#ifdef CONFIG_KEXEC_CORE
+  DEFINE(KIMAGE_ARCH_DTB_MEM,          offsetof(struct kimage, arch.dtb_mem));
+  DEFINE(KIMAGE_HEAD,                  offsetof(struct kimage, head));
+  DEFINE(KIMAGE_START,                 offsetof(struct kimage, start));
+  BLANK();
 #endif
   return 0;
 }
 
 {
        kimage_entry_t *entry;
 
+       dcache_clean_inval_poc((unsigned long)kimage,
+                              (unsigned long)kimage + sizeof(*kimage));
+
        for (entry = &kimage->head; ; entry++) {
                unsigned int flag;
                unsigned long addr;
                restart(is_hyp_nvhe(), kimage->start, kimage->arch.dtb_mem,
                        0, 0);
        } else {
-               cpu_soft_restart(kimage->arch.kern_reloc, kimage->head,
-                                kimage->start, kimage->arch.dtb_mem);
+               cpu_soft_restart(kimage->arch.kern_reloc, virt_to_phys(kimage),
+                                0, 0);
        }
 
        BUG(); /* Should never get here. */
 
  */
 SYM_CODE_START(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 */
+       ldr     x16, [x0, #KIMAGE_HEAD]         /* x16 = kimage_head */
        mov     x14, xzr                        /* x14 = entry ptr */
        mov     x13, xzr                        /* x13 = copy dest */
        raw_dcache_line_size x15, x1            /* x15 = dcache line size */
        isb
 
        /* Start new image. */
-       mov     x0, x18
+       ldr     x4, [x0, #KIMAGE_START]         /* relocation start */
+       ldr     x0, [x0, #KIMAGE_ARCH_DTB_MEM]  /* dtb address */
        mov     x1, xzr
        mov     x2, xzr
        mov     x3, xzr
-       br      x17
-
+       br      x4
 SYM_CODE_END(arm64_relocate_new_kernel)
 
 .align 3       /* To keep the 64-bit values below naturally aligned. */