@@ -735,10 +735,12 @@ static void ppgtt_free_spt(struct intel_vgpu_ppgtt_spt *spt)
735735
736736 radix_tree_delete (& spt -> vgpu -> gtt .spt_tree , spt -> shadow_page .mfn );
737737
738- if (spt -> guest_page .oos_page )
739- detach_oos_page (spt -> vgpu , spt -> guest_page .oos_page );
738+ if (spt -> guest_page .gfn ) {
739+ if (spt -> guest_page .oos_page )
740+ detach_oos_page (spt -> vgpu , spt -> guest_page .oos_page );
740741
741- intel_vgpu_unregister_page_track (spt -> vgpu , spt -> guest_page .gfn );
742+ intel_vgpu_unregister_page_track (spt -> vgpu , spt -> guest_page .gfn );
743+ }
742744
743745 list_del_init (& spt -> post_shadow_list );
744746 free_spt (spt );
@@ -799,9 +801,9 @@ static inline struct intel_vgpu_ppgtt_spt *intel_vgpu_find_spt_by_mfn(
799801
800802static int reclaim_one_ppgtt_mm (struct intel_gvt * gvt );
801803
804+ /* Allocate shadow page table without guest page. */
802805static struct intel_vgpu_ppgtt_spt * ppgtt_alloc_spt (
803- struct intel_vgpu * vgpu , int type , unsigned long gfn ,
804- bool guest_pde_ips )
806+ struct intel_vgpu * vgpu , intel_gvt_gtt_type_t type )
805807{
806808 struct device * kdev = & vgpu -> gvt -> dev_priv -> drm .pdev -> dev ;
807809 struct intel_vgpu_ppgtt_spt * spt = NULL ;
@@ -836,34 +838,50 @@ static struct intel_vgpu_ppgtt_spt *ppgtt_alloc_spt(
836838 spt -> shadow_page .vaddr = page_address (spt -> shadow_page .page );
837839 spt -> shadow_page .mfn = daddr >> I915_GTT_PAGE_SHIFT ;
838840
839- /*
840- * Init guest_page.
841- */
842- spt -> guest_page .type = type ;
843- spt -> guest_page .gfn = gfn ;
844- spt -> guest_page .pde_ips = guest_pde_ips ;
845-
846- ret = intel_vgpu_register_page_track (vgpu , spt -> guest_page .gfn ,
847- ppgtt_write_protection_handler , spt );
848- if (ret )
849- goto err_unmap_dma ;
850-
851841 ret = radix_tree_insert (& vgpu -> gtt .spt_tree , spt -> shadow_page .mfn , spt );
852842 if (ret )
853- goto err_unreg_page_track ;
843+ goto err_unmap_dma ;
854844
855- trace_spt_alloc (vgpu -> id , spt , type , spt -> shadow_page .mfn , gfn );
856845 return spt ;
857846
858- err_unreg_page_track :
859- intel_vgpu_unregister_page_track (vgpu , spt -> guest_page .gfn );
860847err_unmap_dma :
861848 dma_unmap_page (kdev , daddr , PAGE_SIZE , PCI_DMA_BIDIRECTIONAL );
862849err_free_spt :
863850 free_spt (spt );
864851 return ERR_PTR (ret );
865852}
866853
854+ /* Allocate shadow page table associated with specific gfn. */
855+ static struct intel_vgpu_ppgtt_spt * ppgtt_alloc_spt_gfn (
856+ struct intel_vgpu * vgpu , intel_gvt_gtt_type_t type ,
857+ unsigned long gfn , bool guest_pde_ips )
858+ {
859+ struct intel_vgpu_ppgtt_spt * spt ;
860+ int ret ;
861+
862+ spt = ppgtt_alloc_spt (vgpu , type );
863+ if (IS_ERR (spt ))
864+ return spt ;
865+
866+ /*
867+ * Init guest_page.
868+ */
869+ ret = intel_vgpu_register_page_track (vgpu , gfn ,
870+ ppgtt_write_protection_handler , spt );
871+ if (ret ) {
872+ ppgtt_free_spt (spt );
873+ return ERR_PTR (ret );
874+ }
875+
876+ spt -> guest_page .type = type ;
877+ spt -> guest_page .gfn = gfn ;
878+ spt -> guest_page .pde_ips = guest_pde_ips ;
879+
880+ trace_spt_alloc (vgpu -> id , spt , type , spt -> shadow_page .mfn , gfn );
881+
882+ return spt ;
883+ }
884+
867885#define pt_entry_size_shift (spt ) \
868886 ((spt)->vgpu->gvt->device_info.gtt_entry_size_shift)
869887
@@ -1021,7 +1039,7 @@ static struct intel_vgpu_ppgtt_spt *ppgtt_populate_spt_by_guest_entry(
10211039 if (we -> type == GTT_TYPE_PPGTT_PDE_ENTRY )
10221040 ips = vgpu_ips_enabled (vgpu ) && ops -> test_ips (we );
10231041
1024- spt = ppgtt_alloc_spt (vgpu , type , ops -> get_pfn (we ), ips );
1042+ spt = ppgtt_alloc_spt_gfn (vgpu , type , ops -> get_pfn (we ), ips );
10251043 if (IS_ERR (spt )) {
10261044 ret = PTR_ERR (spt );
10271045 goto fail ;
0 commit comments