blob: 3c90dd1a3bbdb81a0604216924ae86cb578e8ed4 [file] [log] [blame]
Chris Wilson54cf91d2010-11-25 18:00:26 +00001/*
2 * Copyright © 2008,2010 Intel Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21 * IN THE SOFTWARE.
22 *
23 * Authors:
24 * Eric Anholt <eric@anholt.net>
25 * Chris Wilson <chris@chris-wilson.co.uk>
26 *
27 */
28
David Howells760285e2012-10-02 18:01:07 +010029#include <drm/drmP.h>
30#include <drm/i915_drm.h>
Chris Wilson54cf91d2010-11-25 18:00:26 +000031#include "i915_drv.h"
32#include "i915_trace.h"
33#include "intel_drv.h"
Eugeni Dodonovf45b5552011-12-09 17:16:37 -080034#include <linux/dma_remapping.h>
Chris Wilson54cf91d2010-11-25 18:00:26 +000035
Chris Wilsona415d352013-11-26 11:23:15 +000036#define __EXEC_OBJECT_HAS_PIN (1<<31)
37#define __EXEC_OBJECT_HAS_FENCE (1<<30)
38
Ben Widawsky27173f12013-08-14 11:38:36 +020039struct eb_vmas {
40 struct list_head vmas;
Chris Wilson67731b82010-12-08 10:38:14 +000041 int and;
Chris Wilsoneef90cc2013-01-08 10:53:17 +000042 union {
Ben Widawsky27173f12013-08-14 11:38:36 +020043 struct i915_vma *lut[0];
Chris Wilsoneef90cc2013-01-08 10:53:17 +000044 struct hlist_head buckets[0];
45 };
Chris Wilson67731b82010-12-08 10:38:14 +000046};
47
Ben Widawsky27173f12013-08-14 11:38:36 +020048static struct eb_vmas *
Ben Widawsky17601cbc2013-11-25 09:54:38 -080049eb_create(struct drm_i915_gem_execbuffer2 *args)
Chris Wilson67731b82010-12-08 10:38:14 +000050{
Ben Widawsky27173f12013-08-14 11:38:36 +020051 struct eb_vmas *eb = NULL;
Chris Wilson67731b82010-12-08 10:38:14 +000052
Chris Wilsoneef90cc2013-01-08 10:53:17 +000053 if (args->flags & I915_EXEC_HANDLE_LUT) {
Daniel Vetterb205ca52013-09-19 14:00:11 +020054 unsigned size = args->buffer_count;
Ben Widawsky27173f12013-08-14 11:38:36 +020055 size *= sizeof(struct i915_vma *);
56 size += sizeof(struct eb_vmas);
Chris Wilsoneef90cc2013-01-08 10:53:17 +000057 eb = kmalloc(size, GFP_TEMPORARY | __GFP_NOWARN | __GFP_NORETRY);
58 }
59
60 if (eb == NULL) {
Daniel Vetterb205ca52013-09-19 14:00:11 +020061 unsigned size = args->buffer_count;
62 unsigned count = PAGE_SIZE / sizeof(struct hlist_head) / 2;
Lauri Kasanen27b7c632013-03-27 15:04:55 +020063 BUILD_BUG_ON_NOT_POWER_OF_2(PAGE_SIZE / sizeof(struct hlist_head));
Chris Wilsoneef90cc2013-01-08 10:53:17 +000064 while (count > 2*size)
65 count >>= 1;
66 eb = kzalloc(count*sizeof(struct hlist_head) +
Ben Widawsky27173f12013-08-14 11:38:36 +020067 sizeof(struct eb_vmas),
Chris Wilsoneef90cc2013-01-08 10:53:17 +000068 GFP_TEMPORARY);
69 if (eb == NULL)
70 return eb;
71
72 eb->and = count - 1;
73 } else
74 eb->and = -args->buffer_count;
75
Ben Widawsky27173f12013-08-14 11:38:36 +020076 INIT_LIST_HEAD(&eb->vmas);
Chris Wilson67731b82010-12-08 10:38:14 +000077 return eb;
78}
79
80static void
Ben Widawsky27173f12013-08-14 11:38:36 +020081eb_reset(struct eb_vmas *eb)
Chris Wilson67731b82010-12-08 10:38:14 +000082{
Chris Wilsoneef90cc2013-01-08 10:53:17 +000083 if (eb->and >= 0)
84 memset(eb->buckets, 0, (eb->and+1)*sizeof(struct hlist_head));
Chris Wilson67731b82010-12-08 10:38:14 +000085}
86
Chris Wilson3b96eff2013-01-08 10:53:14 +000087static int
Ben Widawsky27173f12013-08-14 11:38:36 +020088eb_lookup_vmas(struct eb_vmas *eb,
89 struct drm_i915_gem_exec_object2 *exec,
90 const struct drm_i915_gem_execbuffer2 *args,
91 struct i915_address_space *vm,
92 struct drm_file *file)
Chris Wilson3b96eff2013-01-08 10:53:14 +000093{
Ben Widawsky27173f12013-08-14 11:38:36 +020094 struct drm_i915_gem_object *obj;
95 struct list_head objects;
96 int i, ret = 0;
Chris Wilson3b96eff2013-01-08 10:53:14 +000097
Ben Widawsky27173f12013-08-14 11:38:36 +020098 INIT_LIST_HEAD(&objects);
Chris Wilson3b96eff2013-01-08 10:53:14 +000099 spin_lock(&file->table_lock);
Ben Widawsky27173f12013-08-14 11:38:36 +0200100 /* Grab a reference to the object and release the lock so we can lookup
101 * or create the VMA without using GFP_ATOMIC */
Chris Wilsoneef90cc2013-01-08 10:53:17 +0000102 for (i = 0; i < args->buffer_count; i++) {
Chris Wilson3b96eff2013-01-08 10:53:14 +0000103 obj = to_intel_bo(idr_find(&file->object_idr, exec[i].handle));
104 if (obj == NULL) {
105 spin_unlock(&file->table_lock);
106 DRM_DEBUG("Invalid object handle %d at index %d\n",
107 exec[i].handle, i);
Ben Widawsky27173f12013-08-14 11:38:36 +0200108 ret = -ENOENT;
109 goto out;
Chris Wilson3b96eff2013-01-08 10:53:14 +0000110 }
111
Ben Widawsky27173f12013-08-14 11:38:36 +0200112 if (!list_empty(&obj->obj_exec_link)) {
Chris Wilson3b96eff2013-01-08 10:53:14 +0000113 spin_unlock(&file->table_lock);
114 DRM_DEBUG("Object %p [handle %d, index %d] appears more than once in object list\n",
115 obj, exec[i].handle, i);
Ben Widawsky27173f12013-08-14 11:38:36 +0200116 ret = -EINVAL;
117 goto out;
Chris Wilson3b96eff2013-01-08 10:53:14 +0000118 }
119
120 drm_gem_object_reference(&obj->base);
Ben Widawsky27173f12013-08-14 11:38:36 +0200121 list_add_tail(&obj->obj_exec_link, &objects);
Chris Wilson3b96eff2013-01-08 10:53:14 +0000122 }
123 spin_unlock(&file->table_lock);
124
Ben Widawsky27173f12013-08-14 11:38:36 +0200125 i = 0;
126 list_for_each_entry(obj, &objects, obj_exec_link) {
127 struct i915_vma *vma;
128
Daniel Vettere656a6c2013-08-14 14:14:04 +0200129 /*
130 * NOTE: We can leak any vmas created here when something fails
131 * later on. But that's no issue since vma_unbind can deal with
132 * vmas which are not actually bound. And since only
133 * lookup_or_create exists as an interface to get at the vma
134 * from the (obj, vm) we don't run the risk of creating
135 * duplicated vmas for the same vm.
136 */
Ben Widawsky27173f12013-08-14 11:38:36 +0200137 vma = i915_gem_obj_lookup_or_create_vma(obj, vm);
138 if (IS_ERR(vma)) {
Ben Widawsky27173f12013-08-14 11:38:36 +0200139 DRM_DEBUG("Failed to lookup VMA\n");
140 ret = PTR_ERR(vma);
141 goto out;
142 }
143
144 list_add_tail(&vma->exec_list, &eb->vmas);
145
146 vma->exec_entry = &exec[i];
147 if (eb->and < 0) {
148 eb->lut[i] = vma;
149 } else {
150 uint32_t handle = args->flags & I915_EXEC_HANDLE_LUT ? i : exec[i].handle;
151 vma->exec_handle = handle;
152 hlist_add_head(&vma->exec_node,
153 &eb->buckets[handle & eb->and]);
154 }
155 ++i;
156 }
157
158
159out:
160 while (!list_empty(&objects)) {
161 obj = list_first_entry(&objects,
162 struct drm_i915_gem_object,
163 obj_exec_link);
164 list_del_init(&obj->obj_exec_link);
165 if (ret)
166 drm_gem_object_unreference(&obj->base);
167 }
168 return ret;
Chris Wilson3b96eff2013-01-08 10:53:14 +0000169}
170
Ben Widawsky27173f12013-08-14 11:38:36 +0200171static struct i915_vma *eb_get_vma(struct eb_vmas *eb, unsigned long handle)
Chris Wilson67731b82010-12-08 10:38:14 +0000172{
Chris Wilsoneef90cc2013-01-08 10:53:17 +0000173 if (eb->and < 0) {
174 if (handle >= -eb->and)
175 return NULL;
176 return eb->lut[handle];
177 } else {
178 struct hlist_head *head;
179 struct hlist_node *node;
Chris Wilson67731b82010-12-08 10:38:14 +0000180
Chris Wilsoneef90cc2013-01-08 10:53:17 +0000181 head = &eb->buckets[handle & eb->and];
182 hlist_for_each(node, head) {
Ben Widawsky27173f12013-08-14 11:38:36 +0200183 struct i915_vma *vma;
Chris Wilsoneef90cc2013-01-08 10:53:17 +0000184
Ben Widawsky27173f12013-08-14 11:38:36 +0200185 vma = hlist_entry(node, struct i915_vma, exec_node);
186 if (vma->exec_handle == handle)
187 return vma;
Chris Wilsoneef90cc2013-01-08 10:53:17 +0000188 }
189 return NULL;
Chris Wilson67731b82010-12-08 10:38:14 +0000190 }
Chris Wilson67731b82010-12-08 10:38:14 +0000191}
192
Chris Wilsona415d352013-11-26 11:23:15 +0000193static void
194i915_gem_execbuffer_unreserve_vma(struct i915_vma *vma)
195{
196 struct drm_i915_gem_exec_object2 *entry;
197 struct drm_i915_gem_object *obj = vma->obj;
198
199 if (!drm_mm_node_allocated(&vma->node))
200 return;
201
202 entry = vma->exec_entry;
203
204 if (entry->flags & __EXEC_OBJECT_HAS_FENCE)
205 i915_gem_object_unpin_fence(obj);
206
207 if (entry->flags & __EXEC_OBJECT_HAS_PIN)
208 i915_gem_object_unpin(obj);
209
210 entry->flags &= ~(__EXEC_OBJECT_HAS_FENCE | __EXEC_OBJECT_HAS_PIN);
211}
212
213static void eb_destroy(struct eb_vmas *eb)
214{
Ben Widawsky27173f12013-08-14 11:38:36 +0200215 while (!list_empty(&eb->vmas)) {
216 struct i915_vma *vma;
Chris Wilsonbcffc3f2013-01-08 10:53:15 +0000217
Ben Widawsky27173f12013-08-14 11:38:36 +0200218 vma = list_first_entry(&eb->vmas,
219 struct i915_vma,
Chris Wilsonbcffc3f2013-01-08 10:53:15 +0000220 exec_list);
Ben Widawsky27173f12013-08-14 11:38:36 +0200221 list_del_init(&vma->exec_list);
Chris Wilsona415d352013-11-26 11:23:15 +0000222 i915_gem_execbuffer_unreserve_vma(vma);
Ben Widawsky27173f12013-08-14 11:38:36 +0200223 drm_gem_object_unreference(&vma->obj->base);
Chris Wilsonbcffc3f2013-01-08 10:53:15 +0000224 }
Chris Wilson67731b82010-12-08 10:38:14 +0000225 kfree(eb);
226}
227
Chris Wilsondabdfe02012-03-26 10:10:27 +0200228static inline int use_cpu_reloc(struct drm_i915_gem_object *obj)
229{
Chris Wilson2cc86b82013-08-26 19:51:00 -0300230 return (HAS_LLC(obj->base.dev) ||
231 obj->base.write_domain == I915_GEM_DOMAIN_CPU ||
Chris Wilson504c7262012-08-23 13:12:52 +0100232 !obj->map_and_fenceable ||
Chris Wilsondabdfe02012-03-26 10:10:27 +0200233 obj->cache_level != I915_CACHE_NONE);
234}
235
Chris Wilson54cf91d2010-11-25 18:00:26 +0000236static int
Rafael Barbalho5032d872013-08-21 17:10:51 +0100237relocate_entry_cpu(struct drm_i915_gem_object *obj,
238 struct drm_i915_gem_relocation_entry *reloc)
239{
Ben Widawsky3c94cee2013-11-02 21:07:11 -0700240 struct drm_device *dev = obj->base.dev;
Rafael Barbalho5032d872013-08-21 17:10:51 +0100241 uint32_t page_offset = offset_in_page(reloc->offset);
242 char *vaddr;
243 int ret = -EINVAL;
244
Chris Wilson2cc86b82013-08-26 19:51:00 -0300245 ret = i915_gem_object_set_to_cpu_domain(obj, true);
Rafael Barbalho5032d872013-08-21 17:10:51 +0100246 if (ret)
247 return ret;
248
249 vaddr = kmap_atomic(i915_gem_object_get_page(obj,
250 reloc->offset >> PAGE_SHIFT));
251 *(uint32_t *)(vaddr + page_offset) = reloc->delta;
Ben Widawsky3c94cee2013-11-02 21:07:11 -0700252
253 if (INTEL_INFO(dev)->gen >= 8) {
254 page_offset = offset_in_page(page_offset + sizeof(uint32_t));
255
256 if (page_offset == 0) {
257 kunmap_atomic(vaddr);
258 vaddr = kmap_atomic(i915_gem_object_get_page(obj,
259 (reloc->offset + sizeof(uint32_t)) >> PAGE_SHIFT));
260 }
261
262 *(uint32_t *)(vaddr + page_offset) = 0;
263 }
264
Rafael Barbalho5032d872013-08-21 17:10:51 +0100265 kunmap_atomic(vaddr);
266
267 return 0;
268}
269
270static int
271relocate_entry_gtt(struct drm_i915_gem_object *obj,
272 struct drm_i915_gem_relocation_entry *reloc)
273{
274 struct drm_device *dev = obj->base.dev;
275 struct drm_i915_private *dev_priv = dev->dev_private;
276 uint32_t __iomem *reloc_entry;
277 void __iomem *reloc_page;
278 int ret = -EINVAL;
279
280 ret = i915_gem_object_set_to_gtt_domain(obj, true);
281 if (ret)
282 return ret;
283
284 ret = i915_gem_object_put_fence(obj);
285 if (ret)
286 return ret;
287
288 /* Map the page containing the relocation we're going to perform. */
289 reloc->offset += i915_gem_obj_ggtt_offset(obj);
290 reloc_page = io_mapping_map_atomic_wc(dev_priv->gtt.mappable,
291 reloc->offset & PAGE_MASK);
292 reloc_entry = (uint32_t __iomem *)
293 (reloc_page + offset_in_page(reloc->offset));
294 iowrite32(reloc->delta, reloc_entry);
Ben Widawsky3c94cee2013-11-02 21:07:11 -0700295
296 if (INTEL_INFO(dev)->gen >= 8) {
297 reloc_entry += 1;
298
299 if (offset_in_page(reloc->offset + sizeof(uint32_t)) == 0) {
300 io_mapping_unmap_atomic(reloc_page);
301 reloc_page = io_mapping_map_atomic_wc(
302 dev_priv->gtt.mappable,
303 reloc->offset + sizeof(uint32_t));
304 reloc_entry = reloc_page;
305 }
306
307 iowrite32(0, reloc_entry);
308 }
309
Rafael Barbalho5032d872013-08-21 17:10:51 +0100310 io_mapping_unmap_atomic(reloc_page);
311
312 return 0;
313}
314
315static int
Chris Wilson54cf91d2010-11-25 18:00:26 +0000316i915_gem_execbuffer_relocate_entry(struct drm_i915_gem_object *obj,
Ben Widawsky27173f12013-08-14 11:38:36 +0200317 struct eb_vmas *eb,
Ben Widawsky28d6a7b2013-07-31 17:00:02 -0700318 struct drm_i915_gem_relocation_entry *reloc,
319 struct i915_address_space *vm)
Chris Wilson54cf91d2010-11-25 18:00:26 +0000320{
321 struct drm_device *dev = obj->base.dev;
322 struct drm_gem_object *target_obj;
Daniel Vetter149c8402012-02-15 23:50:23 +0100323 struct drm_i915_gem_object *target_i915_obj;
Ben Widawsky27173f12013-08-14 11:38:36 +0200324 struct i915_vma *target_vma;
Chris Wilson54cf91d2010-11-25 18:00:26 +0000325 uint32_t target_offset;
326 int ret = -EINVAL;
327
Chris Wilson67731b82010-12-08 10:38:14 +0000328 /* we've already hold a reference to all valid objects */
Ben Widawsky27173f12013-08-14 11:38:36 +0200329 target_vma = eb_get_vma(eb, reloc->target_handle);
330 if (unlikely(target_vma == NULL))
Chris Wilson54cf91d2010-11-25 18:00:26 +0000331 return -ENOENT;
Ben Widawsky27173f12013-08-14 11:38:36 +0200332 target_i915_obj = target_vma->obj;
333 target_obj = &target_vma->obj->base;
Chris Wilson54cf91d2010-11-25 18:00:26 +0000334
Ben Widawsky5ce09722013-11-25 09:54:40 -0800335 target_offset = target_vma->node.start;
Chris Wilson54cf91d2010-11-25 18:00:26 +0000336
Eric Anholte844b992012-07-31 15:35:01 -0700337 /* Sandybridge PPGTT errata: We need a global gtt mapping for MI and
338 * pipe_control writes because the gpu doesn't properly redirect them
339 * through the ppgtt for non_secure batchbuffers. */
340 if (unlikely(IS_GEN6(dev) &&
341 reloc->write_domain == I915_GEM_DOMAIN_INSTRUCTION &&
342 !target_i915_obj->has_global_gtt_mapping)) {
343 i915_gem_gtt_bind_object(target_i915_obj,
344 target_i915_obj->cache_level);
345 }
346
Chris Wilson54cf91d2010-11-25 18:00:26 +0000347 /* Validate that the target is in a valid r/w GPU domain */
Chris Wilsonb8f7ab12010-12-08 10:43:06 +0000348 if (unlikely(reloc->write_domain & (reloc->write_domain - 1))) {
Daniel Vetterff240192012-01-31 21:08:14 +0100349 DRM_DEBUG("reloc with multiple write domains: "
Chris Wilson54cf91d2010-11-25 18:00:26 +0000350 "obj %p target %d offset %d "
351 "read %08x write %08x",
352 obj, reloc->target_handle,
353 (int) reloc->offset,
354 reloc->read_domains,
355 reloc->write_domain);
Chris Wilson67731b82010-12-08 10:38:14 +0000356 return ret;
Chris Wilson54cf91d2010-11-25 18:00:26 +0000357 }
Daniel Vetter4ca4a252011-12-14 13:57:27 +0100358 if (unlikely((reloc->write_domain | reloc->read_domains)
359 & ~I915_GEM_GPU_DOMAINS)) {
Daniel Vetterff240192012-01-31 21:08:14 +0100360 DRM_DEBUG("reloc with read/write non-GPU domains: "
Chris Wilson54cf91d2010-11-25 18:00:26 +0000361 "obj %p target %d offset %d "
362 "read %08x write %08x",
363 obj, reloc->target_handle,
364 (int) reloc->offset,
365 reloc->read_domains,
366 reloc->write_domain);
Chris Wilson67731b82010-12-08 10:38:14 +0000367 return ret;
Chris Wilson54cf91d2010-11-25 18:00:26 +0000368 }
Chris Wilson54cf91d2010-11-25 18:00:26 +0000369
370 target_obj->pending_read_domains |= reloc->read_domains;
371 target_obj->pending_write_domain |= reloc->write_domain;
372
373 /* If the relocation already has the right value in it, no
374 * more work needs to be done.
375 */
376 if (target_offset == reloc->presumed_offset)
Chris Wilson67731b82010-12-08 10:38:14 +0000377 return 0;
Chris Wilson54cf91d2010-11-25 18:00:26 +0000378
379 /* Check that the relocation address is valid... */
Ben Widawsky3c94cee2013-11-02 21:07:11 -0700380 if (unlikely(reloc->offset >
381 obj->base.size - (INTEL_INFO(dev)->gen >= 8 ? 8 : 4))) {
Daniel Vetterff240192012-01-31 21:08:14 +0100382 DRM_DEBUG("Relocation beyond object bounds: "
Chris Wilson54cf91d2010-11-25 18:00:26 +0000383 "obj %p target %d offset %d size %d.\n",
384 obj, reloc->target_handle,
385 (int) reloc->offset,
386 (int) obj->base.size);
Chris Wilson67731b82010-12-08 10:38:14 +0000387 return ret;
Chris Wilson54cf91d2010-11-25 18:00:26 +0000388 }
Chris Wilsonb8f7ab12010-12-08 10:43:06 +0000389 if (unlikely(reloc->offset & 3)) {
Daniel Vetterff240192012-01-31 21:08:14 +0100390 DRM_DEBUG("Relocation not 4-byte aligned: "
Chris Wilson54cf91d2010-11-25 18:00:26 +0000391 "obj %p target %d offset %d.\n",
392 obj, reloc->target_handle,
393 (int) reloc->offset);
Chris Wilson67731b82010-12-08 10:38:14 +0000394 return ret;
Chris Wilson54cf91d2010-11-25 18:00:26 +0000395 }
396
Chris Wilsondabdfe02012-03-26 10:10:27 +0200397 /* We can't wait for rendering with pagefaults disabled */
398 if (obj->active && in_atomic())
399 return -EFAULT;
400
Chris Wilson54cf91d2010-11-25 18:00:26 +0000401 reloc->delta += target_offset;
Rafael Barbalho5032d872013-08-21 17:10:51 +0100402 if (use_cpu_reloc(obj))
403 ret = relocate_entry_cpu(obj, reloc);
404 else
405 ret = relocate_entry_gtt(obj, reloc);
Chris Wilson54cf91d2010-11-25 18:00:26 +0000406
Daniel Vetterd4d36012013-09-02 20:56:23 +0200407 if (ret)
408 return ret;
409
Chris Wilson54cf91d2010-11-25 18:00:26 +0000410 /* and update the user's relocation entry */
411 reloc->presumed_offset = target_offset;
412
Chris Wilson67731b82010-12-08 10:38:14 +0000413 return 0;
Chris Wilson54cf91d2010-11-25 18:00:26 +0000414}
415
416static int
Ben Widawsky27173f12013-08-14 11:38:36 +0200417i915_gem_execbuffer_relocate_vma(struct i915_vma *vma,
418 struct eb_vmas *eb)
Chris Wilson54cf91d2010-11-25 18:00:26 +0000419{
Chris Wilson1d83f442012-03-24 20:12:53 +0000420#define N_RELOC(x) ((x) / sizeof(struct drm_i915_gem_relocation_entry))
421 struct drm_i915_gem_relocation_entry stack_reloc[N_RELOC(512)];
Chris Wilson54cf91d2010-11-25 18:00:26 +0000422 struct drm_i915_gem_relocation_entry __user *user_relocs;
Ben Widawsky27173f12013-08-14 11:38:36 +0200423 struct drm_i915_gem_exec_object2 *entry = vma->exec_entry;
Chris Wilson1d83f442012-03-24 20:12:53 +0000424 int remain, ret;
Chris Wilson54cf91d2010-11-25 18:00:26 +0000425
Ville Syrjälä2bb46292013-02-22 16:12:51 +0200426 user_relocs = to_user_ptr(entry->relocs_ptr);
Chris Wilson54cf91d2010-11-25 18:00:26 +0000427
Chris Wilson1d83f442012-03-24 20:12:53 +0000428 remain = entry->relocation_count;
429 while (remain) {
430 struct drm_i915_gem_relocation_entry *r = stack_reloc;
431 int count = remain;
432 if (count > ARRAY_SIZE(stack_reloc))
433 count = ARRAY_SIZE(stack_reloc);
434 remain -= count;
435
436 if (__copy_from_user_inatomic(r, user_relocs, count*sizeof(r[0])))
Chris Wilson54cf91d2010-11-25 18:00:26 +0000437 return -EFAULT;
438
Chris Wilson1d83f442012-03-24 20:12:53 +0000439 do {
440 u64 offset = r->presumed_offset;
Chris Wilson54cf91d2010-11-25 18:00:26 +0000441
Ben Widawsky27173f12013-08-14 11:38:36 +0200442 ret = i915_gem_execbuffer_relocate_entry(vma->obj, eb, r,
443 vma->vm);
Chris Wilson1d83f442012-03-24 20:12:53 +0000444 if (ret)
445 return ret;
446
447 if (r->presumed_offset != offset &&
448 __copy_to_user_inatomic(&user_relocs->presumed_offset,
449 &r->presumed_offset,
450 sizeof(r->presumed_offset))) {
451 return -EFAULT;
452 }
453
454 user_relocs++;
455 r++;
456 } while (--count);
Chris Wilson54cf91d2010-11-25 18:00:26 +0000457 }
458
459 return 0;
Chris Wilson1d83f442012-03-24 20:12:53 +0000460#undef N_RELOC
Chris Wilson54cf91d2010-11-25 18:00:26 +0000461}
462
463static int
Ben Widawsky27173f12013-08-14 11:38:36 +0200464i915_gem_execbuffer_relocate_vma_slow(struct i915_vma *vma,
465 struct eb_vmas *eb,
466 struct drm_i915_gem_relocation_entry *relocs)
Chris Wilson54cf91d2010-11-25 18:00:26 +0000467{
Ben Widawsky27173f12013-08-14 11:38:36 +0200468 const struct drm_i915_gem_exec_object2 *entry = vma->exec_entry;
Chris Wilson54cf91d2010-11-25 18:00:26 +0000469 int i, ret;
470
471 for (i = 0; i < entry->relocation_count; i++) {
Ben Widawsky27173f12013-08-14 11:38:36 +0200472 ret = i915_gem_execbuffer_relocate_entry(vma->obj, eb, &relocs[i],
473 vma->vm);
Chris Wilson54cf91d2010-11-25 18:00:26 +0000474 if (ret)
475 return ret;
476 }
477
478 return 0;
479}
480
481static int
Ben Widawsky17601cbc2013-11-25 09:54:38 -0800482i915_gem_execbuffer_relocate(struct eb_vmas *eb)
Chris Wilson54cf91d2010-11-25 18:00:26 +0000483{
Ben Widawsky27173f12013-08-14 11:38:36 +0200484 struct i915_vma *vma;
Chris Wilsond4aeee72011-03-14 15:11:24 +0000485 int ret = 0;
Chris Wilson54cf91d2010-11-25 18:00:26 +0000486
Chris Wilsond4aeee72011-03-14 15:11:24 +0000487 /* This is the fast path and we cannot handle a pagefault whilst
488 * holding the struct mutex lest the user pass in the relocations
489 * contained within a mmaped bo. For in such a case we, the page
490 * fault handler would call i915_gem_fault() and we would try to
491 * acquire the struct mutex again. Obviously this is bad and so
492 * lockdep complains vehemently.
493 */
494 pagefault_disable();
Ben Widawsky27173f12013-08-14 11:38:36 +0200495 list_for_each_entry(vma, &eb->vmas, exec_list) {
496 ret = i915_gem_execbuffer_relocate_vma(vma, eb);
Chris Wilson54cf91d2010-11-25 18:00:26 +0000497 if (ret)
Chris Wilsond4aeee72011-03-14 15:11:24 +0000498 break;
Chris Wilson54cf91d2010-11-25 18:00:26 +0000499 }
Chris Wilsond4aeee72011-03-14 15:11:24 +0000500 pagefault_enable();
Chris Wilson54cf91d2010-11-25 18:00:26 +0000501
Chris Wilsond4aeee72011-03-14 15:11:24 +0000502 return ret;
Chris Wilson54cf91d2010-11-25 18:00:26 +0000503}
504
Chris Wilson1690e1e2011-12-14 13:57:08 +0100505static int
Ben Widawsky27173f12013-08-14 11:38:36 +0200506need_reloc_mappable(struct i915_vma *vma)
Chris Wilsondabdfe02012-03-26 10:10:27 +0200507{
Ben Widawsky27173f12013-08-14 11:38:36 +0200508 struct drm_i915_gem_exec_object2 *entry = vma->exec_entry;
509 return entry->relocation_count && !use_cpu_reloc(vma->obj) &&
510 i915_is_ggtt(vma->vm);
Chris Wilsondabdfe02012-03-26 10:10:27 +0200511}
512
513static int
Ben Widawsky27173f12013-08-14 11:38:36 +0200514i915_gem_execbuffer_reserve_vma(struct i915_vma *vma,
515 struct intel_ring_buffer *ring,
516 bool *need_reloc)
Chris Wilson1690e1e2011-12-14 13:57:08 +0100517{
Ben Widawsky27173f12013-08-14 11:38:36 +0200518 struct drm_i915_private *dev_priv = ring->dev->dev_private;
519 struct drm_i915_gem_exec_object2 *entry = vma->exec_entry;
Chris Wilson1690e1e2011-12-14 13:57:08 +0100520 bool has_fenced_gpu_access = INTEL_INFO(ring->dev)->gen < 4;
521 bool need_fence, need_mappable;
Ben Widawsky27173f12013-08-14 11:38:36 +0200522 struct drm_i915_gem_object *obj = vma->obj;
Chris Wilson1690e1e2011-12-14 13:57:08 +0100523 int ret;
524
525 need_fence =
526 has_fenced_gpu_access &&
527 entry->flags & EXEC_OBJECT_NEEDS_FENCE &&
528 obj->tiling_mode != I915_TILING_NONE;
Ben Widawsky27173f12013-08-14 11:38:36 +0200529 need_mappable = need_fence || need_reloc_mappable(vma);
Chris Wilson1690e1e2011-12-14 13:57:08 +0100530
Ben Widawsky27173f12013-08-14 11:38:36 +0200531 ret = i915_gem_object_pin(obj, vma->vm, entry->alignment, need_mappable,
Ben Widawsky28d6a7b2013-07-31 17:00:02 -0700532 false);
Chris Wilson1690e1e2011-12-14 13:57:08 +0100533 if (ret)
534 return ret;
535
Chris Wilson7788a762012-08-24 19:18:18 +0100536 entry->flags |= __EXEC_OBJECT_HAS_PIN;
537
Chris Wilson1690e1e2011-12-14 13:57:08 +0100538 if (has_fenced_gpu_access) {
539 if (entry->flags & EXEC_OBJECT_NEEDS_FENCE) {
Chris Wilson06d98132012-04-17 15:31:24 +0100540 ret = i915_gem_object_get_fence(obj);
Chris Wilson9a5a53b2012-03-22 15:10:00 +0000541 if (ret)
Chris Wilson7788a762012-08-24 19:18:18 +0100542 return ret;
Chris Wilson1690e1e2011-12-14 13:57:08 +0100543
Chris Wilson9a5a53b2012-03-22 15:10:00 +0000544 if (i915_gem_object_pin_fence(obj))
Chris Wilson1690e1e2011-12-14 13:57:08 +0100545 entry->flags |= __EXEC_OBJECT_HAS_FENCE;
Chris Wilson9a5a53b2012-03-22 15:10:00 +0000546
Chris Wilson7dd49062012-03-21 10:48:18 +0000547 obj->pending_fenced_gpu_access = true;
Chris Wilson1690e1e2011-12-14 13:57:08 +0100548 }
Chris Wilson1690e1e2011-12-14 13:57:08 +0100549 }
550
Chris Wilson7788a762012-08-24 19:18:18 +0100551 /* Ensure ppgtt mapping exists if needed */
552 if (dev_priv->mm.aliasing_ppgtt && !obj->has_aliasing_ppgtt_mapping) {
553 i915_ppgtt_bind_object(dev_priv->mm.aliasing_ppgtt,
554 obj, obj->cache_level);
555
556 obj->has_aliasing_ppgtt_mapping = 1;
557 }
558
Ben Widawsky27173f12013-08-14 11:38:36 +0200559 if (entry->offset != vma->node.start) {
560 entry->offset = vma->node.start;
Daniel Vettered5982e2013-01-17 22:23:36 +0100561 *need_reloc = true;
562 }
563
564 if (entry->flags & EXEC_OBJECT_WRITE) {
565 obj->base.pending_read_domains = I915_GEM_DOMAIN_RENDER;
566 obj->base.pending_write_domain = I915_GEM_DOMAIN_RENDER;
567 }
568
569 if (entry->flags & EXEC_OBJECT_NEEDS_GTT &&
570 !obj->has_global_gtt_mapping)
571 i915_gem_gtt_bind_object(obj, obj->cache_level);
572
Chris Wilson1690e1e2011-12-14 13:57:08 +0100573 return 0;
Chris Wilson7788a762012-08-24 19:18:18 +0100574}
Chris Wilson1690e1e2011-12-14 13:57:08 +0100575
Chris Wilson54cf91d2010-11-25 18:00:26 +0000576static int
Chris Wilsond9e86c02010-11-10 16:40:20 +0000577i915_gem_execbuffer_reserve(struct intel_ring_buffer *ring,
Ben Widawsky27173f12013-08-14 11:38:36 +0200578 struct list_head *vmas,
Daniel Vettered5982e2013-01-17 22:23:36 +0100579 bool *need_relocs)
Chris Wilson54cf91d2010-11-25 18:00:26 +0000580{
Chris Wilson432e58e2010-11-25 19:32:06 +0000581 struct drm_i915_gem_object *obj;
Ben Widawsky27173f12013-08-14 11:38:36 +0200582 struct i915_vma *vma;
Ben Widawsky68c8c172013-09-11 14:57:50 -0700583 struct i915_address_space *vm;
Ben Widawsky27173f12013-08-14 11:38:36 +0200584 struct list_head ordered_vmas;
Chris Wilson7788a762012-08-24 19:18:18 +0100585 bool has_fenced_gpu_access = INTEL_INFO(ring->dev)->gen < 4;
586 int retry;
Chris Wilson6fe4f142011-01-10 17:35:37 +0000587
Ben Widawsky68c8c172013-09-11 14:57:50 -0700588 if (list_empty(vmas))
589 return 0;
590
591 vm = list_first_entry(vmas, struct i915_vma, exec_list)->vm;
592
Ben Widawsky27173f12013-08-14 11:38:36 +0200593 INIT_LIST_HEAD(&ordered_vmas);
594 while (!list_empty(vmas)) {
Chris Wilson6fe4f142011-01-10 17:35:37 +0000595 struct drm_i915_gem_exec_object2 *entry;
596 bool need_fence, need_mappable;
597
Ben Widawsky27173f12013-08-14 11:38:36 +0200598 vma = list_first_entry(vmas, struct i915_vma, exec_list);
599 obj = vma->obj;
600 entry = vma->exec_entry;
Chris Wilson6fe4f142011-01-10 17:35:37 +0000601
602 need_fence =
603 has_fenced_gpu_access &&
604 entry->flags & EXEC_OBJECT_NEEDS_FENCE &&
605 obj->tiling_mode != I915_TILING_NONE;
Ben Widawsky27173f12013-08-14 11:38:36 +0200606 need_mappable = need_fence || need_reloc_mappable(vma);
Chris Wilson6fe4f142011-01-10 17:35:37 +0000607
608 if (need_mappable)
Ben Widawsky27173f12013-08-14 11:38:36 +0200609 list_move(&vma->exec_list, &ordered_vmas);
Chris Wilson6fe4f142011-01-10 17:35:37 +0000610 else
Ben Widawsky27173f12013-08-14 11:38:36 +0200611 list_move_tail(&vma->exec_list, &ordered_vmas);
Chris Wilson595dad72011-01-13 11:03:48 +0000612
Daniel Vettered5982e2013-01-17 22:23:36 +0100613 obj->base.pending_read_domains = I915_GEM_GPU_DOMAINS & ~I915_GEM_DOMAIN_COMMAND;
Chris Wilson595dad72011-01-13 11:03:48 +0000614 obj->base.pending_write_domain = 0;
Chris Wilson016fd0c2012-07-20 12:41:07 +0100615 obj->pending_fenced_gpu_access = false;
Chris Wilson6fe4f142011-01-10 17:35:37 +0000616 }
Ben Widawsky27173f12013-08-14 11:38:36 +0200617 list_splice(&ordered_vmas, vmas);
Chris Wilson54cf91d2010-11-25 18:00:26 +0000618
619 /* Attempt to pin all of the buffers into the GTT.
620 * This is done in 3 phases:
621 *
622 * 1a. Unbind all objects that do not match the GTT constraints for
623 * the execbuffer (fenceable, mappable, alignment etc).
624 * 1b. Increment pin count for already bound objects.
625 * 2. Bind new objects.
626 * 3. Decrement pin count.
627 *
Chris Wilson7788a762012-08-24 19:18:18 +0100628 * This avoid unnecessary unbinding of later objects in order to make
Chris Wilson54cf91d2010-11-25 18:00:26 +0000629 * room for the earlier objects *unless* we need to defragment.
630 */
631 retry = 0;
632 do {
Chris Wilson7788a762012-08-24 19:18:18 +0100633 int ret = 0;
Chris Wilson54cf91d2010-11-25 18:00:26 +0000634
635 /* Unbind any ill-fitting objects or pin. */
Ben Widawsky27173f12013-08-14 11:38:36 +0200636 list_for_each_entry(vma, vmas, exec_list) {
637 struct drm_i915_gem_exec_object2 *entry = vma->exec_entry;
Chris Wilson54cf91d2010-11-25 18:00:26 +0000638 bool need_fence, need_mappable;
Chris Wilson1690e1e2011-12-14 13:57:08 +0100639
Ben Widawsky27173f12013-08-14 11:38:36 +0200640 obj = vma->obj;
641
642 if (!drm_mm_node_allocated(&vma->node))
Chris Wilson54cf91d2010-11-25 18:00:26 +0000643 continue;
644
645 need_fence =
Chris Wilson9b3826b2010-12-05 17:11:54 +0000646 has_fenced_gpu_access &&
Chris Wilson54cf91d2010-11-25 18:00:26 +0000647 entry->flags & EXEC_OBJECT_NEEDS_FENCE &&
648 obj->tiling_mode != I915_TILING_NONE;
Ben Widawsky27173f12013-08-14 11:38:36 +0200649 need_mappable = need_fence || need_reloc_mappable(vma);
Chris Wilson54cf91d2010-11-25 18:00:26 +0000650
Ben Widawsky28d6a7b2013-07-31 17:00:02 -0700651 WARN_ON((need_mappable || need_fence) &&
Ben Widawsky27173f12013-08-14 11:38:36 +0200652 !i915_is_ggtt(vma->vm));
Ben Widawsky28d6a7b2013-07-31 17:00:02 -0700653
Ben Widawskyf343c5f2013-07-05 14:41:04 -0700654 if ((entry->alignment &&
Ben Widawsky27173f12013-08-14 11:38:36 +0200655 vma->node.start & (entry->alignment - 1)) ||
Chris Wilson54cf91d2010-11-25 18:00:26 +0000656 (need_mappable && !obj->map_and_fenceable))
Ben Widawsky27173f12013-08-14 11:38:36 +0200657 ret = i915_vma_unbind(vma);
Chris Wilson54cf91d2010-11-25 18:00:26 +0000658 else
Ben Widawsky27173f12013-08-14 11:38:36 +0200659 ret = i915_gem_execbuffer_reserve_vma(vma, ring, need_relocs);
Chris Wilson432e58e2010-11-25 19:32:06 +0000660 if (ret)
Chris Wilson54cf91d2010-11-25 18:00:26 +0000661 goto err;
Chris Wilson54cf91d2010-11-25 18:00:26 +0000662 }
663
664 /* Bind fresh objects */
Ben Widawsky27173f12013-08-14 11:38:36 +0200665 list_for_each_entry(vma, vmas, exec_list) {
666 if (drm_mm_node_allocated(&vma->node))
Chris Wilson1690e1e2011-12-14 13:57:08 +0100667 continue;
Chris Wilson54cf91d2010-11-25 18:00:26 +0000668
Ben Widawsky27173f12013-08-14 11:38:36 +0200669 ret = i915_gem_execbuffer_reserve_vma(vma, ring, need_relocs);
Chris Wilson7788a762012-08-24 19:18:18 +0100670 if (ret)
671 goto err;
Chris Wilson54cf91d2010-11-25 18:00:26 +0000672 }
673
Chris Wilsona415d352013-11-26 11:23:15 +0000674err:
Chris Wilson6c085a72012-08-20 11:40:46 +0200675 if (ret != -ENOSPC || retry++)
Chris Wilson54cf91d2010-11-25 18:00:26 +0000676 return ret;
677
Chris Wilsona415d352013-11-26 11:23:15 +0000678 /* Decrement pin count for bound objects */
679 list_for_each_entry(vma, vmas, exec_list)
680 i915_gem_execbuffer_unreserve_vma(vma);
681
Ben Widawsky68c8c172013-09-11 14:57:50 -0700682 ret = i915_gem_evict_vm(vm, true);
Chris Wilson54cf91d2010-11-25 18:00:26 +0000683 if (ret)
684 return ret;
Chris Wilson54cf91d2010-11-25 18:00:26 +0000685 } while (1);
686}
687
688static int
689i915_gem_execbuffer_relocate_slow(struct drm_device *dev,
Daniel Vettered5982e2013-01-17 22:23:36 +0100690 struct drm_i915_gem_execbuffer2 *args,
Chris Wilson54cf91d2010-11-25 18:00:26 +0000691 struct drm_file *file,
Chris Wilsond9e86c02010-11-10 16:40:20 +0000692 struct intel_ring_buffer *ring,
Ben Widawsky27173f12013-08-14 11:38:36 +0200693 struct eb_vmas *eb,
694 struct drm_i915_gem_exec_object2 *exec)
Chris Wilson54cf91d2010-11-25 18:00:26 +0000695{
696 struct drm_i915_gem_relocation_entry *reloc;
Ben Widawsky27173f12013-08-14 11:38:36 +0200697 struct i915_address_space *vm;
698 struct i915_vma *vma;
Daniel Vettered5982e2013-01-17 22:23:36 +0100699 bool need_relocs;
Chris Wilsondd6864a2011-01-12 23:49:13 +0000700 int *reloc_offset;
Chris Wilson54cf91d2010-11-25 18:00:26 +0000701 int i, total, ret;
Daniel Vetterb205ca52013-09-19 14:00:11 +0200702 unsigned count = args->buffer_count;
Chris Wilson54cf91d2010-11-25 18:00:26 +0000703
Ben Widawsky27173f12013-08-14 11:38:36 +0200704 if (WARN_ON(list_empty(&eb->vmas)))
705 return 0;
706
707 vm = list_first_entry(&eb->vmas, struct i915_vma, exec_list)->vm;
708
Chris Wilson67731b82010-12-08 10:38:14 +0000709 /* We may process another execbuffer during the unlock... */
Ben Widawsky27173f12013-08-14 11:38:36 +0200710 while (!list_empty(&eb->vmas)) {
711 vma = list_first_entry(&eb->vmas, struct i915_vma, exec_list);
712 list_del_init(&vma->exec_list);
Chris Wilsona415d352013-11-26 11:23:15 +0000713 i915_gem_execbuffer_unreserve_vma(vma);
Ben Widawsky27173f12013-08-14 11:38:36 +0200714 drm_gem_object_unreference(&vma->obj->base);
Chris Wilson67731b82010-12-08 10:38:14 +0000715 }
716
Chris Wilson54cf91d2010-11-25 18:00:26 +0000717 mutex_unlock(&dev->struct_mutex);
718
719 total = 0;
720 for (i = 0; i < count; i++)
Chris Wilson432e58e2010-11-25 19:32:06 +0000721 total += exec[i].relocation_count;
Chris Wilson54cf91d2010-11-25 18:00:26 +0000722
Chris Wilsondd6864a2011-01-12 23:49:13 +0000723 reloc_offset = drm_malloc_ab(count, sizeof(*reloc_offset));
Chris Wilson54cf91d2010-11-25 18:00:26 +0000724 reloc = drm_malloc_ab(total, sizeof(*reloc));
Chris Wilsondd6864a2011-01-12 23:49:13 +0000725 if (reloc == NULL || reloc_offset == NULL) {
726 drm_free_large(reloc);
727 drm_free_large(reloc_offset);
Chris Wilson54cf91d2010-11-25 18:00:26 +0000728 mutex_lock(&dev->struct_mutex);
729 return -ENOMEM;
730 }
731
732 total = 0;
733 for (i = 0; i < count; i++) {
734 struct drm_i915_gem_relocation_entry __user *user_relocs;
Chris Wilson262b6d32013-01-15 16:17:54 +0000735 u64 invalid_offset = (u64)-1;
736 int j;
Chris Wilson54cf91d2010-11-25 18:00:26 +0000737
Ville Syrjälä2bb46292013-02-22 16:12:51 +0200738 user_relocs = to_user_ptr(exec[i].relocs_ptr);
Chris Wilson54cf91d2010-11-25 18:00:26 +0000739
740 if (copy_from_user(reloc+total, user_relocs,
Chris Wilson432e58e2010-11-25 19:32:06 +0000741 exec[i].relocation_count * sizeof(*reloc))) {
Chris Wilson54cf91d2010-11-25 18:00:26 +0000742 ret = -EFAULT;
743 mutex_lock(&dev->struct_mutex);
744 goto err;
745 }
746
Chris Wilson262b6d32013-01-15 16:17:54 +0000747 /* As we do not update the known relocation offsets after
748 * relocating (due to the complexities in lock handling),
749 * we need to mark them as invalid now so that we force the
750 * relocation processing next time. Just in case the target
751 * object is evicted and then rebound into its old
752 * presumed_offset before the next execbuffer - if that
753 * happened we would make the mistake of assuming that the
754 * relocations were valid.
755 */
756 for (j = 0; j < exec[i].relocation_count; j++) {
757 if (copy_to_user(&user_relocs[j].presumed_offset,
758 &invalid_offset,
759 sizeof(invalid_offset))) {
760 ret = -EFAULT;
761 mutex_lock(&dev->struct_mutex);
762 goto err;
763 }
764 }
765
Chris Wilsondd6864a2011-01-12 23:49:13 +0000766 reloc_offset[i] = total;
Chris Wilson432e58e2010-11-25 19:32:06 +0000767 total += exec[i].relocation_count;
Chris Wilson54cf91d2010-11-25 18:00:26 +0000768 }
769
770 ret = i915_mutex_lock_interruptible(dev);
771 if (ret) {
772 mutex_lock(&dev->struct_mutex);
773 goto err;
774 }
775
Chris Wilson67731b82010-12-08 10:38:14 +0000776 /* reacquire the objects */
Chris Wilson67731b82010-12-08 10:38:14 +0000777 eb_reset(eb);
Ben Widawsky27173f12013-08-14 11:38:36 +0200778 ret = eb_lookup_vmas(eb, exec, args, vm, file);
Chris Wilson3b96eff2013-01-08 10:53:14 +0000779 if (ret)
780 goto err;
Chris Wilson67731b82010-12-08 10:38:14 +0000781
Daniel Vettered5982e2013-01-17 22:23:36 +0100782 need_relocs = (args->flags & I915_EXEC_NO_RELOC) == 0;
Ben Widawsky27173f12013-08-14 11:38:36 +0200783 ret = i915_gem_execbuffer_reserve(ring, &eb->vmas, &need_relocs);
Chris Wilson54cf91d2010-11-25 18:00:26 +0000784 if (ret)
785 goto err;
786
Ben Widawsky27173f12013-08-14 11:38:36 +0200787 list_for_each_entry(vma, &eb->vmas, exec_list) {
788 int offset = vma->exec_entry - exec;
789 ret = i915_gem_execbuffer_relocate_vma_slow(vma, eb,
790 reloc + reloc_offset[offset]);
Chris Wilson54cf91d2010-11-25 18:00:26 +0000791 if (ret)
792 goto err;
Chris Wilson54cf91d2010-11-25 18:00:26 +0000793 }
794
795 /* Leave the user relocations as are, this is the painfully slow path,
796 * and we want to avoid the complication of dropping the lock whilst
797 * having buffers reserved in the aperture and so causing spurious
798 * ENOSPC for random operations.
799 */
800
801err:
802 drm_free_large(reloc);
Chris Wilsondd6864a2011-01-12 23:49:13 +0000803 drm_free_large(reloc_offset);
Chris Wilson54cf91d2010-11-25 18:00:26 +0000804 return ret;
805}
806
Chris Wilson54cf91d2010-11-25 18:00:26 +0000807static int
Chris Wilson432e58e2010-11-25 19:32:06 +0000808i915_gem_execbuffer_move_to_gpu(struct intel_ring_buffer *ring,
Ben Widawsky27173f12013-08-14 11:38:36 +0200809 struct list_head *vmas)
Chris Wilson54cf91d2010-11-25 18:00:26 +0000810{
Ben Widawsky27173f12013-08-14 11:38:36 +0200811 struct i915_vma *vma;
Daniel Vetter6ac42f42012-07-21 12:25:01 +0200812 uint32_t flush_domains = 0;
Chris Wilson000433b2013-08-08 14:41:09 +0100813 bool flush_chipset = false;
Chris Wilson432e58e2010-11-25 19:32:06 +0000814 int ret;
Chris Wilson54cf91d2010-11-25 18:00:26 +0000815
Ben Widawsky27173f12013-08-14 11:38:36 +0200816 list_for_each_entry(vma, vmas, exec_list) {
817 struct drm_i915_gem_object *obj = vma->obj;
Ben Widawsky2911a352012-04-05 14:47:36 -0700818 ret = i915_gem_object_sync(obj, ring);
Chris Wilson1ec14ad2010-12-04 11:30:53 +0000819 if (ret)
820 return ret;
Daniel Vetter6ac42f42012-07-21 12:25:01 +0200821
822 if (obj->base.write_domain & I915_GEM_DOMAIN_CPU)
Chris Wilson000433b2013-08-08 14:41:09 +0100823 flush_chipset |= i915_gem_clflush_object(obj, false);
Daniel Vetter6ac42f42012-07-21 12:25:01 +0200824
Daniel Vetter6ac42f42012-07-21 12:25:01 +0200825 flush_domains |= obj->base.write_domain;
Chris Wilson54cf91d2010-11-25 18:00:26 +0000826 }
827
Chris Wilson000433b2013-08-08 14:41:09 +0100828 if (flush_chipset)
Ben Widawskye76e9ae2012-11-04 09:21:27 -0800829 i915_gem_chipset_flush(ring->dev);
Daniel Vetter6ac42f42012-07-21 12:25:01 +0200830
831 if (flush_domains & I915_GEM_DOMAIN_GTT)
832 wmb();
833
Chris Wilson09cf7c92012-07-13 14:14:08 +0100834 /* Unconditionally invalidate gpu caches and ensure that we do flush
835 * any residual writes from the previous batch.
836 */
Chris Wilsona7b97612012-07-20 12:41:08 +0100837 return intel_ring_invalidate_all_caches(ring);
Chris Wilson54cf91d2010-11-25 18:00:26 +0000838}
839
Chris Wilson432e58e2010-11-25 19:32:06 +0000840static bool
841i915_gem_check_execbuffer(struct drm_i915_gem_execbuffer2 *exec)
Chris Wilson54cf91d2010-11-25 18:00:26 +0000842{
Daniel Vettered5982e2013-01-17 22:23:36 +0100843 if (exec->flags & __I915_EXEC_UNKNOWN_FLAGS)
844 return false;
845
Chris Wilson432e58e2010-11-25 19:32:06 +0000846 return ((exec->batch_start_offset | exec->batch_len) & 0x7) == 0;
Chris Wilson54cf91d2010-11-25 18:00:26 +0000847}
848
849static int
850validate_exec_list(struct drm_i915_gem_exec_object2 *exec,
851 int count)
852{
853 int i;
Daniel Vetterb205ca52013-09-19 14:00:11 +0200854 unsigned relocs_total = 0;
855 unsigned relocs_max = UINT_MAX / sizeof(struct drm_i915_gem_relocation_entry);
Chris Wilson54cf91d2010-11-25 18:00:26 +0000856
857 for (i = 0; i < count; i++) {
Ville Syrjälä2bb46292013-02-22 16:12:51 +0200858 char __user *ptr = to_user_ptr(exec[i].relocs_ptr);
Chris Wilson54cf91d2010-11-25 18:00:26 +0000859 int length; /* limited by fault_in_pages_readable() */
860
Daniel Vettered5982e2013-01-17 22:23:36 +0100861 if (exec[i].flags & __EXEC_OBJECT_UNKNOWN_FLAGS)
862 return -EINVAL;
863
Kees Cook3118a4f2013-03-11 17:31:45 -0700864 /* First check for malicious input causing overflow in
865 * the worst case where we need to allocate the entire
866 * relocation tree as a single array.
867 */
868 if (exec[i].relocation_count > relocs_max - relocs_total)
Chris Wilson54cf91d2010-11-25 18:00:26 +0000869 return -EINVAL;
Kees Cook3118a4f2013-03-11 17:31:45 -0700870 relocs_total += exec[i].relocation_count;
Chris Wilson54cf91d2010-11-25 18:00:26 +0000871
872 length = exec[i].relocation_count *
873 sizeof(struct drm_i915_gem_relocation_entry);
Kees Cook30587532013-03-11 14:37:35 -0700874 /*
875 * We must check that the entire relocation array is safe
876 * to read, but since we may need to update the presumed
877 * offsets during execution, check for full write access.
878 */
Chris Wilson54cf91d2010-11-25 18:00:26 +0000879 if (!access_ok(VERIFY_WRITE, ptr, length))
880 return -EFAULT;
881
Xiong Zhang0b74b502013-07-19 13:51:24 +0800882 if (likely(!i915_prefault_disable)) {
883 if (fault_in_multipages_readable(ptr, length))
884 return -EFAULT;
885 }
Chris Wilson54cf91d2010-11-25 18:00:26 +0000886 }
887
888 return 0;
889}
890
Chris Wilson432e58e2010-11-25 19:32:06 +0000891static void
Ben Widawsky27173f12013-08-14 11:38:36 +0200892i915_gem_execbuffer_move_to_active(struct list_head *vmas,
Chris Wilson9d7730912012-11-27 16:22:52 +0000893 struct intel_ring_buffer *ring)
Chris Wilson432e58e2010-11-25 19:32:06 +0000894{
Ben Widawsky27173f12013-08-14 11:38:36 +0200895 struct i915_vma *vma;
Chris Wilson432e58e2010-11-25 19:32:06 +0000896
Ben Widawsky27173f12013-08-14 11:38:36 +0200897 list_for_each_entry(vma, vmas, exec_list) {
898 struct drm_i915_gem_object *obj = vma->obj;
Chris Wilson69c2fc82012-07-20 12:41:03 +0100899 u32 old_read = obj->base.read_domains;
900 u32 old_write = obj->base.write_domain;
Chris Wilsondb53a302011-02-03 11:57:46 +0000901
Chris Wilson432e58e2010-11-25 19:32:06 +0000902 obj->base.write_domain = obj->base.pending_write_domain;
Daniel Vettered5982e2013-01-17 22:23:36 +0100903 if (obj->base.write_domain == 0)
904 obj->base.pending_read_domains |= obj->base.read_domains;
905 obj->base.read_domains = obj->base.pending_read_domains;
Chris Wilson432e58e2010-11-25 19:32:06 +0000906 obj->fenced_gpu_access = obj->pending_fenced_gpu_access;
907
Ben Widawskye2d05a82013-09-24 09:57:58 -0700908 i915_vma_move_to_active(vma, ring);
Chris Wilson432e58e2010-11-25 19:32:06 +0000909 if (obj->base.write_domain) {
910 obj->dirty = 1;
Chris Wilson9d7730912012-11-27 16:22:52 +0000911 obj->last_write_seqno = intel_ring_get_seqno(ring);
Chris Wilsonacb87df2012-05-03 15:47:57 +0100912 if (obj->pin_count) /* check for potential scanout */
Chris Wilsonc65355b2013-06-06 16:53:41 -0300913 intel_mark_fb_busy(obj, ring);
Chris Wilson432e58e2010-11-25 19:32:06 +0000914 }
915
Chris Wilsondb53a302011-02-03 11:57:46 +0000916 trace_i915_gem_object_change_domain(obj, old_read, old_write);
Chris Wilson432e58e2010-11-25 19:32:06 +0000917 }
918}
919
Chris Wilson54cf91d2010-11-25 18:00:26 +0000920static void
921i915_gem_execbuffer_retire_commands(struct drm_device *dev,
Chris Wilson432e58e2010-11-25 19:32:06 +0000922 struct drm_file *file,
Mika Kuoppala7d736f42013-06-12 15:01:39 +0300923 struct intel_ring_buffer *ring,
924 struct drm_i915_gem_object *obj)
Chris Wilson54cf91d2010-11-25 18:00:26 +0000925{
Daniel Vettercc889e02012-06-13 20:45:19 +0200926 /* Unconditionally force add_request to emit a full flush. */
927 ring->gpu_caches_dirty = true;
Chris Wilson54cf91d2010-11-25 18:00:26 +0000928
Chris Wilson432e58e2010-11-25 19:32:06 +0000929 /* Add a breadcrumb for the completion of the batch buffer */
Mika Kuoppala7d736f42013-06-12 15:01:39 +0300930 (void)__i915_add_request(ring, file, obj, NULL);
Chris Wilson432e58e2010-11-25 19:32:06 +0000931}
Chris Wilson54cf91d2010-11-25 18:00:26 +0000932
933static int
Eric Anholtae662d32012-01-03 09:23:29 -0800934i915_reset_gen7_sol_offsets(struct drm_device *dev,
935 struct intel_ring_buffer *ring)
936{
937 drm_i915_private_t *dev_priv = dev->dev_private;
938 int ret, i;
939
940 if (!IS_GEN7(dev) || ring != &dev_priv->ring[RCS])
941 return 0;
942
943 ret = intel_ring_begin(ring, 4 * 3);
944 if (ret)
945 return ret;
946
947 for (i = 0; i < 4; i++) {
948 intel_ring_emit(ring, MI_LOAD_REGISTER_IMM(1));
949 intel_ring_emit(ring, GEN7_SO_WRITE_OFFSET(i));
950 intel_ring_emit(ring, 0);
951 }
952
953 intel_ring_advance(ring);
954
955 return 0;
956}
957
958static int
Chris Wilson54cf91d2010-11-25 18:00:26 +0000959i915_gem_do_execbuffer(struct drm_device *dev, void *data,
960 struct drm_file *file,
961 struct drm_i915_gem_execbuffer2 *args,
Ben Widawsky28d6a7b2013-07-31 17:00:02 -0700962 struct drm_i915_gem_exec_object2 *exec,
963 struct i915_address_space *vm)
Chris Wilson54cf91d2010-11-25 18:00:26 +0000964{
965 drm_i915_private_t *dev_priv = dev->dev_private;
Ben Widawsky27173f12013-08-14 11:38:36 +0200966 struct eb_vmas *eb;
Chris Wilson54cf91d2010-11-25 18:00:26 +0000967 struct drm_i915_gem_object *batch_obj;
968 struct drm_clip_rect *cliprects = NULL;
Chris Wilson54cf91d2010-11-25 18:00:26 +0000969 struct intel_ring_buffer *ring;
Mika Kuoppalabe62acb2013-08-30 16:19:28 +0300970 struct i915_ctx_hang_stats *hs;
Ben Widawsky6e0a69d2012-06-04 14:42:55 -0700971 u32 ctx_id = i915_execbuffer2_get_context_id(*args);
Chris Wilsonc4e7a412010-11-30 14:10:25 +0000972 u32 exec_start, exec_len;
Daniel Vettered5982e2013-01-17 22:23:36 +0100973 u32 mask, flags;
Chris Wilson72bfa192010-12-19 11:42:05 +0000974 int ret, mode, i;
Daniel Vettered5982e2013-01-17 22:23:36 +0100975 bool need_relocs;
Chris Wilson54cf91d2010-11-25 18:00:26 +0000976
Daniel Vettered5982e2013-01-17 22:23:36 +0100977 if (!i915_gem_check_execbuffer(args))
Chris Wilson432e58e2010-11-25 19:32:06 +0000978 return -EINVAL;
Chris Wilson432e58e2010-11-25 19:32:06 +0000979
980 ret = validate_exec_list(exec, args->buffer_count);
Chris Wilson54cf91d2010-11-25 18:00:26 +0000981 if (ret)
982 return ret;
983
Chris Wilsond7d4eed2012-10-17 12:09:54 +0100984 flags = 0;
985 if (args->flags & I915_EXEC_SECURE) {
986 if (!file->is_master || !capable(CAP_SYS_ADMIN))
987 return -EPERM;
988
989 flags |= I915_DISPATCH_SECURE;
990 }
Daniel Vetterb45305f2012-12-17 16:21:27 +0100991 if (args->flags & I915_EXEC_IS_PINNED)
992 flags |= I915_DISPATCH_PINNED;
Chris Wilsond7d4eed2012-10-17 12:09:54 +0100993
Chris Wilson54cf91d2010-11-25 18:00:26 +0000994 switch (args->flags & I915_EXEC_RING_MASK) {
995 case I915_EXEC_DEFAULT:
996 case I915_EXEC_RENDER:
Chris Wilson1ec14ad2010-12-04 11:30:53 +0000997 ring = &dev_priv->ring[RCS];
Chris Wilson54cf91d2010-11-25 18:00:26 +0000998 break;
999 case I915_EXEC_BSD:
Chris Wilson1ec14ad2010-12-04 11:30:53 +00001000 ring = &dev_priv->ring[VCS];
Chris Wilsone8520962013-07-03 17:22:07 +03001001 if (ctx_id != DEFAULT_CONTEXT_ID) {
Ben Widawsky6e0a69d2012-06-04 14:42:55 -07001002 DRM_DEBUG("Ring %s doesn't support contexts\n",
1003 ring->name);
1004 return -EPERM;
1005 }
Chris Wilson54cf91d2010-11-25 18:00:26 +00001006 break;
1007 case I915_EXEC_BLT:
Chris Wilson1ec14ad2010-12-04 11:30:53 +00001008 ring = &dev_priv->ring[BCS];
Chris Wilsone8520962013-07-03 17:22:07 +03001009 if (ctx_id != DEFAULT_CONTEXT_ID) {
Ben Widawsky6e0a69d2012-06-04 14:42:55 -07001010 DRM_DEBUG("Ring %s doesn't support contexts\n",
1011 ring->name);
1012 return -EPERM;
1013 }
Chris Wilson54cf91d2010-11-25 18:00:26 +00001014 break;
Xiang, Haihao82f91b62013-05-28 19:22:33 -07001015 case I915_EXEC_VEBOX:
1016 ring = &dev_priv->ring[VECS];
Chris Wilsone8520962013-07-03 17:22:07 +03001017 if (ctx_id != DEFAULT_CONTEXT_ID) {
Xiang, Haihao82f91b62013-05-28 19:22:33 -07001018 DRM_DEBUG("Ring %s doesn't support contexts\n",
1019 ring->name);
1020 return -EPERM;
1021 }
1022 break;
1023
Chris Wilson54cf91d2010-11-25 18:00:26 +00001024 default:
Daniel Vetterff240192012-01-31 21:08:14 +01001025 DRM_DEBUG("execbuf with unknown ring: %d\n",
Chris Wilson54cf91d2010-11-25 18:00:26 +00001026 (int)(args->flags & I915_EXEC_RING_MASK));
1027 return -EINVAL;
1028 }
Chris Wilsona15817c2012-05-11 14:29:31 +01001029 if (!intel_ring_initialized(ring)) {
1030 DRM_DEBUG("execbuf with invalid ring: %d\n",
1031 (int)(args->flags & I915_EXEC_RING_MASK));
1032 return -EINVAL;
1033 }
Chris Wilson54cf91d2010-11-25 18:00:26 +00001034
Chris Wilson72bfa192010-12-19 11:42:05 +00001035 mode = args->flags & I915_EXEC_CONSTANTS_MASK;
Ben Widawsky84f9f932011-12-12 19:21:58 -08001036 mask = I915_EXEC_CONSTANTS_MASK;
Chris Wilson72bfa192010-12-19 11:42:05 +00001037 switch (mode) {
1038 case I915_EXEC_CONSTANTS_REL_GENERAL:
1039 case I915_EXEC_CONSTANTS_ABSOLUTE:
1040 case I915_EXEC_CONSTANTS_REL_SURFACE:
1041 if (ring == &dev_priv->ring[RCS] &&
1042 mode != dev_priv->relative_constants_mode) {
1043 if (INTEL_INFO(dev)->gen < 4)
1044 return -EINVAL;
1045
1046 if (INTEL_INFO(dev)->gen > 5 &&
1047 mode == I915_EXEC_CONSTANTS_REL_SURFACE)
1048 return -EINVAL;
Ben Widawsky84f9f932011-12-12 19:21:58 -08001049
1050 /* The HW changed the meaning on this bit on gen6 */
1051 if (INTEL_INFO(dev)->gen >= 6)
1052 mask &= ~I915_EXEC_CONSTANTS_REL_SURFACE;
Chris Wilson72bfa192010-12-19 11:42:05 +00001053 }
1054 break;
1055 default:
Daniel Vetterff240192012-01-31 21:08:14 +01001056 DRM_DEBUG("execbuf with unknown constants: %d\n", mode);
Chris Wilson72bfa192010-12-19 11:42:05 +00001057 return -EINVAL;
1058 }
1059
Chris Wilson54cf91d2010-11-25 18:00:26 +00001060 if (args->buffer_count < 1) {
Daniel Vetterff240192012-01-31 21:08:14 +01001061 DRM_DEBUG("execbuf with %d buffers\n", args->buffer_count);
Chris Wilson54cf91d2010-11-25 18:00:26 +00001062 return -EINVAL;
1063 }
Chris Wilson54cf91d2010-11-25 18:00:26 +00001064
1065 if (args->num_cliprects != 0) {
Chris Wilson1ec14ad2010-12-04 11:30:53 +00001066 if (ring != &dev_priv->ring[RCS]) {
Daniel Vetterff240192012-01-31 21:08:14 +01001067 DRM_DEBUG("clip rectangles are only valid with the render ring\n");
Chris Wilsonc4e7a412010-11-30 14:10:25 +00001068 return -EINVAL;
1069 }
1070
Daniel Vetter6ebebc92012-04-26 23:28:11 +02001071 if (INTEL_INFO(dev)->gen >= 5) {
1072 DRM_DEBUG("clip rectangles are only valid on pre-gen5\n");
1073 return -EINVAL;
1074 }
1075
Xi Wang44afb3a2012-04-23 04:06:42 -04001076 if (args->num_cliprects > UINT_MAX / sizeof(*cliprects)) {
1077 DRM_DEBUG("execbuf with %u cliprects\n",
1078 args->num_cliprects);
1079 return -EINVAL;
1080 }
Daniel Vetter5e13a0c2012-05-08 13:39:59 +02001081
Daniel Vettera1e22652013-09-21 00:35:38 +02001082 cliprects = kcalloc(args->num_cliprects,
1083 sizeof(*cliprects),
Chris Wilson54cf91d2010-11-25 18:00:26 +00001084 GFP_KERNEL);
1085 if (cliprects == NULL) {
1086 ret = -ENOMEM;
1087 goto pre_mutex_err;
1088 }
1089
Chris Wilson432e58e2010-11-25 19:32:06 +00001090 if (copy_from_user(cliprects,
Ville Syrjälä2bb46292013-02-22 16:12:51 +02001091 to_user_ptr(args->cliprects_ptr),
1092 sizeof(*cliprects)*args->num_cliprects)) {
Chris Wilson54cf91d2010-11-25 18:00:26 +00001093 ret = -EFAULT;
1094 goto pre_mutex_err;
1095 }
1096 }
1097
Chris Wilson54cf91d2010-11-25 18:00:26 +00001098 ret = i915_mutex_lock_interruptible(dev);
1099 if (ret)
1100 goto pre_mutex_err;
1101
Daniel Vetterdb1b76c2013-07-09 16:51:37 +02001102 if (dev_priv->ums.mm_suspended) {
Chris Wilson54cf91d2010-11-25 18:00:26 +00001103 mutex_unlock(&dev->struct_mutex);
1104 ret = -EBUSY;
1105 goto pre_mutex_err;
1106 }
1107
Ben Widawsky17601cbc2013-11-25 09:54:38 -08001108 eb = eb_create(args);
Chris Wilson67731b82010-12-08 10:38:14 +00001109 if (eb == NULL) {
1110 mutex_unlock(&dev->struct_mutex);
1111 ret = -ENOMEM;
1112 goto pre_mutex_err;
1113 }
1114
Chris Wilson54cf91d2010-11-25 18:00:26 +00001115 /* Look up object handles */
Ben Widawsky27173f12013-08-14 11:38:36 +02001116 ret = eb_lookup_vmas(eb, exec, args, vm, file);
Chris Wilson3b96eff2013-01-08 10:53:14 +00001117 if (ret)
1118 goto err;
Chris Wilson54cf91d2010-11-25 18:00:26 +00001119
Chris Wilson6fe4f142011-01-10 17:35:37 +00001120 /* take note of the batch buffer before we might reorder the lists */
Ben Widawsky27173f12013-08-14 11:38:36 +02001121 batch_obj = list_entry(eb->vmas.prev, struct i915_vma, exec_list)->obj;
Chris Wilson6fe4f142011-01-10 17:35:37 +00001122
Chris Wilson54cf91d2010-11-25 18:00:26 +00001123 /* Move the objects en-masse into the GTT, evicting if necessary. */
Daniel Vettered5982e2013-01-17 22:23:36 +01001124 need_relocs = (args->flags & I915_EXEC_NO_RELOC) == 0;
Ben Widawsky27173f12013-08-14 11:38:36 +02001125 ret = i915_gem_execbuffer_reserve(ring, &eb->vmas, &need_relocs);
Chris Wilson54cf91d2010-11-25 18:00:26 +00001126 if (ret)
1127 goto err;
1128
1129 /* The objects are in their final locations, apply the relocations. */
Daniel Vettered5982e2013-01-17 22:23:36 +01001130 if (need_relocs)
Ben Widawsky17601cbc2013-11-25 09:54:38 -08001131 ret = i915_gem_execbuffer_relocate(eb);
Chris Wilson54cf91d2010-11-25 18:00:26 +00001132 if (ret) {
1133 if (ret == -EFAULT) {
Daniel Vettered5982e2013-01-17 22:23:36 +01001134 ret = i915_gem_execbuffer_relocate_slow(dev, args, file, ring,
Ben Widawsky27173f12013-08-14 11:38:36 +02001135 eb, exec);
Chris Wilson54cf91d2010-11-25 18:00:26 +00001136 BUG_ON(!mutex_is_locked(&dev->struct_mutex));
1137 }
1138 if (ret)
1139 goto err;
1140 }
1141
1142 /* Set the pending read domains for the batch buffer to COMMAND */
Chris Wilson54cf91d2010-11-25 18:00:26 +00001143 if (batch_obj->base.pending_write_domain) {
Daniel Vetterff240192012-01-31 21:08:14 +01001144 DRM_DEBUG("Attempting to use self-modifying batch buffer\n");
Chris Wilson54cf91d2010-11-25 18:00:26 +00001145 ret = -EINVAL;
1146 goto err;
1147 }
1148 batch_obj->base.pending_read_domains |= I915_GEM_DOMAIN_COMMAND;
1149
Chris Wilsond7d4eed2012-10-17 12:09:54 +01001150 /* snb/ivb/vlv conflate the "batch in ppgtt" bit with the "non-secure
1151 * batch" bit. Hence we need to pin secure batches into the global gtt.
Ben Widawsky28cf5412013-11-02 21:07:26 -07001152 * hsw should have this fixed, but bdw mucks it up again. */
Chris Wilsond7d4eed2012-10-17 12:09:54 +01001153 if (flags & I915_DISPATCH_SECURE && !batch_obj->has_global_gtt_mapping)
1154 i915_gem_gtt_bind_object(batch_obj, batch_obj->cache_level);
1155
Ben Widawsky27173f12013-08-14 11:38:36 +02001156 ret = i915_gem_execbuffer_move_to_gpu(ring, &eb->vmas);
Chris Wilson54cf91d2010-11-25 18:00:26 +00001157 if (ret)
1158 goto err;
1159
Mika Kuoppalabe62acb2013-08-30 16:19:28 +03001160 hs = i915_gem_context_get_hang_stats(dev, file, ctx_id);
1161 if (IS_ERR(hs)) {
1162 ret = PTR_ERR(hs);
1163 goto err;
1164 }
1165
1166 if (hs->banned) {
1167 ret = -EIO;
1168 goto err;
1169 }
1170
Eric Anholt0da5cec2012-07-23 12:33:55 -07001171 ret = i915_switch_context(ring, file, ctx_id);
1172 if (ret)
1173 goto err;
1174
Ben Widawskye2971bd2011-12-12 19:21:57 -08001175 if (ring == &dev_priv->ring[RCS] &&
1176 mode != dev_priv->relative_constants_mode) {
1177 ret = intel_ring_begin(ring, 4);
1178 if (ret)
1179 goto err;
1180
1181 intel_ring_emit(ring, MI_NOOP);
1182 intel_ring_emit(ring, MI_LOAD_REGISTER_IMM(1));
1183 intel_ring_emit(ring, INSTPM);
Ben Widawsky84f9f932011-12-12 19:21:58 -08001184 intel_ring_emit(ring, mask << 16 | mode);
Ben Widawskye2971bd2011-12-12 19:21:57 -08001185 intel_ring_advance(ring);
1186
1187 dev_priv->relative_constants_mode = mode;
1188 }
1189
Eric Anholtae662d32012-01-03 09:23:29 -08001190 if (args->flags & I915_EXEC_GEN7_SOL_RESET) {
1191 ret = i915_reset_gen7_sol_offsets(dev, ring);
1192 if (ret)
1193 goto err;
1194 }
1195
Ben Widawsky28d6a7b2013-07-31 17:00:02 -07001196 exec_start = i915_gem_obj_offset(batch_obj, vm) +
1197 args->batch_start_offset;
Chris Wilsonc4e7a412010-11-30 14:10:25 +00001198 exec_len = args->batch_len;
1199 if (cliprects) {
1200 for (i = 0; i < args->num_cliprects; i++) {
1201 ret = i915_emit_box(dev, &cliprects[i],
1202 args->DR1, args->DR4);
1203 if (ret)
1204 goto err;
1205
1206 ret = ring->dispatch_execbuffer(ring,
Chris Wilsond7d4eed2012-10-17 12:09:54 +01001207 exec_start, exec_len,
1208 flags);
Chris Wilsonc4e7a412010-11-30 14:10:25 +00001209 if (ret)
1210 goto err;
1211 }
1212 } else {
Chris Wilsond7d4eed2012-10-17 12:09:54 +01001213 ret = ring->dispatch_execbuffer(ring,
1214 exec_start, exec_len,
1215 flags);
Chris Wilsonc4e7a412010-11-30 14:10:25 +00001216 if (ret)
1217 goto err;
1218 }
Chris Wilson54cf91d2010-11-25 18:00:26 +00001219
Chris Wilson9d7730912012-11-27 16:22:52 +00001220 trace_i915_gem_ring_dispatch(ring, intel_ring_get_seqno(ring), flags);
1221
Ben Widawsky27173f12013-08-14 11:38:36 +02001222 i915_gem_execbuffer_move_to_active(&eb->vmas, ring);
Mika Kuoppala7d736f42013-06-12 15:01:39 +03001223 i915_gem_execbuffer_retire_commands(dev, file, ring, batch_obj);
Chris Wilson54cf91d2010-11-25 18:00:26 +00001224
1225err:
Chris Wilson67731b82010-12-08 10:38:14 +00001226 eb_destroy(eb);
Chris Wilson54cf91d2010-11-25 18:00:26 +00001227
1228 mutex_unlock(&dev->struct_mutex);
1229
1230pre_mutex_err:
Chris Wilson54cf91d2010-11-25 18:00:26 +00001231 kfree(cliprects);
Chris Wilson54cf91d2010-11-25 18:00:26 +00001232 return ret;
1233}
1234
1235/*
1236 * Legacy execbuffer just creates an exec2 list from the original exec object
1237 * list array and passes it to the real function.
1238 */
1239int
1240i915_gem_execbuffer(struct drm_device *dev, void *data,
1241 struct drm_file *file)
1242{
Ben Widawsky28d6a7b2013-07-31 17:00:02 -07001243 struct drm_i915_private *dev_priv = dev->dev_private;
Chris Wilson54cf91d2010-11-25 18:00:26 +00001244 struct drm_i915_gem_execbuffer *args = data;
1245 struct drm_i915_gem_execbuffer2 exec2;
1246 struct drm_i915_gem_exec_object *exec_list = NULL;
1247 struct drm_i915_gem_exec_object2 *exec2_list = NULL;
1248 int ret, i;
1249
Chris Wilson54cf91d2010-11-25 18:00:26 +00001250 if (args->buffer_count < 1) {
Daniel Vetterff240192012-01-31 21:08:14 +01001251 DRM_DEBUG("execbuf with %d buffers\n", args->buffer_count);
Chris Wilson54cf91d2010-11-25 18:00:26 +00001252 return -EINVAL;
1253 }
1254
1255 /* Copy in the exec list from userland */
1256 exec_list = drm_malloc_ab(sizeof(*exec_list), args->buffer_count);
1257 exec2_list = drm_malloc_ab(sizeof(*exec2_list), args->buffer_count);
1258 if (exec_list == NULL || exec2_list == NULL) {
Daniel Vetterff240192012-01-31 21:08:14 +01001259 DRM_DEBUG("Failed to allocate exec list for %d buffers\n",
Chris Wilson54cf91d2010-11-25 18:00:26 +00001260 args->buffer_count);
1261 drm_free_large(exec_list);
1262 drm_free_large(exec2_list);
1263 return -ENOMEM;
1264 }
1265 ret = copy_from_user(exec_list,
Ville Syrjälä2bb46292013-02-22 16:12:51 +02001266 to_user_ptr(args->buffers_ptr),
Chris Wilson54cf91d2010-11-25 18:00:26 +00001267 sizeof(*exec_list) * args->buffer_count);
1268 if (ret != 0) {
Daniel Vetterff240192012-01-31 21:08:14 +01001269 DRM_DEBUG("copy %d exec entries failed %d\n",
Chris Wilson54cf91d2010-11-25 18:00:26 +00001270 args->buffer_count, ret);
1271 drm_free_large(exec_list);
1272 drm_free_large(exec2_list);
1273 return -EFAULT;
1274 }
1275
1276 for (i = 0; i < args->buffer_count; i++) {
1277 exec2_list[i].handle = exec_list[i].handle;
1278 exec2_list[i].relocation_count = exec_list[i].relocation_count;
1279 exec2_list[i].relocs_ptr = exec_list[i].relocs_ptr;
1280 exec2_list[i].alignment = exec_list[i].alignment;
1281 exec2_list[i].offset = exec_list[i].offset;
1282 if (INTEL_INFO(dev)->gen < 4)
1283 exec2_list[i].flags = EXEC_OBJECT_NEEDS_FENCE;
1284 else
1285 exec2_list[i].flags = 0;
1286 }
1287
1288 exec2.buffers_ptr = args->buffers_ptr;
1289 exec2.buffer_count = args->buffer_count;
1290 exec2.batch_start_offset = args->batch_start_offset;
1291 exec2.batch_len = args->batch_len;
1292 exec2.DR1 = args->DR1;
1293 exec2.DR4 = args->DR4;
1294 exec2.num_cliprects = args->num_cliprects;
1295 exec2.cliprects_ptr = args->cliprects_ptr;
1296 exec2.flags = I915_EXEC_RENDER;
Ben Widawsky6e0a69d2012-06-04 14:42:55 -07001297 i915_execbuffer2_set_context_id(exec2, 0);
Chris Wilson54cf91d2010-11-25 18:00:26 +00001298
Ben Widawsky28d6a7b2013-07-31 17:00:02 -07001299 ret = i915_gem_do_execbuffer(dev, data, file, &exec2, exec2_list,
1300 &dev_priv->gtt.base);
Chris Wilson54cf91d2010-11-25 18:00:26 +00001301 if (!ret) {
1302 /* Copy the new buffer offsets back to the user's exec list. */
1303 for (i = 0; i < args->buffer_count; i++)
1304 exec_list[i].offset = exec2_list[i].offset;
1305 /* ... and back out to userspace */
Ville Syrjälä2bb46292013-02-22 16:12:51 +02001306 ret = copy_to_user(to_user_ptr(args->buffers_ptr),
Chris Wilson54cf91d2010-11-25 18:00:26 +00001307 exec_list,
1308 sizeof(*exec_list) * args->buffer_count);
1309 if (ret) {
1310 ret = -EFAULT;
Daniel Vetterff240192012-01-31 21:08:14 +01001311 DRM_DEBUG("failed to copy %d exec entries "
Chris Wilson54cf91d2010-11-25 18:00:26 +00001312 "back to user (%d)\n",
1313 args->buffer_count, ret);
1314 }
1315 }
1316
1317 drm_free_large(exec_list);
1318 drm_free_large(exec2_list);
1319 return ret;
1320}
1321
1322int
1323i915_gem_execbuffer2(struct drm_device *dev, void *data,
1324 struct drm_file *file)
1325{
Ben Widawsky28d6a7b2013-07-31 17:00:02 -07001326 struct drm_i915_private *dev_priv = dev->dev_private;
Chris Wilson54cf91d2010-11-25 18:00:26 +00001327 struct drm_i915_gem_execbuffer2 *args = data;
1328 struct drm_i915_gem_exec_object2 *exec2_list = NULL;
1329 int ret;
1330
Xi Wanged8cd3b2012-04-23 04:06:41 -04001331 if (args->buffer_count < 1 ||
1332 args->buffer_count > UINT_MAX / sizeof(*exec2_list)) {
Daniel Vetterff240192012-01-31 21:08:14 +01001333 DRM_DEBUG("execbuf2 with %d buffers\n", args->buffer_count);
Chris Wilson54cf91d2010-11-25 18:00:26 +00001334 return -EINVAL;
1335 }
1336
Chris Wilson8408c282011-02-21 12:54:48 +00001337 exec2_list = kmalloc(sizeof(*exec2_list)*args->buffer_count,
Chris Wilson419fa722013-01-08 10:53:13 +00001338 GFP_TEMPORARY | __GFP_NOWARN | __GFP_NORETRY);
Chris Wilson8408c282011-02-21 12:54:48 +00001339 if (exec2_list == NULL)
1340 exec2_list = drm_malloc_ab(sizeof(*exec2_list),
1341 args->buffer_count);
Chris Wilson54cf91d2010-11-25 18:00:26 +00001342 if (exec2_list == NULL) {
Daniel Vetterff240192012-01-31 21:08:14 +01001343 DRM_DEBUG("Failed to allocate exec list for %d buffers\n",
Chris Wilson54cf91d2010-11-25 18:00:26 +00001344 args->buffer_count);
1345 return -ENOMEM;
1346 }
1347 ret = copy_from_user(exec2_list,
Ville Syrjälä2bb46292013-02-22 16:12:51 +02001348 to_user_ptr(args->buffers_ptr),
Chris Wilson54cf91d2010-11-25 18:00:26 +00001349 sizeof(*exec2_list) * args->buffer_count);
1350 if (ret != 0) {
Daniel Vetterff240192012-01-31 21:08:14 +01001351 DRM_DEBUG("copy %d exec entries failed %d\n",
Chris Wilson54cf91d2010-11-25 18:00:26 +00001352 args->buffer_count, ret);
1353 drm_free_large(exec2_list);
1354 return -EFAULT;
1355 }
1356
Ben Widawsky28d6a7b2013-07-31 17:00:02 -07001357 ret = i915_gem_do_execbuffer(dev, data, file, args, exec2_list,
1358 &dev_priv->gtt.base);
Chris Wilson54cf91d2010-11-25 18:00:26 +00001359 if (!ret) {
1360 /* Copy the new buffer offsets back to the user's exec list. */
Ville Syrjälä2bb46292013-02-22 16:12:51 +02001361 ret = copy_to_user(to_user_ptr(args->buffers_ptr),
Chris Wilson54cf91d2010-11-25 18:00:26 +00001362 exec2_list,
1363 sizeof(*exec2_list) * args->buffer_count);
1364 if (ret) {
1365 ret = -EFAULT;
Daniel Vetterff240192012-01-31 21:08:14 +01001366 DRM_DEBUG("failed to copy %d exec entries "
Chris Wilson54cf91d2010-11-25 18:00:26 +00001367 "back to user (%d)\n",
1368 args->buffer_count, ret);
1369 }
1370 }
1371
1372 drm_free_large(exec2_list);
1373 return ret;
1374}