.. | .. |
---|
636 | 636 | struct intel_gvt_gtt_entry *entry, unsigned long index) |
---|
637 | 637 | { |
---|
638 | 638 | struct intel_gvt_gtt_pte_ops *pte_ops = mm->vgpu->gvt->gtt.pte_ops; |
---|
| 639 | + unsigned long offset = index; |
---|
639 | 640 | |
---|
640 | 641 | GEM_BUG_ON(mm->type != INTEL_GVT_MM_GGTT); |
---|
| 642 | + |
---|
| 643 | + if (vgpu_gmadr_is_aperture(mm->vgpu, index << I915_GTT_PAGE_SHIFT)) { |
---|
| 644 | + offset -= (vgpu_aperture_gmadr_base(mm->vgpu) >> PAGE_SHIFT); |
---|
| 645 | + mm->ggtt_mm.host_ggtt_aperture[offset] = entry->val64; |
---|
| 646 | + } else if (vgpu_gmadr_is_hidden(mm->vgpu, index << I915_GTT_PAGE_SHIFT)) { |
---|
| 647 | + offset -= (vgpu_hidden_gmadr_base(mm->vgpu) >> PAGE_SHIFT); |
---|
| 648 | + mm->ggtt_mm.host_ggtt_hidden[offset] = entry->val64; |
---|
| 649 | + } |
---|
641 | 650 | |
---|
642 | 651 | pte_ops->set_entry(NULL, entry, index, false, 0, mm->vgpu); |
---|
643 | 652 | } |
---|
.. | .. |
---|
1192 | 1201 | for_each_shadow_entry(sub_spt, &sub_se, sub_index) { |
---|
1193 | 1202 | ret = intel_gvt_hypervisor_dma_map_guest_page(vgpu, |
---|
1194 | 1203 | start_gfn + sub_index, PAGE_SIZE, &dma_addr); |
---|
1195 | | - if (ret) { |
---|
1196 | | - ppgtt_invalidate_spt(spt); |
---|
1197 | | - return ret; |
---|
1198 | | - } |
---|
| 1204 | + if (ret) |
---|
| 1205 | + goto err; |
---|
1199 | 1206 | sub_se.val64 = se->val64; |
---|
1200 | 1207 | |
---|
1201 | 1208 | /* Copy the PAT field from PDE. */ |
---|
.. | .. |
---|
1214 | 1221 | ops->set_pfn(se, sub_spt->shadow_page.mfn); |
---|
1215 | 1222 | ppgtt_set_shadow_entry(spt, se, index); |
---|
1216 | 1223 | return 0; |
---|
| 1224 | +err: |
---|
| 1225 | + /* Cancel the existing addess mappings of DMA addr. */ |
---|
| 1226 | + for_each_present_shadow_entry(sub_spt, &sub_se, sub_index) { |
---|
| 1227 | + gvt_vdbg_mm("invalidate 4K entry\n"); |
---|
| 1228 | + ppgtt_invalidate_pte(sub_spt, &sub_se); |
---|
| 1229 | + } |
---|
| 1230 | + /* Release the new allocated spt. */ |
---|
| 1231 | + trace_spt_change(sub_spt->vgpu->id, "release", sub_spt, |
---|
| 1232 | + sub_spt->guest_page.gfn, sub_spt->shadow_page.type); |
---|
| 1233 | + ppgtt_free_spt(sub_spt); |
---|
| 1234 | + return ret; |
---|
1217 | 1235 | } |
---|
1218 | 1236 | |
---|
1219 | 1237 | static int split_64KB_gtt_entry(struct intel_vgpu *vgpu, |
---|
.. | .. |
---|
1944 | 1962 | return ERR_PTR(-ENOMEM); |
---|
1945 | 1963 | } |
---|
1946 | 1964 | |
---|
| 1965 | + mm->ggtt_mm.host_ggtt_aperture = vzalloc((vgpu_aperture_sz(vgpu) >> PAGE_SHIFT) * sizeof(u64)); |
---|
| 1966 | + if (!mm->ggtt_mm.host_ggtt_aperture) { |
---|
| 1967 | + vfree(mm->ggtt_mm.virtual_ggtt); |
---|
| 1968 | + vgpu_free_mm(mm); |
---|
| 1969 | + return ERR_PTR(-ENOMEM); |
---|
| 1970 | + } |
---|
| 1971 | + |
---|
| 1972 | + mm->ggtt_mm.host_ggtt_hidden = vzalloc((vgpu_hidden_sz(vgpu) >> PAGE_SHIFT) * sizeof(u64)); |
---|
| 1973 | + if (!mm->ggtt_mm.host_ggtt_hidden) { |
---|
| 1974 | + vfree(mm->ggtt_mm.host_ggtt_aperture); |
---|
| 1975 | + vfree(mm->ggtt_mm.virtual_ggtt); |
---|
| 1976 | + vgpu_free_mm(mm); |
---|
| 1977 | + return ERR_PTR(-ENOMEM); |
---|
| 1978 | + } |
---|
| 1979 | + |
---|
1947 | 1980 | return mm; |
---|
1948 | 1981 | } |
---|
1949 | 1982 | |
---|
.. | .. |
---|
1971 | 2004 | invalidate_ppgtt_mm(mm); |
---|
1972 | 2005 | } else { |
---|
1973 | 2006 | vfree(mm->ggtt_mm.virtual_ggtt); |
---|
| 2007 | + vfree(mm->ggtt_mm.host_ggtt_aperture); |
---|
| 2008 | + vfree(mm->ggtt_mm.host_ggtt_hidden); |
---|
1974 | 2009 | } |
---|
1975 | 2010 | |
---|
1976 | 2011 | vgpu_free_mm(mm); |
---|
.. | .. |
---|
2836 | 2871 | } |
---|
2837 | 2872 | |
---|
2838 | 2873 | /** |
---|
2839 | | - * intel_vgpu_reset_gtt - reset the all GTT related status |
---|
2840 | | - * @vgpu: a vGPU |
---|
| 2874 | + * intel_gvt_restore_ggtt - restore all vGPU's ggtt entries |
---|
| 2875 | + * @gvt: intel gvt device |
---|
2841 | 2876 | * |
---|
2842 | | - * This function is called from vfio core to reset reset all |
---|
2843 | | - * GTT related status, including GGTT, PPGTT, scratch page. |
---|
| 2877 | + * This function is called at driver resume stage to restore |
---|
| 2878 | + * GGTT entries of every vGPU. |
---|
2844 | 2879 | * |
---|
2845 | 2880 | */ |
---|
2846 | | -void intel_vgpu_reset_gtt(struct intel_vgpu *vgpu) |
---|
| 2881 | +void intel_gvt_restore_ggtt(struct intel_gvt *gvt) |
---|
2847 | 2882 | { |
---|
2848 | | - /* Shadow pages are only created when there is no page |
---|
2849 | | - * table tracking data, so remove page tracking data after |
---|
2850 | | - * removing the shadow pages. |
---|
2851 | | - */ |
---|
2852 | | - intel_vgpu_destroy_all_ppgtt_mm(vgpu); |
---|
2853 | | - intel_vgpu_reset_ggtt(vgpu, true); |
---|
| 2883 | + struct intel_vgpu *vgpu; |
---|
| 2884 | + struct intel_vgpu_mm *mm; |
---|
| 2885 | + int id; |
---|
| 2886 | + gen8_pte_t pte; |
---|
| 2887 | + u32 idx, num_low, num_hi, offset; |
---|
| 2888 | + |
---|
| 2889 | + /* Restore dirty host ggtt for all vGPUs */ |
---|
| 2890 | + idr_for_each_entry(&(gvt)->vgpu_idr, vgpu, id) { |
---|
| 2891 | + mm = vgpu->gtt.ggtt_mm; |
---|
| 2892 | + |
---|
| 2893 | + num_low = vgpu_aperture_sz(vgpu) >> PAGE_SHIFT; |
---|
| 2894 | + offset = vgpu_aperture_gmadr_base(vgpu) >> PAGE_SHIFT; |
---|
| 2895 | + for (idx = 0; idx < num_low; idx++) { |
---|
| 2896 | + pte = mm->ggtt_mm.host_ggtt_aperture[idx]; |
---|
| 2897 | + if (pte & _PAGE_PRESENT) |
---|
| 2898 | + write_pte64(vgpu->gvt->gt->ggtt, offset + idx, pte); |
---|
| 2899 | + } |
---|
| 2900 | + |
---|
| 2901 | + num_hi = vgpu_hidden_sz(vgpu) >> PAGE_SHIFT; |
---|
| 2902 | + offset = vgpu_hidden_gmadr_base(vgpu) >> PAGE_SHIFT; |
---|
| 2903 | + for (idx = 0; idx < num_hi; idx++) { |
---|
| 2904 | + pte = mm->ggtt_mm.host_ggtt_hidden[idx]; |
---|
| 2905 | + if (pte & _PAGE_PRESENT) |
---|
| 2906 | + write_pte64(vgpu->gvt->gt->ggtt, offset + idx, pte); |
---|
| 2907 | + } |
---|
| 2908 | + } |
---|
2854 | 2909 | } |
---|