From patchwork Thu Jun 1 22:39:57 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lucas De Marchi X-Patchwork-Id: 13264560 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 89E2DC7EE29 for ; Thu, 1 Jun 2023 22:40:19 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229781AbjFAWkT (ORCPT ); Thu, 1 Jun 2023 18:40:19 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50382 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229542AbjFAWkR (ORCPT ); Thu, 1 Jun 2023 18:40:17 -0400 Received: from mail-ed1-x534.google.com (mail-ed1-x534.google.com [IPv6:2a00:1450:4864:20::534]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 7DC91136 for ; Thu, 1 Jun 2023 15:40:15 -0700 (PDT) Received: by mail-ed1-x534.google.com with SMTP id 4fb4d7f45d1cf-5149aafef44so2092881a12.0 for ; Thu, 01 Jun 2023 15:40:15 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20221208; t=1685659213; x=1688251213; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=FnDwmBmVGYJiv8QjZrAsENAi8v+nWukYeqS6LJo5B0Y=; b=djAC3hjC2JMZEPYypExL5z1iQGdUysPbxsBt6+AcNIk39cmwaENgD8sdpnX9IrJt8M LnufqxaaPLgJfd2PXB13MioQEmyw6yTUm4OCqyKUohTb5u7aQvt7+phXYwrh5/CfibQn 9LwPN/H7LLP7HnrtgR0hsLZdhRP4wQIW+L5k171DaUzgv6MQI+w0jpr8GXUsnXOHR5aS 7UvHZ6U9fZfoEd7WEI5ivlOcLDyWCrlMibQjbs4dcg14pOGR1bmGv3GjE9FE70G+ph3M e4bzZ6UpyeJZn7QlQitcq9Pl7C3Jv+FhEuOCNZ6YoRFBwNyqwLx9HyF6WTwSU3Wzz57/ quqw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1685659213; x=1688251213; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=FnDwmBmVGYJiv8QjZrAsENAi8v+nWukYeqS6LJo5B0Y=; b=GW/LLuHxQFw4ugRLROnKNdtyRJIPHT5NrOAg8R9f9eArIDagP4pKJDFAVMqgq4r/yU SSt1YaAflo4QrcbixEev9jkrCgHxvU77f2O4KVWB8t0Co7oyTvH1m8NX59D5uCxjxnvT o1SUVoOBRoBtyvO5en2XeixFvlOylKohWxGr9XDkHPbqd0KcR0wKln5SyonwnQ0v3H4r Yoz5E7pL5pTp/8nC+UpsFbjPVTxEIsmOap6phf1uQFRQgCC5xw5hbGLXKItRQvBDrgrv AOOauPZMJnAOt/DK8bGAi1PYxMrq+yySpQ2mnaC1mjOAeAyorwPUct81eD1zAE1of6zw /zoQ== X-Gm-Message-State: AC+VfDxb/PHF0nLs7lv8/6u7hNFCwmdf94y1lIpPOAnkLRCa90fj06CV um50CxZu1u9mPv1yQzivfAGccTEgAxA= X-Google-Smtp-Source: ACHHUZ7k2uiGKmbQOul1olNoNh+bQcDmkV9TvnxlFsW7CDG+bA42eyQLbrQFIk37GptglxM8HpuE7A== X-Received: by 2002:a17:907:9343:b0:96f:afe9:25c4 with SMTP id bv3-20020a170907934300b0096fafe925c4mr8676255ejc.50.1685659213025; Thu, 01 Jun 2023 15:40:13 -0700 (PDT) Received: from ldmartin-desk2.jf.intel.com ([134.134.137.83]) by smtp.gmail.com with ESMTPSA id se24-20020a170906ce5800b009662b4230cesm11253318ejb.148.2023.06.01.15.40.10 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 01 Jun 2023 15:40:12 -0700 (PDT) From: Lucas De Marchi To: linux-modules@vger.kernel.org Cc: Luis Chamberlain , Lucas De Marchi Subject: [PATCH 1/5] libkmod: Do not inititialize file->memory on open Date: Thu, 1 Jun 2023 15:39:57 -0700 Message-Id: <20230601224001.23397-2-lucas.de.marchi@gmail.com> X-Mailer: git-send-email 2.40.1 In-Reply-To: <20230601224001.23397-1-lucas.de.marchi@gmail.com> References: <20230601224001.23397-1-lucas.de.marchi@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: Add a separate function to load the file contents when it's needed. When it's not needed on the path of loading modules via finit_module(), there is no need to mmap the file. This will help support loading modules with the in-kernel compression support. This is done differently than the lazy initialization for kmod_file_get_elf() because on the contents case there is also the file->size to be updated. It would be a weird API to return the pointer and have the size changed as a side-effect. Signed-off-by: Lucas De Marchi --- libkmod/libkmod-elf.c | 5 +++++ libkmod/libkmod-file.c | 17 ++++++++++++++--- libkmod/libkmod-internal.h | 3 ++- libkmod/libkmod-module.c | 2 ++ 4 files changed, 23 insertions(+), 4 deletions(-) diff --git a/libkmod/libkmod-elf.c b/libkmod/libkmod-elf.c index fb2e3d9..933825b 100644 --- a/libkmod/libkmod-elf.c +++ b/libkmod/libkmod-elf.c @@ -281,6 +281,11 @@ struct kmod_elf *kmod_elf_new(const void *memory, off_t size) assert_cc(sizeof(uint32_t) == sizeof(Elf32_Word)); assert_cc(sizeof(uint32_t) == sizeof(Elf64_Word)); + if (!memory) { + errno = -EINVAL; + return NULL; + } + class = elf_identify(memory, size); if (class < 0) { errno = -class; diff --git a/libkmod/libkmod-file.c b/libkmod/libkmod-file.c index b6a8cc9..1449c41 100644 --- a/libkmod/libkmod-file.c +++ b/libkmod/libkmod-file.c @@ -421,6 +421,7 @@ struct kmod_elf *kmod_file_get_elf(struct kmod_file *file) if (file->elf) return file->elf; + kmod_file_load_contents(file); file->elf = kmod_elf_new(file->memory, file->size); return file->elf; } @@ -431,7 +432,7 @@ struct kmod_file *kmod_file_open(const struct kmod_ctx *ctx, struct kmod_file *file = calloc(1, sizeof(struct kmod_file)); const struct comp_type *itr; size_t magic_size_max = 0; - int err; + int err = 0; if (file == NULL) return NULL; @@ -477,8 +478,8 @@ struct kmod_file *kmod_file_open(const struct kmod_ctx *ctx, if (file->ops == NULL) file->ops = ®_ops; - err = file->ops->load(file); file->ctx = ctx; + error: if (err < 0) { if (file->fd >= 0) @@ -491,6 +492,14 @@ error: return file; } +int kmod_file_load_contents(struct kmod_file *file) +{ + if (file->memory) + return 0; + + return file->ops->load(file); +} + void *kmod_file_get_contents(const struct kmod_file *file) { return file->memory; @@ -516,7 +525,9 @@ void kmod_file_unref(struct kmod_file *file) if (file->elf) kmod_elf_unref(file->elf); - file->ops->unload(file); + if (file->memory) + file->ops->unload(file); + if (file->fd >= 0) close(file->fd); free(file); diff --git a/libkmod/libkmod-internal.h b/libkmod/libkmod-internal.h index 4a4af58..4799ed5 100644 --- a/libkmod/libkmod-internal.h +++ b/libkmod/libkmod-internal.h @@ -152,6 +152,7 @@ bool kmod_module_is_builtin(struct kmod_module *mod) __attribute__((nonnull(1))) /* libkmod-file.c */ struct kmod_file *kmod_file_open(const struct kmod_ctx *ctx, const char *filename) _must_check_ __attribute__((nonnull(1,2))); struct kmod_elf *kmod_file_get_elf(struct kmod_file *file) __attribute__((nonnull(1))); +int kmod_file_load_contents(struct kmod_file *file) _must_check_ __attribute__((nonnull(1))); void *kmod_file_get_contents(const struct kmod_file *file) _must_check_ __attribute__((nonnull(1))); off_t kmod_file_get_size(const struct kmod_file *file) _must_check_ __attribute__((nonnull(1))); bool kmod_file_get_direct(const struct kmod_file *file) _must_check_ __attribute__((nonnull(1))); @@ -166,7 +167,7 @@ struct kmod_modversion { char *symbol; }; -struct kmod_elf *kmod_elf_new(const void *memory, off_t size) _must_check_ __attribute__((nonnull(1))); +struct kmod_elf *kmod_elf_new(const void *memory, off_t size) _must_check_; void kmod_elf_unref(struct kmod_elf *elf) __attribute__((nonnull(1))); const void *kmod_elf_get_memory(const struct kmod_elf *elf) _must_check_ __attribute__((nonnull(1))); int kmod_elf_get_strings(const struct kmod_elf *elf, const char *section, char ***array) _must_check_ __attribute__((nonnull(1,2,3))); diff --git a/libkmod/libkmod-module.c b/libkmod/libkmod-module.c index 7736b7e..f352fe1 100644 --- a/libkmod/libkmod-module.c +++ b/libkmod/libkmod-module.c @@ -917,6 +917,8 @@ KMOD_EXPORT int kmod_module_insert_module(struct kmod_module *mod, goto init_finished; } + kmod_file_load_contents(mod->file); + if (flags & (KMOD_INSERT_FORCE_VERMAGIC | KMOD_INSERT_FORCE_MODVERSION)) { elf = kmod_file_get_elf(mod->file); if (elf == NULL) { From patchwork Thu Jun 1 22:39:58 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lucas De Marchi X-Patchwork-Id: 13264562 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 26253C77B7A for ; Thu, 1 Jun 2023 22:40:23 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229542AbjFAWkW (ORCPT ); Thu, 1 Jun 2023 18:40:22 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50400 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231354AbjFAWkV (ORCPT ); Thu, 1 Jun 2023 18:40:21 -0400 Received: from mail-ej1-x62d.google.com (mail-ej1-x62d.google.com [IPv6:2a00:1450:4864:20::62d]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 7C9DB12C for ; Thu, 1 Jun 2023 15:40:17 -0700 (PDT) Received: by mail-ej1-x62d.google.com with SMTP id a640c23a62f3a-973f78329e3so204873866b.3 for ; Thu, 01 Jun 2023 15:40:17 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20221208; t=1685659215; x=1688251215; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=lLlr9LTWmO1Di1JRcm2H6urym/NeH+WNeVsxjTLNg78=; b=F/Hw8KuWB5O0KDJ5XzZadsGr1LGXTvKpkdaykjNmQzgqQIKhLFmj43lBEexDwYp2vY an0QqcQGumGHO2qsXbObViw/2R4KriBRq/IqiennTMNnfTb2OS8ZLmOrvgcqSEHOLSoF d16f1YeKkTvB6/7VZxsXhFXM/XFt3xVvLWMbhxkB7YW3fqJo8qwtXp8OhTQrLMof2zWr Vn1nRWI9eNOYbpqJI7+kQUIQPT18OWRBSmpJK8nrbjfHqV5QolvrYS9GD6FSJ+SCtjI8 dKulVIg7bE6pFSWWF8rodpjMt9vLmpep47pjczQ9AhCVkYa/6NzeeSsfiYQOqsLH3YDS VATA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1685659215; x=1688251215; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=lLlr9LTWmO1Di1JRcm2H6urym/NeH+WNeVsxjTLNg78=; b=ICso9XFZOBAD8dU22NhMAJwdEO5gVG2E5D7zlBjuQQBUasj6j97rD4vDk+I7pBIKYU VpqHKQHegHgRKuru0Rh3oLbktTBNUIa2ZgXvA2OI9gdEtRVi4YKE2ob4qxgPXr9Ga83h armbU2W2aJbkR45ST8VpncAf/+tbPhYgAZIAR+EI3VdvymBthr+R6TSyedBeoMuTvCd+ e0k7SKCRvbABzSlpvnAaB1+RosutsisgzjxcaGyH9Jp/5GXr+u91UDlcIlrXffTg4boh pLl1Uy4KGEBb9Tibm60ubzxp4RGcg7RVJgx4JdkivUR75Wq+wjQEiOPADO/MGT+h1J0A VJxA== X-Gm-Message-State: AC+VfDyig5Eog/mcu35WuGuIuafC5qcyFC9XBsj4dJo6cteukz5eYK/9 fA7o7BmLjhRy8iPbVRapp8ZGpK+6Pjc= X-Google-Smtp-Source: ACHHUZ60l04wZxKjXHYCE9QTwVX4fQuB4h4YI1DOhvoiPexyocOn04mzYyQ3i9gTzO2aNkM0Yv/4IQ== X-Received: by 2002:a17:907:a09:b0:974:5480:171e with SMTP id bb9-20020a1709070a0900b009745480171emr1366067ejc.32.1685659215391; Thu, 01 Jun 2023 15:40:15 -0700 (PDT) Received: from ldmartin-desk2.jf.intel.com ([134.134.137.83]) by smtp.gmail.com with ESMTPSA id se24-20020a170906ce5800b009662b4230cesm11253318ejb.148.2023.06.01.15.40.13 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 01 Jun 2023 15:40:14 -0700 (PDT) From: Lucas De Marchi To: linux-modules@vger.kernel.org Cc: Luis Chamberlain , Lucas De Marchi Subject: [PATCH 2/5] libkmod: Extract finit_module vs init_module paths Date: Thu, 1 Jun 2023 15:39:58 -0700 Message-Id: <20230601224001.23397-3-lucas.de.marchi@gmail.com> X-Mailer: git-send-email 2.40.1 In-Reply-To: <20230601224001.23397-1-lucas.de.marchi@gmail.com> References: <20230601224001.23397-1-lucas.de.marchi@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: Extract 2 functions to handle finit_module vs init_modules differences, with a fallback from the former to the latter. Signed-off-by: Lucas De Marchi Reviewed-by: Luis Chamberlain --- libkmod/libkmod-module.c | 120 ++++++++++++++++++++++++--------------- 1 file changed, 73 insertions(+), 47 deletions(-) diff --git a/libkmod/libkmod-module.c b/libkmod/libkmod-module.c index f352fe1..6ed5ad4 100644 --- a/libkmod/libkmod-module.c +++ b/libkmod/libkmod-module.c @@ -861,6 +861,73 @@ KMOD_EXPORT int kmod_module_remove_module(struct kmod_module *mod, extern long init_module(const void *mem, unsigned long len, const char *args); +static int do_finit_module(struct kmod_module *mod, unsigned int flags, + const char *args) +{ + unsigned int kernel_flags = 0; + int err; + + /* + * Re-use ENOSYS, returned when there is no such syscall, so the + * fallback to init_module applies + */ + if (!kmod_file_get_direct(mod->file)) + return -ENOSYS; + + if (flags & KMOD_INSERT_FORCE_VERMAGIC) + kernel_flags |= MODULE_INIT_IGNORE_VERMAGIC; + if (flags & KMOD_INSERT_FORCE_MODVERSION) + kernel_flags |= MODULE_INIT_IGNORE_MODVERSIONS; + + err = finit_module(kmod_file_get_fd(mod->file), args, kernel_flags); + if (err < 0) + err = -errno; + + return err; +} + +static int do_init_module(struct kmod_module *mod, unsigned int flags, + const char *args) +{ + struct kmod_elf *elf; + const void *mem; + off_t size; + int err; + + kmod_file_load_contents(mod->file); + + if (flags & (KMOD_INSERT_FORCE_VERMAGIC | KMOD_INSERT_FORCE_MODVERSION)) { + elf = kmod_file_get_elf(mod->file); + if (elf == NULL) { + err = -errno; + return err; + } + + if (flags & KMOD_INSERT_FORCE_MODVERSION) { + err = kmod_elf_strip_section(elf, "__versions"); + if (err < 0) + INFO(mod->ctx, "Failed to strip modversion: %s\n", strerror(-err)); + } + + if (flags & KMOD_INSERT_FORCE_VERMAGIC) { + err = kmod_elf_strip_vermagic(elf); + if (err < 0) + INFO(mod->ctx, "Failed to strip vermagic: %s\n", strerror(-err)); + } + + mem = kmod_elf_get_memory(elf); + } else { + mem = kmod_file_get_contents(mod->file); + } + size = kmod_file_get_size(mod->file); + + err = init_module(mem, size, args); + if (err < 0) + err = -errno; + + return err; +} + /** * kmod_module_insert_module: * @mod: kmod module @@ -881,9 +948,6 @@ KMOD_EXPORT int kmod_module_insert_module(struct kmod_module *mod, const char *options) { int err; - const void *mem; - off_t size; - struct kmod_elf *elf; const char *path; const char *args = options ? options : ""; @@ -904,52 +968,14 @@ KMOD_EXPORT int kmod_module_insert_module(struct kmod_module *mod, } } - if (kmod_file_get_direct(mod->file)) { - unsigned int kernel_flags = 0; - - if (flags & KMOD_INSERT_FORCE_VERMAGIC) - kernel_flags |= MODULE_INIT_IGNORE_VERMAGIC; - if (flags & KMOD_INSERT_FORCE_MODVERSION) - kernel_flags |= MODULE_INIT_IGNORE_MODVERSIONS; - - err = finit_module(kmod_file_get_fd(mod->file), args, kernel_flags); - if (err == 0 || errno != ENOSYS) - goto init_finished; - } - - kmod_file_load_contents(mod->file); - - if (flags & (KMOD_INSERT_FORCE_VERMAGIC | KMOD_INSERT_FORCE_MODVERSION)) { - elf = kmod_file_get_elf(mod->file); - if (elf == NULL) { - err = -errno; - return err; - } + err = do_finit_module(mod, flags, args); + if (err == -ENOSYS) + err = do_init_module(mod, flags, args); - if (flags & KMOD_INSERT_FORCE_MODVERSION) { - err = kmod_elf_strip_section(elf, "__versions"); - if (err < 0) - INFO(mod->ctx, "Failed to strip modversion: %s\n", strerror(-err)); - } - - if (flags & KMOD_INSERT_FORCE_VERMAGIC) { - err = kmod_elf_strip_vermagic(elf); - if (err < 0) - INFO(mod->ctx, "Failed to strip vermagic: %s\n", strerror(-err)); - } - - mem = kmod_elf_get_memory(elf); - } else { - mem = kmod_file_get_contents(mod->file); - } - size = kmod_file_get_size(mod->file); + if (err < 0) + INFO(mod->ctx, "Failed to insert module '%s': %s\n", + path, strerror(-err)); - err = init_module(mem, size, args); -init_finished: - if (err < 0) { - err = -errno; - INFO(mod->ctx, "Failed to insert module '%s': %m\n", path); - } return err; } From patchwork Thu Jun 1 22:39:59 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lucas De Marchi X-Patchwork-Id: 13264561 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id BDC7DC7EE23 for ; Thu, 1 Jun 2023 22:40:22 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231429AbjFAWkW (ORCPT ); Thu, 1 Jun 2023 18:40:22 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50394 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229542AbjFAWkV (ORCPT ); Thu, 1 Jun 2023 18:40:21 -0400 Received: from mail-ej1-x635.google.com (mail-ej1-x635.google.com [IPv6:2a00:1450:4864:20::635]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id A91B8133 for ; Thu, 1 Jun 2023 15:40:19 -0700 (PDT) Received: by mail-ej1-x635.google.com with SMTP id a640c23a62f3a-96f5d651170so576998566b.1 for ; Thu, 01 Jun 2023 15:40:19 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20221208; t=1685659217; x=1688251217; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=sUIr4zbU6vKwT8OnP+vGUDlU9LfEpC4TuQOUZ+IBSH4=; b=kNLxUsKsG01eA4VF1b8/ytsZouB3bCAT0DrXu4ttx7uTKtC7uBygJ6jnOXJycJHs01 81Zd/0S/fDl4Ix2w1oRKbuVPKWq6LGyr8ATLZ2DdKt0G+ih1e9r9Dlh6A6w+yHNoQIcN WGvS4g6WaXL0eWv9AQGpONsLoZ8Ph6Wh6vZ5bBHz498m69AFDTFPu/LoLoF9IQt/9Bc5 lkYoFvcTnV/WDdTVSVjE2SPGkqcb59Rw/2zm8pGf85Hs1oOl+fdr6aAycFw4BEFzlS3c Hx0hWskVtpzXfx2CptzFJU9Mpgv2oulSREacj/F+LLvNJCVkzfajP7Ens5qCYYZj3+VH qLsQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1685659217; x=1688251217; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=sUIr4zbU6vKwT8OnP+vGUDlU9LfEpC4TuQOUZ+IBSH4=; b=H8fBd6WJjOWWwKzxxxnDvOE0QnJa6ZIx21e3D3YU2/CdEK4FwANwQyHKTuO5Jj7E0a z9bcgBkky9ScJ2PQe9rYvKFUZDw89rXkuzm44YdKCdVrU9+bUW80JIH2UXQqsWEr9WFt 0eCixUrWU5PDzBGNuQtBn6x20l8hRg5w0jgw1w6zBfW6qjfLs1z+y2THkpWHQu31lh7Z 8T6dloS6+foPByPuc4kpTxKsd33DFUGaUesTxIHNH/6vkqntHfq1jaJESNeMuXg1fdBJ inMTOxCP9+tspCxmtTO0tm8qBByWc+MqtmXg4AFVlUFRlkD532GU8XNXyNjBCnWmvdWw Z2mg== X-Gm-Message-State: AC+VfDyhSQMSOmJalonfX3EatanTPu4/HBQFpXqc5EOGKkL4zvps1R4x ATywjVXKLcRNIXKA7GL5eO1sGa04H+4= X-Google-Smtp-Source: ACHHUZ50Rxlp86BkqwZ968gPQx4cUM2JK894O1wRH/cOxTyAAPmYASfbiVAIVRtDTW4YhBXBfINGrA== X-Received: by 2002:a17:907:e87:b0:974:5e8b:fc28 with SMTP id ho7-20020a1709070e8700b009745e8bfc28mr484888ejc.9.1685659217437; Thu, 01 Jun 2023 15:40:17 -0700 (PDT) Received: from ldmartin-desk2.jf.intel.com ([134.134.137.83]) by smtp.gmail.com with ESMTPSA id se24-20020a170906ce5800b009662b4230cesm11253318ejb.148.2023.06.01.15.40.15 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 01 Jun 2023 15:40:16 -0700 (PDT) From: Lucas De Marchi To: linux-modules@vger.kernel.org Cc: Luis Chamberlain , Lucas De Marchi Subject: [PATCH 3/5] libkmod: Keep track of compression type Date: Thu, 1 Jun 2023 15:39:59 -0700 Message-Id: <20230601224001.23397-4-lucas.de.marchi@gmail.com> X-Mailer: git-send-email 2.40.1 In-Reply-To: <20230601224001.23397-1-lucas.de.marchi@gmail.com> References: <20230601224001.23397-1-lucas.de.marchi@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: Do not only set the type as direct, but also keep track of the compression being used. This will allow using the in-kernel compression in future. Signed-off-by: Lucas De Marchi Reviewed-by: Luis Chamberlain --- libkmod/libkmod-file.c | 27 +++++++++++++++------------ libkmod/libkmod-internal.h | 7 +++++++ 2 files changed, 22 insertions(+), 12 deletions(-) diff --git a/libkmod/libkmod-file.c b/libkmod/libkmod-file.c index 1449c41..705770a 100644 --- a/libkmod/libkmod-file.c +++ b/libkmod/libkmod-file.c @@ -58,7 +58,7 @@ struct kmod_file { gzFile gzf; #endif int fd; - bool direct; + enum kmod_file_compression_type compression; off_t size; void *memory; const struct file_ops *ops; @@ -376,19 +376,20 @@ static const char magic_zlib[] = {0x1f, 0x8b}; static const struct comp_type { size_t magic_size; + enum kmod_file_compression_type compression; const char *magic_bytes; const struct file_ops ops; } comp_types[] = { #ifdef ENABLE_ZSTD - {sizeof(magic_zstd), magic_zstd, {load_zstd, unload_zstd}}, + {sizeof(magic_zstd), KMOD_FILE_COMPRESSION_ZSTD, magic_zstd, {load_zstd, unload_zstd}}, #endif #ifdef ENABLE_XZ - {sizeof(magic_xz), magic_xz, {load_xz, unload_xz}}, + {sizeof(magic_xz), KMOD_FILE_COMPRESSION_XZ, magic_xz, {load_xz, unload_xz}}, #endif #ifdef ENABLE_ZLIB - {sizeof(magic_zlib), magic_zlib, {load_zlib, unload_zlib}}, + {sizeof(magic_zlib), KMOD_FILE_COMPRESSION_ZLIB, magic_zlib, {load_zlib, unload_zlib}}, #endif - {0, NULL, {NULL, NULL}} + {0, KMOD_FILE_COMPRESSION_NONE, NULL, {NULL, NULL}} }; static int load_reg(struct kmod_file *file) @@ -403,7 +404,7 @@ static int load_reg(struct kmod_file *file) file->fd, 0); if (file->memory == MAP_FAILED) return -errno; - file->direct = true; + return 0; } @@ -448,7 +449,6 @@ struct kmod_file *kmod_file_open(const struct kmod_ctx *ctx, magic_size_max = itr->magic_size; } - file->direct = false; if (magic_size_max > 0) { char *buf = alloca(magic_size_max + 1); ssize_t sz; @@ -468,15 +468,18 @@ struct kmod_file *kmod_file_open(const struct kmod_ctx *ctx, } for (itr = comp_types; itr->ops.load != NULL; itr++) { - if (memcmp(buf, itr->magic_bytes, itr->magic_size) == 0) + if (memcmp(buf, itr->magic_bytes, itr->magic_size) == 0) { + file->ops = &itr->ops; + file->compression = itr->compression; break; + } } - if (itr->ops.load != NULL) - file->ops = &itr->ops; } - if (file->ops == NULL) + if (file->ops == NULL) { file->ops = ®_ops; + file->compression = KMOD_FILE_COMPRESSION_NONE; + } file->ctx = ctx; @@ -512,7 +515,7 @@ off_t kmod_file_get_size(const struct kmod_file *file) bool kmod_file_get_direct(const struct kmod_file *file) { - return file->direct; + return file->compression == KMOD_FILE_COMPRESSION_NONE; } int kmod_file_get_fd(const struct kmod_file *file) diff --git a/libkmod/libkmod-internal.h b/libkmod/libkmod-internal.h index 4799ed5..7b8a158 100644 --- a/libkmod/libkmod-internal.h +++ b/libkmod/libkmod-internal.h @@ -61,6 +61,13 @@ struct kmod_list { void *data; }; +enum kmod_file_compression_type { + KMOD_FILE_COMPRESSION_NONE = 0, + KMOD_FILE_COMPRESSION_ZSTD, + KMOD_FILE_COMPRESSION_XZ, + KMOD_FILE_COMPRESSION_ZLIB, +}; + struct kmod_list *kmod_list_append(struct kmod_list *list, const void *data) _must_check_ __attribute__((nonnull(2))); struct kmod_list *kmod_list_prepend(struct kmod_list *list, const void *data) _must_check_ __attribute__((nonnull(2))); struct kmod_list *kmod_list_remove(struct kmod_list *list) _must_check_; From patchwork Thu Jun 1 22:40:00 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lucas De Marchi X-Patchwork-Id: 13264563 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 371F5C7EE29 for ; Thu, 1 Jun 2023 22:40:24 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231354AbjFAWkX (ORCPT ); Thu, 1 Jun 2023 18:40:23 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50408 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231558AbjFAWkW (ORCPT ); Thu, 1 Jun 2023 18:40:22 -0400 Received: from mail-ed1-x535.google.com (mail-ed1-x535.google.com [IPv6:2a00:1450:4864:20::535]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 93EF2133 for ; Thu, 1 Jun 2023 15:40:21 -0700 (PDT) Received: by mail-ed1-x535.google.com with SMTP id 4fb4d7f45d1cf-51491b87565so2100166a12.1 for ; Thu, 01 Jun 2023 15:40:21 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20221208; t=1685659219; x=1688251219; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=KuIY6m6T2GoGWX1CRKzLylKddebbN2NyDB0hQA927hc=; b=MNHTw0J7L8YY8smAjK5Lc956UXVgAXdusEiUc35PZrjfV+9T8UnZ8Er9er2JX+6qx3 LiqZpBddmOfCeAORfj984mGAxZTbM7QWUI2uiewQFUqDizPOTGRJxZ9MmZW5LH+sX7tm AmqEmHYUS3Hb83QVd7ZKy6u0JxgPrXgwWnGrBvTzJPLeN7Y9f4ceyRB3MHD31G7BhMnN DGDwuGSJ1c6thWXu9tR08U87TYbujTpfReKmjMhx2X748SvrJqB8yZxKozk5JHdnd4o2 5LV9UYkJuYKuT2e81X4GGNxG3mH6NUkuoPJHvLiF8Alj0GnD0M7jmoxsS7SmB/ChIqlj ln1A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1685659219; x=1688251219; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=KuIY6m6T2GoGWX1CRKzLylKddebbN2NyDB0hQA927hc=; b=j4Jik5VEOTqE43sCvB7WWsWvWoebYMNQ/dUSrRh2aFMcK6Awx1Ih6MDs1OR7D4I6zD QjD5l3d7vcaNouvuJvqa5Z7dASOjV7F4jIHtGKXnXhijRxvmE11smadpO1u80bqbsIMv UV1+4Opsr9ssG2PUjhspkmBLd8gf3IxgM3T49ibey9VwCFponTkd6MZyq4ApFWjPkRiC C4OWLgQkZI65mzY5bIsoUK9IU/bbjH1kZUm35Q55IT6QQYczUny2w2l0246zQq2iaMhF Kl0e0/mNvH5bZeHn4wRw/h/UclNXwrPkux1CxfByGzC+D5gGcP4lA4V0ytnutlvqzV1V BB0Q== X-Gm-Message-State: AC+VfDw89iSVSCaOE8pnBALRbVfJOIfFX+E73wujQsuTShqpVB71yNOE wUqhhRCgdVvvkEbtqyeP3kO0TFEOFzs= X-Google-Smtp-Source: ACHHUZ7j90zM1/Cyv0X5ljCbojaSD2kfvh67Q/nAX8pGW13so4lezJsEBrvmhPZ4zqBZxTrAJujVmg== X-Received: by 2002:a17:907:7fa7:b0:94f:59aa:8a7c with SMTP id qk39-20020a1709077fa700b0094f59aa8a7cmr10784894ejc.20.1685659219497; Thu, 01 Jun 2023 15:40:19 -0700 (PDT) Received: from ldmartin-desk2.jf.intel.com ([134.134.137.83]) by smtp.gmail.com with ESMTPSA id se24-20020a170906ce5800b009662b4230cesm11253318ejb.148.2023.06.01.15.40.17 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 01 Jun 2023 15:40:18 -0700 (PDT) From: Lucas De Marchi To: linux-modules@vger.kernel.org Cc: Luis Chamberlain , Lucas De Marchi Subject: [PATCH 4/5] libkmod: Keep track of in-kernel compression support Date: Thu, 1 Jun 2023 15:40:00 -0700 Message-Id: <20230601224001.23397-5-lucas.de.marchi@gmail.com> X-Mailer: git-send-email 2.40.1 In-Reply-To: <20230601224001.23397-1-lucas.de.marchi@gmail.com> References: <20230601224001.23397-1-lucas.de.marchi@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: When creating the context, read /sys/kernel/compression to check what's the compression type supported by the kernel. This will later be used when loading modules to check if the decompression step has to happen in userspace or if it can be delegated to the kernel. Signed-off-by: Lucas De Marchi Reviewed-by: Luis Chamberlain Reviewed-by: Luis Chamberlain --- libkmod/libkmod.c | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/libkmod/libkmod.c b/libkmod/libkmod.c index 2670f9a..103469e 100644 --- a/libkmod/libkmod.c +++ b/libkmod/libkmod.c @@ -83,6 +83,7 @@ struct kmod_ctx { void *log_data; const void *userdata; char *dirname; + enum kmod_file_compression_type kernel_compression; struct kmod_config *config; struct hash *modules_by_name; struct index_mm *indexes[_KMOD_INDEX_MODULES_SIZE]; @@ -227,6 +228,40 @@ static char *get_kernel_release(const char *dirname) return p; } +static enum kmod_file_compression_type get_kernel_compression(struct kmod_ctx *ctx) +{ + const char *path = "/sys/module/compression"; + char buf[16]; + int fd; + int err; + + fd = open(path, O_RDONLY|O_CLOEXEC); + if (fd < 0) { + /* Not having the file is not an error: kernel may be too old */ + DBG(ctx, "could not open '%s' for reading: %m\n", path); + return KMOD_FILE_COMPRESSION_NONE; + } + + err = read_str_safe(fd, buf, sizeof(buf)); + close(fd); + if (err < 0) { + ERR(ctx, "could not read from '%s': %s\n", + path, strerror(-err)); + return KMOD_FILE_COMPRESSION_NONE; + } + + if (streq(buf, "zstd\n")) + return KMOD_FILE_COMPRESSION_ZSTD; + else if (streq(buf, "xz\n")) + return KMOD_FILE_COMPRESSION_XZ; + else if (streq(buf, "gzip\n")) + return KMOD_FILE_COMPRESSION_ZLIB; + + ERR(ctx, "unknown kernel compression %s", buf); + + return KMOD_FILE_COMPRESSION_NONE; +} + /** * kmod_new: * @dirname: what to consider as linux module's directory, if NULL @@ -272,6 +307,8 @@ KMOD_EXPORT struct kmod_ctx *kmod_new(const char *dirname, if (env != NULL) kmod_set_log_priority(ctx, log_priority(env)); + ctx->kernel_compression = get_kernel_compression(ctx); + if (config_paths == NULL) config_paths = default_config_paths; err = kmod_config_new(ctx, &ctx->config, config_paths); From patchwork Thu Jun 1 22:40:01 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lucas De Marchi X-Patchwork-Id: 13264564 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 85E61C77B7A for ; Thu, 1 Jun 2023 22:40:28 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230492AbjFAWk1 (ORCPT ); Thu, 1 Jun 2023 18:40:27 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50418 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231558AbjFAWk0 (ORCPT ); Thu, 1 Jun 2023 18:40:26 -0400 Received: from mail-lj1-x234.google.com (mail-lj1-x234.google.com [IPv6:2a00:1450:4864:20::234]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 8504712C for ; Thu, 1 Jun 2023 15:40:24 -0700 (PDT) Received: by mail-lj1-x234.google.com with SMTP id 38308e7fff4ca-2b1a6a8e851so12853341fa.2 for ; Thu, 01 Jun 2023 15:40:24 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20221208; t=1685659222; x=1688251222; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=FBkV9oYQPFu7USkDL/ITikjBCLxq5r+G6YZDTAlhVT8=; b=Bg4Gnw+kQbHtCTcaxAuNG/+ek6ULfWBV/ClnH3srOBd8BpEewrwJpuGC5I9m8zEXl8 R725RSkr9ip+pZ6ja/LYABZECdqOML8CGJhd7LeMo88O/TEcl1kqLjAcBIgWfbdFA38X 1FlsvzV4iiRWXTx7sQDQrMnfTCtNFMzilS9lKRk9ut+sRogRwA1GzF+w8Hm7zzkYCgft COSJswxh4Xxtss2eS776AGvDSzA2zMqEfC6FqCZRMJLnzTmofFAXu69ZPJFRu6e+5C/m QU0DGLpa/Gyxq6HNk97Kr9eg5bvjXi9H8wllT75RACgbTsJHXP7esCTlmGiyslvwp4Vi fRSA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1685659222; x=1688251222; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=FBkV9oYQPFu7USkDL/ITikjBCLxq5r+G6YZDTAlhVT8=; b=EqP/Cax+1QiOXvHqVBI3uX1dZSu85bgFmDOKJTu0ESnrNeHSGxgMfpEaxbizUr1PPK D5CfLtCtoyZNWiHmLNmEgjYDY8mTiO2UkJGlv35kGrz3yY+JEIA4r2NwQUJ2/zjUU+4y L2nLPhlYZaRpYKcu3IEOFMh1rnQrTCorZKV/fjJ883pYSjmxsVBFXfuQWBfqd8/Izkz8 yp2xq/bVbtOSOsJ+2CYX5MzVqjwvOG/NP7FAGMN79XsqfafFYd2GLSYRMEvgTAgUFgiZ sUACLAch0tZ3VudkSPY6EVHRMtaeYtuw+2Ml2PJjalRJB0ibuGVGa4ID8iDDwlhGHJ78 8KEg== X-Gm-Message-State: AC+VfDwfNccsvK3NObQjX4qyemqAs8dd+AmJnuxNd+6Xe7cbOKF/pBzy RIi1zglw2NGcEwS19j8YQ54cJWhtpns= X-Google-Smtp-Source: ACHHUZ42clg0PX/wg5XsVCyhnnRJdeEPVVfMu912kcjAE4zF9wqcmXEeO51Xosh3iN2aGe76tLPYQw== X-Received: by 2002:a2e:9c8b:0:b0:2ad:90c8:7fa3 with SMTP id x11-20020a2e9c8b000000b002ad90c87fa3mr540251lji.29.1685659221698; Thu, 01 Jun 2023 15:40:21 -0700 (PDT) Received: from ldmartin-desk2.jf.intel.com ([134.134.137.83]) by smtp.gmail.com with ESMTPSA id se24-20020a170906ce5800b009662b4230cesm11253318ejb.148.2023.06.01.15.40.19 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 01 Jun 2023 15:40:20 -0700 (PDT) From: Lucas De Marchi To: linux-modules@vger.kernel.org Cc: Luis Chamberlain , Lucas De Marchi Subject: [PATCH 5/5] libkmod: Use kernel decompression when available Date: Thu, 1 Jun 2023 15:40:01 -0700 Message-Id: <20230601224001.23397-6-lucas.de.marchi@gmail.com> X-Mailer: git-send-email 2.40.1 In-Reply-To: <20230601224001.23397-1-lucas.de.marchi@gmail.com> References: <20230601224001.23397-1-lucas.de.marchi@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: With the recent changes to bypass loading the file it's possible to reduce the work in userspace and delegating it to the kernel. Without any compression to illustrate: Before: read(3, "\177ELF\2\1", 6) = 6 lseek(3, 0, SEEK_SET) = 0 newfstatat(3, "", {st_mode=S_IFREG|0644, st_size=238592, ...}, AT_EMPTY_PATH) = 0 mmap(NULL, 238592, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7fd85cbd1000 finit_module(3, "", 0) = 0 munmap(0x7fd85cbd1000, 238592) = 0 close(3) = 0 After: read(3, "\177ELF\2\1", 6) = 6 lseek(3, 0, SEEK_SET) = 0 finit_module(3, "", 0) = 0 close(3) = 0 When using kernel compression now it's also possible to direct libkmod to take the finit_module() path, avoiding the decompression in userspace and just delegating it to the kernel. Before: read(3, "(\265/\375\244\0", 6) = 6 lseek(3, 0, SEEK_SET) = 0 read(3, "(\265/\375\244", 5) = 5 mmap(NULL, 135168, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f3fa431e000 read(3, "\0\244\3\0\\y\6", 7) = 7 mmap(NULL, 372736, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f3fa414f000 brk(0x55944c6a1000) = 0x55944c6a1000 read(3, "\356|\6G\27U\20 \312\260s\211\335\333\263\326\330\336\273O\211\356\306K\360Z\341\374U6\342\221"..., 53038) = 53038 mremap(0x7f3fa431e000, 135168, 266240, MREMAP_MAYMOVE) = 0x7f3fa410e000 read(3, ",;\3\nqf\311\362\325\211\7\341\375A\355\221\371L\\\5\7\375 \32\246<(\258=K\304"..., 20851) = 20851 mremap(0x7f3fa410e000, 266240, 397312, MREMAP_MAYMOVE) = 0x7f3fa40ad000 read(3, ")\36\250\213", 4) = 4 read(3, "", 4) = 0 munmap(0x7f3fa414f000, 372736) = 0 init_module(0x7f3fa40ad010, 238592, "") = 0 munmap(0x7f3fa40ad000, 397312) = 0 close(3) = 0 After: read(3, "(\265/\375\244P", 6) = 6 lseek(3, 0, SEEK_SET) = 0 finit_module(3, "", 0x4 /* MODULE_INIT_??? */) = 0 close(3) = 0 Signed-off-by: Lucas De Marchi --- libkmod/libkmod-file.c | 4 ++-- libkmod/libkmod-internal.h | 3 ++- libkmod/libkmod-module.c | 17 +++++++++++++---- libkmod/libkmod.c | 5 +++++ 4 files changed, 22 insertions(+), 7 deletions(-) diff --git a/libkmod/libkmod-file.c b/libkmod/libkmod-file.c index 705770a..ffdda92 100644 --- a/libkmod/libkmod-file.c +++ b/libkmod/libkmod-file.c @@ -513,9 +513,9 @@ off_t kmod_file_get_size(const struct kmod_file *file) return file->size; } -bool kmod_file_get_direct(const struct kmod_file *file) +enum kmod_file_compression_type kmod_file_get_compression(const struct kmod_file *file) { - return file->compression == KMOD_FILE_COMPRESSION_NONE; + return file->compression; } int kmod_file_get_fd(const struct kmod_file *file) diff --git a/libkmod/libkmod-internal.h b/libkmod/libkmod-internal.h index 7b8a158..edb4eac 100644 --- a/libkmod/libkmod-internal.h +++ b/libkmod/libkmod-internal.h @@ -112,6 +112,7 @@ void kmod_pool_add_module(struct kmod_ctx *ctx, struct kmod_module *mod, const c void kmod_pool_del_module(struct kmod_ctx *ctx, struct kmod_module *mod, const char *key) __attribute__((nonnull(1, 2, 3))); const struct kmod_config *kmod_get_config(const struct kmod_ctx *ctx) __attribute__((nonnull(1))); +enum kmod_file_compression_type kmod_get_kernel_compression(const struct kmod_ctx *ctx) __attribute__((nonnull(1))); /* libkmod-config.c */ struct kmod_config_path { @@ -162,7 +163,7 @@ struct kmod_elf *kmod_file_get_elf(struct kmod_file *file) __attribute__((nonnul int kmod_file_load_contents(struct kmod_file *file) _must_check_ __attribute__((nonnull(1))); void *kmod_file_get_contents(const struct kmod_file *file) _must_check_ __attribute__((nonnull(1))); off_t kmod_file_get_size(const struct kmod_file *file) _must_check_ __attribute__((nonnull(1))); -bool kmod_file_get_direct(const struct kmod_file *file) _must_check_ __attribute__((nonnull(1))); +enum kmod_file_compression_type kmod_file_get_compression(const struct kmod_file *file) _must_check_ __attribute__((nonnull(1))); int kmod_file_get_fd(const struct kmod_file *file) _must_check_ __attribute__((nonnull(1))); void kmod_file_unref(struct kmod_file *file) __attribute__((nonnull(1))); diff --git a/libkmod/libkmod-module.c b/libkmod/libkmod-module.c index 6ed5ad4..a9e1be8 100644 --- a/libkmod/libkmod-module.c +++ b/libkmod/libkmod-module.c @@ -864,15 +864,24 @@ extern long init_module(const void *mem, unsigned long len, const char *args); static int do_finit_module(struct kmod_module *mod, unsigned int flags, const char *args) { + enum kmod_file_compression_type compression, kernel_compression; unsigned int kernel_flags = 0; int err; /* - * Re-use ENOSYS, returned when there is no such syscall, so the - * fallback to init_module applies + * When module is not compressed or its compression type matches the + * one in use by the kernel, there is no need to read the file + * in userspace. Otherwise, re-use ENOSYS to trigger the same fallback + * as when finit_module() is not supported. */ - if (!kmod_file_get_direct(mod->file)) - return -ENOSYS; + compression = kmod_file_get_compression(mod->file); + kernel_compression = kmod_get_kernel_compression(mod->ctx); + if (!(compression == KMOD_FILE_COMPRESSION_NONE || + compression == kernel_compression)) + return ENOSYS; + + if (compression != KMOD_FILE_COMPRESSION_NONE) + kernel_flags |= MODULE_INIT_COMPRESSED_FILE; if (flags & KMOD_INSERT_FORCE_VERMAGIC) kernel_flags |= MODULE_INIT_IGNORE_VERMAGIC; diff --git a/libkmod/libkmod.c b/libkmod/libkmod.c index 103469e..1b8773c 100644 --- a/libkmod/libkmod.c +++ b/libkmod/libkmod.c @@ -1016,3 +1016,8 @@ const struct kmod_config *kmod_get_config(const struct kmod_ctx *ctx) { return ctx->config; } + +enum kmod_file_compression_type kmod_get_kernel_compression(const struct kmod_ctx *ctx) +{ + return ctx->kernel_compression; +}