Merge tag 'modules-6.4-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/mcgrof...
[linux-block.git] / include / linux / module.h
index 3730ed99e5f7e701df542889f0e4af17f362ca44..9e56763dff818753e54aba4334ca737abfb16751 100644 (file)
@@ -27,6 +27,7 @@
 #include <linux/tracepoint-defs.h>
 #include <linux/srcu.h>
 #include <linux/static_call_types.h>
+#include <linux/dynamic_debug.h>
 
 #include <linux/percpu.h>
 #include <asm/module.h>
@@ -320,17 +321,47 @@ struct mod_tree_node {
        struct latch_tree_node node;
 };
 
-struct module_layout {
-       /* The actual code + data. */
+enum mod_mem_type {
+       MOD_TEXT = 0,
+       MOD_DATA,
+       MOD_RODATA,
+       MOD_RO_AFTER_INIT,
+       MOD_INIT_TEXT,
+       MOD_INIT_DATA,
+       MOD_INIT_RODATA,
+
+       MOD_MEM_NUM_TYPES,
+       MOD_INVALID = -1,
+};
+
+#define mod_mem_type_is_init(type)     \
+       ((type) == MOD_INIT_TEXT ||     \
+        (type) == MOD_INIT_DATA ||     \
+        (type) == MOD_INIT_RODATA)
+
+#define mod_mem_type_is_core(type) (!mod_mem_type_is_init(type))
+
+#define mod_mem_type_is_text(type)     \
+        ((type) == MOD_TEXT ||         \
+         (type) == MOD_INIT_TEXT)
+
+#define mod_mem_type_is_data(type) (!mod_mem_type_is_text(type))
+
+#define mod_mem_type_is_core_data(type)        \
+       (mod_mem_type_is_core(type) &&  \
+        mod_mem_type_is_data(type))
+
+#define for_each_mod_mem_type(type)                    \
+       for (enum mod_mem_type (type) = 0;              \
+            (type) < MOD_MEM_NUM_TYPES; (type)++)
+
+#define for_class_mod_mem_type(type, class)            \
+       for_each_mod_mem_type(type)                     \
+               if (mod_mem_type_is_##class(type))
+
+struct module_memory {
        void *base;
-       /* Total size. */
        unsigned int size;
-       /* The size of the executable code.  */
-       unsigned int text_size;
-       /* Size of RO section of the module (text+rodata) */
-       unsigned int ro_size;
-       /* Size of RO after init section */
-       unsigned int ro_after_init_size;
 
 #ifdef CONFIG_MODULES_TREE_LOOKUP
        struct mod_tree_node mtn;
@@ -339,9 +370,9 @@ struct module_layout {
 
 #ifdef CONFIG_MODULES_TREE_LOOKUP
 /* Only touch one cacheline for common rbtree-for-core-layout case. */
-#define __module_layout_align ____cacheline_aligned
+#define __module_memory_align ____cacheline_aligned
 #else
-#define __module_layout_align
+#define __module_memory_align
 #endif
 
 struct mod_kallsyms {
@@ -426,12 +457,7 @@ struct module {
        /* Startup function. */
        int (*init)(void);
 
-       /* Core layout: rbtree is accessed frequently, so keep together. */
-       struct module_layout core_layout __module_layout_align;
-       struct module_layout init_layout;
-#ifdef CONFIG_ARCH_WANTS_MODULES_DATA_IN_VMALLOC
-       struct module_layout data_layout;
-#endif
+       struct module_memory mem[MOD_MEM_NUM_TYPES] __module_memory_align;
 
        /* Arch-specific module values */
        struct mod_arch_specific arch;
@@ -554,6 +580,9 @@ struct module {
        struct error_injection_entry *ei_funcs;
        unsigned int num_ei_funcs;
 #endif
+#ifdef CONFIG_DYNAMIC_DEBUG_CORE
+       struct _ddebug_info dyndbg_info;
+#endif
 } ____cacheline_aligned __randomize_layout;
 #ifndef MODULE_ARCH_INIT
 #define MODULE_ARCH_INIT {}
@@ -581,23 +610,35 @@ bool __is_module_percpu_address(unsigned long addr, unsigned long *can_addr);
 bool is_module_percpu_address(unsigned long addr);
 bool is_module_text_address(unsigned long addr);
 
+static inline bool within_module_mem_type(unsigned long addr,
+                                         const struct module *mod,
+                                         enum mod_mem_type type)
+{
+       unsigned long base, size;
+
+       base = (unsigned long)mod->mem[type].base;
+       size = mod->mem[type].size;
+       return addr - base < size;
+}
+
 static inline bool within_module_core(unsigned long addr,
                                      const struct module *mod)
 {
-#ifdef CONFIG_ARCH_WANTS_MODULES_DATA_IN_VMALLOC
-       if ((unsigned long)mod->data_layout.base <= addr &&
-           addr < (unsigned long)mod->data_layout.base + mod->data_layout.size)
-               return true;
-#endif
-       return (unsigned long)mod->core_layout.base <= addr &&
-              addr < (unsigned long)mod->core_layout.base + mod->core_layout.size;
+       for_class_mod_mem_type(type, core) {
+               if (within_module_mem_type(addr, mod, type))
+                       return true;
+       }
+       return false;
 }
 
 static inline bool within_module_init(unsigned long addr,
                                      const struct module *mod)
 {
-       return (unsigned long)mod->init_layout.base <= addr &&
-              addr < (unsigned long)mod->init_layout.base + mod->init_layout.size;
+       for_class_mod_mem_type(type, init) {
+               if (within_module_mem_type(addr, mod, type))
+                       return true;
+       }
+       return false;
 }
 
 static inline bool within_module(unsigned long addr, const struct module *mod)
@@ -622,10 +663,46 @@ void symbol_put_addr(void *addr);
    to handle the error case (which only happens with rmmod --wait). */
 extern void __module_get(struct module *module);
 
-/* This is the Right Way to get a module: if it fails, it's being removed,
- * so pretend it's not there. */
+/**
+ * try_module_get() - take module refcount unless module is being removed
+ * @module: the module we should check for
+ *
+ * Only try to get a module reference count if the module is not being removed.
+ * This call will fail if the module is already being removed.
+ *
+ * Care must also be taken to ensure the module exists and is alive prior to
+ * usage of this call. This can be gauranteed through two means:
+ *
+ * 1) Direct protection: you know an earlier caller must have increased the
+ *    module reference through __module_get(). This can typically be achieved
+ *    by having another entity other than the module itself increment the
+ *    module reference count.
+ *
+ * 2) Implied protection: there is an implied protection against module
+ *    removal. An example of this is the implied protection used by kernfs /
+ *    sysfs. The sysfs store / read file operations are guaranteed to exist
+ *    through the use of kernfs's active reference (see kernfs_active()) and a
+ *    sysfs / kernfs file removal cannot happen unless the same file is not
+ *    active. Therefore, if a sysfs file is being read or written to the module
+ *    which created it must still exist. It is therefore safe to use
+ *    try_module_get() on module sysfs store / read ops.
+ *
+ * One of the real values to try_module_get() is the module_is_live() check
+ * which ensures that the caller of try_module_get() can yield to userspace
+ * module removal requests and gracefully fail if the module is on its way out.
+ *
+ * Returns true if the reference count was successfully incremented.
+ */
 extern bool try_module_get(struct module *module);
 
+/**
+ * module_put() - release a reference count to a module
+ * @module: the module we should release a reference count for
+ *
+ * If you successfully bump a reference count to a module with try_module_get(),
+ * when you are finished you must call module_put() to release that reference
+ * count.
+ */
 extern void module_put(struct module *module);
 
 #else /*!CONFIG_MODULE_UNLOAD*/
@@ -782,7 +859,7 @@ void *dereference_module_function_descriptor(struct module *mod, void *ptr)
 
 #ifdef CONFIG_SYSFS
 extern struct kset *module_kset;
-extern struct kobj_type module_ktype;
+extern const struct kobj_type module_ktype;
 #endif /* CONFIG_SYSFS */
 
 #define symbol_request(x) try_then_request_module(symbol_get(x), "symbol:" #x)
@@ -836,8 +913,7 @@ static inline bool module_sig_ok(struct module *module)
 
 #if defined(CONFIG_MODULES) && defined(CONFIG_KALLSYMS)
 int module_kallsyms_on_each_symbol(const char *modname,
-                                  int (*fn)(void *, const char *,
-                                            struct module *, unsigned long),
+                                  int (*fn)(void *, const char *, unsigned long),
                                   void *data);
 
 /* For kallsyms to ask for address resolution.  namebuf should be at
@@ -870,8 +946,7 @@ unsigned long find_kallsyms_symbol_value(struct module *mod, const char *name);
 #else  /* CONFIG_MODULES && CONFIG_KALLSYMS */
 
 static inline int module_kallsyms_on_each_symbol(const char *modname,
-                                                int (*fn)(void *, const char *,
-                                                struct module *, unsigned long),
+                                                int (*fn)(void *, const char *, unsigned long),
                                                 void *data)
 {
        return -EOPNOTSUPP;