From nobody Fri May 3 21:17:55 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1506086772159756.3666338305892; Fri, 22 Sep 2017 06:26:12 -0700 (PDT) Received: from localhost ([::1]:58899 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dvNxw-0001DR-8M for importer@patchew.org; Fri, 22 Sep 2017 09:26:00 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:43653) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dvNwU-0000Lp-Ow for qemu-devel@nongnu.org; Fri, 22 Sep 2017 09:24:31 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1dvNwT-0004xZ-Qu for qemu-devel@nongnu.org; Fri, 22 Sep 2017 09:24:30 -0400 Received: from mx1.redhat.com ([209.132.183.28]:41812) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1dvNwT-0004ww-LV for qemu-devel@nongnu.org; Fri, 22 Sep 2017 09:24:29 -0400 Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.phx2.redhat.com [10.5.11.14]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id AF5777F3F6; Fri, 22 Sep 2017 13:24:28 +0000 (UTC) Received: from localhost (ovpn-112-42.ams2.redhat.com [10.36.112.42]) by smtp.corp.redhat.com (Postfix) with ESMTP id F1F7A5D96E; Fri, 22 Sep 2017 13:24:23 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com AF5777F3F6 Authentication-Results: ext-mx01.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com Authentication-Results: ext-mx01.extmail.prod.ext.phx2.redhat.com; spf=fail smtp.mailfrom=marcandre.lureau@redhat.com From: marcandre.lureau@redhat.com To: linux-kernel@vger.kernel.org Date: Fri, 22 Sep 2017 15:24:08 +0200 Message-Id: <20170922132412.9408-2-marcandre.lureau@redhat.com> In-Reply-To: <20170922132412.9408-1-marcandre.lureau@redhat.com> References: <20170922132412.9408-1-marcandre.lureau@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.14 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.25]); Fri, 22 Sep 2017 13:24:28 +0000 (UTC) Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PATCH v3 1/5] fw_cfg: fix the command line module name X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= , somlo@cmu.edu, qemu-devel@nongnu.org, mst@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" From: Marc-Andr=C3=A9 Lureau Signed-off-by: Marc-Andr=C3=A9 Lureau --- drivers/firmware/qemu_fw_cfg.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/firmware/qemu_fw_cfg.c b/drivers/firmware/qemu_fw_cfg.c index 0e2011636fbb..5cfe39f7a45f 100644 --- a/drivers/firmware/qemu_fw_cfg.c +++ b/drivers/firmware/qemu_fw_cfg.c @@ -10,9 +10,9 @@ * and select subsets of aarch64), a Device Tree node (on arm), or using * a kernel module (or command line) parameter with the following syntax: * - * [fw_cfg.]ioport=3D@[::] + * [qemu_fw_cfg.]ioport=3D@[::] * or - * [fw_cfg.]mmio=3D@[::] + * [qemu_fw_cfg.]mmio=3D@[::] * * where: * :=3D size of ioport or mmio range @@ -21,9 +21,9 @@ * :=3D (optional) offset of data register * * e.g.: - * fw_cfg.ioport=3D2@0x510:0:1 (the default on x86) + * qemu_fw_cfg.ioport=3D2@0x510:0:1 (the default on x86) * or - * fw_cfg.mmio=3D0xA@0x9020000:8:0 (the default on arm) + * qemu_fw_cfg.mmio=3D0xA@0x9020000:8:0 (the default on arm) */ =20 #include --=20 2.14.1.146.gd35faa819 From nobody Fri May 3 21:17:55 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1506086879931890.934068386495; Fri, 22 Sep 2017 06:27:59 -0700 (PDT) Received: from localhost ([::1]:58904 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dvNzl-0002jV-RJ for importer@patchew.org; Fri, 22 Sep 2017 09:27:53 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:43686) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dvNwZ-0000Nh-5Z for qemu-devel@nongnu.org; Fri, 22 Sep 2017 09:24:41 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1dvNwW-0004zE-Fn for qemu-devel@nongnu.org; Fri, 22 Sep 2017 09:24:35 -0400 Received: from mx1.redhat.com ([209.132.183.28]:34624) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1dvNwW-0004yt-77 for qemu-devel@nongnu.org; Fri, 22 Sep 2017 09:24:32 -0400 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 4FA08A1F46; Fri, 22 Sep 2017 13:24:31 +0000 (UTC) Received: from localhost (ovpn-112-42.ams2.redhat.com [10.36.112.42]) by smtp.corp.redhat.com (Postfix) with ESMTP id 46F265C89C; Fri, 22 Sep 2017 13:24:29 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com 4FA08A1F46 Authentication-Results: ext-mx10.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com Authentication-Results: ext-mx10.extmail.prod.ext.phx2.redhat.com; spf=fail smtp.mailfrom=marcandre.lureau@redhat.com From: marcandre.lureau@redhat.com To: linux-kernel@vger.kernel.org Date: Fri, 22 Sep 2017 15:24:09 +0200 Message-Id: <20170922132412.9408-3-marcandre.lureau@redhat.com> In-Reply-To: <20170922132412.9408-1-marcandre.lureau@redhat.com> References: <20170922132412.9408-1-marcandre.lureau@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.39]); Fri, 22 Sep 2017 13:24:31 +0000 (UTC) Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PATCH v3 2/5] fw_cfg: add DMA register X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= , somlo@cmu.edu, qemu-devel@nongnu.org, mst@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" From: Marc-Andr=C3=A9 Lureau Add an optional kernel module (or command line) parameter using the following syntax: [qemu_fw_cfg.]ioport=3D@[::[:]] or [qemu_fw_cfg.]mmio=3D@[::[:]] and initializes the register address using given or default offset. Signed-off-by: Marc-Andr=C3=A9 Lureau --- drivers/firmware/qemu_fw_cfg.c | 53 ++++++++++++++++++++++++++++++++------= ---- 1 file changed, 41 insertions(+), 12 deletions(-) diff --git a/drivers/firmware/qemu_fw_cfg.c b/drivers/firmware/qemu_fw_cfg.c index 5cfe39f7a45f..1f3e8545dab7 100644 --- a/drivers/firmware/qemu_fw_cfg.c +++ b/drivers/firmware/qemu_fw_cfg.c @@ -10,20 +10,21 @@ * and select subsets of aarch64), a Device Tree node (on arm), or using * a kernel module (or command line) parameter with the following syntax: * - * [qemu_fw_cfg.]ioport=3D@[::] + * [qemu_fw_cfg.]ioport=3D@[::[:]] * or - * [qemu_fw_cfg.]mmio=3D@[::] + * [qemu_fw_cfg.]mmio=3D@[::[:]] * * where: * :=3D size of ioport or mmio range * :=3D physical base address of ioport or mmio range * :=3D (optional) offset of control register * :=3D (optional) offset of data register + * :=3D (optional) offset of dma register * * e.g.: - * qemu_fw_cfg.ioport=3D2@0x510:0:1 (the default on x86) + * qemu_fw_cfg.ioport=3D12@0x510:0:1:4 (the default on x86) * or - * qemu_fw_cfg.mmio=3D0xA@0x9020000:8:0 (the default on arm) + * qemu_fw_cfg.mmio=3D16@0x9020000:8:0:16 (the default on arm) */ =20 #include @@ -63,6 +64,7 @@ static resource_size_t fw_cfg_p_size; static void __iomem *fw_cfg_dev_base; static void __iomem *fw_cfg_reg_ctrl; static void __iomem *fw_cfg_reg_data; +static void __iomem *fw_cfg_reg_dma; =20 /* atomic access to fw_cfg device (potentially slow i/o, so using mutex) */ static DEFINE_MUTEX(fw_cfg_dev_lock); @@ -118,12 +120,14 @@ static void fw_cfg_io_cleanup(void) # if (defined(CONFIG_ARM) || defined(CONFIG_ARM64)) # define FW_CFG_CTRL_OFF 0x08 # define FW_CFG_DATA_OFF 0x00 +# define FW_CFG_DMA_OFF 0x10 # elif (defined(CONFIG_PPC_PMAC) || defined(CONFIG_SPARC32)) /* ppc/mac,su= n4m */ # define FW_CFG_CTRL_OFF 0x00 # define FW_CFG_DATA_OFF 0x02 # elif (defined(CONFIG_X86) || defined(CONFIG_SPARC64)) /* x86, sun4u */ # define FW_CFG_CTRL_OFF 0x00 # define FW_CFG_DATA_OFF 0x01 +# define FW_CFG_DMA_OFF 0x04 # else # error "QEMU FW_CFG not available on this architecture!" # endif @@ -133,7 +137,7 @@ static void fw_cfg_io_cleanup(void) static int fw_cfg_do_platform_probe(struct platform_device *pdev) { char sig[FW_CFG_SIG_SIZE]; - struct resource *range, *ctrl, *data; + struct resource *range, *ctrl, *data, *dma; =20 /* acquire i/o range details */ fw_cfg_is_mmio =3D false; @@ -170,6 +174,7 @@ static int fw_cfg_do_platform_probe(struct platform_dev= ice *pdev) /* were custom register offsets provided (e.g. on the command line)? */ ctrl =3D platform_get_resource_byname(pdev, IORESOURCE_REG, "ctrl"); data =3D platform_get_resource_byname(pdev, IORESOURCE_REG, "data"); + dma =3D platform_get_resource_byname(pdev, IORESOURCE_REG, "dma"); if (ctrl && data) { fw_cfg_reg_ctrl =3D fw_cfg_dev_base + ctrl->start; fw_cfg_reg_data =3D fw_cfg_dev_base + data->start; @@ -179,6 +184,13 @@ static int fw_cfg_do_platform_probe(struct platform_de= vice *pdev) fw_cfg_reg_data =3D fw_cfg_dev_base + FW_CFG_DATA_OFF; } =20 + if (dma) + fw_cfg_reg_dma =3D fw_cfg_dev_base + dma->start; +#ifdef FW_CFG_DMA_OFF + else + fw_cfg_reg_dma =3D fw_cfg_dev_base + FW_CFG_DMA_OFF; +#endif + /* verify fw_cfg device signature */ fw_cfg_read_blob(FW_CFG_SIGNATURE, sig, 0, FW_CFG_SIG_SIZE); if (memcmp(sig, "QEMU", FW_CFG_SIG_SIZE) !=3D 0) { @@ -628,6 +640,7 @@ static struct platform_device *fw_cfg_cmdline_dev; /* use special scanf/printf modifier for phys_addr_t, resource_size_t */ #define PH_ADDR_SCAN_FMT "@%" __PHYS_ADDR_PREFIX "i%n" \ ":%" __PHYS_ADDR_PREFIX "i" \ + ":%" __PHYS_ADDR_PREFIX "i%n" \ ":%" __PHYS_ADDR_PREFIX "i%n" =20 #define PH_ADDR_PR_1_FMT "0x%" __PHYS_ADDR_PREFIX "x@" \ @@ -637,12 +650,15 @@ static struct platform_device *fw_cfg_cmdline_dev; ":%" __PHYS_ADDR_PREFIX "u" \ ":%" __PHYS_ADDR_PREFIX "u" =20 +#define PH_ADDR_PR_4_FMT PH_ADDR_PR_3_FMT \ + ":%" __PHYS_ADDR_PREFIX "u" + static int fw_cfg_cmdline_set(const char *arg, const struct kernel_param *= kp) { - struct resource res[3] =3D {}; + struct resource res[4] =3D {}; char *str; phys_addr_t base; - resource_size_t size, ctrl_off, data_off; + resource_size_t size, ctrl_off, data_off, dma_off; int processed, consumed =3D 0; =20 /* only one fw_cfg device can exist system-wide, so if one @@ -658,19 +674,20 @@ static int fw_cfg_cmdline_set(const char *arg, const = struct kernel_param *kp) /* consume "" portion of command line argument */ size =3D memparse(arg, &str); =20 - /* get "@[::]" chunks */ + /* get "@[::[:]]" chunks */ processed =3D sscanf(str, PH_ADDR_SCAN_FMT, &base, &consumed, - &ctrl_off, &data_off, &consumed); + &ctrl_off, &data_off, &consumed, + &dma_off, &consumed); =20 - /* sscanf() must process precisely 1 or 3 chunks: + /* sscanf() must process precisely 1, 3 or 4 chunks: * is mandatory, optionally followed by - * and ; + * and , and ; * there must be no extra characters after the last chunk, * so str[consumed] must be '\0'. */ if (str[consumed] || - (processed !=3D 1 && processed !=3D 3)) + (processed !=3D 1 && processed !=3D 3 && processed !=3D 4)) return -EINVAL; =20 res[0].start =3D base; @@ -687,6 +704,11 @@ static int fw_cfg_cmdline_set(const char *arg, const s= truct kernel_param *kp) res[2].start =3D data_off; res[2].flags =3D IORESOURCE_REG; } + if (processed > 3) { + res[3].name =3D "dma"; + res[3].start =3D dma_off; + res[3].flags =3D IORESOURCE_REG; + } =20 /* "processed" happens to nicely match the number of resources * we need to pass in to this platform device. @@ -721,6 +743,13 @@ static int fw_cfg_cmdline_get(char *buf, const struct = kernel_param *kp) fw_cfg_cmdline_dev->resource[0].start, fw_cfg_cmdline_dev->resource[1].start, fw_cfg_cmdline_dev->resource[2].start); + case 4: + return snprintf(buf, PAGE_SIZE, PH_ADDR_PR_4_FMT, + resource_size(&fw_cfg_cmdline_dev->resource[0]), + fw_cfg_cmdline_dev->resource[0].start, + fw_cfg_cmdline_dev->resource[1].start, + fw_cfg_cmdline_dev->resource[2].start, + fw_cfg_cmdline_dev->resource[3].start); } =20 /* Should never get here */ --=20 2.14.1.146.gd35faa819 From nobody Fri May 3 21:17:55 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1506086972272911.8802583292834; Fri, 22 Sep 2017 06:29:32 -0700 (PDT) Received: from localhost ([::1]:58909 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dvO1H-0003lF-7V for importer@patchew.org; Fri, 22 Sep 2017 09:29:27 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:43720) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dvNwe-0000RK-Ei for qemu-devel@nongnu.org; Fri, 22 Sep 2017 09:24:42 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1dvNwc-00051x-Kw for qemu-devel@nongnu.org; Fri, 22 Sep 2017 09:24:40 -0400 Received: from mx1.redhat.com ([209.132.183.28]:24793) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1dvNwc-00051e-Cl for qemu-devel@nongnu.org; Fri, 22 Sep 2017 09:24:38 -0400 Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 7202CC004787; Fri, 22 Sep 2017 13:24:37 +0000 (UTC) Received: from localhost (ovpn-112-42.ams2.redhat.com [10.36.112.42]) by smtp.corp.redhat.com (Postfix) with ESMTP id 3895163636; Fri, 22 Sep 2017 13:24:32 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com 7202CC004787 Authentication-Results: ext-mx08.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com Authentication-Results: ext-mx08.extmail.prod.ext.phx2.redhat.com; spf=fail smtp.mailfrom=marcandre.lureau@redhat.com From: marcandre.lureau@redhat.com To: linux-kernel@vger.kernel.org Date: Fri, 22 Sep 2017 15:24:10 +0200 Message-Id: <20170922132412.9408-4-marcandre.lureau@redhat.com> In-Reply-To: <20170922132412.9408-1-marcandre.lureau@redhat.com> References: <20170922132412.9408-1-marcandre.lureau@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.32]); Fri, 22 Sep 2017 13:24:37 +0000 (UTC) Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PATCH v3 3/5] fw_cfg: do DMA read operation X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= , somlo@cmu.edu, qemu-devel@nongnu.org, mst@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" From: Marc-Andr=C3=A9 Lureau Modify fw_cfg_read_blob() to use DMA if the device supports it. Return errors, because the operation may fail. This is a proof-of-concept patch with some FIXME. It uses yield() to wait for the memory to be cleared. Help on how to improve this is welcome. We may also want to switch all the *buf addresses to use only kmalloc'ed buffer (instead of using stack/image addresses with dma=3Dfalse). Signed-off-by: Marc-Andr=C3=A9 Lureau --- drivers/firmware/qemu_fw_cfg.c | 132 +++++++++++++++++++++++++++++++++++--= ---- 1 file changed, 115 insertions(+), 17 deletions(-) diff --git a/drivers/firmware/qemu_fw_cfg.c b/drivers/firmware/qemu_fw_cfg.c index 1f3e8545dab7..19b4b4d31547 100644 --- a/drivers/firmware/qemu_fw_cfg.c +++ b/drivers/firmware/qemu_fw_cfg.c @@ -33,6 +33,7 @@ #include #include #include +#include =20 MODULE_AUTHOR("Gabriel L. Somlo "); MODULE_DESCRIPTION("QEMU fw_cfg sysfs support"); @@ -43,12 +44,25 @@ MODULE_LICENSE("GPL"); #define FW_CFG_ID 0x01 #define FW_CFG_FILE_DIR 0x19 =20 +#define FW_CFG_VERSION_DMA 0x02 +#define FW_CFG_DMA_CTL_ERROR 0x01 +#define FW_CFG_DMA_CTL_READ 0x02 +#define FW_CFG_DMA_CTL_SKIP 0x04 +#define FW_CFG_DMA_CTL_SELECT 0x08 +#define FW_CFG_DMA_CTL_WRITE 0x10 + /* size in bytes of fw_cfg signature */ #define FW_CFG_SIG_SIZE 4 =20 /* fw_cfg "file name" is up to 56 characters (including terminating nul) */ #define FW_CFG_MAX_FILE_PATH 56 =20 +/* platform device for dma mapping */ +static struct device *dev; + +/* fw_cfg revision attribute, in /sys/firmware/qemu_fw_cfg top-level dir. = */ +static u32 fw_cfg_rev; + /* fw_cfg file directory entry type */ struct fw_cfg_file { u32 size; @@ -57,6 +71,12 @@ struct fw_cfg_file { char name[FW_CFG_MAX_FILE_PATH]; }; =20 +struct fw_cfg_dma { + u32 control; + u32 length; + u64 address; +} __packed; + /* fw_cfg device i/o register addresses */ static bool fw_cfg_is_mmio; static phys_addr_t fw_cfg_p_base; @@ -75,12 +95,73 @@ static inline u16 fw_cfg_sel_endianness(u16 key) return fw_cfg_is_mmio ? cpu_to_be16(key) : cpu_to_le16(key); } =20 +static inline bool fw_cfg_dma_enabled(void) +{ + return fw_cfg_rev & FW_CFG_VERSION_DMA && fw_cfg_reg_dma; +} + +static ssize_t fw_cfg_dma_transfer(void *address, u32 length, u32 control) +{ + dma_addr_t dma_addr =3D 0; + struct fw_cfg_dma *d; + dma_addr_t dma; + ssize_t ret =3D length; + enum dma_data_direction dir =3D + (control & FW_CFG_DMA_CTL_READ ? DMA_FROM_DEVICE : 0); + + if (address && length) { + dma_addr =3D dma_map_single(dev, address, length, dir); + if (dma_mapping_error(NULL, dma_addr)) { + WARN(1, "%s: failed to map address\n", __func__); + return -EFAULT; + } + } + + d =3D kmalloc(sizeof(*d), GFP_KERNEL | GFP_DMA); + if (!d) { + ret =3D -ENOMEM; + goto end; + } + + dma =3D dma_map_single(dev, d, sizeof(*d), DMA_BIDIRECTIONAL); + if (dma_mapping_error(NULL, dma)) { + WARN(1, "%s: failed to map fw_cfg_dma\n", __func__); + ret =3D -EFAULT; + goto end; + } + + *d =3D (struct fw_cfg_dma) { + .address =3D cpu_to_be64(dma_addr), + .length =3D cpu_to_be32(length), + .control =3D cpu_to_be32(control) + }; + + iowrite32be((u64)dma >> 32, fw_cfg_reg_dma); + iowrite32be(dma, fw_cfg_reg_dma + 4); + while (be32_to_cpu(d->control) & ~FW_CFG_DMA_CTL_ERROR) + yield(); /* FIXME: wait_event? */ + + if (be32_to_cpu(d->control) & FW_CFG_DMA_CTL_ERROR) + ret =3D -EIO; + + dma_unmap_single(dev, dma, sizeof(*d), DMA_BIDIRECTIONAL); + +end: + kfree(d); + if (dma_addr) + dma_unmap_single(dev, dma_addr, length, dir); + + return ret; +} + /* read chunk of given fw_cfg blob (caller responsible for sanity-check) */ -static inline void fw_cfg_read_blob(u16 key, - void *buf, loff_t pos, size_t count) +static ssize_t fw_cfg_read_blob(u16 key, + void *buf, loff_t pos, size_t count, + bool dma) { u32 glk =3D -1U; acpi_status status; + ssize_t ret =3D count; =20 /* If we have ACPI, ensure mutual exclusion against any potential * device access by the firmware, e.g. via AML methods: @@ -90,17 +171,36 @@ static inline void fw_cfg_read_blob(u16 key, /* Should never get here */ WARN(1, "fw_cfg_read_blob: Failed to lock ACPI!\n"); memset(buf, 0, count); - return; + return -EBUSY; } =20 mutex_lock(&fw_cfg_dev_lock); - iowrite16(fw_cfg_sel_endianness(key), fw_cfg_reg_ctrl); - while (pos-- > 0) - ioread8(fw_cfg_reg_data); - ioread8_rep(fw_cfg_reg_data, buf, count); + if (dma && fw_cfg_dma_enabled()) { + if (pos =3D=3D 0) { + ret =3D fw_cfg_dma_transfer(buf, count, key << 16 + | FW_CFG_DMA_CTL_SELECT + | FW_CFG_DMA_CTL_READ); + } else { + iowrite16(fw_cfg_sel_endianness(key), fw_cfg_reg_ctrl); + ret =3D fw_cfg_dma_transfer(0, pos, FW_CFG_DMA_CTL_SKIP); + if (ret < 0) + goto end; + ret =3D fw_cfg_dma_transfer(buf, count, + FW_CFG_DMA_CTL_READ); + } + } else { + iowrite16(fw_cfg_sel_endianness(key), fw_cfg_reg_ctrl); + while (pos-- > 0) + ioread8(fw_cfg_reg_data); + ioread8_rep(fw_cfg_reg_data, buf, count); + } + +end: mutex_unlock(&fw_cfg_dev_lock); =20 acpi_release_global_lock(glk); + + return ret; } =20 /* clean up fw_cfg device i/o */ @@ -192,7 +292,7 @@ static int fw_cfg_do_platform_probe(struct platform_dev= ice *pdev) #endif =20 /* verify fw_cfg device signature */ - fw_cfg_read_blob(FW_CFG_SIGNATURE, sig, 0, FW_CFG_SIG_SIZE); + fw_cfg_read_blob(FW_CFG_SIGNATURE, sig, 0, FW_CFG_SIG_SIZE, false); if (memcmp(sig, "QEMU", FW_CFG_SIG_SIZE) !=3D 0) { fw_cfg_io_cleanup(); return -ENODEV; @@ -201,9 +301,6 @@ static int fw_cfg_do_platform_probe(struct platform_dev= ice *pdev) return 0; } =20 -/* fw_cfg revision attribute, in /sys/firmware/qemu_fw_cfg top-level dir. = */ -static u32 fw_cfg_rev; - static ssize_t fw_cfg_showrev(struct kobject *k, struct attribute *a, char= *buf) { return sprintf(buf, "%u\n", fw_cfg_rev); @@ -351,8 +448,7 @@ static ssize_t fw_cfg_sysfs_read_raw(struct file *filp,= struct kobject *kobj, if (count > entry->f.size - pos) count =3D entry->f.size - pos; =20 - fw_cfg_read_blob(entry->f.select, buf, pos, count); - return count; + return fw_cfg_read_blob(entry->f.select, buf, pos, count, true); } =20 static struct bin_attribute fw_cfg_sysfs_attr_raw =3D { @@ -505,7 +601,7 @@ static int fw_cfg_register_dir_entries(void) struct fw_cfg_file *dir; size_t dir_size; =20 - fw_cfg_read_blob(FW_CFG_FILE_DIR, &count, 0, sizeof(count)); + fw_cfg_read_blob(FW_CFG_FILE_DIR, &count, 0, sizeof(count), false); count =3D be32_to_cpu(count); dir_size =3D count * sizeof(struct fw_cfg_file); =20 @@ -513,7 +609,7 @@ static int fw_cfg_register_dir_entries(void) if (!dir) return -ENOMEM; =20 - fw_cfg_read_blob(FW_CFG_FILE_DIR, dir, sizeof(count), dir_size); + fw_cfg_read_blob(FW_CFG_FILE_DIR, dir, sizeof(count), dir_size, true); =20 for (i =3D 0; i < count; i++) { dir[i].size =3D be32_to_cpu(dir[i].size); @@ -544,9 +640,10 @@ static int fw_cfg_sysfs_probe(struct platform_device *= pdev) * one fw_cfg device exist system-wide, so if one was already found * earlier, we might as well stop here. */ - if (fw_cfg_sel_ko) + if (dev) return -EBUSY; =20 + dev =3D &pdev->dev; /* create by_key and by_name subdirs of /sys/firmware/qemu_fw_cfg/ */ err =3D -ENOMEM; fw_cfg_sel_ko =3D kobject_create_and_add("by_key", fw_cfg_top_ko); @@ -562,7 +659,7 @@ static int fw_cfg_sysfs_probe(struct platform_device *p= dev) goto err_probe; =20 /* get revision number, add matching top-level attribute */ - fw_cfg_read_blob(FW_CFG_ID, &fw_cfg_rev, 0, sizeof(fw_cfg_rev)); + fw_cfg_read_blob(FW_CFG_ID, &fw_cfg_rev, 0, sizeof(fw_cfg_rev), false); fw_cfg_rev =3D le32_to_cpu(fw_cfg_rev); err =3D sysfs_create_file(fw_cfg_top_ko, &fw_cfg_rev_attr.attr); if (err) @@ -587,6 +684,7 @@ static int fw_cfg_sysfs_probe(struct platform_device *p= dev) err_name: fw_cfg_kobj_cleanup(fw_cfg_sel_ko); err_sel: + dev =3D NULL; return err; } =20 --=20 2.14.1.146.gd35faa819 From nobody Fri May 3 21:17:55 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1506086785062373.9548937416365; Fri, 22 Sep 2017 06:26:25 -0700 (PDT) Received: from localhost ([::1]:58900 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dvNyF-0001Sk-K6 for importer@patchew.org; Fri, 22 Sep 2017 09:26:19 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:43746) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dvNwj-0000VS-Um for qemu-devel@nongnu.org; Fri, 22 Sep 2017 09:24:47 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1dvNwh-00055N-9n for qemu-devel@nongnu.org; Fri, 22 Sep 2017 09:24:45 -0400 Received: from mx1.redhat.com ([209.132.183.28]:64721) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1dvNwh-000550-0v for qemu-devel@nongnu.org; Fri, 22 Sep 2017 09:24:43 -0400 Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.phx2.redhat.com [10.5.11.14]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 1EBAC7C83A; Fri, 22 Sep 2017 13:24:42 +0000 (UTC) Received: from localhost (ovpn-112-42.ams2.redhat.com [10.36.112.42]) by smtp.corp.redhat.com (Postfix) with ESMTP id 4FF3F5D96B; Fri, 22 Sep 2017 13:24:38 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com 1EBAC7C83A Authentication-Results: ext-mx03.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com Authentication-Results: ext-mx03.extmail.prod.ext.phx2.redhat.com; spf=fail smtp.mailfrom=marcandre.lureau@redhat.com From: marcandre.lureau@redhat.com To: linux-kernel@vger.kernel.org Date: Fri, 22 Sep 2017 15:24:11 +0200 Message-Id: <20170922132412.9408-5-marcandre.lureau@redhat.com> In-Reply-To: <20170922132412.9408-1-marcandre.lureau@redhat.com> References: <20170922132412.9408-1-marcandre.lureau@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.14 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.27]); Fri, 22 Sep 2017 13:24:42 +0000 (UTC) Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PATCH v3 4/5] fw_cfg: write vmcoreinfo details X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= , somlo@cmu.edu, qemu-devel@nongnu.org, mst@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" From: Marc-Andr=C3=A9 Lureau If the "etc/vmcoreinfo" file is present, write the addr/size of the vmcoreinfo ELF note. Signed-off-by: Marc-Andr=C3=A9 Lureau --- drivers/firmware/qemu_fw_cfg.c | 80 ++++++++++++++++++++++++++++++++++++++= +++- 1 file changed, 79 insertions(+), 1 deletion(-) diff --git a/drivers/firmware/qemu_fw_cfg.c b/drivers/firmware/qemu_fw_cfg.c index 19b4b4d31547..54b569da3257 100644 --- a/drivers/firmware/qemu_fw_cfg.c +++ b/drivers/firmware/qemu_fw_cfg.c @@ -34,6 +34,7 @@ #include #include #include +#include =20 MODULE_AUTHOR("Gabriel L. Somlo "); MODULE_DESCRIPTION("QEMU fw_cfg sysfs support"); @@ -57,6 +58,8 @@ MODULE_LICENSE("GPL"); /* fw_cfg "file name" is up to 56 characters (including terminating nul) */ #define FW_CFG_MAX_FILE_PATH 56 =20 +#define VMCOREINFO_FORMAT_ELF 0x1 + /* platform device for dma mapping */ static struct device *dev; =20 @@ -107,7 +110,8 @@ static ssize_t fw_cfg_dma_transfer(void *address, u32 l= ength, u32 control) dma_addr_t dma; ssize_t ret =3D length; enum dma_data_direction dir =3D - (control & FW_CFG_DMA_CTL_READ ? DMA_FROM_DEVICE : 0); + (control & FW_CFG_DMA_CTL_READ ? DMA_FROM_DEVICE : 0) | + (control & FW_CFG_DMA_CTL_WRITE ? DMA_TO_DEVICE : 0); =20 if (address && length) { dma_addr =3D dma_map_single(dev, address, length, dir); @@ -203,6 +207,46 @@ static ssize_t fw_cfg_read_blob(u16 key, return ret; } =20 +/* write chunk of given fw_cfg blob (caller responsible for sanity-check) = */ +static ssize_t fw_cfg_write_blob(u16 key, + void *buf, loff_t pos, size_t count) +{ + u32 glk =3D -1U; + acpi_status status; + ssize_t ret =3D count; + + /* If we have ACPI, ensure mutual exclusion against any potential + * device access by the firmware, e.g. via AML methods: + */ + status =3D acpi_acquire_global_lock(ACPI_WAIT_FOREVER, &glk); + if (ACPI_FAILURE(status) && status !=3D AE_NOT_CONFIGURED) { + /* Should never get here */ + WARN(1, "%s: Failed to lock ACPI!\n", __func__); + memset(buf, 0, count); + return -EBUSY; + } + + mutex_lock(&fw_cfg_dev_lock); + if (pos =3D=3D 0) { + ret =3D fw_cfg_dma_transfer(buf, count, key << 16 + | FW_CFG_DMA_CTL_SELECT + | FW_CFG_DMA_CTL_WRITE); + } else { + iowrite16(fw_cfg_sel_endianness(key), fw_cfg_reg_ctrl); + ret =3D fw_cfg_dma_transfer(0, pos, FW_CFG_DMA_CTL_SKIP); + if (ret < 0) + goto end; + ret =3D fw_cfg_dma_transfer(buf, count, FW_CFG_DMA_CTL_WRITE); + } + +end: + mutex_unlock(&fw_cfg_dev_lock); + + acpi_release_global_lock(glk); + + return ret; +} + /* clean up fw_cfg device i/o */ static void fw_cfg_io_cleanup(void) { @@ -321,6 +365,35 @@ struct fw_cfg_sysfs_entry { struct list_head list; }; =20 +static ssize_t write_vmcoreinfo(const struct fw_cfg_file *f) +{ + struct vmci { + __le16 host_format; + __le16 guest_format; + __le32 size; + __le64 paddr; + } __packed; + struct vmci *data; + ssize_t ret; + + data =3D kmalloc(sizeof(struct vmci), GFP_KERNEL | GFP_DMA); + if (!data) + return -ENOMEM; + + /* spare ourself reading host format support for now since we + * don't know what else to format - host may ignore ours + */ + *data =3D (struct vmci) { + .guest_format =3D cpu_to_le16(VMCOREINFO_FORMAT_ELF), + .size =3D cpu_to_le32(VMCOREINFO_NOTE_SIZE), + .paddr =3D cpu_to_le64(paddr_vmcoreinfo_note()) + }; + ret =3D fw_cfg_write_blob(f->select, data, 0, sizeof(struct vmci)); + + kfree(data); + return ret; +} + /* get fw_cfg_sysfs_entry from kobject member */ static inline struct fw_cfg_sysfs_entry *to_entry(struct kobject *kobj) { @@ -560,6 +633,11 @@ static int fw_cfg_register_file(const struct fw_cfg_fi= le *f) int err; struct fw_cfg_sysfs_entry *entry; =20 + if (strcmp(f->name, "etc/vmcoreinfo") =3D=3D 0) { + if (write_vmcoreinfo(f) < 0) + pr_warn("fw_cfg: failed to write vmcoreinfo"); + } + /* allocate new entry */ entry =3D kzalloc(sizeof(*entry), GFP_KERNEL); if (!entry) --=20 2.14.1.146.gd35faa819 From nobody Fri May 3 21:17:55 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1506086879862879.6069354625836; Fri, 22 Sep 2017 06:27:59 -0700 (PDT) Received: from localhost ([::1]:58905 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dvNzm-0002kA-TZ for importer@patchew.org; Fri, 22 Sep 2017 09:27:54 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:43755) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dvNwk-0000Vs-IY for qemu-devel@nongnu.org; Fri, 22 Sep 2017 09:24:47 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1dvNwj-00056i-Nt for qemu-devel@nongnu.org; Fri, 22 Sep 2017 09:24:46 -0400 Received: from mx1.redhat.com ([209.132.183.28]:36340) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1dvNwj-00056F-HA for qemu-devel@nongnu.org; Fri, 22 Sep 2017 09:24:45 -0400 Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 9DADAA0C23; Fri, 22 Sep 2017 13:24:44 +0000 (UTC) Received: from localhost (ovpn-112-42.ams2.redhat.com [10.36.112.42]) by smtp.corp.redhat.com (Postfix) with ESMTP id 0B11D6362B; Fri, 22 Sep 2017 13:24:43 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com 9DADAA0C23 Authentication-Results: ext-mx10.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com Authentication-Results: ext-mx10.extmail.prod.ext.phx2.redhat.com; spf=fail smtp.mailfrom=marcandre.lureau@redhat.com From: marcandre.lureau@redhat.com To: linux-kernel@vger.kernel.org Date: Fri, 22 Sep 2017 15:24:12 +0200 Message-Id: <20170922132412.9408-6-marcandre.lureau@redhat.com> In-Reply-To: <20170922132412.9408-1-marcandre.lureau@redhat.com> References: <20170922132412.9408-1-marcandre.lureau@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.39]); Fri, 22 Sep 2017 13:24:44 +0000 (UTC) Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PATCH v3 5/5] RFC: fw_cfg: add DMA write operation in sysfs X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= , somlo@cmu.edu, qemu-devel@nongnu.org, mst@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" From: Marc-Andr=C3=A9 Lureau Since qemu 2.9, DMA write operations are allowed. However, usage of this interface from kernel or user-space is strongly discouraged by the maintainers. This patch is meant for experimentations for now. Signed-off-by: Marc-Andr=C3=A9 Lureau --- drivers/firmware/qemu_fw_cfg.c | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/drivers/firmware/qemu_fw_cfg.c b/drivers/firmware/qemu_fw_cfg.c index 54b569da3257..e2f2ad1c9c0c 100644 --- a/drivers/firmware/qemu_fw_cfg.c +++ b/drivers/firmware/qemu_fw_cfg.c @@ -524,9 +524,28 @@ static ssize_t fw_cfg_sysfs_read_raw(struct file *filp= , struct kobject *kobj, return fw_cfg_read_blob(entry->f.select, buf, pos, count, true); } =20 +static ssize_t fw_cfg_sysfs_write_raw(struct file *filp, struct kobject *k= obj, + struct bin_attribute *bin_attr, + char *buf, loff_t pos, size_t count) +{ + struct fw_cfg_sysfs_entry *entry =3D to_entry(kobj); + + if (!fw_cfg_dma_enabled()) + return -ENOTSUPP; + + if (pos > entry->f.size) + return -EINVAL; + + if (count > entry->f.size - pos) + count =3D entry->f.size - pos; + + return fw_cfg_write_blob(entry->f.select, buf, pos, count); +} + static struct bin_attribute fw_cfg_sysfs_attr_raw =3D { - .attr =3D { .name =3D "raw", .mode =3D S_IRUSR }, + .attr =3D { .name =3D "raw", .mode =3D S_IRUSR | S_IWUSR }, .read =3D fw_cfg_sysfs_read_raw, + .write =3D fw_cfg_sysfs_write_raw, }; =20 /* --=20 2.14.1.146.gd35faa819