diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2019-11-13 13:50:13 +0000 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2019-11-13 23:34:42 +0000 |
commit | d0893f764e2e78a8ed1f9223c9c82163003e82bf (patch) | |
tree | b2cb23b5518746ddf8c72ba6e40a956ab7a2e28d | |
parent | 0ff3c792d4361cb5ebb1322120b17abf342b3489 (diff) |
i915/gem_create: Check for cache bypass around zeroed pages
Check that even if userspace tries to sneak around the CPU caches of its
zeroed pages, it sees nothing but zeroes.
Suggested-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Cc: Matthew Auld <matthew.auld@intel.com>
Reviewed-by: Matthew Auld <matthew.auld@intel.com>
-rw-r--r-- | tests/i915/gem_create.c | 49 |
1 files changed, 43 insertions, 6 deletions
diff --git a/tests/i915/gem_create.c b/tests/i915/gem_create.c index aed7d1cec..ea1482000 100644 --- a/tests/i915/gem_create.c +++ b/tests/i915/gem_create.c @@ -55,8 +55,10 @@ #include "intel_io.h" #include "intel_chipset.h" #include "igt_aux.h" +#include "igt_x86.h" #include "drmtest.h" #include "drm.h" +#include "i915/gem_mman.h" #include "i915_drm.h" IGT_TEST_DESCRIPTION("This is a test for the extended & old gem_create ioctl," @@ -188,11 +190,13 @@ static void *thread_clear(void *data) { struct thread_clear *arg = data; unsigned long checked = 0; + enum { PRW, GTT, WC, WB, __LAST__ } mode = PRW; int i915 = arg->i915; igt_until_timeout(arg->timeout) { struct drm_i915_gem_create create = {}; uint64_t npages; + void *ptr; npages = random(); npages <<= 32; @@ -201,18 +205,51 @@ static void *thread_clear(void *data) create.size = npages << 12; create_ioctl(i915, &create); - for (uint64_t page = 0; page < npages; page++) { - uint64_t x; + switch (mode) { + case __LAST__: + case PRW: + ptr = NULL; + break; + case WB: + ptr = __gem_mmap__cpu(i915, create.handle, + 0, create.size, PROT_READ); + break; + case WC: + ptr = __gem_mmap__wc(i915, create.handle, + 0, create.size, PROT_READ); + break; + case GTT: + ptr = __gem_mmap__gtt(i915, create.handle, + create.size, PROT_READ); + break; + } + /* No set-domains as we are being as naughty as possible */ - gem_read(i915, create.handle, - page * 4096 + (page % (4096 - sizeof(x))), - &x, sizeof(x)); - igt_assert_eq_u64(x, 0); + for (uint64_t page = 0; page < npages; page++) { + uint64_t x[8] = { + page * 4096 + + sizeof(x) * ((page % (4096 - sizeof(x)) / sizeof(x))) + }; + + if (!ptr) + gem_read(i915, create.handle, x[0], x, sizeof(x)); + else if (page & 1) + igt_memcpy_from_wc(x, ptr + x[0], sizeof(x)); + else + memcpy(x, ptr + x[0], sizeof(x)); + + for (int i = 0; i < ARRAY_SIZE(x); i++) + igt_assert_eq_u64(x[i], 0); } + if (ptr) + munmap(ptr, create.size); gem_close(i915, create.handle); checked += npages; atomic_fetch_add(&arg->max, npages); + + if (++mode == __LAST__) + mode = PRW; } return (void *)(uintptr_t)checked; |