@@ -137,19 +137,25 @@ i915_ttm_place_from_region(const struct intel_memory_region *mr,
if (mr->type == INTEL_MEMORY_SYSTEM)
return;
+#define SAFE_CONVERSION(ptr, value) ({ \
+ if (!safe_conversion(ptr, value)) { \
+ GEM_BUG_ON(overflows_type(value, *ptr)); \
+ } \
+})
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(&place->fpfn, offset >> PAGE_SHIFT);
+ SAFE_CONVERSION(&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(&place->lpfn, mr->io_size >> PAGE_SHIFT);
}
}
+#undef SAFE_CONVERSION
}
static void
@@ -202,24 +202,34 @@ intel_region_ttm_resource_alloc(struct intel_memory_region *mem,
struct ttm_resource *res;
int ret;
+#define SAFE_CONVERSION(ptr, value) ({ \
+ if (!safe_conversion(ptr, value)) { \
+ GEM_BUG_ON(overflows_type(value, *ptr)); \
+ ret = -E2BIG; \
+ goto out; \
+ } \
+})
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(&place.fpfn, offset >> PAGE_SHIFT);
+ SAFE_CONVERSION(&place.lpfn, place.fpfn + (size >> PAGE_SHIFT));
} 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;
+ SAFE_CONVERSION(&place.lpfn, mem->io_size >> PAGE_SHIFT);
}
}
+#undef SAFE_CONVERSION
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)
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 our overflows_type check and report E2BIG or overflow_type prior to the operation. 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> --- drivers/gpu/drm/i915/gem/i915_gem_ttm.c | 12 +++++++++--- drivers/gpu/drm/i915/intel_region_ttm.c | 16 +++++++++++++--- 2 files changed, 22 insertions(+), 6 deletions(-)