@@ -114,19 +114,13 @@ extern struct uml_param __uml_setup_start, __uml_setup_end;
#ifdef __UM_HOST__
-#define __define_initcall(level,fn) \
- static initcall_t __initcall_##fn __used \
- __attribute__((__section__(".initcall" level ".init"))) = fn
-
-/* Userspace initcalls shouldn't depend on anything in the kernel, so we'll
- * make them run first.
- */
-#define __initcall(fn) __define_initcall("1", fn)
+#undef __uml_exit_call
+#define __uml_exit_call __used __section(os_exitcalls)
+#define __init_call __used __section(os_initcalls)
+#define __initcall(fn) static initcall_t __initcall_##fn __init_call = fn
#define __exitcall(fn) static exitcall_t __exitcall_##fn __exit_call = fn
-#define __init_call __used __section(".initcall.init")
-
#endif
#endif /* _LINUX_UML_INIT_H */
@@ -35,10 +35,15 @@ static void kill_off_processes(void)
read_unlock(&tasklist_lock);
}
+void __weak os_exitcalls(void)
+{
+}
+
void uml_cleanup(void)
{
kmalloc_ok = 0;
do_uml_exitcalls();
+ os_exitcalls();
kill_off_processes();
}
@@ -444,3 +444,14 @@ static int init_pm_wake_signal(void)
late_initcall(init_pm_wake_signal);
#endif
+
+int __weak os_initcalls(void)
+{
+ return 0;
+}
+
+int __init run_os_initcalls(void)
+{
+ return os_initcalls();
+}
+early_initcall(run_os_initcalls);
@@ -186,3 +186,29 @@ void os_warn(const char *fmt, ...)
vfprintf(stderr, fmt, list);
va_end(list);
}
+
+extern void (*__start_os_exitcalls)(void);
+extern void (*__stop_os_exitcalls)(void);
+
+void os_exitcalls(void)
+{
+ exitcall_t *call;
+
+ call = &__stop_os_exitcalls;
+ while (--call >= &__start_os_exitcalls && (*call))
+ (*call)();
+}
+
+extern int (*__start_os_initcalls)(void);
+extern int (*__stop_os_initcalls)(void);
+
+int os_initcalls(void)
+{
+ initcall_t *call;
+
+ call = &__stop_os_initcalls;
+ while (--call >= &__start_os_initcalls && (*call))
+ (*call)();
+
+ return 0;
+}