summaryrefslogtreecommitdiff
path: root/lib/intel_batchbuffer.c
diff options
context:
space:
mode:
authorZbigniew Kempczyński <zbigniew.kempczynski@intel.com>2020-09-11 10:07:24 +0200
committerChris Wilson <chris@chris-wilson.co.uk>2020-09-16 14:15:22 +0100
commita86802d988c1aeda34ac2911200213a48b934117 (patch)
tree12c07e1c0bca8cefc3a3e71e3ee5551722a35f1a /lib/intel_batchbuffer.c
parenta13282d661bb5af9e6aa61317924b340b0a650e8 (diff)
lib/intel_batchbuffer: use canonical addresses for 48bit ppgtt
For all EXEC_OBJECT_PINNED objects we need to be sure address passed must be in canonical form. Until IGT allocator will be written just limit 48 and 47 bit gtt tables to 46 bit only. We don't want to play with canonical addresses with 47-bit set to 1 (and then 63:48). Signed-off-by: Zbigniew Kempczyński <zbigniew.kempczynski@intel.com> Cc: Dominik Grzegorzek <dominik.grzegorzek@intel.com> Cc: Chris Wilson <chris@chris-wilson.co.uk> Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk> Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Diffstat (limited to 'lib/intel_batchbuffer.c')
-rw-r--r--lib/intel_batchbuffer.c37
1 files changed, 32 insertions, 5 deletions
diff --git a/lib/intel_batchbuffer.c b/lib/intel_batchbuffer.c
index 29932e1b..23355c07 100644
--- a/lib/intel_batchbuffer.c
+++ b/lib/intel_batchbuffer.c
@@ -1205,6 +1205,20 @@ static void __reallocate_objects(struct intel_bb *ibb)
}
}
+/*
+ * gen8_canonical_addr
+ * Used to convert any address into canonical form, i.e. [63:48] == [47].
+ * Based on kernel's sign_extend64 implementation.
+ * @address - a virtual address
+ */
+#define GEN8_HIGH_ADDRESS_BIT 47
+static uint64_t gen8_canonical_addr(uint64_t address)
+{
+ int shift = 63 - GEN8_HIGH_ADDRESS_BIT;
+
+ return (int64_t)(address << shift) >> shift;
+}
+
static inline uint64_t __intel_bb_propose_offset(struct intel_bb *ibb)
{
uint64_t offset;
@@ -1217,6 +1231,7 @@ static inline uint64_t __intel_bb_propose_offset(struct intel_bb *ibb)
offset += 256 << 10; /* Keep the low 256k clear, for negative deltas */
offset &= ibb->gtt_size - 1;
offset &= ~(ibb->alignment - 1);
+ offset = gen8_canonical_addr(offset);
return offset;
}
@@ -1254,9 +1269,21 @@ __intel_bb_create(int i915, uint32_t size, bool do_relocs)
gtt_size = gem_aperture_size(i915);
if (!gem_uses_full_ppgtt(i915))
gtt_size /= 2;
- if ((gtt_size - 1) >> 32)
+ if ((gtt_size - 1) >> 32) {
ibb->supports_48b_address = true;
+ /*
+ * Until we develop IGT address allocator we workaround
+ * playing with canonical addresses with 47-bit set to 1
+ * just by limiting gtt size to 46-bit when gtt is 47 or 48
+ * bit size. Current interface doesn't pass bo size, so
+ * limiting to 46 bit make us sure we won't enter to
+ * addresses with 47-bit set (we use 32-bit size now so
+ * still we fit 47-bit address space).
+ */
+ if (gtt_size & (3ull << 47))
+ gtt_size = (1ull << 46);
+ }
ibb->gtt_size = gtt_size;
__reallocate_objects(ibb);
@@ -1525,7 +1552,11 @@ intel_bb_add_object(struct intel_bb *ibb, uint32_t handle,
i = ibb->num_objects;
object = &ibb->objects[i];
object->handle = handle;
+
+ /* Limit current offset to gtt size */
object->offset = offset;
+ if (offset != INTEL_BUF_INVALID_ADDRESS)
+ object->offset = gen8_canonical_addr(offset & (ibb->gtt_size - 1));
object->alignment = ibb->alignment;
found = tsearch((void *) object, &ibb->root, __compare_objects);
@@ -1863,8 +1894,6 @@ static void intel_bb_dump_execbuf(struct intel_bb *ibb,
from_user_pointer(execbuf->buffers_ptr))[i];
relocs = from_user_pointer(objects->relocs_ptr);
address = objects->offset;
- if (address != INTEL_BUF_INVALID_ADDRESS)
- address = address & (ibb->gtt_size - 1);
igt_info(" [%d] handle: %u, reloc_count: %d, reloc_ptr: %p, "
"align: 0x%llx, offset: 0x%" PRIx64 ", flags: 0x%llx, "
"rsvd1: 0x%llx, rsvd2: 0x%llx\n",
@@ -1879,8 +1908,6 @@ static void intel_bb_dump_execbuf(struct intel_bb *ibb,
for (j = 0; j < objects->relocation_count; j++) {
reloc = &relocs[j];
address = reloc->presumed_offset;
- if (address != INTEL_BUF_INVALID_ADDRESS)
- address = address & (ibb->gtt_size - 1);
igt_info("\t [%d] target handle: %u, "
"offset: 0x%llx, delta: 0x%x, "
"presumed_offset: 0x%" PRIx64 ", "