mirror of
https://github.com/torvalds/linux.git
synced 2026-07-27 09:36:22 +02:00
additional fbdev fixes & cleanups for 7.2-rc1:
Fixes: - fbcon: fix NULL pointer dereference for a console without vc_data [Ian Bridges] - fbdev: fix fb_new_modelist to prevent null-ptr-deref in fb_videomode_to_var [Ian Bridges] Fixes in failure paths: - pm2fb: unwind write-cache setting on probe failure [Haoxiang Li] - goldfishfb: fail pan display on base-update timeout [Pengpeng Hou] - viafb: return error on DMA copy time-out [Pengpeng Hou] - fbcon: fix out-of-bounds read in error path of fbcon_do_set_font() [Mingyu Wang] - fbdev: fix modelist use-after-free in store_modes() [Ian Bridges] Code cleanup: - vga16fb: clean up platform_device_id table [Uwe Kleine-König] -----BEGIN PGP SIGNATURE----- iHUEABYKAB0WIQS86RI+GtKfB8BJu973ErUQojoPXwUCakAKnwAKCRD3ErUQojoP X27+AQCPvMJUMScjO1dlGKkPnnIFiOWCU6AW1aM2m6T+qWrCTQEAnNi5CCI3JiLi 6NCcyPm7/4R6tSXDm+UcWJ5tyzaNvww= =EBHb -----END PGP SIGNATURE----- Merge tag 'fbdev-for-7.2-rc1-2' of git://git.kernel.org/pub/scm/linux/kernel/git/deller/linux-fbdev Pull more fbdev updates from Helge Deller: "Fixes for generic fbdev & fbcon code for the handling of modelists and preventing a potential NULL ptr dereference in the console code. Fix missed cleanups in the error path of various fbdev drivers. And Uwe Kleine-König contributed a cleanup patch to use named initializers in the vga16fb driver" * tag 'fbdev-for-7.2-rc1-2' of git://git.kernel.org/pub/scm/linux/kernel/git/deller/linux-fbdev: fbdev: Fix fb_new_modelist to prevent null-ptr-deref in fb_videomode_to_var fbcon: fix NULL pointer dereference for a console without vc_data fbdev: fix use-after-free in store_modes() fbdev: viafb: return an error when DMA copy times out fbdev: goldfishfb: fail pan display on base-update timeout fbdev: fbcon: fix out-of-bounds read in err_out of fbcon_do_set_font() fbdev: pm2fb: unwind WC setup on probe failure fbdev: vga16fb: Drop unused assignment of platform_device_id driver data
This commit is contained in:
commit
f21df87320
|
|
@ -1273,6 +1273,7 @@ static void fbcon_deinit(struct vc_data *vc)
|
|||
int idx;
|
||||
|
||||
fbcon_free_font(p);
|
||||
p->mode = NULL;
|
||||
idx = con2fb_map[vc->vc_num];
|
||||
|
||||
if (idx == -1)
|
||||
|
|
@ -1443,14 +1444,14 @@ static void fbcon_set_disp(struct fb_info *info, struct fb_var_screeninfo *var,
|
|||
|
||||
p = &fb_display[unit];
|
||||
|
||||
if (var_to_display(p, var, info))
|
||||
return;
|
||||
|
||||
vc = vc_cons[unit].d;
|
||||
|
||||
if (!vc)
|
||||
return;
|
||||
|
||||
if (var_to_display(p, var, info))
|
||||
return;
|
||||
|
||||
default_mode = vc->vc_display_fg;
|
||||
svc = *default_mode;
|
||||
t = &fb_display[svc->vc_num];
|
||||
|
|
@ -2405,6 +2406,7 @@ static int fbcon_do_set_font(struct vc_data *vc, int w, int h, int charcount,
|
|||
int resize, ret, old_width, old_height, old_charcount;
|
||||
font_data_t *old_fontdata = p->fontdata;
|
||||
const u8 *old_data = vc->vc_font.data;
|
||||
unsigned short old_hi_font_mask = vc->vc_hi_font_mask;
|
||||
|
||||
font_data_get(data);
|
||||
|
||||
|
|
@ -2451,6 +2453,12 @@ static int fbcon_do_set_font(struct vc_data *vc, int w, int h, int charcount,
|
|||
vc->vc_font.height = old_height;
|
||||
vc->vc_font.charcount = old_charcount;
|
||||
|
||||
/* Restore the hi_font state and screen buffer */
|
||||
if (old_hi_font_mask && !vc->vc_hi_font_mask)
|
||||
set_vc_hi_font(vc, true);
|
||||
else if (!old_hi_font_mask && vc->vc_hi_font_mask)
|
||||
set_vc_hi_font(vc, false);
|
||||
|
||||
font_data_put(data);
|
||||
|
||||
return ret;
|
||||
|
|
|
|||
|
|
@ -767,6 +767,18 @@ int fb_new_modelist(struct fb_info *info)
|
|||
if (list_empty(&info->modelist))
|
||||
return 1;
|
||||
|
||||
/*
|
||||
* The new modelist may not contain the current mode (info->var), and
|
||||
* fbcon_new_modelist() below only re-points consoles mapped to this
|
||||
* framebuffer. Add the current mode here so info->var keeps a match
|
||||
* even when fbcon is unbound.
|
||||
*/
|
||||
if (!fb_match_mode(&info->var, &info->modelist)) {
|
||||
fb_var_to_videomode(&mode, &info->var);
|
||||
if (fb_add_videomode(&mode, &info->modelist))
|
||||
return 1;
|
||||
}
|
||||
|
||||
fbcon_new_modelist(info);
|
||||
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@
|
|||
#include <linux/major.h>
|
||||
|
||||
#include "fb_internal.h"
|
||||
#include "fbcon.h"
|
||||
|
||||
static int activate(struct fb_info *fb_info, struct fb_var_screeninfo *var)
|
||||
{
|
||||
|
|
@ -108,8 +109,15 @@ static ssize_t store_modes(struct device *device,
|
|||
if (fb_new_modelist(fb_info)) {
|
||||
fb_destroy_modelist(&fb_info->modelist);
|
||||
list_splice(&old_list, &fb_info->modelist);
|
||||
} else
|
||||
} else {
|
||||
/*
|
||||
* fb_display[i].mode and fb_info->mode both point into the old
|
||||
* list. Clear them before it is freed.
|
||||
*/
|
||||
fbcon_delete_modelist(&old_list);
|
||||
fb_info->mode = NULL;
|
||||
fb_destroy_modelist(&old_list);
|
||||
}
|
||||
|
||||
unlock_fb_info(fb_info);
|
||||
console_unlock();
|
||||
|
|
|
|||
|
|
@ -138,10 +138,12 @@ static int goldfish_fb_pan_display(struct fb_var_screeninfo *var,
|
|||
writel(fb->fb.fix.smem_start + fb->fb.var.xres * 2 * var->yoffset,
|
||||
fb->reg_base + FB_SET_BASE);
|
||||
spin_unlock_irqrestore(&fb->lock, irq_flags);
|
||||
wait_event_timeout(fb->wait,
|
||||
fb->base_update_count != base_update_count, HZ / 15);
|
||||
if (fb->base_update_count == base_update_count)
|
||||
if (!wait_event_timeout(fb->wait,
|
||||
fb->base_update_count != base_update_count,
|
||||
HZ / 15)) {
|
||||
pr_err("%s: timeout waiting for base update\n", __func__);
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -251,7 +253,9 @@ static int goldfish_fb_probe(struct platform_device *pdev)
|
|||
goto err_request_irq_failed;
|
||||
|
||||
writel(FB_INT_BASE_UPDATE_DONE, fb->reg_base + FB_INT_ENABLE);
|
||||
goldfish_fb_pan_display(&fb->fb.var, &fb->fb); /* updates base */
|
||||
ret = goldfish_fb_pan_display(&fb->fb.var, &fb->fb); /* updates base */
|
||||
if (ret)
|
||||
goto err_pan_display_failed;
|
||||
|
||||
ret = register_framebuffer(&fb->fb);
|
||||
if (ret)
|
||||
|
|
@ -259,6 +263,7 @@ static int goldfish_fb_probe(struct platform_device *pdev)
|
|||
return 0;
|
||||
|
||||
err_register_framebuffer_failed:
|
||||
err_pan_display_failed:
|
||||
free_irq(fb->irq, fb);
|
||||
err_request_irq_failed:
|
||||
err_fb_set_var_failed:
|
||||
|
|
|
|||
|
|
@ -1711,6 +1711,7 @@ static int pm2fb_probe(struct pci_dev *pdev, const struct pci_device_id *id)
|
|||
err_exit_both:
|
||||
kfree(info->pixmap.addr);
|
||||
err_exit_pixmap:
|
||||
arch_phys_wc_del(default_par->wc_cookie);
|
||||
iounmap(info->screen_base);
|
||||
release_mem_region(pm2fb_fix.smem_start, pm2fb_fix.smem_len);
|
||||
err_exit_mmio:
|
||||
|
|
|
|||
|
|
@ -1421,8 +1421,8 @@ static void vga16fb_remove(struct platform_device *dev)
|
|||
}
|
||||
|
||||
static const struct platform_device_id vga16fb_driver_id_table[] = {
|
||||
{"ega-framebuffer", 0},
|
||||
{"vga-framebuffer", 0},
|
||||
{ .name = "ega-framebuffer" },
|
||||
{ .name = "vga-framebuffer" },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(platform, vga16fb_driver_id_table);
|
||||
|
|
|
|||
|
|
@ -234,6 +234,7 @@ int viafb_dma_copy_out_sg(unsigned int offset, struct scatterlist *sg, int nsg)
|
|||
dma_addr_t descr_handle;
|
||||
unsigned long flags;
|
||||
int i;
|
||||
int ret = 0;
|
||||
struct scatterlist *sgentry;
|
||||
dma_addr_t nextdesc;
|
||||
|
||||
|
|
@ -290,8 +291,10 @@ int viafb_dma_copy_out_sg(unsigned int offset, struct scatterlist *sg, int nsg)
|
|||
*/
|
||||
wait_for_completion_timeout(&viafb_dma_completion, 1);
|
||||
msleep(1);
|
||||
if ((viafb_mmio_read(VDMA_CSR0)&VDMA_C_DONE) == 0)
|
||||
if ((viafb_mmio_read(VDMA_CSR0) & VDMA_C_DONE) == 0) {
|
||||
printk(KERN_ERR "VIA DMA timeout!\n");
|
||||
ret = -ETIMEDOUT;
|
||||
}
|
||||
/*
|
||||
* Clean up and we're done.
|
||||
*/
|
||||
|
|
@ -301,7 +304,7 @@ int viafb_dma_copy_out_sg(unsigned int offset, struct scatterlist *sg, int nsg)
|
|||
dma_free_coherent(&global_dev.pdev->dev,
|
||||
nsg*sizeof(struct viafb_vx855_dma_descr), descrpages,
|
||||
descr_handle);
|
||||
return 0;
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(viafb_dma_copy_out_sg);
|
||||
#endif /* CONFIG_VIDEO_VIA_CAMERA */
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user