summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonathan Gray <jsg@cvs.openbsd.org>2023-10-09 02:35:48 +0000
committerJonathan Gray <jsg@cvs.openbsd.org>2023-10-09 02:35:48 +0000
commit43b2ee8e3695d6d6ad33179afad8d0282208ebc8 (patch)
tree90a7189b1ba385125b121370c08b03bfa43555ba
parentea78bd0e1b1bcc9c80bd462e14ae15de8024ff28 (diff)
drm/i915/gt: Fix reservation address in ggtt_reserve_guc_top
From Javier Pello 69dd84470b4deed45658f2717aef533ec4ceb43d in linux-6.1.y/6.1.56 b7599d241778d0b10cdf7a5c755aa7db9b83250c in mainline linux
-rw-r--r--sys/dev/pci/drm/i915/gt/intel_ggtt.c23
1 files changed, 17 insertions, 6 deletions
diff --git a/sys/dev/pci/drm/i915/gt/intel_ggtt.c b/sys/dev/pci/drm/i915/gt/intel_ggtt.c
index ec9465e26fa..96fc3dd2398 100644
--- a/sys/dev/pci/drm/i915/gt/intel_ggtt.c
+++ b/sys/dev/pci/drm/i915/gt/intel_ggtt.c
@@ -529,20 +529,31 @@ void intel_ggtt_unbind_vma(struct i915_address_space *vm,
vm->clear_range(vm, vma_res->start, vma_res->vma_size);
}
+/*
+ * Reserve the top of the GuC address space for firmware images. Addresses
+ * beyond GUC_GGTT_TOP in the GuC address space are inaccessible by GuC,
+ * which makes for a suitable range to hold GuC/HuC firmware images if the
+ * size of the GGTT is 4G. However, on a 32-bit platform the size of the GGTT
+ * is limited to 2G, which is less than GUC_GGTT_TOP, but we reserve a chunk
+ * of the same size anyway, which is far more than needed, to keep the logic
+ * in uc_fw_ggtt_offset() simple.
+ */
+#define GUC_TOP_RESERVE_SIZE (SZ_4G - GUC_GGTT_TOP)
+
static int ggtt_reserve_guc_top(struct i915_ggtt *ggtt)
{
- u64 size;
+ u64 offset;
int ret;
if (!intel_uc_uses_guc(&ggtt->vm.gt->uc))
return 0;
- GEM_BUG_ON(ggtt->vm.total <= GUC_GGTT_TOP);
- size = ggtt->vm.total - GUC_GGTT_TOP;
+ GEM_BUG_ON(ggtt->vm.total <= GUC_TOP_RESERVE_SIZE);
+ offset = ggtt->vm.total - GUC_TOP_RESERVE_SIZE;
- ret = i915_gem_gtt_reserve(&ggtt->vm, NULL, &ggtt->uc_fw, size,
- GUC_GGTT_TOP, I915_COLOR_UNEVICTABLE,
- PIN_NOEVICT);
+ ret = i915_gem_gtt_reserve(&ggtt->vm, NULL, &ggtt->uc_fw,
+ GUC_TOP_RESERVE_SIZE, offset,
+ I915_COLOR_UNEVICTABLE, PIN_NOEVICT);
if (ret)
drm_dbg(&ggtt->vm.i915->drm,
"Failed to reserve top of GGTT for GuC\n");