Received: by 2002:a05:6a10:8c0a:0:0:0:0 with SMTP id go10csp6474284pxb; Wed, 17 Feb 2021 05:40:06 -0800 (PST) X-Google-Smtp-Source: ABdhPJyfxgDzHsSTu2zBtB6m9ZWkELGflv4DIEYNv6TAYnr11meLDKkU4ciObjefmQOG538Fx1yl X-Received: by 2002:a17:906:c455:: with SMTP id ck21mr26487976ejb.354.1613569205874; Wed, 17 Feb 2021 05:40:05 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1613569205; cv=none; d=google.com; s=arc-20160816; b=LfE/a/C1ivORdNZrRjb4Ax4CJ8YWJISnlz/VqzvThrLmF7jKzJoezhS6jrAS8i2UK/ vG9+xkFX6hBU+Xz+PjU01ULnyOA8P/JHZn/l1+pSQFMVLR9hfjcSkhks2Nj3kN6TZlOs i7jxIwbOYxXIS62XREc5bkedhtOK1Um7bQOJFCvLoUnewBLzwpYeum4hoHqBShDhMb7r gAWIPWH0tuXKGBwGBDNKg4tsXchbRjxSQ/dsEd5u1UhPhz0q161M3mn+BaP7jW9HnYxG dx27GdZeOBsohp8+wpOu6MBBg0GCKxTe8IWmJ1mKfOu6tW3qJ2Oop4nCd9rkbwAI6g+w VkYA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:mime-version:user-agent:references:in-reply-to :subject:cc:to:from:message-id:date; bh=D/UgDzWnFIFKgbosSvHRv12CTEnWfU60QouyJQ6rYzY=; b=jQr3hmnaoIiEg75LGU5hM99WjgUvkzR8EkNy/DWExzi+kK1ilMhVzdBS8cazEewsCQ icPtFGYfXifNElTWeP0Ro2wQANheh5a2ftqFqtjnwXvXcoV+npngLd5b+tq7uDQgOtiW fYsdnsdAYPzVNPjkPz4mpikJBuJjw4dQPdL62bLB2RdpZwiOc8igBI+eHhmeDklW8ttz QV8CAyB09emsNfalYPvYoAP8Segl5un1MA3WJ4hFMrSx4LiBWLi/i9FzkAHJ1KP/2KN2 b7pryFgVgpJhaQEjZUSZX8ebVgQ2JDzf6OH7diHfmvz2GYSi3xuMbFWU/Vt7ntpaWB02 VOnA== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id o26si1362829edw.74.2021.02.17.05.39.43; Wed, 17 Feb 2021 05:40:05 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232480AbhBQNaz (ORCPT + 99 others); Wed, 17 Feb 2021 08:30:55 -0500 Received: from mx2.suse.de ([195.135.220.15]:35472 "EHLO mx2.suse.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231248AbhBQNX0 (ORCPT ); Wed, 17 Feb 2021 08:23:26 -0500 X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay2.suse.de (unknown [195.135.221.27]) by mx2.suse.de (Postfix) with ESMTP id 4F1F5B8F2; Wed, 17 Feb 2021 13:22:41 +0000 (UTC) Date: Wed, 17 Feb 2021 14:22:41 +0100 Message-ID: From: Takashi Iwai To: Luis Chamberlain Cc: Greg Kroah-Hartman , "Rafael J . Wysocki" , linux-kernel@vger.kernel.org Subject: Re: [PATCH RFC 1/4] firmware: Add the support for ZSTD-compressed firmware files In-Reply-To: <20210217131644.GM4332@42.do-not-panic.com> References: <20210127154939.13288-1-tiwai@suse.de> <20210127154939.13288-2-tiwai@suse.de> <20210217131644.GM4332@42.do-not-panic.com> User-Agent: Wanderlust/2.15.9 (Almost Unreal) SEMI/1.14.6 (Maruoka) FLIM/1.14.9 (=?UTF-8?B?R29qxY0=?=) APEL/10.8 Emacs/25.3 (x86_64-suse-linux-gnu) MULE/6.0 (HANACHIRUSATO) MIME-Version: 1.0 (generated by SEMI 1.14.6 - "Maruoka") Content-Type: text/plain; charset=US-ASCII Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Wed, 17 Feb 2021 14:16:44 +0100, Luis Chamberlain wrote: > > On Wed, Jan 27, 2021 at 04:49:36PM +0100, Takashi Iwai wrote: > > Due to the popular demands on ZSTD, here is a patch to add a support > > of ZSTD-compressed firmware files via the direct firmware loader. > > It's just like XZ-compressed file support, providing a decompressor > > with ZSTD. Since ZSTD API can give the decompression size beforehand, > > the code is even simpler than XZ. > > > > Signed-off-by: Takashi Iwai > > --- > > drivers/base/firmware_loader/Kconfig | 21 ++++++-- > > drivers/base/firmware_loader/main.c | 74 ++++++++++++++++++++++++++-- > > 2 files changed, 87 insertions(+), 8 deletions(-) > > > > diff --git a/drivers/base/firmware_loader/Kconfig b/drivers/base/firmware_loader/Kconfig > > index 5b24f3959255..f5307978927c 100644 > > --- a/drivers/base/firmware_loader/Kconfig > > +++ b/drivers/base/firmware_loader/Kconfig > > @@ -157,17 +157,28 @@ 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). > > +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" > > diff --git a/drivers/base/firmware_loader/main.c b/drivers/base/firmware_loader/main.c > > index 78355095e00d..71332ed4959d 100644 > > --- a/drivers/base/firmware_loader/main.c > > +++ b/drivers/base/firmware_loader/main.c > > @@ -34,6 +34,7 @@ > > #include > > #include > > #include > > +#include > > #include > > > > #include > > @@ -362,10 +363,72 @@ 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->data) { > > + out_size = fw_priv->allocated_size; > > + out_buf = fw_priv->data; > > + } else { > > + out_size = ZSTD_findDecompressedSize(in_buffer, in_size); > > + if (out_size == ZSTD_CONTENTSIZE_UNKNOWN || > > + out_size == ZSTD_CONTENTSIZE_ERROR) { > > + dev_dbg(dev, "%s: invalid decompression size\n", __func__); > > + return -EINVAL; > > + } > > + out_buf = vzalloc(out_size); > > + if (!out_buf) > > + return -ENOMEM; > > + } > > + > > + workspace_size = ZSTD_DCtxWorkspaceBound(); > > + workspace = kvzalloc(workspace_size, GFP_KERNEL); > > + if (!workspace) { > > + err = -ENOMEM; > > + goto error; > > + } > > + > > + ctx = ZSTD_initDCtx(workspace, workspace_size); > > + if (!ctx) { > > + dev_dbg(dev, "%s: failed to initialize context\n", __func__); > > + err = -EINVAL; > > + goto error; > > + } > > + > > + len = ZSTD_decompressDCtx(ctx, out_buf, out_size, in_buffer, in_size); > > + if (ZSTD_isError(len)) { > > + dev_dbg(dev, "%s: failed to decompress: %d\n", __func__, > > + ZSTD_getErrorCode(len)); > > + err = -EINVAL; > > + goto error; > > + } > > + > > + fw_priv->size = len; > > + if (!fw_priv->data) > > + fw_priv->data = out_buf; > > + err = 0; > > + > > + error: > > + kvfree(workspace); > > + if (!fw_priv->data) > > + 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) > > { > > @@ -459,7 +522,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]; > > @@ -814,7 +877,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); > > Since this is growing, it would be nicer if we avoid the #ifdef mess and > simply have code iterate over supported compressions, and this is > observed here in one line. If it ever grows further, yeah, but I guess this won't happen so often :) As of now, I chose the open-code as there are only two. thanks, Takashi