[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [MINI-OS PATCH 11/12] kexec: add kexec callback functionality
Add a kexec_call() macro which will provide the capability to register a function for being called when doing a kexec() call. The called functions will be called with a boolean parameter "undo" indicating whether a previous call needs to be undone due to a failure during kexec(). The related loop to call all callbacks is added to kexec(). Signed-off-by: Juergen Gross <jgross@xxxxxxxx> --- arch/x86/minios-x86.lds.S | 8 ++++++++ arch/x86/mm.c | 3 ++- include/kexec.h | 6 ++++++ kexec.c | 13 +++++++++++++ 4 files changed, 29 insertions(+), 1 deletion(-) diff --git a/arch/x86/minios-x86.lds.S b/arch/x86/minios-x86.lds.S index 83ec41ce..35356b34 100644 --- a/arch/x86/minios-x86.lds.S +++ b/arch/x86/minios-x86.lds.S @@ -58,6 +58,14 @@ SECTIONS } PROVIDE (__fini_array_end = .); +#if defined(CONFIG_KEXEC) + PROVIDE (__kexec_array_start = .); + .kexec_array : { + *(.kexec_array) + } + PROVIDE (__kexec_array_end = .); +#endif + .ctors : { __CTOR_LIST__ = .; *(.ctors) diff --git a/arch/x86/mm.c b/arch/x86/mm.c index f4419d95..26ede6f4 100644 --- a/arch/x86/mm.c +++ b/arch/x86/mm.c @@ -529,7 +529,8 @@ void change_readonly(bool readonly) #endif } - printk("setting %p-%p readonly\n", &_text, &_erodata); + printk("setting %p-%p %s\n", &_text, &_erodata, + readonly ? "readonly" : "writable"); walk_pt(start_address, ro.etext, change_readonly_func, &ro); #ifdef CONFIG_PARAVIRT diff --git a/include/kexec.h b/include/kexec.h index 411fa013..b89c3000 100644 --- a/include/kexec.h +++ b/include/kexec.h @@ -18,6 +18,12 @@ struct kexec_action { extern char _kexec_start[], _kexec_end[]; extern struct kexec_action kexec_actions[KEXEC_MAX_ACTIONS]; +extern unsigned long __kexec_array_start[], __kexec_array_end[]; + +typedef int(*kexeccall_t)(bool undo); +#define kexec_call(func) \ + static kexeccall_t __kexeccall_##func __attribute__((__used__)) \ + __attribute__((__section__(".kexec_array"))) = func extern unsigned long kexec_last_addr; diff --git a/kexec.c b/kexec.c index 2992f58f..2db876e8 100644 --- a/kexec.c +++ b/kexec.c @@ -168,6 +168,7 @@ static int analyze_kernel(void *kernel, unsigned long size) int kexec(void *kernel, unsigned long kernel_size, const char *cmdline) { int ret; + unsigned long *func; ret = analyze_kernel(kernel, kernel_size); if ( ret ) @@ -191,6 +192,18 @@ int kexec(void *kernel, unsigned long kernel_size, const char *cmdline) if ( ret ) goto err; + for ( func = __kexec_array_start; func < __kexec_array_end; func++ ) + { + ret = ((kexeccall_t)(*func))(false); + if ( ret ) + { + for ( func--; func >= __kexec_array_start; func-- ) + ((kexeccall_t)(*func))(true); + + goto err; + } + } + /* Error exit. */ ret = ENOSYS; -- 2.43.0
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |