Skip to content

Commit 2343750

Browse files
author
Jocelyn Falempe
committed
drm/panic: Fix 24bit pixel crossing page boundaries
When using page list framebuffer, and using RGB888 format, some pixels can cross the page boundaries, and this case was not handled, leading to writing 1 or 2 bytes on the next virtual address. Add a check and a specific function to handle this case. Fixes: c9ff280 ("drm/panic: Add support to scanout buffer as array of pages") Reviewed-by: Javier Martinez Canillas <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Jocelyn Falempe <[email protected]>
1 parent 2e337dd commit 2343750

File tree

1 file changed

+44
-2
lines changed

1 file changed

+44
-2
lines changed

drivers/gpu/drm/drm_panic.c

Lines changed: 44 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,33 @@ static void drm_panic_write_pixel24(void *vaddr, unsigned int offset, u32 color)
174174
*p = color & 0xff;
175175
}
176176

177+
/*
178+
* Special case if the pixel crosses page boundaries
179+
*/
180+
static void drm_panic_write_pixel24_xpage(void *vaddr, struct page *next_page,
181+
unsigned int offset, u32 color)
182+
{
183+
u8 *vaddr2;
184+
u8 *p = vaddr + offset;
185+
186+
vaddr2 = kmap_local_page_try_from_panic(next_page);
187+
188+
*p++ = color & 0xff;
189+
color >>= 8;
190+
191+
if (offset == PAGE_SIZE - 1)
192+
p = vaddr2;
193+
194+
*p++ = color & 0xff;
195+
color >>= 8;
196+
197+
if (offset == PAGE_SIZE - 2)
198+
p = vaddr2;
199+
200+
*p = color & 0xff;
201+
kunmap_local(vaddr2);
202+
}
203+
177204
static void drm_panic_write_pixel32(void *vaddr, unsigned int offset, u32 color)
178205
{
179206
u32 *p = vaddr + offset;
@@ -231,7 +258,14 @@ static void drm_panic_blit_page(struct page **pages, unsigned int dpitch,
231258
page = new_page;
232259
vaddr = kmap_local_page_try_from_panic(pages[page]);
233260
}
234-
if (vaddr)
261+
if (!vaddr)
262+
continue;
263+
264+
// Special case for 24bit, as a pixel might cross page boundaries
265+
if (cpp == 3 && offset + 3 > PAGE_SIZE)
266+
drm_panic_write_pixel24_xpage(vaddr, pages[page + 1],
267+
offset, fg32);
268+
else
235269
drm_panic_write_pixel(vaddr, offset, fg32, cpp);
236270
}
237271
}
@@ -321,7 +355,15 @@ static void drm_panic_fill_page(struct page **pages, unsigned int dpitch,
321355
page = new_page;
322356
vaddr = kmap_local_page_try_from_panic(pages[page]);
323357
}
324-
drm_panic_write_pixel(vaddr, offset, color, cpp);
358+
if (!vaddr)
359+
continue;
360+
361+
// Special case for 24bit, as a pixel might cross page boundaries
362+
if (cpp == 3 && offset + 3 > PAGE_SIZE)
363+
drm_panic_write_pixel24_xpage(vaddr, pages[page + 1],
364+
offset, color);
365+
else
366+
drm_panic_write_pixel(vaddr, offset, color, cpp);
325367
}
326368
}
327369
if (vaddr)

0 commit comments

Comments
 (0)