diff --git a/sys/dev/drm/radeon/radeon_cursor.c b/sys/dev/drm/radeon/radeon_cursor.c index 1111111..2222222 100644 --- a/sys/dev/drm/radeon/radeon_cursor.c +++ b/sys/dev/drm/radeon/radeon_cursor.c @@ -307,6 +307,18 @@ int radeon_crtc_cursor_set2(struct drm_crtc *crtc, return -ENOENT; } + /* + * The display engine fetches width*height*4 bytes starting at the + * pinned cursor BO's VRAM address (pre-AVIVO adds up to + * (max_cursor_height - 1) * 256 more via CUR_OFFSET). Require the + * BO to cover the maximum fetch window, otherwise the cursor scanout + * reads past the end of the BO and paints adjacent VRAM contents on + * the screen. + */ + if (radeon_bo_size(gem_to_radeon_bo(obj)) < + (u64)radeon_crtc->max_cursor_width * + radeon_crtc->max_cursor_height * 4) { + DRM_ERROR("Cursor BO too small for %d x %d cursor\n", + radeon_crtc->max_cursor_width, + radeon_crtc->max_cursor_height); + drm_gem_object_put_unlocked(obj); + return -EINVAL; + } + robj = gem_to_radeon_bo(obj); ret = radeon_bo_reserve(robj, false); if (ret != 0) {