Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 48f112fe authored by Chris Wilson's avatar Chris Wilson
Browse files

drm/i915: Fill unused GGTT with scratch pages for VT-d



One of the numerous VT-d workarounds we require is that the display
hardware reads past the end of the buffer triggering VT-d faults. This
is acknowledged in the code as being safe "since we fill the unused
portions of the GGTT with the scratch page". Alas, that is no longer
always true and so we trigger DMAR read faults.

Skylake also requires another workaround to avoid mixing VT-d and
unpopulated PTE, and so there we also need to ensure we fill unused
entries with the scratch page.

Reported-by: default avatarMike Lothian <mike@fireburn.co.uk>
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=96584


Fixes: f7770bfd ("drm/i915: Skip clearing the GGTT on full-ppgtt systems")
Signed-off-by: default avatarChris Wilson <chris@chris-wilson.co.uk>
Cc: David Weinehall <david.weinehall@intel.com>
Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Link: http://patchwork.freedesktop.org/patch/msgid/1466773634-8106-1-git-send-email-chris@chris-wilson.co.uk


Reviewed-by: default avatarDavid Weinehall <david.weinehall@intel.com>
parent 22dea0be
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -2912,6 +2912,15 @@ struct drm_i915_cmd_table {

#include "i915_trace.h"

static inline bool intel_scanout_needs_vtd_wa(struct drm_i915_private *dev_priv)
{
#ifdef CONFIG_INTEL_IOMMU
	if (INTEL_GEN(dev_priv) >= 6 && intel_iommu_gfx_mapped)
		return true;
#endif
	return false;
}

extern int i915_suspend_switcheroo(struct drm_device *dev, pm_message_t state);
extern int i915_resume_switcheroo(struct drm_device *dev);

+1 −1
Original line number Diff line number Diff line
@@ -3119,7 +3119,7 @@ static int gen8_gmch_probe(struct i915_ggtt *ggtt)
	ggtt->base.unbind_vma = ggtt_unbind_vma;
	ggtt->base.insert_page = gen8_ggtt_insert_page;
	ggtt->base.clear_range = nop_clear_range;
	if (!USES_FULL_PPGTT(dev_priv))
	if (!USES_FULL_PPGTT(dev_priv) || intel_scanout_needs_vtd_wa(dev_priv))
		ggtt->base.clear_range = gen8_ggtt_clear_range;

	ggtt->base.insert_entries = gen8_ggtt_insert_entries;
+1 −10
Original line number Diff line number Diff line
@@ -2046,15 +2046,6 @@ static void intel_disable_pipe(struct intel_crtc *crtc)
		intel_wait_for_pipe_off(crtc);
}

static bool need_vtd_wa(struct drm_device *dev)
{
#ifdef CONFIG_INTEL_IOMMU
	if (INTEL_INFO(dev)->gen >= 6 && intel_iommu_gfx_mapped)
		return true;
#endif
	return false;
}

static unsigned int intel_tile_size(const struct drm_i915_private *dev_priv)
{
	return IS_GEN2(dev_priv) ? 2048 : 4096;
@@ -2236,7 +2227,7 @@ intel_pin_and_fence_fb_obj(struct drm_framebuffer *fb,
	 * we should always have valid PTE following the scanout preventing
	 * the VT-d warning.
	 */
	if (need_vtd_wa(dev) && alignment < 256 * 1024)
	if (intel_scanout_needs_vtd_wa(dev_priv) && alignment < 256 * 1024)
		alignment = 256 * 1024;

	/*