diff mbox

[3/3] i965: implement (per-context) scratch page checking

Message ID 1512720159-6843-4-git-send-email-kevin.rogovin@intel.com (mailing list archive)
State New, archived
Headers show

Commit Message

kevin.rogovin@intel.com Dec. 8, 2017, 8:02 a.m. UTC
From: Kevin Rogovin <kevin.rogovin@intel.com>

---
 src/mesa/drivers/dri/i965/brw_context.c       | 30 +++++++++++++++++++++++++++
 src/mesa/drivers/dri/i965/brw_context.h       | 10 +++++++++
 src/mesa/drivers/dri/i965/intel_batchbuffer.c | 15 +++++++++++++-
 3 files changed, 54 insertions(+), 1 deletion(-)
diff mbox

Patch

diff --git a/src/mesa/drivers/dri/i965/brw_context.c b/src/mesa/drivers/dri/i965/brw_context.c
index 126c187f62..8e1afdc859 100644
--- a/src/mesa/drivers/dri/i965/brw_context.c
+++ b/src/mesa/drivers/dri/i965/brw_context.c
@@ -844,6 +844,7 @@  brwCreateContext(gl_api api,
 {
    struct gl_context *shareCtx = (struct gl_context *) sharedContextPrivate;
    struct intel_screen *screen = driContextPriv->driScreenPriv->driverPrivate;
+   __DRIscreen *dri_screen = screen->driScrnPriv;
    const struct gen_device_info *devinfo = &screen->devinfo;
    struct dd_function_table functions;
 
@@ -1078,6 +1079,30 @@  brwCreateContext(gl_api api,
 
    brw_disk_cache_init(brw);
 
+   brw->scratch.size = 0;
+   if (brw->hw_ctx && (INTEL_DEBUG & DEBUG_CHECK_SCRATCH_PAGE)) {
+      struct drm_i915_gem_context_param p;
+      int ret;
+
+      p.ctx_id = brw->hw_ctx;
+      p.size = 0;
+      p.param = I915_CONTEXT_PARAM_SCRATCH_PAGE_CONTENTS;
+      p.value = 0;
+      ret = drmIoctl(dri_screen->fd, DRM_IOCTL_I915_GEM_CONTEXT_GETPARAM, &p);
+      if (ret == 0 && p.size > 0) {
+         brw->scratch.size = p.size;
+         brw->scratch.values = calloc(brw->scratch.size, 1);
+         brw->scratch.tmp = calloc(brw->scratch.size, 1);
+         for (uint64_t i = 0; i < brw->scratch.size; ++i) {
+            brw->scratch.values[i] = rand() & 0xFF;
+         }
+         p.value = (__u64) (uintptr_t) brw->scratch.values;
+         ret = drmIoctl(dri_screen->fd, DRM_IOCTL_I915_GEM_CONTEXT_SETPARAM, &p);
+         assert(ret == 0);
+         assert(p.size == brw->scratch.size);
+      }
+   }
+
    return true;
 }
 
@@ -1140,6 +1165,11 @@  intelDestroyContext(__DRIcontext * driContextPriv)
 
    driDestroyOptionCache(&brw->optionCache);
 
+   if (brw->scratch.size > 0) {
+      free(brw->scratch.values);
+      free(brw->scratch.tmp);
+   }
+
    /* free the Mesa context */
    _mesa_free_context_data(&brw->ctx);
 
diff --git a/src/mesa/drivers/dri/i965/brw_context.h b/src/mesa/drivers/dri/i965/brw_context.h
index 0f0aad8534..e73eab9160 100644
--- a/src/mesa/drivers/dri/i965/brw_context.h
+++ b/src/mesa/drivers/dri/i965/brw_context.h
@@ -1263,6 +1263,16 @@  struct brw_context
     */
    bool draw_aux_buffer_disabled[MAX_DRAW_BUFFERS];
 
+   /* Checking the scratch page to detect out-of-bounds writes
+    * by the GPU; a zero value on the scratch size indicates
+    * that scratch page checking is not enabled.
+    */
+   struct {
+      uint8_t *values;
+      uint8_t *tmp;
+      uint64_t size;
+   } scratch;
+
    __DRIcontext *driContext;
    struct intel_screen *screen;
 };
diff --git a/src/mesa/drivers/dri/i965/intel_batchbuffer.c b/src/mesa/drivers/dri/i965/intel_batchbuffer.c
index 91a6506a89..2e4e7747d0 100644
--- a/src/mesa/drivers/dri/i965/intel_batchbuffer.c
+++ b/src/mesa/drivers/dri/i965/intel_batchbuffer.c
@@ -936,9 +936,22 @@  _intel_batchbuffer_flush_fence(struct brw_context *brw,
 
    ret = submit_batch(brw, in_fence_fd, out_fence_fd);
 
-   if (unlikely(INTEL_DEBUG & DEBUG_SYNC)) {
+   if (unlikely((INTEL_DEBUG & DEBUG_SYNC) || brw->scratch.size > 0)) {
       fprintf(stderr, "waiting for idle\n");
       brw_bo_wait_rendering(brw->batch.batch.bo);
+      if (brw->scratch.size > 0) {
+         struct drm_i915_gem_context_param p;
+         int ret;
+
+         p.ctx_id = brw->hw_ctx;
+         p.size = brw->scratch.size;
+         p.param = I915_CONTEXT_PARAM_SCRATCH_PAGE_CONTENTS;
+         p.value = (__u64) (uintptr_t) brw->scratch.tmp;
+         ret = drmIoctl(brw->screen->driScrnPriv->fd, DRM_IOCTL_I915_GEM_CONTEXT_GETPARAM, &p);
+         assert(ret == 0);
+         assert(p.size == brw->scratch.size);
+         assert(memcmp(brw->scratch.tmp, brw->scratch.values, brw->scratch.size) == 0);
+      }
    }
 
    /* Start a new batch buffer. */