Commit 489140b5 authored by Chris Wilson's avatar Chris Wilson Committed by Jani Nikula
Browse files

drm/i915/gt: Always try to reserve GGTT address 0x0

Since writing to address 0 is a very common mistake, let's try to avoid
putting anything sensitive there.

References: https://gitlab.freedesktop.org/drm/intel/-/issues/2989


Signed-off-by: default avatarChris Wilson <chris@chris-wilson.co.uk>
Reviewed-by: default avatarMatthew Auld <matthew.auld@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20210125125033.23656-1-chris@chris-wilson.co.uk


Cc: stable@vger.kernel.org
(cherry picked from commit 56b429cc584c6ed8b895d8d8540959655db1ff73)
Signed-off-by: default avatarJani Nikula <jani.nikula@intel.com>
parent f6e98a18
Loading
Loading
Loading
Loading
+35 −12
Original line number Diff line number Diff line
@@ -526,16 +526,39 @@ static int init_ggtt(struct i915_ggtt *ggtt)

	mutex_init(&ggtt->error_mutex);
	if (ggtt->mappable_end) {
		/* Reserve a mappable slot for our lockless error capture */
		ret = drm_mm_insert_node_in_range(&ggtt->vm.mm,
		/*
		 * Reserve a mappable slot for our lockless error capture.
		 *
		 * We strongly prefer taking address 0x0 in order to protect
		 * other critical buffers against accidental overwrites,
		 * as writing to address 0 is a very common mistake.
		 *
		 * Since 0 may already be in use by the system (e.g. the BIOS
		 * framebuffer), we let the reservation fail quietly and hope
		 * 0 remains reserved always.
		 *
		 * If we fail to reserve 0, and then fail to find any space
		 * for an error-capture, remain silent. We can afford not
		 * to reserve an error_capture node as we have fallback
		 * paths, and we trust that 0 will remain reserved. However,
		 * the only likely reason for failure to insert is a driver
		 * bug, which we expect to cause other failures...
		 */
		ggtt->error_capture.size = I915_GTT_PAGE_SIZE;
		ggtt->error_capture.color = I915_COLOR_UNEVICTABLE;
		if (drm_mm_reserve_node(&ggtt->vm.mm, &ggtt->error_capture))
			drm_mm_insert_node_in_range(&ggtt->vm.mm,
						    &ggtt->error_capture,
						  PAGE_SIZE, 0,
						  I915_COLOR_UNEVICTABLE,
						    ggtt->error_capture.size, 0,
						    ggtt->error_capture.color,
						    0, ggtt->mappable_end,
						    DRM_MM_INSERT_LOW);
		if (ret)
			return ret;
	}
	if (drm_mm_node_allocated(&ggtt->error_capture))
		drm_dbg(&ggtt->vm.i915->drm,
			"Reserved GGTT:[%llx, %llx] for use by error capture\n",
			ggtt->error_capture.start,
			ggtt->error_capture.start + ggtt->error_capture.size);

	/*
	 * The upper portion of the GuC address space has a sizeable hole
@@ -548,7 +571,7 @@ static int init_ggtt(struct i915_ggtt *ggtt)

	/* Clear any non-preallocated blocks */
	drm_mm_for_each_hole(entry, &ggtt->vm.mm, hole_start, hole_end) {
		drm_dbg_kms(&ggtt->vm.i915->drm,
		drm_dbg(&ggtt->vm.i915->drm,
			"clearing unused GTT space: [%lx, %lx]\n",
			hole_start, hole_end);
		ggtt->vm.clear_range(&ggtt->vm, hole_start,