Skip to content

Commit 2e0438f

Browse files
KKaras169169Andi Shyti
authored andcommitted
drm/i915: ensure segment offset never exceeds allowed max
Commit 255fc17 ("drm/i915/gem: Calculate object page offset for partial memory mapping") introduced a new offset, which accounts for userspace mapping not starting from the beginning of object's scatterlist. This works fine for cases where first object pte is larger than the new offset - "r->sgt.curr" counter is set to the offset to match the difference in the number of total pages. However, if object's first pte's size is equal to or smaller than the offset, then information about the offset in userspace is covered up by moving "r->sgt" pointer in remap_sg(): r->sgt.curr += PAGE_SIZE; if (r->sgt.curr >= r->sgt.max) r->sgt = __sgt_iter(__sg_next(r->sgt.sgp), use_dma(r->iobase)); This means that two or more pages from virtual memory are counted for only one page in object's memory, because after moving "r->sgt" pointer "r->sgt.curr" will be 0. We should account for this mismatch by moving "r->sgt" pointer to the next pte. For that we may use "r.sgt.max", which already holds the max allowed size. This change also eliminates possible confusion, when looking at i915_scatterlist.h and remap_io_sg() code: former has scatterlist pointer definition, which differentiates "s.max" value based on "dma" flag (sg_dma_len() is used only when the flag is enabled), while latter uses sg_dma_len() indiscriminately. This patch aims to resolve issue: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/12031 v3: - instead of checking if r.sgt.curr would exceed allowed max, changed the value in the while loop to be aligned with `dma` value v4: - remove unnecessary parent relation v5: - update commit message with explanation about page counting mismatch and link to the issue Signed-off-by: Krzysztof Karas <[email protected]> Reviewed-by: Andi Shyti <[email protected]> Signed-off-by: Andi Shyti <[email protected]> Link: https://patchwork.freedesktop.org/patch/msgid/upbjdavlbcxku63ns4vstp5kgbn2anxwewpmnppszgb67fn66t@tfclfgkqijue
1 parent b939a08 commit 2e0438f

File tree

1 file changed

+2
-2
lines changed

1 file changed

+2
-2
lines changed

drivers/gpu/drm/i915/i915_mm.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -143,8 +143,8 @@ int remap_io_sg(struct vm_area_struct *vma,
143143
/* We rely on prevalidation of the io-mapping to skip track_pfn(). */
144144
GEM_BUG_ON((vma->vm_flags & EXPECTED_FLAGS) != EXPECTED_FLAGS);
145145

146-
while (offset >= sg_dma_len(r.sgt.sgp) >> PAGE_SHIFT) {
147-
offset -= sg_dma_len(r.sgt.sgp) >> PAGE_SHIFT;
146+
while (offset >= r.sgt.max >> PAGE_SHIFT) {
147+
offset -= r.sgt.max >> PAGE_SHIFT;
148148
r.sgt = __sgt_iter(__sg_next(r.sgt.sgp), use_dma(iobase));
149149
if (!r.sgt.sgp)
150150
return -EINVAL;

0 commit comments

Comments
 (0)