summaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/gpu/nvgpu/include/nvgpu/linux/vm.h6
-rw-r--r--drivers/gpu/nvgpu/os/linux/cde.c29
-rw-r--r--drivers/gpu/nvgpu/os/linux/ioctl_as.c3
-rw-r--r--drivers/gpu/nvgpu/os/linux/ioctl_dbg.c3
-rw-r--r--drivers/gpu/nvgpu/os/linux/vm.c39
5 files changed, 65 insertions, 15 deletions
diff --git a/drivers/gpu/nvgpu/include/nvgpu/linux/vm.h b/drivers/gpu/nvgpu/include/nvgpu/linux/vm.h
index 97b8334b..6f3beaa9 100644
--- a/drivers/gpu/nvgpu/include/nvgpu/linux/vm.h
+++ b/drivers/gpu/nvgpu/include/nvgpu/linux/vm.h
@@ -54,8 +54,9 @@ struct nvgpu_mapped_buf_priv {
54/* NVGPU_AS_MAP_BUFFER_FLAGS_DIRECT_KIND_CTRL must be set */ 54/* NVGPU_AS_MAP_BUFFER_FLAGS_DIRECT_KIND_CTRL must be set */
55int nvgpu_vm_map_linux(struct vm_gk20a *vm, 55int nvgpu_vm_map_linux(struct vm_gk20a *vm,
56 struct dma_buf *dmabuf, 56 struct dma_buf *dmabuf,
57 u64 offset_align, 57 u64 map_addr,
58 u32 flags, 58 u32 flags,
59 u32 page_size,
59 s16 compr_kind, 60 s16 compr_kind,
60 s16 incompr_kind, 61 s16 incompr_kind,
61 int rw_flag, 62 int rw_flag,
@@ -71,8 +72,9 @@ int nvgpu_vm_map_linux(struct vm_gk20a *vm,
71 */ 72 */
72int nvgpu_vm_map_buffer(struct vm_gk20a *vm, 73int nvgpu_vm_map_buffer(struct vm_gk20a *vm,
73 int dmabuf_fd, 74 int dmabuf_fd,
74 u64 *offset_align, 75 u64 *map_addr,
75 u32 flags, /* NVGPU_AS_MAP_BUFFER_FLAGS_ */ 76 u32 flags, /* NVGPU_AS_MAP_BUFFER_FLAGS_ */
77 u32 page_size,
76 s16 compr_kind, 78 s16 compr_kind,
77 s16 incompr_kind, 79 s16 incompr_kind,
78 u64 buffer_offset, 80 u64 buffer_offset,
diff --git a/drivers/gpu/nvgpu/os/linux/cde.c b/drivers/gpu/nvgpu/os/linux/cde.c
index 66a80403..052a1d21 100644
--- a/drivers/gpu/nvgpu/os/linux/cde.c
+++ b/drivers/gpu/nvgpu/os/linux/cde.c
@@ -975,6 +975,30 @@ static struct gk20a_cde_ctx *gk20a_cde_allocate_context(struct nvgpu_os_linux *l
975 return cde_ctx; 975 return cde_ctx;
976} 976}
977 977
978static u32 gk20a_cde_mapping_page_size(struct vm_gk20a *vm,
979 u32 map_offset, u32 map_size)
980{
981 struct gk20a *g = gk20a_from_vm(vm);
982
983 /*
984 * To be simple we will just make the map size depend on the
985 * iommu'ability of the driver. If there's an IOMMU we can rely on
986 * buffers being contiguous. If not, then we'll use 4k pages since we
987 * know that will work for any buffer.
988 */
989 if (!nvgpu_iommuable(g))
990 return SZ_4K;
991
992 /*
993 * If map size or offset is not 64K aligned then use small pages.
994 */
995 if (map_size & (vm->big_page_size - 1) ||
996 map_offset & (vm->big_page_size - 1))
997 return SZ_4K;
998
999 return vm->big_page_size;
1000}
1001
978int gk20a_cde_convert(struct nvgpu_os_linux *l, 1002int gk20a_cde_convert(struct nvgpu_os_linux *l,
979 struct dma_buf *compbits_scatter_buf, 1003 struct dma_buf *compbits_scatter_buf,
980 u64 compbits_byte_offset, 1004 u64 compbits_byte_offset,
@@ -1071,7 +1095,10 @@ __releases(&l->cde_app->mutex)
1071 err = nvgpu_vm_map_linux(cde_ctx->vm, compbits_scatter_buf, 0, 1095 err = nvgpu_vm_map_linux(cde_ctx->vm, compbits_scatter_buf, 0,
1072 NVGPU_VM_MAP_CACHEABLE | 1096 NVGPU_VM_MAP_CACHEABLE |
1073 NVGPU_VM_MAP_DIRECT_KIND_CTRL, 1097 NVGPU_VM_MAP_DIRECT_KIND_CTRL,
1074 NVGPU_KIND_INVALID, 1098 gk20a_cde_mapping_page_size(cde_ctx->vm,
1099 map_offset,
1100 map_size),
1101 NV_KIND_INVALID,
1075 compbits_kind, /* incompressible kind */ 1102 compbits_kind, /* incompressible kind */
1076 gk20a_mem_flag_none, 1103 gk20a_mem_flag_none,
1077 map_offset, map_size, 1104 map_offset, map_size,
diff --git a/drivers/gpu/nvgpu/os/linux/ioctl_as.c b/drivers/gpu/nvgpu/os/linux/ioctl_as.c
index 47f612cc..5eb9802f 100644
--- a/drivers/gpu/nvgpu/os/linux/ioctl_as.c
+++ b/drivers/gpu/nvgpu/os/linux/ioctl_as.c
@@ -111,6 +111,7 @@ static int gk20a_as_ioctl_map_buffer_ex(
111 111
112 return nvgpu_vm_map_buffer(as_share->vm, args->dmabuf_fd, 112 return nvgpu_vm_map_buffer(as_share->vm, args->dmabuf_fd,
113 &args->offset, args->flags, 113 &args->offset, args->flags,
114 args->page_size,
114 args->compr_kind, 115 args->compr_kind,
115 args->incompr_kind, 116 args->incompr_kind,
116 args->buffer_offset, 117 args->buffer_offset,
@@ -201,7 +202,7 @@ static int gk20a_as_ioctl_map_buffer_batch(
201 202
202 err = nvgpu_vm_map_buffer( 203 err = nvgpu_vm_map_buffer(
203 as_share->vm, map_args.dmabuf_fd, 204 as_share->vm, map_args.dmabuf_fd,
204 &map_args.offset, map_args.flags, 205 &map_args.offset, map_args.flags, map_args.page_size,
205 compressible_kind, incompressible_kind, 206 compressible_kind, incompressible_kind,
206 map_args.buffer_offset, 207 map_args.buffer_offset,
207 map_args.mapping_size, 208 map_args.mapping_size,
diff --git a/drivers/gpu/nvgpu/os/linux/ioctl_dbg.c b/drivers/gpu/nvgpu/os/linux/ioctl_dbg.c
index 76ff25c0..938e0abd 100644
--- a/drivers/gpu/nvgpu/os/linux/ioctl_dbg.c
+++ b/drivers/gpu/nvgpu/os/linux/ioctl_dbg.c
@@ -1372,10 +1372,11 @@ static int gk20a_perfbuf_map(struct dbg_session_gk20a *dbg_s,
1372 args->dmabuf_fd, 1372 args->dmabuf_fd,
1373 &args->offset, 1373 &args->offset,
1374 0, 1374 0,
1375 SZ_4K,
1376 0,
1375 0, 1377 0,
1376 0, 1378 0,
1377 0, 1379 0,
1378 args->mapping_size,
1379 NULL); 1380 NULL);
1380 if (err) 1381 if (err)
1381 goto err_remove_vm; 1382 goto err_remove_vm;
diff --git a/drivers/gpu/nvgpu/os/linux/vm.c b/drivers/gpu/nvgpu/os/linux/vm.c
index baa77515..eb9ca8fd 100644
--- a/drivers/gpu/nvgpu/os/linux/vm.c
+++ b/drivers/gpu/nvgpu/os/linux/vm.c
@@ -175,8 +175,9 @@ struct nvgpu_mapped_buf *nvgpu_vm_find_mapping(struct vm_gk20a *vm,
175 175
176int nvgpu_vm_map_linux(struct vm_gk20a *vm, 176int nvgpu_vm_map_linux(struct vm_gk20a *vm,
177 struct dma_buf *dmabuf, 177 struct dma_buf *dmabuf,
178 u64 offset_align, 178 u64 map_addr,
179 u32 flags, 179 u32 flags,
180 u32 page_size,
180 s16 compr_kind, 181 s16 compr_kind,
181 s16 incompr_kind, 182 s16 incompr_kind,
182 int rw_flag, 183 int rw_flag,
@@ -192,12 +193,8 @@ int nvgpu_vm_map_linux(struct vm_gk20a *vm,
192 struct nvgpu_sgt *nvgpu_sgt = NULL; 193 struct nvgpu_sgt *nvgpu_sgt = NULL;
193 struct nvgpu_mapped_buf *mapped_buffer = NULL; 194 struct nvgpu_mapped_buf *mapped_buffer = NULL;
194 struct dma_buf_attachment *attachment; 195 struct dma_buf_attachment *attachment;
195 u64 map_addr = 0ULL;
196 int err = 0; 196 int err = 0;
197 197
198 if (flags & NVGPU_VM_MAP_FIXED_OFFSET)
199 map_addr = offset_align;
200
201 sgt = gk20a_mm_pin(dev, dmabuf, &attachment); 198 sgt = gk20a_mm_pin(dev, dmabuf, &attachment);
202 if (IS_ERR(sgt)) { 199 if (IS_ERR(sgt)) {
203 nvgpu_warn(g, "Failed to pin dma_buf!"); 200 nvgpu_warn(g, "Failed to pin dma_buf!");
@@ -253,8 +250,9 @@ clean_up:
253 250
254int nvgpu_vm_map_buffer(struct vm_gk20a *vm, 251int nvgpu_vm_map_buffer(struct vm_gk20a *vm,
255 int dmabuf_fd, 252 int dmabuf_fd,
256 u64 *offset_align, 253 u64 *map_addr,
257 u32 flags, /*NVGPU_AS_MAP_BUFFER_FLAGS_*/ 254 u32 flags, /*NVGPU_AS_MAP_BUFFER_FLAGS_*/
255 u32 page_size,
258 s16 compr_kind, 256 s16 compr_kind,
259 s16 incompr_kind, 257 s16 incompr_kind,
260 u64 buffer_offset, 258 u64 buffer_offset,
@@ -274,8 +272,28 @@ int nvgpu_vm_map_buffer(struct vm_gk20a *vm,
274 return PTR_ERR(dmabuf); 272 return PTR_ERR(dmabuf);
275 } 273 }
276 274
275 /*
276 * For regular maps we do not accept either an input address or a
277 * buffer_offset.
278 */
279 if (!(flags & NVGPU_AS_MAP_BUFFER_FLAGS_FIXED_OFFSET) &&
280 (buffer_offset || *map_addr)) {
281 nvgpu_err(g,
282 "Regular map with addr/buf offset is not supported!");
283 return -EINVAL;
284 }
285
286 /*
287 * Map size is always buffer size for non fixed mappings. As such map
288 * size should be left as zero by userspace for non-fixed maps.
289 */
290 if (mapping_size && !(flags & NVGPU_AS_MAP_BUFFER_FLAGS_FIXED_OFFSET)) {
291 nvgpu_err(g, "map_size && non-fixed-mapping!");
292 return -EINVAL;
293 }
294
277 /* verify that we're not overflowing the buffer, i.e. 295 /* verify that we're not overflowing the buffer, i.e.
278 * (buffer_offset + mapping_size)> dmabuf->size. 296 * (buffer_offset + mapping_size) > dmabuf->size.
279 * 297 *
280 * Since buffer_offset + mapping_size could overflow, first check 298 * Since buffer_offset + mapping_size could overflow, first check
281 * that mapping size < dmabuf_size, at which point we can subtract 299 * that mapping size < dmabuf_size, at which point we can subtract
@@ -284,7 +302,7 @@ int nvgpu_vm_map_buffer(struct vm_gk20a *vm,
284 if ((mapping_size > dmabuf->size) || 302 if ((mapping_size > dmabuf->size) ||
285 (buffer_offset > (dmabuf->size - mapping_size))) { 303 (buffer_offset > (dmabuf->size - mapping_size))) {
286 nvgpu_err(g, 304 nvgpu_err(g,
287 "buf size %llx < (offset(%llx) + map_size(%llx))\n", 305 "buf size %llx < (offset(%llx) + map_size(%llx))",
288 (u64)dmabuf->size, buffer_offset, mapping_size); 306 (u64)dmabuf->size, buffer_offset, mapping_size);
289 dma_buf_put(dmabuf); 307 dma_buf_put(dmabuf);
290 return -EINVAL; 308 return -EINVAL;
@@ -296,8 +314,9 @@ int nvgpu_vm_map_buffer(struct vm_gk20a *vm,
296 return err; 314 return err;
297 } 315 }
298 316
299 err = nvgpu_vm_map_linux(vm, dmabuf, *offset_align, 317 err = nvgpu_vm_map_linux(vm, dmabuf, *map_addr,
300 nvgpu_vm_translate_linux_flags(g, flags), 318 nvgpu_vm_translate_linux_flags(g, flags),
319 page_size,
301 compr_kind, incompr_kind, 320 compr_kind, incompr_kind,
302 gk20a_mem_flag_none, 321 gk20a_mem_flag_none,
303 buffer_offset, 322 buffer_offset,
@@ -306,7 +325,7 @@ int nvgpu_vm_map_buffer(struct vm_gk20a *vm,
306 &ret_va); 325 &ret_va);
307 326
308 if (!err) 327 if (!err)
309 *offset_align = ret_va; 328 *map_addr = ret_va;
310 else 329 else
311 dma_buf_put(dmabuf); 330 dma_buf_put(dmabuf);
312 331