module: Move procfs support into a separate file
authorAaron Tomlin <atomlin@redhat.com>
Tue, 22 Mar 2022 14:03:41 +0000 (14:03 +0000)
committerLuis Chamberlain <mcgrof@kernel.org>
Tue, 5 Apr 2022 15:43:04 +0000 (08:43 -0700)
No functional change.

This patch migrates code that allows one to generate a
list of loaded/or linked modules via /proc when procfs
support is enabled into kernel/module/procfs.c.

Reviewed-by: Christophe Leroy <christophe.leroy@csgroup.eu>
Signed-off-by: Aaron Tomlin <atomlin@redhat.com>
Signed-off-by: Luis Chamberlain <mcgrof@kernel.org>
kernel/module/Makefile
kernel/module/internal.h
kernel/module/main.c
kernel/module/procfs.c [new file with mode: 0644]

index 9901bed..94296c9 100644 (file)
@@ -15,3 +15,4 @@ obj-$(CONFIG_MODULES_TREE_LOOKUP) += tree_lookup.o
 obj-$(CONFIG_STRICT_MODULE_RWX) += strict_rwx.o
 obj-$(CONFIG_DEBUG_KMEMLEAK) += debug_kmemleak.o
 obj-$(CONFIG_KALLSYMS) += kallsyms.o
+obj-$(CONFIG_PROC_FS) += procfs.o
index 44ca05b..6af40c2 100644 (file)
@@ -72,6 +72,7 @@ struct module *find_module_all(const char *name, size_t len, bool even_unformed)
 int cmp_name(const void *name, const void *sym);
 long module_get_offset(struct module *mod, unsigned int *size, Elf_Shdr *sechdr,
                       unsigned int section);
+char *module_flags(struct module *mod, char *buf);
 
 static inline unsigned long kernel_symbol_value(const struct kernel_symbol *sym)
 {
index 4d74988..63b9845 100644 (file)
@@ -22,7 +22,6 @@
 #include <linux/slab.h>
 #include <linux/vmalloc.h>
 #include <linux/elf.h>
-#include <linux/proc_fs.h>
 #include <linux/seq_file.h>
 #include <linux/syscalls.h>
 #include <linux/fcntl.h>
@@ -805,31 +804,6 @@ out:
        return ret;
 }
 
