|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [mini-os master] mini-os: kexec: build parameters for new kernel
commit b7994b6409a4d6fb3bff30df1fab28e8173b53de
Author: Juergen Gross <jgross@xxxxxxxx>
AuthorDate: Mon Jun 23 10:41:27 2025 +0200
Commit: Jan Beulich <jbeulich@xxxxxxxx>
CommitDate: Mon Jun 23 10:41:27 2025 +0200
mini-os: kexec: build parameters for new kernel
Build the parameters for the new kernel, consisting of the
hvm_start_info struct, the memory map and the command line.
Signed-off-by: Juergen Gross <jgross@xxxxxxxx>
Reviewed-by: Jason Andryuk <jason.andryuk@xxxxxxx>
---
arch/x86/kexec.c | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
include/kexec.h | 4 ++++
kexec.c | 13 ++++++++++++-
3 files changed, 74 insertions(+), 1 deletion(-)
diff --git a/arch/x86/kexec.c b/arch/x86/kexec.c
index 4783090..fc58473 100644
--- a/arch/x86/kexec.c
+++ b/arch/x86/kexec.c
@@ -199,6 +199,7 @@ bool kexec_arch_need_analyze_shdrs(void)
static unsigned long kexec_param_loc;
static unsigned int kexec_param_size;
+static unsigned long kexec_param_mem;
void kexec_set_param_loc(const char *cmdline)
{
@@ -211,4 +212,61 @@ void kexec_set_param_loc(const char *cmdline)
kexec_last_addr += kexec_param_size;
kexec_last_addr = round_pgup(kexec_last_addr);
}
+
+int kexec_get_entry(const char *cmdline)
+{
+ struct hvm_start_info *info;
+ struct hvm_memmap_table_entry *mmap;
+ unsigned int order;
+ unsigned int i;
+
+ if ( kernel_phys_entry == ~0UL )
+ return ENOEXEC;
+
+ order = get_order(kexec_param_size);
+
+ kexec_param_mem = alloc_pages(order);
+ if ( !kexec_param_mem )
+ return ENOMEM;
+
+ info = (struct hvm_start_info *)kexec_param_mem;
+ memset(info, 0, sizeof(*info));
+ info->magic = XEN_HVM_START_MAGIC_VALUE;
+ info->version = 1;
+ info->cmdline_paddr = kexec_param_mem + sizeof(*info) +
+ e820_entries * sizeof(struct hvm_memmap_table_entry);
+ info->memmap_paddr = kexec_param_mem + sizeof(*info);
+ info->memmap_entries = e820_entries;
+
+ mmap = (struct hvm_memmap_table_entry *)(info + 1);
+ for ( i = 0; i < e820_entries; i++ )
+ {
+ mmap->addr = e820_map[i].addr;
+ mmap->size = e820_map[i].size;
+ mmap->type = e820_map[i].type;
+ mmap++;
+ }
+
+ strcpy((char *)mmap, cmdline);
+
+ if ( kexec_add_action(KEXEC_COPY, to_virt(kexec_param_loc), info,
+ kexec_param_size) )
+ return ENOSPC;
+
+ /* The call of the new kernel happens via the physical address! */
+ if ( kexec_add_action(KEXEC_CALL, (void *)kernel_phys_entry,
+ (void *)kexec_param_loc, 0) )
+ return ENOSPC;
+
+ return 0;
+}
+
+void kexec_get_entry_undo(void)
+{
+ if ( kexec_param_mem )
+ {
+ free_pages((void *)kexec_param_mem, get_order(kexec_param_size));
+ kexec_param_mem = 0;
+ }
+}
#endif /* CONFIG_KEXEC */
diff --git a/include/kexec.h b/include/kexec.h
index 8a2b552..7b103de 100644
--- a/include/kexec.h
+++ b/include/kexec.h
@@ -45,4 +45,8 @@ bool kexec_arch_need_analyze_shdrs(void);
/* Finalize parameter location and size. */
void kexec_set_param_loc(const char *cmdline);
+/* Get entry point and parameter of new kernel. */
+int kexec_get_entry(const char *cmdline);
+void kexec_get_entry_undo(void);
+
#endif /* _KEXEC_H */
diff --git a/kexec.c b/kexec.c
index 1a90d8a..e762fbe 100644
--- a/kexec.c
+++ b/kexec.c
@@ -176,10 +176,21 @@ int kexec(void *kernel, unsigned long kernel_size, const
char *cmdline)
reserve_memory_below(kexec_last_addr);
+ ret = kexec_get_entry(cmdline);
+ if ( ret )
+ {
+ printk("kexec: ELF file of new kernel has no valid entry point\n");
+ goto err;
+ }
+
/* Error exit. */
+ ret = ENOSYS;
+
+ err:
unreserve_memory_below();
+ kexec_get_entry_undo();
- return ENOSYS;
+ return ret;
}
EXPORT_SYMBOL(kexec);
--
generated by git-patchbot for /home/xen/git/mini-os.git#master
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |