aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_gem.c19
1 files changed, 16 insertions, 3 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_gem.c b/drivers/gpu/drm/nouveau/nouveau_gem.c
index 2009db2426c3..504833044080 100644
--- a/drivers/gpu/drm/nouveau/nouveau_gem.c
+++ b/drivers/gpu/drm/nouveau/nouveau_gem.c
@@ -466,13 +466,14 @@ u_memcpya(uint64_t user, unsigned nmemb, unsigned size)
466static int 466static int
467nouveau_gem_pushbuf_reloc_apply(struct nouveau_channel *chan, int nr_bo, 467nouveau_gem_pushbuf_reloc_apply(struct nouveau_channel *chan, int nr_bo,
468 struct drm_nouveau_gem_pushbuf_bo *bo, 468 struct drm_nouveau_gem_pushbuf_bo *bo,
469 int nr_relocs, uint64_t ptr_relocs, 469 unsigned nr_relocs, uint64_t ptr_relocs,
470 int nr_dwords, int first_dword, 470 unsigned nr_dwords, unsigned first_dword,
471 uint32_t *pushbuf, bool is_iomem) 471 uint32_t *pushbuf, bool is_iomem)
472{ 472{
473 struct drm_nouveau_gem_pushbuf_reloc *reloc = NULL; 473 struct drm_nouveau_gem_pushbuf_reloc *reloc = NULL;
474 struct drm_device *dev = chan->dev; 474 struct drm_device *dev = chan->dev;
475 int ret = 0, i; 475 int ret = 0;
476 unsigned i;
476 477
477 reloc = u_memcpya(ptr_relocs, nr_relocs, sizeof(*reloc)); 478 reloc = u_memcpya(ptr_relocs, nr_relocs, sizeof(*reloc));
478 if (IS_ERR(reloc)) 479 if (IS_ERR(reloc))
@@ -667,6 +668,18 @@ nouveau_gem_ioctl_pushbuf_call(struct drm_device *dev, void *data,
667 } 668 }
668 pbbo = nouveau_gem_object(gem); 669 pbbo = nouveau_gem_object(gem);
669 670
671 if ((req->offset & 3) || req->nr_dwords < 2 ||
672 (unsigned long)req->offset > (unsigned long)pbbo->bo.mem.size ||
673 (unsigned long)req->nr_dwords >
674 ((unsigned long)(pbbo->bo.mem.size - req->offset ) >> 2)) {
675 NV_ERROR(dev, "pb call misaligned or out of bounds: "
676 "%d + %d * 4 > %ld\n",
677 req->offset, req->nr_dwords, pbbo->bo.mem.size);
678 ret = -EINVAL;
679 drm_gem_object_unreference(gem);
680 goto out;
681 }
682
670 ret = ttm_bo_reserve(&pbbo->bo, false, false, true, 683 ret = ttm_bo_reserve(&pbbo->bo, false, false, true,
671 chan->fence.sequence); 684 chan->fence.sequence);
672 if (ret) { 685 if (ret) {