drm/i915/ttm: implement access_memory
It looks like we need this for local-memory, if we want to use ptrace. Something more is still needed if we want to handle non-mappable memory, which looks quite annoying. v2: - ttm_bo_kmap doesn't seem to work well here, and seems to expect contiguous resource. v3(Andi): - s/PAGE_SIZE/bytes/ when passing in the size of the mapping. References: https://gitlab.freedesktop.org/drm/intel/-/issues/6989 Signed-off-by: Matthew Auld <matthew.auld@intel.com> Cc: Andrzej Hajda <andrzej.hajda@intel.com> Cc: Nirmoy Das <nirmoy.das@intel.com> Cc: Andi Shyti <andi.shyti@linux.intel.com> Reviewed-by: Andi Shyti <andi.shyti@linux.intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20221003172819.99245-1-matthew.auld@intel.com
This commit is contained in:
parent
c24538f538
commit
26b15eb094
@ -699,6 +699,50 @@ static unsigned long i915_ttm_io_mem_pfn(struct ttm_buffer_object *bo,
|
||||
return ((base + sg_dma_address(sg)) >> PAGE_SHIFT) + ofs;
|
||||
}
|
||||
|
||||
static int i915_ttm_access_memory(struct ttm_buffer_object *bo,
|
||||
unsigned long offset, void *buf,
|
||||
int len, int write)
|
||||
{
|
||||
struct drm_i915_gem_object *obj = i915_ttm_to_gem(bo);
|
||||
resource_size_t iomap = obj->mm.region->iomap.base -
|
||||
obj->mm.region->region.start;
|
||||
unsigned long page = offset >> PAGE_SHIFT;
|
||||
unsigned long bytes_left = len;
|
||||
|
||||
/*
|
||||
* TODO: For now just let it fail if the resource is non-mappable,
|
||||
* otherwise we need to perform the memcpy from the gpu here, without
|
||||
* interfering with the object (like moving the entire thing).
|
||||
*/
|
||||
if (!i915_ttm_resource_mappable(bo->resource))
|
||||
return -EIO;
|
||||
|
||||
offset -= page << PAGE_SHIFT;
|
||||
do {
|
||||
unsigned long bytes = min(bytes_left, PAGE_SIZE - offset);
|
||||
void __iomem *ptr;
|
||||
dma_addr_t daddr;
|
||||
|
||||
daddr = i915_gem_object_get_dma_address(obj, page);
|
||||
ptr = ioremap_wc(iomap + daddr + offset, bytes);
|
||||
if (!ptr)
|
||||
return -EIO;
|
||||
|
||||
if (write)
|
||||
memcpy_toio(ptr, buf, bytes);
|
||||
else
|
||||
memcpy_fromio(buf, ptr, bytes);
|
||||
iounmap(ptr);
|
||||
|
||||
page++;
|
||||
buf += bytes;
|
||||
bytes_left -= bytes;
|
||||
offset = 0;
|
||||
} while (bytes_left);
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
/*
|
||||
* All callbacks need to take care not to downcast a struct ttm_buffer_object
|
||||
* without checking its subclass, since it might be a TTM ghost object.
|
||||
@ -715,6 +759,7 @@ static struct ttm_device_funcs i915_ttm_bo_driver = {
|
||||
.delete_mem_notify = i915_ttm_delete_mem_notify,
|
||||
.io_mem_reserve = i915_ttm_io_mem_reserve,
|
||||
.io_mem_pfn = i915_ttm_io_mem_pfn,
|
||||
.access_memory = i915_ttm_access_memory,
|
||||
};
|
||||
|
||||
/**
|
||||
|
Loading…
x
Reference in New Issue
Block a user