drm/i915: Abort command parsing for chained batches
authorBrad Volkin <bradley.d.volkin@intel.com>
Thu, 16 Oct 2014 19:24:42 +0000 (12:24 -0700)
committerDaniel Vetter <daniel.vetter@ffwll.ch>
Tue, 4 Nov 2014 13:04:54 +0000 (14:04 +0100)
libva uses chained batch buffers in a way that the command parser
can't generally handle. Fortunately, libva doesn't need to write
registers from batch buffers in the way that mesa does, so this
patch causes the driver to fall back to non-secure dispatch if
the parser detects a chained batch buffer.

Note: The 2nd hunk to munge the error code of the parser looks a bit
superflous. At least until we have the batch copy code ready and can
run the cmd parser in granting mode. But it isn't since we still need
to let existing libva buffers pass (though not with elevated privs
ofc!).

Testcase: igt/gem_exec_parse/chained-batch
Signed-off-by: Brad Volkin <bradley.d.volkin@intel.com>
[danvet: Add note - this confused me in review and Brad clarified
things (after a few mails ...).]
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
drivers/gpu/drm/i915/i915_cmd_parser.c
drivers/gpu/drm/i915/i915_gem_execbuffer.c

index 86b3ae0934a75c90c694c24f9faee3623ccdd41b..ef38915075a1a26633657dc838e91b6e1dcad99e 100644 (file)
@@ -138,6 +138,11 @@ static const struct drm_i915_cmd_descriptor common_cmds[] = {
                        .mask = MI_GLOBAL_GTT,
                        .expected = 0,
              }},                                                      ),
+       /*
+        * MI_BATCH_BUFFER_START requires some special handling. It's not
+        * really a 'skip' action but it doesn't seem like it's worth adding
+        * a new action. See i915_parse_cmds().
+        */
        CMD(  MI_BATCH_BUFFER_START,            SMI,   !F,  0xFF,   S  ),
 };
 
@@ -955,7 +960,8 @@ static bool check_cmd(const struct intel_engine_cs *ring,
  * Parses the specified batch buffer looking for privilege violations as
  * described in the overview.
  *
- * Return: non-zero if the parser finds violations or otherwise fails
+ * Return: non-zero if the parser finds violations or otherwise fails; -EACCES
+ * if the batch appears legal but should use hardware parsing
  */
 int i915_parse_cmds(struct intel_engine_cs *ring,
                    struct drm_i915_gem_object *batch_obj,
@@ -1002,6 +1008,16 @@ int i915_parse_cmds(struct intel_engine_cs *ring,
                        break;
                }
 
+               /*
+                * If the batch buffer contains a chained batch, return an
+                * error that tells the caller to abort and dispatch the
+                * workload as a non-secure batch.
+                */
+               if (desc->cmd.value == MI_BATCH_BUFFER_START) {
+                       ret = -EACCES;
+                       break;
+               }
+
                if (desc->flags & CMD_DESC_FIXED)
                        length = desc->length.fixed;
                else
index c70b329b07cdf304430b90540d62b65e16d14c54..4b7f5c104ce0f373979fceb21828120ea23cb17b 100644 (file)
@@ -1365,17 +1365,19 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data,
                                      batch_obj,
                                      args->batch_start_offset,
                                      file->is_master);
-               if (ret)
-                       goto err;
-
-               /*
-                * XXX: Actually do this when enabling batch copy...
-                *
-                * Set the DISPATCH_SECURE bit to remove the NON_SECURE bit
-                * from MI_BATCH_BUFFER_START commands issued in the
-                * dispatch_execbuffer implementations. We specifically don't
-                * want that set when the command parser is enabled.
-                */
+               if (ret) {
+                       if (ret != -EACCES)
+                               goto err;
+               } else {
+                       /*
+                        * XXX: Actually do this when enabling batch copy...
+                        *
+                        * Set the DISPATCH_SECURE bit to remove the NON_SECURE bit
+                        * from MI_BATCH_BUFFER_START commands issued in the
+                        * dispatch_execbuffer implementations. We specifically don't
+                        * want that set when the command parser is enabled.
+                        */
+               }
        }
 
        /* snb/ivb/vlv conflate the "batch in ppgtt" bit with the "non-secure