LCOV - code coverage report
Current view: top level - drivers/gpu/drm/i915 - i915_query.c (source / functions) Hit Total Coverage
Test: combined.info Lines: 0 185 0.0 %
Date: 2022-04-01 14:35:51 Functions: 0 8 0.0 %
Branches: 0 122 0.0 %

           Branch data     Line data    Source code
       1                 :            : /*
       2                 :            :  * SPDX-License-Identifier: MIT
       3                 :            :  *
       4                 :            :  * Copyright © 2018 Intel Corporation
       5                 :            :  */
       6                 :            : 
       7                 :            : #include <linux/nospec.h>
       8                 :            : 
       9                 :            : #include "i915_drv.h"
      10                 :            : #include "i915_perf.h"
      11                 :            : #include "i915_query.h"
      12                 :            : #include <uapi/drm/i915_drm.h>
      13                 :            : 
      14                 :            : static int copy_query_item(void *query_hdr, size_t query_sz,
      15                 :            :                            u32 total_length,
      16                 :            :                            struct drm_i915_query_item *query_item)
      17                 :            : {
      18                 :            :         if (query_item->length == 0)
      19                 :            :                 return total_length;
      20                 :            : 
      21                 :            :         if (query_item->length < total_length)
      22                 :            :                 return -EINVAL;
      23                 :            : 
      24                 :            :         if (copy_from_user(query_hdr, u64_to_user_ptr(query_item->data_ptr),
      25                 :            :                            query_sz))
      26                 :            :                 return -EFAULT;
      27                 :            : 
      28                 :            :         if (!access_ok(u64_to_user_ptr(query_item->data_ptr),
      29                 :            :                        total_length))
      30                 :            :                 return -EFAULT;
      31                 :            : 
      32                 :            :         return 0;
      33                 :            : }
      34                 :            : 
      35                 :          0 : static int query_topology_info(struct drm_i915_private *dev_priv,
      36                 :            :                                struct drm_i915_query_item *query_item)
      37                 :            : {
      38                 :          0 :         const struct sseu_dev_info *sseu = &RUNTIME_INFO(dev_priv)->sseu;
      39                 :          0 :         struct drm_i915_query_topology_info topo;
      40                 :          0 :         u32 slice_length, subslice_length, eu_length, total_length;
      41                 :          0 :         int ret;
      42                 :            : 
      43         [ #  # ]:          0 :         if (query_item->flags != 0)
      44                 :            :                 return -EINVAL;
      45                 :            : 
      46         [ #  # ]:          0 :         if (sseu->max_slices == 0)
      47                 :            :                 return -ENODEV;
      48                 :            : 
      49                 :          0 :         BUILD_BUG_ON(sizeof(u8) != sizeof(sseu->slice_mask));
      50                 :            : 
      51                 :          0 :         slice_length = sizeof(sseu->slice_mask);
      52                 :          0 :         subslice_length = sseu->max_slices * sseu->ss_stride;
      53                 :          0 :         eu_length = sseu->max_slices * sseu->max_subslices * sseu->eu_stride;
      54                 :          0 :         total_length = sizeof(topo) + slice_length + subslice_length +
      55                 :            :                        eu_length;
      56                 :            : 
      57                 :          0 :         ret = copy_query_item(&topo, sizeof(topo), total_length,
      58                 :            :                               query_item);
      59         [ #  # ]:          0 :         if (ret != 0)
      60                 :            :                 return ret;
      61                 :            : 
      62         [ #  # ]:          0 :         if (topo.flags != 0)
      63                 :            :                 return -EINVAL;
      64                 :            : 
      65                 :          0 :         memset(&topo, 0, sizeof(topo));
      66                 :          0 :         topo.max_slices = sseu->max_slices;
      67                 :          0 :         topo.max_subslices = sseu->max_subslices;
      68                 :          0 :         topo.max_eus_per_subslice = sseu->max_eus_per_subslice;
      69                 :            : 
      70                 :          0 :         topo.subslice_offset = slice_length;
      71                 :          0 :         topo.subslice_stride = sseu->ss_stride;
      72                 :          0 :         topo.eu_offset = slice_length + subslice_length;
      73                 :          0 :         topo.eu_stride = sseu->eu_stride;
      74                 :            : 
      75         [ #  # ]:          0 :         if (__copy_to_user(u64_to_user_ptr(query_item->data_ptr),
      76                 :            :                            &topo, sizeof(topo)))
      77                 :            :                 return -EFAULT;
      78                 :            : 
      79         [ #  # ]:          0 :         if (__copy_to_user(u64_to_user_ptr(query_item->data_ptr + sizeof(topo)),
      80                 :          0 :                            &sseu->slice_mask, slice_length))
      81                 :            :                 return -EFAULT;
      82                 :            : 
      83         [ #  # ]:          0 :         if (__copy_to_user(u64_to_user_ptr(query_item->data_ptr +
      84                 :            :                                            sizeof(topo) + slice_length),
      85                 :          0 :                            sseu->subslice_mask, subslice_length))
      86                 :            :                 return -EFAULT;
      87                 :            : 
      88         [ #  # ]:          0 :         if (__copy_to_user(u64_to_user_ptr(query_item->data_ptr +
      89                 :            :                                            sizeof(topo) +
      90                 :            :                                            slice_length + subslice_length),
      91                 :          0 :                            sseu->eu_mask, eu_length))
      92                 :            :                 return -EFAULT;
      93                 :            : 
      94                 :          0 :         return total_length;
      95                 :            : }
      96                 :            : 
      97                 :            : static int
      98                 :          0 : query_engine_info(struct drm_i915_private *i915,
      99                 :            :                   struct drm_i915_query_item *query_item)
     100                 :            : {
     101                 :          0 :         struct drm_i915_query_engine_info __user *query_ptr =
     102                 :          0 :                                 u64_to_user_ptr(query_item->data_ptr);
     103                 :          0 :         struct drm_i915_engine_info __user *info_ptr;
     104                 :          0 :         struct drm_i915_query_engine_info query;
     105                 :          0 :         struct drm_i915_engine_info info = { };
     106                 :          0 :         unsigned int num_uabi_engines = 0;
     107                 :          0 :         struct intel_engine_cs *engine;
     108                 :          0 :         int len, ret;
     109                 :            : 
     110         [ #  # ]:          0 :         if (query_item->flags)
     111                 :            :                 return -EINVAL;
     112                 :            : 
     113   [ #  #  #  #  :          0 :         for_each_uabi_engine(engine, i915)
                   #  # ]
     114                 :          0 :                 num_uabi_engines++;
     115                 :            : 
     116                 :          0 :         len = sizeof(struct drm_i915_query_engine_info) +
     117                 :          0 :               num_uabi_engines * sizeof(struct drm_i915_engine_info);
     118                 :            : 
     119                 :          0 :         ret = copy_query_item(&query, sizeof(query), len, query_item);
     120         [ #  # ]:          0 :         if (ret != 0)
     121                 :            :                 return ret;
     122                 :            : 
     123   [ #  #  #  # ]:          0 :         if (query.num_engines || query.rsvd[0] || query.rsvd[1] ||
     124                 :            :             query.rsvd[2])
     125                 :            :                 return -EINVAL;
     126                 :            : 
     127                 :          0 :         info_ptr = &query_ptr->engines[0];
     128                 :            : 
     129   [ #  #  #  #  :          0 :         for_each_uabi_engine(engine, i915) {
                   #  # ]
     130                 :          0 :                 info.engine.engine_class = engine->uabi_class;
     131                 :          0 :                 info.engine.engine_instance = engine->uabi_instance;
     132                 :          0 :                 info.capabilities = engine->uabi_capabilities;
     133                 :            : 
     134         [ #  # ]:          0 :                 if (__copy_to_user(info_ptr, &info, sizeof(info)))
     135                 :            :                         return -EFAULT;
     136                 :            : 
     137                 :          0 :                 query.num_engines++;
     138                 :          0 :                 info_ptr++;
     139                 :            :         }
     140                 :            : 
     141         [ #  # ]:          0 :         if (__copy_to_user(query_ptr, &query, sizeof(query)))
     142                 :          0 :                 return -EFAULT;
     143                 :            : 
     144                 :            :         return len;
     145                 :            : }
     146                 :            : 
     147                 :          0 : static int can_copy_perf_config_registers_or_number(u32 user_n_regs,
     148                 :            :                                                     u64 user_regs_ptr,
     149                 :            :                                                     u32 kernel_n_regs)
     150                 :            : {
     151                 :            :         /*
     152                 :            :          * We'll just put the number of registers, and won't copy the
     153                 :            :          * register.
     154                 :            :          */
     155         [ #  # ]:          0 :         if (user_n_regs == 0)
     156                 :            :                 return 0;
     157                 :            : 
     158         [ #  # ]:          0 :         if (user_n_regs < kernel_n_regs)
     159                 :            :                 return -EINVAL;
     160                 :            : 
     161   [ #  #  #  # ]:          0 :         if (!access_ok(u64_to_user_ptr(user_regs_ptr),
     162                 :            :                        2 * sizeof(u32) * kernel_n_regs))
     163                 :          0 :                 return -EFAULT;
     164                 :            : 
     165                 :            :         return 0;
     166                 :            : }
     167                 :            : 
     168                 :          0 : static int copy_perf_config_registers_or_number(const struct i915_oa_reg *kernel_regs,
     169                 :            :                                                 u32 kernel_n_regs,
     170                 :            :                                                 u64 user_regs_ptr,
     171                 :            :                                                 u32 *user_n_regs)
     172                 :            : {
     173                 :          0 :         u32 r;
     174                 :            : 
     175         [ #  # ]:          0 :         if (*user_n_regs == 0) {
     176                 :          0 :                 *user_n_regs = kernel_n_regs;
     177                 :          0 :                 return 0;
     178                 :            :         }
     179                 :            : 
     180                 :          0 :         *user_n_regs = kernel_n_regs;
     181                 :            : 
     182         [ #  # ]:          0 :         for (r = 0; r < kernel_n_regs; r++) {
     183                 :          0 :                 u32 __user *user_reg_ptr =
     184                 :          0 :                         u64_to_user_ptr(user_regs_ptr + sizeof(u32) * r * 2);
     185                 :          0 :                 u32 __user *user_val_ptr =
     186                 :          0 :                         u64_to_user_ptr(user_regs_ptr + sizeof(u32) * r * 2 +
     187                 :            :                                         sizeof(u32));
     188                 :          0 :                 int ret;
     189                 :            : 
     190         [ #  # ]:          0 :                 ret = __put_user(i915_mmio_reg_offset(kernel_regs[r].addr),
     191                 :            :                                  user_reg_ptr);
     192         [ #  # ]:          0 :                 if (ret)
     193                 :            :                         return -EFAULT;
     194                 :            : 
     195         [ #  # ]:          0 :                 ret = __put_user(kernel_regs[r].value, user_val_ptr);
     196         [ #  # ]:          0 :                 if (ret)
     197                 :            :                         return -EFAULT;
     198                 :            :         }
     199                 :            : 
     200                 :            :         return 0;
     201                 :            : }
     202                 :            : 
     203                 :          0 : static int query_perf_config_data(struct drm_i915_private *i915,
     204                 :            :                                   struct drm_i915_query_item *query_item,
     205                 :            :                                   bool use_uuid)
     206                 :            : {
     207                 :          0 :         struct drm_i915_query_perf_config __user *user_query_config_ptr =
     208                 :          0 :                 u64_to_user_ptr(query_item->data_ptr);
     209                 :          0 :         struct drm_i915_perf_oa_config __user *user_config_ptr =
     210                 :          0 :                 u64_to_user_ptr(query_item->data_ptr +
     211                 :            :                                 sizeof(struct drm_i915_query_perf_config));
     212                 :          0 :         struct drm_i915_perf_oa_config user_config;
     213                 :          0 :         struct i915_perf *perf = &i915->perf;
     214                 :          0 :         struct i915_oa_config *oa_config;
     215                 :          0 :         char uuid[UUID_STRING_LEN + 1];
     216                 :          0 :         u64 config_id;
     217                 :          0 :         u32 flags, total_size;
     218                 :          0 :         int ret;
     219                 :            : 
     220         [ #  # ]:          0 :         if (!perf->i915)
     221                 :            :                 return -ENODEV;
     222                 :            : 
     223                 :          0 :         total_size =
     224                 :            :                 sizeof(struct drm_i915_query_perf_config) +
     225                 :            :                 sizeof(struct drm_i915_perf_oa_config);
     226                 :            : 
     227         [ #  # ]:          0 :         if (query_item->length == 0)
     228                 :            :                 return total_size;
     229                 :            : 
     230         [ #  # ]:          0 :         if (query_item->length < total_size) {
     231                 :          0 :                 DRM_DEBUG("Invalid query config data item size=%u expected=%u\n",
     232                 :            :                           query_item->length, total_size);
     233                 :          0 :                 return -EINVAL;
     234                 :            :         }
     235                 :            : 
     236         [ #  # ]:          0 :         if (!access_ok(user_query_config_ptr, total_size))
     237                 :            :                 return -EFAULT;
     238                 :            : 
     239         [ #  # ]:          0 :         if (__get_user(flags, &user_query_config_ptr->flags))
     240                 :            :                 return -EFAULT;
     241                 :            : 
     242         [ #  # ]:          0 :         if (flags != 0)
     243                 :            :                 return -EINVAL;
     244                 :            : 
     245         [ #  # ]:          0 :         if (use_uuid) {
     246                 :          0 :                 struct i915_oa_config *tmp;
     247                 :          0 :                 int id;
     248                 :            : 
     249                 :          0 :                 BUILD_BUG_ON(sizeof(user_query_config_ptr->uuid) >= sizeof(uuid));
     250                 :            : 
     251                 :          0 :                 memset(&uuid, 0, sizeof(uuid));
     252         [ #  # ]:          0 :                 if (__copy_from_user(uuid, user_query_config_ptr->uuid,
     253                 :            :                                      sizeof(user_query_config_ptr->uuid)))
     254                 :          0 :                         return -EFAULT;
     255                 :            : 
     256                 :          0 :                 oa_config = NULL;
     257                 :          0 :                 rcu_read_lock();
     258         [ #  # ]:          0 :                 idr_for_each_entry(&perf->metrics_idr, tmp, id) {
     259         [ #  # ]:          0 :                         if (!strcmp(tmp->uuid, uuid)) {
     260                 :          0 :                                 oa_config = i915_oa_config_get(tmp);
     261                 :            :                                 break;
     262                 :            :                         }
     263                 :            :                 }
     264                 :          0 :                 rcu_read_unlock();
     265                 :            :         } else {
     266         [ #  # ]:          0 :                 if (__get_user(config_id, &user_query_config_ptr->config))
     267                 :            :                         return -EFAULT;
     268                 :            : 
     269                 :          0 :                 oa_config = i915_perf_get_oa_config(perf, config_id);
     270                 :            :         }
     271         [ #  # ]:          0 :         if (!oa_config)
     272                 :            :                 return -ENOENT;
     273                 :            : 
     274         [ #  # ]:          0 :         if (__copy_from_user(&user_config, user_config_ptr,
     275                 :            :                              sizeof(user_config))) {
     276                 :          0 :                 ret = -EFAULT;
     277                 :          0 :                 goto out;
     278                 :            :         }
     279                 :            : 
     280                 :          0 :         ret = can_copy_perf_config_registers_or_number(user_config.n_boolean_regs,
     281                 :            :                                                        user_config.boolean_regs_ptr,
     282                 :            :                                                        oa_config->b_counter_regs_len);
     283         [ #  # ]:          0 :         if (ret)
     284                 :          0 :                 goto out;
     285                 :            : 
     286                 :          0 :         ret = can_copy_perf_config_registers_or_number(user_config.n_flex_regs,
     287                 :            :                                                        user_config.flex_regs_ptr,
     288                 :            :                                                        oa_config->flex_regs_len);
     289         [ #  # ]:          0 :         if (ret)
     290                 :          0 :                 goto out;
     291                 :            : 
     292                 :          0 :         ret = can_copy_perf_config_registers_or_number(user_config.n_mux_regs,
     293                 :            :                                                        user_config.mux_regs_ptr,
     294                 :            :                                                        oa_config->mux_regs_len);
     295         [ #  # ]:          0 :         if (ret)
     296                 :          0 :                 goto out;
     297                 :            : 
     298                 :          0 :         ret = copy_perf_config_registers_or_number(oa_config->b_counter_regs,
     299                 :            :                                                    oa_config->b_counter_regs_len,
     300                 :            :                                                    user_config.boolean_regs_ptr,
     301                 :            :                                                    &user_config.n_boolean_regs);
     302         [ #  # ]:          0 :         if (ret)
     303                 :          0 :                 goto out;
     304                 :            : 
     305                 :          0 :         ret = copy_perf_config_registers_or_number(oa_config->flex_regs,
     306                 :            :                                                    oa_config->flex_regs_len,
     307                 :            :                                                    user_config.flex_regs_ptr,
     308                 :            :                                                    &user_config.n_flex_regs);
     309         [ #  # ]:          0 :         if (ret)
     310                 :          0 :                 goto out;
     311                 :            : 
     312                 :          0 :         ret = copy_perf_config_registers_or_number(oa_config->mux_regs,
     313                 :            :                                                    oa_config->mux_regs_len,
     314                 :            :                                                    user_config.mux_regs_ptr,
     315                 :            :                                                    &user_config.n_mux_regs);
     316         [ #  # ]:          0 :         if (ret)
     317                 :          0 :                 goto out;
     318                 :            : 
     319                 :          0 :         memcpy(user_config.uuid, oa_config->uuid, sizeof(user_config.uuid));
     320                 :            : 
     321         [ #  # ]:          0 :         if (__copy_to_user(user_config_ptr, &user_config,
     322                 :            :                            sizeof(user_config))) {
     323                 :          0 :                 ret = -EFAULT;
     324                 :          0 :                 goto out;
     325                 :            :         }
     326                 :            : 
     327                 :            :         ret = total_size;
     328                 :            : 
     329                 :          0 : out:
     330                 :          0 :         i915_oa_config_put(oa_config);
     331                 :          0 :         return ret;
     332                 :            : }
     333                 :            : 
     334                 :          0 : static size_t sizeof_perf_config_list(size_t count)
     335                 :            : {
     336                 :          0 :         return sizeof(struct drm_i915_query_perf_config) + sizeof(u64) * count;
     337                 :            : }
     338                 :            : 
     339                 :          0 : static size_t sizeof_perf_metrics(struct i915_perf *perf)
     340                 :            : {
     341                 :          0 :         struct i915_oa_config *tmp;
     342                 :          0 :         size_t i;
     343                 :          0 :         int id;
     344                 :            : 
     345                 :          0 :         i = 1;
     346                 :          0 :         rcu_read_lock();
     347         [ #  # ]:          0 :         idr_for_each_entry(&perf->metrics_idr, tmp, id)
     348                 :          0 :                 i++;
     349                 :          0 :         rcu_read_unlock();
     350                 :            : 
     351                 :          0 :         return sizeof_perf_config_list(i);
     352                 :            : }
     353                 :            : 
     354                 :            : static int query_perf_config_list(struct drm_i915_private *i915,
     355                 :            :                                   struct drm_i915_query_item *query_item)
     356                 :            : {
     357                 :            :         struct drm_i915_query_perf_config __user *user_query_config_ptr =
     358                 :            :                 u64_to_user_ptr(query_item->data_ptr);
     359                 :            :         struct i915_perf *perf = &i915->perf;
     360                 :            :         u64 *oa_config_ids = NULL;
     361                 :            :         int alloc, n_configs;
     362                 :            :         u32 flags;
     363                 :            :         int ret;
     364                 :            : 
     365                 :            :         if (!perf->i915)
     366                 :            :                 return -ENODEV;
     367                 :            : 
     368                 :            :         if (query_item->length == 0)
     369                 :            :                 return sizeof_perf_metrics(perf);
     370                 :            : 
     371                 :            :         if (get_user(flags, &user_query_config_ptr->flags))
     372                 :            :                 return -EFAULT;
     373                 :            : 
     374                 :            :         if (flags != 0)
     375                 :            :                 return -EINVAL;
     376                 :            : 
     377                 :            :         n_configs = 1;
     378                 :            :         do {
     379                 :            :                 struct i915_oa_config *tmp;
     380                 :            :                 u64 *ids;
     381                 :            :                 int id;
     382                 :            : 
     383                 :            :                 ids = krealloc(oa_config_ids,
     384                 :            :                                n_configs * sizeof(*oa_config_ids),
     385                 :            :                                GFP_KERNEL);
     386                 :            :                 if (!ids)
     387                 :            :                         return -ENOMEM;
     388                 :            : 
     389                 :            :                 alloc = fetch_and_zero(&n_configs);
     390                 :            : 
     391                 :            :                 ids[n_configs++] = 1ull; /* reserved for test_config */
     392                 :            :                 rcu_read_lock();
     393                 :            :                 idr_for_each_entry(&perf->metrics_idr, tmp, id) {
     394                 :            :                         if (n_configs < alloc)
     395                 :            :                                 ids[n_configs] = id;
     396                 :            :                         n_configs++;
     397                 :            :                 }
     398                 :            :                 rcu_read_unlock();
     399                 :            : 
     400                 :            :                 oa_config_ids = ids;
     401                 :            :         } while (n_configs > alloc);
     402                 :            : 
     403                 :            :         if (query_item->length < sizeof_perf_config_list(n_configs)) {
     404                 :            :                 DRM_DEBUG("Invalid query config list item size=%u expected=%zu\n",
     405                 :            :                           query_item->length,
     406                 :            :                           sizeof_perf_config_list(n_configs));
     407                 :            :                 kfree(oa_config_ids);
     408                 :            :                 return -EINVAL;
     409                 :            :         }
     410                 :            : 
     411                 :            :         if (put_user(n_configs, &user_query_config_ptr->config)) {
     412                 :            :                 kfree(oa_config_ids);
     413                 :            :                 return -EFAULT;
     414                 :            :         }
     415                 :            : 
     416                 :            :         ret = copy_to_user(user_query_config_ptr + 1,
     417                 :            :                            oa_config_ids,
     418                 :            :                            n_configs * sizeof(*oa_config_ids));
     419                 :            :         kfree(oa_config_ids);
     420                 :            :         if (ret)
     421                 :            :                 return -EFAULT;
     422                 :            : 
     423                 :            :         return sizeof_perf_config_list(n_configs);
     424                 :            : }
     425                 :            : 
     426                 :          0 : static int query_perf_config(struct drm_i915_private *i915,
     427                 :            :                              struct drm_i915_query_item *query_item)
     428                 :            : {
     429   [ #  #  #  # ]:          0 :         switch (query_item->flags) {
     430                 :          0 :         case DRM_I915_QUERY_PERF_CONFIG_LIST:
     431                 :          0 :                 return query_perf_config_list(i915, query_item);
     432                 :          0 :         case DRM_I915_QUERY_PERF_CONFIG_DATA_FOR_UUID:
     433                 :          0 :                 return query_perf_config_data(i915, query_item, true);
     434                 :          0 :         case DRM_I915_QUERY_PERF_CONFIG_DATA_FOR_ID:
     435                 :          0 :                 return query_perf_config_data(i915, query_item, false);
     436                 :            :         default:
     437                 :            :                 return -EINVAL;
     438                 :            :         }
     439                 :            : }
     440                 :            : 
     441                 :            : static int (* const i915_query_funcs[])(struct drm_i915_private *dev_priv,
     442                 :            :                                         struct drm_i915_query_item *query_item) = {
     443                 :            :         query_topology_info,
     444                 :            :         query_engine_info,
     445                 :            :         query_perf_config,
     446                 :            : };
     447                 :            : 
     448                 :          0 : int i915_query_ioctl(struct drm_device *dev, void *data, struct drm_file *file)
     449                 :            : {
     450         [ #  # ]:          0 :         struct drm_i915_private *dev_priv = to_i915(dev);
     451                 :          0 :         struct drm_i915_query *args = data;
     452                 :          0 :         struct drm_i915_query_item __user *user_item_ptr =
     453                 :          0 :                 u64_to_user_ptr(args->items_ptr);
     454                 :          0 :         u32 i;
     455                 :            : 
     456         [ #  # ]:          0 :         if (args->flags != 0)
     457                 :            :                 return -EINVAL;
     458                 :            : 
     459         [ #  # ]:          0 :         for (i = 0; i < args->num_items; i++, user_item_ptr++) {
     460                 :          0 :                 struct drm_i915_query_item item;
     461                 :          0 :                 unsigned long func_idx;
     462                 :          0 :                 int ret;
     463                 :            : 
     464         [ #  # ]:          0 :                 if (copy_from_user(&item, user_item_ptr, sizeof(item)))
     465                 :          0 :                         return -EFAULT;
     466                 :            : 
     467         [ #  # ]:          0 :                 if (item.query_id == 0)
     468                 :            :                         return -EINVAL;
     469                 :            : 
     470                 :          0 :                 if (overflows_type(item.query_id - 1, unsigned long))
     471                 :            :                         return -EINVAL;
     472                 :            : 
     473                 :          0 :                 func_idx = item.query_id - 1;
     474                 :            : 
     475                 :          0 :                 ret = -EINVAL;
     476         [ #  # ]:          0 :                 if (func_idx < ARRAY_SIZE(i915_query_funcs)) {
     477                 :          0 :                         func_idx = array_index_nospec(func_idx,
     478                 :            :                                                       ARRAY_SIZE(i915_query_funcs));
     479                 :          0 :                         ret = i915_query_funcs[func_idx](dev_priv, &item);
     480                 :            :                 }
     481                 :            : 
     482                 :            :                 /* Only write the length back to userspace if they differ. */
     483   [ #  #  #  # ]:          0 :                 if (ret != item.length && put_user(ret, &user_item_ptr->length))
     484                 :            :                         return -EFAULT;
     485                 :            :         }
     486                 :            : 
     487                 :            :         return 0;
     488                 :            : }

Generated by: LCOV version 1.14