diff options
author | Matthew Wilcox <matthew.r.wilcox@intel.com> | 2011-09-13 17:01:39 -0400 |
---|---|---|
committer | Matthew Wilcox <matthew.r.wilcox@intel.com> | 2011-11-04 15:53:04 -0400 |
commit | d0ba1e497bca83a3d353eb47c9658afc54d83228 (patch) | |
tree | 67357b1a15493caf232448fc8f5c13bf73fbe215 /drivers/block | |
parent | 6413214c5d424fd5aae6567848340f962ad2ce0f (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.c | 10 |
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; |