aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJoonas Lahtinen <joonas.lahtinen@linux.intel.com>2015-03-16 08:11:13 -0400
committerDaniel Vetter <daniel.vetter@ffwll.ch>2015-03-20 06:48:03 -0400
commitec7adb6ee79c8c9fe64d63ad638a31cd62e55515 (patch)
tree9af18c1e023146304feacf5dd5006ae07498d267
parentaca5e361e84d20ac68eedb37b7c4561a33f56198 (diff)
drm/i915: Do not use ggtt_view with (aliasing) PPGTT
GGTT views are only applicable when dealing with GGTT. Change the code to reject ggtt_view where it should not be used and require it when it should be. v2: - Dropped _ppgtt_ infixes, allow both types to be passed - Disregard other but normal views when no view is specified - More checks that valid parameters are passed - More readable error checking v3: - Prefer WARN_ONCE over BUG_ON when there is code path for failure Signed-off-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com> Reviewed-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com> [danvet: Drop unecessary forward decl from earlier patch iterations.] [danvet: Remove unused variable spotted by Tvrtko.] Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
-rw-r--r--drivers/gpu/drm/i915/i915_drv.h100
-rw-r--r--drivers/gpu/drm/i915/i915_gem.c174
-rw-r--r--drivers/gpu/drm/i915/i915_gem_gtt.c71
3 files changed, 226 insertions, 119 deletions
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 8ba7e1b7b733..81f60b48def2 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -2623,20 +2623,16 @@ void i915_gem_vma_destroy(struct i915_vma *vma);
2623#define PIN_GLOBAL 0x4 2623#define PIN_GLOBAL 0x4
2624#define PIN_OFFSET_BIAS 0x8 2624#define PIN_OFFSET_BIAS 0x8
2625#define PIN_OFFSET_MASK (~4095) 2625#define PIN_OFFSET_MASK (~4095)
2626int __must_check i915_gem_object_pin_view(struct drm_i915_gem_object *obj, 2626int __must_check
2627 struct i915_address_space *vm, 2627i915_gem_object_pin(struct drm_i915_gem_object *obj,
2628 uint32_t alignment, 2628 struct i915_address_space *vm,
2629 uint64_t flags, 2629 uint32_t alignment,
2630 const struct i915_ggtt_view *view); 2630 uint64_t flags);
2631static inline 2631int __must_check
2632int __must_check i915_gem_object_pin(struct drm_i915_gem_object *obj, 2632i915_gem_object_ggtt_pin(struct drm_i915_gem_object *obj,
2633 struct i915_address_space *vm, 2633 const struct i915_ggtt_view *view,
2634 uint32_t alignment, 2634 uint32_t alignment,
2635 uint64_t flags) 2635 uint64_t flags);
2636{
2637 return i915_gem_object_pin_view(obj, vm, alignment, flags,
2638 &i915_ggtt_view_normal);
2639}
2640 2636
2641int i915_vma_bind(struct i915_vma *vma, enum i915_cache_level cache_level, 2637int i915_vma_bind(struct i915_vma *vma, enum i915_cache_level cache_level,
2642 u32 flags); 2638 u32 flags);
@@ -2800,60 +2796,46 @@ struct dma_buf *i915_gem_prime_export(struct drm_device *dev,
2800 2796
2801void i915_gem_restore_fences(struct drm_device *dev); 2797void i915_gem_restore_fences(struct drm_device *dev);
2802 2798
2803unsigned long i915_gem_obj_offset_view(struct drm_i915_gem_object *o, 2799unsigned long
2804 struct i915_address_space *vm, 2800i915_gem_obj_ggtt_offset_view(struct drm_i915_gem_object *o,
2805 enum i915_ggtt_view_type view); 2801 enum i915_ggtt_view_type view);
2806static inline 2802unsigned long
2807unsigned long i915_gem_obj_offset(struct drm_i915_gem_object *o, 2803i915_gem_obj_offset(struct drm_i915_gem_object *o,
2808 struct i915_address_space *vm) 2804 struct i915_address_space *vm);
2805static inline unsigned long
2806i915_gem_obj_ggtt_offset(struct drm_i915_gem_object *o)
2809{ 2807{
2810 return i915_gem_obj_offset_view(o, vm, I915_GGTT_VIEW_NORMAL); 2808 return i915_gem_obj_ggtt_offset_view(o, I915_GGTT_VIEW_NORMAL);
2811} 2809}
2810
2812bool i915_gem_obj_bound_any(struct drm_i915_gem_object *o); 2811bool i915_gem_obj_bound_any(struct drm_i915_gem_object *o);
2813bool i915_gem_obj_bound_view(struct drm_i915_gem_object *o, 2812bool i915_gem_obj_ggtt_bound_view(struct drm_i915_gem_object *o,
2814 struct i915_address_space *vm, 2813 enum i915_ggtt_view_type view);
2815 enum i915_ggtt_view_type view);
2816static inline
2817bool i915_gem_obj_bound(struct drm_i915_gem_object *o, 2814bool i915_gem_obj_bound(struct drm_i915_gem_object *o,
2818 struct i915_address_space *vm) 2815 struct i915_address_space *vm);
2819{
2820 return i915_gem_obj_bound_view(o, vm, I915_GGTT_VIEW_NORMAL);
2821}
2822 2816
2823unsigned long i915_gem_obj_size(struct drm_i915_gem_object *o, 2817unsigned long i915_gem_obj_size(struct drm_i915_gem_object *o,
2824 struct i915_address_space *vm); 2818 struct i915_address_space *vm);
2825struct i915_vma *i915_gem_obj_to_vma_view(struct drm_i915_gem_object *obj,
2826 struct i915_address_space *vm,
2827 const struct i915_ggtt_view *view);
2828static inline
2829struct i915_vma *i915_gem_obj_to_vma(struct drm_i915_gem_object *obj,
2830 struct i915_address_space *vm)
2831{
2832 return i915_gem_obj_to_vma_view(obj, vm, &i915_ggtt_view_normal);
2833}
2834
2835struct i915_vma * 2819struct i915_vma *
2836i915_gem_obj_lookup_or_create_vma_view(struct drm_i915_gem_object *obj, 2820i915_gem_obj_to_vma(struct drm_i915_gem_object *obj,
2837 struct i915_address_space *vm, 2821 struct i915_address_space *vm);
2838 const struct i915_ggtt_view *view); 2822struct i915_vma *
2823i915_gem_obj_to_ggtt_view(struct drm_i915_gem_object *obj,
2824 const struct i915_ggtt_view *view);
2839 2825
2840static inline
2841struct i915_vma * 2826struct i915_vma *
2842i915_gem_obj_lookup_or_create_vma(struct drm_i915_gem_object *obj, 2827i915_gem_obj_lookup_or_create_vma(struct drm_i915_gem_object *obj,
2843 struct i915_address_space *vm) 2828 struct i915_address_space *vm);
2844{ 2829struct i915_vma *
2845 return i915_gem_obj_lookup_or_create_vma_view(obj, vm, 2830i915_gem_obj_lookup_or_create_ggtt_vma(struct drm_i915_gem_object *obj,
2846 &i915_ggtt_view_normal); 2831 const struct i915_ggtt_view *view);
2847}
2848 2832
2849struct i915_vma *i915_gem_obj_to_ggtt(struct drm_i915_gem_object *obj); 2833static inline struct i915_vma *
2850static inline bool i915_gem_obj_is_pinned(struct drm_i915_gem_object *obj) { 2834i915_gem_obj_to_ggtt(struct drm_i915_gem_object *obj)
2851 struct i915_vma *vma; 2835{
2852 list_for_each_entry(vma, &obj->vma_list, vma_link) 2836 return i915_gem_obj_to_ggtt_view(obj, &i915_ggtt_view_normal);
2853 if (vma->pin_count > 0)
2854 return true;
2855 return false;
2856} 2837}
2838bool i915_gem_obj_is_pinned(struct drm_i915_gem_object *obj);
2857 2839
2858/* Some GGTT VM helpers */ 2840/* Some GGTT VM helpers */
2859#define i915_obj_to_ggtt(obj) \ 2841#define i915_obj_to_ggtt(obj) \
@@ -2876,13 +2858,7 @@ i915_vm_to_ppgtt(struct i915_address_space *vm)
2876 2858
2877static inline bool i915_gem_obj_ggtt_bound(struct drm_i915_gem_object *obj) 2859static inline bool i915_gem_obj_ggtt_bound(struct drm_i915_gem_object *obj)
2878{ 2860{
2879 return i915_gem_obj_bound(obj, i915_obj_to_ggtt(obj)); 2861 return i915_gem_obj_ggtt_bound_view(obj, I915_GGTT_VIEW_NORMAL);
2880}
2881
2882static inline unsigned long
2883i915_gem_obj_ggtt_offset(struct drm_i915_gem_object *obj)
2884{
2885 return i915_gem_obj_offset(obj, i915_obj_to_ggtt(obj));
2886} 2862}
2887 2863
2888static inline unsigned long 2864static inline unsigned long
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 0fe313d0f609..cc8672a16da4 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -3518,9 +3518,9 @@ static bool i915_gem_valid_gtt_space(struct i915_vma *vma,
3518static struct i915_vma * 3518static struct i915_vma *
3519i915_gem_object_bind_to_vm(struct drm_i915_gem_object *obj, 3519i915_gem_object_bind_to_vm(struct drm_i915_gem_object *obj,
3520 struct i915_address_space *vm, 3520 struct i915_address_space *vm,
3521 const struct i915_ggtt_view *ggtt_view,
3521 unsigned alignment, 3522 unsigned alignment,
3522 uint64_t flags, 3523 uint64_t flags)
3523 const struct i915_ggtt_view *view)
3524{ 3524{
3525 struct drm_device *dev = obj->base.dev; 3525 struct drm_device *dev = obj->base.dev;
3526 struct drm_i915_private *dev_priv = dev->dev_private; 3526 struct drm_i915_private *dev_priv = dev->dev_private;
@@ -3532,6 +3532,9 @@ i915_gem_object_bind_to_vm(struct drm_i915_gem_object *obj,
3532 struct i915_vma *vma; 3532 struct i915_vma *vma;
3533 int ret; 3533 int ret;
3534 3534
3535 if(WARN_ON(i915_is_ggtt(vm) != !!ggtt_view))
3536 return ERR_PTR(-EINVAL);
3537
3535 fence_size = i915_gem_get_gtt_size(dev, 3538 fence_size = i915_gem_get_gtt_size(dev,
3536 obj->base.size, 3539 obj->base.size,
3537 obj->tiling_mode); 3540 obj->tiling_mode);
@@ -3570,7 +3573,9 @@ i915_gem_object_bind_to_vm(struct drm_i915_gem_object *obj,
3570 3573
3571 i915_gem_object_pin_pages(obj); 3574 i915_gem_object_pin_pages(obj);
3572 3575
3573 vma = i915_gem_obj_lookup_or_create_vma_view(obj, vm, view); 3576 vma = ggtt_view ? i915_gem_obj_lookup_or_create_ggtt_vma(obj, ggtt_view) :
3577 i915_gem_obj_lookup_or_create_vma(obj, vm);
3578
3574 if (IS_ERR(vma)) 3579 if (IS_ERR(vma))
3575 goto err_unpin; 3580 goto err_unpin;
3576 3581
@@ -4167,12 +4172,12 @@ i915_vma_misplaced(struct i915_vma *vma, uint32_t alignment, uint64_t flags)
4167 return false; 4172 return false;
4168} 4173}
4169 4174
4170int 4175static int
4171i915_gem_object_pin_view(struct drm_i915_gem_object *obj, 4176i915_gem_object_do_pin(struct drm_i915_gem_object *obj,
4172 struct i915_address_space *vm, 4177 struct i915_address_space *vm,
4173 uint32_t alignment, 4178 const struct i915_ggtt_view *ggtt_view,
4174 uint64_t flags, 4179 uint32_t alignment,
4175 const struct i915_ggtt_view *view) 4180 uint64_t flags)
4176{ 4181{
4177 struct drm_i915_private *dev_priv = obj->base.dev->dev_private; 4182 struct drm_i915_private *dev_priv = obj->base.dev->dev_private;
4178 struct i915_vma *vma; 4183 struct i915_vma *vma;
@@ -4188,17 +4193,29 @@ i915_gem_object_pin_view(struct drm_i915_gem_object *obj,
4188 if (WARN_ON((flags & (PIN_MAPPABLE | PIN_GLOBAL)) == PIN_MAPPABLE)) 4193 if (WARN_ON((flags & (PIN_MAPPABLE | PIN_GLOBAL)) == PIN_MAPPABLE))
4189 return -EINVAL; 4194 return -EINVAL;
4190 4195
4191 vma = i915_gem_obj_to_vma_view(obj, vm, view); 4196 if (WARN_ON(i915_is_ggtt(vm) != !!ggtt_view))
4197 return -EINVAL;
4198
4199 vma = ggtt_view ? i915_gem_obj_to_ggtt_view(obj, ggtt_view) :
4200 i915_gem_obj_to_vma(obj, vm);
4201
4202 if (IS_ERR(vma))
4203 return PTR_ERR(vma);
4204
4192 if (vma) { 4205 if (vma) {
4193 if (WARN_ON(vma->pin_count == DRM_I915_GEM_OBJECT_MAX_PIN_COUNT)) 4206 if (WARN_ON(vma->pin_count == DRM_I915_GEM_OBJECT_MAX_PIN_COUNT))
4194 return -EBUSY; 4207 return -EBUSY;
4195 4208
4196 if (i915_vma_misplaced(vma, alignment, flags)) { 4209 if (i915_vma_misplaced(vma, alignment, flags)) {
4210 unsigned long offset;
4211 offset = ggtt_view ? i915_gem_obj_ggtt_offset_view(obj, ggtt_view->type) :
4212 i915_gem_obj_offset(obj, vm);
4197 WARN(vma->pin_count, 4213 WARN(vma->pin_count,
4198 "bo is already pinned with incorrect alignment:" 4214 "bo is already pinned in %s with incorrect alignment:"
4199 " offset=%lx, req.alignment=%x, req.map_and_fenceable=%d," 4215 " offset=%lx, req.alignment=%x, req.map_and_fenceable=%d,"
4200 " obj->map_and_fenceable=%d\n", 4216 " obj->map_and_fenceable=%d\n",
4201 i915_gem_obj_offset_view(obj, vm, view->type), 4217 ggtt_view ? "ggtt" : "ppgtt",
4218 offset,
4202 alignment, 4219 alignment,
4203 !!(flags & PIN_MAPPABLE), 4220 !!(flags & PIN_MAPPABLE),
4204 obj->map_and_fenceable); 4221 obj->map_and_fenceable);
@@ -4212,8 +4229,8 @@ i915_gem_object_pin_view(struct drm_i915_gem_object *obj,
4212 4229
4213 bound = vma ? vma->bound : 0; 4230 bound = vma ? vma->bound : 0;
4214 if (vma == NULL || !drm_mm_node_allocated(&vma->node)) { 4231 if (vma == NULL || !drm_mm_node_allocated(&vma->node)) {
4215 vma = i915_gem_object_bind_to_vm(obj, vm, alignment, 4232 vma = i915_gem_object_bind_to_vm(obj, vm, ggtt_view, alignment,
4216 flags, view); 4233 flags);
4217 if (IS_ERR(vma)) 4234 if (IS_ERR(vma))
4218 return PTR_ERR(vma); 4235 return PTR_ERR(vma);
4219 } 4236 }
@@ -4254,6 +4271,30 @@ i915_gem_object_pin_view(struct drm_i915_gem_object *obj,
4254 return 0; 4271 return 0;
4255} 4272}
4256 4273
4274int
4275i915_gem_object_pin(struct drm_i915_gem_object *obj,
4276 struct i915_address_space *vm,
4277 uint32_t alignment,
4278 uint64_t flags)
4279{
4280 return i915_gem_object_do_pin(obj, vm,
4281 i915_is_ggtt(vm) ? &i915_ggtt_view_normal : NULL,
4282 alignment, flags);
4283}
4284
4285int
4286i915_gem_object_ggtt_pin(struct drm_i915_gem_object *obj,
4287 const struct i915_ggtt_view *view,
4288 uint32_t alignment,
4289 uint64_t flags)
4290{
4291 if (WARN_ONCE(!view, "no view specified"))
4292 return -EINVAL;
4293
4294 return i915_gem_object_do_pin(obj, i915_obj_to_ggtt(obj), view,
4295 alignment, flags);
4296}
4297
4257void 4298void
4258i915_gem_object_ggtt_unpin(struct drm_i915_gem_object *obj) 4299i915_gem_object_ggtt_unpin(struct drm_i915_gem_object *obj)
4259{ 4300{
@@ -4559,15 +4600,32 @@ void i915_gem_free_object(struct drm_gem_object *gem_obj)
4559 intel_runtime_pm_put(dev_priv); 4600 intel_runtime_pm_put(dev_priv);
4560} 4601}
4561 4602
4562struct i915_vma *i915_gem_obj_to_vma_view(struct drm_i915_gem_object *obj, 4603struct i915_vma *i915_gem_obj_to_vma(struct drm_i915_gem_object *obj,
4563 struct i915_address_space *vm, 4604 struct i915_address_space *vm)
4564 const struct i915_ggtt_view *view)
4565{ 4605{
4566 struct i915_vma *vma; 4606 struct i915_vma *vma;
4567 list_for_each_entry(vma, &obj->vma_list, vma_link) 4607 list_for_each_entry(vma, &obj->vma_list, vma_link) {
4568 if (vma->vm == vm && vma->ggtt_view.type == view->type) 4608 if (i915_is_ggtt(vma->vm) &&
4609 vma->ggtt_view.type != I915_GGTT_VIEW_NORMAL)
4610 continue;
4611 if (vma->vm == vm)
4569 return vma; 4612 return vma;
4613 }
4614 return NULL;
4615}
4616
4617struct i915_vma *i915_gem_obj_to_ggtt_view(struct drm_i915_gem_object *obj,
4618 const struct i915_ggtt_view *view)
4619{
4620 struct i915_address_space *ggtt = i915_obj_to_ggtt(obj);
4621 struct i915_vma *vma;
4570 4622
4623 if (WARN_ONCE(!view, "no view specified"))
4624 return ERR_PTR(-EINVAL);
4625
4626 list_for_each_entry(vma, &obj->vma_list, vma_link)
4627 if (vma->vm == ggtt && vma->ggtt_view.type == view->type)
4628 return vma;
4571 return NULL; 4629 return NULL;
4572} 4630}
4573 4631
@@ -5176,9 +5234,9 @@ i915_gem_shrinker_count(struct shrinker *shrinker, struct shrink_control *sc)
5176} 5234}
5177 5235
5178/* All the new VM stuff */ 5236/* All the new VM stuff */
5179unsigned long i915_gem_obj_offset_view(struct drm_i915_gem_object *o, 5237unsigned long
5180 struct i915_address_space *vm, 5238i915_gem_obj_offset(struct drm_i915_gem_object *o,
5181 enum i915_ggtt_view_type view) 5239 struct i915_address_space *vm)
5182{ 5240{
5183 struct drm_i915_private *dev_priv = o->base.dev->dev_private; 5241 struct drm_i915_private *dev_priv = o->base.dev->dev_private;
5184 struct i915_vma *vma; 5242 struct i915_vma *vma;
@@ -5186,23 +5244,57 @@ unsigned long i915_gem_obj_offset_view(struct drm_i915_gem_object *o,
5186 WARN_ON(vm == &dev_priv->mm.aliasing_ppgtt->base); 5244 WARN_ON(vm == &dev_priv->mm.aliasing_ppgtt->base);
5187 5245
5188 list_for_each_entry(vma, &o->vma_list, vma_link) { 5246 list_for_each_entry(vma, &o->vma_list, vma_link) {
5189 if (vma->vm == vm && vma->ggtt_view.type == view) 5247 if (i915_is_ggtt(vma->vm) &&
5248 vma->ggtt_view.type != I915_GGTT_VIEW_NORMAL)
5249 continue;
5250 if (vma->vm == vm)
5190 return vma->node.start; 5251 return vma->node.start;
5191
5192 } 5252 }
5253
5193 WARN(1, "%s vma for this object not found.\n", 5254 WARN(1, "%s vma for this object not found.\n",
5194 i915_is_ggtt(vm) ? "global" : "ppgtt"); 5255 i915_is_ggtt(vm) ? "global" : "ppgtt");
5195 return -1; 5256 return -1;
5196} 5257}
5197 5258
5198bool i915_gem_obj_bound_view(struct drm_i915_gem_object *o, 5259unsigned long
5199 struct i915_address_space *vm, 5260i915_gem_obj_ggtt_offset_view(struct drm_i915_gem_object *o,
5200 enum i915_ggtt_view_type view) 5261 enum i915_ggtt_view_type view)
5201{ 5262{
5263 struct i915_address_space *ggtt = i915_obj_to_ggtt(o);
5202 struct i915_vma *vma; 5264 struct i915_vma *vma;
5203 5265
5204 list_for_each_entry(vma, &o->vma_list, vma_link) 5266 list_for_each_entry(vma, &o->vma_list, vma_link)
5205 if (vma->vm == vm && 5267 if (vma->vm == ggtt && vma->ggtt_view.type == view)
5268 return vma->node.start;
5269
5270 WARN(1, "global vma for this object not found.\n");
5271 return -1;
5272}
5273
5274bool i915_gem_obj_bound(struct drm_i915_gem_object *o,
5275 struct i915_address_space *vm)
5276{
5277 struct i915_vma *vma;
5278
5279 list_for_each_entry(vma, &o->vma_list, vma_link) {
5280 if (i915_is_ggtt(vma->vm) &&
5281 vma->ggtt_view.type != I915_GGTT_VIEW_NORMAL)
5282 continue;
5283 if (vma->vm == vm && drm_mm_node_allocated(&vma->node))
5284 return true;
5285 }
5286
5287 return false;
5288}
5289
5290bool i915_gem_obj_ggtt_bound_view(struct drm_i915_gem_object *o,
5291 enum i915_ggtt_view_type view)
5292{
5293 struct i915_address_space *ggtt = i915_obj_to_ggtt(o);
5294 struct i915_vma *vma;
5295
5296 list_for_each_entry(vma, &o->vma_list, vma_link)
5297 if (vma->vm == ggtt &&
5206 vma->ggtt_view.type == view && 5298 vma->ggtt_view.type == view &&
5207 drm_mm_node_allocated(&vma->node)) 5299 drm_mm_node_allocated(&vma->node))
5208 return true; 5300 return true;
@@ -5231,10 +5323,13 @@ unsigned long i915_gem_obj_size(struct drm_i915_gem_object *o,
5231 5323
5232 BUG_ON(list_empty(&o->vma_list)); 5324 BUG_ON(list_empty(&o->vma_list));
5233 5325
5234 list_for_each_entry(vma, &o->vma_list, vma_link) 5326 list_for_each_entry(vma, &o->vma_list, vma_link) {
5327 if (i915_is_ggtt(vma->vm) &&
5328 vma->ggtt_view.type != I915_GGTT_VIEW_NORMAL)
5329 continue;
5235 if (vma->vm == vm) 5330 if (vma->vm == vm)
5236 return vma->node.size; 5331 return vma->node.size;
5237 5332 }
5238 return 0; 5333 return 0;
5239} 5334}
5240 5335
@@ -5334,15 +5429,16 @@ i915_gem_shrinker_oom(struct notifier_block *nb, unsigned long event, void *ptr)
5334 return NOTIFY_DONE; 5429 return NOTIFY_DONE;
5335} 5430}
5336 5431
5337struct i915_vma *i915_gem_obj_to_ggtt(struct drm_i915_gem_object *obj) 5432bool i915_gem_obj_is_pinned(struct drm_i915_gem_object *obj)
5338{ 5433{
5339 struct i915_address_space *ggtt = i915_obj_to_ggtt(obj);
5340 struct i915_vma *vma; 5434 struct i915_vma *vma;
5341 5435 list_for_each_entry(vma, &obj->vma_list, vma_link) {
5342 list_for_each_entry(vma, &obj->vma_list, vma_link) 5436 if (i915_is_ggtt(vma->vm) &&
5343 if (vma->vm == ggtt && 5437 vma->ggtt_view.type != I915_GGTT_VIEW_NORMAL)
5344 vma->ggtt_view.type == I915_GGTT_VIEW_NORMAL) 5438 continue;
5345 return vma; 5439 if (vma->pin_count > 0)
5346 5440 return true;
5347 return NULL; 5441 }
5442 return false;
5348} 5443}
5444
diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c
index 2034f7cf238b..f1b9ea61de4b 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -67,8 +67,9 @@
67 * i915_ggtt_view_type and struct i915_ggtt_view. 67 * i915_ggtt_view_type and struct i915_ggtt_view.
68 * 68 *
69 * A new flavour of core GEM functions which work with GGTT bound objects were 69 * A new flavour of core GEM functions which work with GGTT bound objects were
70 * added with the _view suffix. They take the struct i915_ggtt_view parameter 70 * added with the _ggtt_ infix, and sometimes with _view postfix to avoid
71 * encapsulating all metadata required to implement a view. 71 * renaming in large amounts of code. They take the struct i915_ggtt_view
72 * parameter encapsulating all metadata required to implement a view.
72 * 73 *
73 * As a helper for callers which are only interested in the normal view, 74 * As a helper for callers which are only interested in the normal view,
74 * globally const i915_ggtt_view_normal singleton instance exists. All old core 75 * globally const i915_ggtt_view_normal singleton instance exists. All old core
@@ -1726,11 +1727,15 @@ static void ggtt_bind_vma(struct i915_vma *vma,
1726 struct drm_device *dev = vma->vm->dev; 1727 struct drm_device *dev = vma->vm->dev;
1727 struct drm_i915_private *dev_priv = dev->dev_private; 1728 struct drm_i915_private *dev_priv = dev->dev_private;
1728 struct drm_i915_gem_object *obj = vma->obj; 1729 struct drm_i915_gem_object *obj = vma->obj;
1730 struct sg_table *pages = obj->pages;
1729 1731
1730 /* Currently applicable only to VLV */ 1732 /* Currently applicable only to VLV */
1731 if (obj->gt_ro) 1733 if (obj->gt_ro)
1732 flags |= PTE_READ_ONLY; 1734 flags |= PTE_READ_ONLY;
1733 1735
1736 if (i915_is_ggtt(vma->vm))
1737 pages = vma->ggtt_view.pages;
1738
1734 /* If there is no aliasing PPGTT, or the caller needs a global mapping, 1739 /* If there is no aliasing PPGTT, or the caller needs a global mapping,
1735 * or we have a global mapping already but the cacheability flags have 1740 * or we have a global mapping already but the cacheability flags have
1736 * changed, set the global PTEs. 1741 * changed, set the global PTEs.
@@ -1745,7 +1750,7 @@ static void ggtt_bind_vma(struct i915_vma *vma,
1745 if (!dev_priv->mm.aliasing_ppgtt || flags & GLOBAL_BIND) { 1750 if (!dev_priv->mm.aliasing_ppgtt || flags & GLOBAL_BIND) {
1746 if (!(vma->bound & GLOBAL_BIND) || 1751 if (!(vma->bound & GLOBAL_BIND) ||
1747 (cache_level != obj->cache_level)) { 1752 (cache_level != obj->cache_level)) {
1748 vma->vm->insert_entries(vma->vm, vma->ggtt_view.pages, 1753 vma->vm->insert_entries(vma->vm, pages,
1749 vma->node.start, 1754 vma->node.start,
1750 cache_level, flags); 1755 cache_level, flags);
1751 vma->bound |= GLOBAL_BIND; 1756 vma->bound |= GLOBAL_BIND;
@@ -1756,8 +1761,7 @@ static void ggtt_bind_vma(struct i915_vma *vma,
1756 (!(vma->bound & LOCAL_BIND) || 1761 (!(vma->bound & LOCAL_BIND) ||
1757 (cache_level != obj->cache_level))) { 1762 (cache_level != obj->cache_level))) {
1758 struct i915_hw_ppgtt *appgtt = dev_priv->mm.aliasing_ppgtt; 1763 struct i915_hw_ppgtt *appgtt = dev_priv->mm.aliasing_ppgtt;
1759 appgtt->base.insert_entries(&appgtt->base, 1764 appgtt->base.insert_entries(&appgtt->base, pages,
1760 vma->ggtt_view.pages,
1761 vma->node.start, 1765 vma->node.start,
1762 cache_level, flags); 1766 cache_level, flags);
1763 vma->bound |= LOCAL_BIND; 1767 vma->bound |= LOCAL_BIND;
@@ -2331,23 +2335,28 @@ int i915_gem_gtt_init(struct drm_device *dev)
2331 return 0; 2335 return 0;
2332} 2336}
2333 2337
2334static struct i915_vma *__i915_gem_vma_create(struct drm_i915_gem_object *obj, 2338static struct i915_vma *
2335 struct i915_address_space *vm, 2339__i915_gem_vma_create(struct drm_i915_gem_object *obj,
2336 const struct i915_ggtt_view *view) 2340 struct i915_address_space *vm,
2341 const struct i915_ggtt_view *ggtt_view)
2337{ 2342{
2338 struct i915_vma *vma = kzalloc(sizeof(*vma), GFP_KERNEL); 2343 struct i915_vma *vma = kzalloc(sizeof(*vma), GFP_KERNEL);
2339 if (vma == NULL) 2344 if (vma == NULL)
2340 return ERR_PTR(-ENOMEM); 2345 return ERR_PTR(-ENOMEM);
2341 2346
2347 if (WARN_ON(i915_is_ggtt(vm) != !!ggtt_view))
2348 return ERR_PTR(-EINVAL);
2349
2342 INIT_LIST_HEAD(&vma->vma_link); 2350 INIT_LIST_HEAD(&vma->vma_link);
2343 INIT_LIST_HEAD(&vma->mm_list); 2351 INIT_LIST_HEAD(&vma->mm_list);
2344 INIT_LIST_HEAD(&vma->exec_list); 2352 INIT_LIST_HEAD(&vma->exec_list);
2345 vma->vm = vm; 2353 vma->vm = vm;
2346 vma->obj = obj; 2354 vma->obj = obj;
2347 vma->ggtt_view = *view;
2348 2355
2349 if (INTEL_INFO(vm->dev)->gen >= 6) { 2356 if (INTEL_INFO(vm->dev)->gen >= 6) {
2350 if (i915_is_ggtt(vm)) { 2357 if (i915_is_ggtt(vm)) {
2358 vma->ggtt_view = *ggtt_view;
2359
2351 vma->unbind_vma = ggtt_unbind_vma; 2360 vma->unbind_vma = ggtt_unbind_vma;
2352 vma->bind_vma = ggtt_bind_vma; 2361 vma->bind_vma = ggtt_bind_vma;
2353 } else { 2362 } else {
@@ -2356,6 +2365,7 @@ static struct i915_vma *__i915_gem_vma_create(struct drm_i915_gem_object *obj,
2356 } 2365 }
2357 } else { 2366 } else {
2358 BUG_ON(!i915_is_ggtt(vm)); 2367 BUG_ON(!i915_is_ggtt(vm));
2368 vma->ggtt_view = *ggtt_view;
2359 vma->unbind_vma = i915_ggtt_unbind_vma; 2369 vma->unbind_vma = i915_ggtt_unbind_vma;
2360 vma->bind_vma = i915_ggtt_bind_vma; 2370 vma->bind_vma = i915_ggtt_bind_vma;
2361 } 2371 }
@@ -2368,21 +2378,44 @@ static struct i915_vma *__i915_gem_vma_create(struct drm_i915_gem_object *obj,
2368} 2378}
2369 2379
2370struct i915_vma * 2380struct i915_vma *
2371i915_gem_obj_lookup_or_create_vma_view(struct drm_i915_gem_object *obj, 2381i915_gem_obj_lookup_or_create_vma(struct drm_i915_gem_object *obj,
2372 struct i915_address_space *vm, 2382 struct i915_address_space *vm)
2383{
2384 struct i915_vma *vma;
2385
2386 vma = i915_gem_obj_to_vma(obj, vm);
2387 if (!vma)
2388 vma = __i915_gem_vma_create(obj, vm,
2389 i915_is_ggtt(vm) ? &i915_ggtt_view_normal : NULL);
2390
2391 return vma;
2392}
2393
2394struct i915_vma *
2395i915_gem_obj_lookup_or_create_ggtt_vma(struct drm_i915_gem_object *obj,
2373 const struct i915_ggtt_view *view) 2396 const struct i915_ggtt_view *view)
2374{ 2397{
2398 struct i915_address_space *ggtt = i915_obj_to_ggtt(obj);
2375 struct i915_vma *vma; 2399 struct i915_vma *vma;
2376 2400
2377 vma = i915_gem_obj_to_vma_view(obj, vm, view); 2401 if (WARN_ON(!view))
2402 return ERR_PTR(-EINVAL);
2403
2404 vma = i915_gem_obj_to_ggtt_view(obj, view);
2405
2406 if (IS_ERR(vma))
2407 return vma;
2408
2378 if (!vma) 2409 if (!vma)
2379 vma = __i915_gem_vma_create(obj, vm, view); 2410 vma = __i915_gem_vma_create(obj, ggtt, view);
2380 2411
2381 return vma; 2412 return vma;
2413
2382} 2414}
2383 2415
2416
2384static inline 2417static inline
2385int i915_get_vma_pages(struct i915_vma *vma) 2418int i915_get_ggtt_vma_pages(struct i915_vma *vma)
2386{ 2419{
2387 if (vma->ggtt_view.pages) 2420 if (vma->ggtt_view.pages)
2388 return 0; 2421 return 0;
@@ -2394,7 +2427,7 @@ int i915_get_vma_pages(struct i915_vma *vma)
2394 vma->ggtt_view.type); 2427 vma->ggtt_view.type);
2395 2428
2396 if (!vma->ggtt_view.pages) { 2429 if (!vma->ggtt_view.pages) {
2397 DRM_ERROR("Failed to get pages for VMA view type %u!\n", 2430 DRM_ERROR("Failed to get pages for GGTT view type %u!\n",
2398 vma->ggtt_view.type); 2431 vma->ggtt_view.type);
2399 return -EINVAL; 2432 return -EINVAL;
2400 } 2433 }
@@ -2415,10 +2448,12 @@ int i915_get_vma_pages(struct i915_vma *vma)
2415int i915_vma_bind(struct i915_vma *vma, enum i915_cache_level cache_level, 2448int i915_vma_bind(struct i915_vma *vma, enum i915_cache_level cache_level,
2416 u32 flags) 2449 u32 flags)
2417{ 2450{
2418 int ret = i915_get_vma_pages(vma); 2451 if (i915_is_ggtt(vma->vm)) {
2452 int ret = i915_get_ggtt_vma_pages(vma);
2419 2453
2420 if (ret) 2454 if (ret)
2421 return ret; 2455 return ret;
2456 }
2422 2457
2423 vma->bind_vma(vma, cache_level, flags); 2458 vma->bind_vma(vma, cache_level, flags);
2424 2459