* [PATCH, RESEND] drm/vmwgfx: Don't double-free the mode stored in par->set_mode
@ 2019-03-18 14:47 Thomas Zimmermann
2019-03-18 16:59 ` Deepak Singh Rawat
0 siblings, 1 reply; 4+ messages in thread
From: Thomas Zimmermann @ 2019-03-18 14:47 UTC (permalink / raw)
To: thellstrom, linux-graphics-maintainer; +Cc: Thomas Zimmermann, dri-devel
When calling vmw_fb_set_par(), the mode stored in par->set_mode gets free'd
twice. The first free is in vmw_fb_kms_detach(), the second is near the
end of vmw_fb_set_par() under the name of 'old_mode'. The mode-setting code
only works correctly if the mode doesn't actually change. Removing 'old_mode'
in favor of using par->set_mode directly fixes the problem.
Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
---
drivers/gpu/drm/vmwgfx/vmwgfx_fb.c | 12 +++---------
1 file changed, 3 insertions(+), 9 deletions(-)
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c b/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c
index b913a56f3426..2a9112515f46 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c
@@ -564,11 +564,9 @@ static int vmw_fb_set_par(struct fb_info *info)
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC)
};
- struct drm_display_mode *old_mode;
struct drm_display_mode *mode;
int ret;
- old_mode = par->set_mode;
mode = drm_mode_duplicate(vmw_priv->dev, &new_mode);
if (!mode) {
DRM_ERROR("Could not create new fb mode.\n");
@@ -579,11 +577,7 @@ static int vmw_fb_set_par(struct fb_info *info)
mode->vdisplay = var->yres;
vmw_guess_mode_timing(mode);
- if (old_mode && drm_mode_equal(old_mode, mode)) {
- drm_mode_destroy(vmw_priv->dev, mode);
- mode = old_mode;
- old_mode = NULL;
- } else if (!vmw_kms_validate_mode_vram(vmw_priv,
+ if (!vmw_kms_validate_mode_vram(vmw_priv,
mode->hdisplay *
DIV_ROUND_UP(var->bits_per_pixel, 8),
mode->vdisplay)) {
@@ -620,8 +614,8 @@ static int vmw_fb_set_par(struct fb_info *info)
schedule_delayed_work(&par->local_work, 0);
out_unlock:
- if (old_mode)
- drm_mode_destroy(vmw_priv->dev, old_mode);
+ if (par->set_mode)
+ drm_mode_destroy(vmw_priv->dev, par->set_mode);
par->set_mode = mode;
mutex_unlock(&par->bo_mutex);
--
2.20.1
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel
^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [PATCH, RESEND] drm/vmwgfx: Don't double-free the mode stored in par->set_mode
2019-03-18 14:47 [PATCH, RESEND] drm/vmwgfx: Don't double-free the mode stored in par->set_mode Thomas Zimmermann
@ 2019-03-18 16:59 ` Deepak Singh Rawat
2019-03-19 17:56 ` Thomas Zimmermann
2019-03-19 18:18 ` Thomas Hellstrom
0 siblings, 2 replies; 4+ messages in thread
From: Deepak Singh Rawat @ 2019-03-18 16:59 UTC (permalink / raw)
To: Thomas Zimmermann, thellstrom, linux-graphics-maintainer; +Cc: dri-devel
Hi Thomas,
Thanks for doing this and somehow I missed the last patch, sorry about
that. Have some questions below otherwise the patch looks good to me.
Reviewed-by: Deepak Rawat <drawat@vmware.com>
I will include your changes in vmwgfx-next and run tests.
On Mon, 2019-03-18 at 15:47 +0100, Thomas Zimmermann wrote:
> When calling vmw_fb_set_par(), the mode stored in par->set_mode gets
> free'd
> twice. The first free is in vmw_fb_kms_detach(), the second is near
> the
> end of vmw_fb_set_par() under the name of 'old_mode'. The mode-
> setting code
> only works correctly if the mode doesn't actually change.
You mean to say that without your patch vmwgfx fb driver fail to change
the mode?
> Removing 'old_mode'
> in favor of using par->set_mode directly fixes the problem.
>
> Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
> ---
> drivers/gpu/drm/vmwgfx/vmwgfx_fb.c | 12 +++---------
> 1 file changed, 3 insertions(+), 9 deletions(-)
>
> diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c
> b/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c
> index b913a56f3426..2a9112515f46 100644
> --- a/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c
> +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c
> @@ -564,11 +564,9 @@ static int vmw_fb_set_par(struct fb_info *info)
> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
> DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC)
> };
> - struct drm_display_mode *old_mode;
> struct drm_display_mode *mode;
> int ret;
>
> - old_mode = par->set_mode;
> mode = drm_mode_duplicate(vmw_priv->dev, &new_mode);
> if (!mode) {
> DRM_ERROR("Could not create new fb mode.\n");
> @@ -579,11 +577,7 @@ static int vmw_fb_set_par(struct fb_info *info)
> mode->vdisplay = var->yres;
> vmw_guess_mode_timing(mode);
>
> - if (old_mode && drm_mode_equal(old_mode, mode)) {
> - drm_mode_destroy(vmw_priv->dev, mode);
> - mode = old_mode;
> - old_mode = NULL;
I am having hard time understanding original intention for this piece
of code. Was there a restriction to send pointer to old mode if mode
were same and that restriction don't hold anymore. Sorry I am not
familiar with this code area.
> - } else if (!vmw_kms_validate_mode_vram(vmw_priv,
> + if (!vmw_kms_validate_mode_vram(vmw_priv,
> mode->hdisplay *
> DIV_ROUND_UP(var-
> >bits_per_pixel, 8),
> mode->vdisplay)) {
> @@ -620,8 +614,8 @@ static int vmw_fb_set_par(struct fb_info *info)
> schedule_delayed_work(&par->local_work, 0);
>
> out_unlock:
> - if (old_mode)
> - drm_mode_destroy(vmw_priv->dev, old_mode);
> + if (par->set_mode)
> + drm_mode_destroy(vmw_priv->dev, par->set_mode);
> par->set_mode = mode;
>
> mutex_unlock(&par->bo_mutex);
> --
> 2.20.1
>
> _______________________________________________
> dri-devel mailing list
> dri-devel@lists.freedesktop.org
>
https://nam04.safelinks.protection.outlook.com/?url=https%3A%2F%2Flists.freedesktop.org%2Fmailman%2Flistinfo%2Fdri-devel&data=02%7C01%7Cdrawat%40vmware.com%7Cb1508247a3954fb0b08b08d6abb0bcd0%7Cb39138ca3cee4b4aa4d6cd83d9dd62f0%7C0%7C0%7C636885172908359973&sdata=AN6UTrMzxcVK7MC6bX3OxNbcyq0j4HdKt0dk1yyHOHc%3D&reserved=0
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH, RESEND] drm/vmwgfx: Don't double-free the mode stored in par->set_mode
2019-03-18 16:59 ` Deepak Singh Rawat
@ 2019-03-19 17:56 ` Thomas Zimmermann
2019-03-19 18:18 ` Thomas Hellstrom
1 sibling, 0 replies; 4+ messages in thread
From: Thomas Zimmermann @ 2019-03-19 17:56 UTC (permalink / raw)
To: Deepak Singh Rawat, thellstrom, linux-graphics-maintainer; +Cc: dri-devel
[-- Attachment #1.1.1: Type: text/plain, Size: 4149 bytes --]
Hi Deepak
Am 18.03.19 um 17:59 schrieb Deepak Singh Rawat:
> Hi Thomas,
>
> Thanks for doing this and somehow I missed the last patch, sorry about
> that. Have some questions below otherwise the patch looks good to me.
>
> Reviewed-by: Deepak Rawat <drawat@vmware.com>
>
> I will include your changes in vmwgfx-next and run tests.
Thank you.
>
> On Mon, 2019-03-18 at 15:47 +0100, Thomas Zimmermann wrote:
>> When calling vmw_fb_set_par(), the mode stored in par->set_mode gets
>> free'd
>> twice. The first free is in vmw_fb_kms_detach(), the second is near
>> the
>> end of vmw_fb_set_par() under the name of 'old_mode'. The mode-
>> setting code
>> only works correctly if the mode doesn't actually change.
>
> You mean to say that without your patch vmwgfx fb driver fail to change
> the mode?
Yes. It's hard to trigger as the usual resolution always appears to be
800x600. We (SUSE) have a customer with a custom X11 modeline setting,
which sets the resolution to something different. In this case, the
double-free bug happens.
>
>> Removing 'old_mode'
>> in favor of using par->set_mode directly fixes the problem.
>>
>> Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
>> ---
>> drivers/gpu/drm/vmwgfx/vmwgfx_fb.c | 12 +++---------
>> 1 file changed, 3 insertions(+), 9 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c
>> b/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c
>> index b913a56f3426..2a9112515f46 100644
>> --- a/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c
>> +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c
>> @@ -564,11 +564,9 @@ static int vmw_fb_set_par(struct fb_info *info)
>> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
>> DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC)
>> };
>> - struct drm_display_mode *old_mode;
>> struct drm_display_mode *mode;
>> int ret;
>>
>> - old_mode = par->set_mode;
>> mode = drm_mode_duplicate(vmw_priv->dev, &new_mode);
>> if (!mode) {
>> DRM_ERROR("Could not create new fb mode.\n");
>> @@ -579,11 +577,7 @@ static int vmw_fb_set_par(struct fb_info *info)
>> mode->vdisplay = var->yres;
>> vmw_guess_mode_timing(mode);
>>
>> - if (old_mode && drm_mode_equal(old_mode, mode)) {
>> - drm_mode_destroy(vmw_priv->dev, mode);
>> - mode = old_mode;
>> - old_mode = NULL;
>
> I am having hard time understanding original intention for this piece
> of code. Was there a restriction to send pointer to old mode if mode
> were same and that restriction don't hold anymore. Sorry I am not
> familiar with this code area.
Hmm, I can only guess about motivation: it looks like the author wanted
to keep the original value of 'par->set_mode' unless the mode really
changes. But it doesn't make a difference whether the pointer's value
changes or not.
Best regards
Thomas
>
>> - } else if (!vmw_kms_validate_mode_vram(vmw_priv,
>> + if (!vmw_kms_validate_mode_vram(vmw_priv,
>> mode->hdisplay *
>> DIV_ROUND_UP(var-
>>> bits_per_pixel, 8),
>> mode->vdisplay)) {
>> @@ -620,8 +614,8 @@ static int vmw_fb_set_par(struct fb_info *info)
>> schedule_delayed_work(&par->local_work, 0);
>>
>> out_unlock:
>> - if (old_mode)
>> - drm_mode_destroy(vmw_priv->dev, old_mode);
>> + if (par->set_mode)
>> + drm_mode_destroy(vmw_priv->dev, par->set_mode);
>> par->set_mode = mode;
>>
>> mutex_unlock(&par->bo_mutex);
>> --
>> 2.20.1
>>
>> _______________________________________________
>> dri-devel mailing list
>> dri-devel@lists.freedesktop.org
>>
> https://nam04.safelinks.protection.outlook.com/?url=https%3A%2F%2Flists.freedesktop.org%2Fmailman%2Flistinfo%2Fdri-devel&data=02%7C01%7Cdrawat%40vmware.com%7Cb1508247a3954fb0b08b08d6abb0bcd0%7Cb39138ca3cee4b4aa4d6cd83d9dd62f0%7C0%7C0%7C636885172908359973&sdata=AN6UTrMzxcVK7MC6bX3OxNbcyq0j4HdKt0dk1yyHOHc%3D&reserved=0
>
--
Thomas Zimmermann
Graphics Driver Developer
SUSE Linux GmbH, Maxfeldstr. 5, D-90409 Nürnberg
Tel: +49-911-74053-0; Fax: +49-911-7417755; https://www.suse.com/
SUSE Linux GmbH, GF: Felix Imendörffer, Jane Smithard,
Graham Norton, HRB 21284 (AG Nürnberg)
[-- Attachment #1.2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 488 bytes --]
[-- Attachment #2: Type: text/plain, Size: 159 bytes --]
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH, RESEND] drm/vmwgfx: Don't double-free the mode stored in par->set_mode
2019-03-18 16:59 ` Deepak Singh Rawat
2019-03-19 17:56 ` Thomas Zimmermann
@ 2019-03-19 18:18 ` Thomas Hellstrom
1 sibling, 0 replies; 4+ messages in thread
From: Thomas Hellstrom @ 2019-03-19 18:18 UTC (permalink / raw)
To: Linux-graphics-maintainer, Deepak Singh Rawat, tzimmermann; +Cc: dri-devel
Hi, Deepak,
On Mon, 2019-03-18 at 09:59 -0700, Deepak Singh Rawat wrote:
> Hi Thomas,
>
> Thanks for doing this and somehow I missed the last patch, sorry
> about
> that. Have some questions below otherwise the patch looks good to me.
>
> Reviewed-by: Deepak Rawat <drawat@vmware.com>
>
> I will include your changes in vmwgfx-next and run tests.
I think we need to run this through vmwgfx-fixes and CC stable. I'll
pick up the patch for that.
>
> On Mon, 2019-03-18 at 15:47 +0100, Thomas Zimmermann wrote:
> > When calling vmw_fb_set_par(), the mode stored in par->set_mode
> > gets
> > free'd
> > twice. The first free is in vmw_fb_kms_detach(), the second is near
> > the
> > end of vmw_fb_set_par() under the name of 'old_mode'. The mode-
> > setting code
> > only works correctly if the mode doesn't actually change.
>
> You mean to say that without your patch vmwgfx fb driver fail to
> change
> the mode?
>
> > Removing 'old_mode'
> > in favor of using par->set_mode directly fixes the problem.
> >
> > Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
> > ---
> > drivers/gpu/drm/vmwgfx/vmwgfx_fb.c | 12 +++---------
> > 1 file changed, 3 insertions(+), 9 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c
> > b/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c
> > index b913a56f3426..2a9112515f46 100644
> > --- a/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c
> > +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c
> > @@ -564,11 +564,9 @@ static int vmw_fb_set_par(struct fb_info
> > *info)
> > 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
> > DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC)
> > };
> > - struct drm_display_mode *old_mode;
> > struct drm_display_mode *mode;
> > int ret;
> >
> > - old_mode = par->set_mode;
> > mode = drm_mode_duplicate(vmw_priv->dev, &new_mode);
> > if (!mode) {
> > DRM_ERROR("Could not create new fb mode.\n");
> > @@ -579,11 +577,7 @@ static int vmw_fb_set_par(struct fb_info
> > *info)
> > mode->vdisplay = var->yres;
> > vmw_guess_mode_timing(mode);
> >
> > - if (old_mode && drm_mode_equal(old_mode, mode)) {
> > - drm_mode_destroy(vmw_priv->dev, mode);
> > - mode = old_mode;
> > - old_mode = NULL;
>
> I am having hard time understanding original intention for this piece
> of code. Was there a restriction to send pointer to old mode if mode
> were same and that restriction don't hold anymore. Sorry I am not
> familiar with this code area.
It looks like that code is there to reuse the old mode if possible. In
that case things work, but if a new mode is indeed created, the old
mode will be double-freed :(
/Thomas
>
> > - } else if (!vmw_kms_validate_mode_vram(vmw_priv,
> > + if (!vmw_kms_validate_mode_vram(vmw_priv,
> > mode->hdisplay *
> > DIV_ROUND_UP(var-
> > > bits_per_pixel, 8),
> > mode->vdisplay)) {
> > @@ -620,8 +614,8 @@ static int vmw_fb_set_par(struct fb_info *info)
> > schedule_delayed_work(&par->local_work, 0);
> >
> > out_unlock:
> > - if (old_mode)
> > - drm_mode_destroy(vmw_priv->dev, old_mode);
> > + if (par->set_mode)
> > + drm_mode_destroy(vmw_priv->dev, par->set_mode);
> > par->set_mode = mode;
> >
> > mutex_unlock(&par->bo_mutex);
> > --
> > 2.20.1
> >
> > _______________________________________________
> > dri-devel mailing list
> > dri-devel@lists.freedesktop.org
> >
> https://nam04.safelinks.protection.outlook.com/?url=https%3A%2F%2Flists.freedesktop.org%2Fmailman%2Flistinfo%2Fdri-devel&data=02%7C01%7Cdrawat%40vmware.com%7Cb1508247a3954fb0b08b08d6abb0bcd0%7Cb39138ca3cee4b4aa4d6cd83d9dd62f0%7C0%7C0%7C636885172908359973&sdata=AN6UTrMzxcVK7MC6bX3OxNbcyq0j4HdKt0dk1yyHOHc%3D&reserved=0
>
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2019-03-19 18:18 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-03-18 14:47 [PATCH, RESEND] drm/vmwgfx: Don't double-free the mode stored in par->set_mode Thomas Zimmermann
2019-03-18 16:59 ` Deepak Singh Rawat
2019-03-19 17:56 ` Thomas Zimmermann
2019-03-19 18:18 ` Thomas Hellstrom
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).