@@ -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)
@@ -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
@@ -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;
@@ -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;
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@suse.com> --- 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(-)