Home | History | Annotate | Line # | Download | only in i915
i915_cmd_parser.c revision 1.2
      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 (at) 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 
     89 static 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 
    108 static 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 
    127 static 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 
    140 static 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 
    166 static 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 
    182 static 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  */
    196 void 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 
    225 static const struct drm_i915_cmd_descriptor*
    226 find_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  */
    251 static const struct drm_i915_cmd_descriptor*
    252 find_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 
    278 static 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 
    292 static u32 *vmap_batch(struct drm_i915_gem_object *obj)
    293 {
    294 	int i;
    295 	void *addr = NULL;
    296 #ifdef __NetBSD__
    297 	struct vm_page *page;
    298 #else
    299 	struct sg_page_iter sg_iter;
    300 #endif
    301 	struct page **pages;
    302 
    303 	pages = drm_malloc_ab(obj->base.size >> PAGE_SHIFT, sizeof(*pages));
    304 	if (pages == NULL) {
    305 		DRM_DEBUG_DRIVER("Failed to get space for pages\n");
    306 		goto finish;
    307 	}
    308 
    309 	i = 0;
    310 #ifdef __NetBSD__
    311 	TAILQ_FOREACH(page, &obj->igo_pageq, pageq.queue) {
    312 		pages[i] = container_of(page, struct page, p_vmp);
    313 		i++;
    314 	}
    315 #else
    316 	for_each_sg_page(obj->pages->sgl, &sg_iter, obj->pages->nents, 0) {
    317 		pages[i] = sg_page_iter_page(&sg_iter);
    318 		i++;
    319 	}
    320 #endif
    321 
    322 	addr = vmap(pages, i, 0, PAGE_KERNEL);
    323 	if (addr == NULL) {
    324 		DRM_DEBUG_DRIVER("Failed to vmap pages\n");
    325 		goto finish;
    326 	}
    327 
    328 finish:
    329 	if (pages)
    330 		drm_free_large(pages);
    331 	return (u32*)addr;
    332 }
    333 
    334 /**
    335  * i915_needs_cmd_parser() - should a given ring use software command parsing?
    336  * @ring: the ring in question
    337  *
    338  * Only certain platforms require software batch buffer command parsing, and
    339  * only when enabled via module paramter.
    340  *
    341  * Return: true if the ring requires software command parsing
    342  */
    343 bool i915_needs_cmd_parser(struct intel_ring_buffer *ring)
    344 {
    345 	/* No command tables indicates a platform without parsing */
    346 	if (!ring->cmd_tables)
    347 		return false;
    348 
    349 	return (i915.enable_cmd_parser == 1);
    350 }
    351 
    352 #define LENGTH_BIAS 2
    353 
    354 /**
    355  * i915_parse_cmds() - parse a submitted batch buffer for privilege violations
    356  * @ring: the ring on which the batch is to execute
    357  * @batch_obj: the batch buffer in question
    358  * @batch_start_offset: byte offset in the batch at which execution starts
    359  * @is_master: is the submitting process the drm master?
    360  *
    361  * Parses the specified batch buffer looking for privilege violations as
    362  * described in the overview.
    363  *
    364  * Return: non-zero if the parser finds violations or otherwise fails
    365  */
    366 int i915_parse_cmds(struct intel_ring_buffer *ring,
    367 		    struct drm_i915_gem_object *batch_obj,
    368 		    u32 batch_start_offset,
    369 		    bool is_master)
    370 {
    371 	int ret = 0;
    372 	u32 *cmd, *batch_base, *batch_end;
    373 	struct drm_i915_cmd_descriptor default_desc = { 0 };
    374 	int needs_clflush = 0;
    375 
    376 	ret = i915_gem_obj_prepare_shmem_read(batch_obj, &needs_clflush);
    377 	if (ret) {
    378 		DRM_DEBUG_DRIVER("CMD: failed to prep read\n");
    379 		return ret;
    380 	}
    381 
    382 	batch_base = vmap_batch(batch_obj);
    383 	if (!batch_base) {
    384 		DRM_DEBUG_DRIVER("CMD: Failed to vmap batch\n");
    385 		i915_gem_object_unpin_pages(batch_obj);
    386 		return -ENOMEM;
    387 	}
    388 
    389 	if (needs_clflush)
    390 		drm_clflush_virt_range((char *)batch_base, batch_obj->base.size);
    391 
    392 	cmd = batch_base + (batch_start_offset / sizeof(*cmd));
    393 	batch_end = cmd + (batch_obj->base.size / sizeof(*batch_end));
    394 
    395 	while (cmd < batch_end) {
    396 		const struct drm_i915_cmd_descriptor *desc;
    397 		u32 length;
    398 
    399 		if (*cmd == MI_BATCH_BUFFER_END)
    400 			break;
    401 
    402 		desc = find_cmd(ring, *cmd, &default_desc);
    403 		if (!desc) {
    404 			DRM_DEBUG_DRIVER("CMD: Unrecognized command: 0x%08X\n",
    405 					 *cmd);
    406 			ret = -EINVAL;
    407 			break;
    408 		}
    409 
    410 		if (desc->flags & CMD_DESC_FIXED)
    411 			length = desc->length.fixed;
    412 		else
    413 			length = ((*cmd & desc->length.mask) + LENGTH_BIAS);
    414 
    415 		if ((batch_end - cmd) < length) {
    416 			DRM_DEBUG_DRIVER("CMD: Command length exceeds batch length: 0x%08X length=%d batchlen=%td\n",
    417 					 *cmd,
    418 					 length,
    419 					 (unsigned long)(batch_end - cmd));
    420 			ret = -EINVAL;
    421 			break;
    422 		}
    423 
    424 		if (desc->flags & CMD_DESC_REJECT) {
    425 			DRM_DEBUG_DRIVER("CMD: Rejected command: 0x%08X\n", *cmd);
    426 			ret = -EINVAL;
    427 			break;
    428 		}
    429 
    430 		if ((desc->flags & CMD_DESC_MASTER) && !is_master) {
    431 			DRM_DEBUG_DRIVER("CMD: Rejected master-only command: 0x%08X\n",
    432 					 *cmd);
    433 			ret = -EINVAL;
    434 			break;
    435 		}
    436 
    437 		if (desc->flags & CMD_DESC_REGISTER) {
    438 			u32 reg_addr = cmd[desc->reg.offset] & desc->reg.mask;
    439 
    440 			if (!valid_reg(ring->reg_table,
    441 				       ring->reg_count, reg_addr)) {
    442 				if (!is_master ||
    443 				    !valid_reg(ring->master_reg_table,
    444 					       ring->master_reg_count,
    445 					       reg_addr)) {
    446 					DRM_DEBUG_DRIVER("CMD: Rejected register 0x%08X in command: 0x%08X (ring=%d)\n",
    447 							 reg_addr,
    448 							 *cmd,
    449 							 ring->id);
    450 					ret = -EINVAL;
    451 					break;
    452 				}
    453 			}
    454 		}
    455 
    456 		if (desc->flags & CMD_DESC_BITMASK) {
    457 			int i;
    458 
    459 			for (i = 0; i < MAX_CMD_DESC_BITMASKS; i++) {
    460 				u32 dword;
    461 
    462 				if (desc->bits[i].mask == 0)
    463 					break;
    464 
    465 				dword = cmd[desc->bits[i].offset] &
    466 					desc->bits[i].mask;
    467 
    468 				if (dword != desc->bits[i].expected) {
    469 					DRM_DEBUG_DRIVER("CMD: Rejected command 0x%08X for bitmask 0x%08X (exp=0x%08X act=0x%08X) (ring=%d)\n",
    470 							 *cmd,
    471 							 desc->bits[i].mask,
    472 							 desc->bits[i].expected,
    473 							 dword, ring->id);
    474 					ret = -EINVAL;
    475 					break;
    476 				}
    477 			}
    478 
    479 			if (ret)
    480 				break;
    481 		}
    482 
    483 		cmd += length;
    484 	}
    485 
    486 	if (cmd >= batch_end) {
    487 		DRM_DEBUG_DRIVER("CMD: Got to the end of the buffer w/o a BBE cmd!\n");
    488 		ret = -EINVAL;
    489 	}
    490 
    491 #ifdef __NetBSD__
    492 	vunmap(batch_base, batch_obj->base.size / PAGE_SIZE);
    493 #else
    494 	vunmap(batch_base);
    495 #endif
    496 
    497 	i915_gem_object_unpin_pages(batch_obj);
    498 
    499 	return ret;
    500 }
    501