@@ -400,6 +400,28 @@ int i915_parse_cmds(struct intel_ring_buffer *ring,
}
}
+ if (desc->flags & CMD_DESC_BITMASK) {
+ int i;
+
+ for (i = 0; i < desc->bits_count; i++) {
+ u32 dword = cmd[desc->bits[i].offset] &
+ desc->bits[i].mask;
+
+ if (dword != desc->bits[i].expected) {
+ DRM_DEBUG_DRIVER("CMD: Rejected command 0x%08X for bitmask 0x%08X (exp=0x%08X act=0x%08X) (ring=%d)\n",
+ *cmd,
+ desc->bits[i].mask,
+ desc->bits[i].expected,
+ dword, ring->id);
+ ret = -EINVAL;
+ break;
+ }
+ }
+
+ if (ret)
+ break;
+ }
+
cmd += length;
}
@@ -1752,6 +1752,7 @@ struct drm_i915_cmd_descriptor {
#define CMD_DESC_SKIP (1<<1)
#define CMD_DESC_REJECT (1<<2)
#define CMD_DESC_REGISTER (1<<3)
+#define CMD_DESC_BITMASK (1<<4)
/**
* The command's unique identification bits and the bitmask to get them.
@@ -1784,6 +1785,21 @@ struct drm_i915_cmd_descriptor {
u32 offset;
u32 mask;
} reg;
+
+#define MAX_CMD_DESC_BITMASKS 3
+ /**
+ * Describes command checks where a particular dword is masked and
+ * compared against an expected value. If the command does not match
+ * the expected value, the parser rejects it. Only valid if flags has
+ * the CMD_DESC_BITMASK bit set.
+ */
+ struct {
+ u32 offset;
+ u32 mask;
+ u32 expected;
+ } bits[MAX_CMD_DESC_BITMASKS];
+ /** Number of valid entries in the bits array */
+ int bits_count;
};
/**