diff options
Diffstat (limited to 'drivers/gpu/drm/i915/i915_gem_execbuffer.c')
-rw-r--r-- | drivers/gpu/drm/i915/i915_gem_execbuffer.c | 35 |
1 files changed, 32 insertions, 3 deletions
diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c index 0ce0d47e4b0f..885d595e0e02 100644 --- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c +++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c | |||
@@ -212,6 +212,7 @@ static int | |||
212 | relocate_entry_cpu(struct drm_i915_gem_object *obj, | 212 | relocate_entry_cpu(struct drm_i915_gem_object *obj, |
213 | struct drm_i915_gem_relocation_entry *reloc) | 213 | struct drm_i915_gem_relocation_entry *reloc) |
214 | { | 214 | { |
215 | struct drm_device *dev = obj->base.dev; | ||
215 | uint32_t page_offset = offset_in_page(reloc->offset); | 216 | uint32_t page_offset = offset_in_page(reloc->offset); |
216 | char *vaddr; | 217 | char *vaddr; |
217 | int ret = -EINVAL; | 218 | int ret = -EINVAL; |
@@ -223,6 +224,19 @@ relocate_entry_cpu(struct drm_i915_gem_object *obj, | |||
223 | vaddr = kmap_atomic(i915_gem_object_get_page(obj, | 224 | vaddr = kmap_atomic(i915_gem_object_get_page(obj, |
224 | reloc->offset >> PAGE_SHIFT)); | 225 | reloc->offset >> PAGE_SHIFT)); |
225 | *(uint32_t *)(vaddr + page_offset) = reloc->delta; | 226 | *(uint32_t *)(vaddr + page_offset) = reloc->delta; |
227 | |||
228 | if (INTEL_INFO(dev)->gen >= 8) { | ||
229 | page_offset = offset_in_page(page_offset + sizeof(uint32_t)); | ||
230 | |||
231 | if (page_offset == 0) { | ||
232 | kunmap_atomic(vaddr); | ||
233 | vaddr = kmap_atomic(i915_gem_object_get_page(obj, | ||
234 | (reloc->offset + sizeof(uint32_t)) >> PAGE_SHIFT)); | ||
235 | } | ||
236 | |||
237 | *(uint32_t *)(vaddr + page_offset) = 0; | ||
238 | } | ||
239 | |||
226 | kunmap_atomic(vaddr); | 240 | kunmap_atomic(vaddr); |
227 | 241 | ||
228 | return 0; | 242 | return 0; |
@@ -253,6 +267,21 @@ relocate_entry_gtt(struct drm_i915_gem_object *obj, | |||
253 | reloc_entry = (uint32_t __iomem *) | 267 | reloc_entry = (uint32_t __iomem *) |
254 | (reloc_page + offset_in_page(reloc->offset)); | 268 | (reloc_page + offset_in_page(reloc->offset)); |
255 | iowrite32(reloc->delta, reloc_entry); | 269 | iowrite32(reloc->delta, reloc_entry); |
270 | |||
271 | if (INTEL_INFO(dev)->gen >= 8) { | ||
272 | reloc_entry += 1; | ||
273 | |||
274 | if (offset_in_page(reloc->offset + sizeof(uint32_t)) == 0) { | ||
275 | io_mapping_unmap_atomic(reloc_page); | ||
276 | reloc_page = io_mapping_map_atomic_wc( | ||
277 | dev_priv->gtt.mappable, | ||
278 | reloc->offset + sizeof(uint32_t)); | ||
279 | reloc_entry = reloc_page; | ||
280 | } | ||
281 | |||
282 | iowrite32(0, reloc_entry); | ||
283 | } | ||
284 | |||
256 | io_mapping_unmap_atomic(reloc_page); | 285 | io_mapping_unmap_atomic(reloc_page); |
257 | 286 | ||
258 | return 0; | 287 | return 0; |
@@ -323,7 +352,8 @@ i915_gem_execbuffer_relocate_entry(struct drm_i915_gem_object *obj, | |||
323 | return 0; | 352 | return 0; |
324 | 353 | ||
325 | /* Check that the relocation address is valid... */ | 354 | /* Check that the relocation address is valid... */ |
326 | if (unlikely(reloc->offset > obj->base.size - 4)) { | 355 | if (unlikely(reloc->offset > |
356 | obj->base.size - (INTEL_INFO(dev)->gen >= 8 ? 8 : 4))) { | ||
327 | DRM_DEBUG("Relocation beyond object bounds: " | 357 | DRM_DEBUG("Relocation beyond object bounds: " |
328 | "obj %p target %d offset %d size %d.\n", | 358 | "obj %p target %d offset %d size %d.\n", |
329 | obj, reloc->target_handle, | 359 | obj, reloc->target_handle, |
@@ -1116,8 +1146,7 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, | |||
1116 | 1146 | ||
1117 | /* snb/ivb/vlv conflate the "batch in ppgtt" bit with the "non-secure | 1147 | /* snb/ivb/vlv conflate the "batch in ppgtt" bit with the "non-secure |
1118 | * batch" bit. Hence we need to pin secure batches into the global gtt. | 1148 | * batch" bit. Hence we need to pin secure batches into the global gtt. |
1119 | * hsw should have this fixed, but let's be paranoid and do it | 1149 | * hsw should have this fixed, but bdw mucks it up again. */ |
1120 | * unconditionally for now. */ | ||
1121 | if (flags & I915_DISPATCH_SECURE && !batch_obj->has_global_gtt_mapping) | 1150 | if (flags & I915_DISPATCH_SECURE && !batch_obj->has_global_gtt_mapping) |
1122 | i915_gem_gtt_bind_object(batch_obj, batch_obj->cache_level); | 1151 | i915_gem_gtt_bind_object(batch_obj, batch_obj->cache_level); |
1123 | 1152 | ||