summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>2012-04-02 13:38:19 +1000
committerDave Airlie <airlied@redhat.com>2012-04-02 11:06:33 +0100
commitd06221c0617ab6d0bc41c4980cefdd9c8cc9a1c1 (patch)
tree5ec7d22876848e194036c019aaea9f6a14e63c2a
parentea71f98d680c9ac768a7849d26d7ce4744064510 (diff)
downloadlinux-d06221c0617ab6d0bc41c4980cefdd9c8cc9a1c1.tar.gz
linux-d06221c0617ab6d0bc41c4980cefdd9c8cc9a1c1.tar.xz
linux-d06221c0617ab6d0bc41c4980cefdd9c8cc9a1c1.zip
nouveau/bios: Fix tracking of BIOS image data
The code tries various methods for retreiving the BIOS data. However it doesn't clear the bios->data pointer between the iterations. In some cases, the shadow() method will fail and not update bios->data at all, which will cause us to "score" the old data and incorrectly attribute that score to the new method. This can cause double frees later when disposing of the unused data. Additionally, we were not freeing the data for methods that fail the score test (we only freed when a "best" is superseeded, not when the new method has a lower score than the exising "best"). Fix that as well. Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org> Acked-by: Ben Skeggs <bskeggs@redhat.com> Signed-off-by: Dave Airlie <airlied@redhat.com>
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_bios.c4
1 files changed, 3 insertions, 1 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_bios.c b/drivers/gpu/drm/nouveau/nouveau_bios.c
index 80963d05b54a..1947d6139a38 100644
--- a/drivers/gpu/drm/nouveau/nouveau_bios.c
+++ b/drivers/gpu/drm/nouveau/nouveau_bios.c
@@ -273,6 +273,7 @@ bios_shadow(struct drm_device *dev)
mthd->score = score_vbios(bios, mthd->rw);
mthd->size = bios->length;
mthd->data = bios->data;
+ bios->data = NULL;
} while (mthd->score != 3 && (++mthd)->shadow);
mthd = shadow_methods;
@@ -281,7 +282,8 @@ bios_shadow(struct drm_device *dev)
if (mthd->score > best->score) {
kfree(best->data);
best = mthd;
- }
+ } else
+ kfree(mthd->data);
} while ((++mthd)->shadow);
if (best->score) {