@@ -103,6 +103,12 @@ void kexec_copy_flush(struct kimage *image);
struct crash_mem;
int update_cpus_node(void *fdt);
int get_crash_memory_ranges(struct crash_mem **mem_ranges);
+
+#if defined(CONFIG_HOTPLUG_CPU) || defined(CONFIG_MEMORY_HOTPLUG)
+
+int machine_kexec_post_load(struct kimage *image);
+#define machine_kexec_post_load machine_kexec_post_load
+#endif
#endif
#if defined(CONFIG_CRASH_DUMP) && defined(CONFIG_PPC_RTAS)
@@ -118,6 +124,9 @@ extern const struct kexec_file_ops kexec_elf64_ops;
struct kimage_arch {
struct crash_mem *exclude_ranges;
+#if defined(CONFIG_HOTPLUG_CPU) || defined(CONFIG_MEMORY_HOTPLUG)
+ int fdt_index;
+#endif
unsigned long backup_start;
void *backup_buf;
void *fdt;
@@ -77,6 +77,33 @@ int machine_kexec_prepare(struct kimage *image)
return 0;
}
+#if defined(CONFIG_HOTPLUG_CPU) || defined(CONFIG_MEMORY_HOTPLUG)
+int machine_kexec_post_load(struct kimage *kimage)
+{
+ int i;
+ void *ptr;
+ unsigned long mem;
+
+ /* Mark fdt_index invalid */
+ kimage->arch.fdt_index = -1;
+
+ if (kimage->type != KEXEC_TYPE_CRASH)
+ return 0;
+
+ for (i = 0; i < kimage->nr_segments; i++) {
+ mem = kimage->segment[i].mem;
+ ptr = __va(mem);
+
+ if (ptr && fdt_magic(ptr) == FDT_MAGIC) {
+ kimage->arch.fdt_index = i;
+ break;
+ }
+ }
+
+ return 0;
+}
+#endif
+
/* Called during kexec sequence with MMU off */
static notrace void copy_segments(unsigned long ind)
{
@@ -123,6 +123,12 @@ static void *elf64_load(struct kimage *image, char *kernel_buf,
kbuf.buf_align = PAGE_SIZE;
kbuf.top_down = true;
kbuf.mem = KEXEC_BUF_MEM_UNKNOWN;
+
+#if defined(CONFIG_HOTPLUG_CPU) || defined(CONFIG_MEMORY_HOTPLUG)
+ image->arch.fdt_index = image->nr_segments;
+#endif
+ kbuf.memsz = fdt_totalsize(fdt);
+
ret = kexec_add_buffer(&kbuf);
if (ret)
goto out_free_fdt;
@@ -1096,6 +1096,11 @@ int arch_kexec_kernel_image_probe(struct kimage *image, void *buf,
return ret;
}
+#if defined(CONFIG_HOTPLUG_CPU)
+ /* Mark fdt_index invalid */
+ image->arch.fdt_index = -1;
+#endif
+
return kexec_image_probe_default(image, buf, buf_len);
}
Add a new member "fdt_index" to kimage_arch struct to hold the index of the FDT (Flattened Device Tree) segment in the kexec segment array. Having direct access to FDT segment will help arch crash hotplug handler to avoid looping kexec segment array to identify the FDT segment index for every FDT update on hotplug events. The fdt_index is initialized during the kexec load for both kexec_load and kexec_file_load system call. Signed-off-by: Sourabh Jain <sourabhjain@linux.ibm.com> --- arch/powerpc/include/asm/kexec.h | 9 +++++++++ arch/powerpc/kexec/core_64.c | 27 +++++++++++++++++++++++++++ arch/powerpc/kexec/elf_64.c | 6 ++++++ arch/powerpc/kexec/file_load_64.c | 5 +++++ 4 files changed, 47 insertions(+)