Skip to content

Commit

Permalink
drm/i915: Check for integer truncation on the configuration of ttm place
Browse files Browse the repository at this point in the history
There is an impedance mismatch between the first/last valid page
frame number of ttm place in unsigned and our memory/page accounting in
unsigned long.
As the object size is under the control of userspace, we have to be prudent
and catch the conversion errors.
To catch the implicit truncation as we switch from unsigned long to
unsigned, we use overflows_type check and report E2BIG or overflow_type
prior to the operation.

v3: Not to change execution inside a macro. (Mauro)
    Add safe_conversion_gem_bug_on() macro and remove temporal
    SAFE_CONVERSION() macro.

Signed-off-by: Gwan-gyeong Mun <gwan-gyeong.mun@intel.com>
Cc: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Matthew Auld <matthew.auld@intel.com>
Cc: Thomas Hellström <thomas.hellstrom@linux.intel.com>
Reviewed-by: Nirmoy Das <nirmoy.das@intel.com>
  • Loading branch information
elongbug authored and intel-lab-lkp committed Jul 14, 2022
1 parent 1eb4f86 commit 04722b3
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 6 deletions.
6 changes: 3 additions & 3 deletions drivers/gpu/drm/i915/gem/i915_gem_ttm.c
Expand Up @@ -140,14 +140,14 @@ i915_ttm_place_from_region(const struct intel_memory_region *mr,
if (flags & I915_BO_ALLOC_CONTIGUOUS)
place->flags |= TTM_PL_FLAG_CONTIGUOUS;
if (offset != I915_BO_INVALID_OFFSET) {
place->fpfn = offset >> PAGE_SHIFT;
place->lpfn = place->fpfn + (size >> PAGE_SHIFT);
safe_conversion_gem_bug_on(&place->fpfn, offset >> PAGE_SHIFT);
safe_conversion_gem_bug_on(&place->lpfn, place->fpfn + (size >> PAGE_SHIFT));
} else if (mr->io_size && mr->io_size < mr->total) {
if (flags & I915_BO_ALLOC_GPU_ONLY) {
place->flags |= TTM_PL_FLAG_TOPDOWN;
} else {
place->fpfn = 0;
place->lpfn = mr->io_size >> PAGE_SHIFT;
safe_conversion_gem_bug_on(&place->lpfn, mr->io_size >> PAGE_SHIFT);
}
}
}
Expand Down
4 changes: 4 additions & 0 deletions drivers/gpu/drm/i915/i915_gem.h
Expand Up @@ -83,5 +83,9 @@ struct drm_i915_private;
#endif

#define I915_GEM_IDLE_TIMEOUT (HZ / 5)
#define safe_conversion_gem_bug_on(ptr, value) ({ \
safe_conversion(ptr, value) ? 1 \
: (({ GEM_BUG_ON(overflows_type(value, *ptr)); }), 0); \
})

#endif /* __I915_GEM_H__ */
20 changes: 17 additions & 3 deletions drivers/gpu/drm/i915/intel_region_ttm.c
Expand Up @@ -209,21 +209,35 @@ intel_region_ttm_resource_alloc(struct intel_memory_region *mem,
if (flags & I915_BO_ALLOC_CONTIGUOUS)
place.flags |= TTM_PL_FLAG_CONTIGUOUS;
if (offset != I915_BO_INVALID_OFFSET) {
place.fpfn = offset >> PAGE_SHIFT;
place.lpfn = place.fpfn + (size >> PAGE_SHIFT);
if (!safe_conversion_gem_bug_on(&place.fpfn,
offset >> PAGE_SHIFT)) {
ret = -E2BIG;
goto out;
}
if (!safe_conversion_gem_bug_on(&place.lpfn,
place.fpfn + (size >> PAGE_SHIFT))) {
ret = -E2BIG;
goto out;
}
} else if (mem->io_size && mem->io_size < mem->total) {
if (flags & I915_BO_ALLOC_GPU_ONLY) {
place.flags |= TTM_PL_FLAG_TOPDOWN;
} else {
place.fpfn = 0;
place.lpfn = mem->io_size >> PAGE_SHIFT;
if (!safe_conversion_gem_bug_on(&place.lpfn,
mem->io_size >> PAGE_SHIFT)) {
ret = -E2BIG;
goto out;
}
}
}

mock_bo.base.size = size;
mock_bo.bdev = &mem->i915->bdev;

ret = man->func->alloc(man, &mock_bo, &place, &res);

out:
if (ret == -ENOSPC)
ret = -ENXIO;
if (!ret)
Expand Down

0 comments on commit 04722b3

Please sign in to comment.