Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
[deliverable/linux.git] / drivers / gpu / drm / i915 / i915_cmd_parser.c
index a337f33bec5b2eb92bae7ce8860d6e6a84042458..b0fd6a7b060380d5d2d8dfe94192a3f3f59dcb9f 100644 (file)
@@ -215,7 +215,8 @@ static const struct drm_i915_cmd_descriptor hsw_render_cmds[] = {
        CMD(  MI_RS_CONTEXT,                    SMI,    F,  1,      S  ),
        CMD(  MI_LOAD_SCAN_LINES_INCL,          SMI,   !F,  0x3F,   M  ),
        CMD(  MI_LOAD_SCAN_LINES_EXCL,          SMI,   !F,  0x3F,   R  ),
-       CMD(  MI_LOAD_REGISTER_REG,             SMI,   !F,  0xFF,   R  ),
+       CMD(  MI_LOAD_REGISTER_REG,             SMI,   !F,  0xFF,   W,
+             .reg = { .offset = 1, .mask = 0x007FFFFC, .step = 1 }    ),
        CMD(  MI_RS_STORE_DATA_IMM,             SMI,   !F,  0xFF,   S  ),
        CMD(  MI_LOAD_URB_MEM,                  SMI,   !F,  0xFF,   S  ),
        CMD(  MI_STORE_URB_MEM,                 SMI,   !F,  0xFF,   S  ),
@@ -736,7 +737,7 @@ static void fini_hash_table(struct intel_engine_cs *engine)
 
 /**
  * i915_cmd_parser_init_ring() - set cmd parser related fields for a ringbuffer
- * @ring: the ringbuffer to initialize
+ * @engine: the engine to initialize
  *
  * Optionally initializes fields related to batch buffer command parsing in the
  * struct intel_engine_cs based on whether the platform requires software
@@ -750,12 +751,12 @@ int i915_cmd_parser_init_ring(struct intel_engine_cs *engine)
        int cmd_table_count;
        int ret;
 
-       if (!IS_GEN7(engine->dev))
+       if (!IS_GEN7(engine->i915))
                return 0;
 
        switch (engine->id) {
        case RCS:
-               if (IS_HASWELL(engine->dev)) {
+               if (IS_HASWELL(engine->i915)) {
                        cmd_tables = hsw_render_ring_cmds;
                        cmd_table_count =
                                ARRAY_SIZE(hsw_render_ring_cmds);
@@ -764,7 +765,7 @@ int i915_cmd_parser_init_ring(struct intel_engine_cs *engine)
                        cmd_table_count = ARRAY_SIZE(gen7_render_cmds);
                }
 
-               if (IS_HASWELL(engine->dev)) {
+               if (IS_HASWELL(engine->i915)) {
                        engine->reg_tables = hsw_render_reg_tables;
                        engine->reg_table_count = ARRAY_SIZE(hsw_render_reg_tables);
                } else {
@@ -780,7 +781,7 @@ int i915_cmd_parser_init_ring(struct intel_engine_cs *engine)
                engine->get_cmd_length_mask = gen7_bsd_get_cmd_length_mask;
                break;
        case BCS:
-               if (IS_HASWELL(engine->dev)) {
+               if (IS_HASWELL(engine->i915)) {
                        cmd_tables = hsw_blt_ring_cmds;
                        cmd_table_count = ARRAY_SIZE(hsw_blt_ring_cmds);
                } else {
@@ -788,7 +789,7 @@ int i915_cmd_parser_init_ring(struct intel_engine_cs *engine)
                        cmd_table_count = ARRAY_SIZE(gen7_blt_cmds);
                }
 
-               if (IS_HASWELL(engine->dev)) {
+               if (IS_HASWELL(engine->i915)) {
                        engine->reg_tables = hsw_blt_reg_tables;
                        engine->reg_table_count = ARRAY_SIZE(hsw_blt_reg_tables);
                } else {
@@ -829,7 +830,7 @@ int i915_cmd_parser_init_ring(struct intel_engine_cs *engine)
 
 /**
  * i915_cmd_parser_fini_ring() - clean up cmd parser related fields
- * @ring: the ringbuffer to clean up
+ * @engine: the engine to clean up
  *
  * Releases any resources related to command parsing that may have been
  * initialized for the specified ring.
@@ -1023,7 +1024,7 @@ unpin_src:
 
 /**
  * i915_needs_cmd_parser() - should a given ring use software command parsing?
- * @ring: the ring in question
+ * @engine: the engine in question
  *
  * Only certain platforms require software batch buffer command parsing, and
  * only when enabled via module parameter.
@@ -1035,7 +1036,7 @@ bool i915_needs_cmd_parser(struct intel_engine_cs *engine)
        if (!engine->needs_cmd_parser)
                return false;
 
-       if (!USES_PPGTT(engine->dev))
+       if (!USES_PPGTT(engine->i915))
                return false;
 
        return (i915.enable_cmd_parser == 1);
@@ -1098,6 +1099,11 @@ static bool check_cmd(const struct intel_engine_cs *engine,
                                        return false;
                                }
 
+                               if (desc->cmd.value == MI_LOAD_REGISTER_REG) {
+                                       DRM_DEBUG_DRIVER("CMD: Rejected LRR to OACONTROL\n");
+                                       return false;
+                               }
+
                                if (desc->cmd.value == MI_LOAD_REGISTER_IMM(1))
                                        *oacontrol_set = (cmd[offset + 1] != 0);
                        }
@@ -1113,6 +1119,12 @@ static bool check_cmd(const struct intel_engine_cs *engine,
                                        return false;
                                }
 
+                               if (desc->cmd.value == MI_LOAD_REGISTER_REG) {
+                                       DRM_DEBUG_DRIVER("CMD: Rejected LRR to masked register 0x%08X\n",
+                                                        reg_addr);
+                                       return false;
+                               }
+
                                if (desc->cmd.value == MI_LOAD_REGISTER_IMM(1) &&
                                    (offset + 2 > length ||
                                     (cmd[offset + 1] & reg->mask) != reg->value)) {
@@ -1164,7 +1176,7 @@ static bool check_cmd(const struct intel_engine_cs *engine,
 
 /**
  * i915_parse_cmds() - parse a submitted batch buffer for privilege violations
- * @ring: the ring on which the batch is to execute
+ * @engine: the engine on which the batch is to execute
  * @batch_obj: the batch buffer in question
  * @shadow_batch_obj: copy of the batch buffer in question
  * @batch_start_offset: byte offset in the batch at which execution starts
@@ -1269,14 +1281,28 @@ int i915_parse_cmds(struct intel_engine_cs *engine,
 
 /**
  * i915_cmd_parser_get_version() - get the cmd parser version number
+ * @dev_priv: i915 device private
  *
  * The cmd parser maintains a simple increasing integer version number suitable
  * for passing to userspace clients to determine what operations are permitted.
  *
  * Return: the current version number of the cmd parser
  */
-int i915_cmd_parser_get_version(void)
+int i915_cmd_parser_get_version(struct drm_i915_private *dev_priv)
 {
+       struct intel_engine_cs *engine;
+       bool active = false;
+
+       /* If the command parser is not enabled, report 0 - unsupported */
+       for_each_engine(engine, dev_priv) {
+               if (i915_needs_cmd_parser(engine)) {
+                       active = true;
+                       break;
+               }
+       }
+       if (!active)
+               return 0;
+
        /*
         * Command parser version history
         *
@@ -1288,6 +1314,7 @@ int i915_cmd_parser_get_version(void)
         * 4. L3 atomic chicken bits of HSW_SCRATCH1 and HSW_ROW_CHICKEN3.
         * 5. GPGPU dispatch compute indirect registers.
         * 6. TIMESTAMP register and Haswell CS GPR registers
+        * 7. Allow MI_LOAD_REGISTER_REG between whitelisted registers.
         */
-       return 6;
+       return 7;
 }
This page took 0.032013 seconds and 5 git commands to generate.