diff options
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_gem.c | 19 |
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) | |||
466 | static int | 466 | static int |
467 | nouveau_gem_pushbuf_reloc_apply(struct nouveau_channel *chan, int nr_bo, | 467 | nouveau_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) { |