mirror of
https://github.com/FEX-Emu/linux.git
synced 2024-12-14 12:49:08 +00:00
drm/i915: fix corruptions on i8xx due to relaxed fencing
It looks like gen2 has a peculiar interleaved 2-row inter-tile
layout. Probably inherited from i81x which had 2kb tiles (which
naturally fit an even-number-of-tile-rows scheme to fit onto 4kb
pages). There is no other mention of this in any docs (also not
in the Intel internal documention according to Chris Wilson).
Problem manifests itself in corruptions in the second half of the
last tile row (if the bo has an odd number of tiles). Which can
only happen with relaxed tiling (introduced in a00b10c360
).
So reject set_tiling calls that don't satisfy this constrain to
prevent broken userspace from causing havoc. While at it, also
check the size for newer chipsets.
LKML: https://lkml.org/lkml/2011/2/19/5
Reported-by: Indan Zupancic <indan@nul.nu>
Tested-by: Indan Zupancic <indan@nul.nu>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
This commit is contained in:
parent
011b9910bd
commit
c2e0eb1670
@ -184,7 +184,7 @@ i915_gem_detect_bit_6_swizzle(struct drm_device *dev)
|
||||
static bool
|
||||
i915_tiling_ok(struct drm_device *dev, int stride, int size, int tiling_mode)
|
||||
{
|
||||
int tile_width;
|
||||
int tile_width, tile_height;
|
||||
|
||||
/* Linear is always fine */
|
||||
if (tiling_mode == I915_TILING_NONE)
|
||||
@ -215,6 +215,20 @@ i915_tiling_ok(struct drm_device *dev, int stride, int size, int tiling_mode)
|
||||
}
|
||||
}
|
||||
|
||||
if (IS_GEN2(dev) ||
|
||||
(tiling_mode == I915_TILING_Y && HAS_128_BYTE_Y_TILING(dev)))
|
||||
tile_height = 32;
|
||||
else
|
||||
tile_height = 8;
|
||||
/* i8xx is strange: It has 2 interleaved rows of tiles, so needs an even
|
||||
* number of tile rows. */
|
||||
if (IS_GEN2(dev))
|
||||
tile_height *= 2;
|
||||
|
||||
/* Size needs to be aligned to a full tile row */
|
||||
if (size & (tile_height * stride - 1))
|
||||
return false;
|
||||
|
||||
/* 965+ just needs multiples of tile width */
|
||||
if (INTEL_INFO(dev)->gen >= 4) {
|
||||
if (stride & (tile_width - 1))
|
||||
|
Loading…
Reference in New Issue
Block a user