[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[MINI-OS PATCH v2 11/12] mini-os: 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>
Reviewed-by: Jason Andryuk <jason.andryuk@xxxxxxx>
---
 arch/x86/minios-x86.lds.S |  8 ++++++++
 include/kexec.h           |  6 ++++++
 kexec.c                   | 13 +++++++++++++
 3 files changed, 27 insertions(+)

diff --git a/arch/x86/minios-x86.lds.S b/arch/x86/minios-x86.lds.S
index 8a1db7d4..8c6e0a60 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/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 1ef7ce84..f42aa8ad 100644
--- a/kexec.c
+++ b/kexec.c
@@ -167,6 +167,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 )
@@ -190,6 +191,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




 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.