All of lore.kernel.org
 help / color / mirror / Atom feed
* [ndctl PATCH] libndctl: don't attempt to read/write past the end of the label area
@ 2016-10-14 19:47 Dan Williams
  0 siblings, 0 replies; only message in thread
From: Dan Williams @ 2016-10-14 19:47 UTC (permalink / raw)
  To: linux-nvdimm; +Cc: Xiao Guangrong

Some NVDIMM platform implementations (like QEMU) rather than partially
completing the part of the transfer that is in-scope fail the request
outright.  Teach the label area iterator to trim the request to the
valid remaining space in the total transfer.

This resolves the following problem when attempting to dump the label
area with "ndctl read-labels -j all":

 nfit ACPI0012:00: acpi_nfit_ctl:nmem0 get_data input length: 8
 get_data00000000: 0001fd80 00000fec                    ........
 nfit ACPI0012:00: acpi_nfit_ctl:nmem0 get_data output length: 8
 get_data00000000: 00000003 00000005                    ........
 nfit ACPI0012:00: acpi_nfit_ctl:nmem0 output object underflow get_data field: 1

The line "get_data00000000: 00000003 00000005" is an EINVAL response
from platform firmware.

Cc: Xiao Guangrong <guangrong.xiao@linux.intel.com>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
---
 ndctl/lib/libndctl-private.h |    1 +
 ndctl/lib/libndctl.c         |   12 ++++++++----
 2 files changed, 9 insertions(+), 4 deletions(-)

diff --git a/ndctl/lib/libndctl-private.h b/ndctl/lib/libndctl-private.h
index 0dc9e30cdb6e..050431850c66 100644
--- a/ndctl/lib/libndctl-private.h
+++ b/ndctl/lib/libndctl-private.h
@@ -176,6 +176,7 @@ struct ndctl_cmd {
 	u32 *firmware_status;
 	struct ndctl_cmd_iter {
 		u32 *offset;
+		u32 *xfer; /* pointer to xfer length in cmd */
 		u8 *data; /* pointer to the data buffer location in cmd */
 		u32 max_xfer;
 		char *total_buf;
diff --git a/ndctl/lib/libndctl.c b/ndctl/lib/libndctl.c
index 14bf2170f816..02524501db16 100644
--- a/ndctl/lib/libndctl.c
+++ b/ndctl/lib/libndctl.c
@@ -1968,6 +1968,7 @@ NDCTL_EXPORT struct ndctl_cmd *ndctl_dimm_cmd_new_cfg_read(struct ndctl_cmd *cfg
 	cmd->get_data->in_length = cfg_size->get_size->max_xfer;
 	cmd->firmware_status = &cmd->get_data->status;
 	cmd->iter.offset = &cmd->get_data->in_offset;
+	cmd->iter.xfer = &cmd->get_data->in_length;
 	cmd->iter.max_xfer = cfg_size->get_size->max_xfer;
 	cmd->iter.data = cmd->get_data->out_buf;
 	cmd->iter.total_xfer = cfg_size->get_size->config_size;
@@ -2021,6 +2022,7 @@ NDCTL_EXPORT struct ndctl_cmd *ndctl_dimm_cmd_new_cfg_write(struct ndctl_cmd *cf
 	cmd->firmware_status = (u32 *) (cmd->cmd_buf
 		+ sizeof(struct nd_cmd_set_config_hdr) + cfg_read->iter.max_xfer);
 	cmd->iter.offset = &cmd->set_data->in_offset;
+	cmd->iter.xfer = &cmd->set_data->in_length;
 	cmd->iter.max_xfer = cfg_read->iter.max_xfer;
 	cmd->iter.data = cmd->set_data->in_buf;
 	cmd->iter.total_xfer = cfg_read->iter.total_xfer;
@@ -2229,19 +2231,21 @@ static int do_cmd(int fd, int ioctl_cmd, struct ndctl_cmd *cmd)
 	}
 
 	for (offset = 0; offset < iter->total_xfer; offset += iter->max_xfer) {
+		*(cmd->iter.xfer) = min(iter->total_xfer - offset,
+				iter->max_xfer);
+		*(cmd->iter.offset) = offset;
 		if (iter->dir == WRITE)
 			memcpy(iter->data, iter->total_buf + offset,
-					iter->max_xfer);
-		*(cmd->iter.offset) = offset;
+					*(cmd->iter.xfer));
 		rc = ioctl(fd, ioctl_cmd, cmd->cmd_buf);
 		if (rc < 0)
 			break;
 
 		if (iter->dir == READ)
 			memcpy(iter->total_buf + offset, iter->data,
-					iter->max_xfer - rc);
+					*(cmd->iter.xfer) - rc);
 		if (*(cmd->firmware_status) || rc) {
-			rc = offset + iter->max_xfer - rc;
+			rc = offset + *(cmd->iter.xfer) - rc;
 			break;
 		}
 	}

_______________________________________________
Linux-nvdimm mailing list
Linux-nvdimm@lists.01.org
https://lists.01.org/mailman/listinfo/linux-nvdimm

^ permalink raw reply related	[flat|nested] only message in thread

only message in thread, other threads:[~2016-10-14 19:50 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-10-14 19:47 [ndctl PATCH] libndctl: don't attempt to read/write past the end of the label area Dan Williams

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.