drm/i915/query: Split out query item checks

This simplifies adding new query item objects.

v2: Use query_hdr (Tvrtko, Chris).
    int instead of u32 in return (Tvrtko)
v3: More naming fixes (Tvrtko)

Signed-off-by: Abdiel Janulgue <abdiel.janulgue@linux.intel.com>
Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Reviewed-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Link: https://patchwork.freedesktop.org/patch/msgid/20190211173251.7131-1-abdiel.janulgue@linux.intel.com
This commit is contained in:
Abdiel Janulgue 2019-02-11 19:32:51 +02:00 committed by Chris Wilson
parent 368375107b
commit 5a80e4a2cd

View File

@ -10,12 +10,34 @@
#include "i915_query.h" #include "i915_query.h"
#include <uapi/drm/i915_drm.h> #include <uapi/drm/i915_drm.h>
static int copy_query_item(void *query_hdr, size_t query_sz,
u32 total_length,
struct drm_i915_query_item *query_item)
{
if (query_item->length == 0)
return total_length;
if (query_item->length < total_length)
return -EINVAL;
if (copy_from_user(query_hdr, u64_to_user_ptr(query_item->data_ptr),
query_sz))
return -EFAULT;
if (!access_ok(u64_to_user_ptr(query_item->data_ptr),
total_length))
return -EFAULT;
return 0;
}
static int query_topology_info(struct drm_i915_private *dev_priv, static int query_topology_info(struct drm_i915_private *dev_priv,
struct drm_i915_query_item *query_item) struct drm_i915_query_item *query_item)
{ {
const struct sseu_dev_info *sseu = &RUNTIME_INFO(dev_priv)->sseu; const struct sseu_dev_info *sseu = &RUNTIME_INFO(dev_priv)->sseu;
struct drm_i915_query_topology_info topo; struct drm_i915_query_topology_info topo;
u32 slice_length, subslice_length, eu_length, total_length; u32 slice_length, subslice_length, eu_length, total_length;
int ret;
if (query_item->flags != 0) if (query_item->flags != 0)
return -EINVAL; return -EINVAL;
@ -33,23 +55,14 @@ static int query_topology_info(struct drm_i915_private *dev_priv,
total_length = sizeof(topo) + slice_length + subslice_length + eu_length; total_length = sizeof(topo) + slice_length + subslice_length + eu_length;
if (query_item->length == 0) ret = copy_query_item(&topo, sizeof(topo), total_length,
return total_length; query_item);
if (ret != 0)
if (query_item->length < total_length) return ret;
return -EINVAL;
if (copy_from_user(&topo, u64_to_user_ptr(query_item->data_ptr),
sizeof(topo)))
return -EFAULT;
if (topo.flags != 0) if (topo.flags != 0)
return -EINVAL; return -EINVAL;
if (!access_ok(u64_to_user_ptr(query_item->data_ptr),
total_length))
return -EFAULT;
memset(&topo, 0, sizeof(topo)); memset(&topo, 0, sizeof(topo));
topo.max_slices = sseu->max_slices; topo.max_slices = sseu->max_slices;
topo.max_subslices = sseu->max_subslices; topo.max_subslices = sseu->max_subslices;