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 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 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 317 finish: 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 */ 332 bool 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 */ 355 int 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=%td\n", 406 *cmd, 407 length, 408 (unsigned long)(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 } 486