Skip to content

Commit 863a8eb

Browse files
Matthew Wilcox (Oracle)rodrigovivi
authored andcommitted
i915: Limit the length of an sg list to the requested length
The folio conversion changed the behaviour of shmem_sg_alloc_table() to put the entire length of the last folio into the sg list, even if the sg list should have been shorter. gen8_ggtt_insert_entries() relied on the list being the right length and would overrun the end of the page tables. Other functions may also have been affected. Clamp the length of the last entry in the sg list to be the expected length. Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org> Fixes: 0b62af2 ("i915: convert shmem_sg_free_table() to use a folio_batch") Cc: stable@vger.kernel.org # 6.5.x Link: https://gitlab.freedesktop.org/drm/intel/-/issues/9256 Link: https://lore.kernel.org/lkml/6287208.lOV4Wx5bFT@natalenko.name/ Reported-by: Oleksandr Natalenko <oleksandr@natalenko.name> Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name> Reviewed-by: Andrzej Hajda <andrzej.hajda@intel.com> Signed-off-by: Andrzej Hajda <andrzej.hajda@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20230919194855.347582-1-willy@infradead.org (cherry picked from commit 26a8e32) Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
1 parent 6465e26 commit 863a8eb

File tree

1 file changed

+7
-4
lines changed

1 file changed

+7
-4
lines changed

drivers/gpu/drm/i915/gem/i915_gem_shmem.c

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@ int shmem_sg_alloc_table(struct drm_i915_private *i915, struct sg_table *st,
100100
st->nents = 0;
101101
for (i = 0; i < page_count; i++) {
102102
struct folio *folio;
103+
unsigned long nr_pages;
103104
const unsigned int shrink[] = {
104105
I915_SHRINK_BOUND | I915_SHRINK_UNBOUND,
105106
0,
@@ -150,20 +151,22 @@ int shmem_sg_alloc_table(struct drm_i915_private *i915, struct sg_table *st,
150151
}
151152
} while (1);
152153

154+
nr_pages = min_t(unsigned long,
155+
folio_nr_pages(folio), page_count - i);
153156
if (!i ||
154157
sg->length >= max_segment ||
155158
folio_pfn(folio) != next_pfn) {
156159
if (i)
157160
sg = sg_next(sg);
158161

159162
st->nents++;
160-
sg_set_folio(sg, folio, folio_size(folio), 0);
163+
sg_set_folio(sg, folio, nr_pages * PAGE_SIZE, 0);
161164
} else {
162165
/* XXX: could overflow? */
163-
sg->length += folio_size(folio);
166+
sg->length += nr_pages * PAGE_SIZE;
164167
}
165-
next_pfn = folio_pfn(folio) + folio_nr_pages(folio);
166-
i += folio_nr_pages(folio) - 1;
168+
next_pfn = folio_pfn(folio) + nr_pages;
169+
i += nr_pages - 1;
167170

168171
/* Check that the i965g/gm workaround works. */
169172
GEM_BUG_ON(gfp & __GFP_DMA32 && next_pfn >= 0x00100000UL);

0 commit comments

Comments
 (0)