[Mesa-dev] [PATCH] intel/isl: Tighten up format info lookup

Anuj Phogat anuj.phogat at gmail.com
Mon Jun 5 17:26:07 UTC 2017


On Mon, Jun 5, 2017 at 9:28 AM, Jason Ekstrand <jason at jlekstrand.net> wrote:
> The old code would just blindly dereference arrays with no protection
> whatsoever.  This is a problem because the format_info array is too
> short to contain ISL_FORMAT_UNSUPPORTED or any of the aux formats.  This
> can lead to segfaults when the array is dereferenced.  This commit
> switches everything over to using a helper for getting isl_format_info
> which does some useful asserting.  While we're here, we add the same
> asserts to isl_format_get_layout().
> ---
>  src/intel/isl/isl.h        |  8 ++++++
>  src/intel/isl/isl_format.c | 62 ++++++++++++++++++++++++++++++++--------------
>  2 files changed, 51 insertions(+), 19 deletions(-)
>
> diff --git a/src/intel/isl/isl.h b/src/intel/isl/isl.h
> index 658f67e..5f9baa7 100644
> --- a/src/intel/isl/isl.h
> +++ b/src/intel/isl/isl.h
> @@ -389,6 +389,11 @@ enum isl_format {
>     ISL_FORMAT_GEN9_CCS_64BPP,
>     ISL_FORMAT_GEN9_CCS_128BPP,
>
> +   /* This way we can easily tell if it's a valid format.  Note:
> +    * ISL_FORMAT_UNSUPPORTED is not considered valid.
> +    */
> +   ISL_FORMAT_MAX_VALID_ENUM,
> +
>     /* Hardware doesn't understand this out-of-band value */
>     ISL_FORMAT_UNSUPPORTED =                             UINT16_MAX,
>  };
> @@ -1170,6 +1175,9 @@ isl_device_get_sample_counts(struct isl_device *dev);
>  static inline const struct isl_format_layout * ATTRIBUTE_CONST
>  isl_format_get_layout(enum isl_format fmt)
>  {
> +   assert(fmt != ISL_FORMAT_UNSUPPORTED);
> +   assert(fmt < ISL_FORMAT_MAX_VALID_ENUM);
> +
>     return &isl_format_layouts[fmt];
>  }
>
> diff --git a/src/intel/isl/isl_format.c b/src/intel/isl/isl_format.c
> index e6d2a43..02e09e9 100644
> --- a/src/intel/isl/isl_format.c
> +++ b/src/intel/isl/isl_format.c
> @@ -21,12 +21,13 @@
>   *  IN THE SOFTWARE.
>   */
>
> +#include <stdlib.h>
>  #include <assert.h>
>
>  #include "isl.h"
>  #include "common/gen_device_info.h"
>
> -struct surface_format_info {
> +struct isl_format_info {
>     bool exists;
>     uint8_t sampling;
>     uint8_t filtering;
> @@ -87,7 +88,7 @@ struct surface_format_info {
>   * - VOL4_Part1 section 3.9.11 Render Target Write.
>   * - Render Target Surface Types [SKL+]
>   */
> -static const struct surface_format_info format_info[] = {
> +static const struct isl_format_info format_infos[] = {
>  /* smpl filt shad CK  RT  AB  VB  SO  color TW  TR  ccs_e */
>     SF( Y, 50,  x,  x,  Y,  Y,  Y,  Y,  x,   70, 90, 90,   R32G32B32A32_FLOAT)
>     SF( Y,  x,  x,  x,  Y,  x,  Y,  Y,  x,   70, 90, 90,   R32G32B32A32_SINT)
> @@ -359,6 +360,21 @@ static const struct surface_format_info format_info[] = {
>  #undef x
>  #undef Y
>
> +static inline const struct isl_format_info *
> +isl_format_get_info(enum isl_format format)
> +{
> +   assert(format != ISL_FORMAT_UNSUPPORTED);
> +   assert(format < ISL_FORMAT_MAX_VALID_ENUM);
> +
> +   if (format >= ARRAY_SIZE(format_infos))
> +      return NULL;
> +
> +   if (!format_infos[format].exists)
> +      return NULL;
> +
> +   return &format_infos[format];
> +}
> +
>  static unsigned
>  format_gen(const struct gen_device_info *devinfo)
>  {
> @@ -369,27 +385,30 @@ bool
>  isl_format_supports_rendering(const struct gen_device_info *devinfo,
>                                enum isl_format format)
>  {
> -   if (!format_info[format].exists)
> +   const struct isl_format_info *info = isl_format_get_info(format);
> +   if (info == NULL)
>        return false;
>
> -   return format_gen(devinfo) >= format_info[format].render_target;
> +   return format_gen(devinfo) >= info->render_target;
>  }
>
>  bool
>  isl_format_supports_alpha_blending(const struct gen_device_info *devinfo,
>                                     enum isl_format format)
>  {
> -   if (!format_info[format].exists)
> +   const struct isl_format_info *info = isl_format_get_info(format);
> +   if (info == NULL)
>        return false;
>
> -   return format_gen(devinfo) >= format_info[format].alpha_blend;
> +   return format_gen(devinfo) >= info->alpha_blend;
>  }
>
>  bool
>  isl_format_supports_sampling(const struct gen_device_info *devinfo,
>                               enum isl_format format)
>  {
> -   if (!format_info[format].exists)
> +   const struct isl_format_info *info = isl_format_get_info(format);
> +   if (info == NULL)
>        return false;
>
>     if (devinfo->is_baytrail) {
> @@ -415,14 +434,15 @@ isl_format_supports_sampling(const struct gen_device_info *devinfo,
>           return true;
>     }
>
> -   return format_gen(devinfo) >= format_info[format].sampling;
> +   return format_gen(devinfo) >= info->sampling;
>  }
>
>  bool
>  isl_format_supports_filtering(const struct gen_device_info *devinfo,
>                                enum isl_format format)
>  {
> -   if (!format_info[format].exists)
> +   const struct isl_format_info *info = isl_format_get_info(format);
> +   if (info == NULL)
>        return false;
>
>     if (devinfo->is_baytrail) {
> @@ -448,23 +468,24 @@ isl_format_supports_filtering(const struct gen_device_info *devinfo,
>           return true;
>     }
>
> -   return format_gen(devinfo) >= format_info[format].filtering;
> +   return format_gen(devinfo) >= info->filtering;
>  }
>
>  bool
>  isl_format_supports_vertex_fetch(const struct gen_device_info *devinfo,
>                                   enum isl_format format)
>  {
> -   if (!format_info[format].exists)
> +   const struct isl_format_info *info = isl_format_get_info(format);
> +   if (info == NULL)
>        return false;
>
>     /* For vertex fetch, Bay Trail supports the same set of formats as Haswell
>      * but is a superset of Ivy Bridge.
>      */
>     if (devinfo->is_baytrail)
> -      return 75 >= format_info[format].input_vb;
> +      return 75 >= info->input_vb;
>
> -   return format_gen(devinfo) >= format_info[format].input_vb;
> +   return format_gen(devinfo) >= info->input_vb;
>  }
>
>  /**
> @@ -474,10 +495,11 @@ bool
>  isl_format_supports_typed_writes(const struct gen_device_info *devinfo,
>                                   enum isl_format format)
>  {
> -   if (!format_info[format].exists)
> +   const struct isl_format_info *info = isl_format_get_info(format);
> +   if (info == NULL)
>        return false;
>
> -   return format_gen(devinfo) >= format_info[format].typed_write;
> +   return format_gen(devinfo) >= info->typed_write;
>  }
>
>
> @@ -495,10 +517,11 @@ bool
>  isl_format_supports_typed_reads(const struct gen_device_info *devinfo,
>                                  enum isl_format format)
>  {
> -   if (!format_info[format].exists)
> +   const struct isl_format_info *info = isl_format_get_info(format);
> +   if (info == NULL)
>        return false;
>
> -   return format_gen(devinfo) >= format_info[format].typed_read;
> +   return format_gen(devinfo) >= info->typed_read;
>  }
>
>  /**
> @@ -533,10 +556,11 @@ bool
>  isl_format_supports_ccs_e(const struct gen_device_info *devinfo,
>                            enum isl_format format)
>  {
> -   if (!format_info[format].exists)
> +   const struct isl_format_info *info = isl_format_get_info(format);
> +   if (info == NULL)
>        return false;
>
> -   return format_gen(devinfo) >= format_info[format].ccs_e;
> +   return format_gen(devinfo) >= info->ccs_e;
>  }
>
>  bool
> --
> 2.5.0.400.gff86faf
>
> _______________________________________________
> mesa-dev mailing list
> mesa-dev at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/mesa-dev

Reviewed-by: Anuj Phogat <anuj.phogat at gmail.com>


More information about the mesa-dev mailing list