[Mesa-dev] [PATCH 15/14] radeonsi: extend the SDMA L2T VM fault workaround to T2L
Nicolai Hähnle
nhaehnle at gmail.com
Sun May 8 16:43:11 UTC 2016
For the history it'd probably be nicer to squash patch 15 in the
appropriate place. Either way, patches 5 - 15 are
Reviewed-by: Nicolai Hähnle <nicolai.haehnle at amd.com>
On 08.05.2016 07:10, Marek Olšák wrote:
> From: Marek Olšák <marek.olsak at amd.com>
>
> Same algorithm, just applied to T2L.
> (and using a 0-based address and surface.bo_size instead of buf->size)
> ---
> src/gallium/drivers/radeonsi/cik_sdma.c | 108 ++++++++++++++++----------------
> 1 file changed, 55 insertions(+), 53 deletions(-)
>
> diff --git a/src/gallium/drivers/radeonsi/cik_sdma.c b/src/gallium/drivers/radeonsi/cik_sdma.c
> index 17c3a83..cd7b0e6 100644
> --- a/src/gallium/drivers/radeonsi/cik_sdma.c
> +++ b/src/gallium/drivers/radeonsi/cik_sdma.c
> @@ -239,6 +239,7 @@ static bool cik_sdma_copy_texture(struct si_context *sctx,
> struct r600_texture *tiled = src_mode >= RADEON_SURF_MODE_1D ? rsrc : rdst;
> struct r600_texture *linear = tiled == rsrc ? rdst : rsrc;
> unsigned tiled_level = tiled == rsrc ? src_level : dst_level;
> + unsigned linear_level = linear == rsrc ? src_level : dst_level;
> unsigned tiled_x = tiled == rsrc ? srcx : dstx;
> unsigned linear_x = linear == rsrc ? srcx : dstx;
> unsigned tiled_y = tiled == rsrc ? srcy : dsty;
> @@ -294,62 +295,63 @@ static bool cik_sdma_copy_texture(struct si_context *sctx,
> tiled_y + copy_height == (1 << 14)))
> return false;
>
> - /* The hw can read outside of the given linear buffer bounds.
> - * Out-of-bounds reads must be prevented.
> + /* The hw can read outside of the given linear buffer bounds,
> + * or access those pages but not touch the memory in case
> + * of writes. (it still causes a VM fault)
> + *
> + * Out-of-bounds memory access or page directory access must
> + * be prevented.
> */
> - if (linear == rsrc) {
> - uint64_t start_linear_address, end_linear_address;
> - unsigned granularity;
> -
> - /* Deduce the size of reads from the linear surface. */
> - switch (tiled_micro_mode) {
> - case V_009910_ADDR_SURF_DISPLAY_MICRO_TILING:
> - granularity = bpp == 1 ? 64 / (8*bpp) :
> - 128 / (8*bpp);
> - break;
> - case V_009910_ADDR_SURF_THIN_MICRO_TILING:
> - case V_009910_ADDR_SURF_DEPTH_MICRO_TILING:
> - if (0 /* TODO: THICK microtiling */)
> - granularity = bpp == 1 ? 32 / (8*bpp) :
> - bpp == 2 ? 64 / (8*bpp) :
> - bpp <= 8 ? 128 / (8*bpp) :
> - 256 / (8*bpp);
> - else
> - granularity = bpp <= 2 ? 64 / (8*bpp) :
> - bpp <= 8 ? 128 / (8*bpp) :
> - 256 / (8*bpp);
> - break;
> - default:
> - return false;
> - }
> -
> - /* The linear reads start at tiled_x & ~(granularity - 1).
> - * If linear_x == 0 && tiled_x % granularity != 0, the hw
> - * starts reading from an address preceding linear_address!!!
> - */
> - start_linear_address =
> - linear_address +
> - bpp * (linear_z * src_slice_pitch +
> - linear_y * src_pitch +
> - linear_x -
> - tiled_x % granularity);
> -
> - end_linear_address =
> - linear_address +
> - bpp * ((linear_z + copy_depth - 1) * src_slice_pitch +
> - (linear_y + copy_height - 1) * src_pitch +
> - (linear_x + copy_width));
> -
> - if ((tiled_x + copy_width) % granularity)
> - end_linear_address += granularity -
> - (tiled_x + copy_width) % granularity;
> -
> - if (start_linear_address < linear->resource.gpu_address ||
> - end_linear_address > (linear->resource.gpu_address +
> - linear->resource.buf->size))
> - return false;
> + int64_t start_linear_address, end_linear_address;
> + unsigned granularity;
> +
> + /* Deduce the size of reads from the linear surface. */
> + switch (tiled_micro_mode) {
> + case V_009910_ADDR_SURF_DISPLAY_MICRO_TILING:
> + granularity = bpp == 1 ? 64 / (8*bpp) :
> + 128 / (8*bpp);
> + break;
> + case V_009910_ADDR_SURF_THIN_MICRO_TILING:
> + case V_009910_ADDR_SURF_DEPTH_MICRO_TILING:
> + if (0 /* TODO: THICK microtiling */)
> + granularity = bpp == 1 ? 32 / (8*bpp) :
> + bpp == 2 ? 64 / (8*bpp) :
> + bpp <= 8 ? 128 / (8*bpp) :
> + 256 / (8*bpp);
> + else
> + granularity = bpp <= 2 ? 64 / (8*bpp) :
> + bpp <= 8 ? 128 / (8*bpp) :
> + 256 / (8*bpp);
> + break;
> + default:
> + return false;
> }
>
> + /* The linear reads start at tiled_x & ~(granularity - 1).
> + * If linear_x == 0 && tiled_x % granularity != 0, the hw
> + * starts reading from an address preceding linear_address!!!
> + */
> + start_linear_address =
> + linear->surface.level[linear_level].offset +
> + bpp * (linear_z * linear_slice_pitch +
> + linear_y * linear_pitch +
> + linear_x);
> + start_linear_address -= (int)(bpp * (tiled_x % granularity));
> +
> + end_linear_address =
> + linear->surface.level[linear_level].offset +
> + bpp * ((linear_z + copy_depth - 1) * linear_slice_pitch +
> + (linear_y + copy_height - 1) * linear_pitch +
> + (linear_x + copy_width));
> +
> + if ((tiled_x + copy_width) % granularity)
> + end_linear_address += granularity -
> + (tiled_x + copy_width) % granularity;
> +
> + if (start_linear_address < 0 ||
> + end_linear_address > linear->surface.bo_size)
> + return false;
> +
> /* Check requirements. */
> if (tiled_address % 256 == 0 &&
> linear_address % 4 == 0 &&
>
More information about the mesa-dev
mailing list