Skip to content

Commit b3e8813

Browse files
author
Thomas Zimmermann
committed
fbdev: Warn on incorrect framebuffer access
Test in framebuffer read, write and drawing helpers if FBINFO_VIRTFB has been set correctly. Framebuffers in I/O memory should only be accessed with the architecture's respective helpers. Framebuffers in system memory should be accessed with the regular load and store operations. Presumably not all drivers get this right, so we now warn about it. Signed-off-by: Thomas Zimmermann <[email protected]> Reviewed-by: Javier Martinez Canillas <[email protected]> Link: https://patchwork.freedesktop.org/patch/msgid/[email protected]
1 parent 33253d9 commit b3e8813

File tree

9 files changed

+40
-1
lines changed

9 files changed

+40
-1
lines changed

drivers/video/fbdev/core/cfbcopyarea.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -391,6 +391,9 @@ void cfb_copyarea(struct fb_info *p, const struct fb_copyarea *area)
391391
if (p->state != FBINFO_STATE_RUNNING)
392392
return;
393393

394+
if (p->flags & FBINFO_VIRTFB)
395+
fb_warn_once(p, "Framebuffer is not in I/O address space.");
396+
394397
/* if the beginning of the target area might overlap with the end of
395398
the source area, be have to copy the area reverse. */
396399
if ((dy == sy && dx > sx) || (dy > sy)) {

drivers/video/fbdev/core/cfbfillrect.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -287,6 +287,9 @@ void cfb_fillrect(struct fb_info *p, const struct fb_fillrect *rect)
287287
if (p->state != FBINFO_STATE_RUNNING)
288288
return;
289289

290+
if (p->flags & FBINFO_VIRTFB)
291+
fb_warn_once(p, "Framebuffer is not in I/O address space.");
292+
290293
if (p->fix.visual == FB_VISUAL_TRUECOLOR ||
291294
p->fix.visual == FB_VISUAL_DIRECTCOLOR )
292295
fg = ((u32 *) (p->pseudo_palette))[rect->color];

drivers/video/fbdev/core/cfbimgblt.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -326,6 +326,9 @@ void cfb_imageblit(struct fb_info *p, const struct fb_image *image)
326326
if (p->state != FBINFO_STATE_RUNNING)
327327
return;
328328

329+
if (p->flags & FBINFO_VIRTFB)
330+
fb_warn_once(p, "Framebuffer is not in I/O address space.");
331+
329332
bitstart = (dy * p->fix.line_length * 8) + (dx * bpp);
330333
start_index = bitstart & (32 - 1);
331334
pitch_index = (p->fix.line_length & (bpl - 1)) * 8;

drivers/video/fbdev/core/fb_io_fops.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@ ssize_t fb_io_read(struct fb_info *info, char __user *buf, size_t count, loff_t
1212
int c, cnt = 0, err = 0;
1313
unsigned long total_size, trailing;
1414

15+
if (info->flags & FBINFO_VIRTFB)
16+
fb_warn_once(info, "Framebuffer is not in I/O address space.");
17+
1518
if (!info->screen_base)
1619
return -ENODEV;
1720

@@ -73,6 +76,9 @@ ssize_t fb_io_write(struct fb_info *info, const char __user *buf, size_t count,
7376
int c, cnt = 0, err = 0;
7477
unsigned long total_size, trailing;
7578

79+
if (info->flags & FBINFO_VIRTFB)
80+
fb_warn_once(info, "Framebuffer is not in I/O address space.");
81+
7682
if (!info->screen_base)
7783
return -ENODEV;
7884

@@ -138,6 +144,9 @@ int fb_io_mmap(struct fb_info *info, struct vm_area_struct *vma)
138144
u32 len = info->fix.smem_len;
139145
unsigned long mmio_pgoff = PAGE_ALIGN((start & ~PAGE_MASK) + len) >> PAGE_SHIFT;
140146

147+
if (info->flags & FBINFO_VIRTFB)
148+
fb_warn_once(info, "Framebuffer is not in I/O address space.");
149+
141150
/*
142151
* This can be either the framebuffer mapping, or if pgoff points
143152
* past it, the mmio mapping.

drivers/video/fbdev/core/fb_sys_fops.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,9 @@ ssize_t fb_sys_read(struct fb_info *info, char __user *buf, size_t count,
2222
unsigned long total_size, c;
2323
ssize_t ret;
2424

25+
if (!(info->flags & FBINFO_VIRTFB))
26+
fb_warn_once(info, "Framebuffer is not in virtual address space.");
27+
2528
if (!info->screen_buffer)
2629
return -ENODEV;
2730

@@ -64,6 +67,9 @@ ssize_t fb_sys_write(struct fb_info *info, const char __user *buf,
6467
unsigned long total_size, c;
6568
size_t ret;
6669

70+
if (!(info->flags & FBINFO_VIRTFB))
71+
fb_warn_once(info, "Framebuffer is not in virtual address space.");
72+
6773
if (!info->screen_buffer)
6874
return -ENODEV;
6975

drivers/video/fbdev/core/syscopyarea.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -324,6 +324,9 @@ void sys_copyarea(struct fb_info *p, const struct fb_copyarea *area)
324324
if (p->state != FBINFO_STATE_RUNNING)
325325
return;
326326

327+
if (!(p->flags & FBINFO_VIRTFB))
328+
fb_warn_once(p, "Framebuffer is not in virtual address space.");
329+
327330
/* if the beginning of the target area might overlap with the end of
328331
the source area, be have to copy the area reverse. */
329332
if ((dy == sy && dx > sx) || (dy > sy)) {

drivers/video/fbdev/core/sysfillrect.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -242,6 +242,9 @@ void sys_fillrect(struct fb_info *p, const struct fb_fillrect *rect)
242242
if (p->state != FBINFO_STATE_RUNNING)
243243
return;
244244

245+
if (!(p->flags & FBINFO_VIRTFB))
246+
fb_warn_once(p, "Framebuffer is not in virtual address space.");
247+
245248
if (p->fix.visual == FB_VISUAL_TRUECOLOR ||
246249
p->fix.visual == FB_VISUAL_DIRECTCOLOR )
247250
fg = ((u32 *) (p->pseudo_palette))[rect->color];

drivers/video/fbdev/core/sysimgblt.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -296,6 +296,9 @@ void sys_imageblit(struct fb_info *p, const struct fb_image *image)
296296
if (p->state != FBINFO_STATE_RUNNING)
297297
return;
298298

299+
if (!(p->flags & FBINFO_VIRTFB))
300+
fb_warn_once(p, "Framebuffer is not in virtual address space.");
301+
299302
bitstart = (dy * p->fix.line_length * 8) + (dx * bpp);
300303
start_index = bitstart & (32 - 1);
301304
pitch_index = (p->fix.line_length & (bpl - 1)) * 8;

include/linux/fb.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -849,7 +849,10 @@ static inline bool fb_modesetting_disabled(const char *drvname)
849849
}
850850
#endif
851851

852-
/* Convenience logging macros */
852+
/*
853+
* Convenience logging macros
854+
*/
855+
853856
#define fb_err(fb_info, fmt, ...) \
854857
pr_err("fb%d: " fmt, (fb_info)->node, ##__VA_ARGS__)
855858
#define fb_notice(info, fmt, ...) \
@@ -861,4 +864,7 @@ static inline bool fb_modesetting_disabled(const char *drvname)
861864
#define fb_dbg(fb_info, fmt, ...) \
862865
pr_debug("fb%d: " fmt, (fb_info)->node, ##__VA_ARGS__)
863866

867+
#define fb_warn_once(fb_info, fmt, ...) \
868+
pr_warn_once("fb%d: " fmt, (fb_info)->node, ##__VA_ARGS__)
869+
864870
#endif /* _LINUX_FB_H */

0 commit comments

Comments
 (0)