Received: by 2002:a05:6a10:6d10:0:0:0:0 with SMTP id gq16csp836648pxb; Fri, 22 Apr 2022 12:13:43 -0700 (PDT) X-Google-Smtp-Source: ABdhPJzA0oXeCHiuUkYZ/ZB+CSLKEBLlnPPhjtV3oAZ71L+lMPxVDBj+SarDF5Ym4m8BQ3NVf3G+ X-Received: by 2002:a17:90b:4d11:b0:1d2:a600:3014 with SMTP id mw17-20020a17090b4d1100b001d2a6003014mr18313998pjb.108.1650654822952; Fri, 22 Apr 2022 12:13:42 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1650654822; cv=none; d=google.com; s=arc-20160816; b=X07c8VdQgs+JLsnaUV0uNtC5danxEXcxhXU0N0Yk5gDu8gb5dQVNIdaz7DmAfKbndB UtnWjIQtS5vZUFJOzRkkXvBqiSRVQzq7xaiO3eAFfSXAWY8bA4B45GFku5pckUKJWCDw 6WEKB4w766YlNsCx1/qbQgKwEO1jjMGSK2LUhmti7roBKlg0EdTHGc16IZ1fUyuv/RF3 QU/VFFO3YxkYZvKD3HyETL8waDHZxhxQeaAG1p56v1/TkhUjWPVm24Pc1xY6foY0JTcZ pfZEBsKvApqkVg6YQlnQsUpznJ1MsRuUS7qWPETv2CoxglU6IoCJUE6AmHQP/kATNboa VxxA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature:dkim-signature; bh=U3HQQK/ahKzOFQfSanytEFirEBOLzYKPfyJHKxVcTxg=; b=m0YQf2kHhcD1wcLWfRyNqFL2qx33JzfhrKf57LvekvJe+IQZRWGPoqlVpibwd4dpEm Q82oms8Kamj1x8JNivFAkzm3tGRGUYekoYNH9fPGYcFsZVR+f89if1aaTAngGiEPjwSP vFYMNs2ZwQSO4JtAQLqiH819ZiqMlrZSswoGXQgMksCsmSuGsZvXo5tdE6BxMpSJYGu5 4YFinuLVCjJz1nYImbnum8hBuw1sScxBxVknvEa9Da9cQe8vqs1pfL9fnnuTvzvCsV3t 69xmZKfwgWlsjWuUNrm6LrnXOddzfp+ijS7USts3ndosD7FaNTLSL3K9USWTFX5tqxq4 vSGw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@suse.de header.s=susede2_rsa header.b=jOefWiU2; dkim=neutral (no key) header.i=@suse.de; spf=softfail (google.com: domain of transitioning linux-kernel-owner@vger.kernel.org does not designate 23.128.96.19 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=suse.de Return-Path: Received: from lindbergh.monkeyblade.net (lindbergh.monkeyblade.net. [23.128.96.19]) by mx.google.com with ESMTPS id kk15-20020a17090b4a0f00b001d1ad44a667si14185325pjb.6.2022.04.22.12.13.42 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 22 Apr 2022 12:13:42 -0700 (PDT) Received-SPF: softfail (google.com: domain of transitioning linux-kernel-owner@vger.kernel.org does not designate 23.128.96.19 as permitted sender) client-ip=23.128.96.19; Authentication-Results: mx.google.com; dkim=pass header.i=@suse.de header.s=susede2_rsa header.b=jOefWiU2; dkim=neutral (no key) header.i=@suse.de; spf=softfail (google.com: domain of transitioning linux-kernel-owner@vger.kernel.org does not designate 23.128.96.19 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=suse.de Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id 16B941524A7; Fri, 22 Apr 2022 11:30:26 -0700 (PDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1390107AbiDUPcP (ORCPT + 99 others); Thu, 21 Apr 2022 11:32:15 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:58386 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1390075AbiDUPcH (ORCPT ); Thu, 21 Apr 2022 11:32:07 -0400 Received: from smtp-out2.suse.de (smtp-out2.suse.de [195.135.220.29]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id E31D543391; Thu, 21 Apr 2022 08:29:15 -0700 (PDT) Received: from relay2.suse.de (relay2.suse.de [149.44.160.134]) by smtp-out2.suse.de (Postfix) with ESMTP id 8B9FE1F748; Thu, 21 Apr 2022 15:29:14 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_rsa; t=1650554954; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=U3HQQK/ahKzOFQfSanytEFirEBOLzYKPfyJHKxVcTxg=; b=jOefWiU2lR+aS8LI47ZgQeSB8RKfnCfjIhixUnIvoba8WlrYLNULzRl13NnHCnXx5UD57B LNOP7FnHhM8TuL08BgNraLdMNfVthVfVmVlY/5p9UyyyzMAVYhp6YpbeqhrNwLQlC1oMMw hbFFBVbkEOncbaQ1tQ8J+nPx64AuE6U= DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_ed25519; t=1650554954; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=U3HQQK/ahKzOFQfSanytEFirEBOLzYKPfyJHKxVcTxg=; b=0zoWgrUpp9wKGyanjC1G4AZ4vcnkyICkdUZFwH/Q49a3KTcmyLyvAYErSgyihKKcTT61De cqnBo2A8iMhYAKBw== Received: from alsa1.nue.suse.com (alsa1.suse.de [10.160.4.42]) by relay2.suse.de (Postfix) with ESMTP id 818FD2C14B; Thu, 21 Apr 2022 15:29:14 +0000 (UTC) From: Takashi Iwai To: Luis Chamberlain Cc: Greg Kroah-Hartman , "Rafael J . Wysocki" , Nick Terrell , Shuah Khan , linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org Subject: [PATCH 1/5] firmware: Add the support for ZSTD-compressed firmware files Date: Thu, 21 Apr 2022 17:29:04 +0200 Message-Id: <20220421152908.4718-2-tiwai@suse.de> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20220421152908.4718-1-tiwai@suse.de> References: <20220421152908.4718-1-tiwai@suse.de> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-2.0 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, MAILING_LIST_MULTI,RDNS_NONE,SPF_HELO_NONE autolearn=no autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org As the growing demand on ZSTD compressions, there have been requests for the support of ZSTD-compressed firmware files, so here it is: this patch extends the firmware loader code to allow loading ZSTD files. The implementation is fairly straightforward, it just adds a ZSTD decompression routine for the file expander. (And the code is even simpler than XZ thanks to the ZSTD API that gives the original decompressed size from the header.) Tested-by: Piotr Gorski Link: https://lore.kernel.org/all/20210127154939.13288-1-tiwai@suse.de/ Signed-off-by: Takashi Iwai --- drivers/base/firmware_loader/Kconfig | 24 ++++++--- drivers/base/firmware_loader/main.c | 76 ++++++++++++++++++++++++++-- 2 files changed, 91 insertions(+), 9 deletions(-) diff --git a/drivers/base/firmware_loader/Kconfig b/drivers/base/firmware_loader/Kconfig index 38f3b66bf52b..08bb50451a96 100644 --- a/drivers/base/firmware_loader/Kconfig +++ b/drivers/base/firmware_loader/Kconfig @@ -159,21 +159,33 @@ config FW_LOADER_USER_HELPER_FALLBACK config FW_LOADER_COMPRESS bool "Enable compressed firmware support" - select FW_LOADER_PAGED_BUF - select XZ_DEC help This option enables the support for loading compressed firmware files. The caller of firmware API receives the decompressed file content. The compressed file is loaded as a fallback, only after loading the raw file failed at first. - Currently only XZ-compressed files are supported, and they have to - be compressed with either none or crc32 integrity check type (pass - "-C crc32" option to xz command). - Compressed firmware support does not apply to firmware images that are built into the kernel image (CONFIG_EXTRA_FIRMWARE). +if FW_LOADER_COMPRESS +config FW_LOADER_COMPRESS_XZ + bool "Enable XZ-compressed firmware support" + select FW_LOADER_PAGED_BUF + select XZ_DEC + help + This option adds the support for XZ-compressed files. + The files have to be compressed with either none or crc32 + integrity check type (pass "-C crc32" option to xz command). + +config FW_LOADER_COMPRESS_ZSTD + bool "Enable ZSTD-compressed firmware support" + select ZSTD_DECOMPRESS + help + This option adds the support for ZSTD-compressed files. + +endif # FW_LOADER_COMPRESS + config FW_CACHE bool "Enable firmware caching during suspend" depends on PM_SLEEP diff --git a/drivers/base/firmware_loader/main.c b/drivers/base/firmware_loader/main.c index 94d1789a233e..74830aeec7f6 100644 --- a/drivers/base/firmware_loader/main.c +++ b/drivers/base/firmware_loader/main.c @@ -35,6 +35,7 @@ #include #include #include +#include #include #include @@ -304,10 +305,74 @@ int fw_map_paged_buf(struct fw_priv *fw_priv) } #endif +/* + * ZSTD-compressed firmware support + */ +#ifdef CONFIG_FW_LOADER_COMPRESS_ZSTD +static int fw_decompress_zstd(struct device *dev, struct fw_priv *fw_priv, + size_t in_size, const void *in_buffer) +{ + size_t len, out_size, workspace_size; + void *workspace, *out_buf; + zstd_dctx *ctx; + int err; + + if (fw_priv->allocated_size) { + out_size = fw_priv->allocated_size; + out_buf = fw_priv->data; + } else { + zstd_frame_header params; + + if (zstd_get_frame_header(¶ms, in_buffer, in_size) || + params.frameContentSize == ZSTD_CONTENTSIZE_UNKNOWN) { + dev_dbg(dev, "%s: invalid zstd header\n", __func__); + return -EINVAL; + } + out_size = params.frameContentSize; + out_buf = vzalloc(out_size); + if (!out_buf) + return -ENOMEM; + } + + workspace_size = zstd_dctx_workspace_bound(); + workspace = kvzalloc(workspace_size, GFP_KERNEL); + if (!workspace) { + err = -ENOMEM; + goto error; + } + + ctx = zstd_init_dctx(workspace, workspace_size); + if (!ctx) { + dev_dbg(dev, "%s: failed to initialize context\n", __func__); + err = -EINVAL; + goto error; + } + + len = zstd_decompress_dctx(ctx, out_buf, out_size, in_buffer, in_size); + if (zstd_is_error(len)) { + dev_dbg(dev, "%s: failed to decompress: %d\n", __func__, + zstd_get_error_code(len)); + err = -EINVAL; + goto error; + } + + if (!fw_priv->allocated_size) + fw_priv->data = out_buf; + fw_priv->size = len; + err = 0; + + error: + kvfree(workspace); + if (err && !fw_priv->allocated_size) + vfree(out_buf); + return err; +} +#endif /* CONFIG_FW_LOADER_COMPRESS_ZSTD */ + /* * XZ-compressed firmware support */ -#ifdef CONFIG_FW_LOADER_COMPRESS +#ifdef CONFIG_FW_LOADER_COMPRESS_XZ /* show an error and return the standard error code */ static int fw_decompress_xz_error(struct device *dev, enum xz_ret xz_ret) { @@ -401,7 +466,7 @@ static int fw_decompress_xz(struct device *dev, struct fw_priv *fw_priv, else return fw_decompress_xz_pages(dev, fw_priv, in_size, in_buffer); } -#endif /* CONFIG_FW_LOADER_COMPRESS */ +#endif /* CONFIG_FW_LOADER_COMPRESS_XZ */ /* direct firmware loading support */ static char fw_path_para[256]; @@ -757,7 +822,12 @@ _request_firmware(const struct firmware **firmware_p, const char *name, if (!(opt_flags & FW_OPT_PARTIAL)) nondirect = true; -#ifdef CONFIG_FW_LOADER_COMPRESS +#ifdef CONFIG_FW_LOADER_COMPRESS_ZSTD + if (ret == -ENOENT && nondirect) + ret = fw_get_filesystem_firmware(device, fw->priv, ".zst", + fw_decompress_zstd); +#endif +#ifdef CONFIG_FW_LOADER_COMPRESS_XZ if (ret == -ENOENT && nondirect) ret = fw_get_filesystem_firmware(device, fw->priv, ".xz", fw_decompress_xz); -- 2.31.1