From: Matthew Wilcox <matthew.r.wilcox@intel.com>
Date: Tue, 16 Apr 2013 19:21:06 +0000 (-0400)
Subject: NVMe: Fix endian-related problems in user I/O submission path
X-Git-Tag: firefly_0821_release~3680^2~503^2~16
X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=1c9b52651dad0ff1fa71fc6205c86d972f25bcc0;p=firefly-linux-kernel-4.4.55.git

NVMe: Fix endian-related problems in user I/O submission path

When constructing the command, dsmgmt needs to be treated as a 32-bit
value, not a 16-bit value.  reftag, apptag and appmask all need to be
converted from native-endian to little-endian.  Again, sparse's bitwise
warnings caught this problem.  Thanks to Keith for pointing out the
correct way to fix the reftag.

Signed-off-by: Matthew Wilcox <matthew.r.wilcox@intel.com>
Acked-by: Keith Busch <keith.busch@intel.com>
---

diff --git a/drivers/block/nvme-core.c b/drivers/block/nvme-core.c
index a3c7d504d5e2..dbd2103533c1 100644
--- a/drivers/block/nvme-core.c
+++ b/drivers/block/nvme-core.c
@@ -1166,10 +1166,10 @@ static int nvme_submit_io(struct nvme_ns *ns, struct nvme_user_io __user *uio)
 	c.rw.slba = cpu_to_le64(io.slba);
 	c.rw.length = cpu_to_le16(io.nblocks);
 	c.rw.control = cpu_to_le16(io.control);
-	c.rw.dsmgmt = cpu_to_le16(io.dsmgmt);
-	c.rw.reftag = io.reftag;
-	c.rw.apptag = io.apptag;
-	c.rw.appmask = io.appmask;
+	c.rw.dsmgmt = cpu_to_le32(io.dsmgmt);
+	c.rw.reftag = cpu_to_le32(io.reftag);
+	c.rw.apptag = cpu_to_le16(io.apptag);
+	c.rw.appmask = cpu_to_le16(io.appmask);
 	/* XXX: metadata */
 	length = nvme_setup_prps(dev, &c.common, iod, length, GFP_KERNEL);
 
diff --git a/include/linux/nvme.h b/include/linux/nvme.h
index 09f419d4da4e..7ae7ecfc0947 100644
--- a/include/linux/nvme.h
+++ b/include/linux/nvme.h
@@ -207,11 +207,11 @@ struct nvme_common_command {
 	__u8			flags;
 	__u16			command_id;
 	__le32			nsid;
-	__u32			cdw2[2];
+	__le32			cdw2[2];
 	__le64			metadata;
 	__le64			prp1;
 	__le64			prp2;
-	__u32			cdw10[6];
+	__le32			cdw10[6];
 };
 
 struct nvme_rw_command {