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 4435ad9439abba65fa4902ac200cd20c55f79bd5..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 {
@@ -353,9 +384,9 @@ struct mod_kallsyms {
 
 #ifdef CONFIG_LIVEPATCH
 /**
- * struct klp_modinfo - Elf information preserved from the livepatch module
+ * struct klp_modinfo - ELF information preserved from the livepatch module
  *
- * @hdr: Elf header
+ * @hdr: ELF header
  * @sechdrs: Section header table
  * @secstrings: String table for the section headers
  * @symndx: The symbol table section index
@@ -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;
@@ -523,7 +549,7 @@ struct module {
        bool klp; /* Is this a livepatch module? */
        bool klp_alive;
 
-       /* Elf information */
+       /* ELF information */
        struct klp_modinfo *klp_info;
 #endif
 
@@ -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)
@@ -608,14 +649,6 @@ static inline bool within_module(unsigned long addr, const struct module *mod)
 /* Search for module by name: must be in a RCU-sched critical section. */
 struct module *find_module(const char *name);
 
-/* Returns 0 and fills in value, defined and namebuf, or -ERANGE if
-   symnum out of range. */
-int module_get_kallsym(unsigned int symnum, unsigned long *value, char *type,
-                       char *name, char *module_name, int *exported);
-
-/* Look for this name: can be of form module:name. */
-unsigned long module_kallsyms_lookup_name(const char *name);
-
 extern void __noreturn __module_put_and_kthread_exit(struct module *mod,
                        long code);
 #define module_put_and_kthread_exit(code) __module_put_and_kthread_exit(THIS_MODULE, code)
@@ -630,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*/
@@ -662,17 +731,6 @@ static inline void __module_get(struct module *module)
 /* Dereference module function descriptor */
 void *dereference_module_function_descriptor(struct module *mod, void *ptr);
 
-/* For kallsyms to ask for address resolution.  namebuf should be at
- * least KSYM_NAME_LEN long: a pointer to namebuf is returned if
- * found, otherwise NULL. */
-const char *module_address_lookup(unsigned long addr,
-                           unsigned long *symbolsize,
-                           unsigned long *offset,
-                           char **modname, const unsigned char **modbuildid,
-                           char *namebuf);
-int lookup_module_symbol_name(unsigned long addr, char *symname);
-int lookup_module_symbol_attrs(unsigned long addr, unsigned long *size, unsigned long *offset, char *modname, char *name);
-
 int register_module_notifier(struct notifier_block *nb);
 int unregister_module_notifier(struct notifier_block *nb);
 
@@ -763,39 +821,6 @@ static inline void module_put(struct module *module)
 
 #define module_name(mod) "kernel"
 
-/* For kallsyms to ask for address resolution.  NULL means not found. */
-static inline const char *module_address_lookup(unsigned long addr,
-                                         unsigned long *symbolsize,
-                                         unsigned long *offset,
-                                         char **modname,
-                                         const unsigned char **modbuildid,
-                                         char *namebuf)
-{
-       return NULL;
-}
-
-static inline int lookup_module_symbol_name(unsigned long addr, char *symname)
-{
-       return -ERANGE;
-}
-
-static inline int lookup_module_symbol_attrs(unsigned long addr, unsigned long *size, unsigned long *offset, char *modname, char *name)
-{
-       return -ERANGE;
-}
-
-static inline int module_get_kallsym(unsigned int symnum, unsigned long *value,
-                                       char *type, char *name,
-                                       char *module_name, int *exported)
-{
-       return -ERANGE;
-}
-
-static inline unsigned long module_kallsyms_lookup_name(const char *name)
-{
-       return 0;
-}
-
 static inline int register_module_notifier(struct notifier_block *nb)
 {
        /* no events will happen anyway, so this can always succeed */
@@ -834,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)
@@ -888,17 +913,88 @@ 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);
-#else
+
+/* For kallsyms to ask for address resolution.  namebuf should be at
+ * least KSYM_NAME_LEN long: a pointer to namebuf is returned if
+ * found, otherwise NULL.
+ */
+const char *module_address_lookup(unsigned long addr,
+                                 unsigned long *symbolsize,
+                                 unsigned long *offset,
+                                 char **modname, const unsigned char **modbuildid,
+                                 char *namebuf);
+int lookup_module_symbol_name(unsigned long addr, char *symname);
+int lookup_module_symbol_attrs(unsigned long addr,
+                              unsigned long *size,
+                              unsigned long *offset,
+                              char *modname,
+                              char *name);
+
+/* Returns 0 and fills in value, defined and namebuf, or -ERANGE if
+ * symnum out of range.
+ */
+int module_get_kallsym(unsigned int symnum, unsigned long *value, char *type,
+                      char *name, char *module_name, int *exported);
+
+/* Look for this name: can be of form module:name. */
+unsigned long module_kallsyms_lookup_name(const char *name);
+
+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;
 }
+
+/* For kallsyms to ask for address resolution.  NULL means not found. */
+static inline const char *module_address_lookup(unsigned long addr,
+                                               unsigned long *symbolsize,
+                                               unsigned long *offset,
+                                               char **modname,
+                                               const unsigned char **modbuildid,
+                                               char *namebuf)
+{
+       return NULL;
+}
+
+static inline int lookup_module_symbol_name(unsigned long addr, char *symname)
+{
+       return -ERANGE;
+}
+
+static inline int lookup_module_symbol_attrs(unsigned long addr,
+                                            unsigned long *size,
+                                            unsigned long *offset,
+                                            char *modname,
+                                            char *name)
+{
+       return -ERANGE;
+}
+
+static inline int module_get_kallsym(unsigned int symnum, unsigned long *value,
+                                    char *type, char *name,
+                                    char *module_name, int *exported)
+{
+       return -ERANGE;
+}
+
+static inline unsigned long module_kallsyms_lookup_name(const char *name)
+{
+       return 0;
+}
+
+static inline unsigned long find_kallsyms_symbol_value(struct module *mod,
+                                                      const char *name)
+{
+       return 0;
+}
+
 #endif  /* CONFIG_MODULES && CONFIG_KALLSYMS */
 
 #endif /* _LINUX_MODULE_H */