* [PATCH kexec-tools 0/4] ppc64: Support kexec with initrd and DTB together
@ 2025-10-22 13:46 Shivang Upadhyay
2025-10-22 13:46 ` [PATCH kexec-tools 1/4] ppc64: ensure /memreserve/ sections exist in user-provided FDT Shivang Upadhyay
` (4 more replies)
0 siblings, 5 replies; 7+ messages in thread
From: Shivang Upadhyay @ 2025-10-22 13:46 UTC (permalink / raw)
To: horms; +Cc: shivangu, sourabhjain, kexec
Currently, on ppc64 systems, kexec cannot directly use a
user-provided devicetreeblob (dtb) when booting a new
kernel with an initrd. This limitation exists because the
dtb must be modified at runtime — for example, to include
the initrd’s memory location and size, and to add
/memreserve/ entries based on the current system memory
layout.
Previously, kexec handled this by generating a fresh dtb in
memory from the running system’s /proc/device-tree directory.
However, this approach prevents users from making
intentional modifications to the dtb — such as changin boot
arguments, enabling or disabling devices, or testing kernel
changes that depend on specific device tree properties.
Adding support for user-provided dtb (with appropriate
patching by kexec) allows more control for developers,
particularly when experimenting with custom kernels or
hardware configurations.
This patch series lifts this restriction and ensures that
the necessary /memreserve/ sections are properly added to
the new DTB. on ppc64, it is mandatory, for the rebooting
cpu to be present in the new kernel’s dtb, so additional
logic has been added to identify and mark one of available
cpu as reboot cpu on currect system.
A new architecture-specific function, arch_do_unload(), has
been introduced to perform the necessary cleanup during
kexec unload. in ppc64, the reboot CPU changes due to kexec,
and it gets reset back on kexec unload.
Shivang Upadhyay (4):
ppc64: ensure /memreserve/ sections exist in user-provided FDT
ppc64: handle reboot CPU in case of user provided DTB
Add arch_do_unload hook for arch-specific cleanup
ppc64: life the dtb and initrd restriction
kexec/arch/arm/kexec-arm.c | 4 +
kexec/arch/arm64/kexec-arm64.c | 4 +
kexec/arch/cris/kexec-cris.c | 4 +
kexec/arch/hppa/kexec-hppa.c | 4 +
kexec/arch/i386/kexec-x86.c | 4 +
kexec/arch/ia64/kexec-ia64.c | 4 +
kexec/arch/loongarch/kexec-loongarch.c | 4 +
kexec/arch/m68k/kexec-m68k.c | 4 +
kexec/arch/mips/kexec-mips.c | 4 +
kexec/arch/ppc/kexec-ppc.c | 4 +
kexec/arch/ppc64/kexec-elf-ppc64.c | 262 ++++++++++++++++++++++++-
kexec/arch/ppc64/kexec-ppc64.c | 8 +
kexec/arch/riscv/kexec-riscv.c | 4 +
kexec/arch/s390/kexec-s390.c | 4 +
kexec/arch/sh/kexec-sh.c | 4 +
kexec/arch/x86_64/kexec-x86_64.c | 5 +
kexec/kexec.c | 1 +
kexec/kexec.h | 1 +
18 files changed, 324 insertions(+), 5 deletions(-)
--
2.51.0
^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH kexec-tools 1/4] ppc64: ensure /memreserve/ sections exist in user-provided FDT
2025-10-22 13:46 [PATCH kexec-tools 0/4] ppc64: Support kexec with initrd and DTB together Shivang Upadhyay
@ 2025-10-22 13:46 ` Shivang Upadhyay
2025-10-22 13:46 ` [PATCH kexec-tools 2/4] ppc64: handle reboot CPU in case of user provided DTB Shivang Upadhyay
` (3 subsequent siblings)
4 siblings, 0 replies; 7+ messages in thread
From: Shivang Upadhyay @ 2025-10-22 13:46 UTC (permalink / raw)
To: horms; +Cc: shivangu, sourabhjain, kexec
User-provided FDTs may lack `/memreserve/` sections, leading to hangs
during kexec. To fix this, allocate a new FDT buffer and use libfdt to
add reserve entries for the initrd, RTAS/OPAL regions (via
/proc/device-tree), and the FDT itself.
Signed-off-by: Shivang Upadhyay <shivangu@linux.ibm.com>
---
kexec/arch/ppc64/kexec-elf-ppc64.c | 165 +++++++++++++++++++++++++++++
1 file changed, 165 insertions(+)
diff --git a/kexec/arch/ppc64/kexec-elf-ppc64.c b/kexec/arch/ppc64/kexec-elf-ppc64.c
index 858c994..e287392 100644
--- a/kexec/arch/ppc64/kexec-elf-ppc64.c
+++ b/kexec/arch/ppc64/kexec-elf-ppc64.c
@@ -40,6 +40,9 @@
#include <libfdt.h>
#include <arch/fdt.h>
#include <arch/options.h>
+#include <dirent.h>
+#include <assert.h>
+#include <linux/limits.h>
uint64_t initrd_base, initrd_size;
unsigned char reuse_initrd = 0;
@@ -180,6 +183,162 @@ out:
return ret;
}
+static int read_proc_file(char* filename, char* buf) {
+ FILE* f;
+ int len;
+
+ f = fopen(filename, "r");
+ if (f == NULL) {
+ perror("unable to open file");
+ }
+ len = fread(buf, 1, 10, f);
+ fclose(f);
+
+ return len;
+}
+
+
+static void add_reserve_mem(void* dtb, uint64_t where, uint64_t length)
+{
+ int ret;
+
+ ret = fdt_add_mem_rsv(dtb, where, length);
+ assert(ret == 0 && "Failed to add memory reservation block to FDT.");
+
+ return;
+}
+
+/* this function is similar to kexec/fs2dt.c's checkprop function, only part
+ * different here is, this version uses libfdt's function to mark the reserve
+ * section
+ */
+static void checkprop(void* dtb, char *name, unsigned *data, int len)
+{
+ static unsigned long long base, size, end;
+
+ if ((data == NULL) && (base || size || end))
+ die("unrecoverable error: no property data");
+ else if (!strcmp(name, "linux,rtas-base"))
+ base = be32_to_cpu(*data);
+ else if (!strcmp(name, "opal-base-address"))
+ base = be64_to_cpu(*(unsigned long long *)data);
+ else if (!strcmp(name, "opal-runtime-size"))
+ size = be64_to_cpu(*(unsigned long long *)data);
+ else if (!strcmp(name, "linux,tce-base"))
+ base = be64_to_cpu(*(unsigned long long *) data);
+ else if (!strcmp(name, "rtas-size") ||
+ !strcmp(name, "linux,tce-size"))
+ size = be32_to_cpu(*data);
+ else if (reuse_initrd && !strcmp(name, "linux,initrd-start")) {
+ if (len == 8)
+ base = be64_to_cpu(*(unsigned long long *) data);
+ else
+ base = be32_to_cpu(*data);
+ } else if (reuse_initrd && !strcmp(name, "linux,initrd-end")) {
+ if (len == 8)
+ end = be64_to_cpu(*(unsigned long long *) data);
+ else
+ end = be32_to_cpu(*data);
+ }
+
+ if (size && end)
+ die("unrecoverable error: size and end set at same time\n");
+ if (base && size) {
+ add_reserve_mem(dtb, base, size);
+ base = size = 0;
+ }
+ if (base && end) {
+ add_reserve_mem(dtb, base, end-base);
+ base = end = 0;
+ }
+}
+
+static void file_traversal(void *dtb, const char *pathname) {
+ DIR *dir = opendir(pathname);
+ if (!dir) {
+ perror("opendir failed");
+ return;
+ }
+
+ struct dirent *entry;
+ while ((entry = readdir(dir)) != NULL) {
+ // Skip '.' and '..'
+ if (entry->d_name[0] == '.')
+ continue;
+
+ char full_path[PATH_MAX];
+ snprintf(full_path, sizeof(full_path), "%s/%s", pathname, entry->d_name);
+
+ // Check if entry is a directory
+ if (entry->d_type == DT_DIR) {
+ file_traversal(dtb, full_path);
+ } else {
+ char file_data[10];
+ int readlen = read_proc_file(full_path, file_data);
+ if (readlen > 0) {
+ checkprop(dtb, entry->d_name,
+ (unsigned *)file_data, readlen);
+ }
+ }
+ }
+
+ closedir(dir);
+}
+
+void patch_devicetree_with_initrd_info(char* dtb, uint64_t initrd_base,
+ uint64_t initrd_size) {
+
+ int ret, offset;
+ unsigned long initrd_end = initrd_base + initrd_size;
+ uint64_t base_be = cpu_to_be64(initrd_base);
+ uint64_t end_be = cpu_to_be64(initrd_end);
+
+ ret = 0;
+ offset = fdt_path_offset(dtb, "/chosen");
+ assert(offset >= 0 && "failed to find the /chosen node");
+
+ ret = fdt_setprop(dtb, offset, "linux,initrd-start", &base_be, sizeof(base_be));
+ assert(ret == 0 && "failed to set initrd-start on dtb");
+
+ ret = fdt_setprop(dtb, offset, "linux,initrd-end", &end_be, sizeof(end_be));
+ assert(ret == 0 && "failed to set initrd-end on dtb");
+
+}
+
+
+static void patch_devicetree(char *dtb, uint64_t initrd_base,
+ uint64_t initrd_size)
+{
+ int ret;
+
+ patch_devicetree_with_initrd_info(dtb, initrd_base, initrd_size);
+
+ file_traversal(dtb, "/proc/device-tree");
+
+ ret = fdt_add_mem_rsv(dtb, initrd_base, initrd_size);
+ assert(ret == 0 && "failed to add rsvmap");
+
+ ret = fdt_add_mem_rsv(dtb, 0, fdt_totalsize(dtb));
+ assert(ret == 0 && "failed to add rsvmap");
+
+ fdt_set_boot_cpuid_phys(dtb, 0x0);
+ fdt_set_last_comp_version(dtb, 17);
+
+}
+
+static char* alloc_new_dtb(char* dtb, off_t* newsize) {
+ int ret;
+
+ *newsize = fdt_totalsize(dtb) + 256;
+ dtb = (char*) realloc(dtb, *newsize);
+ ret = fdt_open_into(dtb, dtb, *newsize);
+
+ assert(ret == 0 &&
+ "fdt_open_into failed");
+
+ return dtb;
+}
+
int elf_ppc64_load(int argc, char **argv, const char *buf, off_t len,
struct kexec_info *info)
{
@@ -340,6 +499,12 @@ int elf_ppc64_load(int argc, char **argv, const char *buf, off_t len,
if (devicetreeblob) {
/* Grab device tree from buffer */
seg_buf = slurp_file(devicetreeblob, &seg_size);
+
+ if (ramdisk) {
+ seg_buf = alloc_new_dtb(seg_buf, &seg_size);
+ patch_devicetree(seg_buf, initrd_base, initrd_size);
+ }
+
} else {
/* create from fs2dt */
create_flatten_tree(&seg_buf, &seg_size, cmdline);
--
2.51.0
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH kexec-tools 2/4] ppc64: handle reboot CPU in case of user provided DTB
2025-10-22 13:46 [PATCH kexec-tools 0/4] ppc64: Support kexec with initrd and DTB together Shivang Upadhyay
2025-10-22 13:46 ` [PATCH kexec-tools 1/4] ppc64: ensure /memreserve/ sections exist in user-provided FDT Shivang Upadhyay
@ 2025-10-22 13:46 ` Shivang Upadhyay
2025-10-22 13:46 ` [PATCH kexec-tools 3/4] Add arch_do_unload hook for arch-specific cleanup Shivang Upadhyay
` (2 subsequent siblings)
4 siblings, 0 replies; 7+ messages in thread
From: Shivang Upadhyay @ 2025-10-22 13:46 UTC (permalink / raw)
To: horms; +Cc: shivangu, sourabhjain, kexec
When restricting available CPUs for the next kexec'ed kernel, ensure the
reboot CPU is part of that available CPU's in new DTB. ppc64 requires
the booting CPU to be present in the new kernel’s DTB; otherwise, the
system will panic during bring-up.
Example Scenario
==============================
Current Kernel
--------------
Physical CPUs: [1] [2] [3] [4] [5] [6] [7] [8]
Available set: ^ ^ ^ ^ ^ ^ ^ ^
| | | | | | | |
+---+---+---+---+---+---+---+
All CPUs available
Next Kernel (limited CPU set)
-----------------------------
Physical CPUs: [4] [5] [6] [7]
Logical IDs: [0] [1] [2] [3]
Mapping:
Logical 0 → Physical 4
Logical 1 → Physical 5
Logical 2 → Physical 6
Logical 3 → Physical 7
If next kernel should only boot on CPUs 6 and 7
------------------------------------------------
Selected CPUs:
Physical CPUs: [6] [7]
Logical IDs: [2] [3]
Required reboot CPU = Logical ID [3]
→ Physical CPU [7]
Signed-off-by: Shivang Upadhyay <shivangu@linux.ibm.com>
---
kexec/arch/ppc64/kexec-elf-ppc64.c | 86 ++++++++++++++++++++++++++++++
1 file changed, 86 insertions(+)
diff --git a/kexec/arch/ppc64/kexec-elf-ppc64.c b/kexec/arch/ppc64/kexec-elf-ppc64.c
index e287392..2084356 100644
--- a/kexec/arch/ppc64/kexec-elf-ppc64.c
+++ b/kexec/arch/ppc64/kexec-elf-ppc64.c
@@ -43,6 +43,7 @@
#include <dirent.h>
#include <assert.h>
#include <linux/limits.h>
+#include <stdbool.h>
uint64_t initrd_base, initrd_size;
unsigned char reuse_initrd = 0;
@@ -305,6 +306,88 @@ void patch_devicetree_with_initrd_info(char* dtb, uint64_t initrd_base,
}
+int find_logical_cpu_from_physical(int physical_cpu) {
+
+ char possible_buffer[0x2f];
+ char physical_id_buffer[0x2f];
+ char physical_id_filename_buffer[0x5f];
+ char online_filename_buffer[0x5f];
+ char online_buffer[0x1f];
+ FILE *possible_file, *online_file;
+ FILE *physical_id_file;
+ int pc;
+ int is_online;
+ int first_cpu, last_cpu;
+
+ possible_file = fopen("/sys/devices/system/cpu/possible", "r");
+ fread(possible_buffer, 0x2f, 1, possible_file);
+ fclose(possible_file);
+ sscanf(possible_buffer, "%d-%d", &first_cpu, &last_cpu);
+
+ for (int lc = first_cpu; lc <= last_cpu; lc++) {
+ sprintf(online_filename_buffer,
+ "/sys/devices/system/cpu/cpu%d/online", lc);
+ online_file = fopen(online_filename_buffer, "r");
+ fread(online_buffer, 0xf, 1, online_file);
+ fclose(online_file);
+ sscanf(online_buffer, "%d", &is_online);
+
+ if (!is_online)
+ continue;
+
+ sprintf(physical_id_filename_buffer,
+ "/sys/devices/system/cpu/cpu%d/physical_id", lc);
+ physical_id_file = fopen(physical_id_filename_buffer, "r");
+ fread(physical_id_buffer, 0x2f, 1, physical_id_file);
+ fclose(physical_id_file);
+ sscanf(physical_id_buffer, "%d", &pc);
+
+ if (pc == physical_cpu)
+ return lc;
+ }
+
+ return -1;
+}
+
+static void set_valid_bootcpu(const void* dtb) {
+ int node = -1;
+ int len;
+ int nthreads;
+ const struct fdt_property *intserv;
+ __be32* intserv_data;
+ int i;
+ char cmd_buffer[0x5f];
+ int boot_cpuid;
+ bool found = false;
+
+ while ((node = fdt_next_node(dtb, node, NULL)) >= 0) {
+ intserv = fdt_get_property(dtb, node, "ibm,ppc-interrupt-server#s",
+ &len);
+ if (!intserv) continue;
+ intserv_data = (__be32*)intserv->data;
+ nthreads = len / sizeof(int);
+ for (i = 0; i < nthreads; i++) {
+ boot_cpuid = be32_to_cpu(intserv_data[i]);
+ int logical_cpu = find_logical_cpu_from_physical(boot_cpuid);
+ if (logical_cpu < 0)
+ continue;
+ sprintf(cmd_buffer, "echo %d > /sys/kernel/reboot/cpu",
+ logical_cpu);
+ system(cmd_buffer);
+ printf("setting boot cpu: %d (physical_id: %d)\n",
+ logical_cpu, boot_cpuid);
+ found = true;
+ break;
+ }
+ if (found)
+ break;
+ }
+
+ if (!found) {
+ die("can't find a valid boot_cpu inside the FDT.\n");
+ }
+
+}
static void patch_devicetree(char *dtb, uint64_t initrd_base,
uint64_t initrd_size)
@@ -324,6 +407,9 @@ static void patch_devicetree(char *dtb, uint64_t initrd_base,
fdt_set_boot_cpuid_phys(dtb, 0x0);
fdt_set_last_comp_version(dtb, 17);
+
+ set_valid_bootcpu(dtb);
+
}
static char* alloc_new_dtb(char* dtb, off_t* newsize) {
--
2.51.0
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH kexec-tools 3/4] Add arch_do_unload hook for arch-specific cleanup
2025-10-22 13:46 [PATCH kexec-tools 0/4] ppc64: Support kexec with initrd and DTB together Shivang Upadhyay
2025-10-22 13:46 ` [PATCH kexec-tools 1/4] ppc64: ensure /memreserve/ sections exist in user-provided FDT Shivang Upadhyay
2025-10-22 13:46 ` [PATCH kexec-tools 2/4] ppc64: handle reboot CPU in case of user provided DTB Shivang Upadhyay
@ 2025-10-22 13:46 ` Shivang Upadhyay
2025-10-22 13:46 ` [PATCH kexec-tools 4/4] ppc64: life the dtb and initrd restriction Shivang Upadhyay
2025-11-11 13:47 ` [PATCH kexec-tools 0/4] ppc64: Support kexec with initrd and DTB together Simon Horman
4 siblings, 0 replies; 7+ messages in thread
From: Shivang Upadhyay @ 2025-10-22 13:46 UTC (permalink / raw)
To: horms; +Cc: shivangu, sourabhjain, kexec
Provide a new `arch_do_unload` hook that allows architectures to perform
cleanup actions during kexec unload. On ppc64, this hook resets the boot
CPU.
Signed-off-by: Shivang Upadhyay <shivangu@linux.ibm.com>
---
kexec/arch/arm/kexec-arm.c | 4 ++++
kexec/arch/arm64/kexec-arm64.c | 4 ++++
kexec/arch/cris/kexec-cris.c | 4 ++++
kexec/arch/hppa/kexec-hppa.c | 4 ++++
kexec/arch/i386/kexec-x86.c | 4 ++++
kexec/arch/ia64/kexec-ia64.c | 4 ++++
kexec/arch/loongarch/kexec-loongarch.c | 4 ++++
kexec/arch/m68k/kexec-m68k.c | 4 ++++
kexec/arch/mips/kexec-mips.c | 4 ++++
kexec/arch/ppc/kexec-ppc.c | 4 ++++
kexec/arch/ppc64/kexec-ppc64.c | 8 ++++++++
kexec/arch/riscv/kexec-riscv.c | 4 ++++
kexec/arch/s390/kexec-s390.c | 4 ++++
kexec/arch/sh/kexec-sh.c | 4 ++++
kexec/arch/x86_64/kexec-x86_64.c | 5 +++++
kexec/kexec.c | 1 +
kexec/kexec.h | 1 +
17 files changed, 67 insertions(+)
diff --git a/kexec/arch/arm/kexec-arm.c b/kexec/arch/arm/kexec-arm.c
index 4216327..af5b511 100644
--- a/kexec/arch/arm/kexec-arm.c
+++ b/kexec/arch/arm/kexec-arm.c
@@ -153,3 +153,7 @@ int arch_do_exclude_segment(struct kexec_info *UNUSED(info), struct kexec_segmen
{
return 0;
}
+
+void arch_do_unload(void)
+{
+}
diff --git a/kexec/arch/arm64/kexec-arm64.c b/kexec/arch/arm64/kexec-arm64.c
index 9091f40..58256cf 100644
--- a/kexec/arch/arm64/kexec-arm64.c
+++ b/kexec/arch/arm64/kexec-arm64.c
@@ -1369,3 +1369,7 @@ int arch_do_exclude_segment(struct kexec_info *UNUSED(info), struct kexec_segmen
{
return 0;
}
+
+void arch_do_unload(void)
+{
+}
diff --git a/kexec/arch/cris/kexec-cris.c b/kexec/arch/cris/kexec-cris.c
index 6d048d3..44557ad 100644
--- a/kexec/arch/cris/kexec-cris.c
+++ b/kexec/arch/cris/kexec-cris.c
@@ -113,3 +113,7 @@ int arch_do_exclude_segment(struct kexec_info *UNUSED(info), struct kexec_segmen
{
return 0;
}
+
+void arch_do_unload(void)
+{
+}
diff --git a/kexec/arch/hppa/kexec-hppa.c b/kexec/arch/hppa/kexec-hppa.c
index b2c74ab..ef0eab5 100644
--- a/kexec/arch/hppa/kexec-hppa.c
+++ b/kexec/arch/hppa/kexec-hppa.c
@@ -151,3 +151,7 @@ int arch_do_exclude_segment(struct kexec_info *UNUSED(info), struct kexec_segmen
{
return 0;
}
+
+void arch_do_unload(void)
+{
+}
diff --git a/kexec/arch/i386/kexec-x86.c b/kexec/arch/i386/kexec-x86.c
index eac01e5..f10b545 100644
--- a/kexec/arch/i386/kexec-x86.c
+++ b/kexec/arch/i386/kexec-x86.c
@@ -216,3 +216,7 @@ int arch_do_exclude_segment(struct kexec_info *info, struct kexec_segment *segme
return 0;
}
+
+void arch_do_unload(void)
+{
+}
diff --git a/kexec/arch/ia64/kexec-ia64.c b/kexec/arch/ia64/kexec-ia64.c
index 548a3af..54c8588 100644
--- a/kexec/arch/ia64/kexec-ia64.c
+++ b/kexec/arch/ia64/kexec-ia64.c
@@ -249,3 +249,7 @@ int arch_do_exclude_segment(struct kexec_info *UNUSED(info), struct kexec_segmen
{
return 0;
}
+
+void arch_do_unload(void)
+{
+}
diff --git a/kexec/arch/loongarch/kexec-loongarch.c b/kexec/arch/loongarch/kexec-loongarch.c
index ea0c316..e8713c8 100644
--- a/kexec/arch/loongarch/kexec-loongarch.c
+++ b/kexec/arch/loongarch/kexec-loongarch.c
@@ -386,3 +386,7 @@ int arch_do_exclude_segment(struct kexec_info *UNUSED(info), struct kexec_segmen
{
return 0;
}
+
+void arch_do_unload(void)
+{
+}
diff --git a/kexec/arch/m68k/kexec-m68k.c b/kexec/arch/m68k/kexec-m68k.c
index 4824a02..cbbaaac 100644
--- a/kexec/arch/m68k/kexec-m68k.c
+++ b/kexec/arch/m68k/kexec-m68k.c
@@ -113,3 +113,7 @@ int arch_do_exclude_segment(struct kexec_info *UNUSED(info), struct kexec_segmen
{
return 0;
}
+
+void arch_do_unload(void)
+{
+}
diff --git a/kexec/arch/mips/kexec-mips.c b/kexec/arch/mips/kexec-mips.c
index fb5a5d4..6fb481c 100644
--- a/kexec/arch/mips/kexec-mips.c
+++ b/kexec/arch/mips/kexec-mips.c
@@ -193,3 +193,7 @@ int arch_do_exclude_segment(struct kexec_info *UNUSED(info), struct kexec_segmen
{
return 0;
}
+
+void arch_do_unload(void)
+{
+}
diff --git a/kexec/arch/ppc/kexec-ppc.c b/kexec/arch/ppc/kexec-ppc.c
index d3dad0f..7892385 100644
--- a/kexec/arch/ppc/kexec-ppc.c
+++ b/kexec/arch/ppc/kexec-ppc.c
@@ -970,3 +970,7 @@ int arch_do_exclude_segment(struct kexec_info *UNUSED(info), struct kexec_segmen
{
return 0;
}
+
+void arch_do_unload(void)
+{
+}
diff --git a/kexec/arch/ppc64/kexec-ppc64.c b/kexec/arch/ppc64/kexec-ppc64.c
index 6653246..48afc85 100644
--- a/kexec/arch/ppc64/kexec-ppc64.c
+++ b/kexec/arch/ppc64/kexec-ppc64.c
@@ -979,3 +979,11 @@ int arch_do_exclude_segment(struct kexec_info *info, struct kexec_segment *segme
return 0;
}
+
+void arch_do_unload(void)
+{
+ /*
+ * setting the reboot cpu to 0
+ */
+ system("echo 0 > /sys/kernel/reboot/cpu");
+}
diff --git a/kexec/arch/riscv/kexec-riscv.c b/kexec/arch/riscv/kexec-riscv.c
index f34b468..a5a12a0 100644
--- a/kexec/arch/riscv/kexec-riscv.c
+++ b/kexec/arch/riscv/kexec-riscv.c
@@ -524,3 +524,7 @@ int arch_do_exclude_segment(struct kexec_info *UNUSED(info), struct kexec_segmen
{
return 0;
}
+
+void arch_do_unload(void)
+{
+}
diff --git a/kexec/arch/s390/kexec-s390.c b/kexec/arch/s390/kexec-s390.c
index ad3eb93..86c9fb8 100644
--- a/kexec/arch/s390/kexec-s390.c
+++ b/kexec/arch/s390/kexec-s390.c
@@ -273,3 +273,7 @@ int arch_do_exclude_segment(struct kexec_info *UNUSED(info), struct kexec_segmen
{
return 0;
}
+
+void arch_do_unload(void)
+{
+}
diff --git a/kexec/arch/sh/kexec-sh.c b/kexec/arch/sh/kexec-sh.c
index 7b9ac1c..5231402 100644
--- a/kexec/arch/sh/kexec-sh.c
+++ b/kexec/arch/sh/kexec-sh.c
@@ -262,3 +262,7 @@ int arch_do_exclude_segment(struct kexec_info *UNUSED(info), struct kexec_segmen
{
return 0;
}
+
+void arch_do_unload(void)
+{
+}
diff --git a/kexec/arch/x86_64/kexec-x86_64.c b/kexec/arch/x86_64/kexec-x86_64.c
index f7f59f6..6a0e872 100644
--- a/kexec/arch/x86_64/kexec-x86_64.c
+++ b/kexec/arch/x86_64/kexec-x86_64.c
@@ -197,3 +197,8 @@ int arch_do_exclude_segment(struct kexec_info *info, struct kexec_segment *segme
return 0;
}
+
+
+void arch_do_unload(void)
+{
+}
diff --git a/kexec/kexec.c b/kexec/kexec.c
index 6bf12d7..25b5391 100644
--- a/kexec/kexec.c
+++ b/kexec/kexec.c
@@ -1752,6 +1752,7 @@ int main(int argc, char *argv[])
}
if (!do_kexec_file_syscall)
result = k_unload(kexec_flags);
+ arch_do_unload();
}
if (do_load && (result == 0)) {
if (do_kexec_file_syscall) {
diff --git a/kexec/kexec.h b/kexec/kexec.h
index a2e19c4..d0bccb5 100644
--- a/kexec/kexec.h
+++ b/kexec/kexec.h
@@ -310,6 +310,7 @@ extern int do_hotplug;
void arch_usage(void);
/* Return non-zero if segment needs to be excluded from SHA calculation, else 0. */
int arch_do_exclude_segment(struct kexec_info *info, struct kexec_segment *segment);
+void arch_do_unload(void);
int arch_process_options(int argc, char **argv);
int arch_compat_trampoline(struct kexec_info *info);
void arch_update_purgatory(struct kexec_info *info);
--
2.51.0
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH kexec-tools 4/4] ppc64: life the dtb and initrd restriction
2025-10-22 13:46 [PATCH kexec-tools 0/4] ppc64: Support kexec with initrd and DTB together Shivang Upadhyay
` (2 preceding siblings ...)
2025-10-22 13:46 ` [PATCH kexec-tools 3/4] Add arch_do_unload hook for arch-specific cleanup Shivang Upadhyay
@ 2025-10-22 13:46 ` Shivang Upadhyay
2025-11-11 13:47 ` [PATCH kexec-tools 0/4] ppc64: Support kexec with initrd and DTB together Simon Horman
4 siblings, 0 replies; 7+ messages in thread
From: Shivang Upadhyay @ 2025-10-22 13:46 UTC (permalink / raw)
To: horms; +Cc: shivangu, sourabhjain, kexec
The dtb and initrd restriction is now applied only when performing a
kdump.
Signed-off-by: Shivang Upadhyay <shivangu@linux.ibm.com>
---
kexec/arch/ppc64/kexec-elf-ppc64.c | 11 ++++++-----
1 file changed, 6 insertions(+), 5 deletions(-)
diff --git a/kexec/arch/ppc64/kexec-elf-ppc64.c b/kexec/arch/ppc64/kexec-elf-ppc64.c
index 2084356..288ca41 100644
--- a/kexec/arch/ppc64/kexec-elf-ppc64.c
+++ b/kexec/arch/ppc64/kexec-elf-ppc64.c
@@ -566,15 +566,16 @@ int elf_ppc64_load(int argc, char **argv, const char *buf, off_t len,
elf_rel_build_load(info, &info->rhdr, purgatory,
purgatory_size, 0, max_addr, 1, 0);
+ if (ramdisk && devicetreeblob && (info->kexec_flags & KEXEC_ON_CRASH)) {
+ fprintf(stderr,
+ "Can't use ramdisk with device tree blob input in kdump\n");
+ return -1;
+ }
+
/* Add a ram-disk to the current image
* Note: Add the ramdisk after elf_rel_build_load
*/
if (ramdisk) {
- if (devicetreeblob) {
- fprintf(stderr,
- "Can't use ramdisk with device tree blob input\n");
- return -1;
- }
seg_buf = slurp_file(ramdisk, &seg_size);
hole_addr = add_buffer(info, seg_buf, seg_size, seg_size,
0, 0, max_addr, 1);
--
2.51.0
^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH kexec-tools 0/4] ppc64: Support kexec with initrd and DTB together
2025-10-22 13:46 [PATCH kexec-tools 0/4] ppc64: Support kexec with initrd and DTB together Shivang Upadhyay
` (3 preceding siblings ...)
2025-10-22 13:46 ` [PATCH kexec-tools 4/4] ppc64: life the dtb and initrd restriction Shivang Upadhyay
@ 2025-11-11 13:47 ` Simon Horman
2025-11-12 12:10 ` Shivang Upadhyay
4 siblings, 1 reply; 7+ messages in thread
From: Simon Horman @ 2025-11-11 13:47 UTC (permalink / raw)
To: Shivang Upadhyay; +Cc: sourabhjain, kexec
On Wed, Oct 22, 2025 at 07:16:05PM +0530, Shivang Upadhyay wrote:
> Currently, on ppc64 systems, kexec cannot directly use a
> user-provided devicetreeblob (dtb) when booting a new
> kernel with an initrd. This limitation exists because the
> dtb must be modified at runtime — for example, to include
> the initrd’s memory location and size, and to add
> /memreserve/ entries based on the current system memory
> layout.
>
> Previously, kexec handled this by generating a fresh dtb in
> memory from the running system’s /proc/device-tree directory.
> However, this approach prevents users from making
> intentional modifications to the dtb — such as changin boot
> arguments, enabling or disabling devices, or testing kernel
> changes that depend on specific device tree properties.
>
> Adding support for user-provided dtb (with appropriate
> patching by kexec) allows more control for developers,
> particularly when experimenting with custom kernels or
> hardware configurations.
>
> This patch series lifts this restriction and ensures that
> the necessary /memreserve/ sections are properly added to
> the new DTB. on ppc64, it is mandatory, for the rebooting
> cpu to be present in the new kernel’s dtb, so additional
> logic has been added to identify and mark one of available
> cpu as reboot cpu on currect system.
>
> A new architecture-specific function, arch_do_unload(), has
> been introduced to perform the necessary cleanup during
> kexec unload. in ppc64, the reboot CPU changes due to kexec,
> and it gets reset back on kexec unload.
>
> Shivang Upadhyay (4):
> ppc64: ensure /memreserve/ sections exist in user-provided FDT
> ppc64: handle reboot CPU in case of user provided DTB
> Add arch_do_unload hook for arch-specific cleanup
> ppc64: life the dtb and initrd restriction
Thanks, applied.
- ppc64: life the dtb and initrd restriction
https://git.kernel.org/pub/scm/utils/kernel/kexec/kexec-tools.git/commit/?id=4dc039779675
- Add arch_do_unload hook for arch-specific cleanup
https://git.kernel.org/pub/scm/utils/kernel/kexec/kexec-tools.git/commit/?id=bf4aa2a1f365
- ppc64: handle reboot CPU in case of user provided DTB
https://git.kernel.org/pub/scm/utils/kernel/kexec/kexec-tools.git/commit/?id=39631c8fd64f
- ppc64: ensure /memreserve/ sections exist in user-provided FDT
https://git.kernel.org/pub/scm/utils/kernel/kexec/kexec-tools.git/commit/?id=32f664bfa479
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH kexec-tools 0/4] ppc64: Support kexec with initrd and DTB together
2025-11-11 13:47 ` [PATCH kexec-tools 0/4] ppc64: Support kexec with initrd and DTB together Simon Horman
@ 2025-11-12 12:10 ` Shivang Upadhyay
0 siblings, 0 replies; 7+ messages in thread
From: Shivang Upadhyay @ 2025-11-12 12:10 UTC (permalink / raw)
To: Simon Horman; +Cc: sourabhjain, kexec
On Tue, Nov 11, 2025 at 01:47:01PM +0000, Simon Horman wrote:
> On Wed, Oct 22, 2025 at 07:16:05PM +0530, Shivang Upadhyay wrote:
> > Currently, on ppc64 systems, kexec cannot directly use a
> > user-provided devicetreeblob (dtb) when booting a new
> > kernel with an initrd. This limitation exists because the
> > dtb must be modified at runtime — for example, to include
> > the initrd’s memory location and size, and to add
> > /memreserve/ entries based on the current system memory
> > layout.
> >
> > Previously, kexec handled this by generating a fresh dtb in
> > memory from the running system’s /proc/device-tree directory.
> > However, this approach prevents users from making
> > intentional modifications to the dtb — such as changin boot
> > arguments, enabling or disabling devices, or testing kernel
> > changes that depend on specific device tree properties.
> >
> > Adding support for user-provided dtb (with appropriate
> > patching by kexec) allows more control for developers,
> > particularly when experimenting with custom kernels or
> > hardware configurations.
> >
> > This patch series lifts this restriction and ensures that
> > the necessary /memreserve/ sections are properly added to
> > the new DTB. on ppc64, it is mandatory, for the rebooting
> > cpu to be present in the new kernel’s dtb, so additional
> > logic has been added to identify and mark one of available
> > cpu as reboot cpu on currect system.
> >
> > A new architecture-specific function, arch_do_unload(), has
> > been introduced to perform the necessary cleanup during
> > kexec unload. in ppc64, the reboot CPU changes due to kexec,
> > and it gets reset back on kexec unload.
> >
> > Shivang Upadhyay (4):
> > ppc64: ensure /memreserve/ sections exist in user-provided FDT
> > ppc64: handle reboot CPU in case of user provided DTB
> > Add arch_do_unload hook for arch-specific cleanup
> > ppc64: life the dtb and initrd restriction
>
> Thanks, applied.
Thanks Simon
~Shivang.
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2025-11-12 12:10 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-10-22 13:46 [PATCH kexec-tools 0/4] ppc64: Support kexec with initrd and DTB together Shivang Upadhyay
2025-10-22 13:46 ` [PATCH kexec-tools 1/4] ppc64: ensure /memreserve/ sections exist in user-provided FDT Shivang Upadhyay
2025-10-22 13:46 ` [PATCH kexec-tools 2/4] ppc64: handle reboot CPU in case of user provided DTB Shivang Upadhyay
2025-10-22 13:46 ` [PATCH kexec-tools 3/4] Add arch_do_unload hook for arch-specific cleanup Shivang Upadhyay
2025-10-22 13:46 ` [PATCH kexec-tools 4/4] ppc64: life the dtb and initrd restriction Shivang Upadhyay
2025-11-11 13:47 ` [PATCH kexec-tools 0/4] ppc64: Support kexec with initrd and DTB together Simon Horman
2025-11-12 12:10 ` Shivang Upadhyay
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.