Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drm/radeon: deal with errors from framebuffer init path.

We've been getting occasional oops running a 32-bit kernel on a certain
system in our RHEL test hw. It appears that we fail to get sufficent ioremap
space for the framebuffer, and this leads to an oops.

This patch should fix the oops and leave a message in the logs we can
check for.

A future fix would probably to resize the console to a size that we can
ioremap.

Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Dave Airlie <airlied@redhat.com>

+26 -5
+15 -3
drivers/gpu/drm/radeon/radeon_display.c
··· 1078 1078 .create_handle = radeon_user_framebuffer_create_handle, 1079 1079 }; 1080 1080 1081 - void 1081 + int 1082 1082 radeon_framebuffer_init(struct drm_device *dev, 1083 1083 struct radeon_framebuffer *rfb, 1084 1084 struct drm_mode_fb_cmd2 *mode_cmd, 1085 1085 struct drm_gem_object *obj) 1086 1086 { 1087 + int ret; 1087 1088 rfb->obj = obj; 1088 - drm_framebuffer_init(dev, &rfb->base, &radeon_fb_funcs); 1089 + ret = drm_framebuffer_init(dev, &rfb->base, &radeon_fb_funcs); 1090 + if (ret) { 1091 + rfb->obj = NULL; 1092 + return ret; 1093 + } 1089 1094 drm_helper_mode_fill_fb_struct(&rfb->base, mode_cmd); 1095 + return 0; 1090 1096 } 1091 1097 1092 1098 static struct drm_framebuffer * ··· 1102 1096 { 1103 1097 struct drm_gem_object *obj; 1104 1098 struct radeon_framebuffer *radeon_fb; 1099 + int ret; 1105 1100 1106 1101 obj = drm_gem_object_lookup(dev, file_priv, mode_cmd->handles[0]); 1107 1102 if (obj == NULL) { ··· 1115 1108 if (radeon_fb == NULL) 1116 1109 return ERR_PTR(-ENOMEM); 1117 1110 1118 - radeon_framebuffer_init(dev, radeon_fb, mode_cmd, obj); 1111 + ret = radeon_framebuffer_init(dev, radeon_fb, mode_cmd, obj); 1112 + if (ret) { 1113 + kfree(radeon_fb); 1114 + drm_gem_object_unreference_unlocked(obj); 1115 + return NULL; 1116 + } 1119 1117 1120 1118 return &radeon_fb->base; 1121 1119 }
+10 -1
drivers/gpu/drm/radeon/radeon_fb.c
··· 209 209 sizes->surface_depth); 210 210 211 211 ret = radeonfb_create_pinned_object(rfbdev, &mode_cmd, &gobj); 212 + if (ret) { 213 + DRM_ERROR("failed to create fbcon object %d\n", ret); 214 + return ret; 215 + } 216 + 212 217 rbo = gem_to_radeon_bo(gobj); 213 218 214 219 /* okay we have an object now allocate the framebuffer */ ··· 225 220 226 221 info->par = rfbdev; 227 222 228 - radeon_framebuffer_init(rdev->ddev, &rfbdev->rfb, &mode_cmd, gobj); 223 + ret = radeon_framebuffer_init(rdev->ddev, &rfbdev->rfb, &mode_cmd, gobj); 224 + if (ret) { 225 + DRM_ERROR("failed to initalise framebuffer %d\n", ret); 226 + goto out_unref; 227 + } 229 228 230 229 fb = &rfbdev->rfb.base; 231 230
+1 -1
drivers/gpu/drm/radeon/radeon_mode.h
··· 649 649 u16 blue, int regno); 650 650 extern void radeon_crtc_fb_gamma_get(struct drm_crtc *crtc, u16 *red, u16 *green, 651 651 u16 *blue, int regno); 652 - void radeon_framebuffer_init(struct drm_device *dev, 652 + int radeon_framebuffer_init(struct drm_device *dev, 653 653 struct radeon_framebuffer *rfb, 654 654 struct drm_mode_fb_cmd2 *mode_cmd, 655 655 struct drm_gem_object *obj);