diff options
| author | Emil Velikov <emil.l.velikov@gmail.com> | 2011-08-21 17:48:12 -0400 |
|---|---|---|
| committer | Ben Skeggs <bskeggs@redhat.com> | 2011-09-09 03:23:56 -0400 |
| commit | ffbc559b0699891c6deb9fd2b4750671eab94999 (patch) | |
| tree | eeb1dce1e2a809138353fdba7f81ad2d210a47a1 /drivers | |
| parent | ddf28352b80c86754a6424e3a61e8bdf9213b3c7 (diff) | |
drm/nv50/crtc: Bail out if FB is not bound to crtc
Fixes possbile NULL pointer dereference
Resolves 'kernel crash in nv50_crtc_do_mode_set_base during shutdown'
https://bugs.freedesktop.org/show_bug.cgi?id=40005
Signed-off-by: Emil Velikov <emil.l.velikov@gmail.com>
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Diffstat (limited to 'drivers')
| -rw-r--r-- | drivers/gpu/drm/nouveau/nv50_crtc.c | 12 |
1 files changed, 10 insertions, 2 deletions
diff --git a/drivers/gpu/drm/nouveau/nv50_crtc.c b/drivers/gpu/drm/nouveau/nv50_crtc.c index 46ad59ea2185..5d989073ba6e 100644 --- a/drivers/gpu/drm/nouveau/nv50_crtc.c +++ b/drivers/gpu/drm/nouveau/nv50_crtc.c | |||
| @@ -519,12 +519,18 @@ nv50_crtc_do_mode_set_base(struct drm_crtc *crtc, | |||
| 519 | struct drm_device *dev = nv_crtc->base.dev; | 519 | struct drm_device *dev = nv_crtc->base.dev; |
| 520 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 520 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
| 521 | struct nouveau_channel *evo = nv50_display(dev)->master; | 521 | struct nouveau_channel *evo = nv50_display(dev)->master; |
| 522 | struct drm_framebuffer *drm_fb = nv_crtc->base.fb; | 522 | struct drm_framebuffer *drm_fb; |
| 523 | struct nouveau_framebuffer *fb = nouveau_framebuffer(drm_fb); | 523 | struct nouveau_framebuffer *fb; |
| 524 | int ret; | 524 | int ret; |
| 525 | 525 | ||
| 526 | NV_DEBUG_KMS(dev, "index %d\n", nv_crtc->index); | 526 | NV_DEBUG_KMS(dev, "index %d\n", nv_crtc->index); |
| 527 | 527 | ||
| 528 | /* no fb bound */ | ||
| 529 | if (!atomic && !crtc->fb) { | ||
| 530 | NV_DEBUG_KMS(dev, "No FB bound\n"); | ||
| 531 | return 0; | ||
| 532 | } | ||
| 533 | |||
| 528 | /* If atomic, we want to switch to the fb we were passed, so | 534 | /* If atomic, we want to switch to the fb we were passed, so |
| 529 | * now we update pointers to do that. (We don't pin; just | 535 | * now we update pointers to do that. (We don't pin; just |
| 530 | * assume we're already pinned and update the base address.) | 536 | * assume we're already pinned and update the base address.) |
| @@ -533,6 +539,8 @@ nv50_crtc_do_mode_set_base(struct drm_crtc *crtc, | |||
| 533 | drm_fb = passed_fb; | 539 | drm_fb = passed_fb; |
| 534 | fb = nouveau_framebuffer(passed_fb); | 540 | fb = nouveau_framebuffer(passed_fb); |
| 535 | } else { | 541 | } else { |
| 542 | drm_fb = crtc->fb; | ||
| 543 | fb = nouveau_framebuffer(crtc->fb); | ||
| 536 | /* If not atomic, we can go ahead and pin, and unpin the | 544 | /* If not atomic, we can go ahead and pin, and unpin the |
| 537 | * old fb we were passed. | 545 | * old fb we were passed. |
| 538 | */ | 546 | */ |
