drm/i915: Add support for mandatory cmdparsing

commit 311a50e76a33d1e029563c24b2ff6db0c02b5afe upstream.

The existing cmdparser for gen7 can be bypassed by specifying
batch_len=0 in the execbuf call. This is safe because bypassing
simply reduces the cmd-set available.

In a later patch we will introduce cmdparsing for gen9, as a
security measure, which must be strictly enforced since without
it we are vulnerable to DoS attacks.

Introduce the concept of 'required' cmd parsing that cannot be
bypassed by submitting zero-length bb's.

v2: rebase (Mika)
v2: rebase (Mika)
v3: fix conflict on engine flags (Mika)

Signed-off-by: Jon Bloomfield <jon.bloomfield@intel.com>
Cc: Tony Luck <tony.luck@intel.com>
Cc: Dave Airlie <airlied@redhat.com>
Cc: Takashi Iwai <tiwai@suse.de>
Cc: Tyler Hicks <tyhicks@canonical.com>
Signed-off-by: Mika Kuoppala <mika.kuoppala@linux.intel.com>
Reviewed-by: Chris Wilson <chris.p.wilson@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
Jon Bloomfield 2018-08-01 09:33:59 -07:00 committed by Greg Kroah-Hartman
parent 544fd7d9d4
commit 17e89f3821
3 changed files with 12 additions and 24 deletions

View file

@ -734,7 +734,7 @@ int i915_cmd_parser_init_ring(struct intel_engine_cs *ring)
return ret;
}
ring->needs_cmd_parser = true;
ring->using_cmd_parser = true;
return 0;
}
@ -748,7 +748,7 @@ int i915_cmd_parser_init_ring(struct intel_engine_cs *ring)
*/
void i915_cmd_parser_fini_ring(struct intel_engine_cs *ring)
{
if (!ring->needs_cmd_parser)
if (!ring->using_cmd_parser)
return;
fini_hash_table(ring);
@ -914,26 +914,6 @@ unpin_src:
return ret ? ERR_PTR(ret) : dst;
}
/**
* i915_needs_cmd_parser() - should a given ring use software command parsing?
* @ring: the ring in question
*
* Only certain platforms require software batch buffer command parsing, and
* only when enabled via module parameter.
*
* Return: true if the ring requires software command parsing
*/
bool i915_needs_cmd_parser(struct intel_engine_cs *ring)
{
if (!ring->needs_cmd_parser)
return false;
if (!USES_PPGTT(ring->dev))
return false;
return (i915.enable_cmd_parser == 1);
}
static bool check_cmd(const struct intel_engine_cs *ring,
const struct drm_i915_cmd_descriptor *desc,
const u32 *cmd, u32 length,

View file

@ -1320,6 +1320,13 @@ eb_get_batch(struct eb_vmas *eb)
return vma->obj;
}
static inline bool use_cmdparser(const struct intel_engine_cs *ring,
u32 batch_len)
{
return ring->requires_cmd_parser ||
(ring->using_cmd_parser && batch_len && USES_PPGTT(ring->dev));
}
static int
i915_gem_do_execbuffer(struct drm_device *dev, void *data,
struct drm_file *file,
@ -1491,7 +1498,7 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data,
}
params->args_batch_start_offset = args->batch_start_offset;
if (i915_needs_cmd_parser(ring) && args->batch_len) {
if (use_cmdparser(ring, args->batch_len)) {
struct drm_i915_gem_object *parsed_batch_obj;
parsed_batch_obj = i915_gem_execbuffer_parse(ring,

View file

@ -314,7 +314,8 @@ struct intel_engine_cs {
volatile u32 *cpu_page;
} scratch;
bool needs_cmd_parser;
bool using_cmd_parser;
bool requires_cmd_parser;
/*
* Table of commands the command parser needs to know about