Marcin Slusarz
2011-Mar-10 21:43 UTC
[Nouveau] [PATCH] drm/nouveau: fix oops on unload with disabled LVDS panel
Fixes: https://bugs.freedesktop.org/show_bug.cgi?id=35135 BUG: unable to handle kernel NULL pointer dereference at 000002d8 IP: [<f83694af>] nv04_dfp_restore+0x7f/0xd0 [nouveau] (...) Call Trace: [<f8372208>] nv04_display_destroy+0xa8/0x140 [nouveau] [<f830344a>] nouveau_unload+0x2a/0x160 [nouveau] [<f80d98fb>] drm_put_dev+0xbb/0x1b0 [drm] [<f8301025>] nouveau_pci_remove+0x15/0x20 [nouveau] [<c1292ad4>] pci_device_remove+0x44/0xf0 [<c13339d1>] __device_release_driver+0x51/0xb0 [<c133401f>] driver_detach+0x8f/0xa0 [<c13338a3>] bus_remove_driver+0x63/0xa0 [<c13340a9>] driver_unregister+0x49/0x80 [<c1182f84>] ? sysfs_remove_file+0x14/0x20 [<c1292bb2>] pci_unregister_driver+0x32/0x90 [<c109b1da>] ? __stop_machine+0x5a/0x70 [<f80d3f93>] drm_exit+0x83/0x90 [drm] [<f837875d>] nouveau_exit+0x1b/0x8be [nouveau] [<c1087b5b>] sys_delete_module+0x13b/0x1f0 [<c1104c3e>] ? do_munmap+0x1fe/0x280 [<c1104780>] ? arch_unmap_area_topdown+0x0/0x20 [<c15096f4>] syscall_call+0x7/0xb Reported-by: Francesco Marella <francesco.marella at gmail.com> Tested-by: Francesco Marella <francesco.marella at gmail.com> Signed-off-by: Marcin Slusarz <marcin.slusarz at gmail.com> --- drivers/gpu/drm/nouveau/nv04_dfp.c | 20 +++++++++++++++----- 1 files changed, 15 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nv04_dfp.c b/drivers/gpu/drm/nouveau/nv04_dfp.c index c82db37..b985ab3 100644 --- a/drivers/gpu/drm/nouveau/nv04_dfp.c +++ b/drivers/gpu/drm/nouveau/nv04_dfp.c @@ -579,15 +579,24 @@ static void nv04_dfp_restore(struct drm_encoder *encoder) struct drm_device *dev = encoder->dev; struct drm_nouveau_private *dev_priv = dev->dev_private; int head = nv_encoder->restore.head; + struct nouveau_connector *connector; + struct drm_display_mode *native_mode; if (nv_encoder->dcb->type == OUTPUT_LVDS) { - struct drm_display_mode *native_mode = nouveau_encoder_connector_get(nv_encoder)->native_mode; - if (native_mode) - call_lvds_script(dev, nv_encoder->dcb, head, LVDS_PANEL_ON, - native_mode->clock); - else + connector = nouveau_encoder_connector_get(nv_encoder); + if (!connector) { + NV_ERROR(dev, "No connector for LVDS encoder. Skipping restore.\n"); + goto out; + } + + native_mode = connector->native_mode; + if (!native_mode) { NV_ERROR(dev, "Not restoring LVDS without native mode\n"); + goto out; + } + call_lvds_script(dev, nv_encoder->dcb, head, LVDS_PANEL_ON, + native_mode->clock); } else if (nv_encoder->dcb->type == OUTPUT_TMDS) { int clock = nouveau_hw_pllvals_to_clk (&dev_priv->saved_reg.crtc_reg[head].pllvals); @@ -595,6 +604,7 @@ static void nv04_dfp_restore(struct drm_encoder *encoder) run_tmds_table(dev, nv_encoder->dcb, head, clock); } +out: nv_encoder->last_dpms = NV_DPMS_CLEARED; } -- 1.7.4.rc3
Francisco Jerez
2011-Mar-20 17:45 UTC
[Nouveau] [PATCH] drm/nouveau: fix oops on unload with disabled LVDS panel
Marcin Slusarz <marcin.slusarz at gmail.com> writes:> Fixes: https://bugs.freedesktop.org/show_bug.cgi?id=35135 > BUG: unable to handle kernel NULL pointer dereference at 000002d8 > IP: [<f83694af>] nv04_dfp_restore+0x7f/0xd0 [nouveau] > (...) > Call Trace: > [<f8372208>] nv04_display_destroy+0xa8/0x140 [nouveau] > [<f830344a>] nouveau_unload+0x2a/0x160 [nouveau] > [<f80d98fb>] drm_put_dev+0xbb/0x1b0 [drm] > [<f8301025>] nouveau_pci_remove+0x15/0x20 [nouveau] > [<c1292ad4>] pci_device_remove+0x44/0xf0 > [<c13339d1>] __device_release_driver+0x51/0xb0 > [<c133401f>] driver_detach+0x8f/0xa0 > [<c13338a3>] bus_remove_driver+0x63/0xa0 > [<c13340a9>] driver_unregister+0x49/0x80 > [<c1182f84>] ? sysfs_remove_file+0x14/0x20 > [<c1292bb2>] pci_unregister_driver+0x32/0x90 > [<c109b1da>] ? __stop_machine+0x5a/0x70 > [<f80d3f93>] drm_exit+0x83/0x90 [drm] > [<f837875d>] nouveau_exit+0x1b/0x8be [nouveau] > [<c1087b5b>] sys_delete_module+0x13b/0x1f0 > [<c1104c3e>] ? do_munmap+0x1fe/0x280 > [<c1104780>] ? arch_unmap_area_topdown+0x0/0x20 > [<c15096f4>] syscall_call+0x7/0xb > > Reported-by: Francesco Marella <francesco.marella at gmail.com> > Tested-by: Francesco Marella <francesco.marella at gmail.com> > Signed-off-by: Marcin Slusarz <marcin.slusarz at gmail.com> > --- > drivers/gpu/drm/nouveau/nv04_dfp.c | 20 +++++++++++++++----- > 1 files changed, 15 insertions(+), 5 deletions(-) > > diff --git a/drivers/gpu/drm/nouveau/nv04_dfp.c b/drivers/gpu/drm/nouveau/nv04_dfp.c > index c82db37..b985ab3 100644 > --- a/drivers/gpu/drm/nouveau/nv04_dfp.c > +++ b/drivers/gpu/drm/nouveau/nv04_dfp.c > @@ -579,15 +579,24 @@ static void nv04_dfp_restore(struct drm_encoder *encoder) > struct drm_device *dev = encoder->dev; > struct drm_nouveau_private *dev_priv = dev->dev_private; > int head = nv_encoder->restore.head; > + struct nouveau_connector *connector; > + struct drm_display_mode *native_mode; > > if (nv_encoder->dcb->type == OUTPUT_LVDS) { > - struct drm_display_mode *native_mode = nouveau_encoder_connector_get(nv_encoder)->native_mode; > - if (native_mode) > - call_lvds_script(dev, nv_encoder->dcb, head, LVDS_PANEL_ON, > - native_mode->clock); > - else > + connector = nouveau_encoder_connector_get(nv_encoder); > + if (!connector) { > + NV_ERROR(dev, "No connector for LVDS encoder. Skipping restore.\n"); > + goto out; > + } > + > + native_mode = connector->native_mode; > + if (!native_mode) { > NV_ERROR(dev, "Not restoring LVDS without native mode\n"); > + goto out; > + } > > + call_lvds_script(dev, nv_encoder->dcb, head, LVDS_PANEL_ON, > + native_mode->clock); > } else if (nv_encoder->dcb->type == OUTPUT_TMDS) { > int clock = nouveau_hw_pllvals_to_clk > (&dev_priv->saved_reg.crtc_reg[head].pllvals); > @@ -595,6 +604,7 @@ static void nv04_dfp_restore(struct drm_encoder *encoder) > run_tmds_table(dev, nv_encoder->dcb, head, clock); > } > > +out: > nv_encoder->last_dpms = NV_DPMS_CLEARED; > }Thanks, I've pushed a slightly simplified version of this patch. -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 229 bytes Desc: not available URL: <http://lists.freedesktop.org/archives/nouveau/attachments/20110320/364d9562/attachment.pgp>