-static inline void print_unload_info(struct seq_file *m, struct module *mod)
-{
-       struct module_use *use;
-       int printed_something = 0;
-
-       seq_printf(m, " %i ", module_refcount(mod));
-
-       /*
-        * Always include a trailing , so userspace can differentiate
-        * between this and the old multi-field proc format.
-        */
-       list_for_each_entry(use, &mod->source_list, source_list) {
-               printed_something = 1;
-               seq_printf(m, "%s,", use->source->name);
-       }
-
-       if (mod->init != NULL && mod->exit == NULL) {
-               printed_something = 1;
-               seq_puts(m, "[permanent],");
-       }
-
-       if (!printed_something)
-               seq_puts(m, "-");
-}
-
 void __symbol_put(const char *symbol)
 {
        struct find_symbol_arg fsa = {
@@ -919,12 +893,6 @@ void module_put(struct module *module)
 EXPORT_SYMBOL(module_put);
 
 #else /* !CONFIG_MODULE_UNLOAD */
-static inline void print_unload_info(struct seq_file *m, struct module *mod)
-{
-       /* We don't know the usage count, or what modules are using. */
-       seq_puts(m, " - -");
-}
-
 static inline void module_unload_free(struct module *mod)
 {
 }
@@ -3596,7 +3564,7 @@ static void cfi_cleanup(struct module *mod)
 }
 
 /* Keep in sync with MODULE_FLAGS_BUF_SIZE !!! */
-static char *module_flags(struct module *mod, char *buf)
+char *module_flags(struct module *mod, char *buf)
 {
        int bx = 0;
 
@@ -3619,103 +3587,6 @@ static char *module_flags(struct module *mod, char *buf)
        return buf;
 }
 
-#ifdef CONFIG_PROC_FS
-/* Called by the /proc file system to return a list of modules. */
-static void *m_start(struct seq_file *m, loff_t *pos)
-{
-       mutex_lock(&module_mutex);
-       return seq_list_start(&modules, *pos);
-}
-
-static void *m_next(struct seq_file *m, void *p, loff_t *pos)
-{
-       return seq_list_next(p, &modules, pos);
-}
-
-static void m_stop(struct seq_file *m, void *p)
-{
-       mutex_unlock(&module_mutex);
-}
-
-static int m_show(struct seq_file *m, void *p)
-{
-       struct module *mod = list_entry(p, struct module, list);
-       char buf[MODULE_FLAGS_BUF_SIZE];
-       void *value;
-
-       /* We always ignore unformed modules. */
-       if (mod->state == MODULE_STATE_UNFORMED)
-               return 0;
-
-       seq_printf(m, "%s %u",
-                  mod->name, mod->init_layout.size + mod->core_layout.size);
-       print_unload_info(m, mod);
-
-       /* Informative for users. */
-       seq_printf(m, " %s",
-                  mod->state == MODULE_STATE_GOING ? "Unloading" :
-                  mod->state == MODULE_STATE_COMING ? "Loading" :
-                  "Live");
-       /* Used by oprofile and other similar tools. */
-       value = m->private ? NULL : mod->core_layout.base;
-       seq_printf(m, " 0x%px", value);
-
-       /* Taints info */
-       if (mod->taints)
-               seq_printf(m, " %s", module_flags(mod, buf));
-
-       seq_puts(m, "\n");
-       return 0;
-}
-
-/*
- * Format: modulename size refcount deps address
- *
- * Where refcount is a number or -, and deps is a comma-separated list
- * of depends or -.
- */
-static const struct seq_operations modules_op = {
-       .start  = m_start,
-       .next   = m_next,
-       .stop   = m_stop,
-       .show   = m_show
-};
-
-/*
- * This also sets the "private" pointer to non-NULL if the
- * kernel pointers should be hidden (so you can just test
- * "m->private" to see if you should keep the values private).
- *
- * We use the same logic as for /proc/kallsyms.
- */
-static int modules_open(struct inode *inode, struct file *file)
-{
-       int err = seq_open(file, &modules_op);
-
-       if (!err) {
-               struct seq_file *m = file->private_data;
-               m->private = kallsyms_show_value(file->f_cred) ? NULL : (void *)8ul;
-       }
-
-       return err;
-}
-
-static const struct proc_ops modules_proc_ops = {
-       .proc_flags     = PROC_ENTRY_PERMANENT,
-       .proc_open      = modules_open,
-       .proc_read      = seq_read,
-       .proc_lseek     = seq_lseek,
-       .proc_release   = seq_release,
-};
-
-static int __init proc_modules_init(void)
-{
-       proc_create("modules", 0, NULL, &modules_proc_ops);
-       return 0;
-}
-module_init(proc_modules_init);
-#endif
-
 /* Given an address, look for it in the module exception tables. */
 const struct exception_table_entry *search_module_extables(unsigned long addr)
 {
diff --git a/kernel/module/procfs.c b/kernel/module/procfs.c
new file mode 100644 (file)
index 0000000..2717e13
--- /dev/null
@@ -0,0 +1,142 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Module proc support
+ *
+ * Copyright (C) 2008 Alexey Dobriyan
+ */
+
+#include <linux/module.h>
+#include <linux/kallsyms.h>
+#include <linux/mutex.h>
+#include <linux/seq_file.h>
+#include <linux/proc_fs.h>
+#include "internal.h"
+
+#ifdef CONFIG_MODULE_UNLOAD
+static inline void print_unload_info(struct seq_file *m, struct module *mod)
+{
+       struct module_use *use;
+       int printed_something = 0;
+
+       seq_printf(m, " %i ", module_refcount(mod));
+
+       /*
+        * Always include a trailing , so userspace can differentiate
+        * between this and the old multi-field proc format.
+        */
+       list_for_each_entry(use, &mod->source_list, source_list) {
+               printed_something = 1;
+               seq_printf(m, "%s,", use->source->name);
+       }
+
+       if (mod->init && !mod->exit) {
+               printed_something = 1;
+               seq_puts(m, "[permanent],");
+       }
+
+       if (!printed_something)
+               seq_puts(m, "-");
+}
+#else /* !CONFIG_MODULE_UNLOAD */
+static inline void print_unload_info(struct seq_file *m, struct module *mod)
+{
+       /* We don't know the usage count, or what modules are using. */
+       seq_puts(m, " - -");
+}
+#endif /* CONFIG_MODULE_UNLOAD */
+
+/* Called by the /proc file system to return a list of modules. */
+static void *m_start(struct seq_file *m, loff_t *pos)
+{
+       mutex_lock(&module_mutex);
+       return seq_list_start(&modules, *pos);
+}
+
+static void *m_next(struct seq_file *m, void *p, loff_t *pos)
+{
+       return seq_list_next(p, &modules, pos);
+}
+
+static void m_stop(struct seq_file *m, void *p)
+{
+       mutex_unlock(&module_mutex);
+}
+
+static int m_show(struct seq_file *m, void *p)
+{
+       struct module *mod = list_entry(p, struct module, list);
+       char buf[MODULE_FLAGS_BUF_SIZE];
+       void *value;
+
+       /* We always ignore unformed modules. */
+       if (mod->state == MODULE_STATE_UNFORMED)
+               return 0;
+
+       seq_printf(m, "%s %u",
+                  mod->name, mod->init_layout.size + mod->core_layout.size);
+       print_unload_info(m, mod);
+
+       /* Informative for users. */
+       seq_printf(m, " %s",
+                  mod->state == MODULE_STATE_GOING ? "Unloading" :
+                  mod->state == MODULE_STATE_COMING ? "Loading" :
+                  "Live");
+       /* Used by oprofile and other similar tools. */
+       value = m->private ? NULL : mod->core_layout.base;
+       seq_printf(m, " 0x%px", value);
+
+       /* Taints info */
+       if (mod->taints)
+               seq_printf(m, " %s", module_flags(mod, buf));
+
+       seq_puts(m, "\n");
+       return 0;
+}
+
+/*
+ * Format: modulename size refcount deps address
+ *
+ * Where refcount is a number or -, and deps is a comma-separated list
+ * of depends or -.
+ */
+static const struct seq_operations modules_op = {
+       .start  = m_start,
+       .next   = m_next,
+       .stop   = m_stop,
+       .show   = m_show
+};
+
+/*
+ * This also sets the "private" pointer to non-NULL if the
+ * kernel pointers should be hidden (so you can just test
+ * "m->private" to see if you should keep the values private).
+ *
+ * We use the same logic as for /proc/kallsyms.
+ */
+static int modules_open(struct inode *inode, struct file *file)
+{
+       int err = seq_open(file, &modules_op);
+
+       if (!err) {
+               struct seq_file *m = file->private_data;
+
+               m->private = kallsyms_show_value(file->f_cred) ? NULL : (void *)8ul;
+       }
+
+       return err;
+}
+
+static const struct proc_ops modules_proc_ops = {
+       .proc_flags     = PROC_ENTRY_PERMANENT,
+       .proc_open      = modules_open,
+       .proc_read      = seq_read,
+       .proc_lseek     = seq_lseek,
+       .proc_release   = seq_release,
+};
+
+static int __init proc_modules_init(void)
+{
+       proc_create("modules", 0, NULL, &modules_proc_ops);
+       return 0;
+}
+module_init(proc_modules_init);