diff options
34 files changed, 613 insertions, 68 deletions
diff --git a/.gitignore b/.gitignore index ce2c6348d372..70580bdd352c 100644 --- a/.gitignore +++ b/.gitignore | |||
@@ -32,6 +32,7 @@ | |||
32 | *.lzo | 32 | *.lzo |
33 | *.mod | 33 | *.mod |
34 | *.mod.c | 34 | *.mod.c |
35 | *.ns_deps | ||
35 | *.o | 36 | *.o |
36 | *.o.* | 37 | *.o.* |
37 | *.patch | 38 | *.patch |
diff --git a/Documentation/kbuild/modules.rst b/Documentation/kbuild/modules.rst index 24e763482650..d2ae799237fd 100644 --- a/Documentation/kbuild/modules.rst +++ b/Documentation/kbuild/modules.rst | |||
@@ -470,9 +470,12 @@ build. | |||
470 | 470 | ||
471 | The syntax of the Module.symvers file is:: | 471 | The syntax of the Module.symvers file is:: |
472 | 472 | ||
473 | <CRC> <Symbol> <module> | 473 | <CRC> <Symbol> <Namespace> <Module> <Export Type> |
474 | 474 | ||
475 | 0x2d036834 scsi_remove_host drivers/scsi/scsi_mod | 475 | 0xe1cc2a05 usb_stor_suspend USB_STORAGE drivers/usb/storage/usb-storage EXPORT_SYMBOL_GPL |
476 | |||
477 | The fields are separated by tabs and values may be empty (e.g. | ||
478 | if no namespace is defined for an exported symbol). | ||
476 | 479 | ||
477 | For a kernel build without CONFIG_MODVERSIONS enabled, the CRC | 480 | For a kernel build without CONFIG_MODVERSIONS enabled, the CRC |
478 | would read 0x00000000. | 481 | would read 0x00000000. |
diff --git a/Documentation/kbuild/namespaces.rst b/Documentation/kbuild/namespaces.rst new file mode 100644 index 000000000000..982ed7b568ac --- /dev/null +++ b/Documentation/kbuild/namespaces.rst | |||
@@ -0,0 +1,154 @@ | |||
1 | ================= | ||
2 | Symbol Namespaces | ||
3 | ================= | ||
4 | |||
5 | The following document describes how to use Symbol Namespaces to structure the | ||
6 | export surface of in-kernel symbols exported through the family of | ||
7 | EXPORT_SYMBOL() macros. | ||
8 | |||
9 | .. Table of Contents | ||
10 | |||
11 | === 1 Introduction | ||
12 | === 2 How to define Symbol Namespaces | ||
13 | --- 2.1 Using the EXPORT_SYMBOL macros | ||
14 | --- 2.2 Using the DEFAULT_SYMBOL_NAMESPACE define | ||
15 | === 3 How to use Symbols exported in Namespaces | ||
16 | === 4 Loading Modules that use namespaced Symbols | ||
17 | === 5 Automatically creating MODULE_IMPORT_NS statements | ||
18 | |||
19 | 1. Introduction | ||
20 | =============== | ||
21 | |||
22 | Symbol Namespaces have been introduced as a means to structure the export | ||
23 | surface of the in-kernel API. It allows subsystem maintainers to partition | ||
24 | their exported symbols into separate namespaces. That is useful for | ||
25 | documentation purposes (think of the SUBSYSTEM_DEBUG namespace) as well as for | ||
26 | limiting the availability of a set of symbols for use in other parts of the | ||
27 | kernel. As of today, modules that make use of symbols exported into namespaces, | ||
28 | are required to import the namespace. Otherwise the kernel will, depending on | ||
29 | its configuration, reject loading the module or warn about a missing import. | ||
30 | |||
31 | 2. How to define Symbol Namespaces | ||
32 | ================================== | ||
33 | |||
34 | Symbols can be exported into namespace using different methods. All of them are | ||
35 | changing the way EXPORT_SYMBOL and friends are instrumented to create ksymtab | ||
36 | entries. | ||
37 | |||
38 | 2.1 Using the EXPORT_SYMBOL macros | ||
39 | ================================== | ||
40 | |||
41 | In addition to the macros EXPORT_SYMBOL() and EXPORT_SYMBOL_GPL(), that allow | ||
42 | exporting of kernel symbols to the kernel symbol table, variants of these are | ||
43 | available to export symbols into a certain namespace: EXPORT_SYMBOL_NS() and | ||
44 | EXPORT_SYMBOL_NS_GPL(). They take one additional argument: the namespace. | ||
45 | Please note that due to macro expansion that argument needs to be a | ||
46 | preprocessor symbol. E.g. to export the symbol `usb_stor_suspend` into the | ||
47 | namespace `USB_STORAGE`, use:: | ||
48 | |||
49 | EXPORT_SYMBOL_NS(usb_stor_suspend, USB_STORAGE); | ||
50 | |||
51 | The corresponding ksymtab entry struct `kernel_symbol` will have the member | ||
52 | `namespace` set accordingly. A symbol that is exported without a namespace will | ||
53 | refer to `NULL`. There is no default namespace if none is defined. `modpost` | ||
54 | and kernel/module.c make use the namespace at build time or module load time, | ||
55 | respectively. | ||
56 | |||
57 | 2.2 Using the DEFAULT_SYMBOL_NAMESPACE define | ||
58 | ============================================= | ||
59 | |||
60 | Defining namespaces for all symbols of a subsystem can be very verbose and may | ||
61 | become hard to maintain. Therefore a default define (DEFAULT_SYMBOL_NAMESPACE) | ||
62 | is been provided, that, if set, will become the default for all EXPORT_SYMBOL() | ||
63 | and EXPORT_SYMBOL_GPL() macro expansions that do not specify a namespace. | ||
64 | |||
65 | There are multiple ways of specifying this define and it depends on the | ||
66 | subsystem and the maintainer's preference, which one to use. The first option | ||
67 | is to define the default namespace in the `Makefile` of the subsystem. E.g. to | ||
68 | export all symbols defined in usb-common into the namespace USB_COMMON, add a | ||
69 | line like this to drivers/usb/common/Makefile:: | ||
70 | |||
71 | ccflags-y += -DDEFAULT_SYMBOL_NAMESPACE=USB_COMMON | ||
72 | |||
73 | That will affect all EXPORT_SYMBOL() and EXPORT_SYMBOL_GPL() statements. A | ||
74 | symbol exported with EXPORT_SYMBOL_NS() while this definition is present, will | ||
75 | still be exported into the namespace that is passed as the namespace argument | ||
76 | as this argument has preference over a default symbol namespace. | ||
77 | |||
78 | A second option to define the default namespace is directly in the compilation | ||
79 | unit as preprocessor statement. The above example would then read:: | ||
80 | |||
81 | #undef DEFAULT_SYMBOL_NAMESPACE | ||
82 | #define DEFAULT_SYMBOL_NAMESPACE USB_COMMON | ||
83 | |||
84 | within the corresponding compilation unit before any EXPORT_SYMBOL macro is | ||
85 | used. | ||
86 | |||
87 | 3. How to use Symbols exported in Namespaces | ||
88 | ============================================ | ||
89 | |||
90 | In order to use symbols that are exported into namespaces, kernel modules need | ||
91 | to explicitly import these namespaces. Otherwise the kernel might reject to | ||
92 | load the module. The module code is required to use the macro MODULE_IMPORT_NS | ||
93 | for the namespaces it uses symbols from. E.g. a module using the | ||
94 | usb_stor_suspend symbol from above, needs to import the namespace USB_STORAGE | ||
95 | using a statement like:: | ||
96 | |||
97 | MODULE_IMPORT_NS(USB_STORAGE); | ||
98 | |||
99 | This will create a `modinfo` tag in the module for each imported namespace. | ||
100 | This has the side effect, that the imported namespaces of a module can be | ||
101 | inspected with modinfo:: | ||
102 | |||
103 | $ modinfo drivers/usb/storage/ums-karma.ko | ||
104 | [...] | ||
105 | import_ns: USB_STORAGE | ||
106 | [...] | ||
107 | |||
108 | |||
109 | It is advisable to add the MODULE_IMPORT_NS() statement close to other module | ||
110 | metadata definitions like MODULE_AUTHOR() or MODULE_LICENSE(). Refer to section | ||
111 | 5. for a way to create missing import statements automatically. | ||
112 | |||
113 | 4. Loading Modules that use namespaced Symbols | ||
114 | ============================================== | ||
115 | |||
116 | At module loading time (e.g. `insmod`), the kernel will check each symbol | ||
117 | referenced from the module for its availability and whether the namespace it | ||
118 | might be exported to has been imported by the module. The default behaviour of | ||
119 | the kernel is to reject loading modules that don't specify sufficient imports. | ||
120 | An error will be logged and loading will be failed with EINVAL. In order to | ||
121 | allow loading of modules that don't satisfy this precondition, a configuration | ||
122 | option is available: Setting MODULE_ALLOW_MISSING_NAMESPACE_IMPORTS=y will | ||
123 | enable loading regardless, but will emit a warning. | ||
124 | |||
125 | 5. Automatically creating MODULE_IMPORT_NS statements | ||
126 | ===================================================== | ||
127 | |||
128 | Missing namespaces imports can easily be detected at build time. In fact, | ||
129 | modpost will emit a warning if a module uses a symbol from a namespace | ||
130 | without importing it. | ||
131 | MODULE_IMPORT_NS() statements will usually be added at a definite location | ||
132 | (along with other module meta data). To make the life of module authors (and | ||
133 | subsystem maintainers) easier, a script and make target is available to fixup | ||
134 | missing imports. Fixing missing imports can be done with:: | ||
135 | |||
136 | $ make nsdeps | ||
137 | |||
138 | A typical scenario for module authors would be:: | ||
139 | |||
140 | - write code that depends on a symbol from a not imported namespace | ||
141 | - `make` | ||
142 | - notice the warning of modpost telling about a missing import | ||
143 | - run `make nsdeps` to add the import to the correct code location | ||
144 | |||
145 | For subsystem maintainers introducing a namespace, the steps are very similar. | ||
146 | Again, `make nsdeps` will eventually add the missing namespace imports for | ||
147 | in-tree modules:: | ||
148 | |||
149 | - move or add symbols to a namespace (e.g. with EXPORT_SYMBOL_NS()) | ||
150 | - `make` (preferably with an allmodconfig to cover all in-kernel | ||
151 | modules) | ||
152 | - notice the warning of modpost telling about a missing import | ||
153 | - run `make nsdeps` to add the import to the correct code location | ||
154 | |||
diff --git a/Documentation/kernel-hacking/hacking.rst b/Documentation/kernel-hacking/hacking.rst index 5891a701a159..a3ddb213a5e1 100644 --- a/Documentation/kernel-hacking/hacking.rst +++ b/Documentation/kernel-hacking/hacking.rst | |||
@@ -594,6 +594,24 @@ internal implementation issue, and not really an interface. Some | |||
594 | maintainers and developers may however require EXPORT_SYMBOL_GPL() | 594 | maintainers and developers may however require EXPORT_SYMBOL_GPL() |
595 | when adding any new APIs or functionality. | 595 | when adding any new APIs or functionality. |
596 | 596 | ||
597 | :c:func:`EXPORT_SYMBOL_NS()` | ||
598 | ---------------------------- | ||
599 | |||
600 | Defined in ``include/linux/export.h`` | ||
601 | |||
602 | This is the variant of `EXPORT_SYMBOL()` that allows specifying a symbol | ||
603 | namespace. Symbol Namespaces are documented in | ||
604 | ``Documentation/kbuild/namespaces.rst``. | ||
605 | |||
606 | :c:func:`EXPORT_SYMBOL_NS_GPL()` | ||
607 | -------------------------------- | ||
608 | |||
609 | Defined in ``include/linux/export.h`` | ||
610 | |||
611 | This is the variant of `EXPORT_SYMBOL_GPL()` that allows specifying a symbol | ||
612 | namespace. Symbol Namespaces are documented in | ||
613 | ``Documentation/kbuild/namespaces.rst``. | ||
614 | |||
597 | Routines and Conventions | 615 | Routines and Conventions |
598 | ======================== | 616 | ======================== |
599 | 617 | ||
diff --git a/MAINTAINERS b/MAINTAINERS index 00ace1a989f9..64f63e321fa4 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
@@ -11523,6 +11523,11 @@ S: Maintained | |||
11523 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/wtarreau/nolibc.git | 11523 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/wtarreau/nolibc.git |
11524 | F: tools/include/nolibc/ | 11524 | F: tools/include/nolibc/ |
11525 | 11525 | ||
11526 | NSDEPS | ||
11527 | M: Matthias Maennich <maennich@google.com> | ||
11528 | S: Maintained | ||
11529 | F: scripts/nsdeps | ||
11530 | |||
11526 | NTB AMD DRIVER | 11531 | NTB AMD DRIVER |
11527 | M: Shyam Sundar S K <Shyam-sundar.S-k@amd.com> | 11532 | M: Shyam Sundar S K <Shyam-sundar.S-k@amd.com> |
11528 | L: linux-ntb@googlegroups.com | 11533 | L: linux-ntb@googlegroups.com |
@@ -1498,6 +1498,9 @@ help: | |||
1498 | @echo ' headerdep - Detect inclusion cycles in headers' | 1498 | @echo ' headerdep - Detect inclusion cycles in headers' |
1499 | @echo ' coccicheck - Check with Coccinelle' | 1499 | @echo ' coccicheck - Check with Coccinelle' |
1500 | @echo '' | 1500 | @echo '' |
1501 | @echo 'Tools:' | ||
1502 | @echo ' nsdeps - Generate missing symbol namespace dependencies' | ||
1503 | @echo '' | ||
1501 | @echo 'Kernel selftest:' | 1504 | @echo 'Kernel selftest:' |
1502 | @echo ' kselftest - Build and run kernel selftest (run as root)' | 1505 | @echo ' kselftest - Build and run kernel selftest (run as root)' |
1503 | @echo ' Build, install, and boot kernel before' | 1506 | @echo ' Build, install, and boot kernel before' |
@@ -1679,7 +1682,7 @@ clean: $(clean-dirs) | |||
1679 | -o -name '*.ko.*' \ | 1682 | -o -name '*.ko.*' \ |
1680 | -o -name '*.dtb' -o -name '*.dtb.S' -o -name '*.dt.yaml' \ | 1683 | -o -name '*.dtb' -o -name '*.dtb.S' -o -name '*.dt.yaml' \ |
1681 | -o -name '*.dwo' -o -name '*.lst' \ | 1684 | -o -name '*.dwo' -o -name '*.lst' \ |
1682 | -o -name '*.su' -o -name '*.mod' \ | 1685 | -o -name '*.su' -o -name '*.mod' -o -name '*.ns_deps' \ |
1683 | -o -name '.*.d' -o -name '.*.tmp' -o -name '*.mod.c' \ | 1686 | -o -name '.*.d' -o -name '.*.tmp' -o -name '*.mod.c' \ |
1684 | -o -name '*.lex.c' -o -name '*.tab.[ch]' \ | 1687 | -o -name '*.lex.c' -o -name '*.tab.[ch]' \ |
1685 | -o -name '*.asn1.[ch]' \ | 1688 | -o -name '*.asn1.[ch]' \ |
@@ -1697,6 +1700,15 @@ quiet_cmd_tags = GEN $@ | |||
1697 | tags TAGS cscope gtags: FORCE | 1700 | tags TAGS cscope gtags: FORCE |
1698 | $(call cmd,tags) | 1701 | $(call cmd,tags) |
1699 | 1702 | ||
1703 | # Script to generate missing namespace dependencies | ||
1704 | # --------------------------------------------------------------------------- | ||
1705 | |||
1706 | PHONY += nsdeps | ||
1707 | |||
1708 | nsdeps: modules | ||
1709 | $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modpost nsdeps | ||
1710 | $(Q)$(CONFIG_SHELL) $(srctree)/scripts/$@ | ||
1711 | |||
1700 | # Scripts to check various things for consistency | 1712 | # Scripts to check various things for consistency |
1701 | # --------------------------------------------------------------------------- | 1713 | # --------------------------------------------------------------------------- |
1702 | 1714 | ||
diff --git a/arch/m68k/include/asm/export.h b/arch/m68k/include/asm/export.h index 0af20f48bd07..b53008b67ce1 100644 --- a/arch/m68k/include/asm/export.h +++ b/arch/m68k/include/asm/export.h | |||
@@ -1,3 +1,2 @@ | |||
1 | #define KSYM_ALIGN 2 | ||
2 | #define KCRC_ALIGN 2 | 1 | #define KCRC_ALIGN 2 |
3 | #include <asm-generic/export.h> | 2 | #include <asm-generic/export.h> |
diff --git a/drivers/usb/storage/Makefile b/drivers/usb/storage/Makefile index a67ddcbb4e24..46635fa4a340 100644 --- a/drivers/usb/storage/Makefile +++ b/drivers/usb/storage/Makefile | |||
@@ -8,6 +8,8 @@ | |||
8 | 8 | ||
9 | ccflags-y := -I $(srctree)/drivers/scsi | 9 | ccflags-y := -I $(srctree)/drivers/scsi |
10 | 10 | ||
11 | ccflags-y += -DDEFAULT_SYMBOL_NAMESPACE=USB_STORAGE | ||
12 | |||
11 | obj-$(CONFIG_USB_UAS) += uas.o | 13 | obj-$(CONFIG_USB_UAS) += uas.o |
12 | obj-$(CONFIG_USB_STORAGE) += usb-storage.o | 14 | obj-$(CONFIG_USB_STORAGE) += usb-storage.o |
13 | 15 | ||
diff --git a/drivers/usb/storage/alauda.c b/drivers/usb/storage/alauda.c index 6b8edf6178df..ddab2cd3d2e7 100644 --- a/drivers/usb/storage/alauda.c +++ b/drivers/usb/storage/alauda.c | |||
@@ -36,6 +36,7 @@ | |||
36 | MODULE_DESCRIPTION("Driver for Alauda-based card readers"); | 36 | MODULE_DESCRIPTION("Driver for Alauda-based card readers"); |
37 | MODULE_AUTHOR("Daniel Drake <dsd@gentoo.org>"); | 37 | MODULE_AUTHOR("Daniel Drake <dsd@gentoo.org>"); |
38 | MODULE_LICENSE("GPL"); | 38 | MODULE_LICENSE("GPL"); |
39 | MODULE_IMPORT_NS(USB_STORAGE); | ||
39 | 40 | ||
40 | /* | 41 | /* |
41 | * Status bytes | 42 | * Status bytes |
diff --git a/drivers/usb/storage/cypress_atacb.c b/drivers/usb/storage/cypress_atacb.c index 4825902377eb..a6f3267bbef6 100644 --- a/drivers/usb/storage/cypress_atacb.c +++ b/drivers/usb/storage/cypress_atacb.c | |||
@@ -22,6 +22,7 @@ | |||
22 | MODULE_DESCRIPTION("SAT support for Cypress USB/ATA bridges with ATACB"); | 22 | MODULE_DESCRIPTION("SAT support for Cypress USB/ATA bridges with ATACB"); |
23 | MODULE_AUTHOR("Matthieu Castet <castet.matthieu@free.fr>"); | 23 | MODULE_AUTHOR("Matthieu Castet <castet.matthieu@free.fr>"); |
24 | MODULE_LICENSE("GPL"); | 24 | MODULE_LICENSE("GPL"); |
25 | MODULE_IMPORT_NS(USB_STORAGE); | ||
25 | 26 | ||
26 | /* | 27 | /* |
27 | * The table of devices | 28 | * The table of devices |
diff --git a/drivers/usb/storage/datafab.c b/drivers/usb/storage/datafab.c index 09353be199be..588818483f4b 100644 --- a/drivers/usb/storage/datafab.c +++ b/drivers/usb/storage/datafab.c | |||
@@ -54,6 +54,7 @@ | |||
54 | MODULE_DESCRIPTION("Driver for Datafab USB Compact Flash reader"); | 54 | MODULE_DESCRIPTION("Driver for Datafab USB Compact Flash reader"); |
55 | MODULE_AUTHOR("Jimmie Mayfield <mayfield+datafab@sackheads.org>"); | 55 | MODULE_AUTHOR("Jimmie Mayfield <mayfield+datafab@sackheads.org>"); |
56 | MODULE_LICENSE("GPL"); | 56 | MODULE_LICENSE("GPL"); |
57 | MODULE_IMPORT_NS(USB_STORAGE); | ||
57 | 58 | ||
58 | struct datafab_info { | 59 | struct datafab_info { |
59 | unsigned long sectors; /* total sector count */ | 60 | unsigned long sectors; /* total sector count */ |
diff --git a/drivers/usb/storage/ene_ub6250.c b/drivers/usb/storage/ene_ub6250.c index c26129d5b943..8b1b73065421 100644 --- a/drivers/usb/storage/ene_ub6250.c +++ b/drivers/usb/storage/ene_ub6250.c | |||
@@ -26,6 +26,7 @@ | |||
26 | 26 | ||
27 | MODULE_DESCRIPTION("Driver for ENE UB6250 reader"); | 27 | MODULE_DESCRIPTION("Driver for ENE UB6250 reader"); |
28 | MODULE_LICENSE("GPL"); | 28 | MODULE_LICENSE("GPL"); |
29 | MODULE_IMPORT_NS(USB_STORAGE); | ||
29 | MODULE_FIRMWARE(SD_INIT1_FIRMWARE); | 30 | MODULE_FIRMWARE(SD_INIT1_FIRMWARE); |
30 | MODULE_FIRMWARE(SD_INIT2_FIRMWARE); | 31 | MODULE_FIRMWARE(SD_INIT2_FIRMWARE); |
31 | MODULE_FIRMWARE(SD_RW_FIRMWARE); | 32 | MODULE_FIRMWARE(SD_RW_FIRMWARE); |
diff --git a/drivers/usb/storage/freecom.c b/drivers/usb/storage/freecom.c index 4f542df37a44..34e7eaff1174 100644 --- a/drivers/usb/storage/freecom.c +++ b/drivers/usb/storage/freecom.c | |||
@@ -29,6 +29,7 @@ | |||
29 | MODULE_DESCRIPTION("Driver for Freecom USB/IDE adaptor"); | 29 | MODULE_DESCRIPTION("Driver for Freecom USB/IDE adaptor"); |
30 | MODULE_AUTHOR("David Brown <usb-storage@davidb.org>"); | 30 | MODULE_AUTHOR("David Brown <usb-storage@davidb.org>"); |
31 | MODULE_LICENSE("GPL"); | 31 | MODULE_LICENSE("GPL"); |
32 | MODULE_IMPORT_NS(USB_STORAGE); | ||
32 | 33 | ||
33 | #ifdef CONFIG_USB_STORAGE_DEBUG | 34 | #ifdef CONFIG_USB_STORAGE_DEBUG |
34 | static void pdump(struct us_data *us, void *ibuffer, int length); | 35 | static void pdump(struct us_data *us, void *ibuffer, int length); |
diff --git a/drivers/usb/storage/isd200.c b/drivers/usb/storage/isd200.c index 28e1128d53a4..89f5e33a6e6d 100644 --- a/drivers/usb/storage/isd200.c +++ b/drivers/usb/storage/isd200.c | |||
@@ -53,6 +53,7 @@ | |||
53 | MODULE_DESCRIPTION("Driver for In-System Design, Inc. ISD200 ASIC"); | 53 | MODULE_DESCRIPTION("Driver for In-System Design, Inc. ISD200 ASIC"); |
54 | MODULE_AUTHOR("Björn Stenberg <bjorn@haxx.se>"); | 54 | MODULE_AUTHOR("Björn Stenberg <bjorn@haxx.se>"); |
55 | MODULE_LICENSE("GPL"); | 55 | MODULE_LICENSE("GPL"); |
56 | MODULE_IMPORT_NS(USB_STORAGE); | ||
56 | 57 | ||
57 | static int isd200_Initialization(struct us_data *us); | 58 | static int isd200_Initialization(struct us_data *us); |
58 | 59 | ||
diff --git a/drivers/usb/storage/jumpshot.c b/drivers/usb/storage/jumpshot.c index 917f170c4124..229bf0c1afc9 100644 --- a/drivers/usb/storage/jumpshot.c +++ b/drivers/usb/storage/jumpshot.c | |||
@@ -51,6 +51,7 @@ | |||
51 | MODULE_DESCRIPTION("Driver for Lexar \"Jumpshot\" Compact Flash reader"); | 51 | MODULE_DESCRIPTION("Driver for Lexar \"Jumpshot\" Compact Flash reader"); |
52 | MODULE_AUTHOR("Jimmie Mayfield <mayfield+usb@sackheads.org>"); | 52 | MODULE_AUTHOR("Jimmie Mayfield <mayfield+usb@sackheads.org>"); |
53 | MODULE_LICENSE("GPL"); | 53 | MODULE_LICENSE("GPL"); |
54 | MODULE_IMPORT_NS(USB_STORAGE); | ||
54 | 55 | ||
55 | /* | 56 | /* |
56 | * The table of devices | 57 | * The table of devices |
diff --git a/drivers/usb/storage/karma.c b/drivers/usb/storage/karma.c index 395cf8fb5870..05cec81dcd3f 100644 --- a/drivers/usb/storage/karma.c +++ b/drivers/usb/storage/karma.c | |||
@@ -23,6 +23,7 @@ | |||
23 | MODULE_DESCRIPTION("Driver for Rio Karma"); | 23 | MODULE_DESCRIPTION("Driver for Rio Karma"); |
24 | MODULE_AUTHOR("Bob Copeland <me@bobcopeland.com>, Keith Bennett <keith@mcs.st-and.ac.uk>"); | 24 | MODULE_AUTHOR("Bob Copeland <me@bobcopeland.com>, Keith Bennett <keith@mcs.st-and.ac.uk>"); |
25 | MODULE_LICENSE("GPL"); | 25 | MODULE_LICENSE("GPL"); |
26 | MODULE_IMPORT_NS(USB_STORAGE); | ||
26 | 27 | ||
27 | #define RIO_PREFIX "RIOP\x00" | 28 | #define RIO_PREFIX "RIOP\x00" |
28 | #define RIO_PREFIX_LEN 5 | 29 | #define RIO_PREFIX_LEN 5 |
diff --git a/drivers/usb/storage/onetouch.c b/drivers/usb/storage/onetouch.c index 39a5009a41a6..a989fe930e21 100644 --- a/drivers/usb/storage/onetouch.c +++ b/drivers/usb/storage/onetouch.c | |||
@@ -25,6 +25,7 @@ | |||
25 | MODULE_DESCRIPTION("Maxtor USB OneTouch hard drive button driver"); | 25 | MODULE_DESCRIPTION("Maxtor USB OneTouch hard drive button driver"); |
26 | MODULE_AUTHOR("Nick Sillik <n.sillik@temple.edu>"); | 26 | MODULE_AUTHOR("Nick Sillik <n.sillik@temple.edu>"); |
27 | MODULE_LICENSE("GPL"); | 27 | MODULE_LICENSE("GPL"); |
28 | MODULE_IMPORT_NS(USB_STORAGE); | ||
28 | 29 | ||
29 | #define ONETOUCH_PKT_LEN 0x02 | 30 | #define ONETOUCH_PKT_LEN 0x02 |
30 | #define ONETOUCH_BUTTON KEY_PROG1 | 31 | #define ONETOUCH_BUTTON KEY_PROG1 |
diff --git a/drivers/usb/storage/realtek_cr.c b/drivers/usb/storage/realtek_cr.c index 1d9ce9cbc831..3789698d9d3c 100644 --- a/drivers/usb/storage/realtek_cr.c +++ b/drivers/usb/storage/realtek_cr.c | |||
@@ -35,6 +35,7 @@ | |||
35 | MODULE_DESCRIPTION("Driver for Realtek USB Card Reader"); | 35 | MODULE_DESCRIPTION("Driver for Realtek USB Card Reader"); |
36 | MODULE_AUTHOR("wwang <wei_wang@realsil.com.cn>"); | 36 | MODULE_AUTHOR("wwang <wei_wang@realsil.com.cn>"); |
37 | MODULE_LICENSE("GPL"); | 37 | MODULE_LICENSE("GPL"); |
38 | MODULE_IMPORT_NS(USB_STORAGE); | ||
38 | 39 | ||
39 | static int auto_delink_en = 1; | 40 | static int auto_delink_en = 1; |
40 | module_param(auto_delink_en, int, S_IRUGO | S_IWUSR); | 41 | module_param(auto_delink_en, int, S_IRUGO | S_IWUSR); |
diff --git a/drivers/usb/storage/sddr09.c b/drivers/usb/storage/sddr09.c index bc9da736bdfc..51bcd4a43690 100644 --- a/drivers/usb/storage/sddr09.c +++ b/drivers/usb/storage/sddr09.c | |||
@@ -47,6 +47,7 @@ | |||
47 | MODULE_DESCRIPTION("Driver for SanDisk SDDR-09 SmartMedia reader"); | 47 | MODULE_DESCRIPTION("Driver for SanDisk SDDR-09 SmartMedia reader"); |
48 | MODULE_AUTHOR("Andries Brouwer <aeb@cwi.nl>, Robert Baruch <autophile@starband.net>"); | 48 | MODULE_AUTHOR("Andries Brouwer <aeb@cwi.nl>, Robert Baruch <autophile@starband.net>"); |
49 | MODULE_LICENSE("GPL"); | 49 | MODULE_LICENSE("GPL"); |
50 | MODULE_IMPORT_NS(USB_STORAGE); | ||
50 | 51 | ||
51 | static int usb_stor_sddr09_dpcm_init(struct us_data *us); | 52 | static int usb_stor_sddr09_dpcm_init(struct us_data *us); |
52 | static int sddr09_transport(struct scsi_cmnd *srb, struct us_data *us); | 53 | static int sddr09_transport(struct scsi_cmnd *srb, struct us_data *us); |
diff --git a/drivers/usb/storage/sddr55.c b/drivers/usb/storage/sddr55.c index b8527c55335b..ba955d65eb0e 100644 --- a/drivers/usb/storage/sddr55.c +++ b/drivers/usb/storage/sddr55.c | |||
@@ -29,6 +29,7 @@ | |||
29 | MODULE_DESCRIPTION("Driver for SanDisk SDDR-55 SmartMedia reader"); | 29 | MODULE_DESCRIPTION("Driver for SanDisk SDDR-55 SmartMedia reader"); |
30 | MODULE_AUTHOR("Simon Munton"); | 30 | MODULE_AUTHOR("Simon Munton"); |
31 | MODULE_LICENSE("GPL"); | 31 | MODULE_LICENSE("GPL"); |
32 | MODULE_IMPORT_NS(USB_STORAGE); | ||
32 | 33 | ||
33 | /* | 34 | /* |
34 | * The table of devices | 35 | * The table of devices |
diff --git a/drivers/usb/storage/shuttle_usbat.c b/drivers/usb/storage/shuttle_usbat.c index 854498e1012c..54aa1392c9ca 100644 --- a/drivers/usb/storage/shuttle_usbat.c +++ b/drivers/usb/storage/shuttle_usbat.c | |||
@@ -48,6 +48,7 @@ | |||
48 | MODULE_DESCRIPTION("Driver for SCM Microsystems (a.k.a. Shuttle) USB-ATAPI cable"); | 48 | MODULE_DESCRIPTION("Driver for SCM Microsystems (a.k.a. Shuttle) USB-ATAPI cable"); |
49 | MODULE_AUTHOR("Daniel Drake <dsd@gentoo.org>, Robert Baruch <autophile@starband.net>"); | 49 | MODULE_AUTHOR("Daniel Drake <dsd@gentoo.org>, Robert Baruch <autophile@starband.net>"); |
50 | MODULE_LICENSE("GPL"); | 50 | MODULE_LICENSE("GPL"); |
51 | MODULE_IMPORT_NS(USB_STORAGE); | ||
51 | 52 | ||
52 | /* Supported device types */ | 53 | /* Supported device types */ |
53 | #define USBAT_DEV_HP8200 0x01 | 54 | #define USBAT_DEV_HP8200 0x01 |
diff --git a/drivers/usb/storage/uas.c b/drivers/usb/storage/uas.c index 047c5922618f..bf80d6f81f58 100644 --- a/drivers/usb/storage/uas.c +++ b/drivers/usb/storage/uas.c | |||
@@ -1219,5 +1219,6 @@ static struct usb_driver uas_driver = { | |||
1219 | module_usb_driver(uas_driver); | 1219 | module_usb_driver(uas_driver); |
1220 | 1220 | ||
1221 | MODULE_LICENSE("GPL"); | 1221 | MODULE_LICENSE("GPL"); |
1222 | MODULE_IMPORT_NS(USB_STORAGE); | ||
1222 | MODULE_AUTHOR( | 1223 | MODULE_AUTHOR( |
1223 | "Hans de Goede <hdegoede@redhat.com>, Matthew Wilcox and Sarah Sharp"); | 1224 | "Hans de Goede <hdegoede@redhat.com>, Matthew Wilcox and Sarah Sharp"); |
diff --git a/include/asm-generic/export.h b/include/asm-generic/export.h index 294d6ae785d4..fa577978fbbd 100644 --- a/include/asm-generic/export.h +++ b/include/asm-generic/export.h | |||
@@ -4,26 +4,24 @@ | |||
4 | #ifndef KSYM_FUNC | 4 | #ifndef KSYM_FUNC |
5 | #define KSYM_FUNC(x) x | 5 | #define KSYM_FUNC(x) x |
6 | #endif | 6 | #endif |
7 | #ifdef CONFIG_64BIT | 7 | #ifdef CONFIG_HAVE_ARCH_PREL32_RELOCATIONS |
8 | #ifndef KSYM_ALIGN | 8 | #define KSYM_ALIGN 4 |
9 | #elif defined(CONFIG_64BIT) | ||
9 | #define KSYM_ALIGN 8 | 10 | #define KSYM_ALIGN 8 |
10 | #endif | ||
11 | #else | 11 | #else |
12 | #ifndef KSYM_ALIGN | ||
13 | #define KSYM_ALIGN 4 | 12 | #define KSYM_ALIGN 4 |
14 | #endif | 13 | #endif |
15 | #endif | ||
16 | #ifndef KCRC_ALIGN | 14 | #ifndef KCRC_ALIGN |
17 | #define KCRC_ALIGN 4 | 15 | #define KCRC_ALIGN 4 |
18 | #endif | 16 | #endif |
19 | 17 | ||
20 | .macro __put, val, name | 18 | .macro __put, val, name |
21 | #ifdef CONFIG_HAVE_ARCH_PREL32_RELOCATIONS | 19 | #ifdef CONFIG_HAVE_ARCH_PREL32_RELOCATIONS |
22 | .long \val - ., \name - . | 20 | .long \val - ., \name - ., 0 |
23 | #elif defined(CONFIG_64BIT) | 21 | #elif defined(CONFIG_64BIT) |
24 | .quad \val, \name | 22 | .quad \val, \name, 0 |
25 | #else | 23 | #else |
26 | .long \val, \name | 24 | .long \val, \name, 0 |
27 | #endif | 25 | #endif |
28 | .endm | 26 | .endm |
29 | 27 | ||
@@ -57,7 +55,6 @@ __kcrctab_\name: | |||
57 | #endif | 55 | #endif |
58 | #endif | 56 | #endif |
59 | .endm | 57 | .endm |
60 | #undef __put | ||
61 | 58 | ||
62 | #if defined(CONFIG_TRIM_UNUSED_KSYMS) | 59 | #if defined(CONFIG_TRIM_UNUSED_KSYMS) |
63 | 60 | ||
diff --git a/include/linux/export.h b/include/linux/export.h index 7d8c112a8b61..95f55b7f83a0 100644 --- a/include/linux/export.h +++ b/include/linux/export.h | |||
@@ -18,6 +18,8 @@ extern struct module __this_module; | |||
18 | #define THIS_MODULE ((struct module *)0) | 18 | #define THIS_MODULE ((struct module *)0) |
19 | #endif | 19 | #endif |
20 | 20 | ||
21 | #define NS_SEPARATOR "." | ||
22 | |||
21 | #ifdef CONFIG_MODVERSIONS | 23 | #ifdef CONFIG_MODVERSIONS |
22 | /* Mark the CRC weak since genksyms apparently decides not to | 24 | /* Mark the CRC weak since genksyms apparently decides not to |
23 | * generate a checksums for some symbols */ | 25 | * generate a checksums for some symbols */ |
@@ -26,13 +28,13 @@ extern struct module __this_module; | |||
26 | asm(" .section \"___kcrctab" sec "+" #sym "\", \"a\" \n" \ | 28 | asm(" .section \"___kcrctab" sec "+" #sym "\", \"a\" \n" \ |
27 | " .weak __crc_" #sym " \n" \ | 29 | " .weak __crc_" #sym " \n" \ |
28 | " .long __crc_" #sym " - . \n" \ | 30 | " .long __crc_" #sym " - . \n" \ |
29 | " .previous \n"); | 31 | " .previous \n") |
30 | #else | 32 | #else |
31 | #define __CRC_SYMBOL(sym, sec) \ | 33 | #define __CRC_SYMBOL(sym, sec) \ |
32 | asm(" .section \"___kcrctab" sec "+" #sym "\", \"a\" \n" \ | 34 | asm(" .section \"___kcrctab" sec "+" #sym "\", \"a\" \n" \ |
33 | " .weak __crc_" #sym " \n" \ | 35 | " .weak __crc_" #sym " \n" \ |
34 | " .long __crc_" #sym " \n" \ | 36 | " .long __crc_" #sym " \n" \ |
35 | " .previous \n"); | 37 | " .previous \n") |
36 | #endif | 38 | #endif |
37 | #else | 39 | #else |
38 | #define __CRC_SYMBOL(sym, sec) | 40 | #define __CRC_SYMBOL(sym, sec) |
@@ -46,44 +48,77 @@ extern struct module __this_module; | |||
46 | * absolute relocations that require runtime processing on relocatable | 48 | * absolute relocations that require runtime processing on relocatable |
47 | * kernels. | 49 | * kernels. |
48 | */ | 50 | */ |
51 | #define __KSYMTAB_ENTRY_NS(sym, sec, ns) \ | ||
52 | __ADDRESSABLE(sym) \ | ||
53 | asm(" .section \"___ksymtab" sec "+" #sym "\", \"a\" \n" \ | ||
54 | " .balign 4 \n" \ | ||
55 | "__ksymtab_" #sym NS_SEPARATOR #ns ": \n" \ | ||
56 | " .long " #sym "- . \n" \ | ||
57 | " .long __kstrtab_" #sym "- . \n" \ | ||
58 | " .long __kstrtab_ns_" #sym "- . \n" \ | ||
59 | " .previous \n") | ||
60 | |||
49 | #define __KSYMTAB_ENTRY(sym, sec) \ | 61 | #define __KSYMTAB_ENTRY(sym, sec) \ |
50 | __ADDRESSABLE(sym) \ | 62 | __ADDRESSABLE(sym) \ |
51 | asm(" .section \"___ksymtab" sec "+" #sym "\", \"a\" \n" \ | 63 | asm(" .section \"___ksymtab" sec "+" #sym "\", \"a\" \n" \ |
52 | " .balign 8 \n" \ | 64 | " .balign 4 \n" \ |
53 | "__ksymtab_" #sym ": \n" \ | 65 | "__ksymtab_" #sym ": \n" \ |
54 | " .long " #sym "- . \n" \ | 66 | " .long " #sym "- . \n" \ |
55 | " .long __kstrtab_" #sym "- . \n" \ | 67 | " .long __kstrtab_" #sym "- . \n" \ |
68 | " .long 0 \n" \ | ||
56 | " .previous \n") | 69 | " .previous \n") |
57 | 70 | ||
58 | struct kernel_symbol { | 71 | struct kernel_symbol { |
59 | int value_offset; | 72 | int value_offset; |
60 | int name_offset; | 73 | int name_offset; |
74 | int namespace_offset; | ||
61 | }; | 75 | }; |
62 | #else | 76 | #else |
77 | #define __KSYMTAB_ENTRY_NS(sym, sec, ns) \ | ||
78 | static const struct kernel_symbol __ksymtab_##sym##__##ns \ | ||
79 | asm("__ksymtab_" #sym NS_SEPARATOR #ns) \ | ||
80 | __attribute__((section("___ksymtab" sec "+" #sym), used)) \ | ||
81 | __aligned(sizeof(void *)) \ | ||
82 | = { (unsigned long)&sym, __kstrtab_##sym, __kstrtab_ns_##sym } | ||
83 | |||
63 | #define __KSYMTAB_ENTRY(sym, sec) \ | 84 | #define __KSYMTAB_ENTRY(sym, sec) \ |
64 | static const struct kernel_symbol __ksymtab_##sym \ | 85 | static const struct kernel_symbol __ksymtab_##sym \ |
86 | asm("__ksymtab_" #sym) \ | ||
65 | __attribute__((section("___ksymtab" sec "+" #sym), used)) \ | 87 | __attribute__((section("___ksymtab" sec "+" #sym), used)) \ |
66 | = { (unsigned long)&sym, __kstrtab_##sym } | 88 | __aligned(sizeof(void *)) \ |
89 | = { (unsigned long)&sym, __kstrtab_##sym, NULL } | ||
67 | 90 | ||
68 | struct kernel_symbol { | 91 | struct kernel_symbol { |
69 | unsigned long value; | 92 | unsigned long value; |
70 | const char *name; | 93 | const char *name; |
94 | const char *namespace; | ||
71 | }; | 95 | }; |
72 | #endif | 96 | #endif |
73 | 97 | ||
74 | #ifdef __GENKSYMS__ | 98 | #ifdef __GENKSYMS__ |
75 | 99 | ||
76 | #define ___EXPORT_SYMBOL(sym, sec) __GENKSYMS_EXPORT_SYMBOL(sym) | 100 | #define ___EXPORT_SYMBOL(sym,sec) __GENKSYMS_EXPORT_SYMBOL(sym) |
101 | #define ___EXPORT_SYMBOL_NS(sym,sec,ns) __GENKSYMS_EXPORT_SYMBOL(sym) | ||
77 | 102 | ||
78 | #else | 103 | #else |
79 | 104 | ||
80 | /* For every exported symbol, place a struct in the __ksymtab section */ | 105 | #define ___export_symbol_common(sym, sec) \ |
81 | #define ___EXPORT_SYMBOL(sym, sec) \ | ||
82 | extern typeof(sym) sym; \ | 106 | extern typeof(sym) sym; \ |
83 | __CRC_SYMBOL(sym, sec) \ | 107 | __CRC_SYMBOL(sym, sec); \ |
84 | static const char __kstrtab_##sym[] \ | 108 | static const char __kstrtab_##sym[] \ |
85 | __attribute__((section("__ksymtab_strings"), used, aligned(1))) \ | 109 | __attribute__((section("__ksymtab_strings"), used, aligned(1))) \ |
86 | = #sym; \ | 110 | = #sym \ |
111 | |||
112 | /* For every exported symbol, place a struct in the __ksymtab section */ | ||
113 | #define ___EXPORT_SYMBOL_NS(sym, sec, ns) \ | ||
114 | ___export_symbol_common(sym, sec); \ | ||
115 | static const char __kstrtab_ns_##sym[] \ | ||
116 | __attribute__((section("__ksymtab_strings"), used, aligned(1))) \ | ||
117 | = #ns; \ | ||
118 | __KSYMTAB_ENTRY_NS(sym, sec, ns) | ||
119 | |||
120 | #define ___EXPORT_SYMBOL(sym, sec) \ | ||
121 | ___export_symbol_common(sym, sec); \ | ||
87 | __KSYMTAB_ENTRY(sym, sec) | 122 | __KSYMTAB_ENTRY(sym, sec) |
88 | 123 | ||
89 | #endif | 124 | #endif |
@@ -95,6 +130,7 @@ struct kernel_symbol { | |||
95 | * be reused in other execution contexts such as the UEFI stub or the | 130 | * be reused in other execution contexts such as the UEFI stub or the |
96 | * decompressor. | 131 | * decompressor. |
97 | */ | 132 | */ |
133 | #define __EXPORT_SYMBOL_NS(sym, sec, ns) | ||
98 | #define __EXPORT_SYMBOL(sym, sec) | 134 | #define __EXPORT_SYMBOL(sym, sec) |
99 | 135 | ||
100 | #elif defined(CONFIG_TRIM_UNUSED_KSYMS) | 136 | #elif defined(CONFIG_TRIM_UNUSED_KSYMS) |
@@ -121,15 +157,35 @@ struct kernel_symbol { | |||
121 | #define __cond_export_sym_1(sym, sec) ___EXPORT_SYMBOL(sym, sec) | 157 | #define __cond_export_sym_1(sym, sec) ___EXPORT_SYMBOL(sym, sec) |
122 | #define __cond_export_sym_0(sym, sec) /* nothing */ | 158 | #define __cond_export_sym_0(sym, sec) /* nothing */ |
123 | 159 | ||
160 | #define __EXPORT_SYMBOL_NS(sym, sec, ns) \ | ||
161 | __ksym_marker(sym); \ | ||
162 | __cond_export_ns_sym(sym, sec, ns, __is_defined(__KSYM_##sym)) | ||
163 | #define __cond_export_ns_sym(sym, sec, ns, conf) \ | ||
164 | ___cond_export_ns_sym(sym, sec, ns, conf) | ||
165 | #define ___cond_export_ns_sym(sym, sec, ns, enabled) \ | ||
166 | __cond_export_ns_sym_##enabled(sym, sec, ns) | ||
167 | #define __cond_export_ns_sym_1(sym, sec, ns) ___EXPORT_SYMBOL_NS(sym, sec, ns) | ||
168 | #define __cond_export_ns_sym_0(sym, sec, ns) /* nothing */ | ||
169 | |||
124 | #else | 170 | #else |
125 | 171 | ||
126 | #define __EXPORT_SYMBOL(sym, sec) ___EXPORT_SYMBOL(sym, sec) | 172 | #define __EXPORT_SYMBOL_NS(sym,sec,ns) ___EXPORT_SYMBOL_NS(sym,sec,ns) |
173 | #define __EXPORT_SYMBOL(sym,sec) ___EXPORT_SYMBOL(sym,sec) | ||
127 | 174 | ||
128 | #endif /* CONFIG_MODULES */ | 175 | #endif /* CONFIG_MODULES */ |
129 | 176 | ||
177 | #ifdef DEFAULT_SYMBOL_NAMESPACE | ||
178 | #undef __EXPORT_SYMBOL | ||
179 | #define __EXPORT_SYMBOL(sym, sec) \ | ||
180 | __EXPORT_SYMBOL_NS(sym, sec, DEFAULT_SYMBOL_NAMESPACE) | ||
181 | #endif | ||
182 | |||
130 | #define EXPORT_SYMBOL(sym) __EXPORT_SYMBOL(sym, "") | 183 | #define EXPORT_SYMBOL(sym) __EXPORT_SYMBOL(sym, "") |
131 | #define EXPORT_SYMBOL_GPL(sym) __EXPORT_SYMBOL(sym, "_gpl") | 184 | #define EXPORT_SYMBOL_GPL(sym) __EXPORT_SYMBOL(sym, "_gpl") |
132 | #define EXPORT_SYMBOL_GPL_FUTURE(sym) __EXPORT_SYMBOL(sym, "_gpl_future") | 185 | #define EXPORT_SYMBOL_GPL_FUTURE(sym) __EXPORT_SYMBOL(sym, "_gpl_future") |
186 | #define EXPORT_SYMBOL_NS(sym, ns) __EXPORT_SYMBOL_NS(sym, "", ns) | ||
187 | #define EXPORT_SYMBOL_NS_GPL(sym, ns) __EXPORT_SYMBOL_NS(sym, "_gpl", ns) | ||
188 | |||
133 | #ifdef CONFIG_UNUSED_SYMBOLS | 189 | #ifdef CONFIG_UNUSED_SYMBOLS |
134 | #define EXPORT_UNUSED_SYMBOL(sym) __EXPORT_SYMBOL(sym, "_unused") | 190 | #define EXPORT_UNUSED_SYMBOL(sym) __EXPORT_SYMBOL(sym, "_unused") |
135 | #define EXPORT_UNUSED_SYMBOL_GPL(sym) __EXPORT_SYMBOL(sym, "_unused_gpl") | 191 | #define EXPORT_UNUSED_SYMBOL_GPL(sym) __EXPORT_SYMBOL(sym, "_unused_gpl") |
diff --git a/include/linux/module.h b/include/linux/module.h index 1455812dd325..b3611e749f72 100644 --- a/include/linux/module.h +++ b/include/linux/module.h | |||
@@ -280,6 +280,8 @@ struct notifier_block; | |||
280 | 280 | ||
281 | #ifdef CONFIG_MODULES | 281 | #ifdef CONFIG_MODULES |
282 | 282 | ||
283 | #define MODULE_IMPORT_NS(ns) MODULE_INFO(import_ns, #ns) | ||
284 | |||
283 | extern int modules_disabled; /* for sysctl */ | 285 | extern int modules_disabled; /* for sysctl */ |
284 | /* Get/put a kernel symbol (calls must be symmetric) */ | 286 | /* Get/put a kernel symbol (calls must be symmetric) */ |
285 | void *__symbol_get(const char *symbol); | 287 | void *__symbol_get(const char *symbol); |
diff --git a/init/Kconfig b/init/Kconfig index 058ba4e74250..57123594a7ca 100644 --- a/init/Kconfig +++ b/init/Kconfig | |||
@@ -2047,7 +2047,6 @@ config MODULE_SRCVERSION_ALL | |||
2047 | 2047 | ||
2048 | config MODULE_SIG | 2048 | config MODULE_SIG |
2049 | bool "Module signature verification" | 2049 | bool "Module signature verification" |
2050 | depends on MODULES | ||
2051 | select SYSTEM_DATA_VERIFICATION | 2050 | select SYSTEM_DATA_VERIFICATION |
2052 | help | 2051 | help |
2053 | Check modules for valid signatures upon load: the signature | 2052 | Check modules for valid signatures upon load: the signature |
@@ -2124,7 +2123,6 @@ config MODULE_SIG_HASH | |||
2124 | 2123 | ||
2125 | config MODULE_COMPRESS | 2124 | config MODULE_COMPRESS |
2126 | bool "Compress modules on installation" | 2125 | bool "Compress modules on installation" |
2127 | depends on MODULES | ||
2128 | help | 2126 | help |
2129 | 2127 | ||
2130 | Compresses kernel modules when 'make modules_install' is run; gzip or | 2128 | Compresses kernel modules when 'make modules_install' is run; gzip or |
@@ -2160,9 +2158,38 @@ config MODULE_COMPRESS_XZ | |||
2160 | 2158 | ||
2161 | endchoice | 2159 | endchoice |
2162 | 2160 | ||
2161 | config MODULE_ALLOW_MISSING_NAMESPACE_IMPORTS | ||
2162 | bool "Allow loading of modules with missing namespace imports" | ||
2163 | help | ||
2164 | Symbols exported with EXPORT_SYMBOL_NS*() are considered exported in | ||
2165 | a namespace. A module that makes use of a symbol exported with such a | ||
2166 | namespace is required to import the namespace via MODULE_IMPORT_NS(). | ||
2167 | There is no technical reason to enforce correct namespace imports, | ||
2168 | but it creates consistency between symbols defining namespaces and | ||
2169 | users importing namespaces they make use of. This option relaxes this | ||
2170 | requirement and lifts the enforcement when loading a module. | ||
2171 | |||
2172 | If unsure, say N. | ||
2173 | |||
2174 | config UNUSED_SYMBOLS | ||
2175 | bool "Enable unused/obsolete exported symbols" | ||
2176 | default y if X86 | ||
2177 | help | ||
2178 | Unused but exported symbols make the kernel needlessly bigger. For | ||
2179 | that reason most of these unused exports will soon be removed. This | ||
2180 | option is provided temporarily to provide a transition period in case | ||
2181 | some external kernel module needs one of these symbols anyway. If you | ||
2182 | encounter such a case in your module, consider if you are actually | ||
2183 | using the right API. (rationale: since nobody in the kernel is using | ||
2184 | this in a module, there is a pretty good chance it's actually the | ||
2185 | wrong interface to use). If you really need the symbol, please send a | ||
2186 | mail to the linux kernel mailing list mentioning the symbol and why | ||
2187 | you really need it, and what the merge plan to the mainline kernel for | ||
2188 | your module is. | ||
2189 | |||
2163 | config TRIM_UNUSED_KSYMS | 2190 | config TRIM_UNUSED_KSYMS |
2164 | bool "Trim unused exported kernel symbols" | 2191 | bool "Trim unused exported kernel symbols" |
2165 | depends on MODULES && !UNUSED_SYMBOLS | 2192 | depends on !UNUSED_SYMBOLS |
2166 | help | 2193 | help |
2167 | The kernel and some modules make many symbols available for | 2194 | The kernel and some modules make many symbols available for |
2168 | other modules to use via EXPORT_SYMBOL() and variants. Depending | 2195 | other modules to use via EXPORT_SYMBOL() and variants. Depending |
diff --git a/kernel/module.c b/kernel/module.c index 9ee93421269c..32873bcce738 100644 --- a/kernel/module.c +++ b/kernel/module.c | |||
@@ -544,12 +544,20 @@ static const char *kernel_symbol_name(const struct kernel_symbol *sym) | |||
544 | #endif | 544 | #endif |
545 | } | 545 | } |
546 | 546 | ||
547 | static int cmp_name(const void *va, const void *vb) | 547 | static const char *kernel_symbol_namespace(const struct kernel_symbol *sym) |
548 | { | 548 | { |
549 | const char *a; | 549 | #ifdef CONFIG_HAVE_ARCH_PREL32_RELOCATIONS |
550 | const struct kernel_symbol *b; | 550 | if (!sym->namespace_offset) |
551 | a = va; b = vb; | 551 | return NULL; |
552 | return strcmp(a, kernel_symbol_name(b)); | 552 | return offset_to_ptr(&sym->namespace_offset); |
553 | #else | ||
554 | return sym->namespace; | ||
555 | #endif | ||
556 | } | ||
557 | |||
558 | static int cmp_name(const void *name, const void *sym) | ||
559 | { | ||
560 | return strcmp(name, kernel_symbol_name(sym)); | ||
553 | } | 561 | } |
554 | 562 | ||
555 | static bool find_exported_symbol_in_section(const struct symsearch *syms, | 563 | static bool find_exported_symbol_in_section(const struct symsearch *syms, |
@@ -1379,6 +1387,41 @@ static inline int same_magic(const char *amagic, const char *bmagic, | |||
1379 | } | 1387 | } |
1380 | #endif /* CONFIG_MODVERSIONS */ | 1388 | #endif /* CONFIG_MODVERSIONS */ |
1381 | 1389 | ||
1390 | static char *get_modinfo(const struct load_info *info, const char *tag); | ||
1391 | static char *get_next_modinfo(const struct load_info *info, const char *tag, | ||
1392 | char *prev); | ||
1393 | |||
1394 | static int verify_namespace_is_imported(const struct load_info *info, | ||
1395 | const struct kernel_symbol *sym, | ||
1396 | struct module *mod) | ||
1397 | { | ||
1398 | const char *namespace; | ||
1399 | char *imported_namespace; | ||
1400 | |||
1401 | namespace = kernel_symbol_namespace(sym); | ||
1402 | if (namespace) { | ||
1403 | imported_namespace = get_modinfo(info, "import_ns"); | ||
1404 | while (imported_namespace) { | ||
1405 | if (strcmp(namespace, imported_namespace) == 0) | ||
1406 | return 0; | ||
1407 | imported_namespace = get_next_modinfo( | ||
1408 | info, "import_ns", imported_namespace); | ||
1409 | } | ||
1410 | #ifdef CONFIG_MODULE_ALLOW_MISSING_NAMESPACE_IMPORTS | ||
1411 | pr_warn( | ||
1412 | #else | ||
1413 | pr_err( | ||
1414 | #endif | ||
1415 | "%s: module uses symbol (%s) from namespace %s, but does not import it.\n", | ||
1416 | mod->name, kernel_symbol_name(sym), namespace); | ||
1417 | #ifndef CONFIG_MODULE_ALLOW_MISSING_NAMESPACE_IMPORTS | ||
1418 | return -EINVAL; | ||
1419 | #endif | ||
1420 | } | ||
1421 | return 0; | ||
1422 | } | ||
1423 | |||
1424 | |||
1382 | /* Resolve a symbol for this module. I.e. if we find one, record usage. */ | 1425 | /* Resolve a symbol for this module. I.e. if we find one, record usage. */ |
1383 | static const struct kernel_symbol *resolve_symbol(struct module *mod, | 1426 | static const struct kernel_symbol *resolve_symbol(struct module *mod, |
1384 | const struct load_info *info, | 1427 | const struct load_info *info, |
@@ -1407,6 +1450,12 @@ static const struct kernel_symbol *resolve_symbol(struct module *mod, | |||
1407 | goto getname; | 1450 | goto getname; |
1408 | } | 1451 | } |
1409 | 1452 | ||
1453 | err = verify_namespace_is_imported(info, sym, mod); | ||
1454 | if (err) { | ||
1455 | sym = ERR_PTR(err); | ||
1456 | goto getname; | ||
1457 | } | ||
1458 | |||
1410 | err = ref_module(mod, owner); | 1459 | err = ref_module(mod, owner); |
1411 | if (err) { | 1460 | if (err) { |
1412 | sym = ERR_PTR(err); | 1461 | sym = ERR_PTR(err); |
@@ -2481,7 +2530,8 @@ static char *next_string(char *string, unsigned long *secsize) | |||
2481 | return string; | 2530 | return string; |
2482 | } | 2531 | } |
2483 | 2532 | ||
2484 | static char *get_modinfo(struct load_info *info, const char *tag) | 2533 | static char *get_next_modinfo(const struct load_info *info, const char *tag, |
2534 | char *prev) | ||
2485 | { | 2535 | { |
2486 | char *p; | 2536 | char *p; |
2487 | unsigned int taglen = strlen(tag); | 2537 | unsigned int taglen = strlen(tag); |
@@ -2492,13 +2542,25 @@ static char *get_modinfo(struct load_info *info, const char *tag) | |||
2492 | * get_modinfo() calls made before rewrite_section_headers() | 2542 | * get_modinfo() calls made before rewrite_section_headers() |
2493 | * must use sh_offset, as sh_addr isn't set! | 2543 | * must use sh_offset, as sh_addr isn't set! |
2494 | */ | 2544 | */ |
2495 | for (p = (char *)info->hdr + infosec->sh_offset; p; p = next_string(p, &size)) { | 2545 | char *modinfo = (char *)info->hdr + infosec->sh_offset; |
2546 | |||
2547 | if (prev) { | ||
2548 | size -= prev - modinfo; | ||
2549 | modinfo = next_string(prev, &size); | ||
2550 | } | ||
2551 | |||
2552 | for (p = modinfo; p; p = next_string(p, &size)) { | ||
2496 | if (strncmp(p, tag, taglen) == 0 && p[taglen] == '=') | 2553 | if (strncmp(p, tag, taglen) == 0 && p[taglen] == '=') |
2497 | return p + taglen + 1; | 2554 | return p + taglen + 1; |
2498 | } | 2555 | } |
2499 | return NULL; | 2556 | return NULL; |
2500 | } | 2557 | } |
2501 | 2558 | ||
2559 | static char *get_modinfo(const struct load_info *info, const char *tag) | ||
2560 | { | ||
2561 | return get_next_modinfo(info, tag, NULL); | ||
2562 | } | ||
2563 | |||
2502 | static void setup_modinfo(struct module *mod, struct load_info *info) | 2564 | static void setup_modinfo(struct module *mod, struct load_info *info) |
2503 | { | 2565 | { |
2504 | struct module_attribute *attr; | 2566 | struct module_attribute *attr; |
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug index 5960e2980a8a..e0e14780a13d 100644 --- a/lib/Kconfig.debug +++ b/lib/Kconfig.debug | |||
@@ -277,22 +277,6 @@ config READABLE_ASM | |||
277 | to keep kernel developers who have to stare a lot at assembler listings | 277 | to keep kernel developers who have to stare a lot at assembler listings |
278 | sane. | 278 | sane. |
279 | 279 | ||
280 | config UNUSED_SYMBOLS | ||
281 | bool "Enable unused/obsolete exported symbols" | ||
282 | default y if X86 | ||
283 | help | ||
284 | Unused but exported symbols make the kernel needlessly bigger. For | ||
285 | that reason most of these unused exports will soon be removed. This | ||
286 | option is provided temporarily to provide a transition period in case | ||
287 | some external kernel module needs one of these symbols anyway. If you | ||
288 | encounter such a case in your module, consider if you are actually | ||
289 | using the right API. (rationale: since nobody in the kernel is using | ||
290 | this in a module, there is a pretty good chance it's actually the | ||
291 | wrong interface to use). If you really need the symbol, please send a | ||
292 | mail to the linux kernel mailing list mentioning the symbol and why | ||
293 | you really need it, and what the merge plan to the mainline kernel for | ||
294 | your module is. | ||
295 | |||
296 | config DEBUG_FS | 280 | config DEBUG_FS |
297 | bool "Debug Filesystem" | 281 | bool "Debug Filesystem" |
298 | help | 282 | help |
diff --git a/scripts/Makefile.modpost b/scripts/Makefile.modpost index 9800a3988f23..952fff485546 100644 --- a/scripts/Makefile.modpost +++ b/scripts/Makefile.modpost | |||
@@ -54,7 +54,8 @@ MODPOST = scripts/mod/modpost \ | |||
54 | $(if $(KBUILD_EXTMOD),$(addprefix -e ,$(KBUILD_EXTRA_SYMBOLS))) \ | 54 | $(if $(KBUILD_EXTMOD),$(addprefix -e ,$(KBUILD_EXTRA_SYMBOLS))) \ |
55 | $(if $(KBUILD_EXTMOD),-o $(modulesymfile)) \ | 55 | $(if $(KBUILD_EXTMOD),-o $(modulesymfile)) \ |
56 | $(if $(CONFIG_SECTION_MISMATCH_WARN_ONLY),,-E) \ | 56 | $(if $(CONFIG_SECTION_MISMATCH_WARN_ONLY),,-E) \ |
57 | $(if $(KBUILD_MODPOST_WARN),-w) | 57 | $(if $(KBUILD_MODPOST_WARN),-w) \ |
58 | $(if $(filter nsdeps,$(MAKECMDGOALS)),-d) | ||
58 | 59 | ||
59 | ifdef MODPOST_VMLINUX | 60 | ifdef MODPOST_VMLINUX |
60 | 61 | ||
@@ -95,6 +96,8 @@ ifneq ($(KBUILD_MODPOST_NOFINAL),1) | |||
95 | $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modfinal | 96 | $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modfinal |
96 | endif | 97 | endif |
97 | 98 | ||
99 | nsdeps: __modpost | ||
100 | |||
98 | endif | 101 | endif |
99 | 102 | ||
100 | .PHONY: $(PHONY) | 103 | .PHONY: $(PHONY) |
diff --git a/scripts/coccinelle/misc/add_namespace.cocci b/scripts/coccinelle/misc/add_namespace.cocci new file mode 100644 index 000000000000..c832bb6445a8 --- /dev/null +++ b/scripts/coccinelle/misc/add_namespace.cocci | |||
@@ -0,0 +1,23 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0-only | ||
2 | // | ||
3 | /// Adds missing MODULE_IMPORT_NS statements to source files | ||
4 | /// | ||
5 | /// This script is usually called from scripts/nsdeps with -D ns=<namespace> to | ||
6 | /// add a missing namespace tag to a module source file. | ||
7 | /// | ||
8 | |||
9 | @has_ns_import@ | ||
10 | declarer name MODULE_IMPORT_NS; | ||
11 | identifier virtual.ns; | ||
12 | @@ | ||
13 | MODULE_IMPORT_NS(ns); | ||
14 | |||
15 | // Add missing imports, but only adjacent to a MODULE_LICENSE statement. | ||
16 | // That ensures we are adding it only to the main module source file. | ||
17 | @do_import depends on !has_ns_import@ | ||
18 | declarer name MODULE_LICENSE; | ||
19 | expression license; | ||
20 | identifier virtual.ns; | ||
21 | @@ | ||
22 | MODULE_LICENSE(license); | ||
23 | + MODULE_IMPORT_NS(ns); | ||
diff --git a/scripts/export_report.pl b/scripts/export_report.pl index 7d3030d03a25..548330e8c4e7 100755 --- a/scripts/export_report.pl +++ b/scripts/export_report.pl | |||
@@ -94,7 +94,7 @@ if (defined $opt{'o'}) { | |||
94 | # | 94 | # |
95 | while ( <$module_symvers> ) { | 95 | while ( <$module_symvers> ) { |
96 | chomp; | 96 | chomp; |
97 | my (undef, $symbol, $module, $gpl) = split; | 97 | my (undef, $symbol, $namespace, $module, $gpl) = split('\t'); |
98 | $SYMBOL { $symbol } = [ $module , "0" , $symbol, $gpl]; | 98 | $SYMBOL { $symbol } = [ $module , "0" , $symbol, $gpl]; |
99 | } | 99 | } |
100 | close($module_symvers); | 100 | close($module_symvers); |
diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index 820eed87fb43..3961941e8e7a 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c | |||
@@ -38,6 +38,8 @@ static int sec_mismatch_count = 0; | |||
38 | static int sec_mismatch_fatal = 0; | 38 | static int sec_mismatch_fatal = 0; |
39 | /* ignore missing files */ | 39 | /* ignore missing files */ |
40 | static int ignore_missing_files; | 40 | static int ignore_missing_files; |
41 | /* write namespace dependencies */ | ||
42 | static int write_namespace_deps; | ||
41 | 43 | ||
42 | enum export { | 44 | enum export { |
43 | export_plain, export_unused, export_gpl, | 45 | export_plain, export_unused, export_gpl, |
@@ -164,6 +166,7 @@ struct symbol { | |||
164 | struct module *module; | 166 | struct module *module; |
165 | unsigned int crc; | 167 | unsigned int crc; |
166 | int crc_valid; | 168 | int crc_valid; |
169 | const char *namespace; | ||
167 | unsigned int weak:1; | 170 | unsigned int weak:1; |
168 | unsigned int vmlinux:1; /* 1 if symbol is defined in vmlinux */ | 171 | unsigned int vmlinux:1; /* 1 if symbol is defined in vmlinux */ |
169 | unsigned int kernel:1; /* 1 if symbol is from kernel | 172 | unsigned int kernel:1; /* 1 if symbol is from kernel |
@@ -235,6 +238,37 @@ static struct symbol *find_symbol(const char *name) | |||
235 | return NULL; | 238 | return NULL; |
236 | } | 239 | } |
237 | 240 | ||
241 | static bool contains_namespace(struct namespace_list *list, | ||
242 | const char *namespace) | ||
243 | { | ||
244 | struct namespace_list *ns_entry; | ||
245 | |||
246 | for (ns_entry = list; ns_entry != NULL; ns_entry = ns_entry->next) | ||
247 | if (strcmp(ns_entry->namespace, namespace) == 0) | ||
248 | return true; | ||
249 | |||
250 | return false; | ||
251 | } | ||
252 | |||
253 | static void add_namespace(struct namespace_list **list, const char *namespace) | ||
254 | { | ||
255 | struct namespace_list *ns_entry; | ||
256 | |||
257 | if (!contains_namespace(*list, namespace)) { | ||
258 | ns_entry = NOFAIL(malloc(sizeof(struct namespace_list) + | ||
259 | strlen(namespace) + 1)); | ||
260 | strcpy(ns_entry->namespace, namespace); | ||
261 | ns_entry->next = *list; | ||
262 | *list = ns_entry; | ||
263 | } | ||
264 | } | ||
265 | |||
266 | static bool module_imports_namespace(struct module *module, | ||
267 | const char *namespace) | ||
268 | { | ||
269 | return contains_namespace(module->imported_namespaces, namespace); | ||
270 | } | ||
271 | |||
238 | static const struct { | 272 | static const struct { |
239 | const char *str; | 273 | const char *str; |
240 | enum export export; | 274 | enum export export; |
@@ -314,23 +348,39 @@ static enum export export_from_sec(struct elf_info *elf, unsigned int sec) | |||
314 | return export_unknown; | 348 | return export_unknown; |
315 | } | 349 | } |
316 | 350 | ||
351 | static const char *sym_extract_namespace(const char **symname) | ||
352 | { | ||
353 | size_t n; | ||
354 | char *dupsymname; | ||
355 | |||
356 | n = strcspn(*symname, "."); | ||
357 | if (n < strlen(*symname) - 1) { | ||
358 | dupsymname = NOFAIL(strdup(*symname)); | ||
359 | dupsymname[n] = '\0'; | ||
360 | *symname = dupsymname; | ||
361 | return dupsymname + n + 1; | ||
362 | } | ||
363 | |||
364 | return NULL; | ||
365 | } | ||
366 | |||
317 | /** | 367 | /** |
318 | * Add an exported symbol - it may have already been added without a | 368 | * Add an exported symbol - it may have already been added without a |
319 | * CRC, in this case just update the CRC | 369 | * CRC, in this case just update the CRC |
320 | **/ | 370 | **/ |
321 | static struct symbol *sym_add_exported(const char *name, struct module *mod, | 371 | static struct symbol *sym_add_exported(const char *name, const char *namespace, |
322 | enum export export) | 372 | struct module *mod, enum export export) |
323 | { | 373 | { |
324 | struct symbol *s = find_symbol(name); | 374 | struct symbol *s = find_symbol(name); |
325 | 375 | ||
326 | if (!s) { | 376 | if (!s) { |
327 | s = new_symbol(name, mod, export); | 377 | s = new_symbol(name, mod, export); |
378 | s->namespace = namespace; | ||
328 | } else { | 379 | } else { |
329 | if (!s->preloaded) { | 380 | if (!s->preloaded) { |
330 | warn("%s: '%s' exported twice. Previous export " | 381 | warn("%s: '%s' exported twice. Previous export was in %s%s\n", |
331 | "was in %s%s\n", mod->name, name, | 382 | mod->name, name, s->module->name, |
332 | s->module->name, | 383 | is_vmlinux(s->module->name) ? "" : ".ko"); |
333 | is_vmlinux(s->module->name) ?"":".ko"); | ||
334 | } else { | 384 | } else { |
335 | /* In case Module.symvers was out of date */ | 385 | /* In case Module.symvers was out of date */ |
336 | s->module = mod; | 386 | s->module = mod; |
@@ -622,6 +672,7 @@ static void handle_modversions(struct module *mod, struct elf_info *info, | |||
622 | unsigned int crc; | 672 | unsigned int crc; |
623 | enum export export; | 673 | enum export export; |
624 | bool is_crc = false; | 674 | bool is_crc = false; |
675 | const char *name, *namespace; | ||
625 | 676 | ||
626 | if ((!is_vmlinux(mod->name) || mod->is_dot_o) && | 677 | if ((!is_vmlinux(mod->name) || mod->is_dot_o) && |
627 | strstarts(symname, "__ksymtab")) | 678 | strstarts(symname, "__ksymtab")) |
@@ -693,8 +744,9 @@ static void handle_modversions(struct module *mod, struct elf_info *info, | |||
693 | default: | 744 | default: |
694 | /* All exported symbols */ | 745 | /* All exported symbols */ |
695 | if (strstarts(symname, "__ksymtab_")) { | 746 | if (strstarts(symname, "__ksymtab_")) { |
696 | sym_add_exported(symname + strlen("__ksymtab_"), mod, | 747 | name = symname + strlen("__ksymtab_"); |
697 | export); | 748 | namespace = sym_extract_namespace(&name); |
749 | sym_add_exported(name, namespace, mod, export); | ||
698 | } | 750 | } |
699 | if (strcmp(symname, "init_module") == 0) | 751 | if (strcmp(symname, "init_module") == 0) |
700 | mod->has_init = 1; | 752 | mod->has_init = 1; |
@@ -1945,6 +1997,7 @@ static void read_symbols(const char *modname) | |||
1945 | const char *symname; | 1997 | const char *symname; |
1946 | char *version; | 1998 | char *version; |
1947 | char *license; | 1999 | char *license; |
2000 | char *namespace; | ||
1948 | struct module *mod; | 2001 | struct module *mod; |
1949 | struct elf_info info = { }; | 2002 | struct elf_info info = { }; |
1950 | Elf_Sym *sym; | 2003 | Elf_Sym *sym; |
@@ -1976,6 +2029,12 @@ static void read_symbols(const char *modname) | |||
1976 | license = get_next_modinfo(&info, "license", license); | 2029 | license = get_next_modinfo(&info, "license", license); |
1977 | } | 2030 | } |
1978 | 2031 | ||
2032 | namespace = get_modinfo(&info, "import_ns"); | ||
2033 | while (namespace) { | ||
2034 | add_namespace(&mod->imported_namespaces, namespace); | ||
2035 | namespace = get_next_modinfo(&info, "import_ns", namespace); | ||
2036 | } | ||
2037 | |||
1979 | for (sym = info.symtab_start; sym < info.symtab_stop; sym++) { | 2038 | for (sym = info.symtab_start; sym < info.symtab_stop; sym++) { |
1980 | symname = remove_dot(info.strtab + sym->st_name); | 2039 | symname = remove_dot(info.strtab + sym->st_name); |
1981 | 2040 | ||
@@ -2135,6 +2194,18 @@ static int check_exports(struct module *mod) | |||
2135 | basename++; | 2194 | basename++; |
2136 | else | 2195 | else |
2137 | basename = mod->name; | 2196 | basename = mod->name; |
2197 | |||
2198 | if (exp->namespace) { | ||
2199 | add_namespace(&mod->required_namespaces, | ||
2200 | exp->namespace); | ||
2201 | |||
2202 | if (!write_namespace_deps && | ||
2203 | !module_imports_namespace(mod, exp->namespace)) { | ||
2204 | warn("module %s uses symbol %s from namespace %s, but does not import it.\n", | ||
2205 | basename, exp->name, exp->namespace); | ||
2206 | } | ||
2207 | } | ||
2208 | |||
2138 | if (!mod->gpl_compatible) | 2209 | if (!mod->gpl_compatible) |
2139 | check_for_gpl_usage(exp->export, basename, exp->name); | 2210 | check_for_gpl_usage(exp->export, basename, exp->name); |
2140 | check_for_unused(exp->export, basename, exp->name); | 2211 | check_for_unused(exp->export, basename, exp->name); |
@@ -2354,7 +2425,7 @@ static void read_dump(const char *fname, unsigned int kernel) | |||
2354 | return; | 2425 | return; |
2355 | 2426 | ||
2356 | while ((line = get_next_line(&pos, file, size))) { | 2427 | while ((line = get_next_line(&pos, file, size))) { |
2357 | char *symname, *modname, *d, *export, *end; | 2428 | char *symname, *namespace, *modname, *d, *export, *end; |
2358 | unsigned int crc; | 2429 | unsigned int crc; |
2359 | struct module *mod; | 2430 | struct module *mod; |
2360 | struct symbol *s; | 2431 | struct symbol *s; |
@@ -2362,7 +2433,10 @@ static void read_dump(const char *fname, unsigned int kernel) | |||
2362 | if (!(symname = strchr(line, '\t'))) | 2433 | if (!(symname = strchr(line, '\t'))) |
2363 | goto fail; | 2434 | goto fail; |
2364 | *symname++ = '\0'; | 2435 | *symname++ = '\0'; |
2365 | if (!(modname = strchr(symname, '\t'))) | 2436 | if (!(namespace = strchr(symname, '\t'))) |
2437 | goto fail; | ||
2438 | *namespace++ = '\0'; | ||
2439 | if (!(modname = strchr(namespace, '\t'))) | ||
2366 | goto fail; | 2440 | goto fail; |
2367 | *modname++ = '\0'; | 2441 | *modname++ = '\0'; |
2368 | if ((export = strchr(modname, '\t')) != NULL) | 2442 | if ((export = strchr(modname, '\t')) != NULL) |
@@ -2379,7 +2453,8 @@ static void read_dump(const char *fname, unsigned int kernel) | |||
2379 | mod = new_module(modname); | 2453 | mod = new_module(modname); |
2380 | mod->skip = 1; | 2454 | mod->skip = 1; |
2381 | } | 2455 | } |
2382 | s = sym_add_exported(symname, mod, export_no(export)); | 2456 | s = sym_add_exported(symname, namespace, mod, |
2457 | export_no(export)); | ||
2383 | s->kernel = kernel; | 2458 | s->kernel = kernel; |
2384 | s->preloaded = 1; | 2459 | s->preloaded = 1; |
2385 | s->is_static = 0; | 2460 | s->is_static = 0; |
@@ -2409,16 +2484,20 @@ static void write_dump(const char *fname) | |||
2409 | { | 2484 | { |
2410 | struct buffer buf = { }; | 2485 | struct buffer buf = { }; |
2411 | struct symbol *symbol; | 2486 | struct symbol *symbol; |
2487 | const char *namespace; | ||
2412 | int n; | 2488 | int n; |
2413 | 2489 | ||
2414 | for (n = 0; n < SYMBOL_HASH_SIZE ; n++) { | 2490 | for (n = 0; n < SYMBOL_HASH_SIZE ; n++) { |
2415 | symbol = symbolhash[n]; | 2491 | symbol = symbolhash[n]; |
2416 | while (symbol) { | 2492 | while (symbol) { |
2417 | if (dump_sym(symbol)) | 2493 | if (dump_sym(symbol)) { |
2418 | buf_printf(&buf, "0x%08x\t%s\t%s\t%s\n", | 2494 | namespace = symbol->namespace; |
2419 | symbol->crc, symbol->name, | 2495 | buf_printf(&buf, "0x%08x\t%s\t%s\t%s\t%s\n", |
2420 | symbol->module->name, | 2496 | symbol->crc, symbol->name, |
2421 | export_str(symbol->export)); | 2497 | namespace ? namespace : "", |
2498 | symbol->module->name, | ||
2499 | export_str(symbol->export)); | ||
2500 | } | ||
2422 | symbol = symbol->next; | 2501 | symbol = symbol->next; |
2423 | } | 2502 | } |
2424 | } | 2503 | } |
@@ -2426,6 +2505,31 @@ static void write_dump(const char *fname) | |||
2426 | free(buf.p); | 2505 | free(buf.p); |
2427 | } | 2506 | } |
2428 | 2507 | ||
2508 | static void write_namespace_deps_files(void) | ||
2509 | { | ||
2510 | struct module *mod; | ||
2511 | struct namespace_list *ns; | ||
2512 | struct buffer ns_deps_buf = {}; | ||
2513 | |||
2514 | for (mod = modules; mod; mod = mod->next) { | ||
2515 | char fname[PATH_MAX]; | ||
2516 | |||
2517 | if (mod->skip) | ||
2518 | continue; | ||
2519 | |||
2520 | ns_deps_buf.pos = 0; | ||
2521 | |||
2522 | for (ns = mod->required_namespaces; ns; ns = ns->next) | ||
2523 | buf_printf(&ns_deps_buf, "%s\n", ns->namespace); | ||
2524 | |||
2525 | if (ns_deps_buf.pos == 0) | ||
2526 | continue; | ||
2527 | |||
2528 | sprintf(fname, "%s.ns_deps", mod->name); | ||
2529 | write_if_changed(&ns_deps_buf, fname); | ||
2530 | } | ||
2531 | } | ||
2532 | |||
2429 | struct ext_sym_list { | 2533 | struct ext_sym_list { |
2430 | struct ext_sym_list *next; | 2534 | struct ext_sym_list *next; |
2431 | const char *file; | 2535 | const char *file; |
@@ -2443,7 +2547,7 @@ int main(int argc, char **argv) | |||
2443 | struct ext_sym_list *extsym_iter; | 2547 | struct ext_sym_list *extsym_iter; |
2444 | struct ext_sym_list *extsym_start = NULL; | 2548 | struct ext_sym_list *extsym_start = NULL; |
2445 | 2549 | ||
2446 | while ((opt = getopt(argc, argv, "i:I:e:mnsT:o:awE")) != -1) { | 2550 | while ((opt = getopt(argc, argv, "i:I:e:mnsT:o:awEd")) != -1) { |
2447 | switch (opt) { | 2551 | switch (opt) { |
2448 | case 'i': | 2552 | case 'i': |
2449 | kernel_read = optarg; | 2553 | kernel_read = optarg; |
@@ -2484,6 +2588,9 @@ int main(int argc, char **argv) | |||
2484 | case 'E': | 2588 | case 'E': |
2485 | sec_mismatch_fatal = 1; | 2589 | sec_mismatch_fatal = 1; |
2486 | break; | 2590 | break; |
2591 | case 'd': | ||
2592 | write_namespace_deps = 1; | ||
2593 | break; | ||
2487 | default: | 2594 | default: |
2488 | exit(1); | 2595 | exit(1); |
2489 | } | 2596 | } |
@@ -2518,6 +2625,9 @@ int main(int argc, char **argv) | |||
2518 | 2625 | ||
2519 | err |= check_modname_len(mod); | 2626 | err |= check_modname_len(mod); |
2520 | err |= check_exports(mod); | 2627 | err |= check_exports(mod); |
2628 | if (write_namespace_deps) | ||
2629 | continue; | ||
2630 | |||
2521 | add_header(&buf, mod); | 2631 | add_header(&buf, mod); |
2522 | add_intree_flag(&buf, !external_module); | 2632 | add_intree_flag(&buf, !external_module); |
2523 | add_retpoline(&buf); | 2633 | add_retpoline(&buf); |
@@ -2530,6 +2640,12 @@ int main(int argc, char **argv) | |||
2530 | sprintf(fname, "%s.mod.c", mod->name); | 2640 | sprintf(fname, "%s.mod.c", mod->name); |
2531 | write_if_changed(&buf, fname); | 2641 | write_if_changed(&buf, fname); |
2532 | } | 2642 | } |
2643 | |||
2644 | if (write_namespace_deps) { | ||
2645 | write_namespace_deps_files(); | ||
2646 | return 0; | ||
2647 | } | ||
2648 | |||
2533 | if (dump_write) | 2649 | if (dump_write) |
2534 | write_dump(dump_write); | 2650 | write_dump(dump_write); |
2535 | if (sec_mismatch_count && sec_mismatch_fatal) | 2651 | if (sec_mismatch_count && sec_mismatch_fatal) |
diff --git a/scripts/mod/modpost.h b/scripts/mod/modpost.h index 8453d6ac2f77..92a926d375d2 100644 --- a/scripts/mod/modpost.h +++ b/scripts/mod/modpost.h | |||
@@ -109,6 +109,11 @@ buf_printf(struct buffer *buf, const char *fmt, ...); | |||
109 | void | 109 | void |
110 | buf_write(struct buffer *buf, const char *s, int len); | 110 | buf_write(struct buffer *buf, const char *s, int len); |
111 | 111 | ||
112 | struct namespace_list { | ||
113 | struct namespace_list *next; | ||
114 | char namespace[0]; | ||
115 | }; | ||
116 | |||
112 | struct module { | 117 | struct module { |
113 | struct module *next; | 118 | struct module *next; |
114 | const char *name; | 119 | const char *name; |
@@ -121,6 +126,10 @@ struct module { | |||
121 | struct buffer dev_table_buf; | 126 | struct buffer dev_table_buf; |
122 | char srcversion[25]; | 127 | char srcversion[25]; |
123 | int is_dot_o; | 128 | int is_dot_o; |
129 | // Required namespace dependencies | ||
130 | struct namespace_list *required_namespaces; | ||
131 | // Actual imported namespaces | ||
132 | struct namespace_list *imported_namespaces; | ||
124 | }; | 133 | }; |
125 | 134 | ||
126 | struct elf_info { | 135 | struct elf_info { |
diff --git a/scripts/nsdeps b/scripts/nsdeps new file mode 100644 index 000000000000..ac2b6031dd13 --- /dev/null +++ b/scripts/nsdeps | |||
@@ -0,0 +1,58 @@ | |||
1 | #!/bin/bash | ||
2 | # SPDX-License-Identifier: GPL-2.0 | ||
3 | # Linux kernel symbol namespace import generator | ||
4 | # | ||
5 | # This script requires a minimum spatch version. | ||
6 | SPATCH_REQ_VERSION="1.0.4" | ||
7 | |||
8 | DIR="$(dirname $(readlink -f $0))/.." | ||
9 | SPATCH="`which ${SPATCH:=spatch}`" | ||
10 | if [ ! -x "$SPATCH" ]; then | ||
11 | echo 'spatch is part of the Coccinelle project and is available at http://coccinelle.lip6.fr/' | ||
12 | exit 1 | ||
13 | fi | ||
14 | |||
15 | SPATCH_REQ_VERSION_NUM=$(echo $SPATCH_REQ_VERSION | ${DIR}/scripts/ld-version.sh) | ||
16 | SPATCH_VERSION=$($SPATCH --version | head -1 | awk '{print $3}') | ||
17 | SPATCH_VERSION_NUM=$(echo $SPATCH_VERSION | ${DIR}/scripts/ld-version.sh) | ||
18 | |||
19 | if [ "$SPATCH_VERSION_NUM" -lt "$SPATCH_REQ_VERSION_NUM" ] ; then | ||
20 | echo "spatch needs to be version $SPATCH_REQ_VERSION or higher" | ||
21 | exit 1 | ||
22 | fi | ||
23 | |||
24 | generate_deps_for_ns() { | ||
25 | $SPATCH --very-quiet --in-place --sp-file \ | ||
26 | $srctree/scripts/coccinelle/misc/add_namespace.cocci -D ns=$1 $2 | ||
27 | } | ||
28 | |||
29 | generate_deps() { | ||
30 | local mod_name=`basename $@ .ko` | ||
31 | local mod_file=`echo $@ | sed -e 's/\.ko/\.mod/'` | ||
32 | local ns_deps_file=`echo $@ | sed -e 's/\.ko/\.ns_deps/'` | ||
33 | if [ ! -f "$ns_deps_file" ]; then return; fi | ||
34 | local mod_source_files=`cat $mod_file | sed -n 1p \ | ||
35 | | sed -e 's/\.o/\.c/g' \ | ||
36 | | sed "s/[^ ]* */${srctree}\/&/g"` | ||
37 | for ns in `cat $ns_deps_file`; do | ||
38 | echo "Adding namespace $ns to module $mod_name (if needed)." | ||
39 | generate_deps_for_ns $ns $mod_source_files | ||
40 | # sort the imports | ||
41 | for source_file in $mod_source_files; do | ||
42 | sed '/MODULE_IMPORT_NS/Q' $source_file > ${source_file}.tmp | ||
43 | offset=$(wc -l ${source_file}.tmp | awk '{print $1;}') | ||
44 | cat $source_file | grep MODULE_IMPORT_NS | sort -u >> ${source_file}.tmp | ||
45 | tail -n +$((offset +1)) ${source_file} | grep -v MODULE_IMPORT_NS >> ${source_file}.tmp | ||
46 | if ! diff -q ${source_file} ${source_file}.tmp; then | ||
47 | mv ${source_file}.tmp ${source_file} | ||
48 | else | ||
49 | rm ${source_file}.tmp | ||
50 | fi | ||
51 | done | ||
52 | done | ||
53 | } | ||
54 | |||
55 | for f in `cat $objtree/modules.order`; do | ||
56 | generate_deps $f | ||
57 | done | ||
58 | |||