On Sat, Jun 9, 2012 at 12:15 PM, Boszormenyi Zoltan <zboszor@xxxxx> wrote: > 2012-06-09 16:57 keltezéssel, j.glisse@xxxxxxxxx írta: >> >> From: Jerome Glisse<jglisse@xxxxxxxxxx> >> >> Fix regresson since the introduction of command stream checking on >> evergreen (thread referenced below). Issue is cause by ddx allocating >> bo with formula width*height*bpp while programming the GPU command >> stream with ALIGN(height, 8). In some case (where page alignment does >> not hide the extra size bo should be according to height alignment) >> the kernel will reject the command stream. >> >> This patch reprogram the command stream to slice - 1 (slice is >> a derivative value from height) which avoid rejecting the command >> stream while keeping the value of command stream checking from a >> security point of view. >> >> This patch also fix wrong computation of layer size for 2D tiled >> surface. Which should fix issue when 2D color tiling is enabled. >> This dump the radeon KMS_DRIVER_MINOR so userspace can know if >> they are on a fixed kernel or not. >> >> https://lkml.org/lkml/2012/6/3/80 >> https://bugs.freedesktop.org/show_bug.cgi?id=50892 >> https://bugs.freedesktop.org/show_bug.cgi?id=50857 >> >> !!! STABLE need a custom version of this patch for 3.4 !!! >> >> v2: actually bump the minor version and add comment about stable >> v3: do compute the height the ddx was trying to use >> >> Signed-off-by: Jerome Glisse<jglisse@xxxxxxxxxx> >> --- >> drivers/gpu/drm/radeon/evergreen_cs.c | 50 >> ++++++++++++++++++++++++++++++--- >> drivers/gpu/drm/radeon/radeon_drv.c | 3 +- >> 2 files changed, 48 insertions(+), 5 deletions(-) >> >> diff --git a/drivers/gpu/drm/radeon/evergreen_cs.c >> b/drivers/gpu/drm/radeon/evergreen_cs.c >> index 4e7dd2b..29c43c6 100644 >> --- a/drivers/gpu/drm/radeon/evergreen_cs.c >> +++ b/drivers/gpu/drm/radeon/evergreen_cs.c >> @@ -52,6 +52,7 @@ struct evergreen_cs_track { >> u32 cb_color_view[12]; >> u32 cb_color_pitch[12]; >> u32 cb_color_slice[12]; >> + u32 cb_color_slice_idx[12]; >> u32 cb_color_attrib[12]; >> u32 cb_color_cmask_slice[8];/* unused */ >> u32 cb_color_fmask_slice[8];/* unused */ >> @@ -127,12 +128,14 @@ static void evergreen_cs_track_init(struct >> evergreen_cs_track *track) >> track->cb_color_info[i] = 0; >> track->cb_color_view[i] = 0xFFFFFFFF; >> track->cb_color_pitch[i] = 0; >> - track->cb_color_slice[i] = 0; >> + track->cb_color_slice[i] = 0xfffffff; >> + track->cb_color_slice_idx[i] = 0; >> } >> track->cb_target_mask = 0xFFFFFFFF; >> track->cb_shader_mask = 0xFFFFFFFF; >> track->cb_dirty = true; >> >> + track->db_depth_slice = 0xffffffff; >> track->db_depth_view = 0xFFFFC000; >> track->db_depth_size = 0xFFFFFFFF; >> track->db_depth_control = 0xFFFFFFFF; >> @@ -250,10 +253,9 @@ static int evergreen_surface_check_2d(struct >> radeon_cs_parser *p, >> { >> struct evergreen_cs_track *track = p->track; >> unsigned palign, halign, tileb, slice_pt; >> + unsigned mtile_pr, mtile_ps, mtileb; >> >> tileb = 64 * surf->bpe * surf->nsamples; >> - palign = track->group_size / (8 * surf->bpe * surf->nsamples); >> - palign = MAX(8, palign); >> slice_pt = 1; >> if (tileb> surf->tsplit) { >> slice_pt = tileb / surf->tsplit; >> @@ -262,7 +264,10 @@ static int evergreen_surface_check_2d(struct >> radeon_cs_parser *p, >> /* macro tile width& height */ >> >> palign = (8 * surf->bankw * track->npipes) * surf->mtilea; >> halign = (8 * surf->bankh * surf->nbanks) / surf->mtilea; >> - surf->layer_size = surf->nbx * surf->nby * surf->bpe * slice_pt; >> + mtileb = (palign / 8) * (halign / 8) * tileb;; >> + mtile_pr = surf->nbx / palign; >> + mtile_ps = (mtile_pr * surf->nby) / halign; >> + surf->layer_size = mtile_ps * mtileb * slice_pt; >> surf->base_align = (palign / 8) * (halign / 8) * tileb; >> surf->palign = palign; >> surf->halign = halign; >> @@ -434,6 +439,39 @@ static int evergreen_cs_track_validate_cb(struct >> radeon_cs_parser *p, unsigned i >> >> offset += surf.layer_size * mslice; >> if (offset> radeon_bo_size(track->cb_color_bo[id])) { >> + /* old ddx are broken they allocate bo with w*h*bpp but >> + * program slice with ALIGN(h, 8), catch this and patch >> + * command stream. >> + */ >> + if (!surf.mode) { >> + volatile u32 *ib = p->ib.ptr; >> + unsigned long tmp, nby, bsize, size, min = 0; >> + >> + /* find the height the ddx wants */ >> + if (surf.nby> 8) { >> + min = surf.nby - 8; >> + } >> + bsize = radeon_bo_size(track->cb_color_bo[id]); >> + tmp = track->cb_color_bo_offset[id]<< 8; >> + for (nby = surf.nby; nby> min; nby--) { >> + size = nby * surf.nbx * surf.bpe * >> surf.nsamples; >> + if ((tmp + size * mslice)<= bsize) { >> + break; >> + } >> + } >> + if (nby> min) { >> + surf.nby = nby; >> + slice = ((nby * surf.nbx) / 64) - 1; >> + if (!evergreen_surface_check(p,&surf, >> "cb")) { >> >> + /* check if this one works */ >> + tmp += surf.layer_size * mslice; >> + if (tmp<= bsize) { >> + >> ib[track->cb_color_slice_idx[id]] = slice; >> + goto old_ddx_ok; >> + } >> + } >> + } >> + } >> dev_warn(p->dev, "%s:%d cb[%d] bo too small (layer size %d, >> " >> "offset %d, max layer %d, bo size %ld, slice >> %d)\n", >> __func__, __LINE__, id, surf.layer_size, >> @@ -446,6 +484,7 @@ static int evergreen_cs_track_validate_cb(struct >> radeon_cs_parser *p, unsigned i >> surf.tsplit, surf.mtilea); >> return -EINVAL; >> } >> +old_ddx_ok: >> >> return 0; >> } >> @@ -646,6 +685,7 @@ static int evergreen_cs_track_validate_depth(struct >> radeon_cs_parser *p) >> track->db_depth_slice, track->db_z_info); >> return r; >> } >> +DRM_INFO("%s %d surface nbx,y (%d %d) mode %d format %d surf.tsplit %d >> banks (%d %d %d) tilea %d\n", __func__, __LINE__, surf.nbx, surf.nby, >> surf.mode, surf.format, surf.tsplit, surf.nbanks, surf.bankw, surf.bankh, >> surf.mtilea); > > > This DRM_INFO() is very chatty. > This is a debug left over, final commited version don't have it. Cheers, Jerome _______________________________________________ dri-devel mailing list dri-devel@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/dri-devel