compat: make all modules depend on compat
authorJohannes Berg <johannes.berg@intel.com>
Sun, 4 Mar 2012 05:03:22 +0000 (21:03 -0800)
committerLuis R. Rodriguez <mcgrof@frijolero.org>
Sun, 4 Mar 2012 05:03:22 +0000 (21:03 -0800)
Sometimes, compat based drivers do not depend on
compat.ko because the base kernel is new enough.
This causes compat to not be loaded and makes it
harder to identify that the modules were based
on compat.

Re-define module_init() to make all modules that
were compiled against compat also require to be
linked against compat.ko.

Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Luis R. Rodriguez <mcgrof@frijolero.org>
compat/main.c
include/linux/compat-2.6.h

index f830488..30a4a1e 100644 (file)
@@ -32,6 +32,11 @@ module_param(compat_version, charp, 0400);
 MODULE_PARM_DESC(compat_version,
                 "Version of the kernel compat backport work");
 
+void compat_dependency_symbol(void)
+{
+}
+EXPORT_SYMBOL_GPL(compat_dependency_symbol);
+
 static int __init compat_init(void)
 {
        /* pm-qos for kernels <= 2.6.24, this is a no-op on newer kernels */
index c14aeb8..bb00cd4 100644 (file)
 #include <linux/autoconf.h>
 #endif
 #include <linux/compat_autoconf.h>
+#include <linux/init.h>
+
+/*
+ * The define overwriting module_init is based on the original module_init
+ * which looks like this:
+ * #define module_init(initfn)                                 \
+ *     static inline initcall_t __inittest(void)               \
+ *     { return initfn; }                                      \
+ *     int init_module(void) __attribute__((alias(#initfn)));
+ *
+ * To the call to the initfn we added the symbol dependency on compat
+ * to make sure that compat.ko gets loaded for any compat modules.
+ */
+void compat_dependency_symbol(void);
+
+#undef module_init
+#define module_init(initfn)                                            \
+       static void __init __init_compat(void)                          \
+       {                                                               \
+               compat_dependency_symbol();                             \
+               initfn();                                               \
+       }                                                               \
+       int init_module(void) __attribute__((alias("__init_compat")));
 
 /*
  * Each compat file represents compatibility code for new kernel