@@ -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+
177204static 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 )
@@ -429,6 +471,9 @@ static void drm_panic_logo_rect(struct drm_rect *rect, const struct font_desc *f
429471static void drm_panic_logo_draw (struct drm_scanout_buffer * sb , struct drm_rect * rect ,
430472 const struct font_desc * font , u32 fg_color )
431473{
474+ if (rect -> x2 > sb -> width || rect -> y2 > sb -> height )
475+ return ;
476+
432477 if (logo_mono )
433478 drm_panic_blit (sb , rect , logo_mono -> data ,
434479 DIV_ROUND_UP (drm_rect_width (rect ), 8 ), 1 , fg_color );
@@ -477,7 +522,7 @@ static int draw_line_with_wrap(struct drm_scanout_buffer *sb, const struct font_
477522 struct drm_panic_line * line , int yoffset , u32 fg_color )
478523{
479524 int chars_per_row = sb -> width / font -> width ;
480- struct drm_rect r_txt = DRM_RECT_INIT (0 , yoffset , sb -> width , sb -> height );
525+ struct drm_rect r_txt = DRM_RECT_INIT (0 , yoffset , sb -> width , font -> height );
481526 struct drm_panic_line line_wrap ;
482527
483528 if (line -> len > chars_per_row ) {
@@ -520,7 +565,7 @@ static void draw_panic_static_kmsg(struct drm_scanout_buffer *sb)
520565 struct drm_panic_line line ;
521566 int yoffset ;
522567
523- if (!font )
568+ if (!font || font -> width > sb -> width )
524569 return ;
525570
526571 yoffset = sb -> height - font -> height - (sb -> height % font -> height ) / 2 ;
@@ -733,7 +778,10 @@ static int _draw_panic_static_qr_code(struct drm_scanout_buffer *sb)
733778 pr_debug ("QR width %d and scale %d\n" , qr_width , scale );
734779 r_qr_canvas = DRM_RECT_INIT (0 , 0 , qr_canvas_width * scale , qr_canvas_width * scale );
735780
736- v_margin = (sb -> height - drm_rect_height (& r_qr_canvas ) - drm_rect_height (& r_msg )) / 5 ;
781+ v_margin = sb -> height - drm_rect_height (& r_qr_canvas ) - drm_rect_height (& r_msg );
782+ if (v_margin < 0 )
783+ return - ENOSPC ;
784+ v_margin /= 5 ;
737785
738786 drm_rect_translate (& r_qr_canvas , (sb -> width - r_qr_canvas .x2 ) / 2 , 2 * v_margin );
739787 r_qr = DRM_RECT_INIT (r_qr_canvas .x1 + QR_MARGIN * scale , r_qr_canvas .y1 + QR_MARGIN * scale ,
@@ -746,7 +794,7 @@ static int _draw_panic_static_qr_code(struct drm_scanout_buffer *sb)
746794 /* Fill with the background color, and draw text on top */
747795 drm_panic_fill (sb , & r_screen , bg_color );
748796
749- if (!drm_rect_overlap (& r_logo , & r_msg ) && !drm_rect_overlap (& r_logo , & r_qr ))
797+ if (!drm_rect_overlap (& r_logo , & r_msg ) && !drm_rect_overlap (& r_logo , & r_qr_canvas ))
750798 drm_panic_logo_draw (sb , & r_logo , font , fg_color );
751799
752800 draw_txt_rectangle (sb , font , panic_msg , panic_msg_lines , true, & r_msg , fg_color );
0 commit comments