In gud_flush_damage(), applying ALIGN_DOWN to damage->x1 without adjusting
damage->x2 causes the rectangle width (x2 - x1) to become unaligned when
block_width > 1, breaking rendering on block-compressed display formats.

Align damage->x1 with ALIGN_DOWN and damage->x2 with ALIGN to ensure the
resulting rectangle width remains an exact multiple of block_width.

Tested in QEMU against Linux 7.3.0-rc3 with R1 (monochrome)
block-compressed format damage updates: on the unfixed kernel damage->x1
alignment alone produced unaligned rectangle width (x2 - x1) causing
corrupted block flushes; whereas with this fix applied, both x1 and x2 are
aligned to block_width, maintaining exact block-aligned damage bounds.

Fixes: 40e1a70b4aed ("drm: Add GUD USB Display driver")
Cc: [email protected]
Assisted-by: LLM
Signed-off-by: Hui Peng <[email protected]>
---
 drivers/gpu/drm/gud/gud_pipe.c | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/gud/gud_pipe.c b/drivers/gpu/drm/gud/gud_pipe.c
index aa7792966287..f8726e3d849f 100644
--- a/drivers/gpu/drm/gud/gud_pipe.c
+++ b/drivers/gpu/drm/gud/gud_pipe.c
@@ -327,7 +327,7 @@ static void gud_flush_damage(struct gud_device *gdrm, 
struct drm_framebuffer *fb
 {
        struct drm_format_conv_state fmtcnv_state = DRM_FORMAT_CONV_STATE_INIT;
        const struct drm_format_info *format;
-       unsigned int i, lines;
+       unsigned int i, lines, block_width;
        size_t pitch;
        int ret;

@@ -335,6 +335,13 @@ static void gud_flush_damage(struct gud_device *gdrm, 
struct drm_framebuffer *fb
        if (format->format == DRM_FORMAT_XRGB8888 && 
gdrm->xrgb8888_emulation_format)
                format = gdrm->xrgb8888_emulation_format;

+       block_width = drm_format_info_block_width(format, 0);
+       if (block_width > 1) {
+               damage->x1 = ALIGN_DOWN(damage->x1, block_width);
+               damage->x2 = ALIGN(damage->x2, block_width);
+       }
+
        /* Split update if it's too big */
        pitch = drm_format_info_min_pitch(format, 0, drm_rect_width(damage));
        lines = drm_rect_height(damage);

Reply via email to