summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2019-11-13 13:50:13 +0000
committerChris Wilson <chris@chris-wilson.co.uk>2019-11-13 23:34:42 +0000
commitd0893f764e2e78a8ed1f9223c9c82163003e82bf (patch)
treeb2cb23b5518746ddf8c72ba6e40a956ab7a2e28d
parent0ff3c792d4361cb5ebb1322120b17abf342b3489 (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.c49
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;