2022-12-05 16:51:55

by Nick Alcock

[permalink] [raw]
Subject: [PATCH modules-next v10 00/13] kallsyms: reliable symbol->address lookup with /proc/kallmodsyms

The kallmodsyms patch series was originally posted in Nov 2019, and the thread
(https://lore.kernel.org/linux-kbuild/[email protected]/t/#u)
shows review comments, questions, and feedback from interested parties.
Most recent posting: <https://lore.kernel.org/linux-modules/[email protected]/T/#t>.

All review comments have been satisfied, as far as I know: in particular
Yamada's note about translation units that are shared between built-in
modules is satisfied with a better representation which is also much, much
smaller, and we are no longer using modules_thick.builtin but Luis's new
modules.builtin.objs.

A kernel tree containing this series alone:
https://github.com/oracle/dtrace-linux-kernel kallmodsyms/6.1-rc4-modules-next


The whole point of symbols is that their names are unique: you can look up a
symbol and get back a unique address, and vice versa. Alas, because
/proc/kallsyms (rightly) reports all symbols, even hidden ones, it does not
really satisfy this requirement. Large numbers of symbols are duplicated
many times (just search for __list_del_entry!), and while usually these are
just out-of-lined things defined in header files and thus all have the same
implementation, it does make it needlessly hard to figure out which one is
which in stack dumps, when tracing, and such things. Some configuration
options make things much worse: my test make allyesconfig runs introduced
thousands of text symbols named _sub_I_65535_1, one per compiler-generated
object file, and it was fairly easy to make them appear in ftrace output.

Right now the kernel has no way at all to tell such symbols apart, and nor
has the user: their address differs and that's all. Which module did they
come from? Which object file? We don't know. Figuring out which is which
when tracing needs a combination of guesswork and luck, and if there are
thousands of them that's not a pleasant prospect. In discussions at LPC it
became clear that this is not just annoying me but Steve Rostedt and others,
so it's probably desirable to fix this.

It turns out that the linker, and the kernel build system, can be made to
give us everything we need to resolve this once and for all. This series
provides a new /proc/kallmodsyms which is like /proc/kallsyms except that it
annotates every (textual) symbol which comes from a built-in kernel module
with the module's name, in square brackets: if a symbol is used by multiple
modules, it gets [multiple] [names]; if a symbol is still ambiguous it gets
a cut-down {object file name}; the combination of symbol, [module] [names]
and {object file name} is unique (with one minor exception: the arm64 nvhe
module is pre-linked with ld -r, causing all symbols in it to appear to come
from the same object file: if it was reworked to use thin archives this
problem would go away).

The object file names are cut down to save space: we store only the shortest
suffix needed to distinguish symbols from each other. It's fairly rare even
to see two/level names, let alone three/level/ones. We also save even more
space by annotating every symbol in a given object file with the object file
name if we annotate any of them.

We also add new fields that let you get at this new info in the kallsyms
iterator.

In brief we do this by mapping from address ranges to object files (with
assistance from the linker map file), then mapping from those object files
to built-in kernel modules and object file names. Because the number of
object files is much smaller than the number of symbols, because we fuse
address range and object file entries together if possible, and because we
don't even store object file names unless we need to, this is a fairly
efficient representation, even with a bit of extra complexity to allow
object files to be in more than one module at once.

The size impact of all of this is minimal: in testing, vmlinux grew by 16632
bytes, and the compressed vmlinux only grew by 12544 bytes (about .1% of a
10MiB kernel): though this is very configuration-dependent, it seems likely
to scale roughly with the kernel as a whole.

This is all controlled by a new config parameter CONFIG_KALLMODSYMS, which when
set results in output in /proc/kallmodsyms that looks like this:

ffffffff97606e50 t not_visible
ffffffff97606e70 T perf_msr_probe
ffffffff97606f80 t test_msr [rapl]
ffffffffa6007350 t rapl_pmu_event_stop [rapl]
ffffffffa6007440 t rapl_pmu_event_del [rapl]
ffffffffa6007460 t rapl_hrtimer_handle [rapl]
ffffffffa6007500 t rapl_pmu_event_read [rapl]
ffffffffa6007520 t rapl_pmu_event_init [rapl]
ffffffffa6007630 t rapl_cpu_offline [rapl]
ffffffffa6007710 t amd_pmu_event_map {core.o}
ffffffffa6007750 t amd_pmu_add_event {core.o}
ffffffffa6007760 t amd_put_event_constraints_f17h {core.o}

The modular symbols are notated as [rapl] even if rapl is built into the
kernel. Further, at least one symbol nottated as {core.o} would have been
ambiguous without that notation. If we look a little further down, we see:

ffffffff97607a70 t cmask_show {core.o}
ffffffff97607ab0 t inv_show {core.o}
ffffffff97607ae0 t edge_show {core.o}
ffffffff97607b10 t umask_show {core.o}
ffffffff97607b40 t event_show {core.o}

where event_show in particular is highly ambiguous and appears in many
object files, all of which are now notated with different {object file
names}.

Further down, we see what happens when object files are reused by multiple
modules, all of which are built in to the kernel, and some of which contain
symbols that are ambiguously-named even within that set of modules:

ffffffff97d7aed0 t liquidio_pcie_mmio_enabled [liquidio]
ffffffff97d7aef0 t liquidio_pcie_resume [liquidio]
ffffffff97d7af00 t liquidio_ptp_adjtime [liquidio]
ffffffff97d7af50 t liquidio_ptp_enable [liquidio]
ffffffff97d7af70 t liquidio_get_stats64 [liquidio]
ffffffff97d7b0f0 t liquidio_fix_features [liquidio]
ffffffff97d7b1c0 t liquidio_get_port_parent_id [liquidio]
[...]
ffffffff97d824c0 t lio_vf_rep_modinit [liquidio]
ffffffff97d824f0 t lio_vf_rep_modexit [liquidio]
ffffffff97d82520 t lio_ethtool_get_channels [liquidio] [liquidio_vf]
ffffffff97d82600 t lio_ethtool_get_ringparam [liquidio] [liquidio_vf]
ffffffff97d826a0 t lio_get_msglevel [liquidio] [liquidio_vf]
ffffffff97d826c0 t lio_vf_set_msglevel [liquidio] [liquidio_vf]
ffffffff97d826e0 t lio_get_pauseparam [liquidio] [liquidio_vf]
ffffffff97d82710 t lio_get_ethtool_stats [liquidio] [liquidio_vf]
ffffffff97d82e70 t lio_vf_get_ethtool_stats [liquidio] [liquidio_vf]
[...]
ffffffff97d91a80 t cn23xx_vf_mbox_thread [liquidio] [liquidio_vf] {cn23xx_vf_device.o}
ffffffff97d91aa0 t cpumask_weight.constprop.0 [liquidio] [liquidio_vf] {cn23xx_vf_device.o}
ffffffff97d91ac0 t cn23xx_vf_msix_interrupt_handler [liquidio] [liquidio_vf] {cn23xx_vf_device.o}
ffffffff97d91bd0 t cn23xx_vf_get_oq_ticks [liquidio] [liquidio_vf] {cn23xx_vf_device.o}
ffffffff97d91c00 t cn23xx_vf_ask_pf_to_do_flr [liquidio] [liquidio_vf] {cn23xx_vf_device.o}
ffffffff97d91c70 t cn23xx_octeon_pfvf_handshake [liquidio] [liquidio_vf] {cn23xx_vf_device.o}
ffffffff97d91e20 t cn23xx_setup_octeon_vf_device [liquidio] [liquidio_vf] {cn23xx_vf_device.o}
ffffffff97d92060 t octeon_mbox_read [liquidio] [liquidio_vf]
ffffffff97d92230 t octeon_mbox_write [liquidio] [liquidio_vf]
[...]
ffffffff97d946b0 t octeon_alloc_soft_command_resp [liquidio] [liquidio_vf]
ffffffff97d947e0 t octnet_send_nic_data_pkt [liquidio] [liquidio_vf]
ffffffff97d94820 t octnet_send_nic_ctrl_pkt [liquidio] [liquidio_vf]
ffffffff97d94ab0 t liquidio_get_stats64 [liquidio_vf]
ffffffff97d94c10 t liquidio_fix_features [liquidio_vf]
ffffffff97d94cd0 t wait_for_pending_requests [liquidio_vf]

Like /proc/kallsyms, the output is sorted by address, so keeps the curious
property of /proc/kallsyms that symbols may appear repeatedly with different
addresses: but now, unlike in /proc/kallsyms, we can see that those symbols
appear repeatedly because they are *different symbols* that ultimately
belong to different modules or different object files, all of which are
built in to the kernel.

Note that kernel symbols for built-in modules will probably appear
interspersed with other symbols that are part of different modules and
non-modular always-built-in symbols, which, as usual, have no
square-bracketed module denotation (though they might have an {object file
name}.

As with /proc/kallsyms, non-root usage produces addresses that are all zero.

Tested with a make allyesconfig and allmodconfig, and with and without
CONFIG_X86_KERNEL_IBT.

Limitations:

- this approach only works for textual symbols (and weak ones). I don't
see any way to make it work for data symbols etc: except for initialized
data they don't really have corresponding object files at all and they
tend to get merged together anyway.

- Compiling with clang LTO is untested. Compiling with X86 IBT now works,
but .cold-partitioned symbols are not attributed to any objfiles right
now (currently, this results in no conflicts on a make allyesconfig
build, so it's harmless).

- Non-built-in modules can also have ambiguous symbols in them in different
input object files: they aren't handled yet because kallsyms never runs
over modules to create the necessary sections. This is fixable, but it's
probably best handled in another patch series. (kallsyms would need to
do much less work for modules: only the sections introduced by this patch
series would need emission at all, and no [module] notations would be
needed, only {objfile}.)

- Section start/end symbols necessarily lie on the boundary between object
files, so are sometimes misreported as being in the wrong object file or
module. This is unlikely to be too troublesome for these symbols in
particular, but if anyone can figure out a way to fix this I'd be happy
to do it.

- There is no BPF iterator support yet (it's just a matter of adding it
if needed).

The commits in this series all have reviewed-by tags: they're all from
internal reviews, so please ignore them.

Differences from v9, early November 2022:

- Rework to use Luis Chamberlain's modules.builtin.objs rather than a
tristate-generated "modules_thick.builtin". Keep the iterator over
modules_thick.builtin, but rename it to scripts/modules_builtin.c and
make it more robust against strange lines in modules.builtin.objs,
such as lines with no colon in.
- Rework the old modules_thick.builtin stuff into a "tristate checker"
which warns about source files that contain MODULE_LICENSE for which
the corresponding Kconfig symbol is of type 'bool' rather than
'tristate'. It no longer runs unless requested, so doesn't slow
the build down with a big recursion across the whole source tree.
- Fix up a bunch of places where the tristate checker (and the old
modules_thick.builtin and modules.builtin generators) gave the wrong
answers, usually considering things to be modules that actually
unconditionally built in. (16 makefiles touched.)
- Eliminate MODULE_LICENSE/AUTHOR/DESCRIPTION from a bunch of things
that cannot actually be modules: aarch64 and x86_64 are now clean,
other arches not checked. Verified with make allmodconfig on both
arches. (189 not-actually-modules touched.)
- Use the CONFIG_VMLINUX_MAP machinery rather than generating a whole
second linker mapfile.
- Add (in a separate commit since it is largely conceptually separate)
support for the ld -r linking used by CONFIG_X86_KERNEL_IBT.
- Add a special kallsyms build-time warning for ambiguous symbols that
came from the same object file: note that they are probably the
result of ld -r.
- When lengthening shortened objfile names to resolve an ambiguity,
always lengthen the name of the objfile with the longer (unshortened)
length, fixing ambiguous objfiles with names which are substrings of
other objfiles' names.
- Fix a bug which could cause inflooping when outputting the
.kallsyms_mod_objnames section.
- Rebase atop modules-next.

Differences from v8, February 2022:

- Add object file name handling, emitting only those object names needed to
disambiguate symbols, shortening them as much as possible compatible with
that.
- Rename .kallsyms_module_names to .kallsyms_mod_objnames now that it
contains object file names too.
- Fix a bug in optimize_obj2mod that prevented proper reuse of module names
for object files appearing in both multimodule modules and single-module
modules: saves a few KiB more, often more than the space increase due to
object file name handling.
- Rebased atop v6.1-rc2: move modules_thick.builtin generation into
the top-level Kbuild accordingly, and adjust to getopt_long use in
scripts/kallsyms.
- Significant revisions to the cover letter.
- Add proof-of-concept kallmodsyms module support to perf.
- (This ping) confirmed that series applies atop v6.1-rc4 without
further changes.

Differences from v7, December 2021:

- Adjust for changes in the v5.17 merge window. Adjust a few commit
messages and shrink the cover letter.
- Drop the symbol-size patch, probably better done from userspace.

Differences from v6, November 2021:

- Adjust for rewrite of confdata machinery in v5.16 (tristate.conf
handling is now more of a rewrite than a reversion)

Differences from v5, October 2021:

- Fix generation of mapfiles under UML

Differences from v4, September 2021:

- Fix building of tristate.conf if missing (usually concealed by the
syncconfig being run for other reasons, but not always: the kernel
test robot spotted it).
- Forward-port atop v5.15-rc3.

Differences from v3, August 2021:

- Fix a kernel test robot warning in get_ksymbol_core (possible
use of uninitialized variable if kallmodsyms was wanted but
kallsyms_module_offsets was not present, which is most unlikely).

Differences from v2, June 2021:

- Split the series up. In particular, the size impact of the table
optimizer is now quantified, and the symbol-size patch is split out and
turned into an RFC patch, with the /proc/kallmodsyms format before that
patch lacking a size column. Some speculation on how to make the symbol
sizes less space-wasteful is added (but not yet implemented).

- Drop a couple of unnecessary #includes, one unnecessarily exported
symbol, and a needless de-staticing.

Differences from v1, in 2019:

- Move from a straight symbol->module name mapping to a mapping from
address-range to TU to module name list, bringing major space savings
over the previous approach and support for object files used by many
built-in modules at the same time, at the cost of a slightly more complex
approach (unavoidably so, I think, given that we have to merge three data
sources together: the link map in .tmp_vmlinux.ranges, the nm output on
stdin, and the mapping from TU name to module names in
modules_thick.builtin).

We do opportunistic merging of TUs if they cite the same modules and
reuse module names where doing so is simple: see optimize_obj2mod below.
I considered more extensive searches for mergeable entries and more
intricate encodings of the module name list allowing TUs that are used by
overlapping sets of modules to share their names, but such modules are
rare enough (and such overlapping sharings are vanishingly rare) that it
seemed likely to save only a few bytes at the cost of much more
hard-to-test code. This is doubly true now that the tables needed are
only a few kilobytes in length.

Signed-off-by: Nick Alcock <[email protected]>
Signed-off-by: Eugene Loh <[email protected]>
Reviewed-by: Kris Van Hees <[email protected]>

Luis Chamberlain (1):
kbuild: add modules.builtin.objs

Nick Alcock (12):
kbuild: bring back tristate.conf
kbuild: add tristate checker
kbuild: fix up substitutions in makefiles to allow for tristate
checker
kbuild: remove MODULE_LICENSE/AUTHOR/DESCRIPTION in non-modules
build: add a simple iterator over modules.builtin.objs
kbuild: generate an address ranges map at vmlinux link time
kbuild: make address ranges map work with IBT
kallsyms: introduce sections needed to map symbols to built-in modules
kallsyms: optimize .kallsyms_modules*
kallsyms: distinguish text symbols fully using object file names
kallsyms: add /proc/kallmodsyms for text symbol disambiguation
perf: proof-of-concept kallmodsyms support

.gitignore | 3 +-
Documentation/dontdiff | 4 +-
Documentation/kbuild/kbuild.rst | 5 +
Documentation/kbuild/kconfig.rst | 5 +
Makefile | 35 +-
arch/x86/crypto/blake2s-glue.c | 1 -
arch/x86/mm/debug_pagetables.c | 3 -
crypto/asymmetric_keys/asymmetric_type.c | 1 -
drivers/Makefile | 2 +-
.../accessibility/braille/braille_console.c | 4 -
drivers/amba/tegra-ahb.c | 3 -
drivers/android/binder.c | 1 -
drivers/bus/arm-cci.c | 2 -
drivers/bus/arm-integrator-lm.c | 3 -
drivers/bus/bt1-apb.c | 3 -
drivers/bus/bt1-axi.c | 3 -
drivers/bus/imx-weim.c | 3 -
drivers/bus/intel-ixp4xx-eb.c | 3 -
drivers/bus/qcom-ebi2.c | 3 -
drivers/bus/qcom-ssc-block-bus.c | 3 -
drivers/bus/simple-pm-bus.c | 3 -
drivers/clk/bcm/clk-bcm2835-aux.c | 3 -
drivers/clk/bcm/clk-bcm2835.c | 3 -
drivers/clk/clk-bm1880.c | 3 -
drivers/clk/clk-fixed-mmio.c | 3 -
drivers/clk/clk-fsl-sai.c | 3 -
drivers/clk/hisilicon/clk-hi3559a.c | 2 -
drivers/clk/microchip/clk-mpfs-ccc.c | 3 -
drivers/clk/microchip/clk-mpfs.c | 5 -
drivers/clk/renesas/rcar-usb2-clock-sel.c | 2 -
drivers/clk/renesas/renesas-cpg-mssr.c | 2 -
drivers/clk/renesas/rzg2l-cpg.c | 2 -
drivers/clocksource/em_sti.c | 3 -
drivers/clocksource/sh_cmt.c | 3 -
drivers/clocksource/sh_mtu2.c | 3 -
drivers/clocksource/sh_tmu.c | 3 -
drivers/clocksource/timer-stm32-lp.c | 2 -
drivers/clocksource/timer-tegra186.c | 3 -
drivers/clocksource/timer-ti-dm.c | 3 -
drivers/cpufreq/freq_table.c | 3 -
drivers/cpufreq/intel_pstate.c | 3 -
drivers/cpufreq/tegra124-cpufreq.c | 3 -
drivers/dma-buf/heaps/cma_heap.c | 2 -
drivers/dma-buf/heaps/system_heap.c | 1 -
drivers/dma-buf/udmabuf.c | 2 -
drivers/dma/ep93xx_dma.c | 3 -
drivers/dma/ipu/ipu_idmac.c | 3 -
drivers/dma/mv_xor_v2.c | 2 -
drivers/dma/s3c24xx-dma.c | 3 -
drivers/dma/sh/shdma-base.c | 3 -
drivers/dma/stm32-dmamux.c | 4 -
drivers/dma/stm32-mdma.c | 4 -
drivers/edac/altera_edac.c | 3 -
drivers/firmware/broadcom/bcm47xx_nvram.c | 1 -
drivers/firmware/imx/imx-scu.c | 3 -
drivers/firmware/imx/scu-pd.c | 3 -
drivers/gpio/gpio-aspeed-sgpio.c | 2 -
drivers/gpio/gpio-imx-scu.c | 3 -
drivers/gpio/gpio-mxs.c | 6 -
drivers/gpio/gpio-rda.c | 3 -
drivers/gpu/drm/drm_mipi_dsi.c | 3 -
drivers/hv/Makefile | 2 +-
drivers/hwspinlock/hwspinlock_core.c | 3 -
drivers/interconnect/core.c | 3 -
drivers/iommu/sun50i-iommu.c | 4 -
drivers/irqchip/irq-al-fic.c | 3 -
drivers/irqchip/irq-ls-scfg-msi.c | 3 -
drivers/irqchip/irq-mbigen.c | 4 -
drivers/irqchip/irq-mchp-eic.c | 3 -
drivers/irqchip/irq-mvebu-pic.c | 3 -
drivers/irqchip/irq-renesas-intc-irqpin.c | 3 -
drivers/irqchip/irq-renesas-irqc.c | 3 -
drivers/irqchip/irq-renesas-rza1.c | 3 -
drivers/irqchip/irq-renesas-rzg2l.c | 3 -
drivers/irqchip/irq-sl28cpld.c | 3 -
drivers/irqchip/irq-ti-sci-inta.c | 3 -
drivers/irqchip/irq-ti-sci-intr.c | 3 -
drivers/leds/leds-asic3.c | 3 -
drivers/mailbox/rockchip-mailbox.c | 4 -
drivers/mailbox/zynqmp-ipi-mailbox.c | 3 -
drivers/memory/bt1-l2-ctl.c | 3 -
drivers/memory/da8xx-ddrctl.c | 3 -
drivers/memory/fsl_ifc.c | 3 -
drivers/memory/mvebu-devbus.c | 3 -
drivers/memory/tegra/mc.c | 3 -
drivers/memory/tegra/tegra186-emc.c | 3 -
drivers/mfd/88pm860x-core.c | 3 -
drivers/mfd/altera-sysmgr.c | 3 -
drivers/mfd/bcm2835-pm.c | 3 -
drivers/mfd/da903x.c | 4 -
drivers/mfd/da9052-core.c | 3 -
drivers/mfd/da9052-i2c.c | 3 -
drivers/mfd/da9052-spi.c | 3 -
drivers/mfd/da9055-core.c | 3 -
drivers/mfd/da9055-i2c.c | 3 -
drivers/mfd/ezx-pcap.c | 3 -
drivers/mfd/intel_soc_pmic_crc.c | 4 -
drivers/mfd/lp8788.c | 3 -
drivers/mfd/omap-usb-host.c | 4 -
drivers/mfd/omap-usb-tll.c | 4 -
drivers/mfd/palmas.c | 3 -
drivers/mfd/stmpe-i2c.c | 3 -
drivers/mfd/stmpe-spi.c | 3 -
drivers/mfd/tc3589x.c | 3 -
drivers/mfd/tps6586x.c | 3 -
drivers/mfd/twl4030-audio.c | 3 -
drivers/mfd/twl6040.c | 4 -
drivers/mmc/Makefile | 2 +-
drivers/mtd/parsers/bcm63xxpart.c | 6 -
drivers/net/wireless/silabs/wfx/Makefile | 2 +-
drivers/nvmem/core.c | 4 -
drivers/nvmem/zynqmp_nvmem.c | 3 -
drivers/pci/controller/dwc/pcie-histb.c | 2 -
.../controller/mobiveil/pcie-mobiveil-plat.c | 3 -
drivers/pci/controller/pci-tegra.c | 1 -
drivers/pci/controller/pci-versatile.c | 2 -
drivers/pci/controller/pcie-hisi-error.c | 2 -
drivers/pci/controller/pcie-microchip-host.c | 3 -
drivers/pci/endpoint/pci-ep-cfs.c | 3 -
drivers/pci/endpoint/pci-epc-core.c | 3 -
drivers/pci/endpoint/pci-epc-mem.c | 3 -
drivers/pci/endpoint/pci-epf-core.c | 3 -
drivers/pci/hotplug/acpiphp_core.c | 3 -
drivers/pci/hotplug/shpchp_core.c | 3 -
drivers/perf/apple_m1_cpu_pmu.c | 1 -
drivers/phy/intel/phy-intel-lgm-combo.c | 2 -
drivers/pinctrl/actions/pinctrl-s500.c | 4 -
drivers/pinctrl/actions/pinctrl-s700.c | 3 -
drivers/pinctrl/actions/pinctrl-s900.c | 4 -
drivers/pinctrl/bcm/pinctrl-ns.c | 2 -
drivers/pinctrl/mediatek/pinctrl-mt8188.c | 2 -
drivers/pinctrl/mediatek/pinctrl-mt8192.c | 2 -
drivers/pinctrl/mediatek/pinctrl-mt8365.c | 3 -
drivers/pinctrl/nuvoton/pinctrl-npcm7xx.c | 4 -
drivers/pinctrl/pinctrl-amd.c | 3 -
drivers/pinctrl/renesas/pinctrl-rza1.c | 3 -
drivers/pinctrl/renesas/pinctrl-rza2.c | 3 -
drivers/pinctrl/renesas/pinctrl-rzg2l.c | 3 -
drivers/pinctrl/renesas/pinctrl-rzn1.c | 3 -
drivers/pinctrl/renesas/pinctrl-rzv2m.c | 3 -
drivers/power/reset/as3722-poweroff.c | 3 -
drivers/power/reset/gpio-poweroff.c | 3 -
drivers/power/reset/gpio-restart.c | 3 -
drivers/power/reset/keystone-reset.c | 3 -
drivers/power/reset/ltc2952-poweroff.c | 3 -
drivers/power/reset/mt6323-poweroff.c | 3 -
drivers/power/reset/regulator-poweroff.c | 3 -
drivers/power/reset/restart-poweroff.c | 3 -
drivers/power/reset/tps65086-restart.c | 3 -
drivers/power/supply/power_supply_core.c | 6 -
drivers/power/supply/wm97xx_battery.c | 3 -
drivers/powercap/powercap_sys.c | 3 -
drivers/regulator/stm32-pwr.c | 3 -
drivers/remoteproc/remoteproc_core.c | 2 -
drivers/reset/reset-axs10x.c | 3 -
drivers/reset/reset-hsdk.c | 3 -
drivers/reset/reset-lantiq.c | 3 -
drivers/reset/reset-microchip-sparx5.c | 3 -
drivers/reset/reset-mpfs.c | 3 -
drivers/s390/char/Makefile | 2 +-
drivers/s390/crypto/Makefile | 2 +-
drivers/soc/apple/apple-pmgr-pwrstate.c | 3 -
drivers/soc/bcm/bcm2835-power.c | 3 -
drivers/soc/bcm/raspberrypi-power.c | 4 -
drivers/soc/fujitsu/a64fx-diag.c | 3 -
drivers/soc/sunxi/sunxi_sram.c | 3 -
drivers/soc/tegra/cbb/tegra194-cbb.c | 3 -
drivers/soc/tegra/cbb/tegra234-cbb.c | 2 -
drivers/tty/n_null.c | 3 -
drivers/tty/serial/imx_earlycon.c | 3 -
drivers/tty/serial/rda-uart.c | 3 -
drivers/video/console/vgacon.c | 1 -
drivers/video/fbdev/asiliantfb.c | 1 -
drivers/video/fbdev/gbefb.c | 1 -
drivers/video/fbdev/imsttfb.c | 1 -
drivers/video/fbdev/mmp/hw/mmp_ctrl.c | 3 -
.../video/fbdev/mmp/panel/tpo_tj032md01bw.c | 3 -
drivers/video/fbdev/vesafb.c | 1 -
drivers/video/fbdev/wm8505fb.c | 3 -
drivers/video/fbdev/wmt_ge_rops.c | 4 -
drivers/xen/grant-dma-ops.c | 3 -
drivers/xen/xenbus/xenbus_probe.c | 1 -
fs/binfmt_elf.c | 1 -
fs/nfs_common/nfs_ssc.c | 1 -
fs/unicode/utf8-core.c | 1 -
include/linux/module.h | 4 +-
init/Kconfig | 10 +
kernel/dma/map_benchmark.c | 3 -
kernel/events/hw_breakpoint_test.c | 2 -
kernel/kallsyms.c | 277 +++-
kernel/kallsyms_internal.h | 14 +
kernel/trace/rv/reactor_panic.c | 3 -
kernel/trace/rv/reactor_printk.c | 3 -
kernel/watch_queue.c | 3 -
lib/btree.c | 3 -
lib/crypto/blake2s-generic.c | 3 -
lib/crypto/blake2s.c | 3 -
lib/glob.c | 2 -
lib/packing.c | 2 -
lib/pldmfw/pldmfw.c | 3 -
lib/test_fprobe.c | 1 -
mm/zpool.c | 3 -
mm/zswap.c | 3 -
net/8021q/Makefile | 2 +-
net/Makefile | 2 +-
net/bridge/Makefile | 4 +-
net/dccp/Makefile | 4 +-
net/ipv6/Makefile | 2 +-
net/l2tp/Makefile | 12 +-
net/mctp/af_mctp.c | 3 -
net/netfilter/Makefile | 2 +-
net/netlabel/Makefile | 2 +-
net/sctp/Makefile | 2 +-
scripts/.gitignore | 1 +
scripts/Kbuild.include | 21 +
scripts/Makefile | 7 +
scripts/Makefile.lib | 13 +-
scripts/Makefile.vmlinux_o | 21 +-
scripts/addaddrs.c | 28 +
scripts/check-tristates.mk | 56 +
scripts/kallsyms.c | 1223 ++++++++++++++++-
scripts/kconfig/confdata.c | 41 +-
scripts/link-vmlinux.sh | 38 +-
scripts/modules_builtin.c | 200 +++
scripts/modules_builtin.h | 48 +
tools/perf/builtin-kallsyms.c | 35 +-
tools/perf/util/event.c | 14 +-
tools/perf/util/machine.c | 6 +-
tools/perf/util/machine.h | 1 +
tools/perf/util/symbol.c | 207 ++-
tools/perf/util/symbol.h | 12 +-
231 files changed, 2241 insertions(+), 671 deletions(-)
create mode 100644 scripts/addaddrs.c
create mode 100644 scripts/check-tristates.mk
create mode 100644 scripts/modules_builtin.c
create mode 100644 scripts/modules_builtin.h

--
2.38.0.266.g481848f278


2022-12-05 16:52:16

by Nick Alcock

[permalink] [raw]
Subject: [PATCH v10 11/13] kallsyms: distinguish text symbols fully using object file names

The commits before this one will let /proc/kallmodsyms distinguish
identically-named text symbols located in different built-in object
files from each other; but identically-named symbols can appear in any
object files at all, including object files that cannot be built as
modules. Even modules can have identically-named symbols in them, in
distinct translation units. (This might seem like overdesign, after
all, how many such symbols can there be? But Some config options
introduce huge numbers of such symbols, notably _sub_I_65535_1: these
all contain code and might show up in trace output, but appear in almost
every compiled object file. Distinguishing them really needs machine
assistance: nobody wants to figure out which of three thousand
_sub_I_65535_1's is which by hand!)

We already have nearly all the machinery to disambiguate such symbols
reliably. Since any given object file emitted by the compiler can
contain at most one definition of a given symbol, it suffices to name
the object files containing any symbol which is otherwise ambiguous.
(No others need be named, saving a bunch of space).

We associate address ranges with object file names using a new
.kallsyms_objfiles section just like the previously-added
.kallsyms_modules section.

But that's not quite enough. Even the object file name is ambiguous in
some cases: e.g. there are a lot of files named "core.o" in the kernel.
We could just store the full pathname for every object file, but this is
needlessly wasteful: doing this eats more than 50KiB in object file
names alone, and nearly all the content of every name is repeated for
many names. But if we store the object file names in the same section
as the built-in module names, drop the .o, and store minimal path
suffixes, we can save almost all that space. (For example, "core.o"
would be stored as "core" unless there are ambiguous symbols in two
different object files both named "core", in which case they'd be named
"sched/core" and "futex/core", etc, possibly re-extending to
"kernel/sched/core" if still ambiguous).

We do this by a repeated-rehashing process. First, we compute a hash
value for symbol\0modhash for every symbol (the modhash is ignored if
this is a built-in symbol). Any two symbols with the same such hash are
identically-named: add the maximally-shortened (one-component,
.o-stripped) object file name for all such symbols, and rehash, this
time hashing symbol\0objname\0modhash. Any two symbols which still have
the same hash are still ambiguous: lengthen the name given to one of the
symbols' object files and repeat -- we pick the object file with the
longest full pathname so that we can disambiguate e.g.
arch/x86/kernel/smp.o and kernel/smp.o from each other.
Eventually, all the ambiguity will go away. (We do have to take care
not to re-lengthen anything we already lengthened in any given hashing
round.)

This involves multiple sorting passes but the impact on compilation time
appears to be nearly zero, and the impact on space in the running kernel
is noticeable: only a few dozen names usually need lengthening, so we
can completely ignore the overhead from storing repeated path components
because there are hardly any of them.

But that's not all. We can also do similar optimization tricks to what
was done with .kallsyms_modules, reusing module names and names of
already-emitted object files: so any given object file name only appears
once in the strtab, and can be cited by many address ranges and even by
module entries.

Put all this together and the net overhead of this in my testing is
about 3KiB of new object file names in the .kallsyms_mod_objnames table
and 6KiB for the .kallsyms_objfiles table (mostly zeroes: in future
maybe we can find a way to elide some of those, but 6KiB is small enough
that it's not worth taking too much effort).

No ambiguous textual symbols remain outside actual modules (which can
still contain identically-named symbols in different object files
because kallsyms doesn't run over them so none of these tables can be
built for them. At least, it doesn't yet). We warn about any ambiguous
symbols we find at build time.

(Caveat: the nvhe module on aarch64 is still linked with ld -r, which
causes its contents to appear to come from a single object file when the
linker emits its final mapfile. We spot such unfixable ambiguous
symbols and don't warn about them because there's nothing we can do. The
solution is probably to fix nvhe so it uses thin archives like
everything else does.)

Signed-off-by: Nick Alcock <[email protected]>
Reviewed-by: Kris Van Hees <[email protected]>
---

Notes:
v9: new.
v10: Handle objnames that are substrings of other objnames. Warn
about conflicts which seem to be the result of ld -r. Fix
potential infloop emitting .kallsyms_mod_objnames.
Mention ultimate user (kallmodsyms), problems with ld -r and
aarch64 nvhe in commit log.

scripts/kallsyms.c | 595 ++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 582 insertions(+), 13 deletions(-)

diff --git a/scripts/kallsyms.c b/scripts/kallsyms.c
index 4d8289040ad5..ecb993efe499 100644
--- a/scripts/kallsyms.c
+++ b/scripts/kallsyms.c
@@ -115,6 +115,9 @@ static unsigned int memhash(char *s, size_t len)
return hash;
}

+/*
+ * Object file -> module and shortened object file name tracking machinery.
+ */
#define OBJ2MOD_BITS 10
#define OBJ2MOD_N (1 << OBJ2MOD_BITS)
#define OBJ2MOD_MASK (OBJ2MOD_N - 1)
@@ -145,15 +148,40 @@ struct obj2mod_elem {
struct obj2mod_elem *mod2obj_next;
};

+/*
+ * Shortened object file names. These are only ever consulted after checking
+ * the obj2mod hashes: names that already exist in there are used directly from
+ * there (pointed to via the mod_xref field) rather than being re-emitted.
+ * Entries that do not exist there are added to the end of the mod_objnames
+ * list.
+ */
+struct obj2short_elem {
+ const char *obj;
+ char *desuffixed; /* objname sans suffix */
+ const char *short_obj; /* shortened at / and suffix */
+ int short_offset; /* offset of short name in .kallsyms_mod_objnames */
+ int last_rehash; /* used during disambiguate_hash_syms */
+
+ struct obj2mod_elem *mod_xref;
+ struct obj2short_elem *short_xref;
+ struct obj2short_elem *short_next;
+};
+
/*
* Map from object files to obj2mod entries (a unique mapping), and vice versa
* (not unique, but entries for objfiles in more than one module in this hash
- * are ignored).
+ * are ignored); also map from object file names to shortened names for them
+ * (also unique: there is no point storing both longer and shorter forms of one
+ * name, so if a longer name is needed we consistently use it instead of the
+ * shorter form.)
+ *
+ * obj2short is populated very late, at disambiguate_syms time.
*/

static struct obj2mod_elem *obj2mod[OBJ2MOD_N];
static struct obj2mod_elem *mod2obj[OBJ2MOD_N];
-static size_t num_objfiles;
+static struct obj2short_elem *obj2short[OBJ2MOD_N];
+static size_t num_objfiles, num_shortnames;

/*
* An ordered list of address ranges and the objfile that occupies that range.
@@ -167,6 +195,9 @@ struct addrmap_entry {
static struct addrmap_entry *addrmap;
static int addrmap_num, addrmap_alloced;

+static void disambiguate_syms(void);
+static void optimize_objnames(void);
+
static void obj2mod_init(void)
{
memset(obj2mod, 0, sizeof(obj2mod));
@@ -184,6 +215,18 @@ static struct obj2mod_elem *obj2mod_get(const char *obj)
return NULL;
}

+static struct obj2short_elem *obj2short_get(const char *obj)
+{
+ int i = strhash(obj) & OBJ2MOD_MASK;
+ struct obj2short_elem *elem;
+
+ for (elem = obj2short[i]; elem; elem = elem->short_next) {
+ if (strcmp(elem->obj, obj) == 0)
+ return elem;
+ }
+ return NULL;
+}
+
/*
* Note that a given object file is found in some module, interning it in the
* obj2mod hash. Should not be called more than once for any given (module,
@@ -256,6 +299,12 @@ static int qmodhash(const void *a, const void *b)
return 0;
}

+static int qobj2short(const void *a, const void *b)
+{
+ return strcmp((*(struct obj2short_elem **)a)->short_obj,
+ (*(struct obj2short_elem **)b)->short_obj);
+}
+
/*
* Associate all object files in obj2mod which refer to the same module with a
* single obj2mod entry for emission, preferring to point into the module list
@@ -395,6 +444,370 @@ static void optimize_obj2mod(void)
fprintf(stderr, "kallsyms: out of memory optimizing module list\n");
exit(EXIT_FAILURE);
}
+
+/*
+ * Associate all short-name entries in obj2short that refer to the same short
+ * name with a single entry for emission, either (preferably) a module that
+ * shares that name or (alternatively) the first obj2short entry referencing
+ * that name.
+ */
+static void optimize_objnames(void)
+{
+ size_t i;
+ size_t num_objnames = 0;
+ struct obj2short_elem *elem;
+ struct obj2short_elem **uniq;
+ struct obj2short_elem *last;
+
+ uniq = malloc(sizeof(struct obj2short_elem *) * num_shortnames);
+ if (uniq == NULL) {
+ fprintf(stderr, "kallsyms: out of memory optimizing object file name list\n");
+ exit(EXIT_FAILURE);
+ }
+
+ /*
+ * Much like optimize_obj2mod, except there is no need to canonicalize
+ * anything or handle multimodule entries, and we need to chase down
+ * possible entries in mod2obj first (so as not to duplicate them in the
+ * final kallsyms_mod_objnames strtab).
+ */
+ for (i = 0; i < OBJ2MOD_N; i++)
+ for (elem = obj2short[i]; elem; elem = elem->short_next)
+ uniq[num_objnames++] = elem;
+
+ qsort(uniq, num_objnames, sizeof(struct obj2short_elem *), qobj2short);
+
+ for (i = 0, last = NULL; i < num_objnames; i++) {
+ int h = strhash(uniq[i]->short_obj) & OBJ2MOD_MASK;
+ struct obj2mod_elem *mod_elem;
+
+ for (mod_elem = mod2obj[h]; mod_elem;
+ mod_elem = mod_elem->mod2obj_next) {
+ /*
+ * mod_elem entries are only valid if they are for
+ * single-module objfiles: see obj2mod_add
+ */
+ if (mod_elem->nmods > 1)
+ continue;
+
+ if (strcmp(mod_elem->mods, uniq[i]->short_obj) != 0)
+ continue;
+ uniq[i]->mod_xref = mod_elem;
+ break;
+ }
+
+ /*
+ * Only look for a short_xref match if we don't already have one
+ * in mod_xref. (This means that multiple objfiles with the
+ * same short name that is also a module name all chain directly
+ * to the module name via mod_xref, rather than going through a
+ * chain of short_xrefs.)
+ */
+ if (uniq[i]->mod_xref)
+ continue;
+
+ if (last != NULL && strcmp(last->short_obj,
+ uniq[i]->short_obj) == 0) {
+ uniq[i]->short_xref = last;
+ continue;
+ }
+
+ last = uniq[i];
+ }
+
+ free(uniq);
+}
+
+/*
+ * Used inside disambiguate_syms to identify colliding symbols. We spot this by
+ * hashing symbol\0modhash (or just the symbol name if this is in the core
+ * kernel) and seeing if that collides. (This means we don't need to bother
+ * canonicalizing the module list, since optimize_obj2mod already did it for
+ * us.)
+ *
+ * If that collides, we try disambiguating by adding ever-longer pieces of the
+ * object file name before the modhash until we no longer collide. The result
+ * of this repeated addition becomes the obj2short hashtab.
+ */
+struct sym_maybe_collides {
+ struct sym_entry *sym;
+ struct addrmap_entry *addr;
+ unsigned int symhash;
+ int warned;
+};
+
+static int qsymhash(const void *a, const void *b)
+{
+ const struct sym_maybe_collides *el_a = a;
+ const struct sym_maybe_collides *el_b = b;
+ if (el_a->symhash < el_b->symhash)
+ return -1;
+ else if (el_a->symhash > el_b->symhash)
+ return 1;
+ return 0;
+}
+
+static int find_addrmap(const void *a, const void *b)
+{
+ const struct sym_entry *sym = a;
+ const struct addrmap_entry *map = b;
+
+ if (sym->addr < map->addr)
+ return -1;
+ else if (sym->addr >= map->end_addr)
+ return 1;
+ return 0;
+}
+
+/*
+ * Allocate or lengthen an object file name for a symbol that needs it.
+ */
+static int lengthen_short_name(struct sym_maybe_collides *sym,
+ struct sym_maybe_collides *last_sym,
+ int hash_cycle)
+{
+ struct obj2short_elem *short_objname;
+
+ /*
+ * If both symbols come from the same object file, skip as unresolvable
+ * and avoid retrying. This can happen if the intermediate object file
+ * was partially linked via ld -r, concealing the original object file
+ * names from the linker and thus from us.
+ */
+ if (strcmp(last_sym->addr->obj, sym->addr->obj) == 0) {
+ if (!sym->warned && !last_sym->warned) {
+ fprintf(stderr, "Symbol %s appears multiple times in %s; likely linked with ld -r; entry in /proc/kallmodsyms will be ambiguous\n",
+ &sym->sym->sym[1], sym->addr->obj);
+ }
+ sym->warned = 1;
+ last_sym->warned = 1;
+ return 0;
+ }
+
+ /*
+ * Always lengthen the symbol that has the longest objname to lengthen,
+ * ensuring that where one objname is a strict subset of another, we
+ * always lengthen the one that will eventually resolve the ambiguity.
+ */
+ if (strlen(last_sym->addr->obj) > strlen(sym->addr->obj)) {
+ struct sym_maybe_collides *tmp;
+
+ tmp = sym;
+ sym = last_sym;
+ last_sym = tmp;
+ }
+
+ short_objname = obj2short_get(sym->addr->obj);
+
+ if (!short_objname) {
+ int i = strhash(sym->addr->obj) & OBJ2MOD_MASK;
+ char *p;
+
+ short_objname = malloc(sizeof(struct obj2short_elem));
+ if (short_objname == NULL)
+ goto oom;
+
+ /*
+ * New symbol: try maximal shortening, which is just the object
+ * file name (no directory) with the suffix removed (the suffix
+ * is useless for disambiguation since it is almost always .o).
+ *
+ * Add a bit of paranoia to allow for names starting with /,
+ * ending with ., and names with no suffix. (At least two of
+ * these are most unlikely, but possible.)
+ */
+
+ memset(short_objname, 0, sizeof(struct obj2short_elem));
+ short_objname->obj = sym->addr->obj;
+
+ p = strrchr(sym->addr->obj, '.');
+ if (p)
+ short_objname->desuffixed = strndup(sym->addr->obj,
+ p - sym->addr->obj);
+ else
+ short_objname->desuffixed = strdup(sym->addr->obj);
+
+ if (short_objname->desuffixed == NULL)
+ goto oom;
+
+ p = strrchr(short_objname->desuffixed, '/');
+ if (p && p[1] != 0)
+ short_objname->short_obj = p + 1;
+ else
+ short_objname->short_obj = short_objname->desuffixed;
+
+ short_objname->short_next = obj2short[i];
+ short_objname->last_rehash = hash_cycle;
+ obj2short[i] = short_objname;
+
+ num_shortnames++;
+ return 1;
+ }
+
+ /*
+ * Objname already lengthened by a previous symbol clash: do nothing
+ * until we rehash again.
+ */
+ if (short_objname->last_rehash == hash_cycle)
+ return 0;
+ short_objname->last_rehash = hash_cycle;
+
+ /*
+ * Existing symbol: lengthen the objname we already have.
+ */
+
+ if (short_objname->desuffixed == short_objname->short_obj) {
+ fprintf(stderr, "Cannot disambiguate %s: objname %s is "
+ "max-length but still colliding\n",
+ &sym->sym->sym[1], short_objname->short_obj);
+ return 0;
+ }
+
+ /*
+ * Allow for absolute paths, where the first byte is '/'.
+ */
+
+ if (short_objname->desuffixed >= short_objname->short_obj - 2)
+ short_objname->short_obj = short_objname->desuffixed;
+ else {
+ for (short_objname->short_obj -= 2;
+ short_objname->short_obj > short_objname->desuffixed &&
+ *short_objname->short_obj != '/';
+ short_objname->short_obj--);
+
+ if (*short_objname->short_obj == '/')
+ short_objname->short_obj++;
+ }
+ return 1;
+ oom:
+ fprintf(stderr, "Out of memory disambiguating syms\n");
+ exit(EXIT_FAILURE);
+}
+
+/*
+ * Do one round of disambiguation-check symbol hashing, factoring in the current
+ * set of applicable shortened object file names for those symbols that need
+ * them.
+ */
+static void disambiguate_hash_syms(struct sym_maybe_collides *syms)
+{
+ size_t i;
+ for (i = 0; i < table_cnt; i++) {
+ struct obj2short_elem *short_objname = NULL;
+ char *tmp, *p;
+ size_t tmp_size;
+
+ if (syms[i].sym == NULL) {
+ syms[i].symhash = 0;
+ continue;
+ }
+
+ short_objname = obj2short_get(syms[i].addr->obj);
+
+ tmp_size = strlen((char *) &(syms[i].sym->sym[1])) + 1;
+
+ if (short_objname)
+ tmp_size += strlen(short_objname->short_obj) + 1;
+
+ if (syms[i].addr->objfile)
+ tmp_size += sizeof(syms[i].addr->objfile->modhash);
+
+ tmp = malloc(tmp_size);
+ if (tmp == NULL) {
+ fprintf(stderr, "Out of memory disambiguating syms\n");
+ exit(EXIT_FAILURE);
+ }
+
+ p = stpcpy(tmp, (char *) &(syms[i].sym->sym[1]));
+ p++;
+ if (short_objname) {
+ p = stpcpy(p, short_objname->short_obj);
+ p++;
+ }
+ if (syms[i].addr->objfile)
+ memcpy(p, &(syms[i].addr->objfile->modhash),
+ sizeof(syms[i].addr->objfile->modhash));
+
+ syms[i].symhash = memhash(tmp, tmp_size);
+ free(tmp);
+ }
+
+ qsort(syms, table_cnt, sizeof (struct sym_maybe_collides), qsymhash);
+}
+
+/*
+ * Figure out which object file names are necessary to disambiguate all symbols
+ * in the linked kernel: transform them for minimum length while retaining
+ * disambiguity: point to them in obj2short.
+ */
+static void disambiguate_syms(void)
+{
+ size_t i;
+ int retry;
+ int hash_cycle = 0;
+ unsigned int lasthash;
+ struct sym_maybe_collides *syms;
+
+ syms = calloc(table_cnt, sizeof(struct sym_maybe_collides));
+
+ if (syms == NULL)
+ goto oom;
+
+ /*
+ * Initial table population: symbol-dependent things not affected by
+ * disambiguation rounds.
+ */
+ for (i = 0; i < table_cnt; i++) {
+ struct addrmap_entry *addr;
+
+ /*
+ * Only bother doing anything for function symbols.
+ */
+ if (table[i]->sym[0] != 't' && table[i]->sym[0] != 'T' &&
+ table[i]->sym[0] != 'w' && table[i]->sym[0] != 'W')
+ continue;
+
+ addr = bsearch(table[i], addrmap, addrmap_num,
+ sizeof(struct addrmap_entry), find_addrmap);
+
+ /*
+ * Some function symbols (section start symbols, discarded
+ * non-text-range symbols, etc) don't appear in the linker map
+ * at all.
+ */
+ if (addr == NULL)
+ continue;
+
+ syms[i].sym = table[i];
+ syms[i].addr = addr;
+ }
+
+ do {
+ hash_cycle++;
+ retry = 0;
+ lasthash = 0;
+ disambiguate_hash_syms(syms);
+
+ for (i = 0; i < table_cnt; i++) {
+ if (syms[i].sym == NULL)
+ continue;
+ if (syms[i].symhash == lasthash) {
+ if (lengthen_short_name(&syms[i], &syms[i-1],
+ hash_cycle))
+ retry = 1;
+ }
+ lasthash = syms[i].symhash;
+ }
+ } while (retry);
+
+ free(syms);
+ return;
+ oom:
+ fprintf(stderr, "kallsyms: out of memory disambiguating syms\n");
+ exit(EXIT_FAILURE);
+
+}
+
#endif /* CONFIG_KALLMODSYMS */

static void usage(void)
@@ -426,6 +839,7 @@ static bool is_ignored_symbol(const char *name, char type)
"kallsyms_relative_base",
"kallsyms_num_syms",
"kallsyms_num_modules",
+ "kallsyms_num_objfiles",
"kallsyms_names",
"kallsyms_markers",
"kallsyms_token_table",
@@ -433,6 +847,7 @@ static bool is_ignored_symbol(const char *name, char type)
"kallsyms_module_offsets",
"kallsyms_module_addresses",
"kallsyms_modules",
+ "kallsyms_objfiles",
"kallsyms_mod_objnames",
"kallsyms_mod_objnames_len",
/* Exclude linker generated symbols which vary between passes */
@@ -702,6 +1117,7 @@ static void output_address(unsigned long long addr)
static void output_kallmodsyms_mod_objnames(void)
{
struct obj2mod_elem *elem;
+ struct obj2short_elem *short_elem;
size_t offset = 1;
size_t i;

@@ -757,15 +1173,77 @@ static void output_kallmodsyms_mod_objnames(void)
}
}
}
+
+ /*
+ * Module names are done; now emit objfile names that don't match
+ * objfile names. They go in the same section to enable deduplication
+ * between (maximally-shortened) objfile names and module names.
+ * (This is another reason why objfile names drop the suffix.)
+ */
+ for (i = 0; i < OBJ2MOD_N; i++) {
+ for (short_elem = obj2short[i]; short_elem;
+ short_elem = short_elem->short_next) {
+
+ struct obj2short_elem *out_elem = short_elem;
+
+ /* Already emitted? */
+ if (out_elem->mod_xref)
+ continue;
+
+ if (out_elem->short_xref)
+ out_elem = out_elem->short_xref;
+
+ if (out_elem->short_offset != 0)
+ continue;
+
+ printf("/* 0x%lx: shortened from %s */\n", offset,
+ out_elem->obj);
+
+ out_elem->short_offset = offset;
+ printf("\t.asciz\t\"%s\"\n", out_elem->short_obj);
+ offset += strlen(out_elem->short_obj) + 1;
+ }
+ }
+
printf("\n");
output_label("kallsyms_mod_objnames_len");
printf("\t.long\t%zi\n", offset);
}

+/*
+ * Return 1 if this address range cites the same built-in module and objfile
+ * name as the previous one.
+ */
+static int same_kallmodsyms_range(int i)
+{
+ struct obj2short_elem *last_short;
+ struct obj2short_elem *this_short;
+ if (i == 0)
+ return 0;
+
+ last_short = obj2short_get(addrmap[i-1].obj);
+ this_short = obj2short_get(addrmap[i].obj);
+
+ if (addrmap[i-1].objfile == addrmap[i].objfile) {
+
+ if ((last_short == NULL && this_short != NULL) ||
+ (last_short != NULL && this_short == NULL))
+ return 0;
+
+ if (last_short == NULL && this_short == NULL)
+ return 1;
+
+ if (strcmp(last_short->short_obj, this_short->short_obj) == 0)
+ return 1;
+ }
+ return 0;
+}
+
static void output_kallmodsyms_objfiles(void)
{
size_t i = 0;
size_t emitted_offsets = 0;
+ size_t emitted_modules = 0;
size_t emitted_objfiles = 0;

if (base_relative)
@@ -777,12 +1255,15 @@ static void output_kallmodsyms_objfiles(void)
long long offset;
int overflow;

- /*
- * Fuse consecutive address ranges citing the same object file
- * into one.
- */
- if (i > 0 && addrmap[i-1].objfile == addrmap[i].objfile)
- continue;
+ printf("/* 0x%llx--0x%llx: %s */\n", addrmap[i].addr,
+ addrmap[i].end_addr, addrmap[i].obj);
+
+ /*
+ * Fuse consecutive address ranges citing the same built-in
+ * module and objfile name into one.
+ */
+ if (same_kallmodsyms_range(i))
+ continue;

if (base_relative) {
if (!absolute_percpu) {
@@ -809,11 +1290,12 @@ static void output_kallmodsyms_objfiles(void)

for (i = 0; i < addrmap_num; i++) {
struct obj2mod_elem *elem = addrmap[i].objfile;
+ struct obj2mod_elem *orig_elem = NULL;
int orig_nmods;
const char *orig_modname;
int mod_offset;

- if (i > 0 && addrmap[i-1].objfile == addrmap[i].objfile)
+ if (same_kallmodsyms_range(i))
continue;

/*
@@ -821,8 +1303,10 @@ static void output_kallmodsyms_objfiles(void)
* built-in module.
*/
if (addrmap[i].objfile == NULL) {
+ printf("/* 0x%llx--0x%llx: %s: built-in */\n",
+ addrmap[i].addr, addrmap[i].end_addr, addrmap[i].obj);
printf("\t.long\t0x0\n");
- emitted_objfiles++;
+ emitted_modules++;
continue;
}

@@ -837,8 +1321,10 @@ static void output_kallmodsyms_objfiles(void)
* always points at the start of the xref target, so its offset
* can be used as is.
*/
- if (elem->xref)
+ if (elem->xref) {
+ orig_elem = elem;
elem = elem->xref;
+ }

if (elem->nmods == 1 || orig_nmods > 1) {

@@ -874,6 +1360,19 @@ static void output_kallmodsyms_objfiles(void)
* the multimodule entry.
*/
mod_offset += onemod - elem->mods + 2;
+
+ /*
+ * If this was the result of an xref chase, store this
+ * mod_offset in the original entry so we can just reuse
+ * it if an objfile shares this name.
+ */
+
+ printf("/* 0x%llx--0x%llx: %s: single-module ref to %s in multimodule at %x */\n",
+ addrmap[i].addr, addrmap[i].end_addr,
+ orig_elem->mods, onemod, elem->mod_offset);
+
+ if (orig_elem)
+ orig_elem->mod_offset = mod_offset;
}

/*
@@ -883,12 +1382,68 @@ static void output_kallmodsyms_objfiles(void)
assert(elem->mod_offset != 0);

printf("\t.long\t0x%x\n", mod_offset);
- emitted_objfiles++;
+ emitted_modules++;
}

- assert(emitted_offsets == emitted_objfiles);
+ assert(emitted_offsets == emitted_modules);
output_label("kallsyms_num_modules");
+ printf("\t.long\t%zi\n", emitted_modules);
+
+ output_label("kallsyms_objfiles");
+
+ for (i = 0; i < addrmap_num; i++) {
+ struct obj2short_elem *elem;
+ int mod_offset;
+
+ if (same_kallmodsyms_range(i))
+ continue;
+
+ /*
+ * No corresponding objfile name: no disambiguation needed;
+ * point at 0.
+ */
+ elem = obj2short_get(addrmap[i].obj);
+
+ if (elem == NULL) {
+ printf("/* 0x%llx--0x%llx: %s: unambiguous */\n",
+ addrmap[i].addr, addrmap[i].end_addr,
+ addrmap[i].obj);
+ printf("\t.long\t0x0\n");
+ emitted_objfiles++;
+ continue;
+ }
+
+ /*
+ * Maybe the name is also used for a module: if it is, it cannot
+ * be a multimodule.
+ */
+
+ if (elem->mod_xref) {
+ assert(elem->mod_xref->nmods == 1);
+ mod_offset = elem->mod_xref->mod_offset;
+ printf("/* 0x%llx--0x%llx: %s: shortened as %s, references module */\n",
+ addrmap[i].addr, addrmap[i].end_addr,
+ addrmap[i].obj, elem->short_obj);
+ } else {
+ /*
+ * A name only used for objfiles. Chase down xrefs to
+ * reuse existing entries.
+ */
+ if (elem->short_xref)
+ elem = elem->short_xref;
+
+ mod_offset = elem->short_offset;
+ printf("/* 0x%llx--0x%llx: %s: shortened as %s */\n",
+ addrmap[i].addr, addrmap[i].end_addr,
+ addrmap[i].obj, elem->short_obj);
+ }
+ printf("\t.long\t0x%x\n", mod_offset);
+ emitted_objfiles++;
+ }
+ assert(emitted_offsets == emitted_objfiles);
+ output_label("kallsyms_num_objfiles");
printf("\t.long\t%zi\n", emitted_objfiles);
+
printf("\n");
}
#endif /* CONFIG_KALLMODSYMS */
@@ -1501,6 +2056,20 @@ static void read_modules(const char *modules_builtin)
* Read linker map.
*/
read_linker_map();
+
+ /*
+ * Now the modules are sorted out and we know their address ranges, use
+ * the modhashes computed in optimize_obj2mod to identify any symbols
+ * that are still ambiguous and set up the minimal representation of
+ * their objfile name to disambiguate them.
+ */
+ disambiguate_syms();
+
+ /*
+ * Now we have objfile names, optimize the objfile list.
+ */
+ optimize_objnames();
+
}
#else
static void read_modules(const char *unused) {}
--
2.38.0.266.g481848f278

2022-12-05 16:52:35

by Nick Alcock

[permalink] [raw]
Subject: [PATCH v10 01/13] kbuild: add modules.builtin.objs

From: Luis Chamberlain <[email protected]>

The file modules.builtin contains all modules that are built into
the kernel and this is used by modprobe to not fail when trying to
load something builtin. But for tools which want to see which object
files come from what modules we want to help them with such a mapping
as it is not easy to get this otherwise.

We do this by just extending scripts/Makefile.lib with a new variable
and define to capture all possible objects, and stuff this into a new
modinfo.

Note that this doesn't bloat the kernel at all because as you can see
in include/asm-generic/vmlinux.lds.h, the .modinfo section is discarded
at the link stage.

Signed-off-by: Luis Chamberlain <[email protected]>
Reviewed-by: Nick Alcock <[email protected]>
---

Notes:
v10: new.

.gitignore | 2 +-
Documentation/dontdiff | 2 +-
Documentation/kbuild/kbuild.rst | 5 +++++
Makefile | 10 +++++++---
include/linux/module.h | 4 +++-
scripts/Makefile.lib | 5 ++++-
scripts/Makefile.vmlinux_o | 15 ++++++++++++++-
7 files changed, 35 insertions(+), 8 deletions(-)

diff --git a/.gitignore b/.gitignore
index 5da004814678..ef8665c64f21 100644
--- a/.gitignore
+++ b/.gitignore
@@ -67,7 +67,7 @@ modules.order
/System.map
/Module.markers
/modules.builtin
-/modules.builtin.modinfo
+/modules.builtin.*
/modules.nsdeps

#
diff --git a/Documentation/dontdiff b/Documentation/dontdiff
index 352ff53a2306..ed1fbc711f33 100644
--- a/Documentation/dontdiff
+++ b/Documentation/dontdiff
@@ -180,7 +180,7 @@ mkutf8data
modpost
modules-only.symvers
modules.builtin
-modules.builtin.modinfo
+modules.builtin.*
modules.nsdeps
modules.order
modversions.h*
diff --git a/Documentation/kbuild/kbuild.rst b/Documentation/kbuild/kbuild.rst
index 08f575e6236c..504f31517cb4 100644
--- a/Documentation/kbuild/kbuild.rst
+++ b/Documentation/kbuild/kbuild.rst
@@ -17,6 +17,11 @@ modules.builtin
This file lists all modules that are built into the kernel. This is used
by modprobe to not fail when trying to load something builtin.

+modules.builtin.objs
+-----------------------
+This file contains object mapping of modules that are built into the kernel
+to their corresponding object files used to build the module.
+
modules.builtin.modinfo
-----------------------
This file contains modinfo from all modules that are built into the kernel.
diff --git a/Makefile b/Makefile
index ac2ec990422d..93bfaae45396 100644
--- a/Makefile
+++ b/Makefile
@@ -1228,7 +1228,11 @@ PHONY += vmlinux_o
vmlinux_o: vmlinux.a $(KBUILD_VMLINUX_LIBS)
$(Q)$(MAKE) -f $(srctree)/scripts/Makefile.vmlinux_o

-vmlinux.o modules.builtin.modinfo modules.builtin: vmlinux_o
+MODULES_BUILTIN := modules.builtin.modinfo
+MODULES_BUILTIN += modules.builtin
+MODULES_BUILTIN += modules.builtin.objs
+
+vmlinux.o $(MODULES_BUILTIN): vmlinux_o
@:

PHONY += vmlinux
@@ -1558,7 +1562,7 @@ __modinst_pre:
fi
@sed 's:^:kernel/:' modules.order > $(MODLIB)/modules.order
@cp -f modules.builtin $(MODLIB)/
- @cp -f $(objtree)/modules.builtin.modinfo $(MODLIB)/
+ @cp -f $(objtree)/modules.builtin.* $(MODLIB)/

endif # CONFIG_MODULES

@@ -1571,7 +1575,7 @@ endif # CONFIG_MODULES

# Directories & files removed with 'make clean'
CLEAN_FILES += include/ksym vmlinux.symvers modules-only.symvers \
- modules.builtin modules.builtin.modinfo modules.nsdeps \
+ modules.builtin modules.builtin.* modules.nsdeps \
compile_commands.json .thinlto-cache rust/test rust/doc \
.vmlinux.objs .vmlinux.export.c

diff --git a/include/linux/module.h b/include/linux/module.h
index 676614d56c25..8c3bdadc93e6 100644
--- a/include/linux/module.h
+++ b/include/linux/module.h
@@ -179,7 +179,9 @@ extern void cleanup_module(void);
#ifdef MODULE
#define MODULE_FILE
#else
-#define MODULE_FILE MODULE_INFO(file, KBUILD_MODFILE);
+#define MODULE_FILE \
+ MODULE_INFO(file, KBUILD_MODFILE); \
+ MODULE_INFO(objs, KBUILD_MODOBJS);
#endif

/*
diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib
index 3aa384cec76b..f7e5a83572fa 100644
--- a/scripts/Makefile.lib
+++ b/scripts/Makefile.lib
@@ -112,6 +112,8 @@ modname-multi = $(sort $(foreach m,$(multi-obj-ym),\
__modname = $(or $(modname-multi),$(basetarget))

modname = $(subst $(space),:,$(__modname))
+modname-objs = $($(modname)-objs) $($(modname)-y) $($(modname)-Y)
+modname-objs-prefixed = $(sort $(strip $(addprefix $(obj)/, $(modname-objs))))
modfile = $(addprefix $(obj)/,$(__modname))

# target with $(obj)/ and its suffix stripped
@@ -125,7 +127,8 @@ name-fix = $(call stringify,$(call name-fix-token,$1))
basename_flags = -DKBUILD_BASENAME=$(call name-fix,$(basetarget))
modname_flags = -DKBUILD_MODNAME=$(call name-fix,$(modname)) \
-D__KBUILD_MODNAME=kmod_$(call name-fix-token,$(modname))
-modfile_flags = -DKBUILD_MODFILE=$(call stringify,$(modfile))
+modfile_flags = -DKBUILD_MODFILE=$(call stringify,$(modfile)) \
+ -DKBUILD_MODOBJS=$(call stringify,$(modfile).o:$(subst $(space),|,$(modname-objs-prefixed)))

_c_flags = $(filter-out $(CFLAGS_REMOVE_$(target-stem).o), \
$(filter-out $(ccflags-remove-y), \
diff --git a/scripts/Makefile.vmlinux_o b/scripts/Makefile.vmlinux_o
index 0edfdb40364b..9b4ca83f0695 100644
--- a/scripts/Makefile.vmlinux_o
+++ b/scripts/Makefile.vmlinux_o
@@ -1,7 +1,7 @@
# SPDX-License-Identifier: GPL-2.0-only

PHONY := __default
-__default: vmlinux.o modules.builtin.modinfo modules.builtin
+__default: vmlinux.o modules.builtin.modinfo modules.builtin modules.builtin.objs

include include/config/auto.conf
include $(srctree)/scripts/Kbuild.include
@@ -86,6 +86,19 @@ targets += modules.builtin
modules.builtin: modules.builtin.modinfo FORCE
$(call if_changed,modules_builtin)

+# module.builtin.objs
+# ---------------------------------------------------------------------------
+quiet_cmd_modules_builtin_objs = GEN $@
+ cmd_modules_builtin_objs = \
+ tr '\0' '\n' < $< | \
+ sed -n 's/^[[:alnum:]:_]*\.objs=//p' | \
+ tr ' ' '\n' | uniq | sed -e 's|:|: |' -e 's:|: :g' | \
+ tr -s ' ' > $@
+
+targets += modules.builtin.objs
+modules.builtin.objs: modules.builtin.modinfo FORCE
+ $(call if_changed,modules_builtin_objs)
+
# Add FORCE to the prequisites of a target to force it to be always rebuilt.
# ---------------------------------------------------------------------------

--
2.38.0.266.g481848f278

2022-12-05 16:52:32

by Nick Alcock

[permalink] [raw]
Subject: [PATCH v10 05/13] kbuild: remove MODULE_LICENSE/AUTHOR/DESCRIPTION in non-modules

Since commit 8b41fc4454e ("kbuild: create modules.builtin without
Makefile.modbuiltin or tristate.conf"), MODULE_LICENSE declarations in
non-modules will cause modprobe to misidentify their containing object
file as a module when it is not, which might cause it to spuriously fail
when trying to load something that is built in to the kernel. They
also cause misconstruction of modules.builtin.objs, leading to incorrect
output in kallmodsyms (notating things as being in modules when they
actually cannot be built as a module at all).

Automatically identified with the new tristate checker, and purged with
sed and a subsequent make allmodconfig to double-check.

Signed-off-by: Nick Alcock <[email protected]>
---

Notes:
v10: new.

arch/x86/crypto/blake2s-glue.c | 1 -
arch/x86/mm/debug_pagetables.c | 3 ---
crypto/asymmetric_keys/asymmetric_type.c | 1 -
drivers/accessibility/braille/braille_console.c | 4 ----
drivers/amba/tegra-ahb.c | 3 ---
drivers/android/binder.c | 1 -
drivers/bus/arm-cci.c | 2 --
drivers/bus/arm-integrator-lm.c | 3 ---
drivers/bus/bt1-apb.c | 3 ---
drivers/bus/bt1-axi.c | 3 ---
drivers/bus/imx-weim.c | 3 ---
drivers/bus/intel-ixp4xx-eb.c | 3 ---
drivers/bus/qcom-ebi2.c | 3 ---
drivers/bus/qcom-ssc-block-bus.c | 3 ---
drivers/bus/simple-pm-bus.c | 3 ---
drivers/clk/bcm/clk-bcm2835-aux.c | 3 ---
drivers/clk/bcm/clk-bcm2835.c | 3 ---
drivers/clk/clk-bm1880.c | 3 ---
drivers/clk/clk-fixed-mmio.c | 3 ---
drivers/clk/clk-fsl-sai.c | 3 ---
drivers/clk/hisilicon/clk-hi3559a.c | 2 --
drivers/clk/microchip/clk-mpfs-ccc.c | 3 ---
drivers/clk/microchip/clk-mpfs.c | 5 -----
drivers/clk/renesas/rcar-usb2-clock-sel.c | 2 --
drivers/clk/renesas/renesas-cpg-mssr.c | 2 --
drivers/clk/renesas/rzg2l-cpg.c | 2 --
drivers/clocksource/em_sti.c | 3 ---
drivers/clocksource/sh_cmt.c | 3 ---
drivers/clocksource/sh_mtu2.c | 3 ---
drivers/clocksource/sh_tmu.c | 3 ---
drivers/clocksource/timer-stm32-lp.c | 2 --
drivers/clocksource/timer-tegra186.c | 3 ---
drivers/clocksource/timer-ti-dm.c | 3 ---
drivers/cpufreq/freq_table.c | 3 ---
drivers/cpufreq/intel_pstate.c | 3 ---
drivers/cpufreq/tegra124-cpufreq.c | 3 ---
drivers/dma-buf/heaps/cma_heap.c | 2 --
drivers/dma-buf/heaps/system_heap.c | 1 -
drivers/dma-buf/udmabuf.c | 2 --
drivers/dma/ep93xx_dma.c | 3 ---
drivers/dma/ipu/ipu_idmac.c | 3 ---
drivers/dma/mv_xor_v2.c | 2 --
drivers/dma/s3c24xx-dma.c | 3 ---
drivers/dma/sh/shdma-base.c | 3 ---
drivers/dma/stm32-dmamux.c | 4 ----
drivers/dma/stm32-mdma.c | 4 ----
drivers/edac/altera_edac.c | 3 ---
drivers/firmware/broadcom/bcm47xx_nvram.c | 1 -
drivers/firmware/imx/imx-scu.c | 3 ---
drivers/firmware/imx/scu-pd.c | 3 ---
drivers/gpio/gpio-aspeed-sgpio.c | 2 --
drivers/gpio/gpio-imx-scu.c | 3 ---
drivers/gpio/gpio-mxs.c | 6 ------
drivers/gpio/gpio-rda.c | 3 ---
drivers/gpu/drm/drm_mipi_dsi.c | 3 ---
drivers/hwspinlock/hwspinlock_core.c | 3 ---
drivers/interconnect/core.c | 3 ---
drivers/iommu/sun50i-iommu.c | 4 ----
drivers/irqchip/irq-al-fic.c | 3 ---
drivers/irqchip/irq-ls-scfg-msi.c | 3 ---
drivers/irqchip/irq-mbigen.c | 4 ----
drivers/irqchip/irq-mchp-eic.c | 3 ---
drivers/irqchip/irq-mvebu-pic.c | 3 ---
drivers/irqchip/irq-renesas-intc-irqpin.c | 3 ---
drivers/irqchip/irq-renesas-irqc.c | 3 ---
drivers/irqchip/irq-renesas-rza1.c | 3 ---
drivers/irqchip/irq-renesas-rzg2l.c | 3 ---
drivers/irqchip/irq-sl28cpld.c | 3 ---
drivers/irqchip/irq-ti-sci-inta.c | 3 ---
drivers/irqchip/irq-ti-sci-intr.c | 3 ---
drivers/leds/leds-asic3.c | 3 ---
drivers/mailbox/rockchip-mailbox.c | 4 ----
drivers/mailbox/zynqmp-ipi-mailbox.c | 3 ---
drivers/memory/bt1-l2-ctl.c | 3 ---
drivers/memory/da8xx-ddrctl.c | 3 ---
drivers/memory/fsl_ifc.c | 3 ---
drivers/memory/mvebu-devbus.c | 3 ---
drivers/memory/tegra/mc.c | 3 ---
drivers/memory/tegra/tegra186-emc.c | 3 ---
drivers/mfd/88pm860x-core.c | 3 ---
drivers/mfd/altera-sysmgr.c | 3 ---
drivers/mfd/bcm2835-pm.c | 3 ---
drivers/mfd/da903x.c | 4 ----
drivers/mfd/da9052-core.c | 3 ---
drivers/mfd/da9052-i2c.c | 3 ---
drivers/mfd/da9052-spi.c | 3 ---
drivers/mfd/da9055-core.c | 3 ---
drivers/mfd/da9055-i2c.c | 3 ---
drivers/mfd/ezx-pcap.c | 3 ---
drivers/mfd/intel_soc_pmic_crc.c | 4 ----
drivers/mfd/lp8788.c | 3 ---
drivers/mfd/omap-usb-host.c | 4 ----
drivers/mfd/omap-usb-tll.c | 4 ----
drivers/mfd/palmas.c | 3 ---
drivers/mfd/stmpe-i2c.c | 3 ---
drivers/mfd/stmpe-spi.c | 3 ---
drivers/mfd/tc3589x.c | 3 ---
drivers/mfd/tps6586x.c | 3 ---
drivers/mfd/twl4030-audio.c | 3 ---
drivers/mfd/twl6040.c | 4 ----
drivers/mtd/parsers/bcm63xxpart.c | 6 ------
drivers/nvmem/core.c | 4 ----
drivers/nvmem/zynqmp_nvmem.c | 3 ---
drivers/pci/controller/dwc/pcie-histb.c | 2 --
drivers/pci/controller/mobiveil/pcie-mobiveil-plat.c | 3 ---
drivers/pci/controller/pci-tegra.c | 1 -
drivers/pci/controller/pci-versatile.c | 2 --
drivers/pci/controller/pcie-hisi-error.c | 2 --
drivers/pci/controller/pcie-microchip-host.c | 3 ---
drivers/pci/endpoint/pci-ep-cfs.c | 3 ---
drivers/pci/endpoint/pci-epc-core.c | 3 ---
drivers/pci/endpoint/pci-epc-mem.c | 3 ---
drivers/pci/endpoint/pci-epf-core.c | 3 ---
drivers/pci/hotplug/acpiphp_core.c | 3 ---
drivers/pci/hotplug/shpchp_core.c | 3 ---
drivers/perf/apple_m1_cpu_pmu.c | 1 -
drivers/phy/intel/phy-intel-lgm-combo.c | 2 --
drivers/pinctrl/actions/pinctrl-s500.c | 4 ----
drivers/pinctrl/actions/pinctrl-s700.c | 3 ---
drivers/pinctrl/actions/pinctrl-s900.c | 4 ----
drivers/pinctrl/bcm/pinctrl-ns.c | 2 --
drivers/pinctrl/mediatek/pinctrl-mt8188.c | 2 --
drivers/pinctrl/mediatek/pinctrl-mt8192.c | 2 --
drivers/pinctrl/mediatek/pinctrl-mt8365.c | 3 ---
drivers/pinctrl/nuvoton/pinctrl-npcm7xx.c | 4 ----
drivers/pinctrl/pinctrl-amd.c | 3 ---
drivers/pinctrl/renesas/pinctrl-rza1.c | 3 ---
drivers/pinctrl/renesas/pinctrl-rza2.c | 3 ---
drivers/pinctrl/renesas/pinctrl-rzg2l.c | 3 ---
drivers/pinctrl/renesas/pinctrl-rzn1.c | 3 ---
drivers/pinctrl/renesas/pinctrl-rzv2m.c | 3 ---
drivers/power/reset/as3722-poweroff.c | 3 ---
drivers/power/reset/gpio-poweroff.c | 3 ---
drivers/power/reset/gpio-restart.c | 3 ---
drivers/power/reset/keystone-reset.c | 3 ---
drivers/power/reset/ltc2952-poweroff.c | 3 ---
drivers/power/reset/mt6323-poweroff.c | 3 ---
drivers/power/reset/regulator-poweroff.c | 3 ---
drivers/power/reset/restart-poweroff.c | 3 ---
drivers/power/reset/tps65086-restart.c | 3 ---
drivers/power/supply/power_supply_core.c | 6 ------
drivers/power/supply/wm97xx_battery.c | 3 ---
drivers/powercap/powercap_sys.c | 3 ---
drivers/regulator/stm32-pwr.c | 3 ---
drivers/remoteproc/remoteproc_core.c | 2 --
drivers/reset/reset-axs10x.c | 3 ---
drivers/reset/reset-hsdk.c | 3 ---
drivers/reset/reset-lantiq.c | 3 ---
drivers/reset/reset-microchip-sparx5.c | 3 ---
drivers/reset/reset-mpfs.c | 3 ---
drivers/soc/apple/apple-pmgr-pwrstate.c | 3 ---
drivers/soc/bcm/bcm2835-power.c | 3 ---
drivers/soc/bcm/raspberrypi-power.c | 4 ----
drivers/soc/fujitsu/a64fx-diag.c | 3 ---
drivers/soc/sunxi/sunxi_sram.c | 3 ---
drivers/soc/tegra/cbb/tegra194-cbb.c | 3 ---
drivers/soc/tegra/cbb/tegra234-cbb.c | 2 --
drivers/tty/n_null.c | 3 ---
drivers/tty/serial/imx_earlycon.c | 3 ---
drivers/tty/serial/rda-uart.c | 3 ---
drivers/video/console/vgacon.c | 1 -
drivers/video/fbdev/asiliantfb.c | 1 -
drivers/video/fbdev/gbefb.c | 1 -
drivers/video/fbdev/imsttfb.c | 1 -
drivers/video/fbdev/mmp/hw/mmp_ctrl.c | 3 ---
drivers/video/fbdev/mmp/panel/tpo_tj032md01bw.c | 3 ---
drivers/video/fbdev/vesafb.c | 1 -
drivers/video/fbdev/wm8505fb.c | 3 ---
drivers/video/fbdev/wmt_ge_rops.c | 4 ----
drivers/xen/grant-dma-ops.c | 3 ---
drivers/xen/xenbus/xenbus_probe.c | 1 -
fs/binfmt_elf.c | 1 -
fs/nfs_common/nfs_ssc.c | 1 -
fs/unicode/utf8-core.c | 1 -
kernel/dma/map_benchmark.c | 3 ---
kernel/events/hw_breakpoint_test.c | 2 --
kernel/trace/rv/reactor_panic.c | 3 ---
kernel/trace/rv/reactor_printk.c | 3 ---
kernel/watch_queue.c | 3 ---
lib/btree.c | 3 ---
lib/crypto/blake2s-generic.c | 3 ---
lib/crypto/blake2s.c | 3 ---
lib/glob.c | 2 --
lib/packing.c | 2 --
lib/pldmfw/pldmfw.c | 3 ---
lib/test_fprobe.c | 1 -
mm/zpool.c | 3 ---
mm/zswap.c | 3 ---
net/mctp/af_mctp.c | 3 ---
189 files changed, 539 deletions(-)

diff --git a/arch/x86/crypto/blake2s-glue.c b/arch/x86/crypto/blake2s-glue.c
index aaba21230528..0df9ec15643a 100644
--- a/arch/x86/crypto/blake2s-glue.c
+++ b/arch/x86/crypto/blake2s-glue.c
@@ -74,4 +74,3 @@ static int __init blake2s_mod_init(void)

module_init(blake2s_mod_init);

-MODULE_LICENSE("GPL v2");
diff --git a/arch/x86/mm/debug_pagetables.c b/arch/x86/mm/debug_pagetables.c
index 092ea436c7e6..ad25ad29aa10 100644
--- a/arch/x86/mm/debug_pagetables.c
+++ b/arch/x86/mm/debug_pagetables.c
@@ -71,6 +71,3 @@ static void __exit pt_dump_debug_exit(void)

module_init(pt_dump_debug_init);
module_exit(pt_dump_debug_exit);
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Arjan van de Ven <[email protected]>");
-MODULE_DESCRIPTION("Kernel debugging helper that dumps pagetables");
diff --git a/crypto/asymmetric_keys/asymmetric_type.c b/crypto/asymmetric_keys/asymmetric_type.c
index 41a2f0eb4ce4..a5da8ccd353e 100644
--- a/crypto/asymmetric_keys/asymmetric_type.c
+++ b/crypto/asymmetric_keys/asymmetric_type.c
@@ -17,7 +17,6 @@
#include <keys/user-type.h>
#include "asymmetric_keys.h"

-MODULE_LICENSE("GPL");

const char *const key_being_used_for[NR__KEY_BEING_USED_FOR] = {
[VERIFYING_MODULE_SIGNATURE] = "mod sig",
diff --git a/drivers/accessibility/braille/braille_console.c b/drivers/accessibility/braille/braille_console.c
index c4d54a5326b1..4ea6893659af 100644
--- a/drivers/accessibility/braille/braille_console.c
+++ b/drivers/accessibility/braille/braille_console.c
@@ -22,10 +22,6 @@
#include <linux/kbd_kern.h>
#include <linux/input.h>

-MODULE_AUTHOR("[email protected]");
-MODULE_DESCRIPTION("braille device");
-MODULE_LICENSE("GPL");
-
/*
* Braille device support part.
*/
diff --git a/drivers/amba/tegra-ahb.c b/drivers/amba/tegra-ahb.c
index 0b2c20fddb7c..084ac10c4286 100644
--- a/drivers/amba/tegra-ahb.c
+++ b/drivers/amba/tegra-ahb.c
@@ -283,7 +283,4 @@ static struct platform_driver tegra_ahb_driver = {
};
module_platform_driver(tegra_ahb_driver);

-MODULE_AUTHOR("Hiroshi DOYU <[email protected]>");
-MODULE_DESCRIPTION("Tegra AHB driver");
-MODULE_LICENSE("GPL v2");
MODULE_ALIAS("platform:" DRV_NAME);
diff --git a/drivers/android/binder.c b/drivers/android/binder.c
index 880224ec6abb..e36164108da6 100644
--- a/drivers/android/binder.c
+++ b/drivers/android/binder.c
@@ -6597,4 +6597,3 @@ device_initcall(binder_init);
#define CREATE_TRACE_POINTS
#include "binder_trace.h"

-MODULE_LICENSE("GPL v2");
diff --git a/drivers/bus/arm-cci.c b/drivers/bus/arm-cci.c
index b8184a903583..6702bee4ca5c 100644
--- a/drivers/bus/arm-cci.c
+++ b/drivers/bus/arm-cci.c
@@ -583,5 +583,3 @@ EXPORT_SYMBOL_GPL(cci_probed);

early_initcall(cci_init);
core_initcall(cci_platform_init);
-MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("ARM CCI support");
diff --git a/drivers/bus/arm-integrator-lm.c b/drivers/bus/arm-integrator-lm.c
index 2344d560b144..61a649acdfef 100644
--- a/drivers/bus/arm-integrator-lm.c
+++ b/drivers/bus/arm-integrator-lm.c
@@ -124,6 +124,3 @@ static struct platform_driver integrator_ap_lm_driver = {
},
};
module_platform_driver(integrator_ap_lm_driver);
-MODULE_AUTHOR("Linus Walleij <[email protected]>");
-MODULE_DESCRIPTION("Integrator AP Logical Module driver");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/bus/bt1-apb.c b/drivers/bus/bt1-apb.c
index 63b1b4a76671..1d4e509b195b 100644
--- a/drivers/bus/bt1-apb.c
+++ b/drivers/bus/bt1-apb.c
@@ -414,6 +414,3 @@ static struct platform_driver bt1_apb_driver = {
};
module_platform_driver(bt1_apb_driver);

-MODULE_AUTHOR("Serge Semin <[email protected]>");
-MODULE_DESCRIPTION("Baikal-T1 APB-bus driver");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/bus/bt1-axi.c b/drivers/bus/bt1-axi.c
index 70e49a6e5374..9b4461ec8084 100644
--- a/drivers/bus/bt1-axi.c
+++ b/drivers/bus/bt1-axi.c
@@ -307,6 +307,3 @@ static struct platform_driver bt1_axi_driver = {
};
module_platform_driver(bt1_axi_driver);

-MODULE_AUTHOR("Serge Semin <[email protected]>");
-MODULE_DESCRIPTION("Baikal-T1 AXI-bus driver");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/bus/imx-weim.c b/drivers/bus/imx-weim.c
index 828c66bbaa67..b8519526dd24 100644
--- a/drivers/bus/imx-weim.c
+++ b/drivers/bus/imx-weim.c
@@ -403,6 +403,3 @@ static void __exit weim_exit(void)
}
module_exit(weim_exit);

-MODULE_AUTHOR("Freescale Semiconductor Inc.");
-MODULE_DESCRIPTION("i.MX EIM Controller Driver");
-MODULE_LICENSE("GPL");
diff --git a/drivers/bus/intel-ixp4xx-eb.c b/drivers/bus/intel-ixp4xx-eb.c
index a4388440aca7..6e02369aedeb 100644
--- a/drivers/bus/intel-ixp4xx-eb.c
+++ b/drivers/bus/intel-ixp4xx-eb.c
@@ -424,6 +424,3 @@ static struct platform_driver ixp4xx_exp_driver = {
},
};
module_platform_driver(ixp4xx_exp_driver);
-MODULE_AUTHOR("Linus Walleij <[email protected]>");
-MODULE_DESCRIPTION("Intel IXP4xx external bus driver");
-MODULE_LICENSE("GPL");
diff --git a/drivers/bus/qcom-ebi2.c b/drivers/bus/qcom-ebi2.c
index 663c82749222..5846c2ffe99c 100644
--- a/drivers/bus/qcom-ebi2.c
+++ b/drivers/bus/qcom-ebi2.c
@@ -401,6 +401,3 @@ static struct platform_driver qcom_ebi2_driver = {
},
};
module_platform_driver(qcom_ebi2_driver);
-MODULE_AUTHOR("Linus Walleij <[email protected]>");
-MODULE_DESCRIPTION("Qualcomm EBI2 driver");
-MODULE_LICENSE("GPL");
diff --git a/drivers/bus/qcom-ssc-block-bus.c b/drivers/bus/qcom-ssc-block-bus.c
index eedeb29a5ff3..040f3432b989 100644
--- a/drivers/bus/qcom-ssc-block-bus.c
+++ b/drivers/bus/qcom-ssc-block-bus.c
@@ -384,6 +384,3 @@ static struct platform_driver qcom_ssc_block_bus_driver = {

module_platform_driver(qcom_ssc_block_bus_driver);

-MODULE_DESCRIPTION("A driver for handling the init sequence needed for accessing the SSC block on (some) qcom SoCs over AHB");
-MODULE_AUTHOR("Michael Srba <[email protected]>");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/bus/simple-pm-bus.c b/drivers/bus/simple-pm-bus.c
index 6b8d6257ed8a..22fe6478e7b5 100644
--- a/drivers/bus/simple-pm-bus.c
+++ b/drivers/bus/simple-pm-bus.c
@@ -90,6 +90,3 @@ static struct platform_driver simple_pm_bus_driver = {

module_platform_driver(simple_pm_bus_driver);

-MODULE_DESCRIPTION("Simple Power-Managed Bus Driver");
-MODULE_AUTHOR("Geert Uytterhoeven <[email protected]>");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/clk/bcm/clk-bcm2835-aux.c b/drivers/clk/bcm/clk-bcm2835-aux.c
index 290a2846a86b..9aeeee6096a8 100644
--- a/drivers/clk/bcm/clk-bcm2835-aux.c
+++ b/drivers/clk/bcm/clk-bcm2835-aux.c
@@ -67,6 +67,3 @@ static struct platform_driver bcm2835_aux_clk_driver = {
};
builtin_platform_driver(bcm2835_aux_clk_driver);

-MODULE_AUTHOR("Eric Anholt <[email protected]>");
-MODULE_DESCRIPTION("BCM2835 auxiliary peripheral clock driver");
-MODULE_LICENSE("GPL");
diff --git a/drivers/clk/bcm/clk-bcm2835.c b/drivers/clk/bcm/clk-bcm2835.c
index e74fe6219d14..eec7146b12a0 100644
--- a/drivers/clk/bcm/clk-bcm2835.c
+++ b/drivers/clk/bcm/clk-bcm2835.c
@@ -2348,6 +2348,3 @@ static struct platform_driver bcm2835_clk_driver = {

builtin_platform_driver(bcm2835_clk_driver);

-MODULE_AUTHOR("Eric Anholt <[email protected]>");
-MODULE_DESCRIPTION("BCM2835 clock driver");
-MODULE_LICENSE("GPL");
diff --git a/drivers/clk/clk-bm1880.c b/drivers/clk/clk-bm1880.c
index fad78a22218e..67aace6d4e2a 100644
--- a/drivers/clk/clk-bm1880.c
+++ b/drivers/clk/clk-bm1880.c
@@ -947,6 +947,3 @@ static struct platform_driver bm1880_clk_driver = {
};
module_platform_driver(bm1880_clk_driver);

-MODULE_AUTHOR("Manivannan Sadhasivam <[email protected]>");
-MODULE_DESCRIPTION("Clock driver for Bitmain BM1880 SoC");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/clk/clk-fixed-mmio.c b/drivers/clk/clk-fixed-mmio.c
index 5225d17d6b3f..b4d51972357e 100644
--- a/drivers/clk/clk-fixed-mmio.c
+++ b/drivers/clk/clk-fixed-mmio.c
@@ -97,6 +97,3 @@ static struct platform_driver of_fixed_mmio_clk_driver = {
};
module_platform_driver(of_fixed_mmio_clk_driver);

-MODULE_AUTHOR("Jan Kotas <[email protected]>");
-MODULE_DESCRIPTION("Memory Mapped IO Fixed clock driver");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/clk/clk-fsl-sai.c b/drivers/clk/clk-fsl-sai.c
index 6238fcea0467..c2cb71d474d2 100644
--- a/drivers/clk/clk-fsl-sai.c
+++ b/drivers/clk/clk-fsl-sai.c
@@ -86,7 +86,4 @@ static struct platform_driver fsl_sai_clk_driver = {
};
module_platform_driver(fsl_sai_clk_driver);

-MODULE_DESCRIPTION("Freescale SAI bitclock-as-a-clock driver");
-MODULE_AUTHOR("Michael Walle <[email protected]>");
-MODULE_LICENSE("GPL");
MODULE_ALIAS("platform:fsl-sai-clk");
diff --git a/drivers/clk/hisilicon/clk-hi3559a.c b/drivers/clk/hisilicon/clk-hi3559a.c
index 9ea1a80acbe8..f56c837811ae 100644
--- a/drivers/clk/hisilicon/clk-hi3559a.c
+++ b/drivers/clk/hisilicon/clk-hi3559a.c
@@ -841,5 +841,3 @@ static void __exit hi3559av100_crg_exit(void)
module_exit(hi3559av100_crg_exit);


-MODULE_LICENSE("GPL v2");
-MODULE_DESCRIPTION("HiSilicon Hi3559AV100 CRG Driver");
diff --git a/drivers/clk/microchip/clk-mpfs-ccc.c b/drivers/clk/microchip/clk-mpfs-ccc.c
index 7be028dced63..cce7d9689859 100644
--- a/drivers/clk/microchip/clk-mpfs-ccc.c
+++ b/drivers/clk/microchip/clk-mpfs-ccc.c
@@ -285,6 +285,3 @@ static void __exit clk_ccc_exit(void)
}
module_exit(clk_ccc_exit);

-MODULE_DESCRIPTION("Microchip PolarFire SoC Clock Conditioning Circuitry Driver");
-MODULE_AUTHOR("Conor Dooley <[email protected]>");
-MODULE_LICENSE("GPL");
diff --git a/drivers/clk/microchip/clk-mpfs.c b/drivers/clk/microchip/clk-mpfs.c
index 4f0a19db7ed7..1433e467cab9 100644
--- a/drivers/clk/microchip/clk-mpfs.c
+++ b/drivers/clk/microchip/clk-mpfs.c
@@ -509,8 +509,3 @@ static void __exit clk_mpfs_exit(void)
}
module_exit(clk_mpfs_exit);

-MODULE_DESCRIPTION("Microchip PolarFire SoC Clock Driver");
-MODULE_AUTHOR("Padmarao Begari <[email protected]>");
-MODULE_AUTHOR("Daire McNamara <[email protected]>");
-MODULE_AUTHOR("Conor Dooley <[email protected]>");
-MODULE_LICENSE("GPL");
diff --git a/drivers/clk/renesas/rcar-usb2-clock-sel.c b/drivers/clk/renesas/rcar-usb2-clock-sel.c
index 684d8937965e..2968c9b1aaa5 100644
--- a/drivers/clk/renesas/rcar-usb2-clock-sel.c
+++ b/drivers/clk/renesas/rcar-usb2-clock-sel.c
@@ -219,5 +219,3 @@ static struct platform_driver rcar_usb2_clock_sel_driver = {
};
builtin_platform_driver(rcar_usb2_clock_sel_driver);

-MODULE_DESCRIPTION("Renesas R-Car USB2 clock selector Driver");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/clk/renesas/renesas-cpg-mssr.c b/drivers/clk/renesas/renesas-cpg-mssr.c
index 1a0cdf001b2f..a4f4f1fee9d3 100644
--- a/drivers/clk/renesas/renesas-cpg-mssr.c
+++ b/drivers/clk/renesas/renesas-cpg-mssr.c
@@ -1153,5 +1153,3 @@ void __init mssr_mod_reparent(struct mssr_mod_clk *mod_clks,
}
}

-MODULE_DESCRIPTION("Renesas CPG/MSSR Driver");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/clk/renesas/rzg2l-cpg.c b/drivers/clk/renesas/rzg2l-cpg.c
index 3ff6ecd61756..8f530972ccf7 100644
--- a/drivers/clk/renesas/rzg2l-cpg.c
+++ b/drivers/clk/renesas/rzg2l-cpg.c
@@ -1430,5 +1430,3 @@ static int __init rzg2l_cpg_init(void)

subsys_initcall(rzg2l_cpg_init);

-MODULE_DESCRIPTION("Renesas RZ/G2L CPG Driver");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/clocksource/em_sti.c b/drivers/clocksource/em_sti.c
index ab190dffb1ed..6eaa6620a330 100644
--- a/drivers/clocksource/em_sti.c
+++ b/drivers/clocksource/em_sti.c
@@ -366,6 +366,3 @@ static void __exit em_sti_exit(void)
subsys_initcall(em_sti_init);
module_exit(em_sti_exit);

-MODULE_AUTHOR("Magnus Damm");
-MODULE_DESCRIPTION("Renesas Emma Mobile STI Timer Driver");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/clocksource/sh_cmt.c b/drivers/clocksource/sh_cmt.c
index 64dcb082d4cf..cec602c91499 100644
--- a/drivers/clocksource/sh_cmt.c
+++ b/drivers/clocksource/sh_cmt.c
@@ -1155,6 +1155,3 @@ sh_early_platform_init("earlytimer", &sh_cmt_device_driver);
subsys_initcall(sh_cmt_init);
module_exit(sh_cmt_exit);

-MODULE_AUTHOR("Magnus Damm");
-MODULE_DESCRIPTION("SuperH CMT Timer Driver");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/clocksource/sh_mtu2.c b/drivers/clocksource/sh_mtu2.c
index 169a1fccc497..b71d634464c7 100644
--- a/drivers/clocksource/sh_mtu2.c
+++ b/drivers/clocksource/sh_mtu2.c
@@ -528,6 +528,3 @@ sh_early_platform_init("earlytimer", &sh_mtu2_device_driver);
subsys_initcall(sh_mtu2_init);
module_exit(sh_mtu2_exit);

-MODULE_AUTHOR("Magnus Damm");
-MODULE_DESCRIPTION("SuperH MTU2 Timer Driver");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/clocksource/sh_tmu.c b/drivers/clocksource/sh_tmu.c
index b00dec0655cb..b92f1d3f53e9 100644
--- a/drivers/clocksource/sh_tmu.c
+++ b/drivers/clocksource/sh_tmu.c
@@ -677,6 +677,3 @@ sh_early_platform_init("earlytimer", &sh_tmu_device_driver);
subsys_initcall(sh_tmu_init);
module_exit(sh_tmu_exit);

-MODULE_AUTHOR("Magnus Damm");
-MODULE_DESCRIPTION("SuperH TMU Timer Driver");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/clocksource/timer-stm32-lp.c b/drivers/clocksource/timer-stm32-lp.c
index db2841d0beb8..54ab3db7de55 100644
--- a/drivers/clocksource/timer-stm32-lp.c
+++ b/drivers/clocksource/timer-stm32-lp.c
@@ -217,5 +217,3 @@ static struct platform_driver stm32_clkevent_lp_driver = {
module_platform_driver(stm32_clkevent_lp_driver);

MODULE_ALIAS("platform:stm32-lptimer-timer");
-MODULE_DESCRIPTION("STMicroelectronics STM32 clockevent low power driver");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/clocksource/timer-tegra186.c b/drivers/clocksource/timer-tegra186.c
index ea742889ee06..d87e2ed2c5bf 100644
--- a/drivers/clocksource/timer-tegra186.c
+++ b/drivers/clocksource/timer-tegra186.c
@@ -509,6 +509,3 @@ static struct platform_driver tegra186_wdt_driver = {
};
module_platform_driver(tegra186_wdt_driver);

-MODULE_AUTHOR("Thierry Reding <[email protected]>");
-MODULE_DESCRIPTION("NVIDIA Tegra186 timers driver");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/clocksource/timer-ti-dm.c b/drivers/clocksource/timer-ti-dm.c
index cad29ded3a48..85842520065f 100644
--- a/drivers/clocksource/timer-ti-dm.c
+++ b/drivers/clocksource/timer-ti-dm.c
@@ -1265,6 +1265,3 @@ static struct platform_driver omap_dm_timer_driver = {

module_platform_driver(omap_dm_timer_driver);

-MODULE_DESCRIPTION("OMAP Dual-Mode Timer Driver");
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Texas Instruments Inc");
diff --git a/drivers/cpufreq/freq_table.c b/drivers/cpufreq/freq_table.c
index 67e56cf638ef..c34d813e4687 100644
--- a/drivers/cpufreq/freq_table.c
+++ b/drivers/cpufreq/freq_table.c
@@ -365,6 +365,3 @@ int cpufreq_table_validate_and_sort(struct cpufreq_policy *policy)
return set_freq_table_sorted(policy);
}

-MODULE_AUTHOR("Dominik Brodowski <[email protected]>");
-MODULE_DESCRIPTION("CPUfreq frequency table helpers");
-MODULE_LICENSE("GPL");
diff --git a/drivers/cpufreq/intel_pstate.c b/drivers/cpufreq/intel_pstate.c
index 6ff73c30769f..518febe0c9f4 100644
--- a/drivers/cpufreq/intel_pstate.c
+++ b/drivers/cpufreq/intel_pstate.c
@@ -3526,6 +3526,3 @@ static int __init intel_pstate_setup(char *str)
}
early_param("intel_pstate", intel_pstate_setup);

-MODULE_AUTHOR("Dirk Brandewie <[email protected]>");
-MODULE_DESCRIPTION("'intel_pstate' - P state driver Intel Core processors");
-MODULE_LICENSE("GPL");
diff --git a/drivers/cpufreq/tegra124-cpufreq.c b/drivers/cpufreq/tegra124-cpufreq.c
index 7a1ea6fdcab6..d41292a87b14 100644
--- a/drivers/cpufreq/tegra124-cpufreq.c
+++ b/drivers/cpufreq/tegra124-cpufreq.c
@@ -219,6 +219,3 @@ static int __init tegra_cpufreq_init(void)
}
module_init(tegra_cpufreq_init);

-MODULE_AUTHOR("Tuomas Tynkkynen <[email protected]>");
-MODULE_DESCRIPTION("cpufreq driver for NVIDIA Tegra124");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/dma-buf/heaps/cma_heap.c b/drivers/dma-buf/heaps/cma_heap.c
index 28fb04eccdd0..6d6b92743613 100644
--- a/drivers/dma-buf/heaps/cma_heap.c
+++ b/drivers/dma-buf/heaps/cma_heap.c
@@ -403,5 +403,3 @@ static int add_default_cma_heap(void)
return ret;
}
module_init(add_default_cma_heap);
-MODULE_DESCRIPTION("DMA-BUF CMA Heap");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/dma-buf/heaps/system_heap.c b/drivers/dma-buf/heaps/system_heap.c
index fcf836ba9c1f..1b8d1db6ce23 100644
--- a/drivers/dma-buf/heaps/system_heap.c
+++ b/drivers/dma-buf/heaps/system_heap.c
@@ -437,4 +437,3 @@ static int system_heap_create(void)
return 0;
}
module_init(system_heap_create);
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/dma-buf/udmabuf.c b/drivers/dma-buf/udmabuf.c
index 2bcdb935a3ac..f3421e56c140 100644
--- a/drivers/dma-buf/udmabuf.c
+++ b/drivers/dma-buf/udmabuf.c
@@ -398,5 +398,3 @@ static void __exit udmabuf_dev_exit(void)
module_init(udmabuf_dev_init)
module_exit(udmabuf_dev_exit)

-MODULE_AUTHOR("Gerd Hoffmann <[email protected]>");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/dma/ep93xx_dma.c b/drivers/dma/ep93xx_dma.c
index d19ea885c63e..26c38657a079 100644
--- a/drivers/dma/ep93xx_dma.c
+++ b/drivers/dma/ep93xx_dma.c
@@ -1429,6 +1429,3 @@ static int __init ep93xx_dma_module_init(void)
}
subsys_initcall(ep93xx_dma_module_init);

-MODULE_AUTHOR("Mika Westerberg <[email protected]>");
-MODULE_DESCRIPTION("EP93xx DMA driver");
-MODULE_LICENSE("GPL");
diff --git a/drivers/dma/ipu/ipu_idmac.c b/drivers/dma/ipu/ipu_idmac.c
index baab1ca9f621..82a22ee145b1 100644
--- a/drivers/dma/ipu/ipu_idmac.c
+++ b/drivers/dma/ipu/ipu_idmac.c
@@ -1796,7 +1796,4 @@ static int __init ipu_init(void)
}
subsys_initcall(ipu_init);

-MODULE_DESCRIPTION("IPU core driver");
-MODULE_LICENSE("GPL v2");
-MODULE_AUTHOR("Guennadi Liakhovetski <[email protected]>");
MODULE_ALIAS("platform:ipu-core");
diff --git a/drivers/dma/mv_xor_v2.c b/drivers/dma/mv_xor_v2.c
index 113834e1167b..c10f9959b7dd 100644
--- a/drivers/dma/mv_xor_v2.c
+++ b/drivers/dma/mv_xor_v2.c
@@ -919,5 +919,3 @@ static struct platform_driver mv_xor_v2_driver = {

module_platform_driver(mv_xor_v2_driver);

-MODULE_DESCRIPTION("DMA engine driver for Marvell's Version 2 of XOR engine");
-MODULE_LICENSE("GPL");
diff --git a/drivers/dma/s3c24xx-dma.c b/drivers/dma/s3c24xx-dma.c
index a09eeb545f7d..aa10b57560be 100644
--- a/drivers/dma/s3c24xx-dma.c
+++ b/drivers/dma/s3c24xx-dma.c
@@ -1423,6 +1423,3 @@ bool s3c24xx_dma_filter(struct dma_chan *chan, void *param)
}
EXPORT_SYMBOL(s3c24xx_dma_filter);

-MODULE_DESCRIPTION("S3C24XX DMA Driver");
-MODULE_AUTHOR("Heiko Stuebner");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/dma/sh/shdma-base.c b/drivers/dma/sh/shdma-base.c
index 158e5e7defae..8c3080997f07 100644
--- a/drivers/dma/sh/shdma-base.c
+++ b/drivers/dma/sh/shdma-base.c
@@ -1047,6 +1047,3 @@ static void __exit shdma_exit(void)
}
module_exit(shdma_exit);

-MODULE_LICENSE("GPL v2");
-MODULE_DESCRIPTION("SH-DMA driver base library");
-MODULE_AUTHOR("Guennadi Liakhovetski <[email protected]>");
diff --git a/drivers/dma/stm32-dmamux.c b/drivers/dma/stm32-dmamux.c
index ee3cbbf51006..67dafaf85c4b 100644
--- a/drivers/dma/stm32-dmamux.c
+++ b/drivers/dma/stm32-dmamux.c
@@ -397,7 +397,3 @@ static int __init stm32_dmamux_init(void)
}
arch_initcall(stm32_dmamux_init);

-MODULE_DESCRIPTION("DMA Router driver for STM32 DMA MUX");
-MODULE_AUTHOR("M'boumba Cedric Madianga <[email protected]>");
-MODULE_AUTHOR("Pierre-Yves Mordret <[email protected]>");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/dma/stm32-mdma.c b/drivers/dma/stm32-mdma.c
index b9d4c843635f..559576f197e3 100644
--- a/drivers/dma/stm32-mdma.c
+++ b/drivers/dma/stm32-mdma.c
@@ -1813,7 +1813,3 @@ static int __init stm32_mdma_init(void)

subsys_initcall(stm32_mdma_init);

-MODULE_DESCRIPTION("Driver for STM32 MDMA controller");
-MODULE_AUTHOR("M'boumba Cedric Madianga <[email protected]>");
-MODULE_AUTHOR("Pierre-Yves Mordret <[email protected]>");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/edac/altera_edac.c b/drivers/edac/altera_edac.c
index e7e8e624a436..17e3f788bcf5 100644
--- a/drivers/edac/altera_edac.c
+++ b/drivers/edac/altera_edac.c
@@ -2226,6 +2226,3 @@ static struct platform_driver altr_edac_a10_driver = {
};
module_platform_driver(altr_edac_a10_driver);

-MODULE_LICENSE("GPL v2");
-MODULE_AUTHOR("Thor Thayer");
-MODULE_DESCRIPTION("EDAC Driver for Altera Memories");
diff --git a/drivers/firmware/broadcom/bcm47xx_nvram.c b/drivers/firmware/broadcom/bcm47xx_nvram.c
index bd235833b687..2f70c8814b73 100644
--- a/drivers/firmware/broadcom/bcm47xx_nvram.c
+++ b/drivers/firmware/broadcom/bcm47xx_nvram.c
@@ -237,4 +237,3 @@ char *bcm47xx_nvram_get_contents(size_t *nvram_size)
}
EXPORT_SYMBOL(bcm47xx_nvram_get_contents);

-MODULE_LICENSE("GPL v2");
diff --git a/drivers/firmware/imx/imx-scu.c b/drivers/firmware/imx/imx-scu.c
index dca79caccd01..93d57a3b64fa 100644
--- a/drivers/firmware/imx/imx-scu.c
+++ b/drivers/firmware/imx/imx-scu.c
@@ -356,6 +356,3 @@ static struct platform_driver imx_scu_driver = {
};
builtin_platform_driver(imx_scu_driver);

-MODULE_AUTHOR("Dong Aisheng <[email protected]>");
-MODULE_DESCRIPTION("IMX SCU firmware protocol driver");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/firmware/imx/scu-pd.c b/drivers/firmware/imx/scu-pd.c
index af3d057e6421..83f7274a3fe5 100644
--- a/drivers/firmware/imx/scu-pd.c
+++ b/drivers/firmware/imx/scu-pd.c
@@ -418,6 +418,3 @@ static struct platform_driver imx_sc_pd_driver = {
};
builtin_platform_driver(imx_sc_pd_driver);

-MODULE_AUTHOR("Dong Aisheng <[email protected]>");
-MODULE_DESCRIPTION("IMX SCU Power Domain driver");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/gpio/gpio-aspeed-sgpio.c b/drivers/gpio/gpio-aspeed-sgpio.c
index 454cefbeecf0..e3f656945704 100644
--- a/drivers/gpio/gpio-aspeed-sgpio.c
+++ b/drivers/gpio/gpio-aspeed-sgpio.c
@@ -608,5 +608,3 @@ static struct platform_driver aspeed_sgpio_driver = {
};

module_platform_driver_probe(aspeed_sgpio_driver, aspeed_sgpio_probe);
-MODULE_DESCRIPTION("Aspeed Serial GPIO Driver");
-MODULE_LICENSE("GPL");
diff --git a/drivers/gpio/gpio-imx-scu.c b/drivers/gpio/gpio-imx-scu.c
index 17be21b8f3b7..45ce2785d487 100644
--- a/drivers/gpio/gpio-imx-scu.c
+++ b/drivers/gpio/gpio-imx-scu.c
@@ -134,6 +134,3 @@ static int __init _imx_scu_gpio_init(void)

subsys_initcall_sync(_imx_scu_gpio_init);

-MODULE_AUTHOR("Shenwei Wang <[email protected]>");
-MODULE_DESCRIPTION("NXP GPIO over IMX SCU API");
-MODULE_LICENSE("GPL");
diff --git a/drivers/gpio/gpio-mxs.c b/drivers/gpio/gpio-mxs.c
index 7f59e5d936c2..cacee67c0f8f 100644
--- a/drivers/gpio/gpio-mxs.c
+++ b/drivers/gpio/gpio-mxs.c
@@ -359,9 +359,3 @@ static int __init mxs_gpio_init(void)
return platform_driver_register(&mxs_gpio_driver);
}
postcore_initcall(mxs_gpio_init);
-
-MODULE_AUTHOR("Freescale Semiconductor, "
- "Daniel Mack <danielncaiaq.de>, "
- "Juergen Beisert <[email protected]>");
-MODULE_DESCRIPTION("Freescale MXS GPIO");
-MODULE_LICENSE("GPL");
diff --git a/drivers/gpio/gpio-rda.c b/drivers/gpio/gpio-rda.c
index 62ba18b3a602..568ba1c3601f 100644
--- a/drivers/gpio/gpio-rda.c
+++ b/drivers/gpio/gpio-rda.c
@@ -284,6 +284,3 @@ static struct platform_driver rda_gpio_driver = {

module_platform_driver_probe(rda_gpio_driver, rda_gpio_probe);

-MODULE_DESCRIPTION("RDA Micro GPIO driver");
-MODULE_AUTHOR("Manivannan Sadhasivam <[email protected]>");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/gpu/drm/drm_mipi_dsi.c b/drivers/gpu/drm/drm_mipi_dsi.c
index 3ec02748d56f..d5c0725045c8 100644
--- a/drivers/gpu/drm/drm_mipi_dsi.c
+++ b/drivers/gpu/drm/drm_mipi_dsi.c
@@ -1292,6 +1292,3 @@ static int __init mipi_dsi_bus_init(void)
}
postcore_initcall(mipi_dsi_bus_init);

-MODULE_AUTHOR("Andrzej Hajda <[email protected]>");
-MODULE_DESCRIPTION("MIPI DSI Bus");
-MODULE_LICENSE("GPL and additional rights");
diff --git a/drivers/hwspinlock/hwspinlock_core.c b/drivers/hwspinlock/hwspinlock_core.c
index fd5f5c5a5244..2f32e4706ca8 100644
--- a/drivers/hwspinlock/hwspinlock_core.c
+++ b/drivers/hwspinlock/hwspinlock_core.c
@@ -949,6 +949,3 @@ struct hwspinlock *devm_hwspin_lock_request_specific(struct device *dev,
}
EXPORT_SYMBOL_GPL(devm_hwspin_lock_request_specific);

-MODULE_LICENSE("GPL v2");
-MODULE_DESCRIPTION("Hardware spinlock interface");
-MODULE_AUTHOR("Ohad Ben-Cohen <[email protected]>");
diff --git a/drivers/interconnect/core.c b/drivers/interconnect/core.c
index 25debded65a8..764c92a06e68 100644
--- a/drivers/interconnect/core.c
+++ b/drivers/interconnect/core.c
@@ -1144,6 +1144,3 @@ static int __init icc_init(void)

device_initcall(icc_init);

-MODULE_AUTHOR("Georgi Djakov <[email protected]>");
-MODULE_DESCRIPTION("Interconnect Driver Core");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/iommu/sun50i-iommu.c b/drivers/iommu/sun50i-iommu.c
index cd9b74ee24de..a06e9ec880fa 100644
--- a/drivers/iommu/sun50i-iommu.c
+++ b/drivers/iommu/sun50i-iommu.c
@@ -997,7 +997,3 @@ static struct platform_driver sun50i_iommu_driver = {
};
builtin_platform_driver_probe(sun50i_iommu_driver, sun50i_iommu_probe);

-MODULE_DESCRIPTION("Allwinner H6 IOMMU driver");
-MODULE_AUTHOR("Maxime Ripard <[email protected]>");
-MODULE_AUTHOR("zhuxianbin <[email protected]>");
-MODULE_LICENSE("Dual BSD/GPL");
diff --git a/drivers/irqchip/irq-al-fic.c b/drivers/irqchip/irq-al-fic.c
index 886de028a901..0b11f4881afe 100644
--- a/drivers/irqchip/irq-al-fic.c
+++ b/drivers/irqchip/irq-al-fic.c
@@ -24,9 +24,6 @@

#define NR_FIC_IRQS 32

-MODULE_AUTHOR("Talel Shenhar");
-MODULE_DESCRIPTION("Amazon's Annapurna Labs Interrupt Controller Driver");
-MODULE_LICENSE("GPL v2");

enum al_fic_state {
AL_FIC_UNCONFIGURED = 0,
diff --git a/drivers/irqchip/irq-ls-scfg-msi.c b/drivers/irqchip/irq-ls-scfg-msi.c
index 527c90e0920e..af9feb9beff3 100644
--- a/drivers/irqchip/irq-ls-scfg-msi.c
+++ b/drivers/irqchip/irq-ls-scfg-msi.c
@@ -428,6 +428,3 @@ static struct platform_driver ls_scfg_msi_driver = {

module_platform_driver(ls_scfg_msi_driver);

-MODULE_AUTHOR("Minghuan Lian <[email protected]>");
-MODULE_DESCRIPTION("Freescale Layerscape SCFG MSI controller driver");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/irqchip/irq-mbigen.c b/drivers/irqchip/irq-mbigen.c
index f3faf5c99770..98496aa0311e 100644
--- a/drivers/irqchip/irq-mbigen.c
+++ b/drivers/irqchip/irq-mbigen.c
@@ -387,7 +387,3 @@ static struct platform_driver mbigen_platform_driver = {

module_platform_driver(mbigen_platform_driver);

-MODULE_AUTHOR("Jun Ma <[email protected]>");
-MODULE_AUTHOR("Yun Wu <[email protected]>");
-MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("HiSilicon MBI Generator driver");
diff --git a/drivers/irqchip/irq-mchp-eic.c b/drivers/irqchip/irq-mchp-eic.c
index c726a19837d2..0aa28f4ae03b 100644
--- a/drivers/irqchip/irq-mchp-eic.c
+++ b/drivers/irqchip/irq-mchp-eic.c
@@ -275,6 +275,3 @@ IRQCHIP_PLATFORM_DRIVER_BEGIN(mchp_eic)
IRQCHIP_MATCH("microchip,sama7g5-eic", mchp_eic_init)
IRQCHIP_PLATFORM_DRIVER_END(mchp_eic)

-MODULE_DESCRIPTION("Microchip External Interrupt Controller");
-MODULE_LICENSE("GPL v2");
-MODULE_AUTHOR("Claudiu Beznea <[email protected]>");
diff --git a/drivers/irqchip/irq-mvebu-pic.c b/drivers/irqchip/irq-mvebu-pic.c
index ef3d3646ccc2..ea541b1fef5b 100644
--- a/drivers/irqchip/irq-mvebu-pic.c
+++ b/drivers/irqchip/irq-mvebu-pic.c
@@ -193,8 +193,5 @@ static struct platform_driver mvebu_pic_driver = {
};
module_platform_driver(mvebu_pic_driver);

-MODULE_AUTHOR("Yehuda Yitschak <[email protected]>");
-MODULE_AUTHOR("Thomas Petazzoni <[email protected]>");
-MODULE_LICENSE("GPL v2");
MODULE_ALIAS("platform:mvebu_pic");

diff --git a/drivers/irqchip/irq-renesas-intc-irqpin.c b/drivers/irqchip/irq-renesas-intc-irqpin.c
index e83756aca14e..5eacec89cdb4 100644
--- a/drivers/irqchip/irq-renesas-intc-irqpin.c
+++ b/drivers/irqchip/irq-renesas-intc-irqpin.c
@@ -606,6 +606,3 @@ static void __exit intc_irqpin_exit(void)
}
module_exit(intc_irqpin_exit);

-MODULE_AUTHOR("Magnus Damm");
-MODULE_DESCRIPTION("Renesas INTC External IRQ Pin Driver");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/irqchip/irq-renesas-irqc.c b/drivers/irqchip/irq-renesas-irqc.c
index 1ee5e9941f67..d3e1394dfaa7 100644
--- a/drivers/irqchip/irq-renesas-irqc.c
+++ b/drivers/irqchip/irq-renesas-irqc.c
@@ -268,6 +268,3 @@ static void __exit irqc_exit(void)
}
module_exit(irqc_exit);

-MODULE_AUTHOR("Magnus Damm");
-MODULE_DESCRIPTION("Renesas IRQC Driver");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/irqchip/irq-renesas-rza1.c b/drivers/irqchip/irq-renesas-rza1.c
index 72c06e883d1c..7340868edd9f 100644
--- a/drivers/irqchip/irq-renesas-rza1.c
+++ b/drivers/irqchip/irq-renesas-rza1.c
@@ -279,6 +279,3 @@ static void __exit rza1_irqc_exit(void)
}
module_exit(rza1_irqc_exit);

-MODULE_AUTHOR("Geert Uytterhoeven <[email protected]>");
-MODULE_DESCRIPTION("Renesas RZ/A1 IRQC Driver");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/irqchip/irq-renesas-rzg2l.c b/drivers/irqchip/irq-renesas-rzg2l.c
index 25fd8ee66565..80079ac40384 100644
--- a/drivers/irqchip/irq-renesas-rzg2l.c
+++ b/drivers/irqchip/irq-renesas-rzg2l.c
@@ -388,6 +388,3 @@ static int rzg2l_irqc_init(struct device_node *node, struct device_node *parent)
IRQCHIP_PLATFORM_DRIVER_BEGIN(rzg2l_irqc)
IRQCHIP_MATCH("renesas,rzg2l-irqc", rzg2l_irqc_init)
IRQCHIP_PLATFORM_DRIVER_END(rzg2l_irqc)
-MODULE_AUTHOR("Lad Prabhakar <[email protected]>");
-MODULE_DESCRIPTION("Renesas RZ/G2L IRQC Driver");
-MODULE_LICENSE("GPL");
diff --git a/drivers/irqchip/irq-sl28cpld.c b/drivers/irqchip/irq-sl28cpld.c
index fbb354413ffa..24a68af87e59 100644
--- a/drivers/irqchip/irq-sl28cpld.c
+++ b/drivers/irqchip/irq-sl28cpld.c
@@ -91,6 +91,3 @@ static struct platform_driver sl28cpld_intc_driver = {
};
module_platform_driver(sl28cpld_intc_driver);

-MODULE_DESCRIPTION("sl28cpld Interrupt Controller Driver");
-MODULE_AUTHOR("Michael Walle <[email protected]>");
-MODULE_LICENSE("GPL");
diff --git a/drivers/irqchip/irq-ti-sci-inta.c b/drivers/irqchip/irq-ti-sci-inta.c
index 5fdbb4358dd0..63f003d36f3e 100644
--- a/drivers/irqchip/irq-ti-sci-inta.c
+++ b/drivers/irqchip/irq-ti-sci-inta.c
@@ -741,6 +741,3 @@ static struct platform_driver ti_sci_inta_irq_domain_driver = {
};
module_platform_driver(ti_sci_inta_irq_domain_driver);

-MODULE_AUTHOR("Lokesh Vutla <[email protected]>");
-MODULE_DESCRIPTION("K3 Interrupt Aggregator driver over TI SCI protocol");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/irqchip/irq-ti-sci-intr.c b/drivers/irqchip/irq-ti-sci-intr.c
index fe8fad22bcf9..2d014fe02530 100644
--- a/drivers/irqchip/irq-ti-sci-intr.c
+++ b/drivers/irqchip/irq-ti-sci-intr.c
@@ -300,6 +300,3 @@ static struct platform_driver ti_sci_intr_irq_domain_driver = {
};
module_platform_driver(ti_sci_intr_irq_domain_driver);

-MODULE_AUTHOR("Lokesh Vutla <lokeshvutla@ticom>");
-MODULE_DESCRIPTION("K3 Interrupt Router driver over TI SCI protocol");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/leds/leds-asic3.c b/drivers/leds/leds-asic3.c
index 8cbc1b8bafa5..5929f3b3f0cb 100644
--- a/drivers/leds/leds-asic3.c
+++ b/drivers/leds/leds-asic3.c
@@ -171,7 +171,4 @@ static struct platform_driver asic3_led_driver = {

module_platform_driver(asic3_led_driver);

-MODULE_AUTHOR("Paul Parsons <[email protected]>");
-MODULE_DESCRIPTION("HTC ASIC3 LED driver");
-MODULE_LICENSE("GPL");
MODULE_ALIAS("platform:leds-asic3");
diff --git a/drivers/mailbox/rockchip-mailbox.c b/drivers/mailbox/rockchip-mailbox.c
index 979acc810f30..c80b2b8a162d 100644
--- a/drivers/mailbox/rockchip-mailbox.c
+++ b/drivers/mailbox/rockchip-mailbox.c
@@ -256,7 +256,3 @@ static struct platform_driver rockchip_mbox_driver = {

module_platform_driver(rockchip_mbox_driver);

-MODULE_LICENSE("GPL v2");
-MODULE_DESCRIPTION("Rockchip mailbox: communicate between CPU cores and MCU");
-MODULE_AUTHOR("Addy Ke <[email protected]>");
-MODULE_AUTHOR("Caesar Wang <[email protected]>");
diff --git a/drivers/mailbox/zynqmp-ipi-mailbox.c b/drivers/mailbox/zynqmp-ipi-mailbox.c
index 31a0fa914274..68d44ff802b8 100644
--- a/drivers/mailbox/zynqmp-ipi-mailbox.c
+++ b/drivers/mailbox/zynqmp-ipi-mailbox.c
@@ -716,6 +716,3 @@ static void __exit zynqmp_ipi_exit(void)
}
module_exit(zynqmp_ipi_exit);

-MODULE_LICENSE("GPL v2");
-MODULE_DESCRIPTION("Xilinx ZynqMP IPI Mailbox driver");
-MODULE_AUTHOR("Xilinx Inc.");
diff --git a/drivers/memory/bt1-l2-ctl.c b/drivers/memory/bt1-l2-ctl.c
index 85965fa26e0b..ecba9881e446 100644
--- a/drivers/memory/bt1-l2-ctl.c
+++ b/drivers/memory/bt1-l2-ctl.c
@@ -319,6 +319,3 @@ static struct platform_driver l2_ctl_driver = {
};
module_platform_driver(l2_ctl_driver);

-MODULE_AUTHOR("Serge Semin <[email protected]>");
-MODULE_DESCRIPTION("Baikal-T1 L2-cache driver");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/memory/da8xx-ddrctl.c b/drivers/memory/da8xx-ddrctl.c
index b32005bf269c..13c086579932 100644
--- a/drivers/memory/da8xx-ddrctl.c
+++ b/drivers/memory/da8xx-ddrctl.c
@@ -162,6 +162,3 @@ static struct platform_driver da8xx_ddrctl_driver = {
};
module_platform_driver(da8xx_ddrctl_driver);

-MODULE_AUTHOR("Bartosz Golaszewski <[email protected]>");
-MODULE_DESCRIPTION("TI da8xx DDR2/mDDR controller driver");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/memory/fsl_ifc.c b/drivers/memory/fsl_ifc.c
index e83b61c925a4..4716f344559a 100644
--- a/drivers/memory/fsl_ifc.c
+++ b/drivers/memory/fsl_ifc.c
@@ -327,6 +327,3 @@ static int __init fsl_ifc_init(void)
}
subsys_initcall(fsl_ifc_init);

-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Freescale Semiconductor");
-MODULE_DESCRIPTION("Freescale Integrated Flash Controller driver");
diff --git a/drivers/memory/mvebu-devbus.c b/drivers/memory/mvebu-devbus.c
index 8450638e8670..95ec816352dc 100644
--- a/drivers/memory/mvebu-devbus.c
+++ b/drivers/memory/mvebu-devbus.c
@@ -342,6 +342,3 @@ static int __init mvebu_devbus_init(void)
}
module_init(mvebu_devbus_init);

-MODULE_LICENSE("GPL v2");
-MODULE_AUTHOR("Ezequiel Garcia <[email protected]>");
-MODULE_DESCRIPTION("Marvell EBU SoC Device Bus controller");
diff --git a/drivers/memory/tegra/mc.c b/drivers/memory/tegra/mc.c
index 2f7a58a9df1a..9f02f72c2825 100644
--- a/drivers/memory/tegra/mc.c
+++ b/drivers/memory/tegra/mc.c
@@ -958,6 +958,3 @@ static int tegra_mc_init(void)
}
arch_initcall(tegra_mc_init);

-MODULE_AUTHOR("Thierry Reding <[email protected]>");
-MODULE_DESCRIPTION("NVIDIA Tegra Memory Controller driver");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/memory/tegra/tegra186-emc.c b/drivers/memory/tegra/tegra186-emc.c
index 54b47ca33483..139d01435ad1 100644
--- a/drivers/memory/tegra/tegra186-emc.c
+++ b/drivers/memory/tegra/tegra186-emc.c
@@ -291,6 +291,3 @@ static struct platform_driver tegra186_emc_driver = {
};
module_platform_driver(tegra186_emc_driver);

-MODULE_AUTHOR("Thierry Reding <[email protected]>");
-MODULE_DESCRIPTION("NVIDIA Tegra186 External Memory Controller driver");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/mfd/88pm860x-core.c b/drivers/mfd/88pm860x-core.c
index 5dc86dd66202..4997404ed4c6 100644
--- a/drivers/mfd/88pm860x-core.c
+++ b/drivers/mfd/88pm860x-core.c
@@ -1276,6 +1276,3 @@ static void __exit pm860x_i2c_exit(void)
}
module_exit(pm860x_i2c_exit);

-MODULE_DESCRIPTION("PMIC Driver for Marvell 88PM860x");
-MODULE_AUTHOR("Haojian Zhuang <[email protected]>");
-MODULE_LICENSE("GPL");
diff --git a/drivers/mfd/altera-sysmgr.c b/drivers/mfd/altera-sysmgr.c
index 5d3715a28b28..41fdb1bda3d6 100644
--- a/drivers/mfd/altera-sysmgr.c
+++ b/drivers/mfd/altera-sysmgr.c
@@ -196,6 +196,3 @@ static void __exit altr_sysmgr_exit(void)
}
module_exit(altr_sysmgr_exit);

-MODULE_AUTHOR("Thor Thayer <>");
-MODULE_DESCRIPTION("SOCFPGA System Manager driver");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/mfd/bcm2835-pm.c b/drivers/mfd/bcm2835-pm.c
index 49cd1f03884a..b277825be741 100644
--- a/drivers/mfd/bcm2835-pm.c
+++ b/drivers/mfd/bcm2835-pm.c
@@ -121,6 +121,3 @@ static struct platform_driver bcm2835_pm_driver = {
};
module_platform_driver(bcm2835_pm_driver);

-MODULE_AUTHOR("Eric Anholt <[email protected]>");
-MODULE_DESCRIPTION("Driver for Broadcom BCM2835 PM MFD");
-MODULE_LICENSE("GPL");
diff --git a/drivers/mfd/da903x.c b/drivers/mfd/da903x.c
index 3f8f6ad3a98c..34d6df2dd7ca 100644
--- a/drivers/mfd/da903x.c
+++ b/drivers/mfd/da903x.c
@@ -560,7 +560,3 @@ static void __exit da903x_exit(void)
}
module_exit(da903x_exit);

-MODULE_DESCRIPTION("PMIC Driver for Dialog Semiconductor DA9034");
-MODULE_AUTHOR("Eric Miao <[email protected]>");
-MODULE_AUTHOR("Mike Rapoport <[email protected]>");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/mfd/da9052-core.c b/drivers/mfd/da9052-core.c
index 8b42d2f7024f..c7d6dcfd35a4 100644
--- a/drivers/mfd/da9052-core.c
+++ b/drivers/mfd/da9052-core.c
@@ -651,6 +651,3 @@ void da9052_device_exit(struct da9052 *da9052)
da9052_irq_exit(da9052);
}

-MODULE_AUTHOR("David Dajun Chen <[email protected]>");
-MODULE_DESCRIPTION("DA9052 MFD Core");
-MODULE_LICENSE("GPL");
diff --git a/drivers/mfd/da9052-i2c.c b/drivers/mfd/da9052-i2c.c
index 5a74696c8704..d964f26698a5 100644
--- a/drivers/mfd/da9052-i2c.c
+++ b/drivers/mfd/da9052-i2c.c
@@ -207,6 +207,3 @@ static void __exit da9052_i2c_exit(void)
}
module_exit(da9052_i2c_exit);

-MODULE_AUTHOR("David Dajun Chen <[email protected]>");
-MODULE_DESCRIPTION("I2C driver for Dialog DA9052 PMIC");
-MODULE_LICENSE("GPL");
diff --git a/drivers/mfd/da9052-spi.c b/drivers/mfd/da9052-spi.c
index b79a57b45c1e..4e18fa1db842 100644
--- a/drivers/mfd/da9052-spi.c
+++ b/drivers/mfd/da9052-spi.c
@@ -100,6 +100,3 @@ static void __exit da9052_spi_exit(void)
}
module_exit(da9052_spi_exit);

-MODULE_AUTHOR("David Dajun Chen <[email protected]>");
-MODULE_DESCRIPTION("SPI driver for Dialog DA9052 PMIC");
-MODULE_LICENSE("GPL");
diff --git a/drivers/mfd/da9055-core.c b/drivers/mfd/da9055-core.c
index c3bcbd8905c6..102a2c17fbfa 100644
--- a/drivers/mfd/da9055-core.c
+++ b/drivers/mfd/da9055-core.c
@@ -397,6 +397,3 @@ void da9055_device_exit(struct da9055 *da9055)
mfd_remove_devices(da9055->dev);
}

-MODULE_DESCRIPTION("Core support for the DA9055 PMIC");
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("David Dajun Chen <[email protected]>");
diff --git a/drivers/mfd/da9055-i2c.c b/drivers/mfd/da9055-i2c.c
index 276c7d1c509e..643dec98c9ac 100644
--- a/drivers/mfd/da9055-i2c.c
+++ b/drivers/mfd/da9055-i2c.c
@@ -96,6 +96,3 @@ static void __exit da9055_i2c_exit(void)
}
module_exit(da9055_i2c_exit);

-MODULE_AUTHOR("David Dajun Chen <[email protected]>");
-MODULE_DESCRIPTION("I2C driver for Dialog DA9055 PMIC");
-MODULE_LICENSE("GPL");
diff --git a/drivers/mfd/ezx-pcap.c b/drivers/mfd/ezx-pcap.c
index 3d5ce18aa9ae..13127d7b6598 100644
--- a/drivers/mfd/ezx-pcap.c
+++ b/drivers/mfd/ezx-pcap.c
@@ -528,7 +528,4 @@ static void __exit ezx_pcap_exit(void)
subsys_initcall(ezx_pcap_init);
module_exit(ezx_pcap_exit);

-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Daniel Ribeiro / Harald Welte");
-MODULE_DESCRIPTION("Motorola PCAP2 ASIC Driver");
MODULE_ALIAS("spi:ezx-pcap");
diff --git a/drivers/mfd/intel_soc_pmic_crc.c b/drivers/mfd/intel_soc_pmic_crc.c
index b1548a933dc3..0cbb990d01bd 100644
--- a/drivers/mfd/intel_soc_pmic_crc.c
+++ b/drivers/mfd/intel_soc_pmic_crc.c
@@ -270,7 +270,3 @@ static struct i2c_driver crystal_cove_i2c_driver = {

module_i2c_driver(crystal_cove_i2c_driver);

-MODULE_DESCRIPTION("I2C driver for Intel SoC PMIC");
-MODULE_LICENSE("GPL v2");
-MODULE_AUTHOR("Yang, Bin <[email protected]>");
-MODULE_AUTHOR("Zhu, Lejun <[email protected]>");
diff --git a/drivers/mfd/lp8788.c b/drivers/mfd/lp8788.c
index 724a5712b36b..4f85864b9511 100644
--- a/drivers/mfd/lp8788.c
+++ b/drivers/mfd/lp8788.c
@@ -242,6 +242,3 @@ static void __exit lp8788_exit(void)
}
module_exit(lp8788_exit);

-MODULE_DESCRIPTION("TI LP8788 MFD Driver");
-MODULE_AUTHOR("Milo Kim");
-MODULE_LICENSE("GPL");
diff --git a/drivers/mfd/omap-usb-host.c b/drivers/mfd/omap-usb-host.c
index 787d2ae86375..1d423cb01337 100644
--- a/drivers/mfd/omap-usb-host.c
+++ b/drivers/mfd/omap-usb-host.c
@@ -850,11 +850,7 @@ static struct platform_driver usbhs_omap_driver = {
.remove = usbhs_omap_remove,
};

-MODULE_AUTHOR("Keshava Munegowda <[email protected]>");
-MODULE_AUTHOR("Roger Quadros <[email protected]>");
MODULE_ALIAS("platform:" USBHS_DRIVER_NAME);
-MODULE_LICENSE("GPL v2");
-MODULE_DESCRIPTION("usb host common core driver for omap EHCI and OHCI");

static int omap_usbhs_drvinit(void)
{
diff --git a/drivers/mfd/omap-usb-tll.c b/drivers/mfd/omap-usb-tll.c
index 080d7970a377..5e5d077ac0c9 100644
--- a/drivers/mfd/omap-usb-tll.c
+++ b/drivers/mfd/omap-usb-tll.c
@@ -448,10 +448,6 @@ int omap_tll_disable(struct usbhs_omap_platform_data *pdata)
}
EXPORT_SYMBOL_GPL(omap_tll_disable);

-MODULE_AUTHOR("Keshava Munegowda <[email protected]>");
-MODULE_AUTHOR("Roger Quadros <[email protected]>");
-MODULE_LICENSE("GPL v2");
-MODULE_DESCRIPTION("usb tll driver for TI OMAP EHCI and OHCI controllers");

static int __init omap_usbtll_drvinit(void)
{
diff --git a/drivers/mfd/palmas.c b/drivers/mfd/palmas.c
index 8b7429bd2e3e..b677e38de7bb 100644
--- a/drivers/mfd/palmas.c
+++ b/drivers/mfd/palmas.c
@@ -750,6 +750,3 @@ static void __exit palmas_i2c_exit(void)
}
module_exit(palmas_i2c_exit);

-MODULE_AUTHOR("Graeme Gregory <[email protected]>");
-MODULE_DESCRIPTION("Palmas chip family multi-function driver");
-MODULE_LICENSE("GPL");
diff --git a/drivers/mfd/stmpe-i2c.c b/drivers/mfd/stmpe-i2c.c
index 4d55494a97c4..51da3a632adb 100644
--- a/drivers/mfd/stmpe-i2c.c
+++ b/drivers/mfd/stmpe-i2c.c
@@ -136,6 +136,3 @@ static void __exit stmpe_exit(void)
}
module_exit(stmpe_exit);

-MODULE_LICENSE("GPL v2");
-MODULE_DESCRIPTION("STMPE MFD I2C Interface Driver");
-MODULE_AUTHOR("Rabin Vincent <[email protected]>");
diff --git a/drivers/mfd/stmpe-spi.c b/drivers/mfd/stmpe-spi.c
index ad8055a0e286..98ee83f90d1a 100644
--- a/drivers/mfd/stmpe-spi.c
+++ b/drivers/mfd/stmpe-spi.c
@@ -156,6 +156,3 @@ static void __exit stmpe_exit(void)
}
module_exit(stmpe_exit);

-MODULE_LICENSE("GPL v2");
-MODULE_DESCRIPTION("STMPE MFD SPI Interface Driver");
-MODULE_AUTHOR("Viresh Kumar <[email protected]>");
diff --git a/drivers/mfd/tc3589x.c b/drivers/mfd/tc3589x.c
index d5d0ec117acb..f425f7a6d169 100644
--- a/drivers/mfd/tc3589x.c
+++ b/drivers/mfd/tc3589x.c
@@ -503,6 +503,3 @@ static void __exit tc3589x_exit(void)
}
module_exit(tc3589x_exit);

-MODULE_LICENSE("GPL v2");
-MODULE_DESCRIPTION("TC3589x MFD core driver");
-MODULE_AUTHOR("Hanumath Prasad, Rabin Vincent");
diff --git a/drivers/mfd/tps6586x.c b/drivers/mfd/tps6586x.c
index fb340da64bbc..97b32236ef15 100644
--- a/drivers/mfd/tps6586x.c
+++ b/drivers/mfd/tps6586x.c
@@ -641,6 +641,3 @@ static void __exit tps6586x_exit(void)
}
module_exit(tps6586x_exit);

-MODULE_DESCRIPTION("TPS6586X core driver");
-MODULE_AUTHOR("Mike Rapoport <[email protected]>");
-MODULE_LICENSE("GPL");
diff --git a/drivers/mfd/twl4030-audio.c b/drivers/mfd/twl4030-audio.c
index 4536d829b43e..ed96b52cd799 100644
--- a/drivers/mfd/twl4030-audio.c
+++ b/drivers/mfd/twl4030-audio.c
@@ -283,7 +283,4 @@ static struct platform_driver twl4030_audio_driver = {

module_platform_driver(twl4030_audio_driver);

-MODULE_AUTHOR("Peter Ujfalusi <[email protected]>");
-MODULE_DESCRIPTION("TWL4030 audio block MFD driver");
-MODULE_LICENSE("GPL");
MODULE_ALIAS("platform:twl4030-audio");
diff --git a/drivers/mfd/twl6040.c b/drivers/mfd/twl6040.c
index f429b8f00db6..5db429eafbb0 100644
--- a/drivers/mfd/twl6040.c
+++ b/drivers/mfd/twl6040.c
@@ -840,7 +840,3 @@ static struct i2c_driver twl6040_driver = {

module_i2c_driver(twl6040_driver);

-MODULE_DESCRIPTION("TWL6040 MFD");
-MODULE_AUTHOR("Misael Lopez Cruz <[email protected]>");
-MODULE_AUTHOR("Jorge Eduardo Candelaria <[email protected]>");
-MODULE_LICENSE("GPL");
diff --git a/drivers/mtd/parsers/bcm63xxpart.c b/drivers/mtd/parsers/bcm63xxpart.c
index b15bdadaedb5..f252e3eb017f 100644
--- a/drivers/mtd/parsers/bcm63xxpart.c
+++ b/drivers/mtd/parsers/bcm63xxpart.c
@@ -164,9 +164,3 @@ static struct mtd_part_parser bcm63xx_cfe_parser = {
};
module_mtd_part_parser(bcm63xx_cfe_parser);

-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Daniel Dickinson <[email protected]>");
-MODULE_AUTHOR("Florian Fainelli <[email protected]>");
-MODULE_AUTHOR("Mike Albon <[email protected]>");
-MODULE_AUTHOR("Jonas Gorski <[email protected]");
-MODULE_DESCRIPTION("MTD partitioning for BCM63XX CFE bootloaders");
diff --git a/drivers/nvmem/core.c b/drivers/nvmem/core.c
index 321d7d63e068..386d5efa1b27 100644
--- a/drivers/nvmem/core.c
+++ b/drivers/nvmem/core.c
@@ -1952,7 +1952,3 @@ static void __exit nvmem_exit(void)
subsys_initcall(nvmem_init);
module_exit(nvmem_exit);

-MODULE_AUTHOR("Srinivas Kandagatla <[email protected]");
-MODULE_AUTHOR("Maxime Ripard <[email protected]");
-MODULE_DESCRIPTION("nvmem Driver Core");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/nvmem/zynqmp_nvmem.c b/drivers/nvmem/zynqmp_nvmem.c
index e28d7b133e11..d01d4fddf283 100644
--- a/drivers/nvmem/zynqmp_nvmem.c
+++ b/drivers/nvmem/zynqmp_nvmem.c
@@ -76,6 +76,3 @@ static struct platform_driver zynqmp_nvmem_driver = {

module_platform_driver(zynqmp_nvmem_driver);

-MODULE_AUTHOR("Michal Simek <[email protected]>, Nava kishore Manne <[email protected]>");
-MODULE_DESCRIPTION("ZynqMP NVMEM driver");
-MODULE_LICENSE("GPL");
diff --git a/drivers/pci/controller/dwc/pcie-histb.c b/drivers/pci/controller/dwc/pcie-histb.c
index e2b80f10030d..2db5bc06d1be 100644
--- a/drivers/pci/controller/dwc/pcie-histb.c
+++ b/drivers/pci/controller/dwc/pcie-histb.c
@@ -450,5 +450,3 @@ static struct platform_driver histb_pcie_platform_driver = {
};
module_platform_driver(histb_pcie_platform_driver);

-MODULE_DESCRIPTION("HiSilicon STB PCIe host controller driver");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/pci/controller/mobiveil/pcie-mobiveil-plat.c b/drivers/pci/controller/mobiveil/pcie-mobiveil-plat.c
index f6fcd95c2bf5..704bca668f76 100644
--- a/drivers/pci/controller/mobiveil/pcie-mobiveil-plat.c
+++ b/drivers/pci/controller/mobiveil/pcie-mobiveil-plat.c
@@ -56,6 +56,3 @@ static struct platform_driver mobiveil_pcie_driver = {

builtin_platform_driver(mobiveil_pcie_driver);

-MODULE_LICENSE("GPL v2");
-MODULE_DESCRIPTION("Mobiveil PCIe host controller driver");
-MODULE_AUTHOR("Subrahmanya Lingappa <[email protected]>");
diff --git a/drivers/pci/controller/pci-tegra.c b/drivers/pci/controller/pci-tegra.c
index 8e323e93be91..378e56e9d414 100644
--- a/drivers/pci/controller/pci-tegra.c
+++ b/drivers/pci/controller/pci-tegra.c
@@ -2813,4 +2813,3 @@ static struct platform_driver tegra_pcie_driver = {
.remove = tegra_pcie_remove,
};
module_platform_driver(tegra_pcie_driver);
-MODULE_LICENSE("GPL");
diff --git a/drivers/pci/controller/pci-versatile.c b/drivers/pci/controller/pci-versatile.c
index 7991d334e0f1..73ca239096cc 100644
--- a/drivers/pci/controller/pci-versatile.c
+++ b/drivers/pci/controller/pci-versatile.c
@@ -168,5 +168,3 @@ static struct platform_driver versatile_pci_driver = {
};
module_platform_driver(versatile_pci_driver);

-MODULE_DESCRIPTION("Versatile PCI driver");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/pci/controller/pcie-hisi-error.c b/drivers/pci/controller/pcie-hisi-error.c
index 7959c9c8d2bc..6866bc42da1b 100644
--- a/drivers/pci/controller/pcie-hisi-error.c
+++ b/drivers/pci/controller/pcie-hisi-error.c
@@ -323,5 +323,3 @@ static struct platform_driver hisi_pcie_error_handler_driver = {
};
module_platform_driver(hisi_pcie_error_handler_driver);

-MODULE_DESCRIPTION("HiSilicon HIP PCIe controller error handling driver");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/pci/controller/pcie-microchip-host.c b/drivers/pci/controller/pcie-microchip-host.c
index 7263d175b5ad..b424bb1d13f5 100644
--- a/drivers/pci/controller/pcie-microchip-host.c
+++ b/drivers/pci/controller/pcie-microchip-host.c
@@ -1135,6 +1135,3 @@ static struct platform_driver mc_pcie_driver = {
};

builtin_platform_driver(mc_pcie_driver);
-MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("Microchip PCIe host controller driver");
-MODULE_AUTHOR("Daire McNamara <[email protected]>");
diff --git a/drivers/pci/endpoint/pci-ep-cfs.c b/drivers/pci/endpoint/pci-ep-cfs.c
index d4850bdd837f..bb5c30cbdc2a 100644
--- a/drivers/pci/endpoint/pci-ep-cfs.c
+++ b/drivers/pci/endpoint/pci-ep-cfs.c
@@ -726,6 +726,3 @@ static void __exit pci_ep_cfs_exit(void)
}
module_exit(pci_ep_cfs_exit);

-MODULE_DESCRIPTION("PCI EP CONFIGFS");
-MODULE_AUTHOR("Kishon Vijay Abraham I <[email protected]>");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/pci/endpoint/pci-epc-core.c b/drivers/pci/endpoint/pci-epc-core.c
index 3bc9273d0a08..e68c663a2072 100644
--- a/drivers/pci/endpoint/pci-epc-core.c
+++ b/drivers/pci/endpoint/pci-epc-core.c
@@ -854,6 +854,3 @@ static void __exit pci_epc_exit(void)
}
module_exit(pci_epc_exit);

-MODULE_DESCRIPTION("PCI EPC Library");
-MODULE_AUTHOR("Kishon Vijay Abraham I <[email protected]>");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/pci/endpoint/pci-epc-mem.c b/drivers/pci/endpoint/pci-epc-mem.c
index a97b56a6d2db..2353249311ad 100644
--- a/drivers/pci/endpoint/pci-epc-mem.c
+++ b/drivers/pci/endpoint/pci-epc-mem.c
@@ -258,6 +258,3 @@ void pci_epc_mem_free_addr(struct pci_epc *epc, phys_addr_t phys_addr,
}
EXPORT_SYMBOL_GPL(pci_epc_mem_free_addr);

-MODULE_DESCRIPTION("PCI EPC Address Space Management");
-MODULE_AUTHOR("Kishon Vijay Abraham I <[email protected]>");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/pci/endpoint/pci-epf-core.c b/drivers/pci/endpoint/pci-epf-core.c
index 9ed556936f48..682a69be2040 100644
--- a/drivers/pci/endpoint/pci-epf-core.c
+++ b/drivers/pci/endpoint/pci-epf-core.c
@@ -566,6 +566,3 @@ static void __exit pci_epf_exit(void)
}
module_exit(pci_epf_exit);

-MODULE_DESCRIPTION("PCI EPF Library");
-MODULE_AUTHOR("Kishon Vijay Abraham I <[email protected]>");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/pci/hotplug/acpiphp_core.c b/drivers/pci/hotplug/acpiphp_core.c
index 853e04ad272c..fd8b98c5641a 100644
--- a/drivers/pci/hotplug/acpiphp_core.c
+++ b/drivers/pci/hotplug/acpiphp_core.c
@@ -43,9 +43,6 @@ static struct acpiphp_attention_info *attention_info;
#define DRIVER_AUTHOR "Greg Kroah-Hartman <[email protected]>, Takayoshi Kochi <[email protected]>, Matthew Wilcox <[email protected]>"
#define DRIVER_DESC "ACPI Hot Plug PCI Controller Driver"

-MODULE_AUTHOR(DRIVER_AUTHOR);
-MODULE_DESCRIPTION(DRIVER_DESC);
-MODULE_LICENSE("GPL");
MODULE_PARM_DESC(disable, "disable acpiphp driver");
module_param_named(disable, acpiphp_disabled, bool, 0444);

diff --git a/drivers/pci/hotplug/shpchp_core.c b/drivers/pci/hotplug/shpchp_core.c
index 53692b048301..7610a3f6fb5a 100644
--- a/drivers/pci/hotplug/shpchp_core.c
+++ b/drivers/pci/hotplug/shpchp_core.c
@@ -30,9 +30,6 @@ int shpchp_poll_time;
#define DRIVER_AUTHOR "Dan Zink <[email protected]>, Greg Kroah-Hartman <[email protected]>, Dely Sy <[email protected]>"
#define DRIVER_DESC "Standard Hot Plug PCI Controller Driver"

-MODULE_AUTHOR(DRIVER_AUTHOR);
-MODULE_DESCRIPTION(DRIVER_DESC);
-MODULE_LICENSE("GPL");

module_param(shpchp_debug, bool, 0644);
module_param(shpchp_poll_mode, bool, 0644);
diff --git a/drivers/perf/apple_m1_cpu_pmu.c b/drivers/perf/apple_m1_cpu_pmu.c
index 979a7c2b4f56..7123beeb992f 100644
--- a/drivers/perf/apple_m1_cpu_pmu.c
+++ b/drivers/perf/apple_m1_cpu_pmu.c
@@ -581,4 +581,3 @@ static struct platform_driver m1_pmu_driver = {
};

module_platform_driver(m1_pmu_driver);
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/phy/intel/phy-intel-lgm-combo.c b/drivers/phy/intel/phy-intel-lgm-combo.c
index 6010e246d52e..a15e73f5b1b2 100644
--- a/drivers/phy/intel/phy-intel-lgm-combo.c
+++ b/drivers/phy/intel/phy-intel-lgm-combo.c
@@ -615,5 +615,3 @@ static struct platform_driver intel_cbphy_driver = {

module_platform_driver(intel_cbphy_driver);

-MODULE_DESCRIPTION("Intel Combo-phy driver");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/pinctrl/actions/pinctrl-s500.c b/drivers/pinctrl/actions/pinctrl-s500.c
index ced778079b76..c944c68f22a8 100644
--- a/drivers/pinctrl/actions/pinctrl-s500.c
+++ b/drivers/pinctrl/actions/pinctrl-s500.c
@@ -1721,7 +1721,3 @@ static void __exit s500_pinctrl_exit(void)
}
module_exit(s500_pinctrl_exit);

-MODULE_AUTHOR("Actions Semi Inc.");
-MODULE_AUTHOR("Cristian Ciocaltea <[email protected]>");
-MODULE_DESCRIPTION("Actions Semi S500 SoC Pinctrl Driver");
-MODULE_LICENSE("GPL");
diff --git a/drivers/pinctrl/actions/pinctrl-s700.c b/drivers/pinctrl/actions/pinctrl-s700.c
index fd00940a5799..391aaabdd527 100644
--- a/drivers/pinctrl/actions/pinctrl-s700.c
+++ b/drivers/pinctrl/actions/pinctrl-s700.c
@@ -1906,6 +1906,3 @@ static void __exit s700_pinctrl_exit(void)
}
module_exit(s700_pinctrl_exit);

-MODULE_AUTHOR("Actions Semi Inc.");
-MODULE_DESCRIPTION("Actions Semi S700 Soc Pinctrl Driver");
-MODULE_LICENSE("GPL");
diff --git a/drivers/pinctrl/actions/pinctrl-s900.c b/drivers/pinctrl/actions/pinctrl-s900.c
index 811249a8011e..baddcf15005c 100644
--- a/drivers/pinctrl/actions/pinctrl-s900.c
+++ b/drivers/pinctrl/actions/pinctrl-s900.c
@@ -1824,7 +1824,3 @@ static void __exit s900_pinctrl_exit(void)
}
module_exit(s900_pinctrl_exit);

-MODULE_AUTHOR("Actions Semi Inc.");
-MODULE_AUTHOR("Manivannan Sadhasivam <[email protected]>");
-MODULE_DESCRIPTION("Actions Semi S900 SoC Pinctrl Driver");
-MODULE_LICENSE("GPL");
diff --git a/drivers/pinctrl/bcm/pinctrl-ns.c b/drivers/pinctrl/bcm/pinctrl-ns.c
index 465cc96814a1..62879fadf2f0 100644
--- a/drivers/pinctrl/bcm/pinctrl-ns.c
+++ b/drivers/pinctrl/bcm/pinctrl-ns.c
@@ -298,6 +298,4 @@ static struct platform_driver ns_pinctrl_driver = {

module_platform_driver(ns_pinctrl_driver);

-MODULE_AUTHOR("Rafał Miłecki");
-MODULE_LICENSE("GPL v2");
MODULE_DEVICE_TABLE(of, ns_pinctrl_of_match_table);
diff --git a/drivers/pinctrl/mediatek/pinctrl-mt8188.c b/drivers/pinctrl/mediatek/pinctrl-mt8188.c
index d0e75c1b4417..3d811d83110a 100644
--- a/drivers/pinctrl/mediatek/pinctrl-mt8188.c
+++ b/drivers/pinctrl/mediatek/pinctrl-mt8188.c
@@ -1669,5 +1669,3 @@ static int __init mt8188_pinctrl_init(void)

arch_initcall(mt8188_pinctrl_init);

-MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("MediaTek MT8188 Pinctrl Driver");
diff --git a/drivers/pinctrl/mediatek/pinctrl-mt8192.c b/drivers/pinctrl/mediatek/pinctrl-mt8192.c
index 78c02b7c81f0..5204d87de9d3 100644
--- a/drivers/pinctrl/mediatek/pinctrl-mt8192.c
+++ b/drivers/pinctrl/mediatek/pinctrl-mt8192.c
@@ -1430,5 +1430,3 @@ static int __init mt8192_pinctrl_init(void)
}
arch_initcall(mt8192_pinctrl_init);

-MODULE_LICENSE("GPL v2");
-MODULE_DESCRIPTION("MediaTek MT8192 Pinctrl Driver");
diff --git a/drivers/pinctrl/mediatek/pinctrl-mt8365.c b/drivers/pinctrl/mediatek/pinctrl-mt8365.c
index 57f37a294063..b591c54b5894 100644
--- a/drivers/pinctrl/mediatek/pinctrl-mt8365.c
+++ b/drivers/pinctrl/mediatek/pinctrl-mt8365.c
@@ -476,6 +476,3 @@ static int __init mtk_pinctrl_init(void)
}
arch_initcall(mtk_pinctrl_init);

-MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("MediaTek MT8365 Pinctrl Driver");
-MODULE_AUTHOR("Zhiyong Tao <[email protected]>");
diff --git a/drivers/pinctrl/nuvoton/pinctrl-npcm7xx.c b/drivers/pinctrl/nuvoton/pinctrl-npcm7xx.c
index 1c4e89b046de..2d95765e3b54 100644
--- a/drivers/pinctrl/nuvoton/pinctrl-npcm7xx.c
+++ b/drivers/pinctrl/nuvoton/pinctrl-npcm7xx.c
@@ -2043,7 +2043,3 @@ static int __init npcm7xx_pinctrl_register(void)
}
arch_initcall(npcm7xx_pinctrl_register);

-MODULE_LICENSE("GPL v2");
-MODULE_AUTHOR("[email protected]");
-MODULE_AUTHOR("[email protected]");
-MODULE_DESCRIPTION("Nuvoton NPCM7XX Pinctrl and GPIO driver");
diff --git a/drivers/pinctrl/pinctrl-amd.c b/drivers/pinctrl/pinctrl-amd.c
index 6be896871718..215a4aab1283 100644
--- a/drivers/pinctrl/pinctrl-amd.c
+++ b/drivers/pinctrl/pinctrl-amd.c
@@ -1203,6 +1203,3 @@ static struct platform_driver amd_gpio_driver = {

module_platform_driver(amd_gpio_driver);

-MODULE_LICENSE("GPL v2");
-MODULE_AUTHOR("Ken Xue <[email protected]>, Jeff Wu <[email protected]>");
-MODULE_DESCRIPTION("AMD GPIO pinctrl driver");
diff --git a/drivers/pinctrl/renesas/pinctrl-rza1.c b/drivers/pinctrl/renesas/pinctrl-rza1.c
index 529c0fc4ec06..111eaf8951f8 100644
--- a/drivers/pinctrl/renesas/pinctrl-rza1.c
+++ b/drivers/pinctrl/renesas/pinctrl-rza1.c
@@ -1405,6 +1405,3 @@ static int __init rza1_pinctrl_init(void)
}
core_initcall(rza1_pinctrl_init);

-MODULE_AUTHOR("Jacopo Mondi <[email protected]");
-MODULE_DESCRIPTION("Pin and gpio controller driver for Reneas RZ/A1 SoC");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/pinctrl/renesas/pinctrl-rza2.c b/drivers/pinctrl/renesas/pinctrl-rza2.c
index c0a04f1ee994..ab6b9cd4c6fa 100644
--- a/drivers/pinctrl/renesas/pinctrl-rza2.c
+++ b/drivers/pinctrl/renesas/pinctrl-rza2.c
@@ -512,6 +512,3 @@ static int __init rza2_pinctrl_init(void)
}
core_initcall(rza2_pinctrl_init);

-MODULE_AUTHOR("Chris Brandt <[email protected]>");
-MODULE_DESCRIPTION("Pin and gpio controller driver for RZ/A2 SoC");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/pinctrl/renesas/pinctrl-rzg2l.c b/drivers/pinctrl/renesas/pinctrl-rzg2l.c
index a43824fd9505..2f90c1fa52ee 100644
--- a/drivers/pinctrl/renesas/pinctrl-rzg2l.c
+++ b/drivers/pinctrl/renesas/pinctrl-rzg2l.c
@@ -1557,6 +1557,3 @@ static int __init rzg2l_pinctrl_init(void)
}
core_initcall(rzg2l_pinctrl_init);

-MODULE_AUTHOR("Lad Prabhakar <[email protected]>");
-MODULE_DESCRIPTION("Pin and gpio controller driver for RZ/G2L family");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/pinctrl/renesas/pinctrl-rzn1.c b/drivers/pinctrl/renesas/pinctrl-rzn1.c
index 849d091205d4..bd60a640b6a3 100644
--- a/drivers/pinctrl/renesas/pinctrl-rzn1.c
+++ b/drivers/pinctrl/renesas/pinctrl-rzn1.c
@@ -946,6 +946,3 @@ static int __init _pinctrl_drv_register(void)
}
subsys_initcall(_pinctrl_drv_register);

-MODULE_AUTHOR("Phil Edworthy <[email protected]>");
-MODULE_DESCRIPTION("Renesas RZ/N1 pinctrl driver");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/pinctrl/renesas/pinctrl-rzv2m.c b/drivers/pinctrl/renesas/pinctrl-rzv2m.c
index e8c18198bebd..dbd842edcce8 100644
--- a/drivers/pinctrl/renesas/pinctrl-rzv2m.c
+++ b/drivers/pinctrl/renesas/pinctrl-rzv2m.c
@@ -1114,6 +1114,3 @@ static int __init rzv2m_pinctrl_init(void)
}
core_initcall(rzv2m_pinctrl_init);

-MODULE_AUTHOR("Phil Edworthy <[email protected]>");
-MODULE_DESCRIPTION("Pin and gpio controller driver for RZ/V2M");
-MODULE_LICENSE("GPL");
diff --git a/drivers/power/reset/as3722-poweroff.c b/drivers/power/reset/as3722-poweroff.c
index 661e1c67f82e..a2182470a5e1 100644
--- a/drivers/power/reset/as3722-poweroff.c
+++ b/drivers/power/reset/as3722-poweroff.c
@@ -81,7 +81,4 @@ static struct platform_driver as3722_poweroff_driver = {

module_platform_driver(as3722_poweroff_driver);

-MODULE_DESCRIPTION("Power off driver for ams AS3722 PMIC Device");
MODULE_ALIAS("platform:as3722-power-off");
-MODULE_AUTHOR("Laxman Dewangan <[email protected]>");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/power/reset/gpio-poweroff.c b/drivers/power/reset/gpio-poweroff.c
index 1c5af2fef142..b6c5cce9fe6c 100644
--- a/drivers/power/reset/gpio-poweroff.c
+++ b/drivers/power/reset/gpio-poweroff.c
@@ -103,7 +103,4 @@ static struct platform_driver gpio_poweroff_driver = {

module_platform_driver(gpio_poweroff_driver);

-MODULE_AUTHOR("Jamie Lentin <[email protected]>");
-MODULE_DESCRIPTION("GPIO poweroff driver");
-MODULE_LICENSE("GPL v2");
MODULE_ALIAS("platform:poweroff-gpio");
diff --git a/drivers/power/reset/gpio-restart.c b/drivers/power/reset/gpio-restart.c
index 5466eeea261c..ee6ba7313e0e 100644
--- a/drivers/power/reset/gpio-restart.c
+++ b/drivers/power/reset/gpio-restart.c
@@ -137,6 +137,3 @@ static struct platform_driver gpio_restart_driver = {

module_platform_driver(gpio_restart_driver);

-MODULE_AUTHOR("David Riley <[email protected]>");
-MODULE_DESCRIPTION("GPIO restart driver");
-MODULE_LICENSE("GPL");
diff --git a/drivers/power/reset/keystone-reset.c b/drivers/power/reset/keystone-reset.c
index c720112db704..cfacee839b10 100644
--- a/drivers/power/reset/keystone-reset.c
+++ b/drivers/power/reset/keystone-reset.c
@@ -167,7 +167,4 @@ static struct platform_driver rsctrl_driver = {
};
module_platform_driver(rsctrl_driver);

-MODULE_AUTHOR("Ivan Khoronzhuk <[email protected]>");
-MODULE_DESCRIPTION("Texas Instruments keystone reset driver");
-MODULE_LICENSE("GPL v2");
MODULE_ALIAS("platform:" KBUILD_MODNAME);
diff --git a/drivers/power/reset/ltc2952-poweroff.c b/drivers/power/reset/ltc2952-poweroff.c
index 65d9528cc989..087533bfc752 100644
--- a/drivers/power/reset/ltc2952-poweroff.c
+++ b/drivers/power/reset/ltc2952-poweroff.c
@@ -315,6 +315,3 @@ static struct platform_driver ltc2952_poweroff_driver = {

module_platform_driver(ltc2952_poweroff_driver);

-MODULE_AUTHOR("René Moll <[email protected]>");
-MODULE_DESCRIPTION("LTC PowerPath power-off driver");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/power/reset/mt6323-poweroff.c b/drivers/power/reset/mt6323-poweroff.c
index d90e76fcb938..97e9de37bf07 100644
--- a/drivers/power/reset/mt6323-poweroff.c
+++ b/drivers/power/reset/mt6323-poweroff.c
@@ -95,6 +95,3 @@ static struct platform_driver mt6323_pwrc_driver = {

module_platform_driver(mt6323_pwrc_driver);

-MODULE_DESCRIPTION("Poweroff driver for MT6323 PMIC");
-MODULE_AUTHOR("Sean Wang <[email protected]>");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/power/reset/regulator-poweroff.c b/drivers/power/reset/regulator-poweroff.c
index 20701203935f..4787829875d4 100644
--- a/drivers/power/reset/regulator-poweroff.c
+++ b/drivers/power/reset/regulator-poweroff.c
@@ -77,7 +77,4 @@ static struct platform_driver regulator_poweroff_driver = {

module_platform_driver(regulator_poweroff_driver);

-MODULE_AUTHOR("Michael Klein <[email protected]>");
-MODULE_DESCRIPTION("Regulator poweroff driver");
-MODULE_LICENSE("GPL v2");
MODULE_ALIAS("platform:poweroff-regulator");
diff --git a/drivers/power/reset/restart-poweroff.c b/drivers/power/reset/restart-poweroff.c
index 04d4228119b2..7adc454658ff 100644
--- a/drivers/power/reset/restart-poweroff.c
+++ b/drivers/power/reset/restart-poweroff.c
@@ -57,7 +57,4 @@ static struct platform_driver restart_poweroff_driver = {
};
module_platform_driver(restart_poweroff_driver);

-MODULE_AUTHOR("Andrew Lunn <[email protected]");
-MODULE_DESCRIPTION("restart poweroff driver");
-MODULE_LICENSE("GPL v2");
MODULE_ALIAS("platform:poweroff-restart");
diff --git a/drivers/power/reset/tps65086-restart.c b/drivers/power/reset/tps65086-restart.c
index 78b89f745a3d..866845a012c7 100644
--- a/drivers/power/reset/tps65086-restart.c
+++ b/drivers/power/reset/tps65086-restart.c
@@ -93,6 +93,3 @@ static struct platform_driver tps65086_restart_driver = {
};
module_platform_driver(tps65086_restart_driver);

-MODULE_AUTHOR("Emil Renner Berthing <[email protected]>");
-MODULE_DESCRIPTION("TPS65086 restart driver");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/power/supply/power_supply_core.c b/drivers/power/supply/power_supply_core.c
index 4b5fb172fa99..b253fc0e401f 100644
--- a/drivers/power/supply/power_supply_core.c
+++ b/drivers/power/supply/power_supply_core.c
@@ -1569,9 +1569,3 @@ static void __exit power_supply_class_exit(void)

subsys_initcall(power_supply_class_init);
module_exit(power_supply_class_exit);
-
-MODULE_DESCRIPTION("Universal power supply monitor class");
-MODULE_AUTHOR("Ian Molton <[email protected]>, "
- "Szabolcs Gyurko, "
- "Anton Vorontsov <[email protected]>");
-MODULE_LICENSE("GPL");
diff --git a/drivers/power/supply/wm97xx_battery.c b/drivers/power/supply/wm97xx_battery.c
index a0e1eaa25d93..73d9f7dc4945 100644
--- a/drivers/power/supply/wm97xx_battery.c
+++ b/drivers/power/supply/wm97xx_battery.c
@@ -271,6 +271,3 @@ static struct platform_driver wm97xx_bat_driver = {

module_platform_driver(wm97xx_bat_driver);

-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Marek Vasut <[email protected]>");
-MODULE_DESCRIPTION("WM97xx battery driver");
diff --git a/drivers/powercap/powercap_sys.c b/drivers/powercap/powercap_sys.c
index f0654a932b37..73246663d614 100644
--- a/drivers/powercap/powercap_sys.c
+++ b/drivers/powercap/powercap_sys.c
@@ -672,6 +672,3 @@ static int __init powercap_init(void)

fs_initcall(powercap_init);

-MODULE_DESCRIPTION("PowerCap sysfs Driver");
-MODULE_AUTHOR("Srinivas Pandruvada <[email protected]>");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/regulator/stm32-pwr.c b/drivers/regulator/stm32-pwr.c
index 2a42acb7c24e..42e3a8860abc 100644
--- a/drivers/regulator/stm32-pwr.c
+++ b/drivers/regulator/stm32-pwr.c
@@ -181,6 +181,3 @@ static struct platform_driver stm32_pwr_driver = {
};
module_platform_driver(stm32_pwr_driver);

-MODULE_DESCRIPTION("STM32MP1 PWR voltage regulator driver");
-MODULE_AUTHOR("Pascal Paillet <[email protected]>");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/remoteproc/remoteproc_core.c b/drivers/remoteproc/remoteproc_core.c
index 8768cb64f560..1e2dac5e54ea 100644
--- a/drivers/remoteproc/remoteproc_core.c
+++ b/drivers/remoteproc/remoteproc_core.c
@@ -2752,5 +2752,3 @@ static void __exit remoteproc_exit(void)
}
module_exit(remoteproc_exit);

-MODULE_LICENSE("GPL v2");
-MODULE_DESCRIPTION("Generic Remote Processor Framework");
diff --git a/drivers/reset/reset-axs10x.c b/drivers/reset/reset-axs10x.c
index a854ef41364d..4f9bce547988 100644
--- a/drivers/reset/reset-axs10x.c
+++ b/drivers/reset/reset-axs10x.c
@@ -79,6 +79,3 @@ static struct platform_driver axs10x_reset_driver = {
};
builtin_platform_driver(axs10x_reset_driver);

-MODULE_AUTHOR("Eugeniy Paltsev <[email protected]>");
-MODULE_DESCRIPTION("Synopsys AXS10x reset driver");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/reset/reset-hsdk.c b/drivers/reset/reset-hsdk.c
index 4c7b8647b49c..8b88aca4c4a4 100644
--- a/drivers/reset/reset-hsdk.c
+++ b/drivers/reset/reset-hsdk.c
@@ -133,6 +133,3 @@ static struct platform_driver hsdk_reset_driver = {
};
builtin_platform_driver(hsdk_reset_driver);

-MODULE_AUTHOR("Eugeniy Paltsev <[email protected]>");
-MODULE_DESCRIPTION("Synopsys HSDK SDP reset driver");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/reset/reset-lantiq.c b/drivers/reset/reset-lantiq.c
index b936cfe85641..2ca9bd5930b8 100644
--- a/drivers/reset/reset-lantiq.c
+++ b/drivers/reset/reset-lantiq.c
@@ -205,6 +205,3 @@ static struct platform_driver lantiq_rcu_reset_driver = {
};
module_platform_driver(lantiq_rcu_reset_driver);

-MODULE_AUTHOR("Martin Blumenstingl <[email protected]>");
-MODULE_DESCRIPTION("Lantiq XWAY RCU Reset Controller Driver");
-MODULE_LICENSE("GPL");
diff --git a/drivers/reset/reset-microchip-sparx5.c b/drivers/reset/reset-microchip-sparx5.c
index f3528dd1d084..47b9b43470a0 100644
--- a/drivers/reset/reset-microchip-sparx5.c
+++ b/drivers/reset/reset-microchip-sparx5.c
@@ -177,6 +177,3 @@ static int __init mchp_sparx5_reset_init(void)
*/
postcore_initcall(mchp_sparx5_reset_init);

-MODULE_DESCRIPTION("Microchip Sparx5 switch reset driver");
-MODULE_AUTHOR("Steen Hegelund <[email protected]>");
-MODULE_LICENSE("Dual MIT/GPL");
diff --git a/drivers/reset/reset-mpfs.c b/drivers/reset/reset-mpfs.c
index e003e50590ec..0735076f3c84 100644
--- a/drivers/reset/reset-mpfs.c
+++ b/drivers/reset/reset-mpfs.c
@@ -151,7 +151,4 @@ static struct auxiliary_driver mpfs_reset_driver = {

module_auxiliary_driver(mpfs_reset_driver);

-MODULE_DESCRIPTION("Microchip PolarFire SoC Reset Driver");
-MODULE_AUTHOR("Conor Dooley <[email protected]>");
-MODULE_LICENSE("GPL");
MODULE_IMPORT_NS(MCHP_CLK_MPFS);
diff --git a/drivers/soc/apple/apple-pmgr-pwrstate.c b/drivers/soc/apple/apple-pmgr-pwrstate.c
index e1122288409a..968272e7a38a 100644
--- a/drivers/soc/apple/apple-pmgr-pwrstate.c
+++ b/drivers/soc/apple/apple-pmgr-pwrstate.c
@@ -317,8 +317,5 @@ static struct platform_driver apple_pmgr_ps_driver = {
},
};

-MODULE_AUTHOR("Hector Martin <[email protected]>");
-MODULE_DESCRIPTION("PMGR power state driver for Apple SoCs");
-MODULE_LICENSE("GPL v2");

module_platform_driver(apple_pmgr_ps_driver);
diff --git a/drivers/soc/bcm/bcm2835-power.c b/drivers/soc/bcm/bcm2835-power.c
index 5bcd047768b6..6ff7a4612c18 100644
--- a/drivers/soc/bcm/bcm2835-power.c
+++ b/drivers/soc/bcm/bcm2835-power.c
@@ -715,6 +715,3 @@ static struct platform_driver bcm2835_power_driver = {
};
module_platform_driver(bcm2835_power_driver);

-MODULE_AUTHOR("Eric Anholt <[email protected]>");
-MODULE_DESCRIPTION("Driver for Broadcom BCM2835 PM power domains and reset");
-MODULE_LICENSE("GPL");
diff --git a/drivers/soc/bcm/raspberrypi-power.c b/drivers/soc/bcm/raspberrypi-power.c
index 068715d6e66d..40b05ea991a2 100644
--- a/drivers/soc/bcm/raspberrypi-power.c
+++ b/drivers/soc/bcm/raspberrypi-power.c
@@ -240,7 +240,3 @@ static struct platform_driver rpi_power_driver = {
};
builtin_platform_driver(rpi_power_driver);

-MODULE_AUTHOR("Alexander Aring <[email protected]>");
-MODULE_AUTHOR("Eric Anholt <[email protected]>");
-MODULE_DESCRIPTION("Raspberry Pi power domain driver");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/soc/fujitsu/a64fx-diag.c b/drivers/soc/fujitsu/a64fx-diag.c
index d87f348427bf..84ee52116cdb 100644
--- a/drivers/soc/fujitsu/a64fx-diag.c
+++ b/drivers/soc/fujitsu/a64fx-diag.c
@@ -149,6 +149,3 @@ static struct platform_driver a64fx_diag_driver = {

module_platform_driver(a64fx_diag_driver);

-MODULE_LICENSE("GPL v2");
-MODULE_AUTHOR("Hitomi Hasegawa <[email protected]>");
-MODULE_DESCRIPTION("A64FX diag driver");
diff --git a/drivers/soc/sunxi/sunxi_sram.c b/drivers/soc/sunxi/sunxi_sram.c
index 92f9186c1c42..d704c9d7eac6 100644
--- a/drivers/soc/sunxi/sunxi_sram.c
+++ b/drivers/soc/sunxi/sunxi_sram.c
@@ -419,6 +419,3 @@ static struct platform_driver sunxi_sram_driver = {
};
builtin_platform_driver_probe(sunxi_sram_driver, sunxi_sram_probe);

-MODULE_AUTHOR("Maxime Ripard <[email protected]>");
-MODULE_DESCRIPTION("Allwinner sunXi SRAM Controller Driver");
-MODULE_LICENSE("GPL");
diff --git a/drivers/soc/tegra/cbb/tegra194-cbb.c b/drivers/soc/tegra/cbb/tegra194-cbb.c
index 1ae0bd9a1ac1..0fb96b72735d 100644
--- a/drivers/soc/tegra/cbb/tegra194-cbb.c
+++ b/drivers/soc/tegra/cbb/tegra194-cbb.c
@@ -2359,6 +2359,3 @@ static void __exit tegra194_cbb_exit(void)
}
module_exit(tegra194_cbb_exit);

-MODULE_AUTHOR("Sumit Gupta <[email protected]>");
-MODULE_DESCRIPTION("Control Backbone error handling driver for Tegra194");
-MODULE_LICENSE("GPL");
diff --git a/drivers/soc/tegra/cbb/tegra234-cbb.c b/drivers/soc/tegra/cbb/tegra234-cbb.c
index 3528f9e15d5c..69fdd547eb3d 100644
--- a/drivers/soc/tegra/cbb/tegra234-cbb.c
+++ b/drivers/soc/tegra/cbb/tegra234-cbb.c
@@ -1109,5 +1109,3 @@ static void __exit tegra234_cbb_exit(void)
}
module_exit(tegra234_cbb_exit);

-MODULE_DESCRIPTION("Control Backbone 2.0 error handling driver for Tegra234");
-MODULE_LICENSE("GPL");
diff --git a/drivers/tty/n_null.c b/drivers/tty/n_null.c
index f913b665af72..d8719740bd11 100644
--- a/drivers/tty/n_null.c
+++ b/drivers/tty/n_null.c
@@ -63,7 +63,4 @@ static void __exit n_null_exit(void)
module_init(n_null_init);
module_exit(n_null_exit);

-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Alan Cox");
MODULE_ALIAS_LDISC(N_NULL);
-MODULE_DESCRIPTION("Null ldisc driver");
diff --git a/drivers/tty/serial/imx_earlycon.c b/drivers/tty/serial/imx_earlycon.c
index 7aab38b2bd8c..e1f6e117c4c0 100644
--- a/drivers/tty/serial/imx_earlycon.c
+++ b/drivers/tty/serial/imx_earlycon.c
@@ -45,6 +45,3 @@ imx_console_early_setup(struct earlycon_device *dev, const char *opt)
OF_EARLYCON_DECLARE(ec_imx6q, "fsl,imx6q-uart", imx_console_early_setup);
OF_EARLYCON_DECLARE(ec_imx21, "fsl,imx21-uart", imx_console_early_setup);

-MODULE_AUTHOR("NXP");
-MODULE_DESCRIPTION("IMX earlycon driver");
-MODULE_LICENSE("GPL");
diff --git a/drivers/tty/serial/rda-uart.c b/drivers/tty/serial/rda-uart.c
index 0e387e2144fa..2fe38d6e513c 100644
--- a/drivers/tty/serial/rda-uart.c
+++ b/drivers/tty/serial/rda-uart.c
@@ -824,6 +824,3 @@ static void __exit rda_uart_exit(void)
module_init(rda_uart_init);
module_exit(rda_uart_exit);

-MODULE_AUTHOR("Manivannan Sadhasivam <[email protected]>");
-MODULE_DESCRIPTION("RDA8810PL serial device driver");
-MODULE_LICENSE("GPL");
diff --git a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c
index fcdf017e2665..8e13af1f9042 100644
--- a/drivers/video/console/vgacon.c
+++ b/drivers/video/console/vgacon.c
@@ -1204,4 +1204,3 @@ const struct consw vga_con = {
};
EXPORT_SYMBOL(vga_con);

-MODULE_LICENSE("GPL");
diff --git a/drivers/video/fbdev/asiliantfb.c b/drivers/video/fbdev/asiliantfb.c
index 3818437a8f69..f1992da7e64e 100644
--- a/drivers/video/fbdev/asiliantfb.c
+++ b/drivers/video/fbdev/asiliantfb.c
@@ -629,4 +629,3 @@ static void __exit asiliantfb_exit(void)
pci_unregister_driver(&asiliantfb_driver);
}

-MODULE_LICENSE("GPL");
diff --git a/drivers/video/fbdev/gbefb.c b/drivers/video/fbdev/gbefb.c
index 000b4aa44241..39e89b9f8dca 100644
--- a/drivers/video/fbdev/gbefb.c
+++ b/drivers/video/fbdev/gbefb.c
@@ -1285,4 +1285,3 @@ static void __exit gbefb_exit(void)
module_init(gbefb_init);
module_exit(gbefb_exit);

-MODULE_LICENSE("GPL");
diff --git a/drivers/video/fbdev/imsttfb.c b/drivers/video/fbdev/imsttfb.c
index d7edb9c5d3a3..39562b0449a0 100644
--- a/drivers/video/fbdev/imsttfb.c
+++ b/drivers/video/fbdev/imsttfb.c
@@ -1631,7 +1631,6 @@ static void __exit imsttfb_exit(void)
pci_unregister_driver(&imsttfb_pci_driver);
}

-MODULE_LICENSE("GPL");

module_init(imsttfb_init);
module_exit(imsttfb_exit);
diff --git a/drivers/video/fbdev/mmp/hw/mmp_ctrl.c b/drivers/video/fbdev/mmp/hw/mmp_ctrl.c
index a9df8ee79810..531db18df108 100644
--- a/drivers/video/fbdev/mmp/hw/mmp_ctrl.c
+++ b/drivers/video/fbdev/mmp/hw/mmp_ctrl.c
@@ -574,6 +574,3 @@ static int mmphw_init(void)
}
module_init(mmphw_init);

-MODULE_AUTHOR("Li Guoqing<[email protected]>");
-MODULE_DESCRIPTION("Framebuffer driver for mmp");
-MODULE_LICENSE("GPL");
diff --git a/drivers/video/fbdev/mmp/panel/tpo_tj032md01bw.c b/drivers/video/fbdev/mmp/panel/tpo_tj032md01bw.c
index 34fae588e202..1b6bf02b1d70 100644
--- a/drivers/video/fbdev/mmp/panel/tpo_tj032md01bw.c
+++ b/drivers/video/fbdev/mmp/panel/tpo_tj032md01bw.c
@@ -167,6 +167,3 @@ static struct spi_driver panel_tpohvga_driver = {
};
module_spi_driver(panel_tpohvga_driver);

-MODULE_AUTHOR("Lisa Du<[email protected]>");
-MODULE_DESCRIPTION("Panel driver for tpohvga");
-MODULE_LICENSE("GPL");
diff --git a/drivers/video/fbdev/vesafb.c b/drivers/video/fbdev/vesafb.c
index 929d4775cb4b..73b35fc67d8b 100644
--- a/drivers/video/fbdev/vesafb.c
+++ b/drivers/video/fbdev/vesafb.c
@@ -508,4 +508,3 @@ static struct platform_driver vesafb_driver = {
};

module_platform_driver(vesafb_driver);
-MODULE_LICENSE("GPL");
diff --git a/drivers/video/fbdev/wm8505fb.c b/drivers/video/fbdev/wm8505fb.c
index 8f4d674fa0d0..373d6d35845d 100644
--- a/drivers/video/fbdev/wm8505fb.c
+++ b/drivers/video/fbdev/wm8505fb.c
@@ -405,7 +405,4 @@ static struct platform_driver wm8505fb_driver = {

module_platform_driver(wm8505fb_driver);

-MODULE_AUTHOR("Ed Spiridonov <[email protected]>");
-MODULE_DESCRIPTION("Framebuffer driver for WMT WM8505");
-MODULE_LICENSE("GPL v2");
MODULE_DEVICE_TABLE(of, wmt_dt_ids);
diff --git a/drivers/video/fbdev/wmt_ge_rops.c b/drivers/video/fbdev/wmt_ge_rops.c
index 42255d27a1db..922ec9b15da3 100644
--- a/drivers/video/fbdev/wmt_ge_rops.c
+++ b/drivers/video/fbdev/wmt_ge_rops.c
@@ -167,8 +167,4 @@ static struct platform_driver wmt_ge_rops_driver = {

module_platform_driver(wmt_ge_rops_driver);

-MODULE_AUTHOR("Alexey Charkov <[email protected]>");
-MODULE_DESCRIPTION("Accelerators for raster operations using "
- "WonderMedia Graphics Engine");
-MODULE_LICENSE("GPL v2");
MODULE_DEVICE_TABLE(of, wmt_dt_ids);
diff --git a/drivers/xen/grant-dma-ops.c b/drivers/xen/grant-dma-ops.c
index daa525df7bdc..92f0d3d16d96 100644
--- a/drivers/xen/grant-dma-ops.c
+++ b/drivers/xen/grant-dma-ops.c
@@ -400,6 +400,3 @@ bool xen_virtio_restricted_mem_acc(struct virtio_device *dev)
return ret;
}

-MODULE_DESCRIPTION("Xen grant DMA-mapping layer");
-MODULE_AUTHOR("Juergen Gross <[email protected]>");
-MODULE_LICENSE("GPL");
diff --git a/drivers/xen/xenbus/xenbus_probe.c b/drivers/xen/xenbus/xenbus_probe.c
index 58b732dcbfb8..86c04f239e87 100644
--- a/drivers/xen/xenbus/xenbus_probe.c
+++ b/drivers/xen/xenbus/xenbus_probe.c
@@ -1066,4 +1066,3 @@ static int __init xenbus_init(void)

postcore_initcall(xenbus_init);

-MODULE_LICENSE("GPL");
diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c
index 6a11025e5850..4bc7efece674 100644
--- a/fs/binfmt_elf.c
+++ b/fs/binfmt_elf.c
@@ -2344,7 +2344,6 @@ static void __exit exit_elf_binfmt(void)

core_initcall(init_elf_binfmt);
module_exit(exit_elf_binfmt);
-MODULE_LICENSE("GPL");

#ifdef CONFIG_BINFMT_ELF_KUNIT_TEST
#include "binfmt_elf_test.c"
diff --git a/fs/nfs_common/nfs_ssc.c b/fs/nfs_common/nfs_ssc.c
index 7c1509e968c8..832246b22c51 100644
--- a/fs/nfs_common/nfs_ssc.c
+++ b/fs/nfs_common/nfs_ssc.c
@@ -12,7 +12,6 @@
#include <linux/nfs_ssc.h>
#include "../nfs/nfs4_fs.h"

-MODULE_LICENSE("GPL");

struct nfs_ssc_client_ops_tbl nfs_ssc_client_tbl;
EXPORT_SYMBOL_GPL(nfs_ssc_client_tbl);
diff --git a/fs/unicode/utf8-core.c b/fs/unicode/utf8-core.c
index 67aaadc3ab07..8395066341a4 100644
--- a/fs/unicode/utf8-core.c
+++ b/fs/unicode/utf8-core.c
@@ -214,4 +214,3 @@ void utf8_unload(struct unicode_map *um)
}
EXPORT_SYMBOL(utf8_unload);

-MODULE_LICENSE("GPL v2");
diff --git a/kernel/dma/map_benchmark.c b/kernel/dma/map_benchmark.c
index 0520a8f4fb1d..44fdbb0de1f3 100644
--- a/kernel/dma/map_benchmark.c
+++ b/kernel/dma/map_benchmark.c
@@ -354,6 +354,3 @@ static void __exit map_benchmark_cleanup(void)
module_init(map_benchmark_init);
module_exit(map_benchmark_cleanup);

-MODULE_AUTHOR("Barry Song <[email protected]>");
-MODULE_DESCRIPTION("dma_map benchmark driver");
-MODULE_LICENSE("GPL");
diff --git a/kernel/events/hw_breakpoint_test.c b/kernel/events/hw_breakpoint_test.c
index c57610f52bb4..692bfe95f067 100644
--- a/kernel/events/hw_breakpoint_test.c
+++ b/kernel/events/hw_breakpoint_test.c
@@ -329,5 +329,3 @@ static struct kunit_suite hw_breakpoint_test_suite = {

kunit_test_suites(&hw_breakpoint_test_suite);

-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Marco Elver <[email protected]>");
diff --git a/kernel/trace/rv/reactor_panic.c b/kernel/trace/rv/reactor_panic.c
index d65f6c25a87c..2ab57e6d12bd 100644
--- a/kernel/trace/rv/reactor_panic.c
+++ b/kernel/trace/rv/reactor_panic.c
@@ -38,6 +38,3 @@ static void __exit unregister_react_panic(void)
module_init(register_react_panic);
module_exit(unregister_react_panic);

-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Daniel Bristot de Oliveira");
-MODULE_DESCRIPTION("panic rv reactor: panic if an exception is found.");
diff --git a/kernel/trace/rv/reactor_printk.c b/kernel/trace/rv/reactor_printk.c
index 4b6b7106a477..c8e1b3f8bb4e 100644
--- a/kernel/trace/rv/reactor_printk.c
+++ b/kernel/trace/rv/reactor_printk.c
@@ -37,6 +37,3 @@ static void __exit unregister_react_printk(void)
module_init(register_react_printk);
module_exit(unregister_react_printk);

-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Daniel Bristot de Oliveira");
-MODULE_DESCRIPTION("printk rv reactor: printk if an exception is hit.");
diff --git a/kernel/watch_queue.c b/kernel/watch_queue.c
index a6f9bdd956c3..f1b4df16a63b 100644
--- a/kernel/watch_queue.c
+++ b/kernel/watch_queue.c
@@ -27,9 +27,6 @@
#include <linux/watch_queue.h>
#include <linux/pipe_fs_i.h>

-MODULE_DESCRIPTION("Watch queue");
-MODULE_AUTHOR("Red Hat, Inc.");
-MODULE_LICENSE("GPL");

#define WATCH_QUEUE_NOTE_SIZE 128
#define WATCH_QUEUE_NOTES_PER_PAGE (PAGE_SIZE / WATCH_QUEUE_NOTE_SIZE)
diff --git a/lib/btree.c b/lib/btree.c
index a82100c73b55..201de7eb1bbd 100644
--- a/lib/btree.c
+++ b/lib/btree.c
@@ -792,6 +792,3 @@ static void __exit btree_module_exit(void)
module_init(btree_module_init);
module_exit(btree_module_exit);

-MODULE_AUTHOR("Joern Engel <[email protected]>");
-MODULE_AUTHOR("Johannes Berg <[email protected]>");
-MODULE_LICENSE("GPL");
diff --git a/lib/crypto/blake2s-generic.c b/lib/crypto/blake2s-generic.c
index 75ccb3e633e6..d9483fb0da5b 100644
--- a/lib/crypto/blake2s-generic.c
+++ b/lib/crypto/blake2s-generic.c
@@ -110,6 +110,3 @@ void blake2s_compress_generic(struct blake2s_state *state, const u8 *block,

EXPORT_SYMBOL(blake2s_compress_generic);

-MODULE_LICENSE("GPL v2");
-MODULE_DESCRIPTION("BLAKE2s hash function");
-MODULE_AUTHOR("Jason A. Donenfeld <[email protected]>");
diff --git a/lib/crypto/blake2s.c b/lib/crypto/blake2s.c
index 98e688c6d891..3a55fc138399 100644
--- a/lib/crypto/blake2s.c
+++ b/lib/crypto/blake2s.c
@@ -67,6 +67,3 @@ static int __init blake2s_mod_init(void)
}

module_init(blake2s_mod_init);
-MODULE_LICENSE("GPL v2");
-MODULE_DESCRIPTION("BLAKE2s hash function");
-MODULE_AUTHOR("Jason A. Donenfeld <[email protected]>");
diff --git a/lib/glob.c b/lib/glob.c
index 15b73f490720..5cad078f0b4f 100644
--- a/lib/glob.c
+++ b/lib/glob.c
@@ -6,8 +6,6 @@
* ATA code that depends on it can be as well. In practice, they're
* both usually compiled in and the module overhead goes away.
*/
-MODULE_DESCRIPTION("glob(7) matching");
-MODULE_LICENSE("Dual MIT/GPL");

/**
* glob_match - Shell-style pattern matching, like !fnmatch(pat, str, 0)
diff --git a/lib/packing.c b/lib/packing.c
index 9a72f4bbf0e2..cfa5167c84b1 100644
--- a/lib/packing.c
+++ b/lib/packing.c
@@ -210,5 +210,3 @@ int packing(void *pbuf, u64 *uval, int startbit, int endbit, size_t pbuflen,
}
EXPORT_SYMBOL(packing);

-MODULE_LICENSE("GPL v2");
-MODULE_DESCRIPTION("Generic bitfield packing and unpacking");
diff --git a/lib/pldmfw/pldmfw.c b/lib/pldmfw/pldmfw.c
index 6e77eb6d8e72..816c4c6f8a47 100644
--- a/lib/pldmfw/pldmfw.c
+++ b/lib/pldmfw/pldmfw.c
@@ -874,6 +874,3 @@ int pldmfw_flash_image(struct pldmfw *context, const struct firmware *fw)
}
EXPORT_SYMBOL(pldmfw_flash_image);

-MODULE_AUTHOR("Jacob Keller <[email protected]>");
-MODULE_LICENSE("GPL v2");
-MODULE_DESCRIPTION("PLDM firmware flash update library");
diff --git a/lib/test_fprobe.c b/lib/test_fprobe.c
index e0381b3ec410..692c1438ed58 100644
--- a/lib/test_fprobe.c
+++ b/lib/test_fprobe.c
@@ -171,4 +171,3 @@ static struct kunit_suite fprobe_test_suite = {

kunit_test_suites(&fprobe_test_suite);

-MODULE_LICENSE("GPL");
diff --git a/mm/zpool.c b/mm/zpool.c
index 68facc193496..03bf00a404c8 100644
--- a/mm/zpool.c
+++ b/mm/zpool.c
@@ -394,6 +394,3 @@ bool zpool_can_sleep_mapped(struct zpool *zpool)
return zpool->can_sleep_mapped;
}

-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Dan Streetman <[email protected]>");
-MODULE_DESCRIPTION("Common API for compressed memory storage");
diff --git a/mm/zswap.c b/mm/zswap.c
index 2d48fd59cc7a..add3d5b55bd0 100644
--- a/mm/zswap.c
+++ b/mm/zswap.c
@@ -1537,6 +1537,3 @@ static int __init init_zswap(void)
/* must be late so crypto has time to come up */
late_initcall(init_zswap);

-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Seth Jennings <[email protected]>");
-MODULE_DESCRIPTION("Compressed cache for swap pages");
diff --git a/net/mctp/af_mctp.c b/net/mctp/af_mctp.c
index fc9e728b6333..597ddd40645c 100644
--- a/net/mctp/af_mctp.c
+++ b/net/mctp/af_mctp.c
@@ -693,8 +693,5 @@ static __exit void mctp_exit(void)
subsys_initcall(mctp_init);
module_exit(mctp_exit);

-MODULE_DESCRIPTION("MCTP core");
-MODULE_LICENSE("GPL v2");
-MODULE_AUTHOR("Jeremy Kerr <[email protected]>");

MODULE_ALIAS_NETPROTO(PF_MCTP);
--
2.38.0.266.g481848f278

2022-12-05 16:55:03

by Nick Alcock

[permalink] [raw]
Subject: [PATCH v10 09/13] kallsyms: introduce sections needed to map symbols to built-in modules

This is part of the kallmodsyms machinery, allowing disambiguation of
every symbol in the kernel by annotating symbols that are part of
built-in modules with their module name. In order to do this we need a
space-efficient way to associate symbols with modules without annotating
every single symbol.

The mapping needed to do this consists of three new symbols, computed by
integrating the information in the (just-added) .tmp_vmlinux.ranges and
modules.builtin.objs: taken together, they map address ranges
(corresponding to object files on the input) to the names of zero or
more modules containing those address ranges.

- kallsyms_module_addresses/kallsyms_module_offsets encodes the
address/offset of each object file (derived from the linker map), in
exactly the same way as kallsyms_addresses/kallsyms_offsets does
for symbols. There is no size: instead, the object files are assumed
to tile the address space. (This is slightly more space-efficient
than using a size). Non-text-section addresses are skipped: for now,
all the users of this interface only need module/non-module
information for instruction pointer addresses, not absolute-addressed
symbols and the like. This restriction can easily be lifted in
future. (Regarding the name: right now the entries correspond pretty
closely to object files, so we could call the section
kallsyms_objfiles or something, but the optimizer added in the next
commit will change this.)

- kallsyms_mod_objnames encodes the name of each module in a modified
form of strtab: notably, if an object file appears in *multiple*
modules, all of which are built in, this is encoded via a zero byte,
a one-byte module count, then a series of that many null-terminated
strings. As a special case, the table starts with a single zero byte
which does *not* represent the start of a multi-module list.

(The name is "objnames" because in an upcoming commit it will store
some object file names too.)

- kallsyms_modules connects the two, encoding a table associated 1:1
with kallsyms_module_addresses / kallsyms_module_offsets, pointing
at an offset in kallsyms_module_names describing which module (or
modules, for a multi-module list) the code occupying this address
range is part of. If an address range is part of no module (always
built-in) it points at 0 (the null byte at the start of the
kallsyms_module_names list).

There is no optimization yet: kallsyms_modules and
kallsyms_module_names will almost certainly contain many duplicate
entries, and kallsyms_module_{addresses,offsets} may contain
consecutive entries that point to the same place. The size hit is
fairly substantial as a result, though still much less than a naive
implementation mapping each symbol to a module name would be: 50KiB or
so.

Since this commit is the first user of the modules_builtin iterator,
introduce rules to actually build it when CONFIG_KALLMODSYMS is set.
Since it's also the first user of the new Kconfig symbol to enable
compiling-out of /proc/kallmodsyms support, introduce that symbol too.

Signed-off-by: Nick Alcock <[email protected]>
Reviewed-by: Kris Van Hees <[email protected]>
---

Notes:
v9: Rename .kallsyms_module_names to .kallsyms_mod_objnames now that it
contains object file names too. Adjustments to the Kconfig wording;
adjustments to modules_thick.builtin rules. Adjust to getopt_long
use in scripts/kallsyms.

scripts/Makefile | 6 +
scripts/kallsyms.c | 375 ++++++++++++++++++++++++++++++++++++++++++++-
2 files changed, 373 insertions(+), 8 deletions(-)

diff --git a/scripts/Makefile b/scripts/Makefile
index 356cafcd313d..9312d36107aa 100644
--- a/scripts/Makefile
+++ b/scripts/Makefile
@@ -33,6 +33,12 @@ ifdef CONFIG_BUILDTIME_MCOUNT_SORT
HOSTCFLAGS_sorttable.o += -DMCOUNT_SORT_ENABLED
endif

+kallsyms-objs := kallsyms.o
+
+ifdef CONFIG_KALLMODSYMS
+kallsyms-objs += modules_builtin.o
+endif
+
# The following programs are only built on demand
hostprogs += unifdef

diff --git a/scripts/kallsyms.c b/scripts/kallsyms.c
index 04e04fbd9625..48bf4661bd09 100644
--- a/scripts/kallsyms.c
+++ b/scripts/kallsyms.c
@@ -5,7 +5,10 @@
* This software may be used and distributed according to the terms
* of the GNU General Public License, incorporated herein by reference.
*
- * Usage: nm -n vmlinux | scripts/kallsyms [--all-symbols] > symbols.S
+ * Usage: nm -n vmlinux
+ * | scripts/kallsyms [--all-symbols] [--absolute-percpu]
+ * [--base-relative] [--builtin=modules.builtin.objs]
+ * > symbols.S
*
* Table compression uses all the unused char codes on the symbols and
* maps these to the most used substrings (tokens). For instance, it might
@@ -25,6 +28,10 @@
#include <string.h>
#include <ctype.h>
#include <limits.h>
+#include <assert.h>
+#include "modules_builtin.h"
+
+#include "../include/generated/autoconf.h"

#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof(arr[0]))

@@ -86,11 +93,118 @@ static int token_profit[0x10000];
static unsigned char best_table[256][2];
static unsigned char best_table_len[256];

+#ifdef CONFIG_KALLMODSYMS
+static unsigned int strhash(const char *s)
+{
+ /* fnv32 hash */
+ unsigned int hash = 2166136261U;
+
+ for (; *s; s++)
+ hash = (hash ^ *s) * 0x01000193;
+ return hash;
+}
+
+#define OBJ2MOD_BITS 10
+#define OBJ2MOD_N (1 << OBJ2MOD_BITS)
+#define OBJ2MOD_MASK (OBJ2MOD_N - 1)
+struct obj2mod_elem {
+ char *obj;
+ char *mods; /* sorted module name strtab */
+ size_t nmods; /* number of modules in "mods" */
+ size_t mods_size; /* size of all mods together */
+ int mod_offset; /* offset of module name in .kallsyms_mod_objnames */
+ struct obj2mod_elem *obj2mod_next;
+};
+
+/*
+ * Map from object files to obj2mod entries (a unique mapping).
+ */
+
+static struct obj2mod_elem *obj2mod[OBJ2MOD_N];
+static size_t num_objfiles;
+
+/*
+ * An ordered list of address ranges and the objfile that occupies that range.
+ */
+struct addrmap_entry {
+ char *obj;
+ unsigned long long addr;
+ unsigned long long end_addr;
+ struct obj2mod_elem *objfile;
+};
+static struct addrmap_entry *addrmap;
+static int addrmap_num, addrmap_alloced;
+
+static void obj2mod_init(void)
+{
+ memset(obj2mod, 0, sizeof(obj2mod));
+}
+
+static struct obj2mod_elem *obj2mod_get(const char *obj)
+{
+ int i = strhash(obj) & OBJ2MOD_MASK;
+ struct obj2mod_elem *elem;
+
+ for (elem = obj2mod[i]; elem; elem = elem->obj2mod_next) {
+ if (strcmp(elem->obj, obj) == 0)
+ return elem;
+ }
+ return NULL;
+}
+
+/*
+ * Note that a given object file is found in some module, interning it in the
+ * obj2mod hash. Should not be called more than once for any given (module,
+ * object) pair.
+ */
+static void obj2mod_add(char *obj, char *mod)
+{
+ int i = strhash(obj) & OBJ2MOD_MASK;
+ struct obj2mod_elem *elem;
+
+ elem = obj2mod_get(obj);
+ if (!elem) {
+ elem = malloc(sizeof(struct obj2mod_elem));
+ if (!elem)
+ goto oom;
+ memset(elem, 0, sizeof(struct obj2mod_elem));
+ elem->obj = strdup(obj);
+ if (!elem->obj)
+ goto oom;
+ elem->mods = strdup(mod);
+ if (!elem->mods)
+ goto oom;
+
+ elem->obj2mod_next = obj2mod[i];
+ obj2mod[i] = elem;
+ num_objfiles++;
+ } else {
+ elem->mods = realloc(elem->mods, elem->mods_size +
+ strlen(mod) + 1);
+ if (!elem->mods)
+ goto oom;
+ strcpy(elem->mods + elem->mods_size, mod);
+ }
+
+ elem->mods_size += strlen(mod) + 1;
+ elem->nmods++;
+ if (elem->nmods > 255) {
+ fprintf(stderr, "kallsyms: %s: too many modules associated with this object file\n",
+ obj);
+ exit(EXIT_FAILURE);
+ }
+ return;
+oom:
+ fprintf(stderr, "kallsyms: out of memory\n");
+ exit(1);
+}
+#endif /* CONFIG_KALLMODSYMS */

static void usage(void)
{
fprintf(stderr, "Usage: kallsyms [--all-symbols] [--absolute-percpu] "
- "[--base-relative] [--lto-clang] in.map > out.S\n");
+ "[--base-relative] [--lto-clang] [--builtin=modules.builtin.objs] "
+ " in.map > out.S\n");
exit(1);
}

@@ -114,10 +228,16 @@ static bool is_ignored_symbol(const char *name, char type)
"kallsyms_offsets",
"kallsyms_relative_base",
"kallsyms_num_syms",
+ "kallsyms_num_modules",
"kallsyms_names",
"kallsyms_markers",
"kallsyms_token_table",
"kallsyms_token_index",
+ "kallsyms_module_offsets",
+ "kallsyms_module_addresses",
+ "kallsyms_modules",
+ "kallsyms_mod_objnames",
+ "kallsyms_mod_objnames_len",
/* Exclude linker generated symbols which vary between passes */
"_SDA_BASE_", /* ppc */
"_SDA2_BASE_", /* ppc */
@@ -264,8 +384,8 @@ static struct sym_entry *read_symbol(FILE *in)
return sym;
}

-static int symbol_in_range(const struct sym_entry *s,
- const struct addr_range *ranges, int entries)
+static int addr_in_range(unsigned long long addr,
+ const struct addr_range *ranges, int entries)
{
size_t i;
const struct addr_range *ar;
@@ -273,7 +393,7 @@ static int symbol_in_range(const struct sym_entry *s,
for (i = 0; i < entries; ++i) {
ar = &ranges[i];

- if (s->addr >= ar->start && s->addr <= ar->end)
+ if (addr >= ar->start && addr <= ar->end)
return 1;
}

@@ -287,8 +407,8 @@ static int symbol_valid(const struct sym_entry *s)
/* if --all-symbols is not specified, then symbols outside the text
* and inittext sections are discarded */
if (!all_symbols) {
- if (symbol_in_range(s, text_ranges,
- ARRAY_SIZE(text_ranges)) == 0)
+ if (addr_in_range(s->addr, text_ranges,
+ ARRAY_SIZE(text_ranges)) == 0)
return 0;
/* Corner case. Discard any symbols with the same value as
* _etext _einittext; they can move between pass 1 and 2 when
@@ -380,6 +500,121 @@ static void output_address(unsigned long long addr)
printf("\tPTR\t_text - %#llx\n", _text - addr);
}

+#ifdef CONFIG_KALLMODSYMS
+/* Output the .kallmodsyms_mod_objnames symbol content. */
+static void output_kallmodsyms_mod_objnames(void)
+{
+ struct obj2mod_elem *elem;
+ size_t offset = 1;
+ size_t i;
+
+ /*
+ * Traverse and emit, updating mod_offset accordingly. Emit a single \0
+ * at the start, to encode non-modular objfiles.
+ */
+ output_label("kallsyms_mod_objnames");
+ printf("\t.byte\t0\n");
+ for (i = 0; i < OBJ2MOD_N; i++) {
+ for (elem = obj2mod[i]; elem;
+ elem = elem->obj2mod_next) {
+ const char *onemod;
+ size_t i;
+
+ elem->mod_offset = offset;
+ onemod = elem->mods;
+
+ /*
+ * Technically this is a waste of space: we could just
+ * as well implement multimodule entries by pointing one
+ * byte further back, to the trailing \0 of the previous
+ * entry, but doing it this way makes it more obvious
+ * when an entry is a multimodule entry.
+ */
+ if (elem->nmods != 1) {
+ printf("\t.byte\t0\n");
+ printf("\t.byte\t%zi\n", elem->nmods);
+ offset += 2;
+ }
+
+ for (i = elem->nmods; i > 0; i--) {
+ printf("\t.asciz\t\"%s\"\n", onemod);
+ offset += strlen(onemod) + 1;
+ onemod += strlen(onemod) + 1;
+ }
+ }
+ }
+ printf("\n");
+ output_label("kallsyms_mod_objnames_len");
+ printf("\t.long\t%zi\n", offset);
+}
+
+static void output_kallmodsyms_objfiles(void)
+{
+ size_t i = 0;
+ size_t emitted_offsets = 0;
+ size_t emitted_objfiles = 0;
+
+ if (base_relative)
+ output_label("kallsyms_module_offsets");
+ else
+ output_label("kallsyms_module_addresses");
+
+ for (i = 0; i < addrmap_num; i++) {
+ long long offset;
+ int overflow;
+
+ if (base_relative) {
+ if (!absolute_percpu) {
+ offset = addrmap[i].addr - relative_base;
+ overflow = (offset < 0 || offset > UINT_MAX);
+ } else {
+ offset = relative_base - addrmap[i].addr - 1;
+ overflow = (offset < INT_MIN || offset >= 0);
+ }
+ if (overflow) {
+ fprintf(stderr, "kallsyms failure: "
+ "objfile %s at address %#llx out of range in relative mode\n",
+ addrmap[i].objfile ? addrmap[i].objfile->obj :
+ "in always-built-in object", table[i]->addr);
+ exit(EXIT_FAILURE);
+ }
+ printf("\t.long\t0x%x\n", (int)offset);
+ } else
+ printf("\tPTR\t%#llx\n", addrmap[i].addr);
+ emitted_offsets++;
+ }
+
+ output_label("kallsyms_modules");
+
+ for (i = 0; i < addrmap_num; i++) {
+ struct obj2mod_elem *elem = addrmap[i].objfile;
+ /*
+ * Address range cites no modular object file: point at 0, the
+ * built-in module.
+ */
+ if (addrmap[i].objfile == NULL) {
+ printf("\t.long\t0x0\n");
+ emitted_objfiles++;
+ continue;
+ }
+
+ /*
+ * Zero offset is the initial \0, there to catch uninitialized
+ * obj2mod entries, and is forbidden.
+ */
+ assert(elem->mod_offset != 0);
+
+ printf("\t.long\t0x%x\n", elem->mod_offset);
+ emitted_objfiles++;
+ }
+
+ assert(emitted_offsets == emitted_objfiles);
+ output_label("kallsyms_num_modules");
+ printf("\t.long\t%zi\n", emitted_objfiles);
+ printf("\n");
+}
+#endif /* CONFIG_KALLMODSYMS */
+
/* uncompress a compressed symbol. When this function is called, the best table
* might still be compressed itself, so the function needs to be recursive */
static int expand_symbol(const unsigned char *data, int len, char *result)
@@ -538,6 +773,11 @@ static void write_src(void)
printf("\n");
}

+#ifdef CONFIG_KALLMODSYMS
+ output_kallmodsyms_mod_objnames();
+ output_kallmodsyms_objfiles();
+#endif
+
output_label("kallsyms_num_syms");
printf("\t.long\t%u\n", table_cnt);
printf("\n");
@@ -855,7 +1095,7 @@ static void make_percpus_absolute(void)
unsigned int i;

for (i = 0; i < table_cnt; i++)
- if (symbol_in_range(table[i], &percpu_range, 1)) {
+ if (addr_in_range(table[i]->addr, &percpu_range, 1)) {
/*
* Keep the 'A' override for percpu symbols to
* ensure consistent behavior compared to older
@@ -882,14 +1122,124 @@ static void record_relative_base(void)
}
}

+#ifdef CONFIG_KALLMODSYMS
+/*
+ * Read the linker map.
+ */
+static void read_linker_map(void)
+{
+ unsigned long long addr, size;
+ char *obj;
+ FILE *f = fopen(".tmp_vmlinux.ranges", "r");
+
+ if (!f) {
+ fprintf(stderr, "Cannot open '.tmp_vmlinux.ranges'.\n");
+ exit(1);
+ }
+
+ addrmap_num = 0;
+ addrmap_alloced = 4096;
+ addrmap = malloc(sizeof(*addrmap) * addrmap_alloced);
+ if (!addrmap)
+ goto oom;
+
+ /*
+ * For each address range, add to addrmap the address and the objfile
+ * entry to which the range maps. Only add entries relating to text
+ * ranges.
+ *
+ * Ranges that do not correspond to a built-in module, but to an
+ * always-built-in object file, have no obj2mod_elem and point at NULL
+ * instead. Their obj member is still filled out.
+ */
+
+ while (fscanf(f, "%llx %llx %ms\n", &addr, &size, &obj) == 3) {
+ struct obj2mod_elem *elem = obj2mod_get(obj);
+
+ if (addr == 0 || size == 0 ||
+ !addr_in_range(addr, text_ranges, ARRAY_SIZE(text_ranges))) {
+ free(obj);
+ continue;
+ }
+
+ if (addrmap_num >= addrmap_alloced) {
+ addrmap_alloced *= 2;
+ addrmap = realloc(addrmap,
+ sizeof(*addrmap) * addrmap_alloced);
+ if (!addrmap)
+ goto oom;
+ }
+
+ addrmap[addrmap_num].addr = addr;
+ addrmap[addrmap_num].end_addr = addr + size;
+ addrmap[addrmap_num].objfile = elem;
+ addrmap[addrmap_num].obj = obj;
+ addrmap_num++;
+ }
+ fclose(f);
+ return;
+
+oom:
+ fprintf(stderr, "kallsyms: out of memory\n");
+ exit(1);
+}
+
+/*
+ * Read "modules.builtin.objs" (the list of built-in modules). Construct the
+ * obj2mod hash to track objfile -> module mappings. Read ".tmp_vmlinux.ranges"
+ * (the linker map) and build addrmap[], which maps address ranges to built-in
+ * module names (using obj2mod).
+ */
+static void read_modules(const char *modules_builtin)
+{
+ struct modules_builtin_iter *i;
+ char *module_name = NULL;
+ char **module_paths;
+
+ obj2mod_init();
+ /*
+ * Iterate over all modules in modules.builtin.objs and add each.
+ */
+ i = modules_builtin_iter_new(modules_builtin);
+ if (i == NULL) {
+ fprintf(stderr, "Cannot iterate over builtin modules.\n");
+ exit(1);
+ }
+
+ while ((module_paths = modules_builtin_iter_next(i, &module_name))) {
+ char **walk = module_paths;
+ while (*walk) {
+ obj2mod_add(*walk, module_name);
+ walk++;
+ }
+ free(module_paths);
+ }
+
+ free(module_name);
+ modules_builtin_iter_free(i);
+
+ /*
+ * Read linker map.
+ */
+ read_linker_map();
+}
+#else
+static void read_modules(const char *unused) {}
+#endif /* CONFIG_KALLMODSYMS */
+
int main(int argc, char **argv)
{
+ char *modules_builtin = "modules.builtin.objs";
+
while (1) {
+ static int has_modules_builtin;
+
static struct option long_options[] = {
{"all-symbols", no_argument, &all_symbols, 1},
{"absolute-percpu", no_argument, &absolute_percpu, 1},
{"base-relative", no_argument, &base_relative, 1},
{"lto-clang", no_argument, &lto_clang, 1},
+ {"builtin", required_argument, &has_modules_builtin, 1},
{},
};

@@ -899,12 +1249,21 @@ int main(int argc, char **argv)
break;
if (c != 0)
usage();
+
+ if (has_modules_builtin) {
+ modules_builtin = strdup(optarg);
+ if (!modules_builtin) {
+ fprintf(stderr, "Out of memory parsing args\n");
+ exit(1);
+ }
+ }
}

if (optind >= argc)
usage();

read_map(argv[optind]);
+ read_modules(modules_builtin);
shrink_table();
if (absolute_percpu)
make_percpus_absolute();
--
2.38.0.266.g481848f278

2022-12-05 17:05:56

by Nick Alcock

[permalink] [raw]
Subject: [PATCH v10 12/13] kallsyms: add /proc/kallmodsyms for text symbol disambiguation

Use the tables added in the previous commits to introduce a new
/proc/kallmodsyms, in which [module names] are also given for things
that *could* have been modular had they not been built in to the kernel.
So symbols that are part of, say, ext4 are reported as [ext4] even if
ext4 happens to be buiilt in to the kernel in this configuration.

This helps disambiguate symbols with identical names when some are in
built-in modules are some are not, but if symbols are still ambiguous,
{object file names} are added as needed to disambiguate them. The
object file names are only shown if they would prevent ambiguity, and
are minimized by chopping off as many leading path components as
possible without (symbol, module, objfile) combinations becoming
ambiguous again. (Not every symbol with an {object file name} is
necessarily ambiguous, but at least one symbol in any such object file
would have been ambiguous if the object file was not mentioned.)

Symbols that are part of multiple modules at the same time are shown
with [multiple] [module names]: consumers will have to be ready to
handle such lines. Also, kernel symbols for built-in modules will be
sorted by address, as usual for the core kernel, so will probably appear
interspersed with other symbols that are part of different modules and
non-modular always-built-in symbols, which, as usual, have no
square-bracketed module denotation. This differs from /proc/kallsyms;
even though /proc/kallsyms shows the same symbols as /proc/kallmodsyms
in the same order, the only modules it names are loadable ones, which
are necessarily in single contiguous blocks and thus shown contiguously.

The result looks like this: ([...] to show where lines are omitted for
brevity):

ffffffff97606e50 t not_visible
ffffffff97606e70 T perf_msr_probe
ffffffff97606f80 t test_msr [rapl]
ffffffff97606fa0 t __rapl_pmu_event_start [rapl]
[...]
ffffffffa6007350 t rapl_pmu_event_stop [rapl]
ffffffffa6007440 t rapl_pmu_event_del [rapl]
ffffffffa6007460 t rapl_hrtimer_handle [rapl]
ffffffffa6007500 t rapl_pmu_event_read [rapl]
ffffffffa6007520 t rapl_pmu_event_init [rapl]
ffffffffa6007630 t rapl_cpu_offline [rapl]
ffffffffa6007710 t amd_pmu_event_map {core.o}
ffffffffa6007750 t amd_pmu_add_event {core.o}
ffffffffa6007760 t amd_put_event_constraints_f17h {core.o}

The [rapl] notation is emitted even if rapl is built into the kernel
(but, obviously, not if it's not in the .config at all, or is in a
loadable module that is not loaded). The {core.o} is an object file
name.

Further down, we see what happens when object files are reused by
multiple modules, all of which are built in to the kernel, and some of
which have symbols that would be ambiguous without an object file name
attached in addition to the module names:

ffffffff97d7aed0 t liquidio_pcie_mmio_enabled [liquidio]
ffffffff97d7aef0 t liquidio_pcie_resume [liquidio]
ffffffff97d7af00 t liquidio_ptp_adjtime [liquidio]
ffffffff97d7af50 t liquidio_ptp_enable [liquidio]
ffffffff97d7af70 t liquidio_get_stats64 [liquidio]
ffffffff97d7b0f0 t liquidio_fix_features [liquidio]
ffffffff97d7b1c0 t liquidio_get_port_parent_id [liquidio]
[...]
ffffffff97d824c0 t lio_vf_rep_modinit [liquidio]
ffffffff97d824f0 t lio_vf_rep_modexit [liquidio]
ffffffff97d82520 t lio_ethtool_get_channels [liquidio] [liquidio_vf]
ffffffff97d82600 t lio_ethtool_get_ringparam [liquidio] [liquidio_vf]
ffffffff97d826a0 t lio_get_msglevel [liquidio] [liquidio_vf]
ffffffff97d826c0 t lio_vf_set_msglevel [liquidio] [liquidio_vf]
ffffffff97d826e0 t lio_get_pauseparam [liquidio] [liquidio_vf]
ffffffff97d82710 t lio_get_ethtool_stats [liquidio] [liquidio_vf]
ffffffff97d82e70 t lio_vf_get_ethtool_stats [liquidio] [liquidio_vf]
[...]
ffffffff97d91a80 t cn23xx_vf_mbox_thread [liquidio] [liquidio_vf] {cn23xx_vf_device.o}
ffffffff97d91aa0 t cpumask_weight.constprop.0 [liquidio] [liquidio_vf] {cn23xx_vf_device.o}
ffffffff97d91ac0 t cn23xx_vf_msix_interrupt_handler [liquidio] [liquidio_vf] {cn23xx_vf_device.o}
ffffffff97d91bd0 t cn23xx_vf_get_oq_ticks [liquidio] [liquidio_vf] {cn23xx_vf_device.o}
ffffffff97d91c00 t cn23xx_vf_ask_pf_to_do_flr [liquidio] [liquidio_vf] {cn23xx_vf_device.o}
ffffffff97d91c70 t cn23xx_octeon_pfvf_handshake [liquidio] [liquidio_vf] {cn23xx_vf_device.o}
ffffffff97d91e20 t cn23xx_setup_octeon_vf_device [liquidio] [liquidio_vf] {cn23xx_vf_device.o}
ffffffff97d92060 t octeon_mbox_read [liquidio] [liquidio_vf]
ffffffff97d92230 t octeon_mbox_write [liquidio] [liquidio_vf]
[...]
ffffffff97d946b0 t octeon_alloc_soft_command_resp [liquidio] [liquidio_vf]
ffffffff97d947e0 t octnet_send_nic_data_pkt [liquidio] [liquidio_vf]
ffffffff97d94820 t octnet_send_nic_ctrl_pkt [liquidio] [liquidio_vf]
ffffffff97d94ab0 t liquidio_get_stats64 [liquidio_vf]
ffffffff97d94c10 t liquidio_fix_features [liquidio_vf]
ffffffff97d94cd0 t wait_for_pending_requests [liquidio_vf]

Like /proc/kallsyms, the output is driven by address, so keeps the
curious property of /proc/kallsyms that symbols may appear repeatedly
with different addresses: but now, unlike in /proc/kallsyms, we can see
that those symbols appear repeatedly because they are *different
symbols* that ultimately belong to different modules or different object
files within a module, all of which are built in to the kernel.

As with /proc/kallsyms, non-root usage produces addresses that are
all zero.

I am not wedded to the name or format of /proc/kallmodsyms, but felt it
best to split it out of /proc/kallsyms to avoid breaking existing
kallsyms parsers.

This is currently driven by a new config option, but now that
kallmodsyms data uses very little space, this option might be something
people don't want to bother with: maybe we can just control it via
CONFIG_KALLSYMS or something.

Internally, this uses a new kallsyms_builtin_module_address() almost
identical to kallsyms_sym_address() to get the address corresponding to
a given .kallsyms_modules index, and a new get_builtin_modobj_idx quite
similar to get_symbol_pos to determine the index in the
.kallsyms_modules and .kallsyms_objfiles arrays that relate to a given
address. We save a little time by exploiting the fact that all callers
will only ever traverse this list from start to end by allowing them to
pass in the previous index returned from this function as a hint: thus
very few bsearches are actually needed. (In theory this could change to
just walk straight down kallsyms_module_addresses/offsets and not bother
bsearching at all, but doing it this way is hardly any slower and much
more robust.)

We explicitly filter out displaying modules for non-text symbols
(perhaps this could be lifted for initialized data symbols in future).
There might be occasional incorrect module or objfile names for section
start/end symbols.

The display process is complicated a little by the weird format of the
.kallsyms_mod_objnames table: we have to look for multimodule entries
and print them as space-separated lists of module names.

Signed-off-by: Nick Alcock <[email protected]>
Reviewed-by: Kris Van Hees <[email protected]>
---

Notes:
v9: add objfile support. Commit message adjustments.
v10: Slight conflict adjustments.

kernel/kallsyms.c | 277 ++++++++++++++++++++++++++++++++++---
kernel/kallsyms_internal.h | 14 ++
2 files changed, 274 insertions(+), 17 deletions(-)

diff --git a/kernel/kallsyms.c b/kernel/kallsyms.c
index 83f499182c9a..5306208060a0 100644
--- a/kernel/kallsyms.c
+++ b/kernel/kallsyms.c
@@ -163,6 +163,25 @@ unsigned long kallsyms_sym_address(int idx)
return kallsyms_relative_base - 1 - kallsyms_offsets[idx];
}

+#ifdef CONFIG_KALLMODSYMS
+static unsigned long kallsyms_builtin_module_address(int idx)
+{
+ if (!IS_ENABLED(CONFIG_KALLSYMS_BASE_RELATIVE))
+ return kallsyms_module_addresses[idx];
+
+ /* values are unsigned offsets if --absolute-percpu is not in effect */
+ if (!IS_ENABLED(CONFIG_KALLSYMS_ABSOLUTE_PERCPU))
+ return kallsyms_relative_base + (u32)kallsyms_module_offsets[idx];
+
+ /* ...otherwise, positive offsets are absolute values */
+ if (kallsyms_module_offsets[idx] >= 0)
+ return kallsyms_module_offsets[idx];
+
+ /* ...and negative offsets are relative to kallsyms_relative_base - 1 */
+ return kallsyms_relative_base - 1 - kallsyms_module_offsets[idx];
+}
+#endif
+
static bool cleanup_symbol_name(char *s)
{
char *res;
@@ -385,6 +404,54 @@ static unsigned long get_symbol_pos(unsigned long addr,
return low;
}

+/*
+ * The caller passes in an address, and we return an index to the corresponding
+ * builtin module index in .kallsyms_modules and .kallsyms_objfiles, or
+ * (unsigned long) -1 if none match.
+ *
+ * The hint_idx, if set, is a hint as to the possible return value, to handle
+ * the common case in which consecutive runs of addresses relate to the same
+ * index.
+ */
+#ifdef CONFIG_KALLMODSYMS
+static unsigned long get_builtin_modobj_idx(unsigned long addr, unsigned long hint_idx)
+{
+ unsigned long low, high, mid;
+
+ if (!IS_ENABLED(CONFIG_KALLSYMS_BASE_RELATIVE))
+ BUG_ON(!kallsyms_module_addresses);
+ else
+ BUG_ON(!kallsyms_module_offsets);
+
+ /*
+ * Do a binary search on the sorted kallsyms_modules array. The last
+ * entry in this array indicates the end of the text section, not an
+ * object file.
+ */
+ low = 0;
+ high = kallsyms_num_modules - 1;
+
+ if (hint_idx > low && hint_idx < (high - 1) &&
+ addr >= kallsyms_builtin_module_address(hint_idx) &&
+ addr < kallsyms_builtin_module_address(hint_idx + 1))
+ return hint_idx;
+
+ if (addr >= kallsyms_builtin_module_address(low)
+ && addr < kallsyms_builtin_module_address(high)) {
+ while (high - low > 1) {
+ mid = low + (high - low) / 2;
+ if (kallsyms_builtin_module_address(mid) <= addr)
+ low = mid;
+ else
+ high = mid;
+ }
+ return low;
+ }
+
+ return (unsigned long) -1;
+}
+#endif
+
/*
* Lookup an address but don't bother to find any names.
*/
@@ -656,6 +723,9 @@ struct kallsym_iter {
char type;
char name[KSYM_NAME_LEN];
char module_name[MODULE_NAME_LEN];
+ const char *builtin_module_names;
+ const char *builtin_objfile_name;
+ unsigned long hint_builtin_modobj_idx;
int exported;
int show_value;
};
@@ -686,6 +756,9 @@ static int get_ksymbol_mod(struct kallsym_iter *iter)
&iter->value, &iter->type,
iter->name, iter->module_name,
&iter->exported);
+ iter->builtin_module_names = NULL;
+ iter->builtin_objfile_name = NULL;
+
if (ret < 0) {
iter->pos_mod_end = iter->pos;
return 0;
@@ -705,6 +778,9 @@ static int get_ksymbol_ftrace_mod(struct kallsym_iter *iter)
&iter->value, &iter->type,
iter->name, iter->module_name,
&iter->exported);
+ iter->builtin_module_names = NULL;
+ iter->builtin_objfile_name = NULL;
+
if (ret < 0) {
iter->pos_ftrace_mod_end = iter->pos;
return 0;
@@ -719,6 +795,8 @@ static int get_ksymbol_bpf(struct kallsym_iter *iter)

strlcpy(iter->module_name, "bpf", MODULE_NAME_LEN);
iter->exported = 0;
+ iter->builtin_module_names = NULL;
+ iter->builtin_objfile_name = NULL;
ret = bpf_get_kallsym(iter->pos - iter->pos_ftrace_mod_end,
&iter->value, &iter->type,
iter->name);
@@ -739,23 +817,74 @@ static int get_ksymbol_kprobe(struct kallsym_iter *iter)
{
strlcpy(iter->module_name, "__builtin__kprobes", MODULE_NAME_LEN);
iter->exported = 0;
+ iter->builtin_module_names = NULL;
+ iter->builtin_objfile_name = NULL;
return kprobe_get_kallsym(iter->pos - iter->pos_bpf_end,
&iter->value, &iter->type,
iter->name) < 0 ? 0 : 1;
}

/* Returns space to next name. */
-static unsigned long get_ksymbol_core(struct kallsym_iter *iter)
+static unsigned long get_ksymbol_core(struct kallsym_iter *iter, int kallmodsyms)
{
unsigned off = iter->nameoff;

- iter->module_name[0] = '\0';
+ iter->exported = 0;
iter->value = kallsyms_sym_address(iter->pos);

iter->type = kallsyms_get_symbol_type(off);

+ iter->module_name[0] = '\0';
+ iter->builtin_module_names = NULL;
+ iter->builtin_objfile_name = NULL;
+
off = kallsyms_expand_symbol(off, iter->name, ARRAY_SIZE(iter->name));
+#ifdef CONFIG_KALLMODSYMS
+ if (kallmodsyms) {
+ unsigned long modobj_idx = (unsigned long) -1;
+
+ if (kallsyms_module_offsets)
+ modobj_idx =
+ get_builtin_modobj_idx(iter->value,
+ iter->hint_builtin_modobj_idx);

+ /*
+ * This is a built-in module iff the tables of built-in modules
+ * (address->module name mappings), object files (ditto), and
+ * module/objfile names are known, and if the address was found
+ * there, and if the corresponding module index is nonzero, and
+ * iff this is a text (or weak) symbol. All other cases mean
+ * off the end of the binary or in a non-modular range in
+ * between one or more modules.
+ *
+ * The same rules are true for kallsyms_objfiles, except that
+ * zero entries are much more common because we only record
+ * object file names if we need them to disambiguate one or more
+ * symbols: see scripts/kallsyms.c:disambiguate_syms.
+ *
+ * (Also guard against corrupt kallsyms_modules or
+ * kallsyms_objfiles arrays pointing off the end of
+ * kallsyms_mod_objnames.)
+ */
+ if (kallsyms_modules != NULL && kallsyms_mod_objnames != NULL &&
+ kallsyms_objfiles != NULL &&
+ (iter->type == 't' || iter->type == 'T' ||
+ iter->type == 'w' || iter->type == 'W') &&
+ modobj_idx != (unsigned long) -1) {
+
+ if (kallsyms_modules[modobj_idx] != 0 &&
+ kallsyms_modules[modobj_idx] < kallsyms_mod_objnames_len)
+ iter->builtin_module_names =
+ &kallsyms_mod_objnames[kallsyms_modules[modobj_idx]];
+
+ if (kallsyms_objfiles[modobj_idx] != 0 &&
+ kallsyms_objfiles[modobj_idx] < kallsyms_mod_objnames_len)
+ iter->builtin_objfile_name =
+ &kallsyms_mod_objnames[kallsyms_objfiles[modobj_idx]];
+ }
+ iter->hint_builtin_modobj_idx = modobj_idx;
+ }
+#endif
return off - iter->nameoff;
}

@@ -801,7 +930,7 @@ static int update_iter_mod(struct kallsym_iter *iter, loff_t pos)
}

/* Returns false if pos at or past end of file. */
-static int update_iter(struct kallsym_iter *iter, loff_t pos)
+static int update_iter(struct kallsym_iter *iter, loff_t pos, int kallmodsyms)
{
/* Module symbols can be accessed randomly. */
if (pos >= kallsyms_num_syms)
@@ -811,7 +940,7 @@ static int update_iter(struct kallsym_iter *iter, loff_t pos)
if (pos != iter->pos)
reset_iter(iter, pos);

- iter->nameoff += get_ksymbol_core(iter);
+ iter->nameoff += get_ksymbol_core(iter, kallmodsyms);
iter->pos++;

return 1;
@@ -821,14 +950,14 @@ static void *s_next(struct seq_file *m, void *p, loff_t *pos)
{
(*pos)++;

- if (!update_iter(m->private, *pos))
+ if (!update_iter(m->private, *pos, 0))
return NULL;
return p;
}

static void *s_start(struct seq_file *m, loff_t *pos)
{
- if (!update_iter(m->private, *pos))
+ if (!update_iter(m->private, *pos, 0))
return NULL;
return m->private;
}
@@ -837,7 +966,7 @@ static void s_stop(struct seq_file *m, void *p)
{
}

-static int s_show(struct seq_file *m, void *p)
+static int s_show_internal(struct seq_file *m, void *p, int kallmodsyms)
{
void *value;
struct kallsym_iter *iter = m->private;
@@ -848,23 +977,82 @@ static int s_show(struct seq_file *m, void *p)

value = iter->show_value ? (void *)iter->value : NULL;

- if (iter->module_name[0]) {
+ /*
+ * Real module, or built-in module and /proc/kallsyms being shown.
+ */
+ if (iter->module_name[0] != '\0' ||
+ (iter->builtin_module_names != NULL && kallmodsyms != 0)) {
char type;

/*
- * Label it "global" if it is exported,
- * "local" if not exported.
+ * Label it "global" if it is exported, "local" if not exported.
*/
type = iter->exported ? toupper(iter->type) :
tolower(iter->type);
- seq_printf(m, "%px %c %s\t[%s]\n", value,
- type, iter->name, iter->module_name);
- } else
- seq_printf(m, "%px %c %s\n", value,
+#ifdef CONFIG_KALLMODSYMS
+ if (kallmodsyms) {
+ /*
+ * /proc/kallmodsyms, built as a module.
+ */
+ if (iter->builtin_module_names == NULL)
+ seq_printf(m, "%px %c %s\t[%s]", value,
+ type, iter->name,
+ iter->module_name);
+ /*
+ * /proc/kallmodsyms, single-module symbol.
+ */
+ else if (*iter->builtin_module_names != '\0')
+ seq_printf(m, "%px %c %s\t[%s]", value,
+ type, iter->name,
+ iter->builtin_module_names);
+ /*
+ * /proc/kallmodsyms, multimodule symbol. Formatted
+ * as \0MODULE_COUNTmodule-1\0module-2\0, where
+ * MODULE_COUNT is a single byte, 2 or higher.
+ */
+ else {
+ size_t i = *(char *)(iter->builtin_module_names + 1);
+ const char *walk = iter->builtin_module_names + 2;
+
+ seq_printf(m, "%px %c %s\t[%s]", value,
+ type, iter->name, walk);
+
+ while (--i > 0) {
+ walk += strlen(walk) + 1;
+ seq_printf(m, " [%s]", walk);
+ }
+ }
+ /*
+ * Possibly there is an objfile name too, if needed to
+ * disambiguate at least one symbol.
+ */
+ if (iter->builtin_objfile_name)
+ seq_printf(m, " {%s.o}", iter->builtin_objfile_name);
+
+ seq_printf(m, "\n");
+ } else /* !kallmodsyms */
+#endif /* CONFIG_KALLMODSYMS */
+ seq_printf(m, "%px %c %s\t[%s]\n", value,
+ type, iter->name, iter->module_name);
+ } else {
+ seq_printf(m, "%px %c %s", value,
iter->type, iter->name);
+#ifdef CONFIG_KALLMODSYMS
+ if (kallmodsyms) {
+ if (iter->builtin_objfile_name)
+ seq_printf(m, "\t{%s.o}", iter->builtin_objfile_name);
+ }
+#endif /* CONFIG_KALLMODSYMS */
+ seq_printf(m, "\n");
+ }
return 0;
}

+static int s_show(struct seq_file *m, void *p)
+{
+ return s_show_internal(m, p, 0);
+}
+
static const struct seq_operations kallsyms_op = {
.start = s_start,
.next = s_next,
@@ -872,6 +1060,36 @@ static const struct seq_operations kallsyms_op = {
.show = s_show
};

+#ifdef CONFIG_KALLMODSYMS
+static int s_mod_show(struct seq_file *m, void *p)
+{
+ return s_show_internal(m, p, 1);
+}
+
+static void *s_mod_next(struct seq_file *m, void *p, loff_t *pos)
+{
+ (*pos)++;
+
+ if (!update_iter(m->private, *pos, 1))
+ return NULL;
+ return p;
+}
+
+static void *s_mod_start(struct seq_file *m, loff_t *pos)
+{
+ if (!update_iter(m->private, *pos, 1))
+ return NULL;
+ return m->private;
+}
+
+static const struct seq_operations kallmodsyms_op = {
+ .start = s_mod_start,
+ .next = s_mod_next,
+ .stop = s_stop,
+ .show = s_mod_show
+};
+#endif
+
#ifdef CONFIG_BPF_SYSCALL

struct bpf_iter__ksym {
@@ -997,7 +1215,8 @@ bool kallsyms_show_value(const struct cred *cred)
}
}

-static int kallsyms_open(struct inode *inode, struct file *file)
+static int kallsyms_open_internal(struct inode *inode, struct file *file,
+ const struct seq_operations *ops)
{
/*
* We keep iterator in m->private, since normal case is to
@@ -1005,7 +1224,7 @@ static int kallsyms_open(struct inode *inode, struct file *file)
* using get_symbol_offset for every symbol.
*/
struct kallsym_iter *iter;
- iter = __seq_open_private(file, &kallsyms_op, sizeof(*iter));
+ iter = __seq_open_private(file, ops, sizeof(*iter));
if (!iter)
return -ENOMEM;
reset_iter(iter, 0);
@@ -1018,6 +1237,18 @@ static int kallsyms_open(struct inode *inode, struct file *file)
return 0;
}

+static int kallsyms_open(struct inode *inode, struct file *file)
+{
+ return kallsyms_open_internal(inode, file, &kallsyms_op);
+}
+
+#ifdef CONFIG_KALLMODSYMS
+static int kallmodsyms_open(struct inode *inode, struct file *file)
+{
+ return kallsyms_open_internal(inode, file, &kallmodsyms_op);
+}
+#endif
+
#ifdef CONFIG_KGDB_KDB
const char *kdb_walk_kallsyms(loff_t *pos)
{
@@ -1028,7 +1259,7 @@ const char *kdb_walk_kallsyms(loff_t *pos)
reset_iter(&kdb_walk_kallsyms_iter, 0);
}
while (1) {
- if (!update_iter(&kdb_walk_kallsyms_iter, *pos))
+ if (!update_iter(&kdb_walk_kallsyms_iter, *pos, 0))
return NULL;
++*pos;
/* Some debugging symbols have no name. Ignore them. */
@@ -1045,9 +1276,21 @@ static const struct proc_ops kallsyms_proc_ops = {
.proc_release = seq_release_private,
};

+#ifdef CONFIG_KALLMODSYMS
+static const struct proc_ops kallmodsyms_proc_ops = {
+ .proc_open = kallmodsyms_open,
+ .proc_read = seq_read,
+ .proc_lseek = seq_lseek,
+ .proc_release = seq_release_private,
+};
+#endif
+
static int __init kallsyms_init(void)
{
proc_create("kallsyms", 0444, NULL, &kallsyms_proc_ops);
+#ifdef CONFIG_KALLMODSYMS
+ proc_create("kallmodsyms", 0444, NULL, &kallmodsyms_proc_ops);
+#endif
return 0;
}
device_initcall(kallsyms_init);
diff --git a/kernel/kallsyms_internal.h b/kernel/kallsyms_internal.h
index 27fabdcc40f5..91534a75c996 100644
--- a/kernel/kallsyms_internal.h
+++ b/kernel/kallsyms_internal.h
@@ -22,8 +22,22 @@ __section(".rodata") __attribute__((weak));
extern const unsigned long kallsyms_relative_base
__section(".rodata") __attribute__((weak));

+extern const unsigned long kallsyms_num_modules
+__section(".rodata") __attribute__((weak));
+
+extern const unsigned long kallsyms_num_objfiles
+__section(".rodata") __attribute__((weak));
+
+extern const unsigned long kallsyms_mod_objnames_len
+__section(".rodata") __attribute__((weak));
+
extern const char kallsyms_token_table[] __weak;
extern const u16 kallsyms_token_index[] __weak;
+extern const unsigned long kallsyms_module_addresses[] __weak;
+extern const int kallsyms_module_offsets[] __weak;
+extern const u32 kallsyms_modules[] __weak;
+extern const u32 kallsyms_objfiles[] __weak;
+extern const char kallsyms_mod_objnames[] __weak;

extern const unsigned int kallsyms_markers[] __weak;
extern const u8 kallsyms_seqs_of_names[] __weak;
--
2.38.0.266.g481848f278

2022-12-05 17:06:17

by Nick Alcock

[permalink] [raw]
Subject: [PATCH v10 03/13] kbuild: add tristate checker

This new check target uses the tristate.conf machinery just added, and
modules.builtin.objs, to identify source files that have MODULE_*
declarations despite not being modules according to Kconfig. After
commit 8b41fc4454e ("kbuild: create modules.builtin without
Makefile.modbuiltin or tristate.conf"), all such declarations will cause
modprobe to misidentify their containing object file as a module when it
is not, which might cause it to spuriously fail when trying to load
something that is built in to the kernel.

Only source files compiled by the current configuration are checked, so
a make allyesconfig is probably a good thing to do before running this:
output if you don't do that won't be wrong but will probably be
incomplete. Note that it is quite possible for things to be modular on
only some architectures, in which case a make allyesconfig build will
give false positive reports on other arches. (This is rare, but does
apply to e.g. KVM on aarch64.)

The checking is done by comparing modules.builtin.obj to a new
check-tristates.objs, which is built in a way more or less identical to
the way modules.builtin used to be built before commit 8b41fc4454e; the
principal difference is that it's only built when running the checker,
so doesn't slow down existing builds.

This file is similar in structure to modules.builtin.objs, and
constructed in a similar way to the way modules.builtin used to be built
before commit 8b41fc4454e, via tristate.conf inclusion and recursive
concatenation up the tree.

Signed-off-by: Nick Alcock <[email protected]>
---

Notes:
v10: adapted from modules_thick.builtin code: adjusted to use
modules.builtin.objs, turned into a tristate checker. Top-level
Kbuild changes no longer necessary.

.gitignore | 1 +
Documentation/dontdiff | 1 +
Makefile | 23 ++++++++++++++--
scripts/Kbuild.include | 6 ++++
scripts/Makefile.lib | 8 +++++-
scripts/check-tristates.mk | 56 ++++++++++++++++++++++++++++++++++++++
6 files changed, 92 insertions(+), 3 deletions(-)
create mode 100644 scripts/check-tristates.mk

diff --git a/.gitignore b/.gitignore
index ef8665c64f21..75f246e0565f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -52,6 +52,7 @@
*.zst
Module.symvers
modules.order
+check-tristates.objs

#
# Top-level generic files
diff --git a/Documentation/dontdiff b/Documentation/dontdiff
index ed1fbc711f33..17686f59039c 100644
--- a/Documentation/dontdiff
+++ b/Documentation/dontdiff
@@ -183,6 +183,7 @@ modules.builtin
modules.builtin.*
modules.nsdeps
modules.order
+check-tristates.objs
modversions.h*
nconf
nconf-cfg
diff --git a/Makefile b/Makefile
index 248f780cb75b..4d8a4c231cc1 100644
--- a/Makefile
+++ b/Makefile
@@ -1689,6 +1689,7 @@ help:
@echo ' coccicheck - Check with Coccinelle'
@echo ' clang-analyzer - Check with clang static analyzer'
@echo ' clang-tidy - Check with clang-tidy'
+ @echo ' tristatecheck - Check for non-tristates with MODULE_ declarations'
@echo ''
@echo 'Tools:'
@echo ' nsdeps - Generate missing symbol namespace dependencies'
@@ -2012,7 +2013,7 @@ clean: $(clean-dirs)
-o -name '*.lex.c' -o -name '*.tab.[ch]' \
-o -name '*.asn1.[ch]' \
-o -name '*.symtypes' -o -name 'modules.order' \
- -o -name '.tmp_*' \
+ -o -name 'check-tristates.objs' -o -name '.tmp_*' \
-o -name '*.c.[012]*.*' \
-o -name '*.ll' \
-o -name '*.gcno' \
@@ -2082,7 +2083,25 @@ coccicheck:
export_report:
$(PERL) $(srctree)/scripts/export_report.pl

-PHONY += checkstack kernelrelease kernelversion image_name
+tristatecheck: SHELL=/bin/bash
+tristatecheck: check-tristates.objs modules.builtin.objs
+ $(Q) for name in $$(comm -23 <(sed 's,:,,' modules.builtin.objs | tr ' ' '\n' | sort -u) \
+ <(sed 's,:,,' check-tristates.objs | tr ' ' '\n' | sort -u)); do \
+ grep -w $$name modules.builtin.objs | while read -r line; do \
+ case $$line in \
+ $$name:\ ) printf "%s " "$$line" | sed 's,: ,,';; \
+ $$name:\ *) printf "%s " "$$line" | sed 's,^.*: ,,';; \
+ *) echo $$name;; \
+ esac; \
+ done; \
+ done | tr ' ' '\n' | sort -u | while read -r name; do \
+ test -f $${name%.o}.c && echo $${name%.o}.c; \
+ done | xargs grep -l '^ *MODULE_' || true
+
+check-tristates.objs: $(build-dir)
+ $(Q)$(MAKE) $(tristatecheck)=$^ tristates-file=$@
+
+PHONY += checkstack kernelrelease kernelversion image_name tristatecheck

# UML needs a little special treatment here. It wants to use the host
# toolchain, so needs $(SUBARCH) passed to checkstack.pl. Everyone
diff --git a/scripts/Kbuild.include b/scripts/Kbuild.include
index 2bc08ace38a3..8042c067312e 100644
--- a/scripts/Kbuild.include
+++ b/scripts/Kbuild.include
@@ -78,6 +78,12 @@ endef
# $(Q)$(MAKE) $(build)=dir
build := -f $(srctree)/scripts/Makefile.build obj

+###
+# Shorthand for $(Q)$(MAKE) -f scripts/check-tristates.mk need-tristates=1 obj=
+# Usage:
+# $(Q)$(MAKE) $(tristatecheck)=dir
+tristatecheck := -f $(srctree)/scripts/check-tristates.mk need-tristates=1 obj
+
###
# Shorthand for $(Q)$(MAKE) -f scripts/Makefile.dtbinst obj=
# Usage:
diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib
index f7e5a83572fa..3bbfa99259cd 100644
--- a/scripts/Makefile.lib
+++ b/scripts/Makefile.lib
@@ -39,11 +39,17 @@ else
obj-m := $(filter-out %/, $(obj-m))
endif

-ifdef need-builtin
+ifdef need-tristates
+subdir-ym := $(sort $(subdir-y) $(subdir-m) \
+ $(patsubst %/,%, $(filter %/, $(obj-y) $(obj-m) $(obj-Y) $(obj-M))))
obj-y := $(patsubst %/, %/built-in.a, $(obj-y))
else
+ifdef need-builtin
+obj-y := $(patsubst %/, %/built-in.a, $(obj-y))
+else
obj-y := $(filter-out %/, $(obj-y))
endif
+endif

# Expand $(foo-objs) $(foo-y) etc. by replacing their individuals
suffix-search = $(strip $(foreach s, $3, $($(1:%$(strip $2)=%$s))))
diff --git a/scripts/check-tristates.mk b/scripts/check-tristates.mk
new file mode 100644
index 000000000000..fa9fadb79143
--- /dev/null
+++ b/scripts/check-tristates.mk
@@ -0,0 +1,56 @@
+# SPDX-License-Identifier: GPL-2.0
+# ==========================================================================
+# Generating check-tristates.objs
+# ==========================================================================
+
+src := $(obj)
+
+PHONY := __tristates
+__tristates:
+
+include include/config/auto.conf
+# tristate.conf sets tristate variables to uppercase 'Y' or 'M'
+# That way, we get the list of built-in modules in obj-Y
+include include/config/tristate.conf
+
+include scripts/Kbuild.include
+
+ifdef building_out_of_srctree
+# Create output directory if not already present
+_dummy := $(shell [ -d $(obj) ] || mkdir -p $(obj))
+endif
+
+# The filename Kbuild has precedence over Makefile
+kbuild-dir := $(if $(filter /%,$(src)),$(src),$(srctree)/$(src))
+kbuild-file := $(if $(wildcard $(kbuild-dir)/Kbuild),$(kbuild-dir)/Kbuild,$(kbuild-dir)/Makefile)
+include $(kbuild-file)
+
+include scripts/Makefile.lib
+
+check-tristates-subdirs := $(patsubst %,%/check-tristates.objs, $(subdir-ym))
+check-tristates-target := $(obj)/check-tristates.objs
+
+__tristates: $(obj)/$(tristates-file) $(subdir-ym)
+ @:
+
+$(check-tristates-target): $(subdir-ym) FORCE
+ $(Q) rm -f $@
+ $(Q) $(foreach mod-o, $(filter %.o,$(obj-Y)),\
+ printf "%s: " $(addprefix $(obj)/,$(mod-o)) >> $@; \
+ printf " %s" $(sort $(strip $(addprefix $(obj)/,$($(mod-o:.o=-objs)) \
+ $($(mod-o:.o=-y)) $($(mod-o:.o=-Y))))) >> $@; \
+ printf "\n" >> $@; ) \
+ cat /dev/null $(check-tristates-subdirs) >> $@;
+
+PHONY += FORCE
+
+FORCE:
+
+# Descending
+# ---------------------------------------------------------------------------
+
+PHONY += $(subdir-ym)
+$(subdir-ym):
+ $(Q)$(MAKE) $(tristatecheck)=$@ tristates-file=$(tristates-file)
+
+.PHONY: $(PHONY)
--
2.38.0.266.g481848f278

2022-12-05 17:08:06

by Nick Alcock

[permalink] [raw]
Subject: [PATCH v10 08/13] kbuild: make address ranges map work with IBT

The previous commit emits .tmp_vmlinux.ranges, which maps address
range/size pairs in vmlinux to the object files which make them up; this
is used by kallmodsyms to let us associate symbols with object file
names and kernel module names at address-range granularity (i.e.,
space-efficiently).

But the previous commit only works if the final linker runs directly on
the input .o files from the kernel build: if an intermediate ld -r is
done, the final link emits a mapfile containing only the name of the
intermediate ld -r (vmlinux.o), which messes up .tmp_vmlinux.ranges and
makes kallmodsyms attribute all symbols to {vmlinux.o} which isn't much
use for disambiguation. vmlinux.o has the object file names we need, but
the addresses are all wrong so we can't use that either.

This commit fixes that by extracting the addresses from the final
vmlinux mapfile (or one of the intermediate kallsyms mapfiles) and using
them to adjust the address/objfile name pairs extracted from the
vmlinux.o mapfile, giving us a ranges map with the right addresses and
the right names. It's a bit painful because the addresses are often
large numbers, and awk is... not good at handling them (GNU awk can use
large integers, but the feature is at risk of removal). So we emit a
slightly different file format with a pair of hex values (the address in
vmlinux.o and section address from the final mapfile), then pipe it
through a tiny new C filter (scripts/addaddrs) whose only purpose is to
add those two numbers together!

One niggle is that .hot/.cold stuff is no longer correctly attributed to
its object file any more -- it seems to not appear in any of the
mapfiles at all (only in System.map), so I don't see any way to fix
this.

(This possibly makes it work with clang LTO too, but I haven't tested
it, and if the mapfile format differs it will fail until that's fixed.
But this definitely overcomes *one* of the roadblocks preventing clang
LTO from working with kallmodsyms.)

Signed-off-by: Nick Alcock <[email protected]>
Reviewed-by: Kris Van Hees <[email protected]>
---

Notes:
v10: new.

Documentation/dontdiff | 1 +
init/Kconfig | 10 ++++++++++
scripts/.gitignore | 1 +
scripts/Makefile | 1 +
scripts/Makefile.vmlinux_o | 6 +++++-
scripts/addaddrs.c | 28 ++++++++++++++++++++++++++++
scripts/link-vmlinux.sh | 34 +++++++++++++++++++++++++---------
7 files changed, 71 insertions(+), 10 deletions(-)
create mode 100644 scripts/addaddrs.c

diff --git a/Documentation/dontdiff b/Documentation/dontdiff
index 17686f59039c..72c089eea111 100644
--- a/Documentation/dontdiff
+++ b/Documentation/dontdiff
@@ -79,6 +79,7 @@ SCCS
System.map*
TAGS
aconf
+addaddrs
af_names.h
aic7*reg.h*
aic7*reg_print.c*
diff --git a/init/Kconfig b/init/Kconfig
index c45935cd2f1f..160ec1370594 100644
--- a/init/Kconfig
+++ b/init/Kconfig
@@ -1570,6 +1570,16 @@ config POSIX_TIMERS

If unsure say y.

+config KALLMODSYMS
+ default y
+ bool "Enable support for /proc/kallmodsyms" if EXPERT
+ depends on KALLSYMS
+ select VMLINUX_MAP
+ help
+ This option enables the /proc/kallmodsyms file, which unambiguously
+ maps built-in kernel symbols and their associated object files and
+ modules to addresses.
+
config PRINTK
default y
bool "Enable support for printk" if EXPERT
diff --git a/scripts/.gitignore b/scripts/.gitignore
index b7aec8eb1bd4..d042f0e3d13f 100644
--- a/scripts/.gitignore
+++ b/scripts/.gitignore
@@ -1,4 +1,5 @@
# SPDX-License-Identifier: GPL-2.0-only
+/addaddrs
/asn1_compiler
/bin2c
/generate_rust_target
diff --git a/scripts/Makefile b/scripts/Makefile
index 1575af84d557..356cafcd313d 100644
--- a/scripts/Makefile
+++ b/scripts/Makefile
@@ -5,6 +5,7 @@

hostprogs-always-$(CONFIG_BUILD_BIN2C) += bin2c
hostprogs-always-$(CONFIG_KALLSYMS) += kallsyms
+hostprogs-always-$(CONFIG_KALLMODSYMS) += addaddrs
hostprogs-always-$(BUILD_C_RECORDMCOUNT) += recordmcount
hostprogs-always-$(CONFIG_BUILDTIME_TABLE_SORT) += sorttable
hostprogs-always-$(CONFIG_ASN1) += asn1_compiler
diff --git a/scripts/Makefile.vmlinux_o b/scripts/Makefile.vmlinux_o
index 9b4ca83f0695..94c2ec366b91 100644
--- a/scripts/Makefile.vmlinux_o
+++ b/scripts/Makefile.vmlinux_o
@@ -27,6 +27,10 @@ ifdef CONFIG_LTO_CLANG
initcalls-lds := .tmp_initcalls.lds
endif

+ifneq ($(CONFIG_VMLINUX_MAP)$(CONFIG_KALLMODSYMS),)
+KBUILD_MAPFLAGS = [email protected]
+endif
+
# objtool for vmlinux.o
# ---------------------------------------------------------------------------
#
@@ -47,7 +51,7 @@ objtool-args = $(vmlinux-objtool-args-y) --link
quiet_cmd_ld_vmlinux.o = LD $@
cmd_ld_vmlinux.o = \
$(LD) ${KBUILD_LDFLAGS} -r -o $@ \
- $(addprefix -T , $(initcalls-lds)) \
+ $(KBUILD_MAPFLAGS) $(addprefix -T , $(initcalls-lds)) \
--whole-archive vmlinux.a --no-whole-archive \
--start-group $(KBUILD_VMLINUX_LIBS) --end-group \
$(cmd_objtool)
diff --git a/scripts/addaddrs.c b/scripts/addaddrs.c
new file mode 100644
index 000000000000..d15cbbf8d262
--- /dev/null
+++ b/scripts/addaddrs.c
@@ -0,0 +1,28 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+/* Used only by link-vmlinux.sh */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <inttypes.h>
+
+int main (void)
+{
+ int i = 0;
+ while (!feof(stdin)) {
+ uint64_t a, b;
+ int ret;
+ char *rest = NULL;
+
+ i++;
+ if ((ret = scanf("%" SCNx64 " %" SCNx64 " %m[^\n]\n", &a, &b, &rest)) < 3) {
+ fprintf(stderr,
+ "Syntax error: invalid line %i found in rangefile generation: at least three fields expected, %i converted\n", i, ret);
+ exit(1);
+ }
+
+ printf("0x%018" PRIx64 " %s\n", a+b, rest);
+ free(rest);
+ }
+ exit(0);
+}
diff --git a/scripts/link-vmlinux.sh b/scripts/link-vmlinux.sh
index a40d372b1289..3b3ea6214062 100755
--- a/scripts/link-vmlinux.sh
+++ b/scripts/link-vmlinux.sh
@@ -60,10 +60,7 @@ vmlinux_link()
# skip output file argument
shift

- # kallmodsyms needs a linker mapfile that contains original object
- # file names, so cannot use this optimization.
- if { is_enabled CONFIG_LTO_CLANG || is_enabled CONFIG_X86_KERNEL_IBT; } && \
- ! is_enabled CONFIG_KALLMODSYMS; then
+ if is_enabled CONFIG_LTO_CLANG || is_enabled CONFIG_X86_KERNEL_IBT; then
# Use vmlinux.o instead of performing the slow LTO link again.
objs=vmlinux.o
libs=
@@ -153,12 +150,31 @@ kallsyms()
# - but sometimes there is a line break after the first field
# - start reading at "Linker script and memory map"
# - stop reading at ".brk"
+ # if there is a vmlinux.o.map and LTO_CLANG or KERNEL_IBT are
+ # turned on, we have used a vmlinux -r'ed .o for linking: use this
+ # as our primary information source, but acquire section addresses
+ # from the (later) linker map we were passed in. This makes things
+ # a bit more complex, since we have to recognize and eliminate
+ # sections elided by the linker, and add together numbers larger
+ # than awk can portably handle.
if is_enabled CONFIG_KALLMODSYMS; then
- ${AWK} '
- /\.o$/ && start==1 { print $(NF-2), $(NF-1), $NF }
- /^Linker script and memory map/ { start = 1 }
- /^\.brk/ { exit(0) }
- ' ${3} | sort > .tmp_vmlinux.ranges
+ if is_enabled CONFIG_LTO_CLANG || is_enabled CONFIG_X86_KERNEL_IBT; then
+ ${AWK} 'BEGIN { addresses = 1 }
+ /^Linker script and memory map/ { start = 1 }
+ !start { next }
+ { got_section = 0 }
+ /^ \./ { section = $1; got_section = 1; if (NF == 1) { getline }}
+ addresses && got_section && !(section in addrs) { addrs[section] = $2 }
+ !addresses && got_section && section in addrs { print $(NF-2), addrs[section], $(NF-1), $NF }
+ /^\.brk/ || /^\.bss\.\.brk/ { addresses = 0; start = 0; nextfile }
+ ' ${3} vmlinux.o.map | scripts/addaddrs | sort > .tmp_vmlinux.ranges
+ else
+ ${AWK} '
+ start && /\.o$/ { print $(NF-2), $(NF-1), $NF }
+ /^Linker script and memory map/ { start = 1 }
+ /^\.brk/ { exit(0) }
+ ' ${3} | sort > .tmp_vmlinux.ranges
+ fi
fi

# get kallsyms options
--
2.38.0.266.g481848f278

2022-12-05 17:13:28

by Nick Alcock

[permalink] [raw]
Subject: [PATCH v10 04/13] kbuild: fix up substitutions in makefiles to allow for tristate checker

The tristate checker, like the Makefile.modbuiltin that preceded it,
relies on running the makefiles with some CONFIG_ variables set to
uppercase values ('Y' or 'M'). Large portions of the core build system
assume that these values are lowercase, but we mostly don't care about
those because they are only involved in actual building, and make
tristatecheck doesn't build anything (the parts that do need changing so
that recursion etc still worked were changed as part of the tristate
commit).

But some makefiles that are not part of the core build system also
contain assumptions that CONFIG_ variables are always lowercase (every
one of these was also broken wrt the old modules.builtin machinery, but
now this is part of a verifier, the problems are more obvious). In most
cases this is just something like

obj-$(subst m,y,$(CONFIG_FOO)) += blah.o

to indicate that blah.o is always built in even if CONFIG_FOO is a
module. There is a new macro to help this relatively common case, which
should now be rewritten as

obj-$(call always_built_in,$(CONFIG_FOO)) += blah.o

One other case we handle is that in net/dccp where things are built as
modules iff any member of some other set are modular; this is now
handled like so:

obj-$(call module_if_any_modular,$(CONFIG_IP_DCCP)$(CONFIG_IPV6)) += dccp_ipv6.o
dccp_ipv6-$(call module_if_any_modular,$(CONFIG_IP_DCCP)$(CONFIG_IPV6)) := ipv6.o

Signed-off-by: Nick Alcock <[email protected]>
---

Notes:
v10: new.

drivers/Makefile | 2 +-
drivers/hv/Makefile | 2 +-
drivers/mmc/Makefile | 2 +-
drivers/net/wireless/silabs/wfx/Makefile | 2 +-
drivers/s390/char/Makefile | 2 +-
drivers/s390/crypto/Makefile | 2 +-
net/8021q/Makefile | 2 +-
net/Makefile | 2 +-
net/bridge/Makefile | 4 ++--
net/dccp/Makefile | 4 ++--
net/ipv6/Makefile | 2 +-
net/l2tp/Makefile | 12 ++++++------
net/netfilter/Makefile | 2 +-
net/netlabel/Makefile | 2 +-
net/sctp/Makefile | 2 +-
scripts/Kbuild.include | 15 +++++++++++++++
16 files changed, 37 insertions(+), 22 deletions(-)

diff --git a/drivers/Makefile b/drivers/Makefile
index bdf1c66141c9..a6d3296f0c23 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -159,7 +159,7 @@ obj-$(CONFIG_SOUNDWIRE) += soundwire/

# Virtualization drivers
obj-$(CONFIG_VIRT_DRIVERS) += virt/
-obj-$(subst m,y,$(CONFIG_HYPERV)) += hv/
+obj-$(call always_built_in,$(CONFIG_HYPERV)) += hv/

obj-$(CONFIG_PM_DEVFREQ) += devfreq/
obj-$(CONFIG_EXTCON) += extcon/
diff --git a/drivers/hv/Makefile b/drivers/hv/Makefile
index d76df5c8c2a9..06777af02a78 100644
--- a/drivers/hv/Makefile
+++ b/drivers/hv/Makefile
@@ -13,4 +13,4 @@ hv_vmbus-$(CONFIG_HYPERV_TESTING) += hv_debugfs.o
hv_utils-y := hv_util.o hv_kvp.o hv_snapshot.o hv_fcopy.o hv_utils_transport.o

# Code that must be built-in
-obj-$(subst m,y,$(CONFIG_HYPERV)) += hv_common.o
+obj-$(call always_built_in,$(CONFIG_HYPERV)) += hv_common.o
diff --git a/drivers/mmc/Makefile b/drivers/mmc/Makefile
index 3ea0126a9a72..1f4f9ce02490 100644
--- a/drivers/mmc/Makefile
+++ b/drivers/mmc/Makefile
@@ -4,4 +4,4 @@
#

obj-$(CONFIG_MMC) += core/
-obj-$(subst m,y,$(CONFIG_MMC)) += host/
+obj-$(call always_built_in,$(CONFIG_MMC)) += host/
diff --git a/drivers/net/wireless/silabs/wfx/Makefile b/drivers/net/wireless/silabs/wfx/Makefile
index c8b356f71c99..9fe47f5a050a 100644
--- a/drivers/net/wireless/silabs/wfx/Makefile
+++ b/drivers/net/wireless/silabs/wfx/Makefile
@@ -20,6 +20,6 @@ wfx-y := \
debug.o
wfx-$(CONFIG_SPI) += bus_spi.o
# When CONFIG_MMC == m, append to 'wfx-y' (and not to 'wfx-m')
-wfx-$(subst m,y,$(CONFIG_MMC)) += bus_sdio.o
+wfx-$(call always_built_in,$(CONFIG_MMC)) += bus_sdio.o

obj-$(CONFIG_WFX) += wfx.o
diff --git a/drivers/s390/char/Makefile b/drivers/s390/char/Makefile
index ce32270082f5..d21086e99528 100644
--- a/drivers/s390/char/Makefile
+++ b/drivers/s390/char/Makefile
@@ -34,7 +34,7 @@ obj-$(CONFIG_SCLP_VT220_TTY) += sclp_vt220.o

obj-$(CONFIG_PCI) += sclp_pci.o

-obj-$(subst m,y,$(CONFIG_ZCRYPT)) += sclp_ap.o
+obj-$(call always_built_in,$(CONFIG_ZCRYPT)) += sclp_ap.o

obj-$(CONFIG_VMLOGRDR) += vmlogrdr.o
obj-$(CONFIG_VMCP) += vmcp.o
diff --git a/drivers/s390/crypto/Makefile b/drivers/s390/crypto/Makefile
index 22d2db690cd3..e3594486d8f3 100644
--- a/drivers/s390/crypto/Makefile
+++ b/drivers/s390/crypto/Makefile
@@ -4,7 +4,7 @@
#

ap-objs := ap_bus.o ap_card.o ap_queue.o
-obj-$(subst m,y,$(CONFIG_ZCRYPT)) += ap.o
+obj-$(call always_built_in,$(CONFIG_ZCRYPT)) += ap.o
# zcrypt_api.o and zcrypt_msgtype*.o depend on ap.o
zcrypt-objs := zcrypt_api.o zcrypt_card.o zcrypt_queue.o
zcrypt-objs += zcrypt_msgtype6.o zcrypt_msgtype50.o
diff --git a/net/8021q/Makefile b/net/8021q/Makefile
index e05d4d7aab35..50b48af58322 100644
--- a/net/8021q/Makefile
+++ b/net/8021q/Makefile
@@ -2,7 +2,7 @@
#
# Makefile for the Linux VLAN layer.
#
-obj-$(subst m,y,$(CONFIG_VLAN_8021Q)) += vlan_core.o
+obj-$(call always_built_in,$(CONFIG_VLAN_8021Q)) += vlan_core.o
obj-$(CONFIG_VLAN_8021Q) += 8021q.o

8021q-y := vlan.o vlan_dev.o vlan_netlink.o
diff --git a/net/Makefile b/net/Makefile
index 6a62e5b27378..94165eb38b65 100644
--- a/net/Makefile
+++ b/net/Makefile
@@ -42,7 +42,7 @@ obj-$(CONFIG_PHONET) += phonet/
ifneq ($(CONFIG_VLAN_8021Q),)
obj-y += 8021q/
endif
-obj-$(CONFIG_IP_DCCP) += dccp/
+obj-$(call always_built_in,$(CONFIG_IP_DCCP)) += dccp/
obj-$(CONFIG_IP_SCTP) += sctp/
obj-$(CONFIG_RDS) += rds/
obj-$(CONFIG_WIRELESS) += wireless/
diff --git a/net/bridge/Makefile b/net/bridge/Makefile
index 24bd1c0a9a5a..4f3109e170c8 100644
--- a/net/bridge/Makefile
+++ b/net/bridge/Makefile
@@ -12,10 +12,10 @@ bridge-y := br.o br_device.o br_fdb.o br_forward.o br_if.o br_input.o \

bridge-$(CONFIG_SYSFS) += br_sysfs_if.o br_sysfs_br.o

-bridge-$(subst m,y,$(CONFIG_BRIDGE_NETFILTER)) += br_nf_core.o
+bridge-$(call always_built_in,$(CONFIG_BRIDGE_NETFILTER)) += br_nf_core.o

br_netfilter-y := br_netfilter_hooks.o
-br_netfilter-$(subst m,y,$(CONFIG_IPV6)) += br_netfilter_ipv6.o
+br_netfilter-$(call always_built_in,$(CONFIG_IPV6)) += br_netfilter_ipv6.o
obj-$(CONFIG_BRIDGE_NETFILTER) += br_netfilter.o

bridge-$(CONFIG_BRIDGE_IGMP_SNOOPING) += br_multicast.o br_mdb.o br_multicast_eht.o
diff --git a/net/dccp/Makefile b/net/dccp/Makefile
index 5b4ff37bc806..607f6d3dd795 100644
--- a/net/dccp/Makefile
+++ b/net/dccp/Makefile
@@ -17,8 +17,8 @@ dccp-$(CONFIG_IP_DCCP_TFRC_LIB) += ccids/lib/tfrc.o \
dccp_ipv4-y := ipv4.o

# build dccp_ipv6 as module whenever either IPv6 or DCCP is a module
-obj-$(subst y,$(CONFIG_IP_DCCP),$(CONFIG_IPV6)) += dccp_ipv6.o
-dccp_ipv6-y := ipv6.o
+obj-$(call module_if_any_modular,$(CONFIG_IP_DCCP)$(CONFIG_IPV6)) += dccp_ipv6.o
+dccp_ipv6-$(call module_if_any_modular,$(CONFIG_IP_DCCP)$(CONFIG_IPV6)) := ipv6.o

obj-$(CONFIG_INET_DCCP_DIAG) += dccp_diag.o

diff --git a/net/ipv6/Makefile b/net/ipv6/Makefile
index 3036a45e8a1e..b05b0e4668f5 100644
--- a/net/ipv6/Makefile
+++ b/net/ipv6/Makefile
@@ -47,7 +47,7 @@ obj-y += addrconf_core.o exthdrs_core.o ip6_checksum.o ip6_icmp.o
obj-$(CONFIG_INET) += output_core.o protocol.o \
ip6_offload.o tcpv6_offload.o exthdrs_offload.o

-obj-$(subst m,y,$(CONFIG_IPV6)) += inet6_hashtables.o
+obj-$(call always_built_in,$(CONFIG_IPV6)) += inet6_hashtables.o

ifneq ($(CONFIG_IPV6),)
obj-$(CONFIG_NET_UDP_TUNNEL) += ip6_udp_tunnel.o
diff --git a/net/l2tp/Makefile b/net/l2tp/Makefile
index cf8f27071d3f..ff94be92a36e 100644
--- a/net/l2tp/Makefile
+++ b/net/l2tp/Makefile
@@ -8,11 +8,11 @@ obj-$(CONFIG_L2TP) += l2tp_core.o
CFLAGS_l2tp_core.o += -I$(src)

# Build l2tp as modules if L2TP is M
-obj-$(subst y,$(CONFIG_L2TP),$(CONFIG_PPPOL2TP)) += l2tp_ppp.o
-obj-$(subst y,$(CONFIG_L2TP),$(CONFIG_L2TP_IP)) += l2tp_ip.o
-obj-$(subst y,$(CONFIG_L2TP),$(CONFIG_L2TP_V3)) += l2tp_netlink.o
-obj-$(subst y,$(CONFIG_L2TP),$(CONFIG_L2TP_ETH)) += l2tp_eth.o
-obj-$(subst y,$(CONFIG_L2TP),$(CONFIG_L2TP_DEBUGFS)) += l2tp_debugfs.o
+obj-$(subst Y,$(CONFIG_L2TP),$(subst y,$(CONFIG_L2TP),$(CONFIG_PPPOL2TP))) += l2tp_ppp.o
+obj-$(subst Y,$(CONFIG_L2TP),$(subst y,$(CONFIG_L2TP),$(CONFIG_L2TP_IP))) += l2tp_ip.o
+obj-$(subst Y,$(CONFIG_L2TP),$(subst y,$(CONFIG_L2TP),$(CONFIG_L2TP_V3))) += l2tp_netlink.o
+obj-$(subst Y,$(CONFIG_L2TP),$(subst y,$(CONFIG_L2TP),$(CONFIG_L2TP_ETH))) += l2tp_eth.o
+obj-$(subst Y,$(CONFIG_L2TP),$(subst y,$(CONFIG_L2TP),$(CONFIG_L2TP_DEBUGFS))) += l2tp_debugfs.o
ifneq ($(CONFIG_IPV6),)
-obj-$(subst y,$(CONFIG_L2TP),$(CONFIG_L2TP_IP)) += l2tp_ip6.o
+obj-$(subst Y,$(CONFIG_L2TP),$(subst y,$(CONFIG_L2TP),$(CONFIG_L2TP_IP))) += l2tp_ip6.o
endif
diff --git a/net/netfilter/Makefile b/net/netfilter/Makefile
index 0f060d100880..a6f65c956b1b 100644
--- a/net/netfilter/Makefile
+++ b/net/netfilter/Makefile
@@ -6,7 +6,7 @@ nf_conntrack-y := nf_conntrack_core.o nf_conntrack_standalone.o nf_conntrack_exp
nf_conntrack_proto_icmp.o \
nf_conntrack_extend.o nf_conntrack_acct.o nf_conntrack_seqadj.o

-nf_conntrack-$(subst m,y,$(CONFIG_IPV6)) += nf_conntrack_proto_icmpv6.o
+nf_conntrack-$(call always_built_in,$(CONFIG_IPV6)) += nf_conntrack_proto_icmpv6.o
nf_conntrack-$(CONFIG_NF_CONNTRACK_TIMEOUT) += nf_conntrack_timeout.o
nf_conntrack-$(CONFIG_NF_CONNTRACK_TIMESTAMP) += nf_conntrack_timestamp.o
nf_conntrack-$(CONFIG_NF_CONNTRACK_EVENTS) += nf_conntrack_ecache.o
diff --git a/net/netlabel/Makefile b/net/netlabel/Makefile
index 5a46381a64e7..8052bd8e7af8 100644
--- a/net/netlabel/Makefile
+++ b/net/netlabel/Makefile
@@ -13,4 +13,4 @@ obj-y += netlabel_mgmt.o
# protocol modules
obj-y += netlabel_unlabeled.o
obj-y += netlabel_cipso_v4.o
-obj-$(subst m,y,$(CONFIG_IPV6)) += netlabel_calipso.o
+obj-$(call always_built_in,$(CONFIG_IPV6)) += netlabel_calipso.o
diff --git a/net/sctp/Makefile b/net/sctp/Makefile
index e845e4588535..683a345f3626 100644
--- a/net/sctp/Makefile
+++ b/net/sctp/Makefile
@@ -21,4 +21,4 @@ sctp-$(CONFIG_SCTP_DBG_OBJCNT) += objcnt.o
sctp-$(CONFIG_PROC_FS) += proc.o
sctp-$(CONFIG_SYSCTL) += sysctl.o

-sctp-$(subst m,y,$(CONFIG_IPV6)) += ipv6.o
+sctp-$(call always_built_in,$(CONFIG_IPV6)) += ipv6.o
diff --git a/scripts/Kbuild.include b/scripts/Kbuild.include
index 8042c067312e..701bbb499427 100644
--- a/scripts/Kbuild.include
+++ b/scripts/Kbuild.include
@@ -188,6 +188,21 @@ cmd_and_fixdep = \
# and if so will execute $(rule_foo).
if_changed_rule = $(if $(if-changed-cond),$(rule_$(1)),@:)

+# Usage. $(call always-built-in,CONFIG_VAR)
+# Expands to y if CONFIG_VAR is m, suitable for always-built-in pieces
+# of things that otherwise may be modular.
+always_built_in = $(subst M,Y,$(subst m,y,$(1)))
+
+# Usage, obj-$(call module_if_any_modular,$(CONCATENATED)$(CONFIG)$(VARS))
+# Expands to m if any of the concatenated config vars are m, otherwise
+# y if any of them are y, otherwise n
+module_if_any_modular = $(strip \
+ $(if $(findstring m,$(subst M,m,$(1))), \
+ $(if $(findstring M,$(1)),M,m), \
+ $(if $(findstring y,$(subst Y,y,$(1))), \
+ $(if $(findstring Y,$(1)),Y,y), \
+ $(if $(findstring N,$(1)),N,n))))
+
###
# why - tell why a target got built
# enabled by make V=2
--
2.38.0.266.g481848f278

2022-12-05 17:17:38

by Nick Alcock

[permalink] [raw]
Subject: [PATCH v10 02/13] kbuild: bring back tristate.conf

tristate.conf was dropped because it is not needed to build
modules.builtin any more, and doing so avoids one round of recursion
through the build tree to build it. But it has one property that can be
obtained in no other way in the current tree: it provides a
machine-readable record of whether a module is tristate or not.
(modules.builtin.objs, just added, uses modinfo, which is recorded in
the source files themselves, but it is Kconfig that actually controls
whether something can be built as a module.)

So bring it back for this purpose. (Thanks to the refactoring in
the 5.16 timeframe, this is basically a reimplementation of commit
8b41fc4454e36fbfdbb23f940d023d4dece2de29 rather than a simple
reversion.)

A verifier that uses it will be added in the next commit.

Signed-off-by: Nick Alcock <[email protected]>
Reviewed-by: Victor Erminpour <[email protected]>
Reviewed-by: Kris Van Hees <[email protected]>
---

Notes:
v7: rewrite in terms of the new confdata refactoring
v8: adjust for changes in 5.17 merge window
v10: commit log revised

Documentation/kbuild/kconfig.rst | 5 ++++
Makefile | 2 +-
scripts/kconfig/confdata.c | 41 +++++++++++++++++++++++++++-----
3 files changed, 41 insertions(+), 7 deletions(-)

diff --git a/Documentation/kbuild/kconfig.rst b/Documentation/kbuild/kconfig.rst
index 5967c79c3baa..e2c78760d442 100644
--- a/Documentation/kbuild/kconfig.rst
+++ b/Documentation/kbuild/kconfig.rst
@@ -162,6 +162,11 @@ KCONFIG_AUTOCONFIG
This environment variable can be set to specify the path & name of the
"auto.conf" file. Its default value is "include/config/auto.conf".

+KCONFIG_TRISTATE
+----------------
+This environment variable can be set to specify the path & name of the
+"tristate.conf" file. Its default value is "include/config/tristate.conf".
+
KCONFIG_AUTOHEADER
------------------
This environment variable can be set to specify the path & name of the
diff --git a/Makefile b/Makefile
index 93bfaae45396..248f780cb75b 100644
--- a/Makefile
+++ b/Makefile
@@ -793,7 +793,7 @@ $(KCONFIG_CONFIG):
#
# Do not use $(call cmd,...) here. That would suppress prompts from syncconfig,
# so you cannot notice that Kconfig is waiting for the user input.
-%/config/auto.conf %/config/auto.conf.cmd %/generated/autoconf.h %/generated/rustc_cfg: $(KCONFIG_CONFIG)
+%/config/auto.conf %/config/auto.conf.cmd %/generated/autoconf.h %/generated/rustc_cfg %/tristate.conf: $(KCONFIG_CONFIG)
$(Q)$(kecho) " SYNC $@"
$(Q)$(MAKE) -f $(srctree)/Makefile syncconfig
else # !may-sync-config
diff --git a/scripts/kconfig/confdata.c b/scripts/kconfig/confdata.c
index b7c9f1dd5e42..160d12b69957 100644
--- a/scripts/kconfig/confdata.c
+++ b/scripts/kconfig/confdata.c
@@ -223,6 +223,13 @@ static const char *conf_get_rustccfg_name(void)
return name ? name : "include/generated/rustc_cfg";
}

+static const char *conf_get_tristate_name(void)
+{
+ char *name = getenv("KCONFIG_TRISTATE");
+
+ return name ? name : "include/config/tristate.conf";
+}
+
static int conf_set_sym_val(struct symbol *sym, int def, int def_flags, char *p)
{
char *p2;
@@ -670,8 +677,12 @@ static char *escape_string_value(const char *in)

enum output_n { OUTPUT_N, OUTPUT_N_AS_UNSET, OUTPUT_N_NONE };

+#define PRINT_ESCAPE 0x01
+#define PRINT_UPCASE 0x02
+#define PRINT_TRISTATE_ONLY 0x04
+
static void __print_symbol(FILE *fp, struct symbol *sym, enum output_n output_n,
- bool escape_string)
+ int flags)
{
const char *val;
char *escaped = NULL;
@@ -679,6 +690,9 @@ static void __print_symbol(FILE *fp, struct symbol *sym, enum output_n output_n,
if (sym->type == S_UNKNOWN)
return;

+ if (flags & PRINT_TRISTATE_ONLY && sym->type != S_TRISTATE)
+ return;
+
val = sym_get_string_value(sym);

if ((sym->type == S_BOOLEAN || sym->type == S_TRISTATE) &&
@@ -688,29 +702,38 @@ static void __print_symbol(FILE *fp, struct symbol *sym, enum output_n output_n,
return;
}

- if (sym->type == S_STRING && escape_string) {
+ if (sym->type == S_STRING && flags & PRINT_ESCAPE) {
escaped = escape_string_value(val);
val = escaped;
}

- fprintf(fp, "%s%s=%s\n", CONFIG_, sym->name, val);
+ if (flags & PRINT_UPCASE)
+ fprintf(fp, "%s%s=%c\n", CONFIG_, sym->name, (char)toupper(*val));
+ else
+ fprintf(fp, "%s%s=%s\n", CONFIG_, sym->name, val);

free(escaped);
}

static void print_symbol_for_dotconfig(FILE *fp, struct symbol *sym)
{
- __print_symbol(fp, sym, OUTPUT_N_AS_UNSET, true);
+ __print_symbol(fp, sym, OUTPUT_N_AS_UNSET, PRINT_ESCAPE);
}

static void print_symbol_for_autoconf(FILE *fp, struct symbol *sym)
{
- __print_symbol(fp, sym, OUTPUT_N_NONE, false);
+ __print_symbol(fp, sym, OUTPUT_N_NONE, 0);
+}
+
+static void print_symbol_for_tristate(FILE *fp, struct symbol *sym)
+{
+ __print_symbol(fp, sym, OUTPUT_N_NONE, PRINT_ESCAPE | PRINT_UPCASE |
+ PRINT_TRISTATE_ONLY);
}

void print_symbol_for_listconfig(struct symbol *sym)
{
- __print_symbol(stdout, sym, OUTPUT_N, true);
+ __print_symbol(stdout, sym, OUTPUT_N, PRINT_ESCAPE);
}

static void print_symbol_for_c(FILE *fp, struct symbol *sym)
@@ -1207,6 +1230,12 @@ int conf_write_autoconf(int overwrite)
if (ret)
return ret;

+ ret = __conf_write_autoconf(conf_get_tristate_name(),
+ print_symbol_for_tristate,
+ &comment_style_pound);
+ if (ret)
+ return ret;
+
/*
* Create include/config/auto.conf. This must be the last step because
* Kbuild has a dependency on auto.conf and this marks the successful
--
2.38.0.266.g481848f278

2022-12-05 17:18:28

by Nick Alcock

[permalink] [raw]
Subject: [PATCH v10 07/13] kbuild: generate an address ranges map at vmlinux link time

This emits a new file, .tmp_vmlinux.ranges, which maps address
range/size pairs in vmlinux to the object files which make them up,
e.g., in part:

0x0000000000000000 0x30 arch/x86/kernel/cpu/common.o
0x0000000000001000 0x1000 arch/x86/events/intel/ds.o
0x0000000000002000 0x4000 arch/x86/kernel/irq_64.o
0x0000000000006000 0x5000 arch/x86/kernel/process.o
0x000000000000b000 0x1000 arch/x86/kernel/cpu/common.o
0x000000000000c000 0x5000 arch/x86/mm/cpu_entry_area.o
0x0000000000011000 0x10 arch/x86/kernel/espfix_64.o
0x0000000000011010 0x2 arch/x86/kernel/cpu/common.o
[...]

This will be used by kallmodsyms to let us associate symbols with
built-in modules at address-range granularity (i.e., space-efficiently),
and to let us disambiguate symbols with identical name and module by
annotating them with the translation unit they come from.

In my simple tests this seems to work with clang too, but if I'm not
sure how stable the format of clang's linker mapfiles is: if it turns
out not to work in some versions, the mapfile-massaging awk script added
here might need some adjustment.

CONFIG_LTO_CLANG by default optimizes by working from the LTOed
vmlinux.o file: but this doesn't work for kallmodsyms, as the resulting
mapfile lists vmlinux.o as the source object file in all cases, ruining
its attempt to disambiguate symbols using object file names. So we
suppress that optimization in this case.

We also suppress it when IBT is enabled, but IBT *requires* use of the
intermediate vmlinux.o, since that's the .o that objtool has run over.
We lift this restriction in the next commit.

(There are similar problems with everything else that uses ld -r: since
this amounts, in total, to a few parts of KVM on aarch64, I haven't
implemented a general ld -r fix: the fix in the next commit is specific
to vmlinux.o.)

Signed-off-by: Nick Alcock <[email protected]>
Reviewed-by: Kris Van Hees <[email protected]>
---

Notes:
v6: use ${wl} where appropriate to avoid failure on UML
v10: mention ultimate use in kallmodsyms, conflicts with IBT and ld -r

scripts/link-vmlinux.sh | 24 +++++++++++++++++++++---
1 file changed, 21 insertions(+), 3 deletions(-)

diff --git a/scripts/link-vmlinux.sh b/scripts/link-vmlinux.sh
index 32e573943cf0..a40d372b1289 100755
--- a/scripts/link-vmlinux.sh
+++ b/scripts/link-vmlinux.sh
@@ -60,7 +60,10 @@ vmlinux_link()
# skip output file argument
shift

- if is_enabled CONFIG_LTO_CLANG || is_enabled CONFIG_X86_KERNEL_IBT; then
+ # kallmodsyms needs a linker mapfile that contains original object
+ # file names, so cannot use this optimization.
+ if { is_enabled CONFIG_LTO_CLANG || is_enabled CONFIG_X86_KERNEL_IBT; } && \
+ ! is_enabled CONFIG_KALLMODSYMS; then
# Use vmlinux.o instead of performing the slow LTO link again.
objs=vmlinux.o
libs=
@@ -94,7 +97,7 @@ vmlinux_link()
ldflags="${ldflags} ${wl}--strip-debug"
fi

- if is_enabled CONFIG_VMLINUX_MAP; then
+ if is_enabled CONFIG_VMLINUX_MAP || is_enabled CONFIG_KALLMODSYMS; then
ldflags="${ldflags} ${wl}-Map=${output}.map"
fi

@@ -144,6 +147,21 @@ kallsyms()
{
local kallsymopt;

+ # read the linker map to identify ranges of addresses:
+ # - for each *.o file, report address, size, pathname
+ # - most such lines will have four fields
+ # - but sometimes there is a line break after the first field
+ # - start reading at "Linker script and memory map"
+ # - stop reading at ".brk"
+ if is_enabled CONFIG_KALLMODSYMS; then
+ ${AWK} '
+ /\.o$/ && start==1 { print $(NF-2), $(NF-1), $NF }
+ /^Linker script and memory map/ { start = 1 }
+ /^\.brk/ { exit(0) }
+ ' ${3} | sort > .tmp_vmlinux.ranges
+ fi
+
+ # get kallsyms options
if is_enabled CONFIG_KALLSYMS_ALL; then
kallsymopt="${kallsymopt} --all-symbols"
fi
@@ -175,7 +193,7 @@ kallsyms_step()

vmlinux_link ${kallsyms_vmlinux} "${kallsymso_prev}" ${btf_vmlinux_bin_o}
mksysmap ${kallsyms_vmlinux} ${kallsyms_vmlinux}.syms
- kallsyms ${kallsyms_vmlinux}.syms ${kallsyms_S}
+ kallsyms ${kallsyms_vmlinux}.syms ${kallsyms_S} ${kallsyms_vmlinux}.map

info AS ${kallsyms_S}
${CC} ${NOSTDINC_FLAGS} ${LINUXINCLUDE} ${KBUILD_CPPFLAGS} \
--
2.38.0.266.g481848f278

2022-12-06 10:36:51

by Geert Uytterhoeven

[permalink] [raw]
Subject: Re: [PATCH v10 05/13] kbuild: remove MODULE_LICENSE/AUTHOR/DESCRIPTION in non-modules

Hi Nick,

Thanks for your patch!

On Mon, Dec 5, 2022 at 5:34 PM Nick Alcock <[email protected]> wrote:
> Since commit 8b41fc4454e ("kbuild: create modules.builtin without
> Makefile.modbuiltin or tristate.conf"), MODULE_LICENSE declarations in
> non-modules will cause modprobe to misidentify their containing object
> file as a module when it is not, which might cause it to spuriously fail
> when trying to load something that is built in to the kernel. They
> also cause misconstruction of modules.builtin.objs, leading to incorrect
> output in kallmodsyms (notating things as being in modules when they
> actually cannot be built as a module at all).
>
> Automatically identified with the new tristate checker, and purged with
> sed and a subsequent make allmodconfig to double-check.
>
> Signed-off-by: Nick Alcock <[email protected]>

I can (sort of) agree with the MODULE_LICENSE(), as it duplicates the
SPDX-License-Identifier at the top.
However, you don't explain why it is a good thing to remove the
MODULE_{AUTHOR,DESCRIPTION}, too. This is useful information, in an
easy-to-parse format.

Moreover, many of the affected drivers might be converted into modules
in the near or far future.

If the presence of these causes issues for the tooling, perhaps the
tooling can be fixed instead?

Gr{oetje,eeting}s,

Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- [email protected]

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds

2022-12-06 20:19:15

by Nick Alcock

[permalink] [raw]
Subject: Re: [PATCH v10 05/13] kbuild: remove MODULE_LICENSE/AUTHOR/DESCRIPTION in non-modules

On 6 Dec 2022, Geert Uytterhoeven uttered the following:

> On Mon, Dec 5, 2022 at 5:34 PM Nick Alcock <[email protected]> wrote:
>> Since commit 8b41fc4454e ("kbuild: create modules.builtin without
>> Makefile.modbuiltin or tristate.conf"), MODULE_LICENSE declarations in
>> non-modules will cause modprobe to misidentify their containing object
>> file as a module when it is not, which might cause it to spuriously fail
>> when trying to load something that is built in to the kernel. They
>> also cause misconstruction of modules.builtin.objs, leading to incorrect
>> output in kallmodsyms (notating things as being in modules when they
>> actually cannot be built as a module at all).
>>
>> Automatically identified with the new tristate checker, and purged with
>> sed and a subsequent make allmodconfig to double-check.
>>
>> Signed-off-by: Nick Alcock <[email protected]>
>
> I can (sort of) agree with the MODULE_LICENSE(), as it duplicates the
> SPDX-License-Identifier at the top.
> However, you don't explain why it is a good thing to remove the
> MODULE_{AUTHOR,DESCRIPTION}, too. This is useful information, in an
> easy-to-parse format.

I was concerned about that, but I kinda thought they went together and
it would be neater to take them out in one go -- but I'd be happy to
keep them in and only drop MODULE_LICENSE.

> Moreover, many of the affected drivers might be converted into modules
> in the near or far future.
>
> If the presence of these causes issues for the tooling, perhaps the
> tooling can be fixed instead?

Only MODULE_LICENSE invokes MODULE_FILE and thus ends up introducing a
KBUILD_MODOBJS entry that triggers things going wrong iff not a module:
so only it needs to go out (or be replaced with a variant that doesn't
invoke MODULE_FILE, if you want to keep the license in too -- but if the
thing is no longer a standalone entity at all I'm not sure what meaning
it could possibly have).

--
NULL && (void)

2022-12-06 21:19:36

by Arnd Bergmann

[permalink] [raw]
Subject: Re: [PATCH v10 05/13] kbuild: remove MODULE_LICENSE/AUTHOR/DESCRIPTION in non-modules

On Tue, Dec 6, 2022, at 21:03, Nick Alcock wrote:
> On 6 Dec 2022, Geert Uytterhoeven uttered the following:
> Only MODULE_LICENSE invokes MODULE_FILE and thus ends up introducing a
> KBUILD_MODOBJS entry that triggers things going wrong iff not a module:
> so only it needs to go out (or be replaced with a variant that doesn't
> invoke MODULE_FILE, if you want to keep the license in too --

That sounds like a better alternative

> but if the thing is no longer a standalone entity at all I'm not sure
> what meaning it could possibly have).

As far as I can tell, the general trend is to make more things modules,
so there is a good chance that these come back eventually. If the
information in the MODULE_LICENSE field isn't wrong, I would just
leave it in there.

Arnd

2022-12-07 05:26:23

by Luis Chamberlain

[permalink] [raw]
Subject: Re: [PATCH v10 05/13] kbuild: remove MODULE_LICENSE/AUTHOR/DESCRIPTION in non-modules

On Tue, Dec 06, 2022 at 09:03:52PM -0800, Luis Chamberlain wrote:
> On Tue, Dec 06, 2022 at 10:02:30PM +0100, Arnd Bergmann wrote:
> > On Tue, Dec 6, 2022, at 21:03, Nick Alcock wrote:
> > > On 6 Dec 2022, Geert Uytterhoeven uttered the following:
> > > Only MODULE_LICENSE invokes MODULE_FILE and thus ends up introducing a
> > > KBUILD_MODOBJS entry that triggers things going wrong iff not a module:
> > > so only it needs to go out (or be replaced with a variant that doesn't
> > > invoke MODULE_FILE, if you want to keep the license in too --
> >
> > That sounds like a better alternative
> >
> > > but if the thing is no longer a standalone entity at all I'm not sure
> > > what meaning it could possibly have).
> >
> > As far as I can tell, the general trend is to make more things modules,
> > so there is a good chance that these come back eventually. If the
> > information in the MODULE_LICENSE field isn't wrong, I would just
> > leave it in there.
>
> Tooling today uses it though to make a deterministic call on if something
> *can* be a module. In particular after commit 8b41fc4454e ("kbuild: create
> modules.builtin without Makefile.modbuiltin or tristate.conf") we rely on
> the module license tag to generate the modules.builtin file. This in
> turn is used to allow modprobe to *not* fail when trying to load a module
> which is built-in.
>
> So we can't just disable the tag for when the code is built-in as *want*
> to carry it when modules are built-in, that is the point, to help
> userspace with this determination.
>
> I don't think we want to revert 8b41fc4454e as it means we'd force Kbuild to
> traverse the source tree twice.
>
> Geert's point was not keeping MODULE_LICENSE() but instead the other
> MODULE_*() crap for things which are not modules in case in the future
> code becomes a module...
>
> But I don't see the point in keeping things around just in case, if we
> want to keep things simple. Just use the SPDX license tag for the license.

Or if you really want to keep it just make it an *eye-sore*, and comment it out.

I don't see why at build-time we should suffer.

Luis

2022-12-07 05:27:15

by Luis Chamberlain

[permalink] [raw]
Subject: Re: [PATCH v10 05/13] kbuild: remove MODULE_LICENSE/AUTHOR/DESCRIPTION in non-modules

On Tue, Dec 06, 2022 at 10:02:30PM +0100, Arnd Bergmann wrote:
> On Tue, Dec 6, 2022, at 21:03, Nick Alcock wrote:
> > On 6 Dec 2022, Geert Uytterhoeven uttered the following:
> > Only MODULE_LICENSE invokes MODULE_FILE and thus ends up introducing a
> > KBUILD_MODOBJS entry that triggers things going wrong iff not a module:
> > so only it needs to go out (or be replaced with a variant that doesn't
> > invoke MODULE_FILE, if you want to keep the license in too --
>
> That sounds like a better alternative
>
> > but if the thing is no longer a standalone entity at all I'm not sure
> > what meaning it could possibly have).
>
> As far as I can tell, the general trend is to make more things modules,
> so there is a good chance that these come back eventually. If the
> information in the MODULE_LICENSE field isn't wrong, I would just
> leave it in there.

Tooling today uses it though to make a deterministic call on if something
*can* be a module. In particular after commit 8b41fc4454e ("kbuild: create
modules.builtin without Makefile.modbuiltin or tristate.conf") we rely on
the module license tag to generate the modules.builtin file. This in
turn is used to allow modprobe to *not* fail when trying to load a module
which is built-in.

So we can't just disable the tag for when the code is built-in as *want*
to carry it when modules are built-in, that is the point, to help
userspace with this determination.

I don't think we want to revert 8b41fc4454e as it means we'd force Kbuild to
traverse the source tree twice.

Geert's point was not keeping MODULE_LICENSE() but instead the other
MODULE_*() crap for things which are not modules in case in the future
code becomes a module...

But I don't see the point in keeping things around just in case, if we
want to keep things simple. Just use the SPDX license tag for the license.

Luis

2022-12-07 09:01:32

by Christoph Hellwig

[permalink] [raw]
Subject: Re: [PATCH v10 05/13] kbuild: remove MODULE_LICENSE/AUTHOR/DESCRIPTION in non-modules

On Tue, Dec 06, 2022 at 09:03:52PM -0800, Luis Chamberlain wrote:
> But I don't see the point in keeping things around just in case, if we
> want to keep things simple. Just use the SPDX license tag for the license.

It would be very helpful if we could just autogenerate the module
license information from the SPDX tags..

2022-12-16 16:38:47

by Nick Alcock

[permalink] [raw]
Subject: Re: [PING] [PATCH modules-next v10 00/13] kallsyms: reliable symbol->address lookup with /proc/kallmodsyms

(hand-hacked reply: hope it threads properly)

[...]
> A kernel tree containing this series alone:
> https://github.com/oracle/dtrace-linux-kernel kallmodsyms/6.1-rc4-modules-next
[...]
> Nick Alcock (12):
> kbuild: bring back tristate.conf
> kbuild: add tristate checker
> kbuild: fix up substitutions in makefiles to allow for tristate
> checker
> kbuild: remove MODULE_LICENSE/AUTHOR/DESCRIPTION in non-modules
> build: add a simple iterator over modules.builtin.objs
> kbuild: generate an address ranges map at vmlinux link time
> kbuild: make address ranges map work with IBT
> kallsyms: introduce sections needed to map symbols to built-in modules
> kallsyms: optimize .kallsyms_modules*
> kallsyms: distinguish text symbols fully using object file names
> kallsyms: add /proc/kallmodsyms for text symbol disambiguation
> perf: proof-of-concept kallmodsyms support

It's been a couple of weeks, so a gentle ping seems in order :) (I can
resend if people need it, but I suspect everyone interested has it
already.)

2023-01-17 21:54:54

by Luis Chamberlain

[permalink] [raw]
Subject: Re: [PATCH modules-next v10 00/13] kallsyms: reliable symbol->address lookup with /proc/kallmodsyms

On Mon, Dec 05, 2022 at 04:31:44PM +0000, Nick Alcock wrote:
> The kallmodsyms patch series was originally posted in Nov 2019, and the thread
> (https://lore.kernel.org/linux-kbuild/[email protected]/t/#u)
> shows review comments, questions, and feedback from interested parties.
> Most recent posting: <https://lore.kernel.org/linux-modules/[email protected]/T/#t>.
>
> All review comments have been satisfied, as far as I know:

No, not really. I have asked before to trim this cover letter down and
make each patch make sense atomically. You have not done so. I have also
asked you to get users of what you are suggesting to add to kernel to
vouch for this, and for you to make that clear and I feel that falls
short too. I have even suggested folks who likely could help review your
patches for other things they may need or are working on.

So no, this is patch review is slow moving but I'd like to clarify as to why.
It is not that I am ignoring this patch set, it is that each time I come
back to it I see only a slight step forward with the suggestions made.

> A kernel tree containing this series alone:
> https://github.com/oracle/dtrace-linux-kernel kallmodsyms/6.1-rc4-modules-next
>
>
> The whole point of symbols is that their names are unique: you can look up a
> symbol and get back a unique address, and vice versa. Alas, because
> /proc/kallsyms (rightly) reports all symbols, even hidden ones, it does not
> really satisfy this requirement.

You make it sound that's would imply there's bug in kallsyms but its not. We
would have bug reports and I just don't see them associated to what you say.

kallsyms support was added first by Ingo Molnar on 2.5.38 kernel [0] and the
goal was to just to be able to print out symbolic crash information and symbolic
stack backtraces. Rusty Russel later extended support for modules [2] and Kai
Germaschewski finally decreased the speed to generate the file by writing a C
program for it [2]. To this day CONFIG_KALLSYMS is described to relfect that
this is just for oops traces and stack traces.

In that sense getting mapping of addresses to symbols for oops or stack
traces seems kallsyms is successful.

[0] https://git.kernel.org/pub/scm/linux/kernel/git/history/history.git/commit/?id=218af2f340009e624603253ca8a35c884f31ab5a
[1] https://git.kernel.org/pub/scm/linux/kernel/git/history/history.git/commit/?id=a5508ddcd000a435baa37f61ef1bdfb490fcf3c0
[2] https://git.kernel.org/pub/scm/linux/kernel/git/history/history.git/commit/?id=6802d702761dfdd910e37da40ba95fa71fd06dd7

> Large numbers of symbols are duplicated
> many times (just search for __list_del_entry!), and while usually these are
> just out-of-lined things defined in header files and thus all have the same
> implementation, it does make it needlessly hard to figure out which one is
> which in stack dumps, when tracing, and such things.

Here is the problem you have in your cover letter: you first try to
state that kallsyms is falling short for your use case and then skim through
the actual use case where you need a unique mapping.

> Some configuration
> options make things much worse: my test make allyesconfig runs introduced
> thousands of text symbols named _sub_I_65535_1, one per compiler-generated
> object file, and it was fairly easy to make them appear in ftrace output.
>
> Right now the kernel has no way at all to tell such symbols apart, and nor
> has the user: their address differs and that's all.

You need to explain who would care and why this is an issue.

> Which module did they
> come from? Which object file? We don't know. Figuring out which is which
> when tracing

For the very *first* time in the cover letter do I see the first
description of a use case where someone might care.

> needs a combination of guesswork and luck, and if there are
> thousands of them that's not a pleasant prospect. In discussions at LPC it
> became clear that this is not just annoying me but Steve Rostedt and others,
> so it's probably desirable to fix this.

You can just summarize this to say tracing folks care and you need to
explain why. Why this falls short. Why is this limitting tracing folks?

Other than tracing too, wouldn't folks who work on things like crash
care too (Jeff, Omar)? Wouldn't this help them or their teams which
rely on tooling around this?

> It turns out that the linker, and the kernel build system, can be made to
> give us everything we need to resolve this once and for all. This series
> provides a new /proc/kallmodsyms which is like /proc/kallsyms except that it
> annotates every (textual) symbol which comes from a built-in kernel module
> with the module's name, in square brackets: if a symbol is used by multiple
> modules, it gets [multiple] [names]; if a symbol is still ambiguous it gets
> a cut-down {object file name}; the combination of symbol, [module] [names]
> and {object file name} is unique

If this is about tracing and issues with a symbol name being mapped to
multiple objects why would this enhancement only involve what are
possibly modules? If the main motivation for the work you are
introducing is to help tracers get a better bearing when working with
a symbols, yes I can see the value in knowing if a symbol was part of
a module, but I'd likely would want to care about in-kernel symbols
too. Is the reason a new file is being introduced because you can
already get 1-1 mapping for symbols only used for built-in stuff?
Ie, is the semantic requirements for fidelity for pure built-in symbols
already satisfied by kallsyms? And do modules then introduce a new
semantic gap, which make it difficult to know what object file thinggs
map to?

Regardless, if tracing is the main use case and the goal here is to map
symbols to object files, I can't think of a reason why a symbol map
filename which also spits out built-in object files needs to be associated with
modules.

/proc/kallmodsyms seems to imply modules need to be involved somehow,
but it does not seem that's the reason for the file. Rather, you seem to
want to just be able to tell users if the symbol came from an object
file only assocaited to a module.

And if this new feature is being tucked away under a new kconfig symbol,
why not just extend the existing /proc/kallsyms when folks want the new
information?

> (with one minor exception: the arm64 nvhe
> module is pre-linked with ld -r, causing all symbols in it to appear to come
> from the same object file: if it was reworked to use thin archives this
> problem would go away).

OK so ARM64 nVHE folks might care, but perhaps other architectures might
be limitted with this feature. Could you express this via Kconfig so
that the feature cannot be selected by these architectures if they use
'ld -r'?

Please work with Guenter Roeck so to have a new branch for your work
tested on some of the oddball archs he has access to. That should help
proactively find odd arch issues we'd otherwise find out during testing
once merged.

> The object file names are cut down to save space: we store only the shortest
> suffix needed to distinguish symbols from each other.

If the information for tracers was so valuable, why trim this? And how
much space does that save you? Is the idea that CONFIG_KALLMODSYMS
would be enabled on production kernels?

> It's fairly rare even
> to see two/level names, let alone three/level/ones.

What does one level mean? What does two levels mean? What does three
levels mean here?

> We also save even more
> space by annotating every symbol in a given object file with the object file
> name if we annotate any of them.
>
> We also add new fields that let you get at this new info in the kallsyms
> iterator.
>
> In brief we do this by mapping from address ranges to object files (with
> assistance from the linker map file), then mapping from those object files
> to built-in kernel modules and object file names. Because the number of
> object files is much smaller than the number of symbols, because we fuse
> address range and object file entries together if possible, and because we
> don't even store object file names unless we need to, this is a fairly
> efficient representation, even with a bit of extra complexity to allow
> object files to be in more than one module at once.
>
> The size impact of all of this is minimal: in testing, vmlinux grew by 16632
> bytes, and the compressed vmlinux only grew by 12544 bytes (about .1% of a
> 10MiB kernel): though this is very configuration-dependent, it seems likely
> to scale roughly with the kernel as a whole.
>
> This is all controlled by a new config parameter CONFIG_KALLMODSYMS, which when
> set results in output in /proc/kallmodsyms that looks like this:
>
> ffffffff97606e50 t not_visible
> ffffffff97606e70 T perf_msr_probe
> ffffffff97606f80 t test_msr [rapl]
> ffffffffa6007350 t rapl_pmu_event_stop [rapl]
> ffffffffa6007440 t rapl_pmu_event_del [rapl]
> ffffffffa6007460 t rapl_hrtimer_handle [rapl]
> ffffffffa6007500 t rapl_pmu_event_read [rapl]
> ffffffffa6007520 t rapl_pmu_event_init [rapl]
> ffffffffa6007630 t rapl_cpu_offline [rapl]

My /proc/kallsyms already has something like:

ffffffffc04c7940 t show_shost_eh_deadline [scsi_mod]
ffffffffc04c7990 t show_shost_active_mode [scsi_mod]
ffffffffc04c79d0 t sdev_show_preferred_path [scsi_mod]

So why is that falling short vs /proc/kallmodsyms ?

> Differences from v9, early November 2022:
>
> - Rework to use Luis Chamberlain's modules.builtin.objs rather than a
> tristate-generated "modules_thick.builtin". Keep the iterator over
> modules_thick.builtin, but rename it to scripts/modules_builtin.c and
> make it more robust against strange lines in modules.builtin.objs,
> such as lines with no colon in.

Please extend the commit log to describe that subsequent patches would
use that information, as otherwise the commit log seems to just
introduce something for new user. My patch was simply a proof of concept
which denied what you claimed was not possible. You can describe also *why*
this information is useful, ie if your use cas is traces, then mention that
and why. The point to my patch also was to show you don't have to re-intrdouce
the tristate stuff, ie your effect revert of commit 8b41fc4454e36fbf ("kbuild:
create modules.builtin without Makefile.modbuiltin or tristate.conf")
and so I am extremely surprised you are still keeeping that patch and
using that suff in this v10 series! The point was to simplify your
patch series.

The semantics of the module license should suffice.

And please split out the driver conversions to remove module license per
subsystem, and a new thread. The justification should be simple, commit
8b41fc4454e36fbf ("kbuild: create modules.builtin without Makefile.modbuiltin or
tristate.conf") now relies on the module license tag to do simplify the
build system. And as part of follow up work to that patch we want to
correct false positives for modules.builtin where userspace may try to
load a module which is built-in but such module can never be built in.
You can add Suggested-by me to that set.

The same applies to your other Makefile patch (except to the
Suggested-by as I don't understand the goal there yet), I don't know what it is
trying to do, but it should be a separate effort. You can feel free to
Cc me on that too.

And lastly users. This cover letter should reflect clearly who are the
new users who are dying for this feature, Cc them and hope to have them be
actively engaged during review.

Luis

2023-02-09 17:12:57

by Nick Alcock

[permalink] [raw]
Subject: Re: [PATCH modules-next v10 00/13] kallsyms: reliable symbol->address lookup with /proc/kallmodsyms

On 17 Jan 2023, Luis Chamberlain uttered the following:
[...]
> And please split out the driver conversions to remove module license per
> subsystem, and a new thread. The justification should be simple, commit
> 8b41fc4454e36fbf ("kbuild: create modules.builtin without Makefile.modbuiltin or
> tristate.conf") now relies on the module license tag to do simplify the
> build system. And as part of follow up work to that patch we want to
> correct false positives for modules.builtin where userspace may try to
> load a module which is built-in but such module can never be built in.
> You can add Suggested-by me to that set.

I understand what you are saying, and I have been working on this.

I am going to split this whole series into:

1. A series of patches (123 of them at present) Cc:ed to subsystem
maintainers as well as you, to comment out the MODULE_LICENSE usage.
These patches will have Suggested-by you. This series is rebased against
the latest modules-next and revalidated, and is ready to be mailed out;
will do so shortly.

2. A series of patches adding your new modules.builtin.objs and
kallmodsyms (with revised cover letter, etc, as you request). As part of
the second series I will make sure to involve the tracing maintainers
more and provide an example of usage with perf and hopefully ftrace.
(Note that the name "kallmodsym" is not something I am wedded to. We can
find a better one, if we can come up with one: it's more about
unambiguous symbol resolution now, and maximizing the number of module
names is largely a mechanism to accomplish that, so maybe /proc/ksym?)

This second series is not going out quite yet: I'm working on the perf
support now.

> The same applies to your other Makefile patch (except to the
> Suggested-by as I don't understand the goal there yet), I don't know what it is
> trying to do, but it should be a separate effort. You can feel free to
> Cc me on that too.

I have decided not to submit the tristate checker at this time, as it is
not essential and it made things too confused. The Makefile patch you
refer to and the tristate.conf reintroduction were only needed for the
checker, so are dropped, with nothing more than a reference to a branch
containing the checker in the kallmodsyms cover letter. (The checker
does need periodic rerunning to make sure that spurious MODULE_LICENSE
usages don't creep back in -- reintroductions seem to be running at
about one a month -- but that's easy to do ad-hoc and it doesn't need to
be upstream for that.)

> And lastly users. This cover letter should reflect clearly who are the
> new users who are dying for this feature, Cc them and hope to have them be
> actively engaged during review.

I do hope that adding some proof-of-concept usage of this in perf and
ftrace (emitting symbol names formatted like 'symbol@objname:module'
where possible rather than just unadorned symbols) might show the perf
and ftrace maintainers that this is not useless.

Thanks for your patience and feedback.

2023-02-10 00:02:42

by Nick Alcock

[permalink] [raw]
Subject: Re: [PATCH modules-next v10 00/13] kallsyms: reliable symbol->address lookup with /proc/kallmodsyms

[most people trimmed from the Cc: list for this procedural question]

On 9 Feb 2023, Nick Alcock outgrape:
> I am going to split this whole series into:
>
> 1. A series of patches (123 of them at present) Cc:ed to subsystem
> maintainers as well as you, to comment out the MODULE_LICENSE usage.
> These patches will have Suggested-by you. This series is rebased against
> the latest modules-next and revalidated, and is ready to be mailed out;
> will do so shortly.

One quick question: if/when you're happy with this series, are you
planning to take it yourself via modules-next? My understanding is that
if you are, I can just send the lot as one big series, whereas if you're
not I have to do it as a lot of little series to avoid burdening all the
maintainers who will have to take its pieces.

(To me, taking it all at once seems like a lot less work for
everyone... I'm still Cc:ing maintainers on individual commits affecting
their subsystem though. Seems only polite.)

2023-02-21 21:48:41

by Luis Chamberlain

[permalink] [raw]
Subject: Re: [PATCH modules-next v10 00/13] kallsyms: reliable symbol->address lookup with /proc/kallmodsyms

On Thu, Feb 09, 2023 at 11:53:29PM +0000, Nick Alcock wrote:
> [most people trimmed from the Cc: list for this procedural question]
>
> On 9 Feb 2023, Nick Alcock outgrape:
> > I am going to split this whole series into:
> >
> > 1. A series of patches (123 of them at present) Cc:ed to subsystem
> > maintainers as well as you, to comment out the MODULE_LICENSE usage.
> > These patches will have Suggested-by you. This series is rebased against
> > the latest modules-next and revalidated, and is ready to be mailed out;
> > will do so shortly.
>
> One quick question: if/when you're happy with this series, are you
> planning to take it yourself via modules-next?

It seems some maintainers are already taking patches in, so let's see
what folks take in, then if there are not takers I can just take what is
not merged on linux-next through modules-next.

So try to get them into each subsystem tree, and around rc3 send the
ones that are not merged and I'll just take them into modules-next.

Luis

2023-02-22 12:09:12

by Nick Alcock

[permalink] [raw]
Subject: Re: [PATCH modules-next v10 00/13] kallsyms: reliable symbol->address lookup with /proc/kallmodsyms

On 21 Feb 2023, Luis Chamberlain stated:

> On Thu, Feb 09, 2023 at 11:53:29PM +0000, Nick Alcock wrote:
>> [most people trimmed from the Cc: list for this procedural question]
>>
>> On 9 Feb 2023, Nick Alcock outgrape:
>> > I am going to split this whole series into:
>> >
>> > 1. A series of patches (123 of them at present) Cc:ed to subsystem
>> > maintainers as well as you, to comment out the MODULE_LICENSE usage.
>> > These patches will have Suggested-by you. This series is rebased against
>> > the latest modules-next and revalidated, and is ready to be mailed out;
>> > will do so shortly.
>>
>> One quick question: if/when you're happy with this series, are you
>> planning to take it yourself via modules-next?
>
> It seems some maintainers are already taking patches in, so let's see
> what folks take in, then if there are not takers I can just take what is
> not merged on linux-next through modules-next.
>
> So try to get them into each subsystem tree, and around rc3 send the
> ones that are not merged and I'll just take them into modules-next.

Sounds good! I can trivially regenerate a new patch series containing
only the still-missing bits without needing to do anything like track
who took things, because nearly all of this is automated anyway.

... at least I can if I can figure out where all the subsystem trees
that people took them into are (not everyone might mention when they
take one). I might miss a few, but I suspect that's not a problem:
taking the same commit by two different routes does not constitute a
conflict, at least on its own.

2023-02-22 22:25:32

by Luis Chamberlain

[permalink] [raw]
Subject: Re: [PATCH modules-next v10 00/13] kallsyms: reliable symbol->address lookup with /proc/kallmodsyms

On Wed, Feb 22, 2023 at 12:08:12PM +0000, Nick Alcock wrote:
> On 21 Feb 2023, Luis Chamberlain stated:
>
> > On Thu, Feb 09, 2023 at 11:53:29PM +0000, Nick Alcock wrote:
> >> [most people trimmed from the Cc: list for this procedural question]
> >>
> >> On 9 Feb 2023, Nick Alcock outgrape:
> >> > I am going to split this whole series into:
> >> >
> >> > 1. A series of patches (123 of them at present) Cc:ed to subsystem
> >> > maintainers as well as you, to comment out the MODULE_LICENSE usage.
> >> > These patches will have Suggested-by you. This series is rebased against
> >> > the latest modules-next and revalidated, and is ready to be mailed out;
> >> > will do so shortly.
> >>
> >> One quick question: if/when you're happy with this series, are you
> >> planning to take it yourself via modules-next?
> >
> > It seems some maintainers are already taking patches in, so let's see
> > what folks take in, then if there are not takers I can just take what is
> > not merged on linux-next through modules-next.
> >
> > So try to get them into each subsystem tree, and around rc3 send the
> > ones that are not merged and I'll just take them into modules-next.
>
> Sounds good! I can trivially regenerate a new patch series containing
> only the still-missing bits without needing to do anything like track
> who took things, because nearly all of this is automated anyway.

Fantastic.

> ... at least I can if I can figure out where all the subsystem trees
> that people took them into are (not everyone might mention when they
> take one).

This is why I use linux-next. It represents all the latest trees merged.

> I might miss a few, but I suspect that's not a problem:
> taking the same commit by two different routes does not constitute a
> conflict, at least on its own.

Right.

Luis

2023-03-05 08:10:26

by Masahiro Yamada

[permalink] [raw]
Subject: Re: [PATCH v10 05/13] kbuild: remove MODULE_LICENSE/AUTHOR/DESCRIPTION in non-modules

On Wed, Dec 7, 2022 at 2:04 PM Luis Chamberlain <[email protected]> wrote:
>
> On Tue, Dec 06, 2022 at 10:02:30PM +0100, Arnd Bergmann wrote:
> > On Tue, Dec 6, 2022, at 21:03, Nick Alcock wrote:
> > > On 6 Dec 2022, Geert Uytterhoeven uttered the following:
> > > Only MODULE_LICENSE invokes MODULE_FILE and thus ends up introducing a
> > > KBUILD_MODOBJS entry that triggers things going wrong iff not a module:
> > > so only it needs to go out (or be replaced with a variant that doesn't
> > > invoke MODULE_FILE, if you want to keep the license in too --
> >
> > That sounds like a better alternative
> >
> > > but if the thing is no longer a standalone entity at all I'm not sure
> > > what meaning it could possibly have).
> >
> > As far as I can tell, the general trend is to make more things modules,
> > so there is a good chance that these come back eventually. If the
> > information in the MODULE_LICENSE field isn't wrong, I would just
> > leave it in there.
>
> Tooling today uses it though to make a deterministic call on if something
> *can* be a module. In particular after commit 8b41fc4454e ("kbuild: create
> modules.builtin without Makefile.modbuiltin or tristate.conf") we rely on
> the module license tag to generate the modules.builtin file. This in
> turn is used to allow modprobe to *not* fail when trying to load a module
> which is built-in.



If we have a bool driver 'foo.ko' in modules.builtin,
'modprobe foo' will not fail where you expect it will fail.

Is it so important to make this strict?

I do not think so.


What is a point for a user to realize
"Oh, I did not know foo cannot be compiled as a module"


Re-read the commit description of
bc081dd6e9f622c73334dc465359168543ccaabf

The motivation of module.builtin is to know the functionality 'foo'
is available (via built-in or module, whatever).

In this sense, having always-builtin entries in module.builtin is OK.


I do not see any sense in the tooling mess in this patch set.








> So we can't just disable the tag for when the code is built-in as *want*
> to carry it when modules are built-in, that is the point, to help
> userspace with this determination.
>
> I don't think we want to revert 8b41fc4454e as it means we'd force Kbuild to
> traverse the source tree twice.


I do not want to revert it.

and I do not want this series in the mainline.




>
> Geert's point was not keeping MODULE_LICENSE() but instead the other
> MODULE_*() crap for things which are not modules in case in the future
> code becomes a module...
>
> But I don't see the point in keeping things around just in case, if we
> want to keep things simple. Just use the SPDX license tag for the license.
>
> Luis



--
Best Regards
Masahiro Yamada

2023-03-05 08:10:53

by Masahiro Yamada

[permalink] [raw]
Subject: Re: [PATCH v10 02/13] kbuild: bring back tristate.conf

On Tue, Dec 6, 2022 at 1:32 AM Nick Alcock <[email protected]> wrote:
>
> tristate.conf was dropped because it is not needed to build
> modules.builtin any more, and doing so avoids one round of recursion
> through the build tree to build it. But it has one property that can be
> obtained in no other way in the current tree: it provides a
> machine-readable record of whether a module is tristate or not.
> (modules.builtin.objs, just added, uses modinfo, which is recorded in
> the source files themselves, but it is Kconfig that actually controls
> whether something can be built as a module.)
>
> So bring it back for this purpose. (Thanks to the refactoring in
> the 5.16 timeframe, this is basically a reimplementation of commit
> 8b41fc4454e36fbfdbb23f940d023d4dece2de29 rather than a simple
> reversion.)
>
> A verifier that uses it will be added in the next commit.

>
> Signed-off-by: Nick Alcock <[email protected]>
> Reviewed-by: Victor Erminpour <[email protected]>
> Reviewed-by: Kris Van Hees <[email protected]>



IIRC, I said please do not do this.
Please do not come back with this again.

NACK.






--
Best Regards
Masahiro Yamada

2023-03-05 15:11:09

by Masahiro Yamada

[permalink] [raw]
Subject: Re: [PATCH v10 03/13] kbuild: add tristate checker

On Tue, Dec 6, 2022 at 1:32 AM Nick Alcock <[email protected]> wrote:
>
> This new check target uses the tristate.conf machinery just added, and
> modules.builtin.objs, to identify source files that have MODULE_*
> declarations despite not being modules according to Kconfig. After
> commit 8b41fc4454e ("kbuild: create modules.builtin without
> Makefile.modbuiltin or tristate.conf"), all such declarations will cause
> modprobe to misidentify their containing object file as a module when it
> is not, which might cause it to spuriously fail when trying to load
> something that is built in to the kernel.




Having false-positives in modules.builtin should be OK.


Also, scripts/check-tristates.mk is just a rename of
scripts/Makefile.modbuiltin.


NACK.





--
Best Regards


Masahiro Yamada

2023-03-05 15:12:28

by Masahiro Yamada

[permalink] [raw]
Subject: Re: [PATCH v10 04/13] kbuild: fix up substitutions in makefiles to allow for tristate checker

On Tue, Dec 6, 2022 at 1:32 AM Nick Alcock <[email protected]> wrote:
>
> The tristate checker, like the Makefile.modbuiltin that preceded it,
> relies on running the makefiles with some CONFIG_ variables set to
> uppercase values ('Y' or 'M'). Large portions of the core build system
> assume that these values are lowercase, but we mostly don't care about
> those because they are only involved in actual building, and make
> tristatecheck doesn't build anything (the parts that do need changing so
> that recursion etc still worked were changed as part of the tristate
> commit).
>
> But some makefiles that are not part of the core build system also
> contain assumptions that CONFIG_ variables are always lowercase (every
> one of these was also broken wrt the old modules.builtin machinery, but
> now this is part of a verifier, the problems are more obvious). In most
> cases this is just something like
>
> obj-$(subst m,y,$(CONFIG_FOO)) += blah.o
>
> to indicate that blah.o is always built in even if CONFIG_FOO is a
> module. There is a new macro to help this relatively common case, which
> should now be rewritten as
>
> obj-$(call always_built_in,$(CONFIG_FOO)) += blah.o
>
> One other case we handle is that in net/dccp where things are built as
> modules iff any member of some other set are modular; this is now
> handled like so:
>
> obj-$(call module_if_any_modular,$(CONFIG_IP_DCCP)$(CONFIG_IPV6)) += dccp_ipv6.o
> dccp_ipv6-$(call module_if_any_modular,$(CONFIG_IP_DCCP)$(CONFIG_IPV6)) := ipv6.o
>
> Signed-off-by: Nick Alcock <[email protected]>



The tristate checker in the previous commit is so ugly
and should not exist in the upstream.

So, this patch will just introduce lots of ugliness for no good reason.

NACK.






> ---
>
> Notes:
> v10: new.
>
> drivers/Makefile | 2 +-
> drivers/hv/Makefile | 2 +-
> drivers/mmc/Makefile | 2 +-
> drivers/net/wireless/silabs/wfx/Makefile | 2 +-
> drivers/s390/char/Makefile | 2 +-
> drivers/s390/crypto/Makefile | 2 +-
> net/8021q/Makefile | 2 +-
> net/Makefile | 2 +-
> net/bridge/Makefile | 4 ++--
> net/dccp/Makefile | 4 ++--
> net/ipv6/Makefile | 2 +-
> net/l2tp/Makefile | 12 ++++++------
> net/netfilter/Makefile | 2 +-
> net/netlabel/Makefile | 2 +-
> net/sctp/Makefile | 2 +-
> scripts/Kbuild.include | 15 +++++++++++++++
> 16 files changed, 37 insertions(+), 22 deletions(-)
>
> diff --git a/drivers/Makefile b/drivers/Makefile
> index bdf1c66141c9..a6d3296f0c23 100644
> --- a/drivers/Makefile
> +++ b/drivers/Makefile
> @@ -159,7 +159,7 @@ obj-$(CONFIG_SOUNDWIRE) += soundwire/
>
> # Virtualization drivers
> obj-$(CONFIG_VIRT_DRIVERS) += virt/
> -obj-$(subst m,y,$(CONFIG_HYPERV)) += hv/
> +obj-$(call always_built_in,$(CONFIG_HYPERV)) += hv/
>
> obj-$(CONFIG_PM_DEVFREQ) += devfreq/
> obj-$(CONFIG_EXTCON) += extcon/
> diff --git a/drivers/hv/Makefile b/drivers/hv/Makefile
> index d76df5c8c2a9..06777af02a78 100644
> --- a/drivers/hv/Makefile
> +++ b/drivers/hv/Makefile
> @@ -13,4 +13,4 @@ hv_vmbus-$(CONFIG_HYPERV_TESTING) += hv_debugfs.o
> hv_utils-y := hv_util.o hv_kvp.o hv_snapshot.o hv_fcopy.o hv_utils_transport.o
>
> # Code that must be built-in
> -obj-$(subst m,y,$(CONFIG_HYPERV)) += hv_common.o
> +obj-$(call always_built_in,$(CONFIG_HYPERV)) += hv_common.o
> diff --git a/drivers/mmc/Makefile b/drivers/mmc/Makefile
> index 3ea0126a9a72..1f4f9ce02490 100644
> --- a/drivers/mmc/Makefile
> +++ b/drivers/mmc/Makefile
> @@ -4,4 +4,4 @@
> #
>
> obj-$(CONFIG_MMC) += core/
> -obj-$(subst m,y,$(CONFIG_MMC)) += host/
> +obj-$(call always_built_in,$(CONFIG_MMC)) += host/
> diff --git a/drivers/net/wireless/silabs/wfx/Makefile b/drivers/net/wireless/silabs/wfx/Makefile
> index c8b356f71c99..9fe47f5a050a 100644
> --- a/drivers/net/wireless/silabs/wfx/Makefile
> +++ b/drivers/net/wireless/silabs/wfx/Makefile
> @@ -20,6 +20,6 @@ wfx-y := \
> debug.o
> wfx-$(CONFIG_SPI) += bus_spi.o
> # When CONFIG_MMC == m, append to 'wfx-y' (and not to 'wfx-m')
> -wfx-$(subst m,y,$(CONFIG_MMC)) += bus_sdio.o
> +wfx-$(call always_built_in,$(CONFIG_MMC)) += bus_sdio.o
>
> obj-$(CONFIG_WFX) += wfx.o
> diff --git a/drivers/s390/char/Makefile b/drivers/s390/char/Makefile
> index ce32270082f5..d21086e99528 100644
> --- a/drivers/s390/char/Makefile
> +++ b/drivers/s390/char/Makefile
> @@ -34,7 +34,7 @@ obj-$(CONFIG_SCLP_VT220_TTY) += sclp_vt220.o
>
> obj-$(CONFIG_PCI) += sclp_pci.o
>
> -obj-$(subst m,y,$(CONFIG_ZCRYPT)) += sclp_ap.o
> +obj-$(call always_built_in,$(CONFIG_ZCRYPT)) += sclp_ap.o
>
> obj-$(CONFIG_VMLOGRDR) += vmlogrdr.o
> obj-$(CONFIG_VMCP) += vmcp.o
> diff --git a/drivers/s390/crypto/Makefile b/drivers/s390/crypto/Makefile
> index 22d2db690cd3..e3594486d8f3 100644
> --- a/drivers/s390/crypto/Makefile
> +++ b/drivers/s390/crypto/Makefile
> @@ -4,7 +4,7 @@
> #
>
> ap-objs := ap_bus.o ap_card.o ap_queue.o
> -obj-$(subst m,y,$(CONFIG_ZCRYPT)) += ap.o
> +obj-$(call always_built_in,$(CONFIG_ZCRYPT)) += ap.o
> # zcrypt_api.o and zcrypt_msgtype*.o depend on ap.o
> zcrypt-objs := zcrypt_api.o zcrypt_card.o zcrypt_queue.o
> zcrypt-objs += zcrypt_msgtype6.o zcrypt_msgtype50.o
> diff --git a/net/8021q/Makefile b/net/8021q/Makefile
> index e05d4d7aab35..50b48af58322 100644
> --- a/net/8021q/Makefile
> +++ b/net/8021q/Makefile
> @@ -2,7 +2,7 @@
> #
> # Makefile for the Linux VLAN layer.
> #
> -obj-$(subst m,y,$(CONFIG_VLAN_8021Q)) += vlan_core.o
> +obj-$(call always_built_in,$(CONFIG_VLAN_8021Q)) += vlan_core.o
> obj-$(CONFIG_VLAN_8021Q) += 8021q.o
>
> 8021q-y := vlan.o vlan_dev.o vlan_netlink.o
> diff --git a/net/Makefile b/net/Makefile
> index 6a62e5b27378..94165eb38b65 100644
> --- a/net/Makefile
> +++ b/net/Makefile
> @@ -42,7 +42,7 @@ obj-$(CONFIG_PHONET) += phonet/
> ifneq ($(CONFIG_VLAN_8021Q),)
> obj-y += 8021q/
> endif
> -obj-$(CONFIG_IP_DCCP) += dccp/
> +obj-$(call always_built_in,$(CONFIG_IP_DCCP)) += dccp/
> obj-$(CONFIG_IP_SCTP) += sctp/
> obj-$(CONFIG_RDS) += rds/
> obj-$(CONFIG_WIRELESS) += wireless/
> diff --git a/net/bridge/Makefile b/net/bridge/Makefile
> index 24bd1c0a9a5a..4f3109e170c8 100644
> --- a/net/bridge/Makefile
> +++ b/net/bridge/Makefile
> @@ -12,10 +12,10 @@ bridge-y := br.o br_device.o br_fdb.o br_forward.o br_if.o br_input.o \
>
> bridge-$(CONFIG_SYSFS) += br_sysfs_if.o br_sysfs_br.o
>
> -bridge-$(subst m,y,$(CONFIG_BRIDGE_NETFILTER)) += br_nf_core.o
> +bridge-$(call always_built_in,$(CONFIG_BRIDGE_NETFILTER)) += br_nf_core.o
>
> br_netfilter-y := br_netfilter_hooks.o
> -br_netfilter-$(subst m,y,$(CONFIG_IPV6)) += br_netfilter_ipv6.o
> +br_netfilter-$(call always_built_in,$(CONFIG_IPV6)) += br_netfilter_ipv6.o
> obj-$(CONFIG_BRIDGE_NETFILTER) += br_netfilter.o
>
> bridge-$(CONFIG_BRIDGE_IGMP_SNOOPING) += br_multicast.o br_mdb.o br_multicast_eht.o
> diff --git a/net/dccp/Makefile b/net/dccp/Makefile
> index 5b4ff37bc806..607f6d3dd795 100644
> --- a/net/dccp/Makefile
> +++ b/net/dccp/Makefile
> @@ -17,8 +17,8 @@ dccp-$(CONFIG_IP_DCCP_TFRC_LIB) += ccids/lib/tfrc.o \
> dccp_ipv4-y := ipv4.o
>
> # build dccp_ipv6 as module whenever either IPv6 or DCCP is a module
> -obj-$(subst y,$(CONFIG_IP_DCCP),$(CONFIG_IPV6)) += dccp_ipv6.o
> -dccp_ipv6-y := ipv6.o
> +obj-$(call module_if_any_modular,$(CONFIG_IP_DCCP)$(CONFIG_IPV6)) += dccp_ipv6.o
> +dccp_ipv6-$(call module_if_any_modular,$(CONFIG_IP_DCCP)$(CONFIG_IPV6)) := ipv6.o
>
> obj-$(CONFIG_INET_DCCP_DIAG) += dccp_diag.o
>
> diff --git a/net/ipv6/Makefile b/net/ipv6/Makefile
> index 3036a45e8a1e..b05b0e4668f5 100644
> --- a/net/ipv6/Makefile
> +++ b/net/ipv6/Makefile
> @@ -47,7 +47,7 @@ obj-y += addrconf_core.o exthdrs_core.o ip6_checksum.o ip6_icmp.o
> obj-$(CONFIG_INET) += output_core.o protocol.o \
> ip6_offload.o tcpv6_offload.o exthdrs_offload.o
>
> -obj-$(subst m,y,$(CONFIG_IPV6)) += inet6_hashtables.o
> +obj-$(call always_built_in,$(CONFIG_IPV6)) += inet6_hashtables.o
>
> ifneq ($(CONFIG_IPV6),)
> obj-$(CONFIG_NET_UDP_TUNNEL) += ip6_udp_tunnel.o
> diff --git a/net/l2tp/Makefile b/net/l2tp/Makefile
> index cf8f27071d3f..ff94be92a36e 100644
> --- a/net/l2tp/Makefile
> +++ b/net/l2tp/Makefile
> @@ -8,11 +8,11 @@ obj-$(CONFIG_L2TP) += l2tp_core.o
> CFLAGS_l2tp_core.o += -I$(src)
>
> # Build l2tp as modules if L2TP is M
> -obj-$(subst y,$(CONFIG_L2TP),$(CONFIG_PPPOL2TP)) += l2tp_ppp.o
> -obj-$(subst y,$(CONFIG_L2TP),$(CONFIG_L2TP_IP)) += l2tp_ip.o
> -obj-$(subst y,$(CONFIG_L2TP),$(CONFIG_L2TP_V3)) += l2tp_netlink.o
> -obj-$(subst y,$(CONFIG_L2TP),$(CONFIG_L2TP_ETH)) += l2tp_eth.o
> -obj-$(subst y,$(CONFIG_L2TP),$(CONFIG_L2TP_DEBUGFS)) += l2tp_debugfs.o
> +obj-$(subst Y,$(CONFIG_L2TP),$(subst y,$(CONFIG_L2TP),$(CONFIG_PPPOL2TP))) += l2tp_ppp.o
> +obj-$(subst Y,$(CONFIG_L2TP),$(subst y,$(CONFIG_L2TP),$(CONFIG_L2TP_IP))) += l2tp_ip.o
> +obj-$(subst Y,$(CONFIG_L2TP),$(subst y,$(CONFIG_L2TP),$(CONFIG_L2TP_V3))) += l2tp_netlink.o
> +obj-$(subst Y,$(CONFIG_L2TP),$(subst y,$(CONFIG_L2TP),$(CONFIG_L2TP_ETH))) += l2tp_eth.o
> +obj-$(subst Y,$(CONFIG_L2TP),$(subst y,$(CONFIG_L2TP),$(CONFIG_L2TP_DEBUGFS))) += l2tp_debugfs.o
> ifneq ($(CONFIG_IPV6),)
> -obj-$(subst y,$(CONFIG_L2TP),$(CONFIG_L2TP_IP)) += l2tp_ip6.o
> +obj-$(subst Y,$(CONFIG_L2TP),$(subst y,$(CONFIG_L2TP),$(CONFIG_L2TP_IP))) += l2tp_ip6.o
> endif
> diff --git a/net/netfilter/Makefile b/net/netfilter/Makefile
> index 0f060d100880..a6f65c956b1b 100644
> --- a/net/netfilter/Makefile
> +++ b/net/netfilter/Makefile
> @@ -6,7 +6,7 @@ nf_conntrack-y := nf_conntrack_core.o nf_conntrack_standalone.o nf_conntrack_exp
> nf_conntrack_proto_icmp.o \
> nf_conntrack_extend.o nf_conntrack_acct.o nf_conntrack_seqadj.o
>
> -nf_conntrack-$(subst m,y,$(CONFIG_IPV6)) += nf_conntrack_proto_icmpv6.o
> +nf_conntrack-$(call always_built_in,$(CONFIG_IPV6)) += nf_conntrack_proto_icmpv6.o
> nf_conntrack-$(CONFIG_NF_CONNTRACK_TIMEOUT) += nf_conntrack_timeout.o
> nf_conntrack-$(CONFIG_NF_CONNTRACK_TIMESTAMP) += nf_conntrack_timestamp.o
> nf_conntrack-$(CONFIG_NF_CONNTRACK_EVENTS) += nf_conntrack_ecache.o
> diff --git a/net/netlabel/Makefile b/net/netlabel/Makefile
> index 5a46381a64e7..8052bd8e7af8 100644
> --- a/net/netlabel/Makefile
> +++ b/net/netlabel/Makefile
> @@ -13,4 +13,4 @@ obj-y += netlabel_mgmt.o
> # protocol modules
> obj-y += netlabel_unlabeled.o
> obj-y += netlabel_cipso_v4.o
> -obj-$(subst m,y,$(CONFIG_IPV6)) += netlabel_calipso.o
> +obj-$(call always_built_in,$(CONFIG_IPV6)) += netlabel_calipso.o
> diff --git a/net/sctp/Makefile b/net/sctp/Makefile
> index e845e4588535..683a345f3626 100644
> --- a/net/sctp/Makefile
> +++ b/net/sctp/Makefile
> @@ -21,4 +21,4 @@ sctp-$(CONFIG_SCTP_DBG_OBJCNT) += objcnt.o
> sctp-$(CONFIG_PROC_FS) += proc.o
> sctp-$(CONFIG_SYSCTL) += sysctl.o
>
> -sctp-$(subst m,y,$(CONFIG_IPV6)) += ipv6.o
> +sctp-$(call always_built_in,$(CONFIG_IPV6)) += ipv6.o
> diff --git a/scripts/Kbuild.include b/scripts/Kbuild.include
> index 8042c067312e..701bbb499427 100644
> --- a/scripts/Kbuild.include
> +++ b/scripts/Kbuild.include
> @@ -188,6 +188,21 @@ cmd_and_fixdep = \
> # and if so will execute $(rule_foo).
> if_changed_rule = $(if $(if-changed-cond),$(rule_$(1)),@:)
>
> +# Usage. $(call always-built-in,CONFIG_VAR)
> +# Expands to y if CONFIG_VAR is m, suitable for always-built-in pieces
> +# of things that otherwise may be modular.
> +always_built_in = $(subst M,Y,$(subst m,y,$(1)))
> +
> +# Usage, obj-$(call module_if_any_modular,$(CONCATENATED)$(CONFIG)$(VARS))
> +# Expands to m if any of the concatenated config vars are m, otherwise
> +# y if any of them are y, otherwise n
> +module_if_any_modular = $(strip \
> + $(if $(findstring m,$(subst M,m,$(1))), \
> + $(if $(findstring M,$(1)),M,m), \
> + $(if $(findstring y,$(subst Y,y,$(1))), \
> + $(if $(findstring Y,$(1)),Y,y), \
> + $(if $(findstring N,$(1)),N,n))))
> +
> ###
> # why - tell why a target got built
> # enabled by make V=2
> --
> 2.38.0.266.g481848f278
>


--
Best Regards
Masahiro Yamada

2023-04-07 23:33:54

by Josh Poimboeuf

[permalink] [raw]
Subject: Re: [PATCH modules-next v10 00/13] kallsyms: reliable symbol->address lookup with /proc/kallmodsyms

On Mon, Dec 05, 2022 at 04:31:44PM +0000, Nick Alcock wrote:
> The whole point of symbols is that their names are unique: you can look up a
> symbol and get back a unique address, and vice versa. Alas, because
> /proc/kallsyms (rightly) reports all symbols, even hidden ones, it does not
> really satisfy this requirement. Large numbers of symbols are duplicated
> many times (just search for __list_del_entry!), and while usually these are
> just out-of-lined things defined in header files and thus all have the same
> implementation, it does make it needlessly hard to figure out which one is
> which in stack dumps, when tracing, and such things. Some configuration
> options make things much worse: my test make allyesconfig runs introduced
> thousands of text symbols named _sub_I_65535_1, one per compiler-generated
> object file, and it was fairly easy to make them appear in ftrace output.
>
> Right now the kernel has no way at all to tell such symbols apart, and nor
> has the user: their address differs and that's all. Which module did they
> come from? Which object file? We don't know. Figuring out which is which
> when tracing needs a combination of guesswork and luck, and if there are
> thousands of them that's not a pleasant prospect. In discussions at LPC it
> became clear that this is not just annoying me but Steve Rostedt and others,
> so it's probably desirable to fix this.
>
> It turns out that the linker, and the kernel build system, can be made to
> give us everything we need to resolve this once and for all. This series
> provides a new /proc/kallmodsyms which is like /proc/kallsyms except that it
> annotates every (textual) symbol which comes from a built-in kernel module
> with the module's name, in square brackets: if a symbol is used by multiple
> modules, it gets [multiple] [names]; if a symbol is still ambiguous it gets
> a cut-down {object file name}; the combination of symbol, [module] [names]
> and {object file name} is unique (with one minor exception: the arm64 nvhe
> module is pre-linked with ld -r, causing all symbols in it to appear to come
> from the same object file: if it was reworked to use thin archives this
> problem would go away).

Hi Nick,

Sorry for jumping in late on an old patch set. I just saw the LWN
article about the MODULE_LICENSE() patches and I have some comments
about duplicate symbols and a question about the motivation for this
patch set.

For livepatch we have a solution for disambiguating duplicate local
symbols called "sympos". It works (for now) but there are some cases
(like LTO) where it falls apart and it may not be the best long term
solution.

The function granularity KASLR (fgkaslr) patches proposed a potentially
better option: use the GNU linker -zunique_symbols flag which renames
all duplicates to have unique names across the entire linked object.

There are other components which also struggle with duplicate symbols:
ftrace, kprobes, BPF, etc. It would be good to come up with a kallsyms
solution that works for everybody.

Anyway, I was nodding along with the above cover letter until I got to
the third paragraph.

A "built-in kernel module" is not actually a module, as it's built in to
vmlinux. I suspect the point is that if you rebuild with a different
config, it might become a module. But many other changes could also
occur with a changed config, including changed inlining decisions and
GCC IPA optimization function renaming, in which case the symbol might
no longer exist with the new config.

Also I'm confused what it means for a symbol to be "used by multiple
modules". If the same TU or inline symbol is linked into two modules,
it will be loaded twice at two different addresses, and the
implementations could even differ.

It sounds like there are two problems being conflated:

1) how to uniquely identify symbols in the current kernel

For this, all we really need is file+sym.

Or, enable -zunique-symbols in the linker.

2) how to uniquely identify symbols across multiple kernels/configs

This seems much trickier, as much can change across kernels and
configs, including compiler inlining and naming decisions, not to
mention actual code changes.

The problems are related, but distinct.

#2 seems significantly harder to implement properly.

Would solving #1 give you most of what you need?

Based on the difficulty of #2, it really needs a proper justification.
I didn't see that in either of the patch sets.

Can you share more details about what specific problem needs solved and
why? And how this would be used? Examples would be helpful.

The article linked to this brief explanation [1], but that doesn't
clarify why "distinct notation used by users for things in named
modules" would be important.

Is there a reason the user can't just use whatever notation is
appropriate for their specific kernel? Or, once we have #1, couldn't
tooling do an intermediate translation?

[1] https://lwn.net/ml/linux-kernel/[email protected]/

--
Josh

2023-04-10 13:10:47

by Joe Lawrence

[permalink] [raw]
Subject: Re: [PATCH modules-next v10 00/13] kallsyms: reliable symbol->address lookup with /proc/kallmodsyms

On 4/7/23 19:21, Josh Poimboeuf wrote:
> On Mon, Dec 05, 2022 at 04:31:44PM +0000, Nick Alcock wrote:
>> The whole point of symbols is that their names are unique: you can look up a
>> symbol and get back a unique address, and vice versa. Alas, because
>> /proc/kallsyms (rightly) reports all symbols, even hidden ones, it does not
>> really satisfy this requirement. Large numbers of symbols are duplicated
>> many times (just search for __list_del_entry!), and while usually these are
>> just out-of-lined things defined in header files and thus all have the same
>> implementation, it does make it needlessly hard to figure out which one is
>> which in stack dumps, when tracing, and such things. Some configuration
>> options make things much worse: my test make allyesconfig runs introduced
>> thousands of text symbols named _sub_I_65535_1, one per compiler-generated
>> object file, and it was fairly easy to make them appear in ftrace output.
>>
>> Right now the kernel has no way at all to tell such symbols apart, and nor
>> has the user: their address differs and that's all. Which module did they
>> come from? Which object file? We don't know. Figuring out which is which
>> when tracing needs a combination of guesswork and luck, and if there are
>> thousands of them that's not a pleasant prospect. In discussions at LPC it
>> became clear that this is not just annoying me but Steve Rostedt and others,
>> so it's probably desirable to fix this.
>>
>> It turns out that the linker, and the kernel build system, can be made to
>> give us everything we need to resolve this once and for all. This series
>> provides a new /proc/kallmodsyms which is like /proc/kallsyms except that it
>> annotates every (textual) symbol which comes from a built-in kernel module
>> with the module's name, in square brackets: if a symbol is used by multiple
>> modules, it gets [multiple] [names]; if a symbol is still ambiguous it gets
>> a cut-down {object file name}; the combination of symbol, [module] [names]
>> and {object file name} is unique (with one minor exception: the arm64 nvhe
>> module is pre-linked with ld -r, causing all symbols in it to appear to come
>> from the same object file: if it was reworked to use thin archives this
>> problem would go away).
>
> Hi Nick,
>
> Sorry for jumping in late on an old patch set. I just saw the LWN
> article about the MODULE_LICENSE() patches and I have some comments
> about duplicate symbols and a question about the motivation for this
> patch set.
>
> For livepatch we have a solution for disambiguating duplicate local
> symbols called "sympos". It works (for now) but there are some cases
> (like LTO) where it falls apart and it may not be the best long term
> solution.
>
> The function granularity KASLR (fgkaslr) patches proposed a potentially
> better option: use the GNU linker -zunique_symbols flag which renames
> all duplicates to have unique names across the entire linked object.
>

And IIRC, that idea was eventually dropped. Fāng-ruì Sòng posted a few
reasons why -zunique-symbols wouldn't be a great solution [1]

[1]
https://lore.kernel.org/lkml/CAFP8O3K1mkiCGMTEeuSifZtr2piHsKTjP5TOA25nqpv2SrbzYQ@mail.gmail.com/

<file + symbol> was suggested instead, but I'm not 100% if that ever
became the preferred solution.

> There are other components which also struggle with duplicate symbols:
> ftrace, kprobes, BPF, etc. It would be good to come up with a kallsyms
> solution that works for everybody.
>
> Anyway, I was nodding along with the above cover letter until I got to
> the third paragraph.
>
> A "built-in kernel module" is not actually a module, as it's built in to
> vmlinux. I suspect the point is that if you rebuild with a different
> config, it might become a module. But many other changes could also
> occur with a changed config, including changed inlining decisions and
> GCC IPA optimization function renaming, in which case the symbol might
> no longer exist with the new config.
>
> Also I'm confused what it means for a symbol to be "used by multiple
> modules". If the same TU or inline symbol is linked into two modules,
> it will be loaded twice at two different addresses, and the
> implementations could even differ.
>
> It sounds like there are two problems being conflated:
>
> 1) how to uniquely identify symbols in the current kernel
>
> For this, all we really need is file+sym.
>
> Or, enable -zunique-symbols in the linker.
>
> 2) how to uniquely identify symbols across multiple kernels/configs
>
> This seems much trickier, as much can change across kernels and
> configs, including compiler inlining and naming decisions, not to
> mention actual code changes.
>
> The problems are related, but distinct.
>
> #2 seems significantly harder to implement properly.
>
> Would solving #1 give you most of what you need?
>
> Based on the difficulty of #2, it really needs a proper justification.
> I didn't see that in either of the patch sets.
>
> Can you share more details about what specific problem needs solved and
> why? And how this would be used? Examples would be helpful.
>
> The article linked to this brief explanation [1], but that doesn't
> clarify why "distinct notation used by users for things in named
> modules" would be important.
>
> Is there a reason the user can't just use whatever notation is
> appropriate for their specific kernel? Or, once we have #1, couldn't
> tooling do an intermediate translation?
>
> [1] https://lwn.net/ml/linux-kernel/[email protected]/
>

--
Joe

2023-04-24 19:49:08

by Luis Chamberlain

[permalink] [raw]
Subject: Re: [PATCH modules-next v10 00/13] kallsyms: reliable symbol->address lookup with /proc/kallmodsyms

On Fri, Apr 07, 2023 at 04:21:18PM -0700, Josh Poimboeuf wrote:
> Anyway, I was nodding along with the above cover letter until I got to
> the third paragraph.
>
> A "built-in kernel module" is not actually a module, as it's built in to
> vmlinux. I suspect the point is that if you rebuild with a different
> config, it might become a module. But many other changes could also
> occur with a changed config, including changed inlining decisions and
> GCC IPA optimization function renaming, in which case the symbol might
> no longer exist with the new config.

Yes it does not matter, for his tooling effort it was just to be able
to map a possible module to a symbol so tooling can display this to
disambiguate.

> Also I'm confused what it means for a symbol to be "used by multiple
> modules". If the same TU or inline symbol is linked into two modules,
> it will be loaded twice at two different addresses, and the
> implementations could even differ.

He just wants to be able to map if a symbol with the same name but
different addresses is due to a built-in or a module declaration of
the same symbol so it can use it.

> It sounds like there are two problems being conflated:
>
> 1) how to uniquely identify symbols in the current kernel
>
> For this, all we really need is file+sym.
>
> Or, enable -zunique-symbols in the linker.
>
> 2) how to uniquely identify symbols across multiple kernels/configs
>
> This seems much trickier, as much can change across kernels and
> configs, including compiler inlining and naming decisions, not to
> mention actual code changes.
>
> The problems are related, but distinct.
>
> #2 seems significantly harder to implement properly.
>
> Would solving #1 give you most of what you need?

I'm not nick but my reading of his goals is that if you peg a
"possible_module" prefix or postfix or whatever, then yes.

For 2) I think it would be good to see if one could just force Kconfig
tristate to add -DPOSSIBLE_MODULE, that would be an easier approach
than the possible-obj-m thing [0] I had suggested last

[0] https://lore.kernel.org/all/Y/[email protected]/

Luis

2023-04-25 08:31:17

by Petr Mladek

[permalink] [raw]
Subject: Re: [PATCH modules-next v10 00/13] kallsyms: reliable symbol->address lookup with /proc/kallmodsyms

On Mon 2023-04-24 12:47:39, Luis Chamberlain wrote:
> On Fri, Apr 07, 2023 at 04:21:18PM -0700, Josh Poimboeuf wrote:
> > Anyway, I was nodding along with the above cover letter until I got to
> > the third paragraph.
> >
> > A "built-in kernel module" is not actually a module, as it's built in to
> > vmlinux. I suspect the point is that if you rebuild with a different
> > config, it might become a module. But many other changes could also
> > occur with a changed config, including changed inlining decisions and
> > GCC IPA optimization function renaming, in which case the symbol might
> > no longer exist with the new config.
>
> Yes it does not matter, for his tooling effort it was just to be able
> to map a possible module to a symbol so tooling can display this to
> disambiguate.

Note that the same symbol name might be used many times even within
one module. The module might be linked from more .o files. And
more .o files might have a local symbol with the same name.

I think that the best solution is to associate the symbol with
the file name and line. These is very useful information in general.

Best Regards,
Petr

2023-05-08 22:38:24

by Steven Rostedt

[permalink] [raw]
Subject: Re: [PATCH modules-next v10 00/13] kallsyms: reliable symbol->address lookup with /proc/kallmodsyms

This topic came up at LSFMM, presented by Jiri.

I'm Cc'ing this email to the BPF mailing list.

-- Steve


On Mon, 5 Dec 2022 16:31:44 +0000
Nick Alcock <[email protected]> wrote:

> The kallmodsyms patch series was originally posted in Nov 2019, and the thread
> (https://lore.kernel.org/linux-kbuild/[email protected]/t/#u)
> shows review comments, questions, and feedback from interested parties.
> Most recent posting: <https://lore.kernel.org/linux-modules/[email protected]/T/#t>.
>
> All review comments have been satisfied, as far as I know: in particular
> Yamada's note about translation units that are shared between built-in
> modules is satisfied with a better representation which is also much, much
> smaller, and we are no longer using modules_thick.builtin but Luis's new
> modules.builtin.objs.
>
> A kernel tree containing this series alone:
> https://github.com/oracle/dtrace-linux-kernel kallmodsyms/6.1-rc4-modules-next
>
>
> The whole point of symbols is that their names are unique: you can look up a
> symbol and get back a unique address, and vice versa. Alas, because
> /proc/kallsyms (rightly) reports all symbols, even hidden ones, it does not
> really satisfy this requirement. Large numbers of symbols are duplicated
> many times (just search for __list_del_entry!), and while usually these are
> just out-of-lined things defined in header files and thus all have the same
> implementation, it does make it needlessly hard to figure out which one is
> which in stack dumps, when tracing, and such things. Some configuration
> options make things much worse: my test make allyesconfig runs introduced
> thousands of text symbols named _sub_I_65535_1, one per compiler-generated
> object file, and it was fairly easy to make them appear in ftrace output.
>
> Right now the kernel has no way at all to tell such symbols apart, and nor
> has the user: their address differs and that's all. Which module did they
> come from? Which object file? We don't know. Figuring out which is which
> when tracing needs a combination of guesswork and luck, and if there are
> thousands of them that's not a pleasant prospect. In discussions at LPC it
> became clear that this is not just annoying me but Steve Rostedt and others,
> so it's probably desirable to fix this.
>
> It turns out that the linker, and the kernel build system, can be made to
> give us everything we need to resolve this once and for all. This series
> provides a new /proc/kallmodsyms which is like /proc/kallsyms except that it
> annotates every (textual) symbol which comes from a built-in kernel module
> with the module's name, in square brackets: if a symbol is used by multiple
> modules, it gets [multiple] [names]; if a symbol is still ambiguous it gets
> a cut-down {object file name}; the combination of symbol, [module] [names]
> and {object file name} is unique (with one minor exception: the arm64 nvhe
> module is pre-linked with ld -r, causing all symbols in it to appear to come
> from the same object file: if it was reworked to use thin archives this
> problem would go away).
>
> The object file names are cut down to save space: we store only the shortest
> suffix needed to distinguish symbols from each other. It's fairly rare even
> to see two/level names, let alone three/level/ones. We also save even more
> space by annotating every symbol in a given object file with the object file
> name if we annotate any of them.
>
> We also add new fields that let you get at this new info in the kallsyms
> iterator.
>
> In brief we do this by mapping from address ranges to object files (with
> assistance from the linker map file), then mapping from those object files
> to built-in kernel modules and object file names. Because the number of
> object files is much smaller than the number of symbols, because we fuse
> address range and object file entries together if possible, and because we
> don't even store object file names unless we need to, this is a fairly
> efficient representation, even with a bit of extra complexity to allow
> object files to be in more than one module at once.
>
> The size impact of all of this is minimal: in testing, vmlinux grew by 16632
> bytes, and the compressed vmlinux only grew by 12544 bytes (about .1% of a
> 10MiB kernel): though this is very configuration-dependent, it seems likely
> to scale roughly with the kernel as a whole.
>
> This is all controlled by a new config parameter CONFIG_KALLMODSYMS, which when
> set results in output in /proc/kallmodsyms that looks like this:
>
> ffffffff97606e50 t not_visible
> ffffffff97606e70 T perf_msr_probe
> ffffffff97606f80 t test_msr [rapl]
> ffffffffa6007350 t rapl_pmu_event_stop [rapl]
> ffffffffa6007440 t rapl_pmu_event_del [rapl]
> ffffffffa6007460 t rapl_hrtimer_handle [rapl]
> ffffffffa6007500 t rapl_pmu_event_read [rapl]
> ffffffffa6007520 t rapl_pmu_event_init [rapl]
> ffffffffa6007630 t rapl_cpu_offline [rapl]
> ffffffffa6007710 t amd_pmu_event_map {core.o}
> ffffffffa6007750 t amd_pmu_add_event {core.o}
> ffffffffa6007760 t amd_put_event_constraints_f17h {core.o}
>
> The modular symbols are notated as [rapl] even if rapl is built into the
> kernel. Further, at least one symbol nottated as {core.o} would have been
> ambiguous without that notation. If we look a little further down, we see:
>
> ffffffff97607a70 t cmask_show {core.o}
> ffffffff97607ab0 t inv_show {core.o}
> ffffffff97607ae0 t edge_show {core.o}
> ffffffff97607b10 t umask_show {core.o}
> ffffffff97607b40 t event_show {core.o}
>
> where event_show in particular is highly ambiguous and appears in many
> object files, all of which are now notated with different {object file
> names}.
>
> Further down, we see what happens when object files are reused by multiple
> modules, all of which are built in to the kernel, and some of which contain
> symbols that are ambiguously-named even within that set of modules:
>
> ffffffff97d7aed0 t liquidio_pcie_mmio_enabled [liquidio]
> ffffffff97d7aef0 t liquidio_pcie_resume [liquidio]
> ffffffff97d7af00 t liquidio_ptp_adjtime [liquidio]
> ffffffff97d7af50 t liquidio_ptp_enable [liquidio]
> ffffffff97d7af70 t liquidio_get_stats64 [liquidio]
> ffffffff97d7b0f0 t liquidio_fix_features [liquidio]
> ffffffff97d7b1c0 t liquidio_get_port_parent_id [liquidio]
> [...]
> ffffffff97d824c0 t lio_vf_rep_modinit [liquidio]
> ffffffff97d824f0 t lio_vf_rep_modexit [liquidio]
> ffffffff97d82520 t lio_ethtool_get_channels [liquidio] [liquidio_vf]
> ffffffff97d82600 t lio_ethtool_get_ringparam [liquidio] [liquidio_vf]
> ffffffff97d826a0 t lio_get_msglevel [liquidio] [liquidio_vf]
> ffffffff97d826c0 t lio_vf_set_msglevel [liquidio] [liquidio_vf]
> ffffffff97d826e0 t lio_get_pauseparam [liquidio] [liquidio_vf]
> ffffffff97d82710 t lio_get_ethtool_stats [liquidio] [liquidio_vf]
> ffffffff97d82e70 t lio_vf_get_ethtool_stats [liquidio] [liquidio_vf]
> [...]
> ffffffff97d91a80 t cn23xx_vf_mbox_thread [liquidio] [liquidio_vf] {cn23xx_vf_device.o}
> ffffffff97d91aa0 t cpumask_weight.constprop.0 [liquidio] [liquidio_vf] {cn23xx_vf_device.o}
> ffffffff97d91ac0 t cn23xx_vf_msix_interrupt_handler [liquidio] [liquidio_vf] {cn23xx_vf_device.o}
> ffffffff97d91bd0 t cn23xx_vf_get_oq_ticks [liquidio] [liquidio_vf] {cn23xx_vf_device.o}
> ffffffff97d91c00 t cn23xx_vf_ask_pf_to_do_flr [liquidio] [liquidio_vf] {cn23xx_vf_device.o}
> ffffffff97d91c70 t cn23xx_octeon_pfvf_handshake [liquidio] [liquidio_vf] {cn23xx_vf_device.o}
> ffffffff97d91e20 t cn23xx_setup_octeon_vf_device [liquidio] [liquidio_vf] {cn23xx_vf_device.o}
> ffffffff97d92060 t octeon_mbox_read [liquidio] [liquidio_vf]
> ffffffff97d92230 t octeon_mbox_write [liquidio] [liquidio_vf]
> [...]
> ffffffff97d946b0 t octeon_alloc_soft_command_resp [liquidio] [liquidio_vf]
> ffffffff97d947e0 t octnet_send_nic_data_pkt [liquidio] [liquidio_vf]
> ffffffff97d94820 t octnet_send_nic_ctrl_pkt [liquidio] [liquidio_vf]
> ffffffff97d94ab0 t liquidio_get_stats64 [liquidio_vf]
> ffffffff97d94c10 t liquidio_fix_features [liquidio_vf]
> ffffffff97d94cd0 t wait_for_pending_requests [liquidio_vf]
>
> Like /proc/kallsyms, the output is sorted by address, so keeps the curious
> property of /proc/kallsyms that symbols may appear repeatedly with different
> addresses: but now, unlike in /proc/kallsyms, we can see that those symbols
> appear repeatedly because they are *different symbols* that ultimately
> belong to different modules or different object files, all of which are
> built in to the kernel.
>
> Note that kernel symbols for built-in modules will probably appear
> interspersed with other symbols that are part of different modules and
> non-modular always-built-in symbols, which, as usual, have no
> square-bracketed module denotation (though they might have an {object file
> name}.
>
> As with /proc/kallsyms, non-root usage produces addresses that are all zero.
>
> Tested with a make allyesconfig and allmodconfig, and with and without
> CONFIG_X86_KERNEL_IBT.
>
> Limitations:
>
> - this approach only works for textual symbols (and weak ones). I don't
> see any way to make it work for data symbols etc: except for initialized
> data they don't really have corresponding object files at all and they
> tend to get merged together anyway.
>
> - Compiling with clang LTO is untested. Compiling with X86 IBT now works,
> but .cold-partitioned symbols are not attributed to any objfiles right
> now (currently, this results in no conflicts on a make allyesconfig
> build, so it's harmless).
>
> - Non-built-in modules can also have ambiguous symbols in them in different
> input object files: they aren't handled yet because kallsyms never runs
> over modules to create the necessary sections. This is fixable, but it's
> probably best handled in another patch series. (kallsyms would need to
> do much less work for modules: only the sections introduced by this patch
> series would need emission at all, and no [module] notations would be
> needed, only {objfile}.)
>
> - Section start/end symbols necessarily lie on the boundary between object
> files, so are sometimes misreported as being in the wrong object file or
> module. This is unlikely to be too troublesome for these symbols in
> particular, but if anyone can figure out a way to fix this I'd be happy
> to do it.
>
> - There is no BPF iterator support yet (it's just a matter of adding it
> if needed).
>
> The commits in this series all have reviewed-by tags: they're all from
> internal reviews, so please ignore them.
>
> Differences from v9, early November 2022:
>
> - Rework to use Luis Chamberlain's modules.builtin.objs rather than a
> tristate-generated "modules_thick.builtin". Keep the iterator over
> modules_thick.builtin, but rename it to scripts/modules_builtin.c and
> make it more robust against strange lines in modules.builtin.objs,
> such as lines with no colon in.
> - Rework the old modules_thick.builtin stuff into a "tristate checker"
> which warns about source files that contain MODULE_LICENSE for which
> the corresponding Kconfig symbol is of type 'bool' rather than
> 'tristate'. It no longer runs unless requested, so doesn't slow
> the build down with a big recursion across the whole source tree.
> - Fix up a bunch of places where the tristate checker (and the old
> modules_thick.builtin and modules.builtin generators) gave the wrong
> answers, usually considering things to be modules that actually
> unconditionally built in. (16 makefiles touched.)
> - Eliminate MODULE_LICENSE/AUTHOR/DESCRIPTION from a bunch of things
> that cannot actually be modules: aarch64 and x86_64 are now clean,
> other arches not checked. Verified with make allmodconfig on both
> arches. (189 not-actually-modules touched.)
> - Use the CONFIG_VMLINUX_MAP machinery rather than generating a whole
> second linker mapfile.
> - Add (in a separate commit since it is largely conceptually separate)
> support for the ld -r linking used by CONFIG_X86_KERNEL_IBT.
> - Add a special kallsyms build-time warning for ambiguous symbols that
> came from the same object file: note that they are probably the
> result of ld -r.
> - When lengthening shortened objfile names to resolve an ambiguity,
> always lengthen the name of the objfile with the longer (unshortened)
> length, fixing ambiguous objfiles with names which are substrings of
> other objfiles' names.
> - Fix a bug which could cause inflooping when outputting the
> .kallsyms_mod_objnames section.
> - Rebase atop modules-next.
>
> Differences from v8, February 2022:
>
> - Add object file name handling, emitting only those object names needed to
> disambiguate symbols, shortening them as much as possible compatible with
> that.
> - Rename .kallsyms_module_names to .kallsyms_mod_objnames now that it
> contains object file names too.
> - Fix a bug in optimize_obj2mod that prevented proper reuse of module names
> for object files appearing in both multimodule modules and single-module
> modules: saves a few KiB more, often more than the space increase due to
> object file name handling.
> - Rebased atop v6.1-rc2: move modules_thick.builtin generation into
> the top-level Kbuild accordingly, and adjust to getopt_long use in
> scripts/kallsyms.
> - Significant revisions to the cover letter.
> - Add proof-of-concept kallmodsyms module support to perf.
> - (This ping) confirmed that series applies atop v6.1-rc4 without
> further changes.
>
> Differences from v7, December 2021:
>
> - Adjust for changes in the v5.17 merge window. Adjust a few commit
> messages and shrink the cover letter.
> - Drop the symbol-size patch, probably better done from userspace.
>
> Differences from v6, November 2021:
>
> - Adjust for rewrite of confdata machinery in v5.16 (tristate.conf
> handling is now more of a rewrite than a reversion)
>
> Differences from v5, October 2021:
>
> - Fix generation of mapfiles under UML
>
> Differences from v4, September 2021:
>
> - Fix building of tristate.conf if missing (usually concealed by the
> syncconfig being run for other reasons, but not always: the kernel
> test robot spotted it).
> - Forward-port atop v5.15-rc3.
>
> Differences from v3, August 2021:
>
> - Fix a kernel test robot warning in get_ksymbol_core (possible
> use of uninitialized variable if kallmodsyms was wanted but
> kallsyms_module_offsets was not present, which is most unlikely).
>
> Differences from v2, June 2021:
>
> - Split the series up. In particular, the size impact of the table
> optimizer is now quantified, and the symbol-size patch is split out and
> turned into an RFC patch, with the /proc/kallmodsyms format before that
> patch lacking a size column. Some speculation on how to make the symbol
> sizes less space-wasteful is added (but not yet implemented).
>
> - Drop a couple of unnecessary #includes, one unnecessarily exported
> symbol, and a needless de-staticing.
>
> Differences from v1, in 2019:
>
> - Move from a straight symbol->module name mapping to a mapping from
> address-range to TU to module name list, bringing major space savings
> over the previous approach and support for object files used by many
> built-in modules at the same time, at the cost of a slightly more complex
> approach (unavoidably so, I think, given that we have to merge three data
> sources together: the link map in .tmp_vmlinux.ranges, the nm output on
> stdin, and the mapping from TU name to module names in
> modules_thick.builtin).
>
> We do opportunistic merging of TUs if they cite the same modules and
> reuse module names where doing so is simple: see optimize_obj2mod below.
> I considered more extensive searches for mergeable entries and more
> intricate encodings of the module name list allowing TUs that are used by
> overlapping sets of modules to share their names, but such modules are
> rare enough (and such overlapping sharings are vanishingly rare) that it
> seemed likely to save only a few bytes at the cost of much more
> hard-to-test code. This is doubly true now that the tables needed are
> only a few kilobytes in length.
>
> Signed-off-by: Nick Alcock <[email protected]>
> Signed-off-by: Eugene Loh <[email protected]>
> Reviewed-by: Kris Van Hees <[email protected]>
>
> Luis Chamberlain (1):
> kbuild: add modules.builtin.objs
>
> Nick Alcock (12):
> kbuild: bring back tristate.conf
> kbuild: add tristate checker
> kbuild: fix up substitutions in makefiles to allow for tristate
> checker
> kbuild: remove MODULE_LICENSE/AUTHOR/DESCRIPTION in non-modules
> build: add a simple iterator over modules.builtin.objs
> kbuild: generate an address ranges map at vmlinux link time
> kbuild: make address ranges map work with IBT
> kallsyms: introduce sections needed to map symbols to built-in modules
> kallsyms: optimize .kallsyms_modules*
> kallsyms: distinguish text symbols fully using object file names
> kallsyms: add /proc/kallmodsyms for text symbol disambiguation
> perf: proof-of-concept kallmodsyms support
>
> .gitignore | 3 +-
> Documentation/dontdiff | 4 +-
> Documentation/kbuild/kbuild.rst | 5 +
> Documentation/kbuild/kconfig.rst | 5 +
> Makefile | 35 +-
> arch/x86/crypto/blake2s-glue.c | 1 -
> arch/x86/mm/debug_pagetables.c | 3 -
> crypto/asymmetric_keys/asymmetric_type.c | 1 -
> drivers/Makefile | 2 +-
> .../accessibility/braille/braille_console.c | 4 -
> drivers/amba/tegra-ahb.c | 3 -
> drivers/android/binder.c | 1 -
> drivers/bus/arm-cci.c | 2 -
> drivers/bus/arm-integrator-lm.c | 3 -
> drivers/bus/bt1-apb.c | 3 -
> drivers/bus/bt1-axi.c | 3 -
> drivers/bus/imx-weim.c | 3 -
> drivers/bus/intel-ixp4xx-eb.c | 3 -
> drivers/bus/qcom-ebi2.c | 3 -
> drivers/bus/qcom-ssc-block-bus.c | 3 -
> drivers/bus/simple-pm-bus.c | 3 -
> drivers/clk/bcm/clk-bcm2835-aux.c | 3 -
> drivers/clk/bcm/clk-bcm2835.c | 3 -
> drivers/clk/clk-bm1880.c | 3 -
> drivers/clk/clk-fixed-mmio.c | 3 -
> drivers/clk/clk-fsl-sai.c | 3 -
> drivers/clk/hisilicon/clk-hi3559a.c | 2 -
> drivers/clk/microchip/clk-mpfs-ccc.c | 3 -
> drivers/clk/microchip/clk-mpfs.c | 5 -
> drivers/clk/renesas/rcar-usb2-clock-sel.c | 2 -
> drivers/clk/renesas/renesas-cpg-mssr.c | 2 -
> drivers/clk/renesas/rzg2l-cpg.c | 2 -
> drivers/clocksource/em_sti.c | 3 -
> drivers/clocksource/sh_cmt.c | 3 -
> drivers/clocksource/sh_mtu2.c | 3 -
> drivers/clocksource/sh_tmu.c | 3 -
> drivers/clocksource/timer-stm32-lp.c | 2 -
> drivers/clocksource/timer-tegra186.c | 3 -
> drivers/clocksource/timer-ti-dm.c | 3 -
> drivers/cpufreq/freq_table.c | 3 -
> drivers/cpufreq/intel_pstate.c | 3 -
> drivers/cpufreq/tegra124-cpufreq.c | 3 -
> drivers/dma-buf/heaps/cma_heap.c | 2 -
> drivers/dma-buf/heaps/system_heap.c | 1 -
> drivers/dma-buf/udmabuf.c | 2 -
> drivers/dma/ep93xx_dma.c | 3 -
> drivers/dma/ipu/ipu_idmac.c | 3 -
> drivers/dma/mv_xor_v2.c | 2 -
> drivers/dma/s3c24xx-dma.c | 3 -
> drivers/dma/sh/shdma-base.c | 3 -
> drivers/dma/stm32-dmamux.c | 4 -
> drivers/dma/stm32-mdma.c | 4 -
> drivers/edac/altera_edac.c | 3 -
> drivers/firmware/broadcom/bcm47xx_nvram.c | 1 -
> drivers/firmware/imx/imx-scu.c | 3 -
> drivers/firmware/imx/scu-pd.c | 3 -
> drivers/gpio/gpio-aspeed-sgpio.c | 2 -
> drivers/gpio/gpio-imx-scu.c | 3 -
> drivers/gpio/gpio-mxs.c | 6 -
> drivers/gpio/gpio-rda.c | 3 -
> drivers/gpu/drm/drm_mipi_dsi.c | 3 -
> drivers/hv/Makefile | 2 +-
> drivers/hwspinlock/hwspinlock_core.c | 3 -
> drivers/interconnect/core.c | 3 -
> drivers/iommu/sun50i-iommu.c | 4 -
> drivers/irqchip/irq-al-fic.c | 3 -
> drivers/irqchip/irq-ls-scfg-msi.c | 3 -
> drivers/irqchip/irq-mbigen.c | 4 -
> drivers/irqchip/irq-mchp-eic.c | 3 -
> drivers/irqchip/irq-mvebu-pic.c | 3 -
> drivers/irqchip/irq-renesas-intc-irqpin.c | 3 -
> drivers/irqchip/irq-renesas-irqc.c | 3 -
> drivers/irqchip/irq-renesas-rza1.c | 3 -
> drivers/irqchip/irq-renesas-rzg2l.c | 3 -
> drivers/irqchip/irq-sl28cpld.c | 3 -
> drivers/irqchip/irq-ti-sci-inta.c | 3 -
> drivers/irqchip/irq-ti-sci-intr.c | 3 -
> drivers/leds/leds-asic3.c | 3 -
> drivers/mailbox/rockchip-mailbox.c | 4 -
> drivers/mailbox/zynqmp-ipi-mailbox.c | 3 -
> drivers/memory/bt1-l2-ctl.c | 3 -
> drivers/memory/da8xx-ddrctl.c | 3 -
> drivers/memory/fsl_ifc.c | 3 -
> drivers/memory/mvebu-devbus.c | 3 -
> drivers/memory/tegra/mc.c | 3 -
> drivers/memory/tegra/tegra186-emc.c | 3 -
> drivers/mfd/88pm860x-core.c | 3 -
> drivers/mfd/altera-sysmgr.c | 3 -
> drivers/mfd/bcm2835-pm.c | 3 -
> drivers/mfd/da903x.c | 4 -
> drivers/mfd/da9052-core.c | 3 -
> drivers/mfd/da9052-i2c.c | 3 -
> drivers/mfd/da9052-spi.c | 3 -
> drivers/mfd/da9055-core.c | 3 -
> drivers/mfd/da9055-i2c.c | 3 -
> drivers/mfd/ezx-pcap.c | 3 -
> drivers/mfd/intel_soc_pmic_crc.c | 4 -
> drivers/mfd/lp8788.c | 3 -
> drivers/mfd/omap-usb-host.c | 4 -
> drivers/mfd/omap-usb-tll.c | 4 -
> drivers/mfd/palmas.c | 3 -
> drivers/mfd/stmpe-i2c.c | 3 -
> drivers/mfd/stmpe-spi.c | 3 -
> drivers/mfd/tc3589x.c | 3 -
> drivers/mfd/tps6586x.c | 3 -
> drivers/mfd/twl4030-audio.c | 3 -
> drivers/mfd/twl6040.c | 4 -
> drivers/mmc/Makefile | 2 +-
> drivers/mtd/parsers/bcm63xxpart.c | 6 -
> drivers/net/wireless/silabs/wfx/Makefile | 2 +-
> drivers/nvmem/core.c | 4 -
> drivers/nvmem/zynqmp_nvmem.c | 3 -
> drivers/pci/controller/dwc/pcie-histb.c | 2 -
> .../controller/mobiveil/pcie-mobiveil-plat.c | 3 -
> drivers/pci/controller/pci-tegra.c | 1 -
> drivers/pci/controller/pci-versatile.c | 2 -
> drivers/pci/controller/pcie-hisi-error.c | 2 -
> drivers/pci/controller/pcie-microchip-host.c | 3 -
> drivers/pci/endpoint/pci-ep-cfs.c | 3 -
> drivers/pci/endpoint/pci-epc-core.c | 3 -
> drivers/pci/endpoint/pci-epc-mem.c | 3 -
> drivers/pci/endpoint/pci-epf-core.c | 3 -
> drivers/pci/hotplug/acpiphp_core.c | 3 -
> drivers/pci/hotplug/shpchp_core.c | 3 -
> drivers/perf/apple_m1_cpu_pmu.c | 1 -
> drivers/phy/intel/phy-intel-lgm-combo.c | 2 -
> drivers/pinctrl/actions/pinctrl-s500.c | 4 -
> drivers/pinctrl/actions/pinctrl-s700.c | 3 -
> drivers/pinctrl/actions/pinctrl-s900.c | 4 -
> drivers/pinctrl/bcm/pinctrl-ns.c | 2 -
> drivers/pinctrl/mediatek/pinctrl-mt8188.c | 2 -
> drivers/pinctrl/mediatek/pinctrl-mt8192.c | 2 -
> drivers/pinctrl/mediatek/pinctrl-mt8365.c | 3 -
> drivers/pinctrl/nuvoton/pinctrl-npcm7xx.c | 4 -
> drivers/pinctrl/pinctrl-amd.c | 3 -
> drivers/pinctrl/renesas/pinctrl-rza1.c | 3 -
> drivers/pinctrl/renesas/pinctrl-rza2.c | 3 -
> drivers/pinctrl/renesas/pinctrl-rzg2l.c | 3 -
> drivers/pinctrl/renesas/pinctrl-rzn1.c | 3 -
> drivers/pinctrl/renesas/pinctrl-rzv2m.c | 3 -
> drivers/power/reset/as3722-poweroff.c | 3 -
> drivers/power/reset/gpio-poweroff.c | 3 -
> drivers/power/reset/gpio-restart.c | 3 -
> drivers/power/reset/keystone-reset.c | 3 -
> drivers/power/reset/ltc2952-poweroff.c | 3 -
> drivers/power/reset/mt6323-poweroff.c | 3 -
> drivers/power/reset/regulator-poweroff.c | 3 -
> drivers/power/reset/restart-poweroff.c | 3 -
> drivers/power/reset/tps65086-restart.c | 3 -
> drivers/power/supply/power_supply_core.c | 6 -
> drivers/power/supply/wm97xx_battery.c | 3 -
> drivers/powercap/powercap_sys.c | 3 -
> drivers/regulator/stm32-pwr.c | 3 -
> drivers/remoteproc/remoteproc_core.c | 2 -
> drivers/reset/reset-axs10x.c | 3 -
> drivers/reset/reset-hsdk.c | 3 -
> drivers/reset/reset-lantiq.c | 3 -
> drivers/reset/reset-microchip-sparx5.c | 3 -
> drivers/reset/reset-mpfs.c | 3 -
> drivers/s390/char/Makefile | 2 +-
> drivers/s390/crypto/Makefile | 2 +-
> drivers/soc/apple/apple-pmgr-pwrstate.c | 3 -
> drivers/soc/bcm/bcm2835-power.c | 3 -
> drivers/soc/bcm/raspberrypi-power.c | 4 -
> drivers/soc/fujitsu/a64fx-diag.c | 3 -
> drivers/soc/sunxi/sunxi_sram.c | 3 -
> drivers/soc/tegra/cbb/tegra194-cbb.c | 3 -
> drivers/soc/tegra/cbb/tegra234-cbb.c | 2 -
> drivers/tty/n_null.c | 3 -
> drivers/tty/serial/imx_earlycon.c | 3 -
> drivers/tty/serial/rda-uart.c | 3 -
> drivers/video/console/vgacon.c | 1 -
> drivers/video/fbdev/asiliantfb.c | 1 -
> drivers/video/fbdev/gbefb.c | 1 -
> drivers/video/fbdev/imsttfb.c | 1 -
> drivers/video/fbdev/mmp/hw/mmp_ctrl.c | 3 -
> .../video/fbdev/mmp/panel/tpo_tj032md01bw.c | 3 -
> drivers/video/fbdev/vesafb.c | 1 -
> drivers/video/fbdev/wm8505fb.c | 3 -
> drivers/video/fbdev/wmt_ge_rops.c | 4 -
> drivers/xen/grant-dma-ops.c | 3 -
> drivers/xen/xenbus/xenbus_probe.c | 1 -
> fs/binfmt_elf.c | 1 -
> fs/nfs_common/nfs_ssc.c | 1 -
> fs/unicode/utf8-core.c | 1 -
> include/linux/module.h | 4 +-
> init/Kconfig | 10 +
> kernel/dma/map_benchmark.c | 3 -
> kernel/events/hw_breakpoint_test.c | 2 -
> kernel/kallsyms.c | 277 +++-
> kernel/kallsyms_internal.h | 14 +
> kernel/trace/rv/reactor_panic.c | 3 -
> kernel/trace/rv/reactor_printk.c | 3 -
> kernel/watch_queue.c | 3 -
> lib/btree.c | 3 -
> lib/crypto/blake2s-generic.c | 3 -
> lib/crypto/blake2s.c | 3 -
> lib/glob.c | 2 -
> lib/packing.c | 2 -
> lib/pldmfw/pldmfw.c | 3 -
> lib/test_fprobe.c | 1 -
> mm/zpool.c | 3 -
> mm/zswap.c | 3 -
> net/8021q/Makefile | 2 +-
> net/Makefile | 2 +-
> net/bridge/Makefile | 4 +-
> net/dccp/Makefile | 4 +-
> net/ipv6/Makefile | 2 +-
> net/l2tp/Makefile | 12 +-
> net/mctp/af_mctp.c | 3 -
> net/netfilter/Makefile | 2 +-
> net/netlabel/Makefile | 2 +-
> net/sctp/Makefile | 2 +-
> scripts/.gitignore | 1 +
> scripts/Kbuild.include | 21 +
> scripts/Makefile | 7 +
> scripts/Makefile.lib | 13 +-
> scripts/Makefile.vmlinux_o | 21 +-
> scripts/addaddrs.c | 28 +
> scripts/check-tristates.mk | 56 +
> scripts/kallsyms.c | 1223 ++++++++++++++++-
> scripts/kconfig/confdata.c | 41 +-
> scripts/link-vmlinux.sh | 38 +-
> scripts/modules_builtin.c | 200 +++
> scripts/modules_builtin.h | 48 +
> tools/perf/builtin-kallsyms.c | 35 +-
> tools/perf/util/event.c | 14 +-
> tools/perf/util/machine.c | 6 +-
> tools/perf/util/machine.h | 1 +
> tools/perf/util/symbol.c | 207 ++-
> tools/perf/util/symbol.h | 12 +-
> 231 files changed, 2241 insertions(+), 671 deletions(-)
> create mode 100644 scripts/addaddrs.c
> create mode 100644 scripts/check-tristates.mk
> create mode 100644 scripts/modules_builtin.c
> create mode 100644 scripts/modules_builtin.h
>

2023-05-19 16:12:30

by Alexander Lobakin

[permalink] [raw]
Subject: Re: [PATCH modules-next v10 00/13] kallsyms: reliable symbol->address lookup with /proc/kallmodsyms

From: Steven Rostedt <[email protected]>
Date: Mon, 8 May 2023 18:06:53 -0400

> This topic came up at LSFMM, presented by Jiri.
>
> I'm Cc'ing this email to the BPF mailing list.
>
> -- Steve
>
>
> On Mon, 5 Dec 2022 16:31:44 +0000
> Nick Alcock <[email protected]> wrote:
>
>> The kallmodsyms patch series was originally posted in Nov 2019, and the thread
>> (https://lore.kernel.org/linux-kbuild/[email protected]/t/#u)
>> shows review comments, questions, and feedback from interested parties.
>> Most recent posting: <https://lore.kernel.org/linux-modules/[email protected]/T/#t>.
>>
>> All review comments have been satisfied, as far as I know: in particular
>> Yamada's note about translation units that are shared between built-in
>> modules is satisfied with a better representation which is also much, much
>> smaller, and we are no longer using modules_thick.builtin but Luis's new
>> modules.builtin.objs.
>>
>> A kernel tree containing this series alone:
>> https://github.com/oracle/dtrace-linux-kernel kallmodsyms/6.1-rc4-modules-next
>>
>>
>> The whole point of symbols is that their names are unique: you can look up a
>> symbol and get back a unique address, and vice versa. Alas, because
>> /proc/kallsyms (rightly) reports all symbols, even hidden ones, it does not
>> really satisfy this requirement. Large numbers of symbols are duplicated
>> many times (just search for __list_del_entry!), and while usually these are
>> just out-of-lined things defined in header files and thus all have the same
>> implementation, it does make it needlessly hard to figure out which one is
>> which in stack dumps, when tracing, and such things. Some configuration
>> options make things much worse: my test make allyesconfig runs introduced
>> thousands of text symbols named _sub_I_65535_1, one per compiler-generated
>> object file, and it was fairly easy to make them appear in ftrace output.

FYI for devs: I posted RFC of kallsyms with file paths almost a year
ago[0], but it went unnoticed =\

`file name + function name` is not a unique pair: in one of FG-KASLR
discussions, someone even wrote simple script, which showed around 40
collisions in the kernel. My approach was to include file path starting
at the kernel root folder, i.e. `net/core/dev.o:register_netdev`.
I'm not sure why no comments happened back then tho. Maybe you could
take a look, I'm pretty busy with other projects, but if you find
anything useful there in the RFC, I could join to a little bit.

[0]
https://lore.kernel.org/all/[email protected]

Thanks,
Olek

2023-05-23 00:25:24

by Luis Chamberlain

[permalink] [raw]
Subject: Re: [PATCH modules-next v10 00/13] kallsyms: reliable symbol->address lookup with /proc/kallmodsyms

On Fri, May 19, 2023 at 05:50:35PM +0200, Alexander Lobakin wrote:
> FYI for devs: I posted RFC of kallsyms with file paths almost a year
> ago[0], but it went unnoticed =\
>
> `file name + function name` is not a unique pair: in one of FG-KASLR
> discussions, someone even wrote simple script, which showed around 40
> collisions in the kernel. My approach was to include file path starting
> at the kernel root folder, i.e. `net/core/dev.o:register_netdev`.
> I'm not sure why no comments happened back then tho. Maybe you could
> take a look, I'm pretty busy with other projects, but if you find
> anything useful there in the RFC, I could join to a little bit.
>
> [0]
> https://lore.kernel.org/all/[email protected]

Petr suggested line number too, that'd fix it too.

Luis

2023-05-24 15:10:53

by Nick Alcock

[permalink] [raw]
Subject: Re: [PATCH modules-next v10 00/13] kallsyms: reliable symbol->address lookup with /proc/kallmodsyms

On 19 May 2023, Alexander Lobakin outgrape:
> `file name + function name` is not a unique pair: in one of FG-KASLR
> discussions, someone even wrote simple script, which showed around 40
> collisions in the kernel. My approach was to include file path starting
> at the kernel root folder, i.e. `net/core/dev.o:register_netdev`.
> I'm not sure why no comments happened back then tho. Maybe you could
> take a look, I'm pretty busy with other projects, but if you find
> anything useful there in the RFC, I could join to a little bit.

My kallmodsyms patch does much the same, except to save space we
eliminate any leading path elements we can. Keeping those still
necessary to reduce redundancy, and eliminating the TU name entirely if
not necessary, saves several hundred KiB in my measurements and leads to
a total space hit for all of this of only about 12KiB. (Downside:
slightly less clear naming in /proc/kallmodsyms.)

--
NULL && (void)