aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/block
diff options
context:
space:
mode:
authorMatthew Wilcox <matthew.r.wilcox@intel.com>2011-09-13 17:01:39 -0400
committerMatthew Wilcox <matthew.r.wilcox@intel.com>2011-11-04 15:53:04 -0400
commitd0ba1e497bca83a3d353eb47c9658afc54d83228 (patch)
tree67357b1a15493caf232448fc8f5c13bf73fbe215 /drivers/block
parent6413214c5d424fd5aae6567848340f962ad2ce0f (diff)
NVMe: Correct sg list setup in nvme_map_user_pages
Our SG list was constructed to always fill the entire first page, even if that was more than the length of the I/O. This is probably harmless, but some IOMMUs might do something bad. Correcting the first call to sg_set_page() made it look a lot closer to the sg_set_page() in the loop, so fold the first call to sg_set_page() into the loop. Reported-by: Nisheeth Bhat <nisheeth.bhat@intel.com> Signed-off-by: Matthew Wilcox <willy@linux.intel.com>
Diffstat (limited to 'drivers/block')
-rw-r--r--drivers/block/nvme.c10
1 files changed, 5 insertions, 5 deletions
diff --git a/drivers/block/nvme.c b/drivers/block/nvme.c
index 0956e1241520..5843409cac6d 100644
--- a/drivers/block/nvme.c
+++ b/drivers/block/nvme.c
@@ -996,11 +996,11 @@ static int nvme_map_user_pages(struct nvme_dev *dev, int write,
996 996
997 sg = kcalloc(count, sizeof(*sg), GFP_KERNEL); 997 sg = kcalloc(count, sizeof(*sg), GFP_KERNEL);
998 sg_init_table(sg, count); 998 sg_init_table(sg, count);
999 sg_set_page(&sg[0], pages[0], PAGE_SIZE - offset, offset); 999 for (i = 0; i < count; i++) {
1000 length -= (PAGE_SIZE - offset); 1000 sg_set_page(&sg[i], pages[i],
1001 for (i = 1; i < count; i++) { 1001 min_t(int, length, PAGE_SIZE - offset), offset);
1002 sg_set_page(&sg[i], pages[i], min_t(int, length, PAGE_SIZE), 0); 1002 length -= (PAGE_SIZE - offset);
1003 length -= PAGE_SIZE; 1003 offset = 0;
1004 } 1004 }
1005 1005
1006 err = -ENOMEM; 1006 err = -ENOMEM;