aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm
diff options
context:
space:
mode:
authorBrad Volkin <bradley.d.volkin@intel.com>2014-02-18 13:15:46 -0500
committerDaniel Vetter <daniel.vetter@ffwll.ch>2014-03-07 16:37:00 -0500
commit351e3db2b3631556607d0d94fa26df8e2e0d0fd8 (patch)
tree5aff6460da0f3ac6973e0185ee04764871c60a1b /drivers/gpu/drm
parent4c914c0c7c787b8f730128a8cdcca9c50b0784ab (diff)
drm/i915: Implement command buffer parsing logic
The command parser scans batch buffers submitted via execbuffer ioctls before the driver submits them to hardware. At a high level, it looks for several things: 1) Commands which are explicitly defined as privileged or which should only be used by the kernel driver. The parser generally rejects such commands, with the provision that it may allow some from the drm master process. 2) Commands which access registers. To support correct/enhanced userspace functionality, particularly certain OpenGL extensions, the parser provides a whitelist of registers which userspace may safely access (for both normal and drm master processes). 3) Commands which access privileged memory (i.e. GGTT, HWS page, etc). The parser always rejects such commands. See the overview comment in the source for more details. This patch only implements the logic. Subsequent patches will build the tables that drive the parser. v2: Don't set the secure bit if the parser succeeds Fail harder during init Makefile cleanup Kerneldoc cleanup Clarify module param description Convert ints to bools in a few places Move client/subclient defs to i915_reg.h Remove the bits_count field OTC-Tracker: AXIA-4631 Change-Id: I50b98c71c6655893291c78a2d1b8954577b37a30 Signed-off-by: Brad Volkin <bradley.d.volkin@intel.com> Reviewed-by: Jani Nikula <jani.nikula@intel.com> [danvet: Appease checkpatch.] Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Diffstat (limited to 'drivers/gpu/drm')
-rw-r--r--drivers/gpu/drm/i915/Makefile1
-rw-r--r--drivers/gpu/drm/i915/i915_cmd_parser.c485
-rw-r--r--drivers/gpu/drm/i915/i915_drv.h93
-rw-r--r--drivers/gpu/drm/i915/i915_gem_execbuffer.c18
-rw-r--r--drivers/gpu/drm/i915/i915_params.c5
-rw-r--r--drivers/gpu/drm/i915/i915_reg.h12
-rw-r--r--drivers/gpu/drm/i915/intel_ringbuffer.c2
-rw-r--r--drivers/gpu/drm/i915/intel_ringbuffer.h32
8 files changed, 648 insertions, 0 deletions
diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
index 4850494bd548..3569122b1995 100644
--- a/drivers/gpu/drm/i915/Makefile
+++ b/drivers/gpu/drm/i915/Makefile
@@ -14,6 +14,7 @@ i915-y := i915_drv.o i915_dma.o i915_irq.o \
14 i915_gem_gtt.o \ 14 i915_gem_gtt.o \
15 i915_gem_stolen.o \ 15 i915_gem_stolen.o \
16 i915_gem_tiling.o \ 16 i915_gem_tiling.o \
17 i915_cmd_parser.o \
17 i915_params.o \ 18 i915_params.o \
18 i915_sysfs.o \ 19 i915_sysfs.o \
19 i915_trace_points.o \ 20 i915_trace_points.o \
diff --git a/drivers/gpu/drm/i915/i915_cmd_parser.c b/drivers/gpu/drm/i915/i915_cmd_parser.c
new file mode 100644
index 000000000000..7a5756e9bb86
--- /dev/null
+++ b/drivers/gpu/drm/i915/i915_cmd_parser.c
@@ -0,0 +1,485 @@
1/*
2 * Copyright © 2013 Intel Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21 * IN THE SOFTWARE.
22 *
23 * Authors:
24 * Brad Volkin <bradley.d.volkin@intel.com>
25 *
26 */
27
28#include "i915_drv.h"
29
30/**
31 * DOC: i915 batch buffer command parser
32 *
33 * Motivation:
34 * Certain OpenGL features (e.g. transform feedback, performance monitoring)
35 * require userspace code to submit batches containing commands such as
36 * MI_LOAD_REGISTER_IMM to access various registers. Unfortunately, some
37 * generations of the hardware will noop these commands in "unsecure" batches
38 * (which includes all userspace batches submitted via i915) even though the
39 * commands may be safe and represent the intended programming model of the
40 * device.
41 *
42 * The software command parser is similar in operation to the command parsing
43 * done in hardware for unsecure batches. However, the software parser allows
44 * some operations that would be noop'd by hardware, if the parser determines
45 * the operation is safe, and submits the batch as "secure" to prevent hardware
46 * parsing.
47 *
48 * Threats:
49 * At a high level, the hardware (and software) checks attempt to prevent
50 * granting userspace undue privileges. There are three categories of privilege.
51 *
52 * First, commands which are explicitly defined as privileged or which should
53 * only be used by the kernel driver. The parser generally rejects such
54 * commands, though it may allow some from the drm master process.
55 *
56 * Second, commands which access registers. To support correct/enhanced
57 * userspace functionality, particularly certain OpenGL extensions, the parser
58 * provides a whitelist of registers which userspace may safely access (for both
59 * normal and drm master processes).
60 *
61 * Third, commands which access privileged memory (i.e. GGTT, HWS page, etc).
62 * The parser always rejects such commands.
63 *
64 * The majority of the problematic commands fall in the MI_* range, with only a
65 * few specific commands on each ring (e.g. PIPE_CONTROL and MI_FLUSH_DW).
66 *
67 * Implementation:
68 * Each ring maintains tables of commands and registers which the parser uses in
69 * scanning batch buffers submitted to that ring.
70 *
71 * Since the set of commands that the parser must check for is significantly
72 * smaller than the number of commands supported, the parser tables contain only
73 * those commands required by the parser. This generally works because command
74 * opcode ranges have standard command length encodings. So for commands that
75 * the parser does not need to check, it can easily skip them. This is
76 * implementated via a per-ring length decoding vfunc.
77 *
78 * Unfortunately, there are a number of commands that do not follow the standard
79 * length encoding for their opcode range, primarily amongst the MI_* commands.
80 * To handle this, the parser provides a way to define explicit "skip" entries
81 * in the per-ring command tables.
82 *
83 * Other command table entries map fairly directly to high level categories
84 * mentioned above: rejected, master-only, register whitelist. The parser
85 * implements a number of checks, including the privileged memory checks, via a
86 * general bitmasking mechanism.
87 */
88
89static u32 gen7_render_get_cmd_length_mask(u32 cmd_header)
90{
91 u32 client = (cmd_header & INSTR_CLIENT_MASK) >> INSTR_CLIENT_SHIFT;
92 u32 subclient =
93 (cmd_header & INSTR_SUBCLIENT_MASK) >> INSTR_SUBCLIENT_SHIFT;
94
95 if (client == INSTR_MI_CLIENT)
96 return 0x3F;
97 else if (client == INSTR_RC_CLIENT) {
98 if (subclient == INSTR_MEDIA_SUBCLIENT)
99 return 0xFFFF;
100 else
101 return 0xFF;
102 }
103
104 DRM_DEBUG_DRIVER("CMD: Abnormal rcs cmd length! 0x%08X\n", cmd_header);
105 return 0;
106}
107
108static u32 gen7_bsd_get_cmd_length_mask(u32 cmd_header)
109{
110 u32 client = (cmd_header & INSTR_CLIENT_MASK) >> INSTR_CLIENT_SHIFT;
111 u32 subclient =
112 (cmd_header & INSTR_SUBCLIENT_MASK) >> INSTR_SUBCLIENT_SHIFT;
113
114 if (client == INSTR_MI_CLIENT)
115 return 0x3F;
116 else if (client == INSTR_RC_CLIENT) {
117 if (subclient == INSTR_MEDIA_SUBCLIENT)
118 return 0xFFF;
119 else
120 return 0xFF;
121 }
122
123 DRM_DEBUG_DRIVER("CMD: Abnormal bsd cmd length! 0x%08X\n", cmd_header);
124 return 0;
125}
126
127static u32 gen7_blt_get_cmd_length_mask(u32 cmd_header)
128{
129 u32 client = (cmd_header & INSTR_CLIENT_MASK) >> INSTR_CLIENT_SHIFT;
130
131 if (client == INSTR_MI_CLIENT)
132 return 0x3F;
133 else if (client == INSTR_BC_CLIENT)
134 return 0xFF;
135
136 DRM_DEBUG_DRIVER("CMD: Abnormal blt cmd length! 0x%08X\n", cmd_header);
137 return 0;
138}
139
140static void validate_cmds_sorted(struct intel_ring_buffer *ring)
141{
142 int i;
143
144 if (!ring->cmd_tables || ring->cmd_table_count == 0)
145 return;
146
147 for (i = 0; i < ring->cmd_table_count; i++) {
148 const struct drm_i915_cmd_table *table = &ring->cmd_tables[i];
149 u32 previous = 0;
150 int j;
151
152 for (j = 0; j < table->count; j++) {
153 const struct drm_i915_cmd_descriptor *desc =
154 &table->table[i];
155 u32 curr = desc->cmd.value & desc->cmd.mask;
156
157 if (curr < previous)
158 DRM_ERROR("CMD: table not sorted ring=%d table=%d entry=%d cmd=0x%08X prev=0x%08X\n",
159 ring->id, i, j, curr, previous);
160
161 previous = curr;
162 }
163 }
164}
165
166static void check_sorted(int ring_id, const u32 *reg_table, int reg_count)
167{
168 int i;
169 u32 previous = 0;
170
171 for (i = 0; i < reg_count; i++) {
172 u32 curr = reg_table[i];
173
174 if (curr < previous)
175 DRM_ERROR("CMD: table not sorted ring=%d entry=%d reg=0x%08X prev=0x%08X\n",
176 ring_id, i, curr, previous);
177
178 previous = curr;
179 }
180}
181
182static void validate_regs_sorted(struct intel_ring_buffer *ring)
183{
184 check_sorted(ring->id, ring->reg_table, ring->reg_count);
185 check_sorted(ring->id, ring->master_reg_table, ring->master_reg_count);
186}
187
188/**
189 * i915_cmd_parser_init_ring() - set cmd parser related fields for a ringbuffer
190 * @ring: the ringbuffer to initialize
191 *
192 * Optionally initializes fields related to batch buffer command parsing in the
193 * struct intel_ring_buffer based on whether the platform requires software
194 * command parsing.
195 */
196void i915_cmd_parser_init_ring(struct intel_ring_buffer *ring)
197{
198 if (!IS_GEN7(ring->dev))
199 return;
200
201 switch (ring->id) {
202 case RCS:
203 ring->get_cmd_length_mask = gen7_render_get_cmd_length_mask;
204 break;
205 case VCS:
206 ring->get_cmd_length_mask = gen7_bsd_get_cmd_length_mask;
207 break;
208 case BCS:
209 ring->get_cmd_length_mask = gen7_blt_get_cmd_length_mask;
210 break;
211 case VECS:
212 /* VECS can use the same length_mask function as VCS */
213 ring->get_cmd_length_mask = gen7_bsd_get_cmd_length_mask;
214 break;
215 default:
216 DRM_ERROR("CMD: cmd_parser_init with unknown ring: %d\n",
217 ring->id);
218 BUG();
219 }
220
221 validate_cmds_sorted(ring);
222 validate_regs_sorted(ring);
223}
224
225static const struct drm_i915_cmd_descriptor*
226find_cmd_in_table(const struct drm_i915_cmd_table *table,
227 u32 cmd_header)
228{
229 int i;
230
231 for (i = 0; i < table->count; i++) {
232 const struct drm_i915_cmd_descriptor *desc = &table->table[i];
233 u32 masked_cmd = desc->cmd.mask & cmd_header;
234 u32 masked_value = desc->cmd.value & desc->cmd.mask;
235
236 if (masked_cmd == masked_value)
237 return desc;
238 }
239
240 return NULL;
241}
242
243/*
244 * Returns a pointer to a descriptor for the command specified by cmd_header.
245 *
246 * The caller must supply space for a default descriptor via the default_desc
247 * parameter. If no descriptor for the specified command exists in the ring's
248 * command parser tables, this function fills in default_desc based on the
249 * ring's default length encoding and returns default_desc.
250 */
251static const struct drm_i915_cmd_descriptor*
252find_cmd(struct intel_ring_buffer *ring,
253 u32 cmd_header,
254 struct drm_i915_cmd_descriptor *default_desc)
255{
256 u32 mask;
257 int i;
258
259 for (i = 0; i < ring->cmd_table_count; i++) {
260 const struct drm_i915_cmd_descriptor *desc;
261
262 desc = find_cmd_in_table(&ring->cmd_tables[i], cmd_header);
263 if (desc)
264 return desc;
265 }
266
267 mask = ring->get_cmd_length_mask(cmd_header);
268 if (!mask)
269 return NULL;
270
271 BUG_ON(!default_desc);
272 default_desc->flags = CMD_DESC_SKIP;
273 default_desc->length.mask = mask;
274
275 return default_desc;
276}
277
278static bool valid_reg(const u32 *table, int count, u32 addr)
279{
280 if (table && count != 0) {
281 int i;
282
283 for (i = 0; i < count; i++) {
284 if (table[i] == addr)
285 return true;
286 }
287 }
288
289 return false;
290}
291
292static u32 *vmap_batch(struct drm_i915_gem_object *obj)
293{
294 int i;
295 void *addr = NULL;
296 struct sg_page_iter sg_iter;
297 struct page **pages;
298
299 pages = drm_malloc_ab(obj->base.size >> PAGE_SHIFT, sizeof(*pages));
300 if (pages == NULL) {
301 DRM_DEBUG_DRIVER("Failed to get space for pages\n");
302 goto finish;
303 }
304
305 i = 0;
306 for_each_sg_page(obj->pages->sgl, &sg_iter, obj->pages->nents, 0) {
307 pages[i] = sg_page_iter_page(&sg_iter);
308 i++;
309 }
310
311 addr = vmap(pages, i, 0, PAGE_KERNEL);
312 if (addr == NULL) {
313 DRM_DEBUG_DRIVER("Failed to vmap pages\n");
314 goto finish;
315 }
316
317finish:
318 if (pages)
319 drm_free_large(pages);
320 return (u32*)addr;
321}
322
323/**
324 * i915_needs_cmd_parser() - should a given ring use software command parsing?
325 * @ring: the ring in question
326 *
327 * Only certain platforms require software batch buffer command parsing, and
328 * only when enabled via module paramter.
329 *
330 * Return: true if the ring requires software command parsing
331 */
332bool i915_needs_cmd_parser(struct intel_ring_buffer *ring)
333{
334 /* No command tables indicates a platform without parsing */
335 if (!ring->cmd_tables)
336 return false;
337
338 return (i915.enable_cmd_parser == 1);
339}
340
341#define LENGTH_BIAS 2
342
343/**
344 * i915_parse_cmds() - parse a submitted batch buffer for privilege violations
345 * @ring: the ring on which the batch is to execute
346 * @batch_obj: the batch buffer in question
347 * @batch_start_offset: byte offset in the batch at which execution starts
348 * @is_master: is the submitting process the drm master?
349 *
350 * Parses the specified batch buffer looking for privilege violations as
351 * described in the overview.
352 *
353 * Return: non-zero if the parser finds violations or otherwise fails
354 */
355int i915_parse_cmds(struct intel_ring_buffer *ring,
356 struct drm_i915_gem_object *batch_obj,
357 u32 batch_start_offset,
358 bool is_master)
359{
360 int ret = 0;
361 u32 *cmd, *batch_base, *batch_end;
362 struct drm_i915_cmd_descriptor default_desc = { 0 };
363 int needs_clflush = 0;
364
365 ret = i915_gem_obj_prepare_shmem_read(batch_obj, &needs_clflush);
366 if (ret) {
367 DRM_DEBUG_DRIVER("CMD: failed to prep read\n");
368 return ret;
369 }
370
371 batch_base = vmap_batch(batch_obj);
372 if (!batch_base) {
373 DRM_DEBUG_DRIVER("CMD: Failed to vmap batch\n");
374 i915_gem_object_unpin_pages(batch_obj);
375 return -ENOMEM;
376 }
377
378 if (needs_clflush)
379 drm_clflush_virt_range((char *)batch_base, batch_obj->base.size);
380
381 cmd = batch_base + (batch_start_offset / sizeof(*cmd));
382 batch_end = cmd + (batch_obj->base.size / sizeof(*batch_end));
383
384 while (cmd < batch_end) {
385 const struct drm_i915_cmd_descriptor *desc;
386 u32 length;
387
388 if (*cmd == MI_BATCH_BUFFER_END)
389 break;
390
391 desc = find_cmd(ring, *cmd, &default_desc);
392 if (!desc) {
393 DRM_DEBUG_DRIVER("CMD: Unrecognized command: 0x%08X\n",
394 *cmd);
395 ret = -EINVAL;
396 break;
397 }
398
399 if (desc->flags & CMD_DESC_FIXED)
400 length = desc->length.fixed;
401 else
402 length = ((*cmd & desc->length.mask) + LENGTH_BIAS);
403
404 if ((batch_end - cmd) < length) {
405 DRM_DEBUG_DRIVER("CMD: Command length exceeds batch length: 0x%08X length=%d batchlen=%ld\n",
406 *cmd,
407 length,
408 batch_end - cmd);
409 ret = -EINVAL;
410 break;
411 }
412
413 if (desc->flags & CMD_DESC_REJECT) {
414 DRM_DEBUG_DRIVER("CMD: Rejected command: 0x%08X\n", *cmd);
415 ret = -EINVAL;
416 break;
417 }
418
419 if ((desc->flags & CMD_DESC_MASTER) && !is_master) {
420 DRM_DEBUG_DRIVER("CMD: Rejected master-only command: 0x%08X\n",
421 *cmd);
422 ret = -EINVAL;
423 break;
424 }
425
426 if (desc->flags & CMD_DESC_REGISTER) {
427 u32 reg_addr = cmd[desc->reg.offset] & desc->reg.mask;
428
429 if (!valid_reg(ring->reg_table,
430 ring->reg_count, reg_addr)) {
431 if (!is_master ||
432 !valid_reg(ring->master_reg_table,
433 ring->master_reg_count,
434 reg_addr)) {
435 DRM_DEBUG_DRIVER("CMD: Rejected register 0x%08X in command: 0x%08X (ring=%d)\n",
436 reg_addr,
437 *cmd,
438 ring->id);
439 ret = -EINVAL;
440 break;
441 }
442 }
443 }
444
445 if (desc->flags & CMD_DESC_BITMASK) {
446 int i;
447
448 for (i = 0; i < MAX_CMD_DESC_BITMASKS; i++) {
449 u32 dword;
450
451 if (desc->bits[i].mask == 0)
452 break;
453
454 dword = cmd[desc->bits[i].offset] &
455 desc->bits[i].mask;
456
457 if (dword != desc->bits[i].expected) {
458 DRM_DEBUG_DRIVER("CMD: Rejected command 0x%08X for bitmask 0x%08X (exp=0x%08X act=0x%08X) (ring=%d)\n",
459 *cmd,
460 desc->bits[i].mask,
461 desc->bits[i].expected,
462 dword, ring->id);
463 ret = -EINVAL;
464 break;
465 }
466 }
467
468 if (ret)
469 break;
470 }
471
472 cmd += length;
473 }
474
475 if (cmd >= batch_end) {
476 DRM_DEBUG_DRIVER("CMD: Got to the end of the buffer w/o a BBE cmd!\n");
477 ret = -EINVAL;
478 }
479
480 vunmap(batch_base);
481
482 i915_gem_object_unpin_pages(batch_obj);
483
484 return ret;
485}
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index ef386bf9cecd..7b6dfdfb2d8d 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1849,6 +1849,90 @@ struct drm_i915_file_private {
1849 atomic_t rps_wait_boost; 1849 atomic_t rps_wait_boost;
1850}; 1850};
1851 1851
1852/*
1853 * A command that requires special handling by the command parser.
1854 */
1855struct drm_i915_cmd_descriptor {
1856 /*
1857 * Flags describing how the command parser processes the command.
1858 *
1859 * CMD_DESC_FIXED: The command has a fixed length if this is set,
1860 * a length mask if not set
1861 * CMD_DESC_SKIP: The command is allowed but does not follow the
1862 * standard length encoding for the opcode range in
1863 * which it falls
1864 * CMD_DESC_REJECT: The command is never allowed
1865 * CMD_DESC_REGISTER: The command should be checked against the
1866 * register whitelist for the appropriate ring
1867 * CMD_DESC_MASTER: The command is allowed if the submitting process
1868 * is the DRM master
1869 */
1870 u32 flags;
1871#define CMD_DESC_FIXED (1<<0)
1872#define CMD_DESC_SKIP (1<<1)
1873#define CMD_DESC_REJECT (1<<2)
1874#define CMD_DESC_REGISTER (1<<3)
1875#define CMD_DESC_BITMASK (1<<4)
1876#define CMD_DESC_MASTER (1<<5)
1877
1878 /*
1879 * The command's unique identification bits and the bitmask to get them.
1880 * This isn't strictly the opcode field as defined in the spec and may
1881 * also include type, subtype, and/or subop fields.
1882 */
1883 struct {
1884 u32 value;
1885 u32 mask;
1886 } cmd;
1887
1888 /*
1889 * The command's length. The command is either fixed length (i.e. does
1890 * not include a length field) or has a length field mask. The flag
1891 * CMD_DESC_FIXED indicates a fixed length. Otherwise, the command has
1892 * a length mask. All command entries in a command table must include
1893 * length information.
1894 */
1895 union {
1896 u32 fixed;
1897 u32 mask;
1898 } length;
1899
1900 /*
1901 * Describes where to find a register address in the command to check
1902 * against the ring's register whitelist. Only valid if flags has the
1903 * CMD_DESC_REGISTER bit set.
1904 */
1905 struct {
1906 u32 offset;
1907 u32 mask;
1908 } reg;
1909
1910#define MAX_CMD_DESC_BITMASKS 3
1911 /*
1912 * Describes command checks where a particular dword is masked and
1913 * compared against an expected value. If the command does not match
1914 * the expected value, the parser rejects it. Only valid if flags has
1915 * the CMD_DESC_BITMASK bit set. Only entries where mask is non-zero
1916 * are valid.
1917 */
1918 struct {
1919 u32 offset;
1920 u32 mask;
1921 u32 expected;
1922 } bits[MAX_CMD_DESC_BITMASKS];
1923};
1924
1925/*
1926 * A table of commands requiring special handling by the command parser.
1927 *
1928 * Each ring has an array of tables. Each table consists of an array of command
1929 * descriptors, which must be sorted with command opcodes in ascending order.
1930 */
1931struct drm_i915_cmd_table {
1932 const struct drm_i915_cmd_descriptor *table;
1933 int count;
1934};
1935
1852#define INTEL_INFO(dev) (&to_i915(dev)->info) 1936#define INTEL_INFO(dev) (&to_i915(dev)->info)
1853 1937
1854#define IS_I830(dev) ((dev)->pdev->device == 0x3577) 1938#define IS_I830(dev) ((dev)->pdev->device == 0x3577)
@@ -2003,6 +2087,7 @@ struct i915_params {
2003 int enable_pc8; 2087 int enable_pc8;
2004 int pc8_timeout; 2088 int pc8_timeout;
2005 int invert_brightness; 2089 int invert_brightness;
2090 int enable_cmd_parser;
2006 /* leave bools at the end to not create holes */ 2091 /* leave bools at the end to not create holes */
2007 bool enable_hangcheck; 2092 bool enable_hangcheck;
2008 bool fastboot; 2093 bool fastboot;
@@ -2480,6 +2565,14 @@ void i915_destroy_error_state(struct drm_device *dev);
2480void i915_get_extra_instdone(struct drm_device *dev, uint32_t *instdone); 2565void i915_get_extra_instdone(struct drm_device *dev, uint32_t *instdone);
2481const char *i915_cache_level_str(int type); 2566const char *i915_cache_level_str(int type);
2482 2567
2568/* i915_cmd_parser.c */
2569void i915_cmd_parser_init_ring(struct intel_ring_buffer *ring);
2570bool i915_needs_cmd_parser(struct intel_ring_buffer *ring);
2571int i915_parse_cmds(struct intel_ring_buffer *ring,
2572 struct drm_i915_gem_object *batch_obj,
2573 u32 batch_start_offset,
2574 bool is_master);
2575
2483/* i915_suspend.c */ 2576/* i915_suspend.c */
2484extern int i915_save_state(struct drm_device *dev); 2577extern int i915_save_state(struct drm_device *dev);
2485extern int i915_restore_state(struct drm_device *dev); 2578extern int i915_restore_state(struct drm_device *dev);
diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
index d7229ad2bd22..3851a1b1dc88 100644
--- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c
+++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
@@ -1182,6 +1182,24 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data,
1182 } 1182 }
1183 batch_obj->base.pending_read_domains |= I915_GEM_DOMAIN_COMMAND; 1183 batch_obj->base.pending_read_domains |= I915_GEM_DOMAIN_COMMAND;
1184 1184
1185 if (i915_needs_cmd_parser(ring)) {
1186 ret = i915_parse_cmds(ring,
1187 batch_obj,
1188 args->batch_start_offset,
1189 file->is_master);
1190 if (ret)
1191 goto err;
1192
1193 /*
1194 * XXX: Actually do this when enabling batch copy...
1195 *
1196 * Set the DISPATCH_SECURE bit to remove the NON_SECURE bit
1197 * from MI_BATCH_BUFFER_START commands issued in the
1198 * dispatch_execbuffer implementations. We specifically don't
1199 * want that set when the command parser is enabled.
1200 */
1201 }
1202
1185 /* snb/ivb/vlv conflate the "batch in ppgtt" bit with the "non-secure 1203 /* snb/ivb/vlv conflate the "batch in ppgtt" bit with the "non-secure
1186 * batch" bit. Hence we need to pin secure batches into the global gtt. 1204 * batch" bit. Hence we need to pin secure batches into the global gtt.
1187 * hsw should have this fixed, but bdw mucks it up again. */ 1205 * hsw should have this fixed, but bdw mucks it up again. */
diff --git a/drivers/gpu/drm/i915/i915_params.c b/drivers/gpu/drm/i915/i915_params.c
index 3b482585c5ae..a66ffb652bee 100644
--- a/drivers/gpu/drm/i915/i915_params.c
+++ b/drivers/gpu/drm/i915/i915_params.c
@@ -48,6 +48,7 @@ struct i915_params i915 __read_mostly = {
48 .reset = true, 48 .reset = true,
49 .invert_brightness = 0, 49 .invert_brightness = 0,
50 .disable_display = 0, 50 .disable_display = 0,
51 .enable_cmd_parser = 0,
51}; 52};
52 53
53module_param_named(modeset, i915.modeset, int, 0400); 54module_param_named(modeset, i915.modeset, int, 0400);
@@ -157,3 +158,7 @@ MODULE_PARM_DESC(invert_brightness,
157 158
158module_param_named(disable_display, i915.disable_display, bool, 0600); 159module_param_named(disable_display, i915.disable_display, bool, 0600);
159MODULE_PARM_DESC(disable_display, "Disable display (default: false)"); 160MODULE_PARM_DESC(disable_display, "Disable display (default: false)");
161
162module_param_named(enable_cmd_parser, i915.enable_cmd_parser, int, 0600);
163MODULE_PARM_DESC(enable_cmd_parser,
164 "Enable command parsing (1=enabled, 0=disabled [default])");
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index b719385c4511..146609ab42bb 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -175,6 +175,18 @@
175#define VGA_CR_DATA_CGA 0x3d5 175#define VGA_CR_DATA_CGA 0x3d5
176 176
177/* 177/*
178 * Instruction field definitions used by the command parser
179 */
180#define INSTR_CLIENT_SHIFT 29
181#define INSTR_CLIENT_MASK 0xE0000000
182#define INSTR_MI_CLIENT 0x0
183#define INSTR_BC_CLIENT 0x2
184#define INSTR_RC_CLIENT 0x3
185#define INSTR_SUBCLIENT_SHIFT 27
186#define INSTR_SUBCLIENT_MASK 0x18000000
187#define INSTR_MEDIA_SUBCLIENT 0x2
188
189/*
178 * Memory interface instructions used by the kernel 190 * Memory interface instructions used by the kernel
179 */ 191 */
180#define MI_INSTR(opcode, flags) (((opcode) << 23) | (flags)) 192#define MI_INSTR(opcode, flags) (((opcode) << 23) | (flags))
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c
index b2d4f4852c98..5629cc7a7732 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.c
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.c
@@ -1388,6 +1388,8 @@ static int intel_init_ring_buffer(struct drm_device *dev,
1388 if (IS_I830(ring->dev) || IS_845G(ring->dev)) 1388 if (IS_I830(ring->dev) || IS_845G(ring->dev))
1389 ring->effective_size -= 128; 1389 ring->effective_size -= 128;
1390 1390
1391 i915_cmd_parser_init_ring(ring);
1392
1391 return 0; 1393 return 0;
1392 1394
1393err_unmap: 1395err_unmap:
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h
index 38c757e136dc..9d4c3b1182e9 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.h
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.h
@@ -164,6 +164,38 @@ struct intel_ring_buffer {
164 u32 gtt_offset; 164 u32 gtt_offset;
165 volatile u32 *cpu_page; 165 volatile u32 *cpu_page;
166 } scratch; 166 } scratch;
167
168 /*
169 * Tables of commands the command parser needs to know about
170 * for this ring.
171 */
172 const struct drm_i915_cmd_table *cmd_tables;
173 int cmd_table_count;
174
175 /*
176 * Table of registers allowed in commands that read/write registers.
177 */
178 const u32 *reg_table;
179 int reg_count;
180
181 /*
182 * Table of registers allowed in commands that read/write registers, but
183 * only from the DRM master.
184 */
185 const u32 *master_reg_table;
186 int master_reg_count;
187
188 /*
189 * Returns the bitmask for the length field of the specified command.
190 * Return 0 for an unrecognized/invalid command.
191 *
192 * If the command parser finds an entry for a command in the ring's
193 * cmd_tables, it gets the command's length based on the table entry.
194 * If not, it calls this function to determine the per-ring length field
195 * encoding for the command (i.e. certain opcode ranges use certain bits
196 * to encode the command length in the header).
197 */
198 u32 (*get_cmd_length_mask)(u32 cmd_header);
167}; 199};
168 200
169static inline bool 201static inline bool