Similar to PDs, while setting up a page directory pointer, make all entries
of the pdp point to the scratch pdp before mapping (and make all its entries
point to the scratch page); this is to be safe in case of out of bound
access or  proactive prefetch.

v2: Handle scratch_pdp allocation failure correctly, and keep
initialize_px functions together (Akash)
v3: Rebase after Mika's ppgtt cleanup / scratch merge patch series. Rely on
the added macros to initialize the pdps.
v4: Rebase after final merged version of Mika's ppgtt/scratch patches
(and removed commit message part related to v3).

Suggested-by: Akash Goel <akash.g...@intel.com>
Signed-off-by: Michel Thierry <michel.thie...@intel.com>
---
 drivers/gpu/drm/i915/i915_gem_gtt.c | 41 +++++++++++++++++++++++++++++++++++--
 drivers/gpu/drm/i915/i915_gem_gtt.h |  1 +
 2 files changed, 40 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c 
b/drivers/gpu/drm/i915/i915_gem_gtt.c
index f12e2b6..eb724b7 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -603,6 +603,27 @@ static void free_pdp(struct drm_device *dev,
        }
 }
 
+static void gen8_initialize_pdp(struct i915_address_space *vm,
+                               struct i915_page_directory_pointer *pdp)
+{
+       gen8_ppgtt_pdpe_t scratch_pdpe;
+
+       scratch_pdpe = gen8_pdpe_encode(px_dma(vm->scratch_pd), I915_CACHE_LLC);
+
+       fill_px(vm->dev, pdp, scratch_pdpe);
+}
+
+static void gen8_initialize_pml4(struct i915_address_space *vm,
+                                struct i915_pml4 *pml4)
+{
+       gen8_ppgtt_pml4e_t scratch_pml4e;
+
+       scratch_pml4e = gen8_pml4e_encode(px_dma(vm->scratch_pdp),
+                                         I915_CACHE_LLC);
+
+       fill_px(vm->dev, pml4, scratch_pml4e);
+}
+
 static void
 gen8_setup_page_directory(struct i915_hw_ppgtt *ppgtt,
                          struct i915_page_directory_pointer *pdp,
@@ -864,8 +885,20 @@ static int gen8_init_scratch(struct i915_address_space *vm)
                return PTR_ERR(vm->scratch_pd);
        }
 
+       if (USES_FULL_48BIT_PPGTT(dev)) {
+               vm->scratch_pdp = alloc_pdp(dev);
+               if (IS_ERR(vm->scratch_pdp)) {
+                       free_pd(dev, vm->scratch_pd);
+                       free_pt(dev, vm->scratch_pt);
+                       free_scratch_page(dev, vm->scratch_page);
+                       return PTR_ERR(vm->scratch_pdp);
+               }
+       }
+
        gen8_initialize_pt(vm, vm->scratch_pt);
        gen8_initialize_pd(vm, vm->scratch_pd);
+       if (USES_FULL_48BIT_PPGTT(dev))
+               gen8_initialize_pdp(vm, vm->scratch_pdp);
 
        return 0;
 }
@@ -874,6 +907,8 @@ static void gen8_free_scratch(struct i915_address_space *vm)
 {
        struct drm_device *dev = vm->dev;
 
+       if (USES_FULL_48BIT_PPGTT(dev))
+               free_pdp(dev, vm->scratch_pdp);
        free_pd(dev, vm->scratch_pd);
        free_pt(dev, vm->scratch_pt);
        free_scratch_page(dev, vm->scratch_page);
@@ -1231,12 +1266,12 @@ static int gen8_alloc_va_range_4lvl(struct 
i915_address_space *vm,
         * and 4 level code. Just allocate the pdps.
         */
        gen8_for_each_pml4e(pdp, pml4, start, length, temp, pml4e) {
-               if (!pdp) {
-                       WARN_ON(test_bit(pml4e, pml4->used_pml4es));
+               if (!test_bit(pml4e, pml4->used_pml4es)) {
                        pdp = alloc_pdp(vm->dev);
                        if (IS_ERR(pdp))
                                goto err_out;
 
+                       gen8_initialize_pdp(vm, pdp);
                        pml4->pdps[pml4e] = pdp;
                        __set_bit(pml4e, new_pdps);
                        trace_i915_page_directory_pointer_entry_alloc(vm,
@@ -1315,6 +1350,8 @@ static int gen8_ppgtt_init(struct i915_hw_ppgtt *ppgtt)
                if (ret)
                        goto free_scratch;
 
+               gen8_initialize_pml4(&ppgtt->base, &ppgtt->pml4);
+
                ppgtt->base.total = 1ULL << 48;
                ppgtt->switch_mm = gen8_48b_mm_switch;
        } else {
diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.h 
b/drivers/gpu/drm/i915/i915_gem_gtt.h
index ae9463e..99815c9 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.h
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.h
@@ -278,6 +278,7 @@ struct i915_address_space {
        struct i915_page_scratch *scratch_page;
        struct i915_page_table *scratch_pt;
        struct i915_page_directory *scratch_pd;
+       struct i915_page_directory_pointer *scratch_pdp; /* GEN8+ & 48b PPGTT */
 
        /**
         * List of objects currently involved in rendering.
-- 
2.4.5

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

Reply via email to