[i-g-t] i915/gem_create: Check for cache bypass around zeroed pages
diff mbox series

Message ID 20191113135505.11426-1-chris@chris-wilson.co.uk
State New
Headers show
Series
  • [i-g-t] i915/gem_create: Check for cache bypass around zeroed pages
Related show

Commit Message

Chris Wilson Nov. 13, 2019, 1:55 p.m. UTC
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>
---
 tests/i915/gem_create.c | 45 +++++++++++++++++++++++++++++++++++------
 1 file changed, 39 insertions(+), 6 deletions(-)

Patch
diff mbox series

diff --git a/tests/i915/gem_create.c b/tests/i915/gem_create.c
index aed7d1cec..9f7a45025 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, STREAM, __LAST__ } mode = PRW;
 	int i915 = arg->i915;
 
 	igt_until_timeout(arg->timeout) {
 		struct drm_i915_gem_create create = {};
 		uint64_t npages;
+		void *ptr = NULL;
 
 		npages = random();
 		npages <<= 32;
@@ -201,18 +205,47 @@  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:
+			break;
+		case WC:
+		case STREAM:
+			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 (mode == STREAM)
+				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;