On Tue, Mar 6, 2012 at 5:48 AM, Dave Airlie <airlied at gmail.com> wrote: > From: Dave Airlie <airlied at redhat.com> > > We've been seeing a very occasional oops on a 32-bit rn50 platform running EL6 > kernels at boot. It seems to be due to one of these functions failing and > us then accessing a NULL-300 pointer. > > This should prevent the oops and give some info in the logs as to what is > going on. > > Signed-off-by: Dave Airlie <airlied at redhat.com>
Reviewed-by: Alex Deucher <alexander.deucher at amd.com> > --- > ?drivers/gpu/drm/radeon/radeon_display.c | ? 18 +++++++++++++++--- > ?drivers/gpu/drm/radeon/radeon_fb.c ? ? ?| ? 11 ++++++++++- > ?drivers/gpu/drm/radeon/radeon_mode.h ? ?| ? ?2 +- > ?3 files changed, 26 insertions(+), 5 deletions(-) > > diff --git a/drivers/gpu/drm/radeon/radeon_display.c > b/drivers/gpu/drm/radeon/radeon_display.c > index 8c49fef..3d31433 100644 > --- a/drivers/gpu/drm/radeon/radeon_display.c > +++ b/drivers/gpu/drm/radeon/radeon_display.c > @@ -1078,15 +1078,21 @@ static const struct drm_framebuffer_funcs > radeon_fb_funcs = { > ? ? ? ?.create_handle = radeon_user_framebuffer_create_handle, > ?}; > > -void > +int > ?radeon_framebuffer_init(struct drm_device *dev, > ? ? ? ? ? ? ? ? ? ? ? ?struct radeon_framebuffer *rfb, > ? ? ? ? ? ? ? ? ? ? ? ?struct drm_mode_fb_cmd2 *mode_cmd, > ? ? ? ? ? ? ? ? ? ? ? ?struct drm_gem_object *obj) > ?{ > + ? ? ? int ret; > ? ? ? ?rfb->obj = obj; > - ? ? ? drm_framebuffer_init(dev, &rfb->base, &radeon_fb_funcs); > + ? ? ? ret = drm_framebuffer_init(dev, &rfb->base, &radeon_fb_funcs); > + ? ? ? if (ret) { > + ? ? ? ? ? ? ? rfb->obj = NULL; > + ? ? ? ? ? ? ? return ret; > + ? ? ? } > ? ? ? ?drm_helper_mode_fill_fb_struct(&rfb->base, mode_cmd); > + ? ? ? return 0; > ?} > > ?static struct drm_framebuffer * > @@ -1096,6 +1102,7 @@ radeon_user_framebuffer_create(struct drm_device *dev, > ?{ > ? ? ? ?struct drm_gem_object *obj; > ? ? ? ?struct radeon_framebuffer *radeon_fb; > + ? ? ? int ret; > > ? ? ? ?obj = drm_gem_object_lookup(dev, file_priv, mode_cmd->handles[0]); > ? ? ? ?if (obj == ?NULL) { > @@ -1108,7 +1115,12 @@ radeon_user_framebuffer_create(struct drm_device *dev, > ? ? ? ?if (radeon_fb == NULL) > ? ? ? ? ? ? ? ?return ERR_PTR(-ENOMEM); > > - ? ? ? radeon_framebuffer_init(dev, radeon_fb, mode_cmd, obj); > + ? ? ? ret = radeon_framebuffer_init(dev, radeon_fb, mode_cmd, obj); > + ? ? ? if (ret) { > + ? ? ? ? ? ? ? kfree(radeon_fb); > + ? ? ? ? ? ? ? drm_gem_object_unreference_unlocked(obj); > + ? ? ? ? ? ? ? return NULL; > + ? ? ? } > > ? ? ? ?return &radeon_fb->base; > ?} > diff --git a/drivers/gpu/drm/radeon/radeon_fb.c > b/drivers/gpu/drm/radeon/radeon_fb.c > index cf2bf35..195471c 100644 > --- a/drivers/gpu/drm/radeon/radeon_fb.c > +++ b/drivers/gpu/drm/radeon/radeon_fb.c > @@ -209,6 +209,11 @@ static int radeonfb_create(struct radeon_fbdev *rfbdev, > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? > ?sizes->surface_depth); > > ? ? ? ?ret = radeonfb_create_pinned_object(rfbdev, &mode_cmd, &gobj); > + ? ? ? if (ret) { > + ? ? ? ? ? ? ? DRM_ERROR("failed to create fbcon object %d\n", ret); > + ? ? ? ? ? ? ? return ret; > + ? ? ? } > + > ? ? ? ?rbo = gem_to_radeon_bo(gobj); > > ? ? ? ?/* okay we have an object now allocate the framebuffer */ > @@ -220,7 +225,11 @@ static int radeonfb_create(struct radeon_fbdev *rfbdev, > > ? ? ? ?info->par = rfbdev; > > - ? ? ? radeon_framebuffer_init(rdev->ddev, &rfbdev->rfb, &mode_cmd, gobj); > + ? ? ? ret = radeon_framebuffer_init(rdev->ddev, &rfbdev->rfb, &mode_cmd, > gobj); > + ? ? ? if (ret) { > + ? ? ? ? ? ? ? DRM_ERROR("failed to initalise framebuffer %d\n", ret); > + ? ? ? ? ? ? ? goto out_unref; > + ? ? ? } > > ? ? ? ?fb = &rfbdev->rfb.base; > > diff --git a/drivers/gpu/drm/radeon/radeon_mode.h > b/drivers/gpu/drm/radeon/radeon_mode.h > index 4330e32..8a85598 100644 > --- a/drivers/gpu/drm/radeon/radeon_mode.h > +++ b/drivers/gpu/drm/radeon/radeon_mode.h > @@ -649,7 +649,7 @@ extern void radeon_crtc_fb_gamma_set(struct drm_crtc > *crtc, u16 red, u16 green, > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? u16 blue, int regno); > ?extern void radeon_crtc_fb_gamma_get(struct drm_crtc *crtc, u16 *red, u16 > *green, > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? u16 *blue, int regno); > -void radeon_framebuffer_init(struct drm_device *dev, > +int radeon_framebuffer_init(struct drm_device *dev, > ? ? ? ? ? ? ? ? ? ? ? ? ? ? struct radeon_framebuffer *rfb, > ? ? ? ? ? ? ? ? ? ? ? ? ? ? struct drm_mode_fb_cmd2 *mode_cmd, > ? ? ? ? ? ? ? ? ? ? ? ? ? ? struct drm_gem_object *obj); > -- > 1.7.7.6 > > _______________________________________________ > dri-devel mailing list > dri-devel at lists.freedesktop.org > http://lists.freedesktop.org/mailman/listinfo/dri-devel