@@ -444,6 +444,47 @@ static const struct drm_i915_cmd_descriptor hsw_blt_cmds[] = {
444
444
CMD ( MI_LOAD_SCAN_LINES_EXCL , SMI , !F , 0x3F , R ),
445
445
};
446
446
447
+ /*
448
+ * For Gen9 we can still rely on the h/w to enforce cmd security, and only
449
+ * need to re-enforce the register access checks. We therefore only need to
450
+ * teach the cmdparser how to find the end of each command, and identify
451
+ * register accesses. The table doesn't need to reject any commands, and so
452
+ * the only commands listed here are:
453
+ * 1) Those that touch registers
454
+ * 2) Those that do not have the default 8-bit length
455
+ *
456
+ * Note that the default MI length mask chosen for this table is 0xFF, not
457
+ * the 0x3F used on older devices. This is because the vast majority of MI
458
+ * cmds on Gen9 use a standard 8-bit Length field.
459
+ * All the Gen9 blitter instructions are standard 0xFF length mask, and
460
+ * none allow access to non-general registers, so in fact no BLT cmds are
461
+ * included in the table at all.
462
+ *
463
+ */
464
+ static const struct drm_i915_cmd_descriptor gen9_blt_cmds [] = {
465
+ CMD ( MI_NOOP , SMI , F , 1 , S ),
466
+ CMD ( MI_USER_INTERRUPT , SMI , F , 1 , S ),
467
+ CMD ( MI_WAIT_FOR_EVENT , SMI , F , 1 , S ),
468
+ CMD ( MI_FLUSH , SMI , F , 1 , S ),
469
+ CMD ( MI_ARB_CHECK , SMI , F , 1 , S ),
470
+ CMD ( MI_REPORT_HEAD , SMI , F , 1 , S ),
471
+ CMD ( MI_ARB_ON_OFF , SMI , F , 1 , S ),
472
+ CMD ( MI_SUSPEND_FLUSH , SMI , F , 1 , S ),
473
+ CMD ( MI_LOAD_SCAN_LINES_INCL , SMI , !F , 0x3F , S ),
474
+ CMD ( MI_LOAD_SCAN_LINES_EXCL , SMI , !F , 0x3F , S ),
475
+ CMD ( MI_STORE_DWORD_IMM , SMI , !F , 0x3FF , S ),
476
+ CMD ( MI_LOAD_REGISTER_IMM (1 ), SMI , !F , 0xFF , W ,
477
+ .reg = { .offset = 1 , .mask = 0x007FFFFC , .step = 2 } ),
478
+ CMD ( MI_UPDATE_GTT , SMI , !F , 0x3FF , S ),
479
+ CMD ( MI_STORE_REGISTER_MEM_GEN8 , SMI , F , 4 , W ,
480
+ .reg = { .offset = 1 , .mask = 0x007FFFFC } ),
481
+ CMD ( MI_FLUSH_DW , SMI , !F , 0x3F , S ),
482
+ CMD ( MI_LOAD_REGISTER_MEM_GEN8 , SMI , F , 4 , W ,
483
+ .reg = { .offset = 1 , .mask = 0x007FFFFC } ),
484
+ CMD ( MI_LOAD_REGISTER_REG , SMI , !F , 0xFF , W ,
485
+ .reg = { .offset = 1 , .mask = 0x007FFFFC , .step = 1 } ),
486
+ };
487
+
447
488
static const struct drm_i915_cmd_descriptor noop_desc =
448
489
CMD (MI_NOOP , SMI , F , 1 , S );
449
490
@@ -490,6 +531,11 @@ static const struct drm_i915_cmd_table hsw_blt_ring_cmd_table[] = {
490
531
{ hsw_blt_cmds , ARRAY_SIZE (hsw_blt_cmds ) },
491
532
};
492
533
534
+ static const struct drm_i915_cmd_table gen9_blt_cmd_table [] = {
535
+ { gen9_blt_cmds , ARRAY_SIZE (gen9_blt_cmds ) },
536
+ };
537
+
538
+
493
539
/*
494
540
* Register whitelists, sorted by increasing register offset.
495
541
*/
@@ -605,6 +651,29 @@ static const struct drm_i915_reg_descriptor gen7_blt_regs[] = {
605
651
REG64_IDX (RING_TIMESTAMP , BLT_RING_BASE ),
606
652
};
607
653
654
+ static const struct drm_i915_reg_descriptor gen9_blt_regs [] = {
655
+ REG64_IDX (RING_TIMESTAMP , RENDER_RING_BASE ),
656
+ REG64_IDX (RING_TIMESTAMP , BSD_RING_BASE ),
657
+ REG32 (BCS_SWCTRL ),
658
+ REG64_IDX (RING_TIMESTAMP , BLT_RING_BASE ),
659
+ REG64_IDX (BCS_GPR , 0 ),
660
+ REG64_IDX (BCS_GPR , 1 ),
661
+ REG64_IDX (BCS_GPR , 2 ),
662
+ REG64_IDX (BCS_GPR , 3 ),
663
+ REG64_IDX (BCS_GPR , 4 ),
664
+ REG64_IDX (BCS_GPR , 5 ),
665
+ REG64_IDX (BCS_GPR , 6 ),
666
+ REG64_IDX (BCS_GPR , 7 ),
667
+ REG64_IDX (BCS_GPR , 8 ),
668
+ REG64_IDX (BCS_GPR , 9 ),
669
+ REG64_IDX (BCS_GPR , 10 ),
670
+ REG64_IDX (BCS_GPR , 11 ),
671
+ REG64_IDX (BCS_GPR , 12 ),
672
+ REG64_IDX (BCS_GPR , 13 ),
673
+ REG64_IDX (BCS_GPR , 14 ),
674
+ REG64_IDX (BCS_GPR , 15 ),
675
+ };
676
+
608
677
#undef REG64
609
678
#undef REG32
610
679
@@ -630,6 +699,10 @@ static const struct drm_i915_reg_table hsw_blt_reg_tables[] = {
630
699
{ gen7_blt_regs , ARRAY_SIZE (gen7_blt_regs ) },
631
700
};
632
701
702
+ static const struct drm_i915_reg_table gen9_blt_reg_tables [] = {
703
+ { gen9_blt_regs , ARRAY_SIZE (gen9_blt_regs ) },
704
+ };
705
+
633
706
static u32 gen7_render_get_cmd_length_mask (u32 cmd_header )
634
707
{
635
708
u32 client = cmd_header >> INSTR_CLIENT_SHIFT ;
@@ -685,6 +758,17 @@ static u32 gen7_blt_get_cmd_length_mask(u32 cmd_header)
685
758
return 0 ;
686
759
}
687
760
761
+ static u32 gen9_blt_get_cmd_length_mask (u32 cmd_header )
762
+ {
763
+ u32 client = cmd_header >> INSTR_CLIENT_SHIFT ;
764
+
765
+ if (client == INSTR_MI_CLIENT || client == INSTR_BC_CLIENT )
766
+ return 0xFF ;
767
+
768
+ DRM_DEBUG_DRIVER ("CMD: Abnormal blt cmd length! 0x%08X\n" , cmd_header );
769
+ return 0 ;
770
+ }
771
+
688
772
static bool validate_cmds_sorted (const struct intel_engine_cs * engine ,
689
773
const struct drm_i915_cmd_table * cmd_tables ,
690
774
int cmd_table_count )
@@ -842,7 +926,8 @@ void intel_engine_init_cmd_parser(struct intel_engine_cs *engine)
842
926
int cmd_table_count ;
843
927
int ret ;
844
928
845
- if (!IS_GEN (engine -> i915 , 7 ))
929
+ if (!IS_GEN (engine -> i915 , 7 ) && !(IS_GEN (engine -> i915 , 9 ) &&
930
+ engine -> class == COPY_ENGINE_CLASS ))
846
931
return ;
847
932
848
933
switch (engine -> class ) {
@@ -863,7 +948,6 @@ void intel_engine_init_cmd_parser(struct intel_engine_cs *engine)
863
948
engine -> reg_tables = ivb_render_reg_tables ;
864
949
engine -> reg_table_count = ARRAY_SIZE (ivb_render_reg_tables );
865
950
}
866
-
867
951
engine -> get_cmd_length_mask = gen7_render_get_cmd_length_mask ;
868
952
break ;
869
953
case VIDEO_DECODE_CLASS :
@@ -872,23 +956,34 @@ void intel_engine_init_cmd_parser(struct intel_engine_cs *engine)
872
956
engine -> get_cmd_length_mask = gen7_bsd_get_cmd_length_mask ;
873
957
break ;
874
958
case COPY_ENGINE_CLASS :
875
- if (IS_HASWELL (engine -> i915 )) {
959
+ engine -> get_cmd_length_mask = gen7_blt_get_cmd_length_mask ;
960
+ if (IS_GEN (engine -> i915 , 9 )) {
961
+ cmd_tables = gen9_blt_cmd_table ;
962
+ cmd_table_count = ARRAY_SIZE (gen9_blt_cmd_table );
963
+ engine -> get_cmd_length_mask =
964
+ gen9_blt_get_cmd_length_mask ;
965
+
966
+ /* BCS Engine unsafe without parser */
967
+ engine -> flags |= I915_ENGINE_REQUIRES_CMD_PARSER ;
968
+ } else if (IS_HASWELL (engine -> i915 )) {
876
969
cmd_tables = hsw_blt_ring_cmd_table ;
877
970
cmd_table_count = ARRAY_SIZE (hsw_blt_ring_cmd_table );
878
971
} else {
879
972
cmd_tables = gen7_blt_cmd_table ;
880
973
cmd_table_count = ARRAY_SIZE (gen7_blt_cmd_table );
881
974
}
882
975
883
- if (IS_HASWELL (engine -> i915 )) {
976
+ if (IS_GEN (engine -> i915 , 9 )) {
977
+ engine -> reg_tables = gen9_blt_reg_tables ;
978
+ engine -> reg_table_count =
979
+ ARRAY_SIZE (gen9_blt_reg_tables );
980
+ } else if (IS_HASWELL (engine -> i915 )) {
884
981
engine -> reg_tables = hsw_blt_reg_tables ;
885
982
engine -> reg_table_count = ARRAY_SIZE (hsw_blt_reg_tables );
886
983
} else {
887
984
engine -> reg_tables = ivb_blt_reg_tables ;
888
985
engine -> reg_table_count = ARRAY_SIZE (ivb_blt_reg_tables );
889
986
}
890
-
891
- engine -> get_cmd_length_mask = gen7_blt_get_cmd_length_mask ;
892
987
break ;
893
988
case VIDEO_ENHANCEMENT_CLASS :
894
989
cmd_tables = hsw_vebox_cmd_table ;
@@ -1261,9 +1356,9 @@ int intel_engine_cmd_parser(struct intel_engine_cs *engine,
1261
1356
}
1262
1357
1263
1358
/*
1264
- * If the batch buffer contains a chained batch, return an
1265
- * error that tells the caller to abort and dispatch the
1266
- * workload as a non-secure batch.
1359
+ * We don't try to handle BATCH_BUFFER_START because it adds
1360
+ * non-trivial complexity. Instead we abort the scan and return
1361
+ * and error to indicate that the batch is unsafe .
1267
1362
*/
1268
1363
if (desc -> cmd .value == MI_BATCH_BUFFER_START ) {
1269
1364
ret = - EACCES ;
@@ -1342,6 +1437,7 @@ int i915_cmd_parser_get_version(struct drm_i915_private *dev_priv)
1342
1437
* the parser enabled.
1343
1438
* 9. Don't whitelist or handle oacontrol specially, as ownership
1344
1439
* for oacontrol state is moving to i915-perf.
1440
+ * 10. Support for Gen9 BCS Parsing
1345
1441
*/
1346
- return 9 ;
1442
+ return 10 ;
1347
1443
}
0 commit comments