On Tue,  5 Jul 2022 15:24:52 +0300
Gwan-gyeong Mun <gwan-gyeong....@intel.com> wrote:

> 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.
> 
> Signed-off-by: Gwan-gyeong Mun <gwan-gyeong....@intel.com>
> Cc: Chris Wilson <ch...@chris-wilson.co.uk>
> Cc: Matthew Auld <matthew.a...@intel.com>
> Cc: Thomas Hellström <thomas.hellst...@linux.intel.com>
> Reviewed-by: Nirmoy Das <nirmoy....@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(-)
> 
> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_ttm.c 
> b/drivers/gpu/drm/i915/gem/i915_gem_ttm.c
> index cdcb3ee0c433..d579524663b3 100644
> --- a/drivers/gpu/drm/i915/gem/i915_gem_ttm.c
> +++ b/drivers/gpu/drm/i915/gem/i915_gem_ttm.c
> @@ -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
Why?

>  }
>  
>  static void
> diff --git a/drivers/gpu/drm/i915/intel_region_ttm.c 
> b/drivers/gpu/drm/i915/intel_region_ttm.c
> index 62ff77445b01..8fcb8654b978 100644
> --- a/drivers/gpu/drm/i915/intel_region_ttm.c
> +++ b/drivers/gpu/drm/i915/intel_region_ttm.c
> @@ -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; \
> +     } \
> +})

It is a bad practice to change execution inside a macro.
See "12) Macros, Enums and RTL" at Documentation/process/coding-style.rst.

>       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
Why?

>  
>       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)

Reply via email to