mirror of
https://github.com/torvalds/linux.git
synced 2024-11-21 19:41:42 +00:00
Modules changes for v6.12-rc1
There are a few fixes / cleanups from Vincent, Chunhui, and Petr, but the most important part of this pull request is the Rust community stepping up to help maintain both C / Rust code for future Rust module support. We grow the set of modules maintainers by 3 now, and with this hope to scale to help address what's needed to properly support future Rust module support. A lot of exciting stuff coming in future kernel releases. This has been on linux-next for ~ 3 weeks now with no issues. -----BEGIN PGP SIGNATURE----- iQJGBAABCgAwFiEENnNq2KuOejlQLZofziMdCjCSiKcFAmb3InQSHG1jZ3JvZkBr ZXJuZWwub3JnAAoJEM4jHQowkoinA/IP/RP3O3Cwtyjd51lMNzEmJR0WE0J7/C3z v4L3teqoiH4vWF0vDd8jVE1SL9RZ0TnrSUUF/Kbf7YolXELPO+WSvPepGqlzeUTd KH+PZX+AmaGXhwAGmB53AMhcP8HmGci+IZZgyZUnYxZawcFYU24WYO84JAKltNsy /wqepYXObc0HiNXk+VS3h8Z+1y9nhJ55xluvTf5guQbrtjl1xWXSdVdF1/V5wnjp qShNSNn1bktFO0lK7IW/UmM0kEoFHHyUslwNcP/rJLIb99lDV3M+Vd3i41dBkuYw iSCD+a/0fOmUj909Q4VfZQkK4vKEi04XIz1EHb2uYOGKcr75gnWmCRyUL1TJSFO/ oXNd2SlvwMYXxMczsaLppAPERRgSMWnsBEZWZ7nk2uBpuFay43LfEdZcPwknGNkz 7Ns+3PHr6W3phUo1izrgxBk6xTyEDR6etxThSGvq/dhG3VuivV6hRyxFZX9NaTSD a/uFhIj2f8FuV9TLYUzPO/NwwLklPFe9dCvtWEHgSvtyaeX1pSvyjz8fLbXDGyu/ qVXMp2fegLJ2bq9A0ABtd7nuVNCAN24pl+Nwws+GMRmCg9b1Sfego16WoLUDbbHX mjVAFTtKgqEg0ePnbjqGm7I7siY/9x8I39aA9WbNoXKNFu3hwMDHLAavATmj+1dV UlrMxvfv20WQ =4P89 -----END PGP SIGNATURE----- Merge tag 'modules-6.12-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/mcgrof/linux Pull module updates from Luis Chamberlain: "There are a few fixes / cleanups from Vincent, Chunhui, and Petr, but the most important part of this pull request is the Rust community stepping up to help maintain both C / Rust code for future Rust module support. We grow the set of modules maintainers by three now, and with this hope to scale to help address what's needed to properly support future Rust module support. A lot of exciting stuff coming in future kernel releases. This has been on linux-next for ~ 3 weeks now with no issues" * tag 'modules-6.12-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/mcgrof/linux: module: Refine kmemleak scanned areas module: abort module loading when sysfs setup suffer errors MAINTAINERS: scale modules with more reviewers module: Clean up the description of MODULE_SIG_<type> module: Split modules_install compression and in-kernel decompression
This commit is contained in:
commit
6f81a446f8
@ -15678,6 +15678,9 @@ F: include/dt-bindings/clock/mobileye,eyeq5-clk.h
|
|||||||
|
|
||||||
MODULE SUPPORT
|
MODULE SUPPORT
|
||||||
M: Luis Chamberlain <mcgrof@kernel.org>
|
M: Luis Chamberlain <mcgrof@kernel.org>
|
||||||
|
R: Petr Pavlu <petr.pavlu@suse.com>
|
||||||
|
R: Sami Tolvanen <samitolvanen@google.com>
|
||||||
|
R: Daniel Gomez <da.gomez@samsung.com>
|
||||||
L: linux-modules@vger.kernel.org
|
L: linux-modules@vger.kernel.org
|
||||||
L: linux-kernel@vger.kernel.org
|
L: linux-kernel@vger.kernel.org
|
||||||
S: Maintained
|
S: Maintained
|
||||||
|
@ -229,7 +229,7 @@ comment "Do not forget to sign required modules with scripts/sign-file"
|
|||||||
depends on MODULE_SIG_FORCE && !MODULE_SIG_ALL
|
depends on MODULE_SIG_FORCE && !MODULE_SIG_ALL
|
||||||
|
|
||||||
choice
|
choice
|
||||||
prompt "Which hash algorithm should modules be signed with?"
|
prompt "Hash algorithm to sign modules"
|
||||||
depends on MODULE_SIG || IMA_APPRAISE_MODSIG
|
depends on MODULE_SIG || IMA_APPRAISE_MODSIG
|
||||||
help
|
help
|
||||||
This determines which sort of hashing algorithm will be used during
|
This determines which sort of hashing algorithm will be used during
|
||||||
@ -239,31 +239,31 @@ choice
|
|||||||
the signature on that module.
|
the signature on that module.
|
||||||
|
|
||||||
config MODULE_SIG_SHA1
|
config MODULE_SIG_SHA1
|
||||||
bool "Sign modules with SHA-1"
|
bool "SHA-1"
|
||||||
select CRYPTO_SHA1
|
select CRYPTO_SHA1
|
||||||
|
|
||||||
config MODULE_SIG_SHA256
|
config MODULE_SIG_SHA256
|
||||||
bool "Sign modules with SHA-256"
|
bool "SHA-256"
|
||||||
select CRYPTO_SHA256
|
select CRYPTO_SHA256
|
||||||
|
|
||||||
config MODULE_SIG_SHA384
|
config MODULE_SIG_SHA384
|
||||||
bool "Sign modules with SHA-384"
|
bool "SHA-384"
|
||||||
select CRYPTO_SHA512
|
select CRYPTO_SHA512
|
||||||
|
|
||||||
config MODULE_SIG_SHA512
|
config MODULE_SIG_SHA512
|
||||||
bool "Sign modules with SHA-512"
|
bool "SHA-512"
|
||||||
select CRYPTO_SHA512
|
select CRYPTO_SHA512
|
||||||
|
|
||||||
config MODULE_SIG_SHA3_256
|
config MODULE_SIG_SHA3_256
|
||||||
bool "Sign modules with SHA3-256"
|
bool "SHA3-256"
|
||||||
select CRYPTO_SHA3
|
select CRYPTO_SHA3
|
||||||
|
|
||||||
config MODULE_SIG_SHA3_384
|
config MODULE_SIG_SHA3_384
|
||||||
bool "Sign modules with SHA3-384"
|
bool "SHA3-384"
|
||||||
select CRYPTO_SHA3
|
select CRYPTO_SHA3
|
||||||
|
|
||||||
config MODULE_SIG_SHA3_512
|
config MODULE_SIG_SHA3_512
|
||||||
bool "Sign modules with SHA3-512"
|
bool "SHA3-512"
|
||||||
select CRYPTO_SHA3
|
select CRYPTO_SHA3
|
||||||
|
|
||||||
endchoice
|
endchoice
|
||||||
@ -279,64 +279,65 @@ config MODULE_SIG_HASH
|
|||||||
default "sha3-384" if MODULE_SIG_SHA3_384
|
default "sha3-384" if MODULE_SIG_SHA3_384
|
||||||
default "sha3-512" if MODULE_SIG_SHA3_512
|
default "sha3-512" if MODULE_SIG_SHA3_512
|
||||||
|
|
||||||
choice
|
config MODULE_COMPRESS
|
||||||
prompt "Module compression mode"
|
bool "Module compression"
|
||||||
help
|
help
|
||||||
This option allows you to choose the algorithm which will be used to
|
Enable module compression to reduce on-disk size of module binaries.
|
||||||
compress modules when 'make modules_install' is run. (or, you can
|
|
||||||
choose to not compress modules at all.)
|
|
||||||
|
|
||||||
External modules will also be compressed in the same way during the
|
|
||||||
installation.
|
|
||||||
|
|
||||||
For modules inside an initrd or initramfs, it's more efficient to
|
|
||||||
compress the whole initrd or initramfs instead.
|
|
||||||
|
|
||||||
This is fully compatible with signed modules.
|
This is fully compatible with signed modules.
|
||||||
|
|
||||||
Please note that the tool used to load modules needs to support the
|
The tool used to work with modules needs to support the selected
|
||||||
corresponding algorithm. module-init-tools MAY support gzip, and kmod
|
compression type. kmod MAY support gzip, xz and zstd. Other tools
|
||||||
MAY support gzip, xz and zstd.
|
might have a limited selection of the supported types.
|
||||||
|
|
||||||
Your build system needs to provide the appropriate compression tool
|
Note that for modules inside an initrd or initramfs, it's more
|
||||||
to compress the modules.
|
efficient to compress the whole ramdisk instead.
|
||||||
|
|
||||||
If in doubt, select 'None'.
|
If unsure, say N.
|
||||||
|
|
||||||
config MODULE_COMPRESS_NONE
|
choice
|
||||||
bool "None"
|
prompt "Module compression type"
|
||||||
|
depends on MODULE_COMPRESS
|
||||||
help
|
help
|
||||||
Do not compress modules. The installed modules are suffixed
|
Choose the supported algorithm for module compression.
|
||||||
with .ko.
|
|
||||||
|
|
||||||
config MODULE_COMPRESS_GZIP
|
config MODULE_COMPRESS_GZIP
|
||||||
bool "GZIP"
|
bool "GZIP"
|
||||||
help
|
help
|
||||||
Compress modules with GZIP. The installed modules are suffixed
|
Support modules compressed with GZIP. The installed modules are
|
||||||
with .ko.gz.
|
suffixed with .ko.gz.
|
||||||
|
|
||||||
config MODULE_COMPRESS_XZ
|
config MODULE_COMPRESS_XZ
|
||||||
bool "XZ"
|
bool "XZ"
|
||||||
help
|
help
|
||||||
Compress modules with XZ. The installed modules are suffixed
|
Support modules compressed with XZ. The installed modules are
|
||||||
with .ko.xz.
|
suffixed with .ko.xz.
|
||||||
|
|
||||||
config MODULE_COMPRESS_ZSTD
|
config MODULE_COMPRESS_ZSTD
|
||||||
bool "ZSTD"
|
bool "ZSTD"
|
||||||
help
|
help
|
||||||
Compress modules with ZSTD. The installed modules are suffixed
|
Support modules compressed with ZSTD. The installed modules are
|
||||||
with .ko.zst.
|
suffixed with .ko.zst.
|
||||||
|
|
||||||
endchoice
|
endchoice
|
||||||
|
|
||||||
|
config MODULE_COMPRESS_ALL
|
||||||
|
bool "Automatically compress all modules"
|
||||||
|
default y
|
||||||
|
depends on MODULE_COMPRESS
|
||||||
|
help
|
||||||
|
Compress all modules during 'make modules_install'.
|
||||||
|
|
||||||
|
Your build system needs to provide the appropriate compression tool
|
||||||
|
for the selected compression type. External modules will also be
|
||||||
|
compressed in the same way during the installation.
|
||||||
|
|
||||||
config MODULE_DECOMPRESS
|
config MODULE_DECOMPRESS
|
||||||
bool "Support in-kernel module decompression"
|
bool "Support in-kernel module decompression"
|
||||||
depends on MODULE_COMPRESS_GZIP || MODULE_COMPRESS_XZ || MODULE_COMPRESS_ZSTD
|
depends on MODULE_COMPRESS
|
||||||
select ZLIB_INFLATE if MODULE_COMPRESS_GZIP
|
select ZLIB_INFLATE if MODULE_COMPRESS_GZIP
|
||||||
select XZ_DEC if MODULE_COMPRESS_XZ
|
select XZ_DEC if MODULE_COMPRESS_XZ
|
||||||
select ZSTD_DECOMPRESS if MODULE_COMPRESS_ZSTD
|
select ZSTD_DECOMPRESS if MODULE_COMPRESS_ZSTD
|
||||||
help
|
help
|
||||||
|
|
||||||
Support for decompressing kernel modules by the kernel itself
|
Support for decompressing kernel modules by the kernel itself
|
||||||
instead of relying on userspace to perform this task. Useful when
|
instead of relying on userspace to perform this task. Useful when
|
||||||
load pinning security policy is enabled.
|
load pinning security policy is enabled.
|
||||||
|
@ -12,19 +12,9 @@
|
|||||||
void kmemleak_load_module(const struct module *mod,
|
void kmemleak_load_module(const struct module *mod,
|
||||||
const struct load_info *info)
|
const struct load_info *info)
|
||||||
{
|
{
|
||||||
unsigned int i;
|
/* only scan writable, non-executable sections */
|
||||||
|
for_each_mod_mem_type(type) {
|
||||||
/* only scan the sections containing data */
|
if (type != MOD_DATA && type != MOD_INIT_DATA)
|
||||||
kmemleak_scan_area(mod, sizeof(struct module), GFP_KERNEL);
|
kmemleak_no_scan(mod->mem[type].base);
|
||||||
|
|
||||||
for (i = 1; i < info->hdr->e_shnum; i++) {
|
|
||||||
/* Scan all writable sections that's not executable */
|
|
||||||
if (!(info->sechdrs[i].sh_flags & SHF_ALLOC) ||
|
|
||||||
!(info->sechdrs[i].sh_flags & SHF_WRITE) ||
|
|
||||||
(info->sechdrs[i].sh_flags & SHF_EXECINSTR))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
kmemleak_scan_area((void *)info->sechdrs[i].sh_addr,
|
|
||||||
info->sechdrs[i].sh_size, GFP_KERNEL);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -69,12 +69,13 @@ static void free_sect_attrs(struct module_sect_attrs *sect_attrs)
|
|||||||
kfree(sect_attrs);
|
kfree(sect_attrs);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void add_sect_attrs(struct module *mod, const struct load_info *info)
|
static int add_sect_attrs(struct module *mod, const struct load_info *info)
|
||||||
{
|
{
|
||||||
unsigned int nloaded = 0, i, size[2];
|
unsigned int nloaded = 0, i, size[2];
|
||||||
struct module_sect_attrs *sect_attrs;
|
struct module_sect_attrs *sect_attrs;
|
||||||
struct module_sect_attr *sattr;
|
struct module_sect_attr *sattr;
|
||||||
struct bin_attribute **gattr;
|
struct bin_attribute **gattr;
|
||||||
|
int ret;
|
||||||
|
|
||||||
/* Count loaded sections and allocate structures */
|
/* Count loaded sections and allocate structures */
|
||||||
for (i = 0; i < info->hdr->e_shnum; i++)
|
for (i = 0; i < info->hdr->e_shnum; i++)
|
||||||
@ -85,7 +86,7 @@ static void add_sect_attrs(struct module *mod, const struct load_info *info)
|
|||||||
size[1] = (nloaded + 1) * sizeof(sect_attrs->grp.bin_attrs[0]);
|
size[1] = (nloaded + 1) * sizeof(sect_attrs->grp.bin_attrs[0]);
|
||||||
sect_attrs = kzalloc(size[0] + size[1], GFP_KERNEL);
|
sect_attrs = kzalloc(size[0] + size[1], GFP_KERNEL);
|
||||||
if (!sect_attrs)
|
if (!sect_attrs)
|
||||||
return;
|
return -ENOMEM;
|
||||||
|
|
||||||
/* Setup section attributes. */
|
/* Setup section attributes. */
|
||||||
sect_attrs->grp.name = "sections";
|
sect_attrs->grp.name = "sections";
|
||||||
@ -103,8 +104,10 @@ static void add_sect_attrs(struct module *mod, const struct load_info *info)
|
|||||||
sattr->address = sec->sh_addr;
|
sattr->address = sec->sh_addr;
|
||||||
sattr->battr.attr.name =
|
sattr->battr.attr.name =
|
||||||
kstrdup(info->secstrings + sec->sh_name, GFP_KERNEL);
|
kstrdup(info->secstrings + sec->sh_name, GFP_KERNEL);
|
||||||
if (!sattr->battr.attr.name)
|
if (!sattr->battr.attr.name) {
|
||||||
|
ret = -ENOMEM;
|
||||||
goto out;
|
goto out;
|
||||||
|
}
|
||||||
sect_attrs->nsections++;
|
sect_attrs->nsections++;
|
||||||
sattr->battr.read = module_sect_read;
|
sattr->battr.read = module_sect_read;
|
||||||
sattr->battr.size = MODULE_SECT_READ_SIZE;
|
sattr->battr.size = MODULE_SECT_READ_SIZE;
|
||||||
@ -113,13 +116,15 @@ static void add_sect_attrs(struct module *mod, const struct load_info *info)
|
|||||||
}
|
}
|
||||||
*gattr = NULL;
|
*gattr = NULL;
|
||||||
|
|
||||||
if (sysfs_create_group(&mod->mkobj.kobj, §_attrs->grp))
|
ret = sysfs_create_group(&mod->mkobj.kobj, §_attrs->grp);
|
||||||
|
if (ret)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
mod->sect_attrs = sect_attrs;
|
mod->sect_attrs = sect_attrs;
|
||||||
return;
|
return 0;
|
||||||
out:
|
out:
|
||||||
free_sect_attrs(sect_attrs);
|
free_sect_attrs(sect_attrs);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void remove_sect_attrs(struct module *mod)
|
static void remove_sect_attrs(struct module *mod)
|
||||||
@ -158,15 +163,12 @@ static void free_notes_attrs(struct module_notes_attrs *notes_attrs,
|
|||||||
kfree(notes_attrs);
|
kfree(notes_attrs);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void add_notes_attrs(struct module *mod, const struct load_info *info)
|
static int add_notes_attrs(struct module *mod, const struct load_info *info)
|
||||||
{
|
{
|
||||||
unsigned int notes, loaded, i;
|
unsigned int notes, loaded, i;
|
||||||
struct module_notes_attrs *notes_attrs;
|
struct module_notes_attrs *notes_attrs;
|
||||||
struct bin_attribute *nattr;
|
struct bin_attribute *nattr;
|
||||||
|
int ret;
|
||||||
/* failed to create section attributes, so can't create notes */
|
|
||||||
if (!mod->sect_attrs)
|
|
||||||
return;
|
|
||||||
|
|
||||||
/* Count notes sections and allocate structures. */
|
/* Count notes sections and allocate structures. */
|
||||||
notes = 0;
|
notes = 0;
|
||||||
@ -176,12 +178,12 @@ static void add_notes_attrs(struct module *mod, const struct load_info *info)
|
|||||||
++notes;
|
++notes;
|
||||||
|
|
||||||
if (notes == 0)
|
if (notes == 0)
|
||||||
return;
|
return 0;
|
||||||
|
|
||||||
notes_attrs = kzalloc(struct_size(notes_attrs, attrs, notes),
|
notes_attrs = kzalloc(struct_size(notes_attrs, attrs, notes),
|
||||||
GFP_KERNEL);
|
GFP_KERNEL);
|
||||||
if (!notes_attrs)
|
if (!notes_attrs)
|
||||||
return;
|
return -ENOMEM;
|
||||||
|
|
||||||
notes_attrs->notes = notes;
|
notes_attrs->notes = notes;
|
||||||
nattr = ¬es_attrs->attrs[0];
|
nattr = ¬es_attrs->attrs[0];
|
||||||
@ -201,19 +203,23 @@ static void add_notes_attrs(struct module *mod, const struct load_info *info)
|
|||||||
}
|
}
|
||||||
|
|
||||||
notes_attrs->dir = kobject_create_and_add("notes", &mod->mkobj.kobj);
|
notes_attrs->dir = kobject_create_and_add("notes", &mod->mkobj.kobj);
|
||||||
if (!notes_attrs->dir)
|
if (!notes_attrs->dir) {
|
||||||
|
ret = -ENOMEM;
|
||||||
goto out;
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
for (i = 0; i < notes; ++i)
|
for (i = 0; i < notes; ++i) {
|
||||||
if (sysfs_create_bin_file(notes_attrs->dir,
|
ret = sysfs_create_bin_file(notes_attrs->dir, ¬es_attrs->attrs[i]);
|
||||||
¬es_attrs->attrs[i]))
|
if (ret)
|
||||||
goto out;
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
mod->notes_attrs = notes_attrs;
|
mod->notes_attrs = notes_attrs;
|
||||||
return;
|
return 0;
|
||||||
|
|
||||||
out:
|
out:
|
||||||
free_notes_attrs(notes_attrs, i);
|
free_notes_attrs(notes_attrs, i);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void remove_notes_attrs(struct module *mod)
|
static void remove_notes_attrs(struct module *mod)
|
||||||
@ -223,9 +229,15 @@ static void remove_notes_attrs(struct module *mod)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#else /* !CONFIG_KALLSYMS */
|
#else /* !CONFIG_KALLSYMS */
|
||||||
static inline void add_sect_attrs(struct module *mod, const struct load_info *info) { }
|
static inline int add_sect_attrs(struct module *mod, const struct load_info *info)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
static inline void remove_sect_attrs(struct module *mod) { }
|
static inline void remove_sect_attrs(struct module *mod) { }
|
||||||
static inline void add_notes_attrs(struct module *mod, const struct load_info *info) { }
|
static inline int add_notes_attrs(struct module *mod, const struct load_info *info)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
static inline void remove_notes_attrs(struct module *mod) { }
|
static inline void remove_notes_attrs(struct module *mod) { }
|
||||||
#endif /* CONFIG_KALLSYMS */
|
#endif /* CONFIG_KALLSYMS */
|
||||||
|
|
||||||
@ -385,11 +397,20 @@ int mod_sysfs_setup(struct module *mod,
|
|||||||
if (err)
|
if (err)
|
||||||
goto out_unreg_modinfo_attrs;
|
goto out_unreg_modinfo_attrs;
|
||||||
|
|
||||||
add_sect_attrs(mod, info);
|
err = add_sect_attrs(mod, info);
|
||||||
add_notes_attrs(mod, info);
|
if (err)
|
||||||
|
goto out_del_usage_links;
|
||||||
|
|
||||||
|
err = add_notes_attrs(mod, info);
|
||||||
|
if (err)
|
||||||
|
goto out_unreg_sect_attrs;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
out_unreg_sect_attrs:
|
||||||
|
remove_sect_attrs(mod);
|
||||||
|
out_del_usage_links:
|
||||||
|
del_usage_links(mod);
|
||||||
out_unreg_modinfo_attrs:
|
out_unreg_modinfo_attrs:
|
||||||
module_remove_modinfo_attrs(mod, -1);
|
module_remove_modinfo_attrs(mod, -1);
|
||||||
out_unreg_param:
|
out_unreg_param:
|
||||||
|
@ -53,9 +53,11 @@ $(foreach x, % :, $(if $(findstring $x, $(dst)), \
|
|||||||
$(error module installation path cannot contain '$x')))
|
$(error module installation path cannot contain '$x')))
|
||||||
|
|
||||||
suffix-y :=
|
suffix-y :=
|
||||||
|
ifdef CONFIG_MODULE_COMPRESS_ALL
|
||||||
suffix-$(CONFIG_MODULE_COMPRESS_GZIP) := .gz
|
suffix-$(CONFIG_MODULE_COMPRESS_GZIP) := .gz
|
||||||
suffix-$(CONFIG_MODULE_COMPRESS_XZ) := .xz
|
suffix-$(CONFIG_MODULE_COMPRESS_XZ) := .xz
|
||||||
suffix-$(CONFIG_MODULE_COMPRESS_ZSTD) := .zst
|
suffix-$(CONFIG_MODULE_COMPRESS_ZSTD) := .zst
|
||||||
|
endif
|
||||||
|
|
||||||
modules := $(patsubst $(extmod_prefix)%.o, $(dst)/%.ko$(suffix-y), $(modules))
|
modules := $(patsubst $(extmod_prefix)%.o, $(dst)/%.ko$(suffix-y), $(modules))
|
||||||
install-$(CONFIG_MODULES) += $(modules)
|
install-$(CONFIG_MODULES) += $(modules)
|
||||||
|
Loading…
Reference in New Issue
Block a user