@@ -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);
@@ -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;
};
@@ -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. */
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(-)