aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm
diff options
context:
space:
mode:
authorEmil Velikov <emil.l.velikov@gmail.com>2011-08-25 16:36:51 -0400
committerBen Skeggs <bskeggs@redhat.com>2011-09-09 03:24:21 -0400
commit0e83bb4eee1c504ab98367b4f7d1bc337ab213d2 (patch)
treefac5c78b418ba4562cc02246dfbcd61c9032a90f /drivers/gpu/drm
parent1bf27066017c820b8ab2a1ac8430ea470c2de0c3 (diff)
drm/nv04/crtc: Bail out if FB is not bound to crtc
This commit resolves a possible 'NULL pointer dereference' It uses the same approach as radeon, intel and nouveau/nv50 Fixes bug 'Nouveau: Kernel oops when unplugging external monitor' https://bugs.freedesktop.org/show_bug.cgi?id=40336 Signed-off-by: Emil Velikov <emil.l.velikov@gmail.com> Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Diffstat (limited to 'drivers/gpu/drm')
-rw-r--r--drivers/gpu/drm/nouveau/nv04_crtc.c15
1 files changed, 13 insertions, 2 deletions
diff --git a/drivers/gpu/drm/nouveau/nv04_crtc.c b/drivers/gpu/drm/nouveau/nv04_crtc.c
index 118261d4927..5e45398a9e2 100644
--- a/drivers/gpu/drm/nouveau/nv04_crtc.c
+++ b/drivers/gpu/drm/nouveau/nv04_crtc.c
@@ -781,11 +781,20 @@ nv04_crtc_do_mode_set_base(struct drm_crtc *crtc,
781 struct drm_device *dev = crtc->dev; 781 struct drm_device *dev = crtc->dev;
782 struct drm_nouveau_private *dev_priv = dev->dev_private; 782 struct drm_nouveau_private *dev_priv = dev->dev_private;
783 struct nv04_crtc_reg *regp = &dev_priv->mode_reg.crtc_reg[nv_crtc->index]; 783 struct nv04_crtc_reg *regp = &dev_priv->mode_reg.crtc_reg[nv_crtc->index];
784 struct drm_framebuffer *drm_fb = nv_crtc->base.fb; 784 struct drm_framebuffer *drm_fb;
785 struct nouveau_framebuffer *fb = nouveau_framebuffer(drm_fb); 785 struct nouveau_framebuffer *fb;
786 int arb_burst, arb_lwm; 786 int arb_burst, arb_lwm;
787 int ret; 787 int ret;
788 788
789 NV_DEBUG_KMS(dev, "index %d\n", nv_crtc->index);
790
791 /* no fb bound */
792 if (!atomic && !crtc->fb) {
793 NV_DEBUG_KMS(dev, "No FB bound\n");
794 return 0;
795 }
796
797
789 /* If atomic, we want to switch to the fb we were passed, so 798 /* If atomic, we want to switch to the fb we were passed, so
790 * now we update pointers to do that. (We don't pin; just 799 * now we update pointers to do that. (We don't pin; just
791 * assume we're already pinned and update the base address.) 800 * assume we're already pinned and update the base address.)
@@ -794,6 +803,8 @@ nv04_crtc_do_mode_set_base(struct drm_crtc *crtc,
794 drm_fb = passed_fb; 803 drm_fb = passed_fb;
795 fb = nouveau_framebuffer(passed_fb); 804 fb = nouveau_framebuffer(passed_fb);
796 } else { 805 } else {
806 drm_fb = crtc->fb;
807 fb = nouveau_framebuffer(crtc->fb);
797 /* If not atomic, we can go ahead and pin, and unpin the 808 /* If not atomic, we can go ahead and pin, and unpin the
798 * old fb we were passed. 809 * old fb we were passed.
799 */ 810 */