forked from ~ljy/RK356X_SDK_RELEASE

hc
2024-01-31 f70575805708cabdedea7498aaa3f710fde4d920
kernel/drivers/gpu/drm/i915/gvt/gtt.c
....@@ -53,20 +53,28 @@
5353 */
5454 bool intel_gvt_ggtt_validate_range(struct intel_vgpu *vgpu, u64 addr, u32 size)
5555 {
56
- if ((!vgpu_gmadr_is_valid(vgpu, addr)) || (size
57
- && !vgpu_gmadr_is_valid(vgpu, addr + size - 1))) {
58
- gvt_vgpu_err("invalid range gmadr 0x%llx size 0x%x\n",
59
- addr, size);
60
- return false;
61
- }
62
- return true;
56
+ if (size == 0)
57
+ return vgpu_gmadr_is_valid(vgpu, addr);
58
+
59
+ if (vgpu_gmadr_is_aperture(vgpu, addr) &&
60
+ vgpu_gmadr_is_aperture(vgpu, addr + size - 1))
61
+ return true;
62
+ else if (vgpu_gmadr_is_hidden(vgpu, addr) &&
63
+ vgpu_gmadr_is_hidden(vgpu, addr + size - 1))
64
+ return true;
65
+
66
+ gvt_dbg_mm("Invalid ggtt range at 0x%llx, size: 0x%x\n",
67
+ addr, size);
68
+ return false;
6369 }
6470
6571 /* translate a guest gmadr to host gmadr */
6672 int intel_gvt_ggtt_gmadr_g2h(struct intel_vgpu *vgpu, u64 g_addr, u64 *h_addr)
6773 {
68
- if (WARN(!vgpu_gmadr_is_valid(vgpu, g_addr),
69
- "invalid guest gmadr %llx\n", g_addr))
74
+ struct drm_i915_private *i915 = vgpu->gvt->gt->i915;
75
+
76
+ if (drm_WARN(&i915->drm, !vgpu_gmadr_is_valid(vgpu, g_addr),
77
+ "invalid guest gmadr %llx\n", g_addr))
7078 return -EACCES;
7179
7280 if (vgpu_gmadr_is_aperture(vgpu, g_addr))
....@@ -81,8 +89,10 @@
8189 /* translate a host gmadr to guest gmadr */
8290 int intel_gvt_ggtt_gmadr_h2g(struct intel_vgpu *vgpu, u64 h_addr, u64 *g_addr)
8391 {
84
- if (WARN(!gvt_gmadr_is_valid(vgpu->gvt, h_addr),
85
- "invalid host gmadr %llx\n", h_addr))
92
+ struct drm_i915_private *i915 = vgpu->gvt->gt->i915;
93
+
94
+ if (drm_WARN(&i915->drm, !gvt_gmadr_is_valid(vgpu->gvt, h_addr),
95
+ "invalid host gmadr %llx\n", h_addr))
8696 return -EACCES;
8797
8898 if (gvt_gmadr_is_aperture(vgpu->gvt, h_addr))
....@@ -269,24 +279,23 @@
269279 return gtt_type_table[type].pse_entry_type;
270280 }
271281
272
-static u64 read_pte64(struct drm_i915_private *dev_priv, unsigned long index)
282
+static u64 read_pte64(struct i915_ggtt *ggtt, unsigned long index)
273283 {
274
- void __iomem *addr = (gen8_pte_t __iomem *)dev_priv->ggtt.gsm + index;
284
+ void __iomem *addr = (gen8_pte_t __iomem *)ggtt->gsm + index;
275285
276286 return readq(addr);
277287 }
278288
279
-static void ggtt_invalidate(struct drm_i915_private *dev_priv)
289
+static void ggtt_invalidate(struct intel_gt *gt)
280290 {
281
- mmio_hw_access_pre(dev_priv);
282
- I915_WRITE(GFX_FLSH_CNTL_GEN6, GFX_FLSH_CNTL_EN);
283
- mmio_hw_access_post(dev_priv);
291
+ mmio_hw_access_pre(gt);
292
+ intel_uncore_write(gt->uncore, GFX_FLSH_CNTL_GEN6, GFX_FLSH_CNTL_EN);
293
+ mmio_hw_access_post(gt);
284294 }
285295
286
-static void write_pte64(struct drm_i915_private *dev_priv,
287
- unsigned long index, u64 pte)
296
+static void write_pte64(struct i915_ggtt *ggtt, unsigned long index, u64 pte)
288297 {
289
- void __iomem *addr = (gen8_pte_t __iomem *)dev_priv->ggtt.gsm + index;
298
+ void __iomem *addr = (gen8_pte_t __iomem *)ggtt->gsm + index;
290299
291300 writeq(pte, addr);
292301 }
....@@ -309,7 +318,7 @@
309318 if (WARN_ON(ret))
310319 return ret;
311320 } else if (!pt) {
312
- e->val64 = read_pte64(vgpu->gvt->dev_priv, index);
321
+ e->val64 = read_pte64(vgpu->gvt->gt->ggtt, index);
313322 } else {
314323 e->val64 = *((u64 *)pt + index);
315324 }
....@@ -334,7 +343,7 @@
334343 if (WARN_ON(ret))
335344 return ret;
336345 } else if (!pt) {
337
- write_pte64(vgpu->gvt->dev_priv, index, e->val64);
346
+ write_pte64(vgpu->gvt->gt->ggtt, index, e->val64);
338347 } else {
339348 *((u64 *)pt + index) = e->val64;
340349 }
....@@ -627,8 +636,17 @@
627636 struct intel_gvt_gtt_entry *entry, unsigned long index)
628637 {
629638 struct intel_gvt_gtt_pte_ops *pte_ops = mm->vgpu->gvt->gtt.pte_ops;
639
+ unsigned long offset = index;
630640
631641 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
+ }
632650
633651 pte_ops->set_entry(NULL, entry, index, false, 0, mm->vgpu);
634652 }
....@@ -728,7 +746,7 @@
728746
729747 static void ppgtt_free_spt(struct intel_vgpu_ppgtt_spt *spt)
730748 {
731
- struct device *kdev = &spt->vgpu->gvt->dev_priv->drm.pdev->dev;
749
+ struct device *kdev = &spt->vgpu->gvt->gt->i915->drm.pdev->dev;
732750
733751 trace_spt_free(spt->vgpu->id, spt, spt->guest_page.type);
734752
....@@ -750,14 +768,20 @@
750768
751769 static void ppgtt_free_all_spt(struct intel_vgpu *vgpu)
752770 {
753
- struct intel_vgpu_ppgtt_spt *spt;
771
+ struct intel_vgpu_ppgtt_spt *spt, *spn;
754772 struct radix_tree_iter iter;
755
- void **slot;
773
+ LIST_HEAD(all_spt);
774
+ void __rcu **slot;
756775
776
+ rcu_read_lock();
757777 radix_tree_for_each_slot(slot, &vgpu->gtt.spt_tree, &iter, 0) {
758778 spt = radix_tree_deref_slot(slot);
759
- ppgtt_free_spt(spt);
779
+ list_move(&spt->post_shadow_list, &all_spt);
760780 }
781
+ rcu_read_unlock();
782
+
783
+ list_for_each_entry_safe(spt, spn, &all_spt, post_shadow_list)
784
+ ppgtt_free_spt(spt);
761785 }
762786
763787 static int ppgtt_handle_guest_write_page_table_bytes(
....@@ -805,9 +829,9 @@
805829
806830 /* Allocate shadow page table without guest page. */
807831 static struct intel_vgpu_ppgtt_spt *ppgtt_alloc_spt(
808
- struct intel_vgpu *vgpu, intel_gvt_gtt_type_t type)
832
+ struct intel_vgpu *vgpu, enum intel_gvt_gtt_type type)
809833 {
810
- struct device *kdev = &vgpu->gvt->dev_priv->drm.pdev->dev;
834
+ struct device *kdev = &vgpu->gvt->gt->i915->drm.pdev->dev;
811835 struct intel_vgpu_ppgtt_spt *spt = NULL;
812836 dma_addr_t daddr;
813837 int ret;
....@@ -855,7 +879,7 @@
855879
856880 /* Allocate shadow page table associated with specific gfn. */
857881 static struct intel_vgpu_ppgtt_spt *ppgtt_alloc_spt_gfn(
858
- struct intel_vgpu *vgpu, intel_gvt_gtt_type_t type,
882
+ struct intel_vgpu *vgpu, enum intel_gvt_gtt_type type,
859883 unsigned long gfn, bool guest_pde_ips)
860884 {
861885 struct intel_vgpu_ppgtt_spt *spt;
....@@ -928,15 +952,27 @@
928952 static int ppgtt_invalidate_spt_by_shadow_entry(struct intel_vgpu *vgpu,
929953 struct intel_gvt_gtt_entry *e)
930954 {
955
+ struct drm_i915_private *i915 = vgpu->gvt->gt->i915;
931956 struct intel_gvt_gtt_pte_ops *ops = vgpu->gvt->gtt.pte_ops;
932957 struct intel_vgpu_ppgtt_spt *s;
933
- intel_gvt_gtt_type_t cur_pt_type;
958
+ enum intel_gvt_gtt_type cur_pt_type;
934959
935960 GEM_BUG_ON(!gtt_type_is_pt(get_next_pt_type(e->type)));
936961
937962 if (e->type != GTT_TYPE_PPGTT_ROOT_L3_ENTRY
938963 && e->type != GTT_TYPE_PPGTT_ROOT_L4_ENTRY) {
939
- cur_pt_type = get_next_pt_type(e->type) + 1;
964
+ cur_pt_type = get_next_pt_type(e->type);
965
+
966
+ if (!gtt_type_is_pt(cur_pt_type) ||
967
+ !gtt_type_is_pt(cur_pt_type + 1)) {
968
+ drm_WARN(&i915->drm, 1,
969
+ "Invalid page table type, cur_pt_type is: %d\n",
970
+ cur_pt_type);
971
+ return -EINVAL;
972
+ }
973
+
974
+ cur_pt_type += 1;
975
+
940976 if (ops->get_pfn(e) ==
941977 vgpu->gtt.scratch_pt[cur_pt_type].page_mfn)
942978 return 0;
....@@ -1023,7 +1059,7 @@
10231059
10241060 static bool vgpu_ips_enabled(struct intel_vgpu *vgpu)
10251061 {
1026
- struct drm_i915_private *dev_priv = vgpu->gvt->dev_priv;
1062
+ struct drm_i915_private *dev_priv = vgpu->gvt->gt->i915;
10271063
10281064 if (INTEL_GEN(dev_priv) == 9 || INTEL_GEN(dev_priv) == 10) {
10291065 u32 ips = vgpu_vreg_t(vgpu, GEN8_GAMW_ECO_DEV_RW_IA) &
....@@ -1070,6 +1106,11 @@
10701106 } else {
10711107 int type = get_next_pt_type(we->type);
10721108
1109
+ if (!gtt_type_is_pt(type)) {
1110
+ ret = -EINVAL;
1111
+ goto err;
1112
+ }
1113
+
10731114 spt = ppgtt_alloc_spt_gfn(vgpu, type, ops->get_pfn(we), ips);
10741115 if (IS_ERR(spt)) {
10751116 ret = PTR_ERR(spt);
....@@ -1091,6 +1132,7 @@
10911132
10921133 err_free_spt:
10931134 ppgtt_free_spt(spt);
1135
+ spt = NULL;
10941136 err:
10951137 gvt_vgpu_err("fail: shadow page %p guest entry 0x%llx type %d\n",
10961138 spt, we->val64, we->type);
....@@ -1113,6 +1155,10 @@
11131155 }
11141156
11151157 /**
1158
+ * Check if can do 2M page
1159
+ * @vgpu: target vgpu
1160
+ * @entry: target pfn's gtt entry
1161
+ *
11161162 * Return 1 if 2MB huge gtt shadowing is possilbe, 0 if miscondition,
11171163 * negtive if found err.
11181164 */
....@@ -1122,7 +1168,7 @@
11221168 struct intel_gvt_gtt_pte_ops *ops = vgpu->gvt->gtt.pte_ops;
11231169 unsigned long pfn;
11241170
1125
- if (!HAS_PAGE_SIZES(vgpu->gvt->dev_priv, I915_GTT_PAGE_SIZE_2M))
1171
+ if (!HAS_PAGE_SIZES(vgpu->gvt->gt->i915, I915_GTT_PAGE_SIZE_2M))
11261172 return 0;
11271173
11281174 pfn = intel_gvt_hypervisor_gfn_to_mfn(vgpu, ops->get_pfn(entry));
....@@ -1155,10 +1201,8 @@
11551201 for_each_shadow_entry(sub_spt, &sub_se, sub_index) {
11561202 ret = intel_gvt_hypervisor_dma_map_guest_page(vgpu,
11571203 start_gfn + sub_index, PAGE_SIZE, &dma_addr);
1158
- if (ret) {
1159
- ppgtt_invalidate_spt(spt);
1160
- return ret;
1161
- }
1204
+ if (ret)
1205
+ goto err;
11621206 sub_se.val64 = se->val64;
11631207
11641208 /* Copy the PAT field from PDE. */
....@@ -1177,6 +1221,17 @@
11771221 ops->set_pfn(se, sub_spt->shadow_page.mfn);
11781222 ppgtt_set_shadow_entry(spt, se, index);
11791223 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;
11801235 }
11811236
11821237 static int split_64KB_gtt_entry(struct intel_vgpu *vgpu,
....@@ -1251,7 +1306,7 @@
12511306 return -EINVAL;
12521307 default:
12531308 GEM_BUG_ON(1);
1254
- };
1309
+ }
12551310
12561311 /* direct shadow */
12571312 ret = intel_gvt_hypervisor_dma_map_guest_page(vgpu, gfn, page_size,
....@@ -1845,7 +1900,7 @@
18451900 * Zero on success, negative error code in pointer if failed.
18461901 */
18471902 struct intel_vgpu_mm *intel_vgpu_create_ppgtt_mm(struct intel_vgpu *vgpu,
1848
- intel_gvt_gtt_type_t root_entry_type, u64 pdps[])
1903
+ enum intel_gvt_gtt_type root_entry_type, u64 pdps[])
18491904 {
18501905 struct intel_gvt *gvt = vgpu->gvt;
18511906 struct intel_vgpu_mm *mm;
....@@ -1863,6 +1918,7 @@
18631918
18641919 INIT_LIST_HEAD(&mm->ppgtt_mm.list);
18651920 INIT_LIST_HEAD(&mm->ppgtt_mm.lru_list);
1921
+ INIT_LIST_HEAD(&mm->ppgtt_mm.link);
18661922
18671923 if (root_entry_type == GTT_TYPE_PPGTT_ROOT_L4_ENTRY)
18681924 mm->ppgtt_mm.guest_pdps[0] = pdps[0];
....@@ -1878,7 +1934,11 @@
18781934 }
18791935
18801936 list_add_tail(&mm->ppgtt_mm.list, &vgpu->gtt.ppgtt_mm_list_head);
1937
+
1938
+ mutex_lock(&gvt->gtt.ppgtt_mm_lock);
18811939 list_add_tail(&mm->ppgtt_mm.lru_list, &gvt->gtt.ppgtt_mm_lru_list_head);
1940
+ mutex_unlock(&gvt->gtt.ppgtt_mm_lock);
1941
+
18821942 return mm;
18831943 }
18841944
....@@ -1901,7 +1961,21 @@
19011961 vgpu_free_mm(mm);
19021962 return ERR_PTR(-ENOMEM);
19031963 }
1904
- mm->ggtt_mm.last_partial_off = -1UL;
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
+ }
19051979
19061980 return mm;
19071981 }
....@@ -1922,11 +1996,16 @@
19221996
19231997 if (mm->type == INTEL_GVT_MM_PPGTT) {
19241998 list_del(&mm->ppgtt_mm.list);
1999
+
2000
+ mutex_lock(&mm->vgpu->gvt->gtt.ppgtt_mm_lock);
19252001 list_del(&mm->ppgtt_mm.lru_list);
2002
+ mutex_unlock(&mm->vgpu->gvt->gtt.ppgtt_mm_lock);
2003
+
19262004 invalidate_ppgtt_mm(mm);
19272005 } else {
19282006 vfree(mm->ggtt_mm.virtual_ggtt);
1929
- mm->ggtt_mm.last_partial_off = -1UL;
2007
+ vfree(mm->ggtt_mm.host_ggtt_aperture);
2008
+ vfree(mm->ggtt_mm.host_ggtt_hidden);
19302009 }
19312010
19322011 vgpu_free_mm(mm);
....@@ -1945,7 +2024,7 @@
19452024
19462025 /**
19472026 * intel_vgpu_pin_mm - increase the pin count of a vGPU mm object
1948
- * @vgpu: a vGPU
2027
+ * @mm: target vgpu mm
19492028 *
19502029 * This function is called when user wants to use a vGPU mm object. If this
19512030 * mm object hasn't been shadowed yet, the shadow will be populated at this
....@@ -1965,9 +2044,10 @@
19652044 if (ret)
19662045 return ret;
19672046
2047
+ mutex_lock(&mm->vgpu->gvt->gtt.ppgtt_mm_lock);
19682048 list_move_tail(&mm->ppgtt_mm.lru_list,
19692049 &mm->vgpu->gvt->gtt.ppgtt_mm_lru_list_head);
1970
-
2050
+ mutex_unlock(&mm->vgpu->gvt->gtt.ppgtt_mm_lock);
19712051 }
19722052
19732053 return 0;
....@@ -1978,6 +2058,8 @@
19782058 struct intel_vgpu_mm *mm;
19792059 struct list_head *pos, *n;
19802060
2061
+ mutex_lock(&gvt->gtt.ppgtt_mm_lock);
2062
+
19812063 list_for_each_safe(pos, n, &gvt->gtt.ppgtt_mm_lru_list_head) {
19822064 mm = container_of(pos, struct intel_vgpu_mm, ppgtt_mm.lru_list);
19832065
....@@ -1985,9 +2067,11 @@
19852067 continue;
19862068
19872069 list_del_init(&mm->ppgtt_mm.lru_list);
2070
+ mutex_unlock(&gvt->gtt.ppgtt_mm_lock);
19882071 invalidate_ppgtt_mm(mm);
19892072 return 1;
19902073 }
2074
+ mutex_unlock(&gvt->gtt.ppgtt_mm_lock);
19912075 return 0;
19922076 }
19932077
....@@ -2103,10 +2187,19 @@
21032187 struct intel_vgpu_mm *ggtt_mm = vgpu->gtt.ggtt_mm;
21042188 const struct intel_gvt_device_info *info = &vgpu->gvt->device_info;
21052189 unsigned long index = off >> info->gtt_entry_size_shift;
2190
+ unsigned long gma;
21062191 struct intel_gvt_gtt_entry e;
21072192
21082193 if (bytes != 4 && bytes != 8)
21092194 return -EINVAL;
2195
+
2196
+ gma = index << I915_GTT_PAGE_SHIFT;
2197
+ if (!intel_gvt_ggtt_validate_range(vgpu,
2198
+ gma, 1 << I915_GTT_PAGE_SHIFT)) {
2199
+ gvt_dbg_mm("read invalid ggtt at 0x%lx\n", gma);
2200
+ memset(p_data, 0, bytes);
2201
+ return 0;
2202
+ }
21102203
21112204 ggtt_get_guest_entry(ggtt_mm, &e, index);
21122205 memcpy(p_data, (void *)&e.val64 + (off & (info->gtt_entry_size - 1)),
....@@ -2165,6 +2258,8 @@
21652258 struct intel_gvt_gtt_entry m = {.val64 = 0, .type = GTT_TYPE_GGTT_PTE};
21662259 dma_addr_t dma_addr;
21672260 int ret;
2261
+ struct intel_gvt_partial_pte *partial_pte, *pos, *n;
2262
+ bool partial_update = false;
21682263
21692264 if (bytes != 4 && bytes != 8)
21702265 return -EINVAL;
....@@ -2175,68 +2270,57 @@
21752270 if (!vgpu_gmadr_is_valid(vgpu, gma))
21762271 return 0;
21772272
2178
- ggtt_get_guest_entry(ggtt_mm, &e, g_gtt_index);
2179
-
2273
+ e.type = GTT_TYPE_GGTT_PTE;
21802274 memcpy((void *)&e.val64 + (off & (info->gtt_entry_size - 1)), p_data,
21812275 bytes);
21822276
21832277 /* If ggtt entry size is 8 bytes, and it's split into two 4 bytes
2184
- * write, we assume the two 4 bytes writes are consecutive.
2185
- * Otherwise, we abort and report error
2278
+ * write, save the first 4 bytes in a list and update virtual
2279
+ * PTE. Only update shadow PTE when the second 4 bytes comes.
21862280 */
21872281 if (bytes < info->gtt_entry_size) {
2188
- if (ggtt_mm->ggtt_mm.last_partial_off == -1UL) {
2189
- /* the first partial part*/
2190
- ggtt_mm->ggtt_mm.last_partial_off = off;
2191
- ggtt_mm->ggtt_mm.last_partial_data = e.val64;
2192
- return 0;
2193
- } else if ((g_gtt_index ==
2194
- (ggtt_mm->ggtt_mm.last_partial_off >>
2195
- info->gtt_entry_size_shift)) &&
2196
- (off != ggtt_mm->ggtt_mm.last_partial_off)) {
2197
- /* the second partial part */
2282
+ bool found = false;
21982283
2199
- int last_off = ggtt_mm->ggtt_mm.last_partial_off &
2200
- (info->gtt_entry_size - 1);
2284
+ list_for_each_entry_safe(pos, n,
2285
+ &ggtt_mm->ggtt_mm.partial_pte_list, list) {
2286
+ if (g_gtt_index == pos->offset >>
2287
+ info->gtt_entry_size_shift) {
2288
+ if (off != pos->offset) {
2289
+ /* the second partial part*/
2290
+ int last_off = pos->offset &
2291
+ (info->gtt_entry_size - 1);
22012292
2202
- memcpy((void *)&e.val64 + last_off,
2203
- (void *)&ggtt_mm->ggtt_mm.last_partial_data +
2204
- last_off, bytes);
2293
+ memcpy((void *)&e.val64 + last_off,
2294
+ (void *)&pos->data + last_off,
2295
+ bytes);
22052296
2206
- ggtt_mm->ggtt_mm.last_partial_off = -1UL;
2207
- } else {
2208
- int last_offset;
2297
+ list_del(&pos->list);
2298
+ kfree(pos);
2299
+ found = true;
2300
+ break;
2301
+ }
22092302
2210
- gvt_vgpu_err("failed to populate guest ggtt entry: abnormal ggtt entry write sequence, last_partial_off=%lx, offset=%x, bytes=%d, ggtt entry size=%d\n",
2211
- ggtt_mm->ggtt_mm.last_partial_off, off,
2212
- bytes, info->gtt_entry_size);
2303
+ /* update of the first partial part */
2304
+ pos->data = e.val64;
2305
+ ggtt_set_guest_entry(ggtt_mm, &e, g_gtt_index);
2306
+ return 0;
2307
+ }
2308
+ }
22132309
2214
- /* set host ggtt entry to scratch page and clear
2215
- * virtual ggtt entry as not present for last
2216
- * partially write offset
2217
- */
2218
- last_offset = ggtt_mm->ggtt_mm.last_partial_off &
2219
- (~(info->gtt_entry_size - 1));
2220
-
2221
- ggtt_get_host_entry(ggtt_mm, &m, last_offset);
2222
- ggtt_invalidate_pte(vgpu, &m);
2223
- ops->set_pfn(&m, gvt->gtt.scratch_mfn);
2224
- ops->clear_present(&m);
2225
- ggtt_set_host_entry(ggtt_mm, &m, last_offset);
2226
- ggtt_invalidate(gvt->dev_priv);
2227
-
2228
- ggtt_get_guest_entry(ggtt_mm, &e, last_offset);
2229
- ops->clear_present(&e);
2230
- ggtt_set_guest_entry(ggtt_mm, &e, last_offset);
2231
-
2232
- ggtt_mm->ggtt_mm.last_partial_off = off;
2233
- ggtt_mm->ggtt_mm.last_partial_data = e.val64;
2234
-
2235
- return 0;
2310
+ if (!found) {
2311
+ /* the first partial part */
2312
+ partial_pte = kzalloc(sizeof(*partial_pte), GFP_KERNEL);
2313
+ if (!partial_pte)
2314
+ return -ENOMEM;
2315
+ partial_pte->offset = off;
2316
+ partial_pte->data = e.val64;
2317
+ list_add_tail(&partial_pte->list,
2318
+ &ggtt_mm->ggtt_mm.partial_pte_list);
2319
+ partial_update = true;
22362320 }
22372321 }
22382322
2239
- if (ops->test_present(&e)) {
2323
+ if (!partial_update && (ops->test_present(&e))) {
22402324 gfn = ops->get_pfn(&e);
22412325 m.val64 = e.val64;
22422326 m.type = e.type;
....@@ -2261,16 +2345,18 @@
22612345 } else
22622346 ops->set_pfn(&m, dma_addr >> PAGE_SHIFT);
22632347 } else {
2264
- ggtt_get_host_entry(ggtt_mm, &m, g_gtt_index);
2265
- ggtt_invalidate_pte(vgpu, &m);
22662348 ops->set_pfn(&m, gvt->gtt.scratch_mfn);
22672349 ops->clear_present(&m);
22682350 }
22692351
22702352 out:
2271
- ggtt_set_host_entry(ggtt_mm, &m, g_gtt_index);
2272
- ggtt_invalidate(gvt->dev_priv);
22732353 ggtt_set_guest_entry(ggtt_mm, &e, g_gtt_index);
2354
+
2355
+ ggtt_get_host_entry(ggtt_mm, &e, g_gtt_index);
2356
+ ggtt_invalidate_pte(vgpu, &e);
2357
+
2358
+ ggtt_set_host_entry(ggtt_mm, &m, g_gtt_index);
2359
+ ggtt_invalidate(gvt->gt);
22742360 return 0;
22752361 }
22762362
....@@ -2291,28 +2377,45 @@
22912377 {
22922378 const struct intel_gvt_device_info *info = &vgpu->gvt->device_info;
22932379 int ret;
2380
+ struct intel_vgpu_submission *s = &vgpu->submission;
2381
+ struct intel_engine_cs *engine;
2382
+ int i;
22942383
22952384 if (bytes != 4 && bytes != 8)
22962385 return -EINVAL;
22972386
22982387 off -= info->gtt_start_offset;
22992388 ret = emulate_ggtt_mmio_write(vgpu, off, p_data, bytes);
2389
+
2390
+ /* if ggtt of last submitted context is written,
2391
+ * that context is probably got unpinned.
2392
+ * Set last shadowed ctx to invalid.
2393
+ */
2394
+ for_each_engine(engine, vgpu->gvt->gt, i) {
2395
+ if (!s->last_ctx[i].valid)
2396
+ continue;
2397
+
2398
+ if (s->last_ctx[i].lrca == (off >> info->gtt_entry_size_shift))
2399
+ s->last_ctx[i].valid = false;
2400
+ }
23002401 return ret;
23012402 }
23022403
23032404 static int alloc_scratch_pages(struct intel_vgpu *vgpu,
2304
- intel_gvt_gtt_type_t type)
2405
+ enum intel_gvt_gtt_type type)
23052406 {
2407
+ struct drm_i915_private *i915 = vgpu->gvt->gt->i915;
23062408 struct intel_vgpu_gtt *gtt = &vgpu->gtt;
23072409 struct intel_gvt_gtt_pte_ops *ops = vgpu->gvt->gtt.pte_ops;
23082410 int page_entry_num = I915_GTT_PAGE_SIZE >>
23092411 vgpu->gvt->device_info.gtt_entry_size_shift;
23102412 void *scratch_pt;
23112413 int i;
2312
- struct device *dev = &vgpu->gvt->dev_priv->drm.pdev->dev;
2414
+ struct device *dev = &vgpu->gvt->gt->i915->drm.pdev->dev;
23132415 dma_addr_t daddr;
23142416
2315
- if (WARN_ON(type < GTT_TYPE_PPGTT_PTE_PT || type >= GTT_TYPE_MAX))
2417
+ if (drm_WARN_ON(&i915->drm,
2418
+ type < GTT_TYPE_PPGTT_PTE_PT || type >= GTT_TYPE_MAX))
23162419 return -EINVAL;
23172420
23182421 scratch_pt = (void *)get_zeroed_page(GFP_KERNEL);
....@@ -2366,7 +2469,7 @@
23662469 static int release_scratch_page_tree(struct intel_vgpu *vgpu)
23672470 {
23682471 int i;
2369
- struct device *dev = &vgpu->gvt->dev_priv->drm.pdev->dev;
2472
+ struct device *dev = &vgpu->gvt->gt->i915->drm.pdev->dev;
23702473 dma_addr_t daddr;
23712474
23722475 for (i = GTT_TYPE_PPGTT_PTE_PT; i < GTT_TYPE_MAX; i++) {
....@@ -2428,10 +2531,12 @@
24282531
24292532 intel_vgpu_reset_ggtt(vgpu, false);
24302533
2534
+ INIT_LIST_HEAD(&gtt->ggtt_mm->ggtt_mm.partial_pte_list);
2535
+
24312536 return create_scratch_page_tree(vgpu);
24322537 }
24332538
2434
-static void intel_vgpu_destroy_all_ppgtt_mm(struct intel_vgpu *vgpu)
2539
+void intel_vgpu_destroy_all_ppgtt_mm(struct intel_vgpu *vgpu)
24352540 {
24362541 struct list_head *pos, *n;
24372542 struct intel_vgpu_mm *mm;
....@@ -2452,6 +2557,15 @@
24522557
24532558 static void intel_vgpu_destroy_ggtt_mm(struct intel_vgpu *vgpu)
24542559 {
2560
+ struct intel_gvt_partial_pte *pos, *next;
2561
+
2562
+ list_for_each_entry_safe(pos, next,
2563
+ &vgpu->gtt.ggtt_mm->ggtt_mm.partial_pte_list,
2564
+ list) {
2565
+ gvt_dbg_mm("partial PTE update on hold 0x%lx : 0x%llx\n",
2566
+ pos->offset, pos->data);
2567
+ kfree(pos);
2568
+ }
24552569 intel_vgpu_destroy_mm(vgpu->gtt.ggtt_mm);
24562570 vgpu->gtt.ggtt_mm = NULL;
24572571 }
....@@ -2485,6 +2599,7 @@
24852599 list_for_each_safe(pos, n, &gtt->oos_page_free_list_head) {
24862600 oos_page = container_of(pos, struct intel_vgpu_oos_page, list);
24872601 list_del(&oos_page->list);
2602
+ free_page((unsigned long)oos_page->mem);
24882603 kfree(oos_page);
24892604 }
24902605 }
....@@ -2505,6 +2620,12 @@
25052620 ret = -ENOMEM;
25062621 goto fail;
25072622 }
2623
+ oos_page->mem = (void *)__get_free_pages(GFP_KERNEL, 0);
2624
+ if (!oos_page->mem) {
2625
+ ret = -ENOMEM;
2626
+ kfree(oos_page);
2627
+ goto fail;
2628
+ }
25082629
25092630 INIT_LIST_HEAD(&oos_page->list);
25102631 INIT_LIST_HEAD(&oos_page->vm_list);
....@@ -2523,8 +2644,7 @@
25232644 /**
25242645 * intel_vgpu_find_ppgtt_mm - find a PPGTT mm object
25252646 * @vgpu: a vGPU
2526
- * @page_table_level: PPGTT page table level
2527
- * @root_entry: PPGTT page table root pointers
2647
+ * @pdps: pdp root array
25282648 *
25292649 * This function is used to find a PPGTT mm object from mm object pool
25302650 *
....@@ -2569,7 +2689,7 @@
25692689 * Zero on success, negative error code if failed.
25702690 */
25712691 struct intel_vgpu_mm *intel_vgpu_get_ppgtt_mm(struct intel_vgpu *vgpu,
2572
- intel_gvt_gtt_type_t root_entry_type, u64 pdps[])
2692
+ enum intel_gvt_gtt_type root_entry_type, u64 pdps[])
25732693 {
25742694 struct intel_vgpu_mm *mm;
25752695
....@@ -2621,7 +2741,7 @@
26212741 {
26222742 int ret;
26232743 void *page;
2624
- struct device *dev = &gvt->dev_priv->drm.pdev->dev;
2744
+ struct device *dev = &gvt->gt->i915->drm.pdev->dev;
26252745 dma_addr_t daddr;
26262746
26272747 gvt_dbg_core("init gtt\n");
....@@ -2656,6 +2776,7 @@
26562776 }
26572777 }
26582778 INIT_LIST_HEAD(&gvt->gtt.ppgtt_mm_lru_list_head);
2779
+ mutex_init(&gvt->gtt.ppgtt_mm_lock);
26592780 return 0;
26602781 }
26612782
....@@ -2669,7 +2790,7 @@
26692790 */
26702791 void intel_gvt_clean_gtt(struct intel_gvt *gvt)
26712792 {
2672
- struct device *dev = &gvt->dev_priv->drm.pdev->dev;
2793
+ struct device *dev = &gvt->gt->i915->drm.pdev->dev;
26732794 dma_addr_t daddr = (dma_addr_t)(gvt->gtt.scratch_mfn <<
26742795 I915_GTT_PAGE_SHIFT);
26752796
....@@ -2696,7 +2817,9 @@
26962817 list_for_each_safe(pos, n, &vgpu->gtt.ppgtt_mm_list_head) {
26972818 mm = container_of(pos, struct intel_vgpu_mm, ppgtt_mm.list);
26982819 if (mm->type == INTEL_GVT_MM_PPGTT) {
2820
+ mutex_lock(&vgpu->gvt->gtt.ppgtt_mm_lock);
26992821 list_del_init(&mm->ppgtt_mm.lru_list);
2822
+ mutex_unlock(&vgpu->gvt->gtt.ppgtt_mm_lock);
27002823 if (mm->ppgtt_mm.shadowed)
27012824 invalidate_ppgtt_mm(mm);
27022825 }
....@@ -2715,7 +2838,6 @@
27152838 void intel_vgpu_reset_ggtt(struct intel_vgpu *vgpu, bool invalidate_old)
27162839 {
27172840 struct intel_gvt *gvt = vgpu->gvt;
2718
- struct drm_i915_private *dev_priv = gvt->dev_priv;
27192841 struct intel_gvt_gtt_pte_ops *pte_ops = vgpu->gvt->gtt.pte_ops;
27202842 struct intel_gvt_gtt_entry entry = {.type = GTT_TYPE_GGTT_PTE};
27212843 struct intel_gvt_gtt_entry old_entry;
....@@ -2745,23 +2867,43 @@
27452867 ggtt_set_host_entry(vgpu->gtt.ggtt_mm, &entry, index++);
27462868 }
27472869
2748
- ggtt_invalidate(dev_priv);
2870
+ ggtt_invalidate(gvt->gt);
27492871 }
27502872
27512873 /**
2752
- * intel_vgpu_reset_gtt - reset the all GTT related status
2753
- * @vgpu: a vGPU
2874
+ * intel_gvt_restore_ggtt - restore all vGPU's ggtt entries
2875
+ * @gvt: intel gvt device
27542876 *
2755
- * This function is called from vfio core to reset reset all
2756
- * 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.
27572879 *
27582880 */
2759
-void intel_vgpu_reset_gtt(struct intel_vgpu *vgpu)
2881
+void intel_gvt_restore_ggtt(struct intel_gvt *gvt)
27602882 {
2761
- /* Shadow pages are only created when there is no page
2762
- * table tracking data, so remove page tracking data after
2763
- * removing the shadow pages.
2764
- */
2765
- intel_vgpu_destroy_all_ppgtt_mm(vgpu);
2766
- 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
+ }
27672909 }