Skip to content

Commit 12bed14

Browse files
committed
drm/vmwgfx: Add basic support for external buffers
Make vmwgfx go through the dma-buf interface to map/unmap imported buffers. The driver used to try to directly manipulate external buffers, assuming that everything that was coming to it had to live in cpu accessible memory. While technically true because what's in the vms is controlled by us, it's semantically completely broken. Fix importing of external buffers by forwarding all memory access requests to the importer. Tested by the vmw_prime basic_vgem test. Signed-off-by: Zack Rusin <[email protected]> Reviewed-by: Maaz Mombasawala <[email protected]> Reviewed-by: Martin Krastev <[email protected]> Link: https://patchwork.freedesktop.org/patch/msgid/[email protected]
1 parent d6667f0 commit 12bed14

File tree

1 file changed

+58
-4
lines changed

1 file changed

+58
-4
lines changed

drivers/gpu/drm/vmwgfx/vmwgfx_gem.c

Lines changed: 58 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
/* SPDX-License-Identifier: GPL-2.0 OR MIT */
22
/*
3-
* Copyright 2021-2023 VMware, Inc.
3+
* Copyright (c) 2021-2024 Broadcom. All Rights Reserved. The term
4+
* “Broadcom” refers to Broadcom Inc. and/or its subsidiaries.
45
*
56
* Permission is hereby granted, free of charge, to any person
67
* obtaining a copy of this software and associated documentation
@@ -78,6 +79,59 @@ static struct sg_table *vmw_gem_object_get_sg_table(struct drm_gem_object *obj)
7879
return drm_prime_pages_to_sg(obj->dev, vmw_tt->dma_ttm.pages, vmw_tt->dma_ttm.num_pages);
7980
}
8081

82+
static int vmw_gem_vmap(struct drm_gem_object *obj, struct iosys_map *map)
83+
{
84+
struct ttm_buffer_object *bo = drm_gem_ttm_of_gem(obj);
85+
int ret;
86+
87+
if (obj->import_attach) {
88+
ret = dma_buf_vmap(obj->import_attach->dmabuf, map);
89+
if (!ret) {
90+
if (drm_WARN_ON(obj->dev, map->is_iomem)) {
91+
dma_buf_vunmap(obj->import_attach->dmabuf, map);
92+
return -EIO;
93+
}
94+
}
95+
} else {
96+
ret = ttm_bo_vmap(bo, map);
97+
}
98+
99+
return ret;
100+
}
101+
102+
static void vmw_gem_vunmap(struct drm_gem_object *obj, struct iosys_map *map)
103+
{
104+
if (obj->import_attach)
105+
dma_buf_vunmap(obj->import_attach->dmabuf, map);
106+
else
107+
drm_gem_ttm_vunmap(obj, map);
108+
}
109+
110+
static int vmw_gem_mmap(struct drm_gem_object *obj, struct vm_area_struct *vma)
111+
{
112+
int ret;
113+
114+
if (obj->import_attach) {
115+
/*
116+
* Reset both vm_ops and vm_private_data, so we don't end up with
117+
* vm_ops pointing to our implementation if the dma-buf backend
118+
* doesn't set those fields.
119+
*/
120+
vma->vm_private_data = NULL;
121+
vma->vm_ops = NULL;
122+
123+
ret = dma_buf_mmap(obj->dma_buf, vma, 0);
124+
125+
/* Drop the reference drm_gem_mmap_obj() acquired.*/
126+
if (!ret)
127+
drm_gem_object_put(obj);
128+
129+
return ret;
130+
}
131+
132+
return drm_gem_ttm_mmap(obj, vma);
133+
}
134+
81135
static const struct vm_operations_struct vmw_vm_ops = {
82136
.pfn_mkwrite = vmw_bo_vm_mkwrite,
83137
.page_mkwrite = vmw_bo_vm_mkwrite,
@@ -94,9 +148,9 @@ static const struct drm_gem_object_funcs vmw_gem_object_funcs = {
94148
.pin = vmw_gem_object_pin,
95149
.unpin = vmw_gem_object_unpin,
96150
.get_sg_table = vmw_gem_object_get_sg_table,
97-
.vmap = drm_gem_ttm_vmap,
98-
.vunmap = drm_gem_ttm_vunmap,
99-
.mmap = drm_gem_ttm_mmap,
151+
.vmap = vmw_gem_vmap,
152+
.vunmap = vmw_gem_vunmap,
153+
.mmap = vmw_gem_mmap,
100154
.vm_ops = &vmw_vm_ops,
101155
};
102156

0 commit comments

Comments
 (0)