[PATCH v5 2/6] powerpc/crash: update kimage_arch struct
Sourabh Jain
sourabhjain at linux.ibm.com
Sun Nov 20 15:25:04 PST 2022
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 at 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(+)
diff --git a/arch/powerpc/include/asm/kexec.h b/arch/powerpc/include/asm/kexec.h
index 8090ad7d97d9d..fee742ddaf9a6 100644
--- a/arch/powerpc/include/asm/kexec.h
+++ b/arch/powerpc/include/asm/kexec.h
@@ -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;
diff --git a/arch/powerpc/kexec/core_64.c b/arch/powerpc/kexec/core_64.c
index 0b292f93a74cc..0b8e2f8084afb 100644
--- a/arch/powerpc/kexec/core_64.c
+++ b/arch/powerpc/kexec/core_64.c
@@ -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)
{
diff --git a/arch/powerpc/kexec/elf_64.c b/arch/powerpc/kexec/elf_64.c
index eeb258002d1e0..6272d49b49eb4 100644
--- a/arch/powerpc/kexec/elf_64.c
+++ b/arch/powerpc/kexec/elf_64.c
@@ -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;
diff --git a/arch/powerpc/kexec/file_load_64.c b/arch/powerpc/kexec/file_load_64.c
index ca65aa3a69240..87de3fc59159a 100644
--- a/arch/powerpc/kexec/file_load_64.c
+++ b/arch/powerpc/kexec/file_load_64.c
@@ -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);
}
--
2.38.1
More information about the kexec
mailing list