drm/tegra: Fix error handling cleanup

The DRM driver's ->load() implementation didn't do a good job (no job at
all really) cleaning up on failure. Fix that by undoing any prior setup
when an error occurs. This requires a bit of rework to make it possible
to clean up fbdev midway.

This was tested by injecting errors at various points during the
initialization sequence and verifying that error cleanup didn't crash
and no memory leaked (using kmemleak).

Reported-by: Stéphane Marchesin <marcheu@chromium.org>
Reported-by: Sean Paul <seanpaul@chromium.org>
Reviewed-by: Sean Paul <seanpaul@chromium.org>
Signed-off-by: Thierry Reding <treding@nvidia.com>
This commit is contained in:
Thierry Reding
2014-11-06 14:12:08 +01:00
parent 53ea72132d
commit 1d1e6fe9b5
3 changed files with 34 additions and 7 deletions

View File

@@ -42,13 +42,13 @@ static int tegra_drm_load(struct drm_device *drm, unsigned long flags)
err = tegra_drm_fb_prepare(drm);
if (err < 0)
return err;
goto config;
drm_kms_helper_poll_init(drm);
err = host1x_device_init(device);
if (err < 0)
return err;
goto fbdev;
/*
* We don't use the drm_irq_install() helpers provided by the DRM
@@ -59,13 +59,25 @@ static int tegra_drm_load(struct drm_device *drm, unsigned long flags)
err = drm_vblank_init(drm, drm->mode_config.num_crtc);
if (err < 0)
return err;
goto device;
err = tegra_drm_fb_init(drm);
if (err < 0)
return err;
goto vblank;
return 0;
vblank:
drm_vblank_cleanup(drm);
device:
host1x_device_exit(device);
fbdev:
drm_kms_helper_poll_fini(drm);
tegra_drm_fb_free(drm);
config:
drm_mode_config_cleanup(drm);
kfree(tegra);
return err;
}
static int tegra_drm_unload(struct drm_device *drm)