aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915/i915_cmd_parser.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/i915/i915_cmd_parser.c')
-rw-r--r--drivers/gpu/drm/i915/i915_cmd_parser.c209
1 files changed, 135 insertions, 74 deletions
diff --git a/drivers/gpu/drm/i915/i915_cmd_parser.c b/drivers/gpu/drm/i915/i915_cmd_parser.c
index 61ae8ff4eaed..306d9e4e5cf3 100644
--- a/drivers/gpu/drm/i915/i915_cmd_parser.c
+++ b/drivers/gpu/drm/i915/i915_cmd_parser.c
@@ -123,7 +123,7 @@ static const struct drm_i915_cmd_descriptor common_cmds[] = {
123 CMD( MI_SEMAPHORE_MBOX, SMI, !F, 0xFF, R ), 123 CMD( MI_SEMAPHORE_MBOX, SMI, !F, 0xFF, R ),
124 CMD( MI_STORE_DWORD_INDEX, SMI, !F, 0xFF, R ), 124 CMD( MI_STORE_DWORD_INDEX, SMI, !F, 0xFF, R ),
125 CMD( MI_LOAD_REGISTER_IMM(1), SMI, !F, 0xFF, W, 125 CMD( MI_LOAD_REGISTER_IMM(1), SMI, !F, 0xFF, W,
126 .reg = { .offset = 1, .mask = 0x007FFFFC } ), 126 .reg = { .offset = 1, .mask = 0x007FFFFC, .step = 2 } ),
127 CMD( MI_STORE_REGISTER_MEM(1), SMI, !F, 0xFF, W | B, 127 CMD( MI_STORE_REGISTER_MEM(1), SMI, !F, 0xFF, W | B,
128 .reg = { .offset = 1, .mask = 0x007FFFFC }, 128 .reg = { .offset = 1, .mask = 0x007FFFFC },
129 .bits = {{ 129 .bits = {{
@@ -395,16 +395,38 @@ static const struct drm_i915_cmd_table hsw_blt_ring_cmds[] = {
395 395
396/* 396/*
397 * Register whitelists, sorted by increasing register offset. 397 * Register whitelists, sorted by increasing register offset.
398 */
399
400/*
401 * An individual whitelist entry granting access to register addr. If
402 * mask is non-zero the argument of immediate register writes will be
403 * AND-ed with mask, and the command will be rejected if the result
404 * doesn't match value.
405 *
406 * Registers with non-zero mask are only allowed to be written using
407 * LRI.
408 */
409struct drm_i915_reg_descriptor {
410 u32 addr;
411 u32 mask;
412 u32 value;
413};
414
415/* Convenience macro for adding 32-bit registers. */
416#define REG32(address, ...) \
417 { .addr = address, __VA_ARGS__ }
418
419/*
420 * Convenience macro for adding 64-bit registers.
398 * 421 *
399 * Some registers that userspace accesses are 64 bits. The register 422 * Some registers that userspace accesses are 64 bits. The register
400 * access commands only allow 32-bit accesses. Hence, we have to include 423 * access commands only allow 32-bit accesses. Hence, we have to include
401 * entries for both halves of the 64-bit registers. 424 * entries for both halves of the 64-bit registers.
402 */ 425 */
426#define REG64(addr) \
427 REG32(addr), REG32(addr + sizeof(u32))
403 428
404/* Convenience macro for adding 64-bit registers */ 429static const struct drm_i915_reg_descriptor gen7_render_regs[] = {
405#define REG64(addr) (addr), (addr + sizeof(u32))
406
407static const u32 gen7_render_regs[] = {
408 REG64(GPGPU_THREADS_DISPATCHED), 430 REG64(GPGPU_THREADS_DISPATCHED),
409 REG64(HS_INVOCATION_COUNT), 431 REG64(HS_INVOCATION_COUNT),
410 REG64(DS_INVOCATION_COUNT), 432 REG64(DS_INVOCATION_COUNT),
@@ -417,15 +439,15 @@ static const u32 gen7_render_regs[] = {
417 REG64(CL_PRIMITIVES_COUNT), 439 REG64(CL_PRIMITIVES_COUNT),
418 REG64(PS_INVOCATION_COUNT), 440 REG64(PS_INVOCATION_COUNT),
419 REG64(PS_DEPTH_COUNT), 441 REG64(PS_DEPTH_COUNT),
420 OACONTROL, /* Only allowed for LRI and SRM. See below. */ 442 REG32(OACONTROL), /* Only allowed for LRI and SRM. See below. */
421 REG64(MI_PREDICATE_SRC0), 443 REG64(MI_PREDICATE_SRC0),
422 REG64(MI_PREDICATE_SRC1), 444 REG64(MI_PREDICATE_SRC1),
423 GEN7_3DPRIM_END_OFFSET, 445 REG32(GEN7_3DPRIM_END_OFFSET),
424 GEN7_3DPRIM_START_VERTEX, 446 REG32(GEN7_3DPRIM_START_VERTEX),
425 GEN7_3DPRIM_VERTEX_COUNT, 447 REG32(GEN7_3DPRIM_VERTEX_COUNT),
426 GEN7_3DPRIM_INSTANCE_COUNT, 448 REG32(GEN7_3DPRIM_INSTANCE_COUNT),
427 GEN7_3DPRIM_START_INSTANCE, 449 REG32(GEN7_3DPRIM_START_INSTANCE),
428 GEN7_3DPRIM_BASE_VERTEX, 450 REG32(GEN7_3DPRIM_BASE_VERTEX),
429 REG64(GEN7_SO_NUM_PRIMS_WRITTEN(0)), 451 REG64(GEN7_SO_NUM_PRIMS_WRITTEN(0)),
430 REG64(GEN7_SO_NUM_PRIMS_WRITTEN(1)), 452 REG64(GEN7_SO_NUM_PRIMS_WRITTEN(1)),
431 REG64(GEN7_SO_NUM_PRIMS_WRITTEN(2)), 453 REG64(GEN7_SO_NUM_PRIMS_WRITTEN(2)),
@@ -434,33 +456,41 @@ static const u32 gen7_render_regs[] = {
434 REG64(GEN7_SO_PRIM_STORAGE_NEEDED(1)), 456 REG64(GEN7_SO_PRIM_STORAGE_NEEDED(1)),
435 REG64(GEN7_SO_PRIM_STORAGE_NEEDED(2)), 457 REG64(GEN7_SO_PRIM_STORAGE_NEEDED(2)),
436 REG64(GEN7_SO_PRIM_STORAGE_NEEDED(3)), 458 REG64(GEN7_SO_PRIM_STORAGE_NEEDED(3)),
437 GEN7_SO_WRITE_OFFSET(0), 459 REG32(GEN7_SO_WRITE_OFFSET(0)),
438 GEN7_SO_WRITE_OFFSET(1), 460 REG32(GEN7_SO_WRITE_OFFSET(1)),
439 GEN7_SO_WRITE_OFFSET(2), 461 REG32(GEN7_SO_WRITE_OFFSET(2)),
440 GEN7_SO_WRITE_OFFSET(3), 462 REG32(GEN7_SO_WRITE_OFFSET(3)),
441 GEN7_L3SQCREG1, 463 REG32(GEN7_L3SQCREG1),
442 GEN7_L3CNTLREG2, 464 REG32(GEN7_L3CNTLREG2),
443 GEN7_L3CNTLREG3, 465 REG32(GEN7_L3CNTLREG3),
466 REG32(HSW_SCRATCH1,
467 .mask = ~HSW_SCRATCH1_L3_DATA_ATOMICS_DISABLE,
468 .value = 0),
469 REG32(HSW_ROW_CHICKEN3,
470 .mask = ~(HSW_ROW_CHICKEN3_L3_GLOBAL_ATOMICS_DISABLE << 16 |
471 HSW_ROW_CHICKEN3_L3_GLOBAL_ATOMICS_DISABLE),
472 .value = 0),
444}; 473};
445 474
446static const u32 gen7_blt_regs[] = { 475static const struct drm_i915_reg_descriptor gen7_blt_regs[] = {
447 BCS_SWCTRL, 476 REG32(BCS_SWCTRL),
448}; 477};
449 478
450static const u32 ivb_master_regs[] = { 479static const struct drm_i915_reg_descriptor ivb_master_regs[] = {
451 FORCEWAKE_MT, 480 REG32(FORCEWAKE_MT),
452 DERRMR, 481 REG32(DERRMR),
453 GEN7_PIPE_DE_LOAD_SL(PIPE_A), 482 REG32(GEN7_PIPE_DE_LOAD_SL(PIPE_A)),
454 GEN7_PIPE_DE_LOAD_SL(PIPE_B), 483 REG32(GEN7_PIPE_DE_LOAD_SL(PIPE_B)),
455 GEN7_PIPE_DE_LOAD_SL(PIPE_C), 484 REG32(GEN7_PIPE_DE_LOAD_SL(PIPE_C)),
456}; 485};
457 486
458static const u32 hsw_master_regs[] = { 487static const struct drm_i915_reg_descriptor hsw_master_regs[] = {
459 FORCEWAKE_MT, 488 REG32(FORCEWAKE_MT),
460 DERRMR, 489 REG32(DERRMR),
461}; 490};
462 491
463#undef REG64 492#undef REG64
493#undef REG32
464 494
465static u32 gen7_render_get_cmd_length_mask(u32 cmd_header) 495static u32 gen7_render_get_cmd_length_mask(u32 cmd_header)
466{ 496{
@@ -550,14 +580,16 @@ static bool validate_cmds_sorted(struct intel_engine_cs *ring,
550 return ret; 580 return ret;
551} 581}
552 582
553static bool check_sorted(int ring_id, const u32 *reg_table, int reg_count) 583static bool check_sorted(int ring_id,
584 const struct drm_i915_reg_descriptor *reg_table,
585 int reg_count)
554{ 586{
555 int i; 587 int i;
556 u32 previous = 0; 588 u32 previous = 0;
557 bool ret = true; 589 bool ret = true;
558 590
559 for (i = 0; i < reg_count; i++) { 591 for (i = 0; i < reg_count; i++) {
560 u32 curr = reg_table[i]; 592 u32 curr = reg_table[i].addr;
561 593
562 if (curr < previous) { 594 if (curr < previous) {
563 DRM_ERROR("CMD: table not sorted ring=%d entry=%d reg=0x%08X prev=0x%08X\n", 595 DRM_ERROR("CMD: table not sorted ring=%d entry=%d reg=0x%08X prev=0x%08X\n",
@@ -804,18 +836,20 @@ find_cmd(struct intel_engine_cs *ring,
804 return default_desc; 836 return default_desc;
805} 837}
806 838
807static bool valid_reg(const u32 *table, int count, u32 addr) 839static const struct drm_i915_reg_descriptor *
840find_reg(const struct drm_i915_reg_descriptor *table,
841 int count, u32 addr)
808{ 842{
809 if (table && count != 0) { 843 if (table) {
810 int i; 844 int i;
811 845
812 for (i = 0; i < count; i++) { 846 for (i = 0; i < count; i++) {
813 if (table[i] == addr) 847 if (table[i].addr == addr)
814 return true; 848 return &table[i];
815 } 849 }
816 } 850 }
817 851
818 return false; 852 return NULL;
819} 853}
820 854
821static u32 *vmap_batch(struct drm_i915_gem_object *obj, 855static u32 *vmap_batch(struct drm_i915_gem_object *obj,
@@ -869,6 +903,9 @@ static u32 *copy_batch(struct drm_i915_gem_object *dest_obj,
869 batch_len + batch_start_offset > src_obj->base.size) 903 batch_len + batch_start_offset > src_obj->base.size)
870 return ERR_PTR(-E2BIG); 904 return ERR_PTR(-E2BIG);
871 905
906 if (WARN_ON(dest_obj->pages_pin_count == 0))
907 return ERR_PTR(-ENODEV);
908
872 ret = i915_gem_obj_prepare_shmem_read(src_obj, &needs_clflush); 909 ret = i915_gem_obj_prepare_shmem_read(src_obj, &needs_clflush);
873 if (ret) { 910 if (ret) {
874 DRM_DEBUG_DRIVER("CMD: failed to prepare shadow batch\n"); 911 DRM_DEBUG_DRIVER("CMD: failed to prepare shadow batch\n");
@@ -882,13 +919,6 @@ static u32 *copy_batch(struct drm_i915_gem_object *dest_obj,
882 goto unpin_src; 919 goto unpin_src;
883 } 920 }
884 921
885 ret = i915_gem_object_get_pages(dest_obj);
886 if (ret) {
887 DRM_DEBUG_DRIVER("CMD: Failed to get pages for shadow batch\n");
888 goto unmap_src;
889 }
890 i915_gem_object_pin_pages(dest_obj);
891
892 ret = i915_gem_object_set_to_cpu_domain(dest_obj, true); 922 ret = i915_gem_object_set_to_cpu_domain(dest_obj, true);
893 if (ret) { 923 if (ret) {
894 DRM_DEBUG_DRIVER("CMD: Failed to set shadow batch to CPU\n"); 924 DRM_DEBUG_DRIVER("CMD: Failed to set shadow batch to CPU\n");
@@ -898,7 +928,6 @@ static u32 *copy_batch(struct drm_i915_gem_object *dest_obj,
898 dst = vmap_batch(dest_obj, 0, batch_len); 928 dst = vmap_batch(dest_obj, 0, batch_len);
899 if (!dst) { 929 if (!dst) {
900 DRM_DEBUG_DRIVER("CMD: Failed to vmap shadow batch\n"); 930 DRM_DEBUG_DRIVER("CMD: Failed to vmap shadow batch\n");
901 i915_gem_object_unpin_pages(dest_obj);
902 ret = -ENOMEM; 931 ret = -ENOMEM;
903 goto unmap_src; 932 goto unmap_src;
904 } 933 }
@@ -939,7 +968,7 @@ bool i915_needs_cmd_parser(struct intel_engine_cs *ring)
939 968
940static bool check_cmd(const struct intel_engine_cs *ring, 969static bool check_cmd(const struct intel_engine_cs *ring,
941 const struct drm_i915_cmd_descriptor *desc, 970 const struct drm_i915_cmd_descriptor *desc,
942 const u32 *cmd, 971 const u32 *cmd, u32 length,
943 const bool is_master, 972 const bool is_master,
944 bool *oacontrol_set) 973 bool *oacontrol_set)
945{ 974{
@@ -955,38 +984,70 @@ static bool check_cmd(const struct intel_engine_cs *ring,
955 } 984 }
956 985
957 if (desc->flags & CMD_DESC_REGISTER) { 986 if (desc->flags & CMD_DESC_REGISTER) {
958 u32 reg_addr = cmd[desc->reg.offset] & desc->reg.mask;
959
960 /* 987 /*
961 * OACONTROL requires some special handling for writes. We 988 * Get the distance between individual register offset
962 * want to make sure that any batch which enables OA also 989 * fields if the command can perform more than one
963 * disables it before the end of the batch. The goal is to 990 * access at a time.
964 * prevent one process from snooping on the perf data from
965 * another process. To do that, we need to check the value
966 * that will be written to the register. Hence, limit
967 * OACONTROL writes to only MI_LOAD_REGISTER_IMM commands.
968 */ 991 */
969 if (reg_addr == OACONTROL) { 992 const u32 step = desc->reg.step ? desc->reg.step : length;
970 if (desc->cmd.value == MI_LOAD_REGISTER_MEM) { 993 u32 offset;
971 DRM_DEBUG_DRIVER("CMD: Rejected LRM to OACONTROL\n"); 994
995 for (offset = desc->reg.offset; offset < length;
996 offset += step) {
997 const u32 reg_addr = cmd[offset] & desc->reg.mask;
998 const struct drm_i915_reg_descriptor *reg =
999 find_reg(ring->reg_table, ring->reg_count,
1000 reg_addr);
1001
1002 if (!reg && is_master)
1003 reg = find_reg(ring->master_reg_table,
1004 ring->master_reg_count,
1005 reg_addr);
1006
1007 if (!reg) {
1008 DRM_DEBUG_DRIVER("CMD: Rejected register 0x%08X in command: 0x%08X (ring=%d)\n",
1009 reg_addr, *cmd, ring->id);
972 return false; 1010 return false;
973 } 1011 }
974 1012
975 if (desc->cmd.value == MI_LOAD_REGISTER_IMM(1)) 1013 /*
976 *oacontrol_set = (cmd[2] != 0); 1014 * OACONTROL requires some special handling for
977 } 1015 * writes. We want to make sure that any batch which
1016 * enables OA also disables it before the end of the
1017 * batch. The goal is to prevent one process from
1018 * snooping on the perf data from another process. To do
1019 * that, we need to check the value that will be written
1020 * to the register. Hence, limit OACONTROL writes to
1021 * only MI_LOAD_REGISTER_IMM commands.
1022 */
1023 if (reg_addr == OACONTROL) {
1024 if (desc->cmd.value == MI_LOAD_REGISTER_MEM) {
1025 DRM_DEBUG_DRIVER("CMD: Rejected LRM to OACONTROL\n");
1026 return false;
1027 }
1028
1029 if (desc->cmd.value == MI_LOAD_REGISTER_IMM(1))
1030 *oacontrol_set = (cmd[offset + 1] != 0);
1031 }
978 1032
979 if (!valid_reg(ring->reg_table, 1033 /*
980 ring->reg_count, reg_addr)) { 1034 * Check the value written to the register against the
981 if (!is_master || 1035 * allowed mask/value pair given in the whitelist entry.
982 !valid_reg(ring->master_reg_table, 1036 */
983 ring->master_reg_count, 1037 if (reg->mask) {
984 reg_addr)) { 1038 if (desc->cmd.value == MI_LOAD_REGISTER_MEM) {
985 DRM_DEBUG_DRIVER("CMD: Rejected register 0x%08X in command: 0x%08X (ring=%d)\n", 1039 DRM_DEBUG_DRIVER("CMD: Rejected LRM to masked register 0x%08X\n",
986 reg_addr, 1040 reg_addr);
987 *cmd, 1041 return false;
988 ring->id); 1042 }
989 return false; 1043
1044 if (desc->cmd.value == MI_LOAD_REGISTER_IMM(1) &&
1045 (offset + 2 > length ||
1046 (cmd[offset + 1] & reg->mask) != reg->value)) {
1047 DRM_DEBUG_DRIVER("CMD: Rejected LRI to masked register 0x%08X\n",
1048 reg_addr);
1049 return false;
1050 }
990 } 1051 }
991 } 1052 }
992 } 1053 }
@@ -1110,7 +1171,8 @@ int i915_parse_cmds(struct intel_engine_cs *ring,
1110 break; 1171 break;
1111 } 1172 }
1112 1173
1113 if (!check_cmd(ring, desc, cmd, is_master, &oacontrol_set)) { 1174 if (!check_cmd(ring, desc, cmd, length, is_master,
1175 &oacontrol_set)) {
1114 ret = -EINVAL; 1176 ret = -EINVAL;
1115 break; 1177 break;
1116 } 1178 }
@@ -1129,7 +1191,6 @@ int i915_parse_cmds(struct intel_engine_cs *ring,
1129 } 1191 }
1130 1192
1131 vunmap(batch_base); 1193 vunmap(batch_base);
1132 i915_gem_object_unpin_pages(shadow_batch_obj);
1133 1194
1134 return ret; 1195 return ret;
1135} 1196}