drm-shim: Better mmap offsets
Using the bo pointer address as the offset doesn't go over well when someone is fuzzing you. But we already have the mem_addr, we can simply use that instead. Signed-off-by: Rob Clark <robdclark@chromium.org> Reviewed-by: Emma Anholt <emma@anholt.net> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/16250>
This commit is contained in:
parent
97f4e48717
commit
c4b5ebe1fc
|
@ -82,6 +82,8 @@ drm_shim_device_init(void)
|
|||
uint_key_hash,
|
||||
uint_key_compare);
|
||||
|
||||
shim_device.offset_map = _mesa_hash_table_u64_create(NULL);
|
||||
|
||||
mtx_init(&shim_device.mem_lock, mtx_plain);
|
||||
|
||||
shim_device.mem_fd = memfd_create("shim mem", MFD_CLOEXEC);
|
||||
|
@ -372,18 +374,16 @@ drm_shim_bo_get_handle(struct shim_fd *shim_fd, struct shim_bo *bo)
|
|||
}
|
||||
|
||||
/* Creates an mmap offset for the BO in the DRM fd.
|
||||
*
|
||||
* XXX: We should be maintaining a u_mm allocator where the mmap offsets
|
||||
* allocate the size of the BO and it can be used to look the BO back up.
|
||||
* Instead, we just stuff the shim's pointer as the return value, and treat
|
||||
* the incoming mmap offset on the DRM fd as a BO pointer. This doesn't work
|
||||
* if someone tries to map a subset of the BO, but it's enough to get V3D
|
||||
* working for now.
|
||||
*/
|
||||
uint64_t
|
||||
drm_shim_bo_get_mmap_offset(struct shim_fd *shim_fd, struct shim_bo *bo)
|
||||
{
|
||||
return (uintptr_t)bo;
|
||||
mtx_lock(&shim_device.mem_lock);
|
||||
_mesa_hash_table_u64_insert(shim_device.offset_map, bo->mem_addr, bo);
|
||||
mtx_unlock(&shim_device.mem_lock);
|
||||
|
||||
/* reuse the buffer address as the mmap offset: */
|
||||
return bo->mem_addr;
|
||||
}
|
||||
|
||||
/* For mmap() on the DRM fd, look up the BO from the "offset" and map the BO's
|
||||
|
@ -393,7 +393,15 @@ void *
|
|||
drm_shim_mmap(struct shim_fd *shim_fd, size_t length, int prot, int flags,
|
||||
int fd, off64_t offset)
|
||||
{
|
||||
struct shim_bo *bo = (void *)(uintptr_t)offset;
|
||||
mtx_lock(&shim_device.mem_lock);
|
||||
struct shim_bo *bo = _mesa_hash_table_u64_search(shim_device.offset_map, offset);
|
||||
mtx_unlock(&shim_device.mem_lock);
|
||||
|
||||
if (!bo)
|
||||
return MAP_FAILED;
|
||||
|
||||
if (length > bo->size)
|
||||
return MAP_FAILED;
|
||||
|
||||
/* The offset we pass to mmap must be aligned to the page size */
|
||||
assert((bo->mem_addr & (shim_page_size - 1)) == 0);
|
||||
|
|
|
@ -41,6 +41,9 @@ struct shim_device {
|
|||
/* Mapping from int fd to struct shim_fd *. */
|
||||
struct hash_table *fd_map;
|
||||
|
||||
/* Mapping from mmap offset to shim_bo */
|
||||
struct hash_table_u64 *offset_map;
|
||||
|
||||
mtx_t mem_lock;
|
||||
/* Heap from which shim_bo are allocated */
|
||||
struct util_vma_heap mem_heap;
|
||||
|
|
|
@ -120,7 +120,8 @@ i915_ioctl_gem_mmap(int fd, unsigned long request, void *arg)
|
|||
return -1;
|
||||
|
||||
if (!bo->map)
|
||||
bo->map = drm_shim_mmap(shim_fd, bo->size, PROT_READ | PROT_WRITE, MAP_SHARED, -1, (uintptr_t)bo);
|
||||
bo->map = drm_shim_mmap(shim_fd, bo->size, PROT_READ | PROT_WRITE, MAP_SHARED, -1,
|
||||
drm_shim_bo_get_mmap_offset(shim_fd, bo));
|
||||
|
||||
mmap_arg->addr_ptr = (uint64_t) (bo->map + mmap_arg->offset);
|
||||
|
||||
|
|
Loading…
Reference in New Issue