linux/drivers/gpu/drm/i915
Chris Wilson d23db88c3a drm/i915: Prevent negative relocation deltas from wrapping
This is pure evil. Userspace, I'm looking at you SNA, repacks batch
buffers on the fly after generation as they are being passed to the
kernel for execution. These batches also contain self-referenced
relocations as a single buffer encompasses the state commands, kernels,
vertices and sampler. During generation the buffers are placed at known
offsets within the full batch, and then the relocation deltas (as passed
to the kernel) are tweaked as the batch is repacked into a smaller buffer.
This means that userspace is passing negative relocations deltas, which
subsequently wrap to large values if the batch is at a low address. The
GPU hangs when it then tries to use the large value as a base for its
address offsets, rather than wrapping back to the real value (as one
would hope). As the GPU uses positive offsets from the base, we can
treat the relocation address as the minimum address read by the GPU.
For the upper bound, we trust that userspace will not read beyond the
end of the buffer.

So, how do we fix negative relocations from wrapping? We can either
check that every relocation looks valid when we write it, and then
position each object such that we prevent the offset wraparound, or we
just special-case the self-referential behaviour of SNA and force all
batches to be above 256k. Daniel prefers the latter approach.

This fixes a GPU hang when it tries to use an address (relocation +
offset) greater than the GTT size. The issue would occur quite easily
with full-ppgtt as each fd gets its own VM space, so low offsets would
often be handed out. However, with the rearrangement of the low GTT due
to capturing the BIOS framebuffer, it is already affecting kernels 3.15
onwards. I think only IVB+ is susceptible to this bug, but the workaround
should only kick in rarely, so it seems sensible to always apply it.

v3: Use a bias for batch buffers to prevent small negative delta relocations
from wrapping.

v4 from Daniel:
- s/BIAS/BATCH_OFFSET_BIAS/
- Extract eb_vma_misplaced/i915_vma_misplaced since the conditions
  were growing rather cumbersome.
- Add a comment to eb_get_batch explaining why we do this.
- Apply the batch offset bias everywhere but mention that we've only
  observed it on gen7 gpus.
- Drop PIN_OFFSET_FIX for now, that slipped in from a feature patch.

v5: Add static to eb_get_batch, spotted by 0-day tester.

