Skip to content

Commit

Permalink
Merge tag 'modules-for-v5.4' of git://git.kernel.org/pub/scm/linux/ke…
Browse files Browse the repository at this point in the history
…rnel/git/jeyu/linux

Pull modules updates from Jessica Yu:
 "The main bulk of this pull request introduces a new exported symbol
  namespaces feature. The number of exported symbols is increasingly
  growing with each release (we're at about 31k exports as of 5.3-rc7)
  and we currently have no way of visualizing how these symbols are
  "clustered" or making sense of this huge export surface.

  Namespacing exported symbols allows kernel developers to more
  explicitly partition and categorize exported symbols, as well as more
  easily limiting the availability of namespaced symbols to other parts
  of the kernel. For starters, we have introduced the USB_STORAGE
  namespace to demonstrate the API's usage. I have briefly summarized
  the feature and its main motivations in the tag below.

  Summary:

   - Introduce exported symbol namespaces.

     This new feature allows subsystem maintainers to partition and
     categorize their exported symbols into explicit namespaces. Module
     authors are now required to import the namespaces they need.

     Some of the main motivations of this feature include: allowing
     kernel developers to better manage the export surface, allow
     subsystem maintainers to explicitly state that usage of some
     exported symbols should only be limited to certain users (think:
     inter-module or inter-driver symbols, debugging symbols, etc), as
     well as more easily limiting the availability of namespaced symbols
     to other parts of the kernel.

     With the module import requirement, it is also easier to spot the
     misuse of exported symbols during patch review.

     Two new macros are introduced: EXPORT_SYMBOL_NS() and
     EXPORT_SYMBOL_NS_GPL(). The API is thoroughly documented in
     Documentation/kbuild/namespaces.rst.

   - Some small code and kbuild cleanups here and there"

* tag 'modules-for-v5.4' of git://git.kernel.org/pub/scm/linux/kernel/git/jeyu/linux:
  module: Remove leftover '#undef' from export header
  module: remove unneeded casts in cmp_name()
  module: move CONFIG_UNUSED_SYMBOLS to the sub-menu of MODULES
  module: remove redundant 'depends on MODULES'
  module: Fix link failure due to invalid relocation on namespace offset
  usb-storage: export symbols in USB_STORAGE namespace
  usb-storage: remove single-use define for debugging
  docs: Add documentation for Symbol Namespaces
  scripts: Coccinelle script for namespace dependencies.
  modpost: add support for generating namespace dependencies
  export: allow definition default namespaces in Makefiles or sources
  module: add config option MODULE_ALLOW_MISSING_NAMESPACE_IMPORTS
  modpost: add support for symbol namespaces
  module: add support for symbol namespaces.
  export: explicitly align struct kernel_symbol
  module: support reading multiple values per modinfo tag
  • Loading branch information
torvalds committed Sep 22, 2019
2 parents 8808cf8 + 2e6fcfe commit e070355
Show file tree
Hide file tree
Showing 34 changed files with 613 additions and 68 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
*.lzo
*.mod
*.mod.c
*.ns_deps
*.o
*.o.*
*.patch
Expand Down
7 changes: 5 additions & 2 deletions Documentation/kbuild/modules.rst
Original file line number Diff line number Diff line change
Expand Up @@ -470,9 +470,12 @@ build.

The syntax of the Module.symvers file is::

<CRC> <Symbol> <module>
<CRC> <Symbol> <Namespace> <Module> <Export Type>

0x2d036834 scsi_remove_host drivers/scsi/scsi_mod
0xe1cc2a05 usb_stor_suspend USB_STORAGE drivers/usb/storage/usb-storage EXPORT_SYMBOL_GPL

The fields are separated by tabs and values may be empty (e.g.
if no namespace is defined for an exported symbol).

For a kernel build without CONFIG_MODVERSIONS enabled, the CRC
would read 0x00000000.
Expand Down
154 changes: 154 additions & 0 deletions Documentation/kbuild/namespaces.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
=================
Symbol Namespaces
=================

The following document describes how to use Symbol Namespaces to structure the
export surface of in-kernel symbols exported through the family of
EXPORT_SYMBOL() macros.

.. Table of Contents
=== 1 Introduction
=== 2 How to define Symbol Namespaces
--- 2.1 Using the EXPORT_SYMBOL macros
--- 2.2 Using the DEFAULT_SYMBOL_NAMESPACE define
=== 3 How to use Symbols exported in Namespaces
=== 4 Loading Modules that use namespaced Symbols
=== 5 Automatically creating MODULE_IMPORT_NS statements
1. Introduction
===============

Symbol Namespaces have been introduced as a means to structure the export
surface of the in-kernel API. It allows subsystem maintainers to partition
their exported symbols into separate namespaces. That is useful for
documentation purposes (think of the SUBSYSTEM_DEBUG namespace) as well as for
limiting the availability of a set of symbols for use in other parts of the
kernel. As of today, modules that make use of symbols exported into namespaces,
are required to import the namespace. Otherwise the kernel will, depending on
its configuration, reject loading the module or warn about a missing import.

2. How to define Symbol Namespaces
==================================

Symbols can be exported into namespace using different methods. All of them are
changing the way EXPORT_SYMBOL and friends are instrumented to create ksymtab
entries.

2.1 Using the EXPORT_SYMBOL macros
==================================

In addition to the macros EXPORT_SYMBOL() and EXPORT_SYMBOL_GPL(), that allow
exporting of kernel symbols to the kernel symbol table, variants of these are
available to export symbols into a certain namespace: EXPORT_SYMBOL_NS() and
EXPORT_SYMBOL_NS_GPL(). They take one additional argument: the namespace.
Please note that due to macro expansion that argument needs to be a
preprocessor symbol. E.g. to export the symbol `usb_stor_suspend` into the
namespace `USB_STORAGE`, use::

EXPORT_SYMBOL_NS(usb_stor_suspend, USB_STORAGE);

The corresponding ksymtab entry struct `kernel_symbol` will have the member
`namespace` set accordingly. A symbol that is exported without a namespace will
refer to `NULL`. There is no default namespace if none is defined. `modpost`
and kernel/module.c make use the namespace at build time or module load time,
respectively.

2.2 Using the DEFAULT_SYMBOL_NAMESPACE define
=============================================

Defining namespaces for all symbols of a subsystem can be very verbose and may
become hard to maintain. Therefore a default define (DEFAULT_SYMBOL_NAMESPACE)
is been provided, that, if set, will become the default for all EXPORT_SYMBOL()
and EXPORT_SYMBOL_GPL() macro expansions that do not specify a namespace.

There are multiple ways of specifying this define and it depends on the
subsystem and the maintainer's preference, which one to use. The first option
is to define the default namespace in the `Makefile` of the subsystem. E.g. to
export all symbols defined in usb-common into the namespace USB_COMMON, add a
line like this to drivers/usb/common/Makefile::

ccflags-y += -DDEFAULT_SYMBOL_NAMESPACE=USB_COMMON

That will affect all EXPORT_SYMBOL() and EXPORT_SYMBOL_GPL() statements. A
symbol exported with EXPORT_SYMBOL_NS() while this definition is present, will
still be exported into the namespace that is passed as the namespace argument
as this argument has preference over a default symbol namespace.

A second option to define the default namespace is directly in the compilation
unit as preprocessor statement. The above example would then read::

#undef DEFAULT_SYMBOL_NAMESPACE
#define DEFAULT_SYMBOL_NAMESPACE USB_COMMON

within the corresponding compilation unit before any EXPORT_SYMBOL macro is
used.

3. How to use Symbols exported in Namespaces
============================================

In order to use symbols that are exported into namespaces, kernel modules need
to explicitly import these namespaces. Otherwise the kernel might reject to
load the module. The module code is required to use the macro MODULE_IMPORT_NS
for the namespaces it uses symbols from. E.g. a module using the
usb_stor_suspend symbol from above, needs to import the namespace USB_STORAGE
using a statement like::

MODULE_IMPORT_NS(USB_STORAGE);

This will create a `modinfo` tag in the module for each imported namespace.
This has the side effect, that the imported namespaces of a module can be
inspected with modinfo::

$ modinfo drivers/usb/storage/ums-karma.ko
[...]
import_ns: USB_STORAGE
[...]


It is advisable to add the MODULE_IMPORT_NS() statement close to other module
metadata definitions like MODULE_AUTHOR() or MODULE_LICENSE(). Refer to section
5. for a way to create missing import statements automatically.

4. Loading Modules that use namespaced Symbols
==============================================

At module loading time (e.g. `insmod`), the kernel will check each symbol
referenced from the module for its availability and whether the namespace it
might be exported to has been imported by the module. The default behaviour of
the kernel is to reject loading modules that don't specify sufficient imports.
An error will be logged and loading will be failed with EINVAL. In order to
allow loading of modules that don't satisfy this precondition, a configuration
option is available: Setting MODULE_ALLOW_MISSING_NAMESPACE_IMPORTS=y will
enable loading regardless, but will emit a warning.

5. Automatically creating MODULE_IMPORT_NS statements
=====================================================

Missing namespaces imports can easily be detected at build time. In fact,
modpost will emit a warning if a module uses a symbol from a namespace
without importing it.
MODULE_IMPORT_NS() statements will usually be added at a definite location
(along with other module meta data). To make the life of module authors (and
subsystem maintainers) easier, a script and make target is available to fixup
missing imports. Fixing missing imports can be done with::

$ make nsdeps

A typical scenario for module authors would be::

- write code that depends on a symbol from a not imported namespace
- `make`
- notice the warning of modpost telling about a missing import
- run `make nsdeps` to add the import to the correct code location

For subsystem maintainers introducing a namespace, the steps are very similar.
Again, `make nsdeps` will eventually add the missing namespace imports for
in-tree modules::

- move or add symbols to a namespace (e.g. with EXPORT_SYMBOL_NS())
- `make` (preferably with an allmodconfig to cover all in-kernel
modules)
- notice the warning of modpost telling about a missing import
- run `make nsdeps` to add the import to the correct code location

18 changes: 18 additions & 0 deletions Documentation/kernel-hacking/hacking.rst
Original file line number Diff line number Diff line change
Expand Up @@ -594,6 +594,24 @@ internal implementation issue, and not really an interface. Some
maintainers and developers may however require EXPORT_SYMBOL_GPL()
when adding any new APIs or functionality.

:c:func:`EXPORT_SYMBOL_NS()`
----------------------------

Defined in ``include/linux/export.h``

This is the variant of `EXPORT_SYMBOL()` that allows specifying a symbol
namespace. Symbol Namespaces are documented in
``Documentation/kbuild/namespaces.rst``.

:c:func:`EXPORT_SYMBOL_NS_GPL()`
--------------------------------

Defined in ``include/linux/export.h``

This is the variant of `EXPORT_SYMBOL_GPL()` that allows specifying a symbol
namespace. Symbol Namespaces are documented in
``Documentation/kbuild/namespaces.rst``.

Routines and Conventions
========================

Expand Down
5 changes: 5 additions & 0 deletions MAINTAINERS
Original file line number Diff line number Diff line change
Expand Up @@ -11523,6 +11523,11 @@ S: Maintained
T: git git://git.kernel.org/pub/scm/linux/kernel/git/wtarreau/nolibc.git
F: tools/include/nolibc/

NSDEPS
M: Matthias Maennich <maennich@google.com>
S: Maintained
F: scripts/nsdeps

NTB AMD DRIVER
M: Shyam Sundar S K <Shyam-sundar.S-k@amd.com>
L: linux-ntb@googlegroups.com
Expand Down
14 changes: 13 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -1498,6 +1498,9 @@ help:
@echo ' headerdep - Detect inclusion cycles in headers'
@echo ' coccicheck - Check with Coccinelle'
@echo ''
@echo 'Tools:'
@echo ' nsdeps - Generate missing symbol namespace dependencies'
@echo ''
@echo 'Kernel selftest:'
@echo ' kselftest - Build and run kernel selftest (run as root)'
@echo ' Build, install, and boot kernel before'
Expand Down Expand Up @@ -1679,7 +1682,7 @@ clean: $(clean-dirs)
-o -name '*.ko.*' \
-o -name '*.dtb' -o -name '*.dtb.S' -o -name '*.dt.yaml' \
-o -name '*.dwo' -o -name '*.lst' \
-o -name '*.su' -o -name '*.mod' \
-o -name '*.su' -o -name '*.mod' -o -name '*.ns_deps' \
-o -name '.*.d' -o -name '.*.tmp' -o -name '*.mod.c' \
-o -name '*.lex.c' -o -name '*.tab.[ch]' \
-o -name '*.asn1.[ch]' \
Expand All @@ -1697,6 +1700,15 @@ quiet_cmd_tags = GEN $@
tags TAGS cscope gtags: FORCE
$(call cmd,tags)

# Script to generate missing namespace dependencies
# ---------------------------------------------------------------------------

PHONY += nsdeps

nsdeps: modules
$(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modpost nsdeps
$(Q)$(CONFIG_SHELL) $(srctree)/scripts/$@

# Scripts to check various things for consistency
# ---------------------------------------------------------------------------

Expand Down
1 change: 0 additions & 1 deletion arch/m68k/include/asm/export.h
Original file line number Diff line number Diff line change
@@ -1,3 +1,2 @@
#define KSYM_ALIGN 2
#define KCRC_ALIGN 2
#include <asm-generic/export.h>
2 changes: 2 additions & 0 deletions drivers/usb/storage/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@

ccflags-y := -I $(srctree)/drivers/scsi

ccflags-y += -DDEFAULT_SYMBOL_NAMESPACE=USB_STORAGE

obj-$(CONFIG_USB_UAS) += uas.o
obj-$(CONFIG_USB_STORAGE) += usb-storage.o

Expand Down
1 change: 1 addition & 0 deletions drivers/usb/storage/alauda.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
MODULE_DESCRIPTION("Driver for Alauda-based card readers");
MODULE_AUTHOR("Daniel Drake <dsd@gentoo.org>");
MODULE_LICENSE("GPL");
MODULE_IMPORT_NS(USB_STORAGE);

/*
* Status bytes
Expand Down
1 change: 1 addition & 0 deletions drivers/usb/storage/cypress_atacb.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
MODULE_DESCRIPTION("SAT support for Cypress USB/ATA bridges with ATACB");
MODULE_AUTHOR("Matthieu Castet <castet.matthieu@free.fr>");
MODULE_LICENSE("GPL");
MODULE_IMPORT_NS(USB_STORAGE);

/*
* The table of devices
Expand Down
1 change: 1 addition & 0 deletions drivers/usb/storage/datafab.c
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@
MODULE_DESCRIPTION("Driver for Datafab USB Compact Flash reader");
MODULE_AUTHOR("Jimmie Mayfield <mayfield+datafab@sackheads.org>");
MODULE_LICENSE("GPL");
MODULE_IMPORT_NS(USB_STORAGE);

struct datafab_info {
unsigned long sectors; /* total sector count */
Expand Down
1 change: 1 addition & 0 deletions drivers/usb/storage/ene_ub6250.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@

MODULE_DESCRIPTION("Driver for ENE UB6250 reader");
MODULE_LICENSE("GPL");
MODULE_IMPORT_NS(USB_STORAGE);
MODULE_FIRMWARE(SD_INIT1_FIRMWARE);
MODULE_FIRMWARE(SD_INIT2_FIRMWARE);
MODULE_FIRMWARE(SD_RW_FIRMWARE);
Expand Down
1 change: 1 addition & 0 deletions drivers/usb/storage/freecom.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
MODULE_DESCRIPTION("Driver for Freecom USB/IDE adaptor");
MODULE_AUTHOR("David Brown <usb-storage@davidb.org>");
MODULE_LICENSE("GPL");
MODULE_IMPORT_NS(USB_STORAGE);

#ifdef CONFIG_USB_STORAGE_DEBUG
static void pdump(struct us_data *us, void *ibuffer, int length);
Expand Down
1 change: 1 addition & 0 deletions drivers/usb/storage/isd200.c
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@
MODULE_DESCRIPTION("Driver for In-System Design, Inc. ISD200 ASIC");
MODULE_AUTHOR("Björn Stenberg <bjorn@haxx.se>");
MODULE_LICENSE("GPL");
MODULE_IMPORT_NS(USB_STORAGE);

static int isd200_Initialization(struct us_data *us);

Expand Down
1 change: 1 addition & 0 deletions drivers/usb/storage/jumpshot.c
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@
MODULE_DESCRIPTION("Driver for Lexar \"Jumpshot\" Compact Flash reader");
MODULE_AUTHOR("Jimmie Mayfield <mayfield+usb@sackheads.org>");
MODULE_LICENSE("GPL");
MODULE_IMPORT_NS(USB_STORAGE);

/*
* The table of devices
Expand Down
1 change: 1 addition & 0 deletions drivers/usb/storage/karma.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
MODULE_DESCRIPTION("Driver for Rio Karma");
MODULE_AUTHOR("Bob Copeland <me@bobcopeland.com>, Keith Bennett <keith@mcs.st-and.ac.uk>");
MODULE_LICENSE("GPL");
MODULE_IMPORT_NS(USB_STORAGE);

#define RIO_PREFIX "RIOP\x00"
#define RIO_PREFIX_LEN 5
Expand Down
1 change: 1 addition & 0 deletions drivers/usb/storage/onetouch.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
MODULE_DESCRIPTION("Maxtor USB OneTouch hard drive button driver");
MODULE_AUTHOR("Nick Sillik <n.sillik@temple.edu>");
MODULE_LICENSE("GPL");
MODULE_IMPORT_NS(USB_STORAGE);

#define ONETOUCH_PKT_LEN 0x02
#define ONETOUCH_BUTTON KEY_PROG1
Expand Down
1 change: 1 addition & 0 deletions drivers/usb/storage/realtek_cr.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
MODULE_DESCRIPTION("Driver for Realtek USB Card Reader");
MODULE_AUTHOR("wwang <wei_wang@realsil.com.cn>");
MODULE_LICENSE("GPL");
MODULE_IMPORT_NS(USB_STORAGE);

static int auto_delink_en = 1;
module_param(auto_delink_en, int, S_IRUGO | S_IWUSR);
Expand Down
1 change: 1 addition & 0 deletions drivers/usb/storage/sddr09.c
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
MODULE_DESCRIPTION("Driver for SanDisk SDDR-09 SmartMedia reader");
MODULE_AUTHOR("Andries Brouwer <aeb@cwi.nl>, Robert Baruch <autophile@starband.net>");
MODULE_LICENSE("GPL");
MODULE_IMPORT_NS(USB_STORAGE);

static int usb_stor_sddr09_dpcm_init(struct us_data *us);
static int sddr09_transport(struct scsi_cmnd *srb, struct us_data *us);
Expand Down
1 change: 1 addition & 0 deletions drivers/usb/storage/sddr55.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
MODULE_DESCRIPTION("Driver for SanDisk SDDR-55 SmartMedia reader");
MODULE_AUTHOR("Simon Munton");
MODULE_LICENSE("GPL");
MODULE_IMPORT_NS(USB_STORAGE);

/*
* The table of devices
Expand Down
1 change: 1 addition & 0 deletions drivers/usb/storage/shuttle_usbat.c
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
MODULE_DESCRIPTION("Driver for SCM Microsystems (a.k.a. Shuttle) USB-ATAPI cable");
MODULE_AUTHOR("Daniel Drake <dsd@gentoo.org>, Robert Baruch <autophile@starband.net>");
MODULE_LICENSE("GPL");
MODULE_IMPORT_NS(USB_STORAGE);

/* Supported device types */
#define USBAT_DEV_HP8200 0x01
Expand Down
1 change: 1 addition & 0 deletions drivers/usb/storage/uas.c
Original file line number Diff line number Diff line change
Expand Up @@ -1219,5 +1219,6 @@ static struct usb_driver uas_driver = {
module_usb_driver(uas_driver);

MODULE_LICENSE("GPL");
MODULE_IMPORT_NS(USB_STORAGE);
MODULE_AUTHOR(
"Hans de Goede <hdegoede@redhat.com>, Matthew Wilcox and Sarah Sharp");
Loading

0 comments on commit e070355

Please sign in to comment.