@@ -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);
}
}
}
@@ -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) ? 0 \
+ : (({ GEM_BUG_ON(overflows_type(value, *ptr)); }), 1); \
+})
#endif /* __I915_GEM_H__ */
@@ -209,14 +209,26 @@ 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;
+ }
}
}
@@ -224,6 +236,8 @@ intel_region_ttm_resource_alloc(struct intel_memory_region *mem,
mock_bo.bdev = &mem->i915->bdev;
ret = man->func->alloc(man, &mock_bo, &place, &res);
+
+out:
if (ret == -ENOSPC)
ret = -ENXIO;
if (!ret)