All of lore.kernel.org
 help / color / mirror / Atom feed
From: Marek Vasut <marek.vasut@gmail.com>
To: linux-arm-kernel@lists.infradead.org
Subject: Re: [PATCH 1/2] ARM: PXA: PXAFB: Fix double-free issue.
Date: Thu, 17 Feb 2011 18:17:41 +0000	[thread overview]
Message-ID: <201102171917.41442.marek.vasut@gmail.com> (raw)
In-Reply-To: <1297928588-10545-1-git-send-email-anarsoul@gmail.com>

On Thursday 17 February 2011 08:43:07 Vasily Khoruzhick wrote:
> From: Russell King - ARM Linux <linux@arm.linux.org.uk>
> 
> From: Russell King - ARM Linux <linux@arm.linux.org.uk>
> 
> Release callback tries to free memory even if it was not allocated in
> map_video_memory, fix it.
> 
> Added by Vasily Khoruzhick:
> 
> - Clear x_res/y_res fields of fb.var on release, to make sure
> our callback will be called on next FBIOPUT_VSCREENINFO ioctl.
> - Disable overlay only if it was enabled.
> 
> Signed-off-by: Vasily Khoruzhick <anarsoul@gmail.com>
> ---
>  drivers/video/pxafb.c |   55
> +++++++++++++++++++++++++++++++++--------------- drivers/video/pxafb.h |  
>  2 +-
>  2 files changed, 39 insertions(+), 18 deletions(-)
> 
> diff --git a/drivers/video/pxafb.c b/drivers/video/pxafb.c
> index 825b665..c6aad56 100644
> --- a/drivers/video/pxafb.c
> +++ b/drivers/video/pxafb.c
> @@ -629,6 +629,9 @@ static void overlay1fb_disable(struct pxafb_layer *ofb)
>  {
>  	uint32_t lccr5 = lcd_readl(ofb->fbi, LCCR5);
> 
> +	if (!(lcd_readl(ofb->fbi, OVL1C1) & OVLxC1_OEN))
> +		return;
> +
>  	lcd_writel(ofb->fbi, OVL1C1, ofb->control[0] & ~OVLxC1_OEN);
> 
>  	lcd_writel(ofb->fbi, LCSR1, LCSR1_BS(1));
> @@ -636,7 +639,8 @@ static void overlay1fb_disable(struct pxafb_layer *ofb)
>  	lcd_writel(ofb->fbi, FBR1, ofb->fbi->fdadr[DMA_OV1] | 0x3);
> 
>  	if (wait_for_completion_timeout(&ofb->branch_done, 1 * HZ) = 0)
> -		pr_warning("%s: timeout disabling overlay1\n", __func__);
> +		pr_warning("%s: timeout disabling overlay1\n",
> +			__func__);
> 
>  	lcd_writel(ofb->fbi, LCCR5, lccr5);
>  }
> @@ -687,6 +691,9 @@ static void overlay2fb_disable(struct pxafb_layer *ofb)
>  {
>  	uint32_t lccr5 = lcd_readl(ofb->fbi, LCCR5);
> 
> +	if (!(lcd_readl(ofb->fbi, OVL2C1) & OVLxC1_OEN))
> +		return;
> +
>  	lcd_writel(ofb->fbi, OVL2C1, ofb->control[0] & ~OVLxC1_OEN);
> 
>  	lcd_writel(ofb->fbi, LCSR1, LCSR1_BS(2));
> @@ -696,7 +703,8 @@ static void overlay2fb_disable(struct pxafb_layer *ofb)
>  	lcd_writel(ofb->fbi, FBR4, ofb->fbi->fdadr[DMA_OV2_Cr] | 0x3);
> 
>  	if (wait_for_completion_timeout(&ofb->branch_done, 1 * HZ) = 0)
> -		pr_warning("%s: timeout disabling overlay2\n", __func__);
> +		pr_warning("%s: timeout disabling overlay2\n",
> +			__func__);
>  }
> 
>  static struct pxafb_layer_ops ofb_ops[] = {
> @@ -720,12 +728,10 @@ static int overlayfb_open(struct fb_info *info, int
> user) if (user = 0)
>  		return -ENODEV;
> 

Why are you getting rid of the atomic operations ?
Besides, "if (ofb->usage++ = 0)" looks suspicious, especially if you later 
declare it as uint32_t.

> -	/* allow only one user at a time */
> -	if (atomic_inc_and_test(&ofb->usage))
> -		return -EBUSY;
> +	if (ofb->usage++ = 0)
> +		/* unblank the base framebuffer */
> +		fb_blank(&ofb->fbi->fb, FB_BLANK_UNBLANK);
> 
> -	/* unblank the base framebuffer */
> -	fb_blank(&ofb->fbi->fb, FB_BLANK_UNBLANK);
>  	return 0;
>  }
> 
> @@ -733,12 +739,24 @@ static int overlayfb_release(struct fb_info *info,
> int user) {
>  	struct pxafb_layer *ofb = (struct pxafb_layer*) info;
> 

DTTO, why no atomic?

> -	atomic_dec(&ofb->usage);
> -	ofb->ops->disable(ofb);
> -
> -	free_pages_exact(ofb->video_mem, ofb->video_mem_size);
> -	ofb->video_mem = NULL;
> -	ofb->video_mem_size = 0;
> +	if (--ofb->usage = 0) {
> +		ofb->ops->disable(ofb);
> +		ofb->fb.var.height	= -1;
> +		ofb->fb.var.width	= -1;
> +		ofb->fb.var.xres = ofb->fb.var.xres_virtual = 0;
> +		ofb->fb.var.yres = ofb->fb.var.yres_virtual = 0;
> +
> +		mutex_lock(&ofb->fb.mm_lock);
> +		ofb->fb.fix.smem_start	= 0;
> +		ofb->fb.fix.smem_len	= 0;
> +		mutex_unlock(&ofb->fb.mm_lock);
> +
> +		if (ofb->video_mem) {
> +			free_pages_exact(ofb->video_mem, ofb->video_mem_size);
> +			ofb->video_mem = NULL;
> +			ofb->video_mem_size = 0;
> +		}
> +	}
>  	return 0;
>  }
> 
> @@ -817,7 +835,8 @@ static int overlayfb_map_video_memory(struct
> pxafb_layer *ofb) if (ofb->video_mem_size >= size)
>  			return 0;
> 
> -		free_pages_exact(ofb->video_mem, ofb->video_mem_size);
> +		/* don't re-allocate: userspace may have the buffer mapped */
> +		return -EINVAL;
>  	}
> 
>  	ofb->video_mem = alloc_pages_exact(size, GFP_KERNEL | __GFP_ZERO);
> @@ -891,7 +910,7 @@ static void __devinit init_pxafb_overlay(struct
> pxafb_info *fbi,
> 
>  	ofb->id = id;
>  	ofb->ops = &ofb_ops[id];

DTTO

> -	atomic_set(&ofb->usage, 0);
> +	ofb->usage = 0;
>  	ofb->fbi = fbi;
>  	init_completion(&ofb->branch_done);
>  }
> @@ -1368,7 +1387,8 @@ static int pxafb_activate_var(struct
> fb_var_screeninfo *var, (lcd_readl(fbi, LCCR3) != fbi->reg_lccr3) ||
>  	    (lcd_readl(fbi, LCCR4) != fbi->reg_lccr4) ||
>  	    (lcd_readl(fbi, FDADR0) != fbi->fdadr[0]) ||
> -	    (lcd_readl(fbi, FDADR1) != fbi->fdadr[1]))
> +	    ((fbi->lccr0 & LCCR0_SDS) &&
> +	    (lcd_readl(fbi, FDADR1) != fbi->fdadr[1])))
>  		pxafb_schedule_work(fbi, C_REENABLE);
> 
>  	return 0;
> @@ -1420,7 +1440,8 @@ static void pxafb_enable_controller(struct pxafb_info
> *fbi) lcd_writel(fbi, LCCR0, fbi->reg_lccr0 & ~LCCR0_ENB);
> 
>  	lcd_writel(fbi, FDADR0, fbi->fdadr[0]);
> -	lcd_writel(fbi, FDADR1, fbi->fdadr[1]);
> +	if (fbi->lccr0 & LCCR0_SDS)
> +		lcd_writel(fbi, FDADR1, fbi->fdadr[1]);
>  	lcd_writel(fbi, LCCR0, fbi->reg_lccr0 | LCCR0_ENB);
>  }
> 
> diff --git a/drivers/video/pxafb.h b/drivers/video/pxafb.h
> index 2353521..84e3ae1 100644
> --- a/drivers/video/pxafb.h
> +++ b/drivers/video/pxafb.h
> @@ -92,7 +92,7 @@ struct pxafb_layer_ops {
>  struct pxafb_layer {
>  	struct fb_info		fb;
>  	int			id;

DTTO, here.

> -	atomic_t		usage;
> +	uint32_t		usage;
>  	uint32_t		control[2];
> 
>  	struct pxafb_layer_ops	*ops;

WARNING: multiple messages have this Message-ID (diff)
From: marek.vasut@gmail.com (Marek Vasut)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH 1/2] ARM: PXA: PXAFB: Fix double-free issue.
Date: Thu, 17 Feb 2011 19:17:41 +0100	[thread overview]
Message-ID: <201102171917.41442.marek.vasut@gmail.com> (raw)
In-Reply-To: <1297928588-10545-1-git-send-email-anarsoul@gmail.com>

On Thursday 17 February 2011 08:43:07 Vasily Khoruzhick wrote:
> From: Russell King - ARM Linux <linux@arm.linux.org.uk>
> 
> From: Russell King - ARM Linux <linux@arm.linux.org.uk>
> 
> Release callback tries to free memory even if it was not allocated in
> map_video_memory, fix it.
> 
> Added by Vasily Khoruzhick:
> 
> - Clear x_res/y_res fields of fb.var on release, to make sure
> our callback will be called on next FBIOPUT_VSCREENINFO ioctl.
> - Disable overlay only if it was enabled.
> 
> Signed-off-by: Vasily Khoruzhick <anarsoul@gmail.com>
> ---
>  drivers/video/pxafb.c |   55
> +++++++++++++++++++++++++++++++++--------------- drivers/video/pxafb.h |  
>  2 +-
>  2 files changed, 39 insertions(+), 18 deletions(-)
> 
> diff --git a/drivers/video/pxafb.c b/drivers/video/pxafb.c
> index 825b665..c6aad56 100644
> --- a/drivers/video/pxafb.c
> +++ b/drivers/video/pxafb.c
> @@ -629,6 +629,9 @@ static void overlay1fb_disable(struct pxafb_layer *ofb)
>  {
>  	uint32_t lccr5 = lcd_readl(ofb->fbi, LCCR5);
> 
> +	if (!(lcd_readl(ofb->fbi, OVL1C1) & OVLxC1_OEN))
> +		return;
> +
>  	lcd_writel(ofb->fbi, OVL1C1, ofb->control[0] & ~OVLxC1_OEN);
> 
>  	lcd_writel(ofb->fbi, LCSR1, LCSR1_BS(1));
> @@ -636,7 +639,8 @@ static void overlay1fb_disable(struct pxafb_layer *ofb)
>  	lcd_writel(ofb->fbi, FBR1, ofb->fbi->fdadr[DMA_OV1] | 0x3);
> 
>  	if (wait_for_completion_timeout(&ofb->branch_done, 1 * HZ) == 0)
> -		pr_warning("%s: timeout disabling overlay1\n", __func__);
> +		pr_warning("%s: timeout disabling overlay1\n",
> +			__func__);
> 
>  	lcd_writel(ofb->fbi, LCCR5, lccr5);
>  }
> @@ -687,6 +691,9 @@ static void overlay2fb_disable(struct pxafb_layer *ofb)
>  {
>  	uint32_t lccr5 = lcd_readl(ofb->fbi, LCCR5);
> 
> +	if (!(lcd_readl(ofb->fbi, OVL2C1) & OVLxC1_OEN))
> +		return;
> +
>  	lcd_writel(ofb->fbi, OVL2C1, ofb->control[0] & ~OVLxC1_OEN);
> 
>  	lcd_writel(ofb->fbi, LCSR1, LCSR1_BS(2));
> @@ -696,7 +703,8 @@ static void overlay2fb_disable(struct pxafb_layer *ofb)
>  	lcd_writel(ofb->fbi, FBR4, ofb->fbi->fdadr[DMA_OV2_Cr] | 0x3);
> 
>  	if (wait_for_completion_timeout(&ofb->branch_done, 1 * HZ) == 0)
> -		pr_warning("%s: timeout disabling overlay2\n", __func__);
> +		pr_warning("%s: timeout disabling overlay2\n",
> +			__func__);
>  }
> 
>  static struct pxafb_layer_ops ofb_ops[] = {
> @@ -720,12 +728,10 @@ static int overlayfb_open(struct fb_info *info, int
> user) if (user == 0)
>  		return -ENODEV;
> 

Why are you getting rid of the atomic operations ?
Besides, "if (ofb->usage++ == 0)" looks suspicious, especially if you later 
declare it as uint32_t.

> -	/* allow only one user at a time */
> -	if (atomic_inc_and_test(&ofb->usage))
> -		return -EBUSY;
> +	if (ofb->usage++ == 0)
> +		/* unblank the base framebuffer */
> +		fb_blank(&ofb->fbi->fb, FB_BLANK_UNBLANK);
> 
> -	/* unblank the base framebuffer */
> -	fb_blank(&ofb->fbi->fb, FB_BLANK_UNBLANK);
>  	return 0;
>  }
> 
> @@ -733,12 +739,24 @@ static int overlayfb_release(struct fb_info *info,
> int user) {
>  	struct pxafb_layer *ofb = (struct pxafb_layer*) info;
> 

DTTO, why no atomic?

> -	atomic_dec(&ofb->usage);
> -	ofb->ops->disable(ofb);
> -
> -	free_pages_exact(ofb->video_mem, ofb->video_mem_size);
> -	ofb->video_mem = NULL;
> -	ofb->video_mem_size = 0;
> +	if (--ofb->usage == 0) {
> +		ofb->ops->disable(ofb);
> +		ofb->fb.var.height	= -1;
> +		ofb->fb.var.width	= -1;
> +		ofb->fb.var.xres = ofb->fb.var.xres_virtual = 0;
> +		ofb->fb.var.yres = ofb->fb.var.yres_virtual = 0;
> +
> +		mutex_lock(&ofb->fb.mm_lock);
> +		ofb->fb.fix.smem_start	= 0;
> +		ofb->fb.fix.smem_len	= 0;
> +		mutex_unlock(&ofb->fb.mm_lock);
> +
> +		if (ofb->video_mem) {
> +			free_pages_exact(ofb->video_mem, ofb->video_mem_size);
> +			ofb->video_mem = NULL;
> +			ofb->video_mem_size = 0;
> +		}
> +	}
>  	return 0;
>  }
> 
> @@ -817,7 +835,8 @@ static int overlayfb_map_video_memory(struct
> pxafb_layer *ofb) if (ofb->video_mem_size >= size)
>  			return 0;
> 
> -		free_pages_exact(ofb->video_mem, ofb->video_mem_size);
> +		/* don't re-allocate: userspace may have the buffer mapped */
> +		return -EINVAL;
>  	}
> 
>  	ofb->video_mem = alloc_pages_exact(size, GFP_KERNEL | __GFP_ZERO);
> @@ -891,7 +910,7 @@ static void __devinit init_pxafb_overlay(struct
> pxafb_info *fbi,
> 
>  	ofb->id = id;
>  	ofb->ops = &ofb_ops[id];

DTTO

> -	atomic_set(&ofb->usage, 0);
> +	ofb->usage = 0;
>  	ofb->fbi = fbi;
>  	init_completion(&ofb->branch_done);
>  }
> @@ -1368,7 +1387,8 @@ static int pxafb_activate_var(struct
> fb_var_screeninfo *var, (lcd_readl(fbi, LCCR3) != fbi->reg_lccr3) ||
>  	    (lcd_readl(fbi, LCCR4) != fbi->reg_lccr4) ||
>  	    (lcd_readl(fbi, FDADR0) != fbi->fdadr[0]) ||
> -	    (lcd_readl(fbi, FDADR1) != fbi->fdadr[1]))
> +	    ((fbi->lccr0 & LCCR0_SDS) &&
> +	    (lcd_readl(fbi, FDADR1) != fbi->fdadr[1])))
>  		pxafb_schedule_work(fbi, C_REENABLE);
> 
>  	return 0;
> @@ -1420,7 +1440,8 @@ static void pxafb_enable_controller(struct pxafb_info
> *fbi) lcd_writel(fbi, LCCR0, fbi->reg_lccr0 & ~LCCR0_ENB);
> 
>  	lcd_writel(fbi, FDADR0, fbi->fdadr[0]);
> -	lcd_writel(fbi, FDADR1, fbi->fdadr[1]);
> +	if (fbi->lccr0 & LCCR0_SDS)
> +		lcd_writel(fbi, FDADR1, fbi->fdadr[1]);
>  	lcd_writel(fbi, LCCR0, fbi->reg_lccr0 | LCCR0_ENB);
>  }
> 
> diff --git a/drivers/video/pxafb.h b/drivers/video/pxafb.h
> index 2353521..84e3ae1 100644
> --- a/drivers/video/pxafb.h
> +++ b/drivers/video/pxafb.h
> @@ -92,7 +92,7 @@ struct pxafb_layer_ops {
>  struct pxafb_layer {
>  	struct fb_info		fb;
>  	int			id;

DTTO, here.

> -	atomic_t		usage;
> +	uint32_t		usage;
>  	uint32_t		control[2];
> 
>  	struct pxafb_layer_ops	*ops;

  parent reply	other threads:[~2011-02-17 18:17 UTC|newest]

Thread overview: 76+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-02-02 20:46 [PATCH] ARM: PXA: Make PXA27x/PXA3xx overlay actually work Vasily Khoruzhick
2011-02-02 20:46 ` Vasily Khoruzhick
2011-02-13 13:31 ` Russell King - ARM Linux
2011-02-13 13:31   ` Russell King - ARM Linux
2011-02-15  7:35 ` Eric Miao
2011-02-15  7:35   ` Eric Miao
2011-02-15  8:41   ` Vasily Khoruzhick
2011-02-15  8:41     ` Vasily Khoruzhick
2011-02-15 11:51     ` Eric Miao
2011-02-15 11:51       ` Eric Miao
2011-02-15 11:58       ` Vasily Khoruzhick
2011-02-15 11:58         ` Vasily Khoruzhick
2011-02-15 13:36         ` Eric Miao
2011-02-15 13:36           ` Eric Miao
2011-02-15 13:51           ` Vasily Khoruzhick
2011-02-15 13:51             ` Vasily Khoruzhick
2011-02-15 15:12             ` Eric Miao
2011-02-15 15:12               ` Eric Miao
2011-02-15 15:18               ` Vasily Khoruzhick
2011-02-15 15:18                 ` Vasily Khoruzhick
2011-02-17  7:43                 ` [PATCH 1/2] ARM: PXA: PXAFB: Fix double-free issue Vasily Khoruzhick
2011-02-17  7:43                   ` Vasily Khoruzhick
2011-02-17  7:43                   ` [PATCH 2/2] ARM: PXA: PXAFB: fix plane Z-ordering problem Vasily Khoruzhick
2011-02-17  7:43                     ` Vasily Khoruzhick
2011-02-17 11:03                   ` [PATCH 1/2] ARM: PXA: PXAFB: Fix double-free issue Russell King - ARM Linux
2011-02-17 11:03                     ` Russell King - ARM Linux
2011-02-17 11:06                     ` Vasily Khoruzhick
2011-02-17 11:06                       ` Vasily Khoruzhick
2011-02-20 15:02                     ` [PATCH v2 1/3] " Vasily Khoruzhick
2011-02-20 15:02                       ` Vasily Khoruzhick
2011-02-20 15:02                       ` [PATCH v2 2/3] ARM: PXA: PXAFB: Fix plane Z-ordering problem Vasily Khoruzhick
2011-02-20 15:02                         ` Vasily Khoruzhick
2011-02-20 15:02                       ` [PATCH v2 3/3] ARM: PXA: PXAFB: Fix typo in ypos assignment Vasily Khoruzhick
2011-02-20 15:02                         ` Vasily Khoruzhick
2011-02-20 18:47                         ` Marek Vasut
2011-02-20 18:47                           ` Marek Vasut
2011-02-20 18:46                       ` [PATCH v2 1/3] ARM: PXA: PXAFB: Fix double-free issue Marek Vasut
2011-02-20 18:46                         ` Marek Vasut
2011-02-26 16:39                         ` Vasily Khoruzhick
2011-02-26 16:39                           ` Vasily Khoruzhick
2011-03-05 22:30                       ` Vasily Khoruzhick
2011-03-05 22:30                         ` Vasily Khoruzhick
2011-03-11  9:20                         ` [PATCH 1/4] ARM: PXA: PXAFB: rework pxafb overlay memory management Vasily Khoruzhick
2011-03-11  9:20                           ` Vasily Khoruzhick
2011-03-11  9:20                           ` [PATCH 2/4] ARM: PXA: PXAFB: Fix plane Z-ordering problem Vasily Khoruzhick
2011-03-11  9:20                             ` Vasily Khoruzhick
2011-03-16 13:16                             ` Eric Miao
2011-03-16 13:16                               ` Eric Miao
2011-03-11  9:20                           ` [PATCH 3/4] ARM: PXA: PXAFB: Fix typo in ypos assignment Vasily Khoruzhick
2011-03-11  9:20                             ` Vasily Khoruzhick
2011-03-11 21:35                             ` Marek Vasut
2011-03-11 21:35                               ` Marek Vasut
2011-03-16 13:15                             ` Eric Miao
2011-03-16 13:15                               ` Eric Miao
2011-03-11  9:20                           ` [PATCH 4/4] ARM: PXA: PXAFB: don't disable controller on cpufreq transition if overlay is in use Vasily Khoruzhick
2011-03-11  9:20                             ` Vasily Khoruzhick
2011-03-16 13:16                             ` [PATCH 4/4] ARM: PXA: PXAFB: don't disable controller on cpufreq Eric Miao
2011-03-16 13:16                               ` [PATCH 4/4] ARM: PXA: PXAFB: don't disable controller on cpufreq transition if overlay is in use Eric Miao
2011-03-11 21:34                           ` [PATCH 1/4] ARM: PXA: PXAFB: rework pxafb overlay memory management Marek Vasut
2011-03-11 21:34                             ` Marek Vasut
2011-03-11 21:46                             ` Vasily Khoruzhick
2011-03-11 21:46                               ` Vasily Khoruzhick
2011-03-16 11:17                               ` Eric Miao
2011-03-16 11:17                                 ` Eric Miao
2011-02-17 18:17                   ` Marek Vasut [this message]
2011-02-17 18:17                     ` [PATCH 1/2] ARM: PXA: PXAFB: Fix double-free issue Marek Vasut
2011-02-17 18:56                     ` Russell King - ARM Linux
2011-02-17 18:56                       ` Russell King - ARM Linux
2011-02-18  2:24                       ` Eric Miao
2011-02-18  2:24                         ` Eric Miao
2011-02-15  9:48   ` [PATCH] ARM: PXA: Make PXA27x/PXA3xx overlay actually work Russell King - ARM Linux
2011-02-15  9:48     ` Russell King - ARM Linux
2011-02-15 11:43     ` Eric Miao
2011-02-15 11:43       ` Eric Miao
2011-02-18 10:07 ` Sascha Hauer
2011-02-18 10:07   ` Sascha Hauer

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=201102171917.41442.marek.vasut@gmail.com \
    --to=marek.vasut@gmail.com \
    --cc=linux-arm-kernel@lists.infradead.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.