[Intel-gfx] [RFC 08/22] drm/i915: Add support for checking register accesses

bradley.d.volkin at intel.com bradley.d.volkin at intel.com
Tue Nov 26 17:51:25 CET 2013


From: Brad Volkin <bradley.d.volkin at intel.com>

Some OpenGL/media features require userspace to perform register
accesses from batch buffers on Gen hardware.

To enable this, each ring gets a whitelist of registers that userspace
may access from a batch buffer. With this patch, no whitelists are defined,
so no access is allowed.

OTC-Tracker: AXIA-4631
Change-Id: Ibf607ec3b1df0076f6acbd9aee34a2ee48cfac6b
Signed-off-by: Brad Volkin <bradley.d.volkin at intel.com>
---
 drivers/gpu/drm/i915/i915_cmd_parser.c  | 26 ++++++++++++++++++++++++++
 drivers/gpu/drm/i915/i915_drv.h         | 19 ++++++++++++++++---
 drivers/gpu/drm/i915/intel_ringbuffer.h |  6 ++++++
 3 files changed, 48 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_cmd_parser.c b/drivers/gpu/drm/i915/i915_cmd_parser.c
index c64f640..2dbca01 100644
--- a/drivers/gpu/drm/i915/i915_cmd_parser.c
+++ b/drivers/gpu/drm/i915/i915_cmd_parser.c
@@ -285,6 +285,20 @@ find_cmd(struct intel_ring_buffer *ring,
 	return default_desc;
 }
 
+static int valid_reg(const u32 *table, int count, u32 addr)
+{
+	if (table && count != 0) {
+		int i;
+
+		for (i = 0; i < count; i++) {
+			if (table[i] == addr)
+				return 1;
+		}
+	}
+
+	return 0;
+}
+
 static u32 *vmap_batch(struct drm_i915_gem_object *obj)
 {
 	int i;
@@ -374,6 +388,18 @@ int i915_parse_cmds(struct intel_ring_buffer *ring,
 			break;
 		}
 
+		if (desc->flags & CMD_DESC_REGISTER) {
+			u32 reg_addr = cmd[desc->reg.offset] & desc->reg.mask;
+
+			if (!valid_reg(ring->reg_table,
+				       ring->reg_count, reg_addr)) {
+				DRM_DEBUG_DRIVER("CMD: Rejected register 0x%08X in command: 0x%08X (ring=%d)\n",
+						 reg_addr, *cmd, ring->id);
+				ret = -EINVAL;
+				break;
+			}
+		}
+
 		cmd += length;
 	}
 
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 6ace856..83b6031 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1744,11 +1744,14 @@ struct drm_i915_cmd_descriptor {
 	 *                standard length encoding for the opcode range in
 	 *                which it falls
 	 * CMD_DESC_REJECT: The command is never allowed
+	 * CMD_DESC_REGISTER: The command should be checked against the
+	 *                    register whitelist for the appropriate ring
 	 */
 	u32 flags;
-#define CMD_DESC_FIXED  (1<<0)
-#define CMD_DESC_SKIP   (1<<1)
-#define CMD_DESC_REJECT (1<<2)
+#define CMD_DESC_FIXED    (1<<0)
+#define CMD_DESC_SKIP     (1<<1)
+#define CMD_DESC_REJECT   (1<<2)
+#define CMD_DESC_REGISTER (1<<3)
 
 	/**
 	 * The command's unique identification bits and the bitmask to get them.
@@ -1771,6 +1774,16 @@ struct drm_i915_cmd_descriptor {
 		u32 fixed;
 		u32 mask;
 	} length;
+
+	/**
+	 * Describes where to find a register address in the command to check
+	 * against the ring's register whitelist. Only valid if flags has the
+	 * CMD_DESC_REGISTER bit set.
+	 */
+	struct {
+		u32 offset;
+		u32 mask;
+	} reg;
 };
 
 /**
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h
index 8e71b59..b898105a 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.h
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.h
@@ -171,6 +171,12 @@ struct  intel_ring_buffer {
 	int cmd_table_count;
 
 	/**
+	 * Table of registers allowed in commands that read/write registers.
+	 */
+	const u32 *reg_table;
+	int reg_count;
+
+	/**
 	 * Returns the bitmask for the length field of the specified command.
 	 * Return 0 for an unrecognized/invalid command.
 	 *
-- 
1.8.4.4




More information about the Intel-gfx mailing list