Testcase: igt/gem_bad_reloc
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=78533
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> (v3)
Cc: stable@vger.kernel.org
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2014-05-27 11:18:40 +03:00
..
dvo_ch7xxx.c drm/i915: Replace DRM_LOG_KMS() by DRM_DEBUG_KMS() 2014-03-28 12:57:10 +10:00
dvo_ch7017.c
dvo_ivch.c drm/i915: Replace DRM_LOG_KMS() by DRM_DEBUG_KMS() 2014-03-28 12:57:10 +10:00
dvo_ns2501.c drm/i915: Replace DRM_LOG_KMS() by DRM_DEBUG_KMS() 2014-03-28 12:57:10 +10:00
dvo_sil164.c drm/i915: Replace DRM_LOG_KMS() by DRM_DEBUG_KMS() 2014-03-28 12:57:10 +10:00
dvo_tfp410.c drm/i915: Replace DRM_LOG_KMS() by DRM_DEBUG_KMS() 2014-03-28 12:57:10 +10:00
dvo.h drm/i915: Remove unused mode_fixup() vfunc of struct intel_dvo_dev_ops 2013-09-05 21:39:59 +02:00
i915_cmd_parser.c Merge tag 'drm-intel-next-2014-03-21' of git://anongit.freedesktop.org/drm-intel into drm-next 2014-04-03 07:51:54 +10:00
i915_debugfs.c Merge tag 'drm-intel-fixes-2014-04-04' of git://anongit.freedesktop.org/drm-intel into drm-next 2014-04-05 16:14:21 +10:00
i915_dma.c drm/i915: Fix dynamic allocation of physical handles 2014-05-27 11:18:39 +03:00
i915_drv.c drm/i915: move power domain init earlier during system resume 2014-04-04 09:30:10 +02:00
i915_drv.h drm/i915: Prevent negative relocation deltas from wrapping 2014-05-27 11:18:40 +03:00
i915_gem_context.c drm/i915: Always use kref tracking for all contexts. 2014-04-11 13:29:51 +03:00
i915_gem_debug.c drm/i915: prefer struct drm_i915_private to drm_i915_private_t 2014-03-31 15:34:21 +02:00
i915_gem_dmabuf.c drm/i915: Pin pages whilst allocating for dma-buf vmap() 2013-11-29 15:51:20 +01:00
i915_gem_evict.c drm/i915: Prevent negative relocation deltas from wrapping 2014-05-27 11:18:40 +03:00
i915_gem_execbuffer.c drm/i915: Prevent negative relocation deltas from wrapping 2014-05-27 11:18:40 +03:00
i915_gem_gtt.c drm/i915: Prevent negative relocation deltas from wrapping 2014-05-27 11:18:40 +03:00
i915_gem_stolen.c drm/i915: restrict vt-d stolen memory workaround to pre-gen8 2014-03-31 10:45:34 +02:00
i915_gem_tiling.c drm/i915: prefer struct drm_i915_private to drm_i915_private_t 2014-03-31 15:34:21 +02:00
i915_gem.c drm/i915: Prevent negative relocation deltas from wrapping 2014-05-27 11:18:40 +03:00
i915_gpu_error.c drm/i915: prefer struct drm_i915_private to drm_i915_private_t 2014-03-31 15:34:21 +02:00
i915_ioc32.c
i915_irq.c drm/i915: Don't WARN nor handle unexpected hpd interrupts on gmch platforms 2014-04-25 16:01:14 +03:00
i915_params.c drm/i915: make PC8 be part of runtime PM suspend/resume 2014-03-19 16:38:25 +01:00
i915_reg.h drm/i915: Move all ring resets before setting the HWS page 2014-04-25 16:01:14 +03:00
i915_suspend.c drm/i915: Kill most of the FBC register save/restore 2014-01-25 21:17:03 +01:00
i915_sysfs.c drm/i915: remove rps local variables 2014-03-20 14:46:07 +01:00
i915_trace_points.c
i915_trace.h drm/i915: Do not dereference pointers from ring buffer in evict event 2014-03-19 08:17:29 +01:00
i915_ums.c drm/i915: Only restore backlight combination mode reg for ums 2014-01-24 17:22:45 +01:00
intel_acpi.c Merge branch 'acpi-dsm' 2014-01-12 23:45:52 +01:00
intel_bios.c drm/i915: clean up VBT eDP link param decoding 2014-05-07 15:01:49 +03:00
intel_bios.h drm/i915: check VBT for supported backlight type 2014-04-11 13:22:27 +03:00
intel_crt.c Skip intel_crt_init for Dell XPS 8700 2014-04-04 09:30:53 +02:00
intel_ddi.c drm/i915: fix WARNs when reading DDI state while suspended 2014-04-01 22:53:45 +02:00
intel_display.c drm/i915: Fix dynamic allocation of physical handles 2014-05-27 11:18:39 +03:00
intel_dp.c drm/i915/dp: force eDP lane count to max available lanes on BDW 2014-05-15 11:04:21 +03:00
intel_drv.h drm/i915: Don't check gmch state on inherited configs 2014-04-23 10:41:01 +03:00
intel_dsi_cmd.c drm/i915/dsi: s/size_t/int/ 2013-09-04 17:34:51 +02:00
intel_dsi_cmd.h drm/i915/dsi: s/size_t/int/ 2013-09-04 17:34:51 +02:00
intel_dsi_pll.c drm/i915: Try harder to get best m, n, p values with minimal error 2013-12-11 23:52:18 +01:00
intel_dsi.c drm/i915: Make encoder cloning more flexible 2014-03-10 21:33:26 +01:00
intel_dsi.h drm/i915: Parametrize the dphy and other spec specific parameters 2013-12-11 23:52:20 +01:00
intel_dvo.c drm/i915: Make encoder cloning more flexible 2014-03-10 21:33:26 +01:00
intel_fbdev.c drm/i915: Use the first mode if there is no preferred mode in the EDID 2014-05-15 11:32:35 +03:00
intel_hdmi.c drm/i915: Allow user modes to exceed DVI 165MHz limit 2014-04-22 14:33:26 +03:00
intel_i2c.c drm/i915: Disable dp aux irq on g4x 2014-02-07 16:40:07 +01:00
intel_lvds.c Merge tag 'drm-intel-next-2014-03-21' of git://anongit.freedesktop.org/drm-intel into drm-next 2014-04-03 07:51:54 +10:00
intel_modes.c
intel_opregion.c Merge tag 'drm-intel-fixes-2014-02-06' of ssh://git.freedesktop.org/git/drm-intel into drm-next 2014-02-11 12:57:27 +10:00
intel_overlay.c drm/i915: Fix dynamic allocation of physical handles 2014-05-27 11:18:39 +03:00
intel_panel.c drm/i915: restore backlight precision when converting from ACPI 2014-05-15 11:32:51 +03:00
intel_pm.c drm/i915: Increase WM memory latency values on SNB 2014-05-15 14:10:11 +03:00
intel_ringbuffer.c drm/i915: Move all ring resets before setting the HWS page 2014-04-25 16:01:14 +03:00
intel_ringbuffer.h drm/i915: Move all ring resets before setting the HWS page 2014-04-25 16:01:14 +03:00
intel_sdvo_regs.h drm/i915: use __packed instead of __attribute__((packed)) 2013-12-03 18:19:49 +01:00
intel_sdvo.c drm/i915/SDVO: For sysfs link put directory and target in correct order 2014-05-07 15:01:50 +03:00
intel_sideband.c drm/i915: Use FLISDSI interface for band gap reset 2013-12-11 23:52:17 +01:00
intel_sprite.c drm/i915: Shuffle sprite register writes into a tighter group 2014-01-24 17:22:53 +01:00
intel_tv.c drm/i915/tv: fix gen4 composite s-video tv-out 2014-03-28 18:33:16 +01:00
intel_uncore.c drm/i915/vlv: reset VLV media force wake request register 2014-05-09 21:47:26 +03:00
Kconfig ACPI / gpu / drm: Stop selecting VIDEO_OUTPUT_CONTROL 2014-03-20 02:37:22 +01:00
Makefile Merge remote-tracking branch 'airlied/drm-next' into drm-intel-next 2014-03-18 09:43:56 +01:00