Commit 69edc390 authored by Daniele Ceraolo Spurio's avatar Daniele Ceraolo Spurio Committed by Chris Wilson

drm/i915/ggtt: do not set bits 1-11 in gen12 ptes

On TGL, bits 2-4 in the GGTT PTE are not ignored anymore and are
instead used for some extra VT-d capabilities. We don't (yet?) have
support for those capabilities, but, given that we shared the pte_encode
function betweed GGTT and PPGTT, we still set those bits to the PPGTT
PPAT values. The DMA engine gets very confused when those bits are
set while the iommu is enabled, leading to errors. E.g. when loading
the GuC we get:

[    9.796218] DMAR: DRHD: handling fault status reg 2
[    9.796235] DMAR: [DMA Write] Request device [00:02.0] PASID ffffffff fault addr 0 [fault reason 02] Present bit in context entry is clear
[    9.899215] [drm:intel_guc_fw_upload [i915]] *ERROR* GuC firmware signature verification failed

To fix this, just have dedicated gen8_pte_encode function per type of
gtt. Also, explicitly set vm->pte_encode for gen8_ppgtt, even if we
don't use it, to make sure we don't accidentally assign it to the GGTT
one, like we do for gen6_ppgtt, in case we need it in the future.
Reported-by: default avatar"Sodhi, Vunny" <vunny.sodhi@intel.com>
Signed-off-by: default avatarDaniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
Cc: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Mika Kuoppala <mika.kuoppala@linux.intel.com>
Cc: Matthew Auld <matthew.auld@intel.com>
Cc: Michal Wajdeczko <michal.wajdeczko@intel.com>
Reviewed-by: default avatarMika Kuoppala <mika.kuoppala@linux.intel.com>
Signed-off-by: default avatarChris Wilson <chris@chris-wilson.co.uk>
Link: https://patchwork.freedesktop.org/patch/msgid/20200226185657.26445-1-daniele.ceraolospurio@intel.com
parent e94bda14
...@@ -25,6 +25,30 @@ static u64 gen8_pde_encode(const dma_addr_t addr, ...@@ -25,6 +25,30 @@ static u64 gen8_pde_encode(const dma_addr_t addr,
return pde; return pde;
} }
static u64 gen8_pte_encode(dma_addr_t addr,
enum i915_cache_level level,
u32 flags)
{
gen8_pte_t pte = addr | _PAGE_PRESENT | _PAGE_RW;
if (unlikely(flags & PTE_READ_ONLY))
pte &= ~_PAGE_RW;
switch (level) {
case I915_CACHE_NONE:
pte |= PPAT_UNCACHED;
break;
case I915_CACHE_WT:
pte |= PPAT_DISPLAY_ELLC;
break;
default:
pte |= PPAT_CACHED;
break;
}
return pte;
}
static void gen8_ppgtt_notify_vgt(struct i915_ppgtt *ppgtt, bool create) static void gen8_ppgtt_notify_vgt(struct i915_ppgtt *ppgtt, bool create)
{ {
struct drm_i915_private *i915 = ppgtt->vm.i915; struct drm_i915_private *i915 = ppgtt->vm.i915;
...@@ -706,6 +730,8 @@ struct i915_ppgtt *gen8_ppgtt_create(struct intel_gt *gt) ...@@ -706,6 +730,8 @@ struct i915_ppgtt *gen8_ppgtt_create(struct intel_gt *gt)
ppgtt->vm.allocate_va_range = gen8_ppgtt_alloc; ppgtt->vm.allocate_va_range = gen8_ppgtt_alloc;
ppgtt->vm.clear_range = gen8_ppgtt_clear; ppgtt->vm.clear_range = gen8_ppgtt_clear;
ppgtt->vm.pte_encode = gen8_pte_encode;
if (intel_vgpu_active(gt->i915)) if (intel_vgpu_active(gt->i915))
gen8_ppgtt_notify_vgt(ppgtt, true); gen8_ppgtt_notify_vgt(ppgtt, true);
......
...@@ -159,6 +159,13 @@ static void gmch_ggtt_invalidate(struct i915_ggtt *ggtt) ...@@ -159,6 +159,13 @@ static void gmch_ggtt_invalidate(struct i915_ggtt *ggtt)
intel_gtt_chipset_flush(); intel_gtt_chipset_flush();
} }
static u64 gen8_ggtt_pte_encode(dma_addr_t addr,
enum i915_cache_level level,
u32 flags)
{
return addr | _PAGE_PRESENT;
}
static void gen8_set_pte(void __iomem *addr, gen8_pte_t pte) static void gen8_set_pte(void __iomem *addr, gen8_pte_t pte)
{ {
writeq(pte, addr); writeq(pte, addr);
...@@ -174,7 +181,7 @@ static void gen8_ggtt_insert_page(struct i915_address_space *vm, ...@@ -174,7 +181,7 @@ static void gen8_ggtt_insert_page(struct i915_address_space *vm,
gen8_pte_t __iomem *pte = gen8_pte_t __iomem *pte =
(gen8_pte_t __iomem *)ggtt->gsm + offset / I915_GTT_PAGE_SIZE; (gen8_pte_t __iomem *)ggtt->gsm + offset / I915_GTT_PAGE_SIZE;
gen8_set_pte(pte, gen8_pte_encode(addr, level, 0)); gen8_set_pte(pte, gen8_ggtt_pte_encode(addr, level, 0));
ggtt->invalidate(ggtt); ggtt->invalidate(ggtt);
} }
...@@ -187,7 +194,7 @@ static void gen8_ggtt_insert_entries(struct i915_address_space *vm, ...@@ -187,7 +194,7 @@ static void gen8_ggtt_insert_entries(struct i915_address_space *vm,
struct i915_ggtt *ggtt = i915_vm_to_ggtt(vm); struct i915_ggtt *ggtt = i915_vm_to_ggtt(vm);
struct sgt_iter sgt_iter; struct sgt_iter sgt_iter;
gen8_pte_t __iomem *gtt_entries; gen8_pte_t __iomem *gtt_entries;
const gen8_pte_t pte_encode = gen8_pte_encode(0, level, 0); const gen8_pte_t pte_encode = gen8_ggtt_pte_encode(0, level, 0);
dma_addr_t addr; dma_addr_t addr;
/* /*
...@@ -859,7 +866,7 @@ static int gen8_gmch_probe(struct i915_ggtt *ggtt) ...@@ -859,7 +866,7 @@ static int gen8_gmch_probe(struct i915_ggtt *ggtt)
ggtt->vm.vma_ops.set_pages = ggtt_set_pages; ggtt->vm.vma_ops.set_pages = ggtt_set_pages;
ggtt->vm.vma_ops.clear_pages = clear_pages; ggtt->vm.vma_ops.clear_pages = clear_pages;
ggtt->vm.pte_encode = gen8_pte_encode; ggtt->vm.pte_encode = gen8_ggtt_pte_encode;
setup_private_pat(ggtt->vm.gt->uncore); setup_private_pat(ggtt->vm.gt->uncore);
......
...@@ -484,30 +484,6 @@ void gtt_write_workarounds(struct intel_gt *gt) ...@@ -484,30 +484,6 @@ void gtt_write_workarounds(struct intel_gt *gt)
} }
} }
u64 gen8_pte_encode(dma_addr_t addr,
enum i915_cache_level level,
u32 flags)
{
gen8_pte_t pte = addr | _PAGE_PRESENT | _PAGE_RW;
if (unlikely(flags & PTE_READ_ONLY))
pte &= ~_PAGE_RW;
switch (level) {
case I915_CACHE_NONE:
pte |= PPAT_UNCACHED;
break;
case I915_CACHE_WT:
pte |= PPAT_DISPLAY_ELLC;
break;
default:
pte |= PPAT_CACHED;
break;
}
return pte;
}
static void tgl_setup_private_ppat(struct intel_uncore *uncore) static void tgl_setup_private_ppat(struct intel_uncore *uncore)
{ {
/* TGL doesn't support LLC or AGE settings */ /* TGL doesn't support LLC or AGE settings */
......
...@@ -515,10 +515,6 @@ struct i915_ppgtt *i915_ppgtt_create(struct intel_gt *gt); ...@@ -515,10 +515,6 @@ struct i915_ppgtt *i915_ppgtt_create(struct intel_gt *gt);
void i915_ggtt_suspend(struct i915_ggtt *gtt); void i915_ggtt_suspend(struct i915_ggtt *gtt);
void i915_ggtt_resume(struct i915_ggtt *ggtt); void i915_ggtt_resume(struct i915_ggtt *ggtt);
u64 gen8_pte_encode(dma_addr_t addr,
enum i915_cache_level level,
u32 flags);
int setup_page_dma(struct i915_address_space *vm, struct i915_page_dma *p); int setup_page_dma(struct i915_address_space *vm, struct i915_page_dma *p);
void cleanup_page_dma(struct i915_address_space *vm, struct i915_page_dma *p); void cleanup_page_dma(struct i915_address_space *vm, struct i915_page_dma *p);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment