From patchwork Mon Apr 24 22:36:50 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jerry Hoemann X-Patchwork-Id: 9697321 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id BD489601E9 for ; Mon, 24 Apr 2017 22:37:53 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id AEF1725D9E for ; Mon, 24 Apr 2017 22:37:53 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id A36FE28404; Mon, 24 Apr 2017 22:37:53 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-1.9 required=2.0 tests=BAYES_00, RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.1 Received: from ml01.01.org (ml01.01.org [198.145.21.10]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id D109125D9E for ; Mon, 24 Apr 2017 22:37:52 +0000 (UTC) Received: from [127.0.0.1] (localhost [IPv6:::1]) by ml01.01.org (Postfix) with ESMTP id 25B2021954086; Mon, 24 Apr 2017 15:37:52 -0700 (PDT) X-Original-To: linux-nvdimm@lists.01.org Delivered-To: linux-nvdimm@lists.01.org Received: from g2t2353.austin.hpe.com (g2t2353.austin.hpe.com [15.233.44.26]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ml01.01.org (Postfix) with ESMTPS id C4DF321954084 for ; Mon, 24 Apr 2017 15:37:50 -0700 (PDT) Received: from g2t2360.austin.hpecorp.net (g2t2360.austin.hpecorp.net [16.196.225.135]) by g2t2353.austin.hpe.com (Postfix) with ESMTP id 09ABF4A; Mon, 24 Apr 2017 22:37:50 +0000 (UTC) Received: from lxbuild.ftc.rdlabs.hpecorp.net (lxbuild.ftc.rdlabs.hpecorp.net [16.78.34.175]) by g2t2360.austin.hpecorp.net (Postfix) with ESMTP id A6BB636; Mon, 24 Apr 2017 22:37:49 +0000 (UTC) From: Jerry Hoemann To: dan.j.williams@intel.com Subject: [RFC] nvdimm: Unitialized variable used in DSM calls Date: Mon, 24 Apr 2017 16:36:50 -0600 Message-Id: <1493073410-80159-1-git-send-email-jerry.hoemann@hpe.com> X-Mailer: git-send-email 1.8.3.1 X-BeenThere: linux-nvdimm@lists.01.org X-Mailman-Version: 2.1.22 Precedence: list List-Id: "Linux-nvdimm developer list." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: linux-nvdimm@lists.01.org MIME-Version: 1.0 Errors-To: linux-nvdimm-bounces@lists.01.org Sender: "Linux-nvdimm" X-Virus-Scanned: ClamAV using ClamSMTP nd_cmd_out_size is called by __nd_ioctl to size the buffer passed to acpi_nfit_ctl. If the DSM function being called has a variable sized output, nd_cmd_out_size will look at the return field to determine buffer size. However, the DSM call hasn't been made yet, so output size is core residue. Have nd_cmd_out_size be bimodal with version "early" to be called before the DSM call is made. For variable sized output fields have it return ND_IOCTL_MAX_BUFLEN. __nd_ioctl sees new return values and adjust buffer size accordingly. The downside to this approach are: 1) Requires user buffer input size to be ND_IOCTL_MAX_BUFLEN (4 MB) for calls to DSM with variable return. 2) The needless copyin of 4MB An alternative approach (not yet prototyped) would move the call to nd_cmd_out_size until after the return from acpi_nfit_ctl. Here, the call has been made and return size would be known. The size of the buffer allocated in would always be ND_IOCTL_MAX_BUFLEN. Signed-off-by: Jerry Hoemann --- drivers/nvdimm/bus.c | 30 ++++++++++++++++++++++++------ 1 file changed, 24 insertions(+), 6 deletions(-) diff --git a/drivers/nvdimm/bus.c b/drivers/nvdimm/bus.c index 23d4a17..50f8cc6 100644 --- a/drivers/nvdimm/bus.c +++ b/drivers/nvdimm/bus.c @@ -713,9 +713,9 @@ u32 nd_cmd_in_size(struct nvdimm *nvdimm, int cmd, } EXPORT_SYMBOL_GPL(nd_cmd_in_size); -u32 nd_cmd_out_size(struct nvdimm *nvdimm, int cmd, +u32 nd_cmd_out_size_early(struct nvdimm *nvdimm, int cmd, const struct nd_cmd_desc *desc, int idx, const u32 *in_field, - const u32 *out_field, unsigned long remainder) + const u32 *out_field, unsigned long remainder, int early) { if (idx >= desc->out_num) return UINT_MAX; @@ -725,9 +725,13 @@ u32 nd_cmd_out_size(struct nvdimm *nvdimm, int cmd, if (nvdimm && cmd == ND_CMD_GET_CONFIG_DATA && idx == 1) return in_field[1]; - else if (nvdimm && cmd == ND_CMD_VENDOR && idx == 2) + else if (nvdimm && cmd == ND_CMD_VENDOR && idx == 2) { + if (early) + return ND_IOCTL_MAX_BUFLEN; return out_field[1]; - else if (!nvdimm && cmd == ND_CMD_ARS_STATUS && idx == 2) { + } else if (!nvdimm && cmd == ND_CMD_ARS_STATUS && idx == 2) { + if (early) + return ND_IOCTL_MAX_BUFLEN; /* * Per table 9-276 ARS Data in ACPI 6.1, out_field[1] is * "Size of Output Buffer in bytes, including this @@ -753,6 +757,13 @@ u32 nd_cmd_out_size(struct nvdimm *nvdimm, int cmd, return UINT_MAX; } + +u32 nd_cmd_out_size(struct nvdimm *nvdimm, int cmd, + const struct nd_cmd_desc *desc, int idx, const u32 *in_field, + const u32 *out_field, unsigned long remainder) +{ + return nd_cmd_out_size_early(nvdimm, cmd, desc, idx, in_field, out_field, remainder, 0); +} EXPORT_SYMBOL_GPL(nd_cmd_out_size); void wait_nvdimm_bus_probe_idle(struct device *dev) @@ -890,10 +901,17 @@ static int __nd_ioctl(struct nvdimm_bus *nvdimm_bus, struct nvdimm *nvdimm, /* process an output envelope */ for (i = 0; i < desc->out_num; i++) { - u32 out_size = nd_cmd_out_size(nvdimm, cmd, desc, i, - (u32 *) in_env, (u32 *) out_env, 0); + u32 out_size = nd_cmd_out_size_early(nvdimm, cmd, desc, i, + (u32 *) in_env, (u32 *) out_env, 0, 1); u32 copy; + if (out_size == ND_IOCTL_MAX_BUFLEN) { + /* variable sized output */ + out_len = out_size; + out_len -= in_len; + break; + } + if (out_size == UINT_MAX) { dev_dbg(dev, "%s:%s unknown output size cmd: %s field: %d\n", __func__, dimm_name, cmd_name, i);