The MODULE_SYSCTL_TABLE macro emits a struct module_sysctl_table variable
with pointers to a sysctl table's path and entries, and table/entry sizes.

That symbol will be handled by file2alias.c (modpost) with the changes in
mod_devicetable.h and devicetable-offsets.c.

The option macros MODULE_SYSCTL_TABLE_{DISABLE,UNIQUE_ID} can be used on
a per-file basis to disable the macro and change the symbol name pattern.

Signed-off-by: Mauricio Faria de Oliveira <[email protected]>
---
 include/linux/mod_devicetable.h   |  7 +++++++
 include/linux/sysctl.h            | 42 +++++++++++++++++++++++++++++++++++++++
 scripts/mod/devicetable-offsets.c |  6 ++++++
 3 files changed, 55 insertions(+)

diff --git a/include/linux/mod_devicetable.h b/include/linux/mod_devicetable.h
index 
a397213bedace6e81ac600691b3b50ae0f88356b..818a4a53448dba2088e3dbd1ef2c2d4dbb190fcc
 100644
--- a/include/linux/mod_devicetable.h
+++ b/include/linux/mod_devicetable.h
@@ -78,4 +78,11 @@ struct cpu_feature {
        __u16   feature;
 };
 
+struct module_sysctl_table {
+       kernel_ulong_t path;
+       kernel_ulong_t table;
+       __u16 table_size;
+       __u16 entry_size;
+};
+
 #endif /* LINUX_MOD_DEVICETABLE_H */
diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h
index 
e5d7226ab6f5af34a33829883ad5d1b405e19c86..6960fe22c50bfd8a9acc79870e494c2775fa040a
 100644
--- a/include/linux/sysctl.h
+++ b/include/linux/sysctl.h
@@ -293,6 +293,48 @@ struct ctl_table_root {
        int (*permissions)(struct ctl_table_header *head, const struct 
ctl_table *table);
 };
 
+/*
+ * Creates a symbol so file2alias.c can find the sysctl table.
+ *
+ * MODULE_SYSCTL_TABLE() is the sysctl equivalent of MODULE_DEVICE_TABLE(),
+ * with pointers to a sysctl table's path and entries, and table/entry sizes.
+ *
+ * The parameters 'path' and 'table' must be static (e.g., string literal or
+ * static char[]; static struct ctl_table[]) as both are used as initializer
+ * elements for a static struct variable.
+ *
+ * The generated symbol name contains 'table' by default. However, if 'table'
+ * is a struct field (contains '.' or '->'), in order to avoid syntax errors,
+ * define the macro SYSCTL_MODULE_ALIASES_UNIQUE_ID.
+ *
+ * Define the macro SYSCTL_MODULE_ALIASES_DISABLE to disable this.
+ */
+#if defined(CONFIG_SYSCTL_MODULE_ALIASES) && defined(MODULE) &&                
        \
+    !defined(SYSCTL_MODULE_ALIASES_DISABLE)
+
+#include <linux/module.h>
+#include <linux/mod_devicetable.h>
+
+#if defined(SYSCTL_MODULE_ALIASES_UNIQUE_ID)
+#define __MODULE_SYSCTL_TABLE_NAME(table)                                      
\
+       __mod_device_table(sysctl, __UNIQUE_ID)
+#else
+#define __MODULE_SYSCTL_TABLE_NAME(table)                                      
\
+       __mod_device_table(sysctl, table)
+#endif
+
+#define MODULE_SYSCTL_TABLE(path, table)                                       
\
+       static struct module_sysctl_table __used                                
\
+               __MODULE_SYSCTL_TABLE_NAME(table) = {                           
\
+                       (kernel_ulong_t) path,                                  
\
+                       (kernel_ulong_t) table,                                 
\
+                       (u16) sizeof(table),                                    
\
+                       (u16) sizeof(const struct ctl_table)                    
\
+               }
+#else
+#define MODULE_SYSCTL_TABLE(path, table)
+#endif
+
 #define register_sysctl(path, table)   \
        register_sysctl_sz(path, table, ARRAY_SIZE(table))
 
diff --git a/scripts/mod/devicetable-offsets.c 
b/scripts/mod/devicetable-offsets.c
index 
b4178c42d08f50dfaba4d50d5c1d48b8aff88db4..e3b8855e6ebcf8d16f486f71d62900584ee884b1
 100644
--- a/scripts/mod/devicetable-offsets.c
+++ b/scripts/mod/devicetable-offsets.c
@@ -284,5 +284,11 @@ int main(void)
        DEVID(coreboot_device_id);
        DEVID_FIELD(coreboot_device_id, tag);
 
+       DEVID(module_sysctl_table);
+       DEVID_FIELD(module_sysctl_table, path);
+       DEVID_FIELD(module_sysctl_table, table);
+       DEVID_FIELD(module_sysctl_table, table_size);
+       DEVID_FIELD(module_sysctl_table, entry_size);
+
        return 0;
 }

-- 
2.47.3


Reply via email to