[PATCH v2 1/2] drm/radeon: Restrict offset for legacy hardware cursor.
Alex Deucher
alexdeucher at gmail.com
Wed Mar 14 12:10:51 PDT 2012
2012/3/14 Michel Dänzer <michel at daenzer.net>:
> From: Michel Dänzer <michel.daenzer at amd.com>
>
> The hardware only takes 27 bits for the offset, so larger offsets are
> truncated, and the hardware cursor shows random bits other than the intended
> ones.
>
> Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=46796
>
> Cc: stable at vger.kernel.org
> Signed-off-by: Michel Dänzer <michel.daenzer at amd.com>
Reviewed-by: Alex Deucher <alexander.deucher at amd.com>
> ---
>
> v2: Make sure bo->placement.lpfn isn't larger than the memory size, even if
> radeon_bo_pin_restricted were to be called for the GTT domain.
>
> drivers/gpu/drm/radeon/radeon_cursor.c | 13 +++++++++++--
> drivers/gpu/drm/radeon/radeon_object.c | 18 +++++++++++++++++-
> drivers/gpu/drm/radeon/radeon_object.h | 2 ++
> 3 files changed, 30 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/gpu/drm/radeon/radeon_cursor.c b/drivers/gpu/drm/radeon/radeon_cursor.c
> index fde25c0..986d608 100644
> --- a/drivers/gpu/drm/radeon/radeon_cursor.c
> +++ b/drivers/gpu/drm/radeon/radeon_cursor.c
> @@ -151,7 +151,9 @@ int radeon_crtc_cursor_set(struct drm_crtc *crtc,
> uint32_t height)
> {
> struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
> + struct radeon_device *rdev = crtc->dev->dev_private;
> struct drm_gem_object *obj;
> + struct radeon_bo *robj;
> uint64_t gpu_addr;
> int ret;
>
> @@ -173,7 +175,15 @@ int radeon_crtc_cursor_set(struct drm_crtc *crtc,
> return -ENOENT;
> }
>
> - ret = radeon_gem_object_pin(obj, RADEON_GEM_DOMAIN_VRAM, &gpu_addr);
> + robj = gem_to_radeon_bo(obj);
> + ret = radeon_bo_reserve(robj, false);
> + if (unlikely(ret != 0))
> + goto fail;
> + /* Only 27 bit offset for legacy cursor */
> + ret = radeon_bo_pin_restricted(robj, RADEON_GEM_DOMAIN_VRAM,
> + ASIC_IS_AVIVO(rdev) ? 0 : 1 << 27,
> + &gpu_addr);
> + radeon_bo_unreserve(robj);
> if (ret)
> goto fail;
>
> @@ -181,7 +191,6 @@ int radeon_crtc_cursor_set(struct drm_crtc *crtc,
> radeon_crtc->cursor_height = height;
>
> radeon_lock_cursor(crtc, true);
> - /* XXX only 27 bit offset for legacy cursor */
> radeon_set_cursor(crtc, obj, gpu_addr);
> radeon_show_cursor(crtc);
> radeon_lock_cursor(crtc, false);
> diff --git a/drivers/gpu/drm/radeon/radeon_object.c b/drivers/gpu/drm/radeon/radeon_object.c
> index d45df17..fd2dc0e 100644
> --- a/drivers/gpu/drm/radeon/radeon_object.c
> +++ b/drivers/gpu/drm/radeon/radeon_object.c
> @@ -224,7 +224,8 @@ void radeon_bo_unref(struct radeon_bo **bo)
> *bo = NULL;
> }
>
> -int radeon_bo_pin(struct radeon_bo *bo, u32 domain, u64 *gpu_addr)
> +int radeon_bo_pin_restricted(struct radeon_bo *bo, u32 domain, u64 max_offset,
> + u64 *gpu_addr)
> {
> int r, i;
>
> @@ -232,6 +233,7 @@ int radeon_bo_pin(struct radeon_bo *bo, u32 domain, u64 *gpu_addr)
> bo->pin_count++;
> if (gpu_addr)
> *gpu_addr = radeon_bo_gpu_offset(bo);
> + WARN_ON_ONCE(max_offset != 0);
> return 0;
> }
> radeon_ttm_placement_from_domain(bo, domain);
> @@ -239,6 +241,15 @@ int radeon_bo_pin(struct radeon_bo *bo, u32 domain, u64 *gpu_addr)
> /* force to pin into visible video ram */
> bo->placement.lpfn = bo->rdev->mc.visible_vram_size >> PAGE_SHIFT;
> }
> + if (max_offset) {
> + u64 lpfn = max_offset >> PAGE_SHIFT;
> +
> + if (!bo->placement.lpfn)
> + bo->placement.lpfn = bo->rdev->mc.gtt_size >> PAGE_SHIFT;
> +
> + if (lpfn < bo->placement.lpfn)
> + bo->placement.lpfn = lpfn;
> + }
> for (i = 0; i < bo->placement.num_placement; i++)
> bo->placements[i] |= TTM_PL_FLAG_NO_EVICT;
> r = ttm_bo_validate(&bo->tbo, &bo->placement, false, false, false);
> @@ -252,6 +263,11 @@ int radeon_bo_pin(struct radeon_bo *bo, u32 domain, u64 *gpu_addr)
> return r;
> }
>
> +int radeon_bo_pin(struct radeon_bo *bo, u32 domain, u64 *gpu_addr)
> +{
> + return radeon_bo_pin_restricted(bo, domain, 0, gpu_addr);
> +}
> +
> int radeon_bo_unpin(struct radeon_bo *bo)
> {
> int r, i;
> diff --git a/drivers/gpu/drm/radeon/radeon_object.h b/drivers/gpu/drm/radeon/radeon_object.h
> index cde4303..f9104be 100644
> --- a/drivers/gpu/drm/radeon/radeon_object.h
> +++ b/drivers/gpu/drm/radeon/radeon_object.h
> @@ -118,6 +118,8 @@ extern int radeon_bo_kmap(struct radeon_bo *bo, void **ptr);
> extern void radeon_bo_kunmap(struct radeon_bo *bo);
> extern void radeon_bo_unref(struct radeon_bo **bo);
> extern int radeon_bo_pin(struct radeon_bo *bo, u32 domain, u64 *gpu_addr);
> +extern int radeon_bo_pin_restricted(struct radeon_bo *bo, u32 domain,
> + u64 max_offset, u64 *gpu_addr);
> extern int radeon_bo_unpin(struct radeon_bo *bo);
> extern int radeon_bo_evict_vram(struct radeon_device *rdev);
> extern void radeon_bo_force_delete(struct radeon_device *rdev);
> --
> 1.7.9.1
>
> _______________________________________________
> dri-devel mailing list
> dri-devel at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/dri-devel
More information about the dri-devel
mailing list