[PATCH] drm/i915: Mark the final obj->pages sg entry as last

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Currently we may mark the subsequent sg entry as the last, instead of
the actual last element we used. If a later iterator only used
sg_is_last() (such as sg_next()) then we may access the NULL page stored
in the elements beyond the contracted table. This may explain the
occasional NULL dereference we see in insert pages, such as
https://bugzilla.redhat.com/show_bug.cgi?id=1227892

Signed-off-by: Chris Wilson <chris@xxxxxxxxxxxxxxxxxx>
Cc: Imre Deak <imre.deak@xxxxxxxxx>
Cc: stable@xxxxxxxxxxxxxxx
---
 drivers/gpu/drm/i915/i915_gem.c | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index be35f0486202..f3b66461dc68 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -2195,7 +2195,7 @@ i915_gem_object_get_pages_gtt(struct drm_i915_gem_object *obj)
 	int page_count, i;
 	struct address_space *mapping;
 	struct sg_table *st;
-	struct scatterlist *sg;
+	struct scatterlist *sg, *end;
 	struct sg_page_iter sg_iter;
 	struct page *page;
 	unsigned long last_pfn = 0;	/* suppress gcc warning */
@@ -2227,7 +2227,7 @@ i915_gem_object_get_pages_gtt(struct drm_i915_gem_object *obj)
 	gfp = mapping_gfp_mask(mapping);
 	gfp |= __GFP_NORETRY | __GFP_NOWARN | __GFP_NO_KSWAPD;
 	gfp &= ~(__GFP_IO | __GFP_WAIT);
-	sg = st->sgl;
+	end = sg = st->sgl;
 	st->nents = 0;
 	for (i = 0; i < page_count; i++) {
 		page = shmem_read_mapping_page_gfp(mapping, i, gfp);
@@ -2253,13 +2253,13 @@ i915_gem_object_get_pages_gtt(struct drm_i915_gem_object *obj)
 		if (swiotlb_nr_tbl()) {
 			st->nents++;
 			sg_set_page(sg, page, PAGE_SIZE, 0);
-			sg = sg_next(sg);
+			sg = sg_next(end = sg);
 			continue;
 		}
 #endif
 		if (!i || page_to_pfn(page) != last_pfn + 1) {
 			if (i)
-				sg = sg_next(sg);
+				sg = sg_next(end = sg);
 			st->nents++;
 			sg_set_page(sg, page, PAGE_SIZE, 0);
 		} else {
@@ -2273,7 +2273,7 @@ i915_gem_object_get_pages_gtt(struct drm_i915_gem_object *obj)
 #ifdef CONFIG_SWIOTLB
 	if (!swiotlb_nr_tbl())
 #endif
-		sg_mark_end(sg);
+		sg_mark_end(end);
 	obj->pages = st;
 
 	if (i915_gem_object_needs_bit17_swizzle(obj))
-- 
2.1.4

--
To unsubscribe from this list: send the line "unsubscribe stable" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Index of Archives]     [Linux Kernel]     [Kernel Development Newbies]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite Hiking]     [Linux Kernel]     [Linux SCSI]