@@ -58,22 +58,18 @@ static void set_context_pdp_root_pointer(
58
58
59
59
static void update_shadow_pdps (struct intel_vgpu_workload * workload )
60
60
{
61
- struct drm_i915_gem_object * ctx_obj =
62
- workload -> req -> context -> state -> obj ;
63
61
struct execlist_ring_context * shadow_ring_context ;
64
- struct page * page ;
62
+ struct intel_context * ctx = workload -> req -> context ;
65
63
66
64
if (WARN_ON (!workload -> shadow_mm ))
67
65
return ;
68
66
69
67
if (WARN_ON (!atomic_read (& workload -> shadow_mm -> pincount )))
70
68
return ;
71
69
72
- page = i915_gem_object_get_page (ctx_obj , LRC_STATE_PN );
73
- shadow_ring_context = kmap (page );
70
+ shadow_ring_context = (struct execlist_ring_context * )ctx -> lrc_reg_state ;
74
71
set_context_pdp_root_pointer (shadow_ring_context ,
75
72
(void * )workload -> shadow_mm -> ppgtt_mm .shadow_pdps );
76
- kunmap (page );
77
73
}
78
74
79
75
/*
@@ -646,10 +642,11 @@ static void release_shadow_batch_buffer(struct intel_vgpu_workload *workload)
646
642
}
647
643
}
648
644
649
- static int prepare_workload (struct intel_vgpu_workload * workload )
645
+ static int
646
+ intel_vgpu_shadow_mm_pin (struct intel_vgpu_workload * workload )
650
647
{
651
648
struct intel_vgpu * vgpu = workload -> vgpu ;
652
- struct intel_vgpu_submission * s = & vgpu -> submission ;
649
+ struct intel_vgpu_mm * m ;
653
650
int ret = 0 ;
654
651
655
652
ret = intel_vgpu_pin_mm (workload -> shadow_mm );
@@ -664,6 +661,52 @@ static int prepare_workload(struct intel_vgpu_workload *workload)
664
661
return - EINVAL ;
665
662
}
666
663
664
+ if (!list_empty (& workload -> lri_shadow_mm )) {
665
+ list_for_each_entry (m , & workload -> lri_shadow_mm ,
666
+ ppgtt_mm .link ) {
667
+ ret = intel_vgpu_pin_mm (m );
668
+ if (ret ) {
669
+ list_for_each_entry_from_reverse (m ,
670
+ & workload -> lri_shadow_mm ,
671
+ ppgtt_mm .link )
672
+ intel_vgpu_unpin_mm (m );
673
+ gvt_vgpu_err ("LRI shadow ppgtt fail to pin\n" );
674
+ break ;
675
+ }
676
+ }
677
+ }
678
+
679
+ if (ret )
680
+ intel_vgpu_unpin_mm (workload -> shadow_mm );
681
+
682
+ return ret ;
683
+ }
684
+
685
+ static void
686
+ intel_vgpu_shadow_mm_unpin (struct intel_vgpu_workload * workload )
687
+ {
688
+ struct intel_vgpu_mm * m ;
689
+
690
+ if (!list_empty (& workload -> lri_shadow_mm )) {
691
+ list_for_each_entry (m , & workload -> lri_shadow_mm ,
692
+ ppgtt_mm .link )
693
+ intel_vgpu_unpin_mm (m );
694
+ }
695
+ intel_vgpu_unpin_mm (workload -> shadow_mm );
696
+ }
697
+
698
+ static int prepare_workload (struct intel_vgpu_workload * workload )
699
+ {
700
+ struct intel_vgpu * vgpu = workload -> vgpu ;
701
+ struct intel_vgpu_submission * s = & vgpu -> submission ;
702
+ int ret = 0 ;
703
+
704
+ ret = intel_vgpu_shadow_mm_pin (workload );
705
+ if (ret ) {
706
+ gvt_vgpu_err ("fail to pin shadow mm\n" );
707
+ return ret ;
708
+ }
709
+
667
710
update_shadow_pdps (workload );
668
711
669
712
set_context_ppgtt_from_shadow (workload , s -> shadow [workload -> engine -> id ]);
@@ -710,7 +753,7 @@ static int prepare_workload(struct intel_vgpu_workload *workload)
710
753
err_shadow_batch :
711
754
release_shadow_batch_buffer (workload );
712
755
err_unpin_mm :
713
- intel_vgpu_unpin_mm (workload -> shadow_mm );
756
+ intel_vgpu_shadow_mm_unpin (workload );
714
757
return ret ;
715
758
}
716
759
@@ -820,6 +863,37 @@ pick_next_workload(struct intel_gvt *gvt, struct intel_engine_cs *engine)
820
863
return workload ;
821
864
}
822
865
866
+ static void update_guest_pdps (struct intel_vgpu * vgpu ,
867
+ u64 ring_context_gpa , u32 pdp [8 ])
868
+ {
869
+ u64 gpa ;
870
+ int i ;
871
+
872
+ gpa = ring_context_gpa + RING_CTX_OFF (pdps [0 ].val );
873
+
874
+ for (i = 0 ; i < 8 ; i ++ )
875
+ intel_gvt_hypervisor_write_gpa (vgpu ,
876
+ gpa + i * 8 , & pdp [7 - i ], 4 );
877
+ }
878
+
879
+ static bool
880
+ check_shadow_context_ppgtt (struct execlist_ring_context * c , struct intel_vgpu_mm * m )
881
+ {
882
+ if (m -> ppgtt_mm .root_entry_type == GTT_TYPE_PPGTT_ROOT_L4_ENTRY ) {
883
+ u64 shadow_pdp = c -> pdps [7 ].val | (u64 ) c -> pdps [6 ].val << 32 ;
884
+
885
+ if (shadow_pdp != m -> ppgtt_mm .shadow_pdps [0 ]) {
886
+ gvt_dbg_mm ("4-level context ppgtt not match LRI command\n" );
887
+ return false;
888
+ }
889
+ return true;
890
+ } else {
891
+ /* see comment in LRI handler in cmd_parser.c */
892
+ gvt_dbg_mm ("invalid shadow mm type\n" );
893
+ return false;
894
+ }
895
+ }
896
+
823
897
static void update_guest_context (struct intel_vgpu_workload * workload )
824
898
{
825
899
struct i915_request * rq = workload -> req ;
@@ -905,6 +979,15 @@ static void update_guest_context(struct intel_vgpu_workload *workload)
905
979
906
980
shadow_ring_context = (void * ) ctx -> lrc_reg_state ;
907
981
982
+ if (!list_empty (& workload -> lri_shadow_mm )) {
983
+ struct intel_vgpu_mm * m = list_last_entry (& workload -> lri_shadow_mm ,
984
+ struct intel_vgpu_mm ,
985
+ ppgtt_mm .link );
986
+ GEM_BUG_ON (!check_shadow_context_ppgtt (shadow_ring_context , m ));
987
+ update_guest_pdps (vgpu , workload -> ring_context_gpa ,
988
+ (void * )m -> ppgtt_mm .guest_pdps );
989
+ }
990
+
908
991
#define COPY_REG (name ) \
909
992
intel_gvt_hypervisor_write_gpa(vgpu, workload->ring_context_gpa + \
910
993
RING_CTX_OFF(name.val), &shadow_ring_context->name.val, 4)
@@ -1013,6 +1096,9 @@ static void complete_current_workload(struct intel_gvt *gvt, int ring_id)
1013
1096
1014
1097
workload -> complete (workload );
1015
1098
1099
+ intel_vgpu_shadow_mm_unpin (workload );
1100
+ intel_vgpu_destroy_workload (workload );
1101
+
1016
1102
atomic_dec (& s -> running_workload_num );
1017
1103
wake_up (& scheduler -> workload_complete_wq );
1018
1104
@@ -1406,6 +1492,16 @@ void intel_vgpu_destroy_workload(struct intel_vgpu_workload *workload)
1406
1492
release_shadow_batch_buffer (workload );
1407
1493
release_shadow_wa_ctx (& workload -> wa_ctx );
1408
1494
1495
+ if (!list_empty (& workload -> lri_shadow_mm )) {
1496
+ struct intel_vgpu_mm * m , * mm ;
1497
+ list_for_each_entry_safe (m , mm , & workload -> lri_shadow_mm ,
1498
+ ppgtt_mm .link ) {
1499
+ list_del (& m -> ppgtt_mm .link );
1500
+ intel_vgpu_mm_put (m );
1501
+ }
1502
+ }
1503
+
1504
+ GEM_BUG_ON (!list_empty (& workload -> lri_shadow_mm ));
1409
1505
if (workload -> shadow_mm )
1410
1506
intel_vgpu_mm_put (workload -> shadow_mm );
1411
1507
@@ -1424,6 +1520,7 @@ alloc_workload(struct intel_vgpu *vgpu)
1424
1520
1425
1521
INIT_LIST_HEAD (& workload -> list );
1426
1522
INIT_LIST_HEAD (& workload -> shadow_bb );
1523
+ INIT_LIST_HEAD (& workload -> lri_shadow_mm );
1427
1524
1428
1525
init_waitqueue_head (& workload -> shadow_ctx_status_wq );
1429
1526
atomic_set (& workload -> shadow_ctx_active , 0 );
0 commit comments