According to bspec, some parts of HW expect the addresses to be in
a canonical form where bits [63:48] == [47]. Lets satisfy the HW by
converting the address prior to allocating/clearing the entries in page
tables.

Cc: Michel Thierry <[email protected]>
Cc: Mika Kuoppala <[email protected]>
Signed-off-by: Michał Winiarski <[email protected]>
---
 drivers/gpu/drm/i915/i915_gem_gtt.c | 13 +++++++------
 drivers/gpu/drm/i915/i915_gem_gtt.h |  5 +++++
 2 files changed, 12 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c 
b/drivers/gpu/drm/i915/i915_gem_gtt.c
index 7ff7239..f25a33f 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -766,6 +766,7 @@ static void gen8_ppgtt_clear_range(struct 
i915_address_space *vm,
        } else {
                uint64_t templ4, pml4e;
                struct i915_page_directory_pointer *pdp;
+               start = gen8_canonical_addr(start);
 
                gen8_for_each_pml4e(pdp, &ppgtt->pml4, start, length, templ4, 
pml4e) {
                        gen8_ppgtt_clear_pte_range(vm, pdp, start, length,
@@ -1227,15 +1228,10 @@ static int gen8_alloc_va_range_3lvl(struct 
i915_address_space *vm,
        uint32_t pdpes = I915_PDPES_PER_PDP(dev);
        int ret;
 
-       /* Wrap is never okay since we can only represent 48b, and we don't
-        * actually use the other side of the canonical address space.
-        */
+       /* Wrap is never okay */
        if (WARN_ON(start + length < start))
                return -ENODEV;
 
-       if (WARN_ON(start + length > vm->total))
-               return -ENODEV;
-
        ret = alloc_gen8_temp_bitmaps(&new_page_dirs, &new_page_tables, pdpes);
        if (ret)
                return ret;
@@ -1333,6 +1329,8 @@ static int gen8_alloc_va_range_4lvl(struct 
i915_address_space *vm,
        uint64_t temp, pml4e;
        int ret = 0;
 
+       start = gen8_canonical_addr(start);
+
        /* Do the pml4 allocations first, so we don't need to track the newly
         * allocated tables below the pdp */
        bitmap_zero(new_pdps, GEN8_PML4ES_PER_PML4);
@@ -1377,6 +1375,9 @@ static int gen8_alloc_va_range(struct i915_address_space 
*vm,
        struct i915_hw_ppgtt *ppgtt =
                container_of(vm, struct i915_hw_ppgtt, base);
 
+       if (WARN_ON(start + length > vm->total))
+               return -ENODEV;
+
        if (USES_FULL_48BIT_PPGTT(vm->dev))
                return gen8_alloc_va_range_4lvl(vm, &ppgtt->pml4, start, 
length);
        else
diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.h 
b/drivers/gpu/drm/i915/i915_gem_gtt.h
index 8275007..9397387 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.h
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.h
@@ -503,6 +503,11 @@ static inline size_t gen8_pte_count(uint64_t address, 
uint64_t length)
        return i915_pte_count(address, length, GEN8_PDE_SHIFT);
 }
 
+static inline uint64_t gen8_canonical_addr(uint64_t address)
+{
+       return ((int64_t)address << 16) >> 16;
+}
+
 static inline dma_addr_t
 i915_page_dir_dma_addr(const struct i915_hw_ppgtt *ppgtt, const unsigned n)
 {
-- 
2.4.3

_______________________________________________
Intel-gfx mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

Reply via email to