LCOV - code coverage report
Current view: top level - drivers/gpu/drm/i915/gem - i915_gem_context.c (source / functions) Hit Total Coverage
Test: combined.info Lines: 5 966 0.5 %
Date: 2022-04-01 14:35:51 Functions: 1 65 1.5 %
Branches: 1 535 0.2 %

           Branch data     Line data    Source code
       1                 :            : /*
       2                 :            :  * SPDX-License-Identifier: MIT
       3                 :            :  *
       4                 :            :  * Copyright © 2011-2012 Intel Corporation
       5                 :            :  */
       6                 :            : 
       7                 :            : /*
       8                 :            :  * This file implements HW context support. On gen5+ a HW context consists of an
       9                 :            :  * opaque GPU object which is referenced at times of context saves and restores.
      10                 :            :  * With RC6 enabled, the context is also referenced as the GPU enters and exists
      11                 :            :  * from RC6 (GPU has it's own internal power context, except on gen5). Though
      12                 :            :  * something like a context does exist for the media ring, the code only
      13                 :            :  * supports contexts for the render ring.
      14                 :            :  *
      15                 :            :  * In software, there is a distinction between contexts created by the user,
      16                 :            :  * and the default HW context. The default HW context is used by GPU clients
      17                 :            :  * that do not request setup of their own hardware context. The default
      18                 :            :  * context's state is never restored to help prevent programming errors. This
      19                 :            :  * would happen if a client ran and piggy-backed off another clients GPU state.
      20                 :            :  * The default context only exists to give the GPU some offset to load as the
      21                 :            :  * current to invoke a save of the context we actually care about. In fact, the
      22                 :            :  * code could likely be constructed, albeit in a more complicated fashion, to
      23                 :            :  * never use the default context, though that limits the driver's ability to
      24                 :            :  * swap out, and/or destroy other contexts.
      25                 :            :  *
      26                 :            :  * All other contexts are created as a request by the GPU client. These contexts
      27                 :            :  * store GPU state, and thus allow GPU clients to not re-emit state (and
      28                 :            :  * potentially query certain state) at any time. The kernel driver makes
      29                 :            :  * certain that the appropriate commands are inserted.
      30                 :            :  *
      31                 :            :  * The context life cycle is semi-complicated in that context BOs may live
      32                 :            :  * longer than the context itself because of the way the hardware, and object
      33                 :            :  * tracking works. Below is a very crude representation of the state machine
      34                 :            :  * describing the context life.
      35                 :            :  *                                         refcount     pincount     active
      36                 :            :  * S0: initial state                          0            0           0
      37                 :            :  * S1: context created                        1            0           0
      38                 :            :  * S2: context is currently running           2            1           X
      39                 :            :  * S3: GPU referenced, but not current        2            0           1
      40                 :            :  * S4: context is current, but destroyed      1            1           0
      41                 :            :  * S5: like S3, but destroyed                 1            0           1
      42                 :            :  *
      43                 :            :  * The most common (but not all) transitions:
      44                 :            :  * S0->S1: client creates a context
      45                 :            :  * S1->S2: client submits execbuf with context
      46                 :            :  * S2->S3: other clients submits execbuf with context
      47                 :            :  * S3->S1: context object was retired
      48                 :            :  * S3->S2: clients submits another execbuf
      49                 :            :  * S2->S4: context destroy called with current context
      50                 :            :  * S3->S5->S0: destroy path
      51                 :            :  * S4->S5->S0: destroy path on current context
      52                 :            :  *
      53                 :            :  * There are two confusing terms used above:
      54                 :            :  *  The "current context" means the context which is currently running on the
      55                 :            :  *  GPU. The GPU has loaded its state already and has stored away the gtt
      56                 :            :  *  offset of the BO. The GPU is not actively referencing the data at this
      57                 :            :  *  offset, but it will on the next context switch. The only way to avoid this
      58                 :            :  *  is to do a GPU reset.
      59                 :            :  *
      60                 :            :  *  An "active context' is one which was previously the "current context" and is
      61                 :            :  *  on the active list waiting for the next context switch to occur. Until this
      62                 :            :  *  happens, the object must remain at the same gtt offset. It is therefore
      63                 :            :  *  possible to destroy a context, but it is still active.
      64                 :            :  *
      65                 :            :  */
      66                 :            : 
      67                 :            : #include <linux/log2.h>
      68                 :            : #include <linux/nospec.h>
      69                 :            : 
      70                 :            : #include <drm/i915_drm.h>
      71                 :            : 
      72                 :            : #include "gt/gen6_ppgtt.h"
      73                 :            : #include "gt/intel_context.h"
      74                 :            : #include "gt/intel_engine_heartbeat.h"
      75                 :            : #include "gt/intel_engine_pm.h"
      76                 :            : #include "gt/intel_engine_user.h"
      77                 :            : #include "gt/intel_lrc_reg.h"
      78                 :            : #include "gt/intel_ring.h"
      79                 :            : 
      80                 :            : #include "i915_gem_context.h"
      81                 :            : #include "i915_globals.h"
      82                 :            : #include "i915_trace.h"
      83                 :            : #include "i915_user_extensions.h"
      84                 :            : 
      85                 :            : #define ALL_L3_SLICES(dev) (1 << NUM_L3_SLICES(dev)) - 1
      86                 :            : 
      87                 :            : static struct i915_global_gem_context {
      88                 :            :         struct i915_global base;
      89                 :            :         struct kmem_cache *slab_luts;
      90                 :            : } global;
      91                 :            : 
      92                 :          0 : struct i915_lut_handle *i915_lut_handle_alloc(void)
      93                 :            : {
      94                 :          0 :         return kmem_cache_alloc(global.slab_luts, GFP_KERNEL);
      95                 :            : }
      96                 :            : 
      97                 :          0 : void i915_lut_handle_free(struct i915_lut_handle *lut)
      98                 :            : {
      99                 :          0 :         return kmem_cache_free(global.slab_luts, lut);
     100                 :            : }
     101                 :            : 
     102                 :          0 : static void lut_close(struct i915_gem_context *ctx)
     103                 :            : {
     104                 :          0 :         struct radix_tree_iter iter;
     105                 :          0 :         void __rcu **slot;
     106                 :            : 
     107                 :          0 :         lockdep_assert_held(&ctx->mutex);
     108                 :            : 
     109                 :          0 :         rcu_read_lock();
     110   [ #  #  #  # ]:          0 :         radix_tree_for_each_slot(slot, &ctx->handles_vma, &iter, 0) {
     111                 :          0 :                 struct i915_vma *vma = rcu_dereference_raw(*slot);
     112                 :          0 :                 struct drm_i915_gem_object *obj = vma->obj;
     113                 :          0 :                 struct i915_lut_handle *lut;
     114                 :            : 
     115         [ #  # ]:          0 :                 if (!kref_get_unless_zero(&obj->base.refcount))
     116                 :          0 :                         continue;
     117                 :            : 
     118                 :          0 :                 rcu_read_unlock();
     119                 :          0 :                 i915_gem_object_lock(obj);
     120         [ #  # ]:          0 :                 list_for_each_entry(lut, &obj->lut_list, obj_link) {
     121         [ #  # ]:          0 :                         if (lut->ctx != ctx)
     122                 :          0 :                                 continue;
     123                 :            : 
     124         [ #  # ]:          0 :                         if (lut->handle != iter.index)
     125                 :          0 :                                 continue;
     126                 :            : 
     127                 :          0 :                         list_del(&lut->obj_link);
     128                 :            :                         break;
     129                 :            :                 }
     130                 :          0 :                 i915_gem_object_unlock(obj);
     131                 :          0 :                 rcu_read_lock();
     132                 :            : 
     133         [ #  # ]:          0 :                 if (&lut->obj_link != &obj->lut_list) {
     134                 :          0 :                         i915_lut_handle_free(lut);
     135                 :          0 :                         radix_tree_iter_delete(&ctx->handles_vma, &iter, slot);
     136   [ #  #  #  # ]:          0 :                         if (atomic_dec_and_test(&vma->open_count) &&
     137                 :            :                             !i915_vma_is_ggtt(vma))
     138                 :          0 :                                 i915_vma_close(vma);
     139                 :          0 :                         i915_gem_object_put(obj);
     140                 :            :                 }
     141                 :            : 
     142                 :          0 :                 i915_gem_object_put(obj);
     143                 :            :         }
     144                 :          0 :         rcu_read_unlock();
     145                 :          0 : }
     146                 :            : 
     147                 :            : static struct intel_context *
     148                 :            : lookup_user_engine(struct i915_gem_context *ctx,
     149                 :            :                    unsigned long flags,
     150                 :            :                    const struct i915_engine_class_instance *ci)
     151                 :            : #define LOOKUP_USER_INDEX BIT(0)
     152                 :            : {
     153                 :            :         int idx;
     154                 :            : 
     155                 :            :         if (!!(flags & LOOKUP_USER_INDEX) != i915_gem_context_user_engines(ctx))
     156                 :            :                 return ERR_PTR(-EINVAL);
     157                 :            : 
     158                 :            :         if (!i915_gem_context_user_engines(ctx)) {
     159                 :            :                 struct intel_engine_cs *engine;
     160                 :            : 
     161                 :            :                 engine = intel_engine_lookup_user(ctx->i915,
     162                 :            :                                                   ci->engine_class,
     163                 :            :                                                   ci->engine_instance);
     164                 :            :                 if (!engine)
     165                 :            :                         return ERR_PTR(-EINVAL);
     166                 :            : 
     167                 :            :                 idx = engine->legacy_idx;
     168                 :            :         } else {
     169                 :            :                 idx = ci->engine_instance;
     170                 :            :         }
     171                 :            : 
     172                 :            :         return i915_gem_context_get_engine(ctx, idx);
     173                 :            : }
     174                 :            : 
     175                 :            : static struct i915_address_space *
     176                 :          0 : context_get_vm_rcu(struct i915_gem_context *ctx)
     177                 :            : {
     178                 :          0 :         GEM_BUG_ON(!rcu_access_pointer(ctx->vm));
     179                 :            : 
     180                 :          0 :         do {
     181                 :          0 :                 struct i915_address_space *vm;
     182                 :            : 
     183                 :            :                 /*
     184                 :            :                  * We do not allow downgrading from full-ppgtt [to a shared
     185                 :            :                  * global gtt], so ctx->vm cannot become NULL.
     186                 :            :                  */
     187                 :          0 :                 vm = rcu_dereference(ctx->vm);
     188         [ #  # ]:          0 :                 if (!kref_get_unless_zero(&vm->ref))
     189                 :          0 :                         continue;
     190                 :            : 
     191                 :            :                 /*
     192                 :            :                  * This ppgtt may have be reallocated between
     193                 :            :                  * the read and the kref, and reassigned to a third
     194                 :            :                  * context. In order to avoid inadvertent sharing
     195                 :            :                  * of this ppgtt with that third context (and not
     196                 :            :                  * src), we have to confirm that we have the same
     197                 :            :                  * ppgtt after passing through the strong memory
     198                 :            :                  * barrier implied by a successful
     199                 :            :                  * kref_get_unless_zero().
     200                 :            :                  *
     201                 :            :                  * Once we have acquired the current ppgtt of ctx,
     202                 :            :                  * we no longer care if it is released from ctx, as
     203                 :            :                  * it cannot be reallocated elsewhere.
     204                 :            :                  */
     205                 :            : 
     206         [ #  # ]:          0 :                 if (vm == rcu_access_pointer(ctx->vm))
     207                 :          0 :                         return rcu_pointer_handoff(vm);
     208                 :            : 
     209                 :          0 :                 i915_vm_put(vm);
     210                 :            :         } while (1);
     211                 :            : }
     212                 :            : 
     213                 :          0 : static void intel_context_set_gem(struct intel_context *ce,
     214                 :            :                                   struct i915_gem_context *ctx)
     215                 :            : {
     216                 :          0 :         GEM_BUG_ON(rcu_access_pointer(ce->gem_context));
     217                 :          0 :         RCU_INIT_POINTER(ce->gem_context, ctx);
     218                 :            : 
     219         [ #  # ]:          0 :         if (!test_bit(CONTEXT_ALLOC_BIT, &ce->flags))
     220                 :          0 :                 ce->ring = __intel_context_ring_size(SZ_16K);
     221                 :            : 
     222         [ #  # ]:          0 :         if (rcu_access_pointer(ctx->vm)) {
     223                 :          0 :                 struct i915_address_space *vm;
     224                 :            : 
     225                 :          0 :                 rcu_read_lock();
     226                 :          0 :                 vm = context_get_vm_rcu(ctx); /* hmm */
     227                 :          0 :                 rcu_read_unlock();
     228                 :            : 
     229                 :          0 :                 i915_vm_put(ce->vm);
     230                 :          0 :                 ce->vm = vm;
     231                 :            :         }
     232                 :            : 
     233                 :          0 :         GEM_BUG_ON(ce->timeline);
     234         [ #  # ]:          0 :         if (ctx->timeline)
     235                 :          0 :                 ce->timeline = intel_timeline_get(ctx->timeline);
     236                 :            : 
     237   [ #  #  #  # ]:          0 :         if (ctx->sched.priority >= I915_PRIORITY_NORMAL &&
     238         [ #  # ]:          0 :             intel_engine_has_semaphores(ce->engine))
     239                 :          0 :                 __set_bit(CONTEXT_USE_SEMAPHORES, &ce->flags);
     240                 :          0 : }
     241                 :            : 
     242                 :          0 : static void __free_engines(struct i915_gem_engines *e, unsigned int count)
     243                 :            : {
     244         [ #  # ]:          0 :         while (count--) {
     245         [ #  # ]:          0 :                 if (!e->engines[count])
     246                 :          0 :                         continue;
     247                 :            : 
     248                 :          0 :                 RCU_INIT_POINTER(e->engines[count]->gem_context, NULL);
     249                 :          0 :                 intel_context_put(e->engines[count]);
     250                 :            :         }
     251                 :          0 :         kfree(e);
     252                 :          0 : }
     253                 :            : 
     254                 :          0 : static void free_engines(struct i915_gem_engines *e)
     255                 :            : {
     256                 :          0 :         __free_engines(e, e->num_engines);
     257                 :            : }
     258                 :            : 
     259                 :          0 : static void free_engines_rcu(struct rcu_head *rcu)
     260                 :            : {
     261                 :          0 :         free_engines(container_of(rcu, struct i915_gem_engines, rcu));
     262                 :          0 : }
     263                 :            : 
     264                 :          0 : static struct i915_gem_engines *default_engines(struct i915_gem_context *ctx)
     265                 :            : {
     266                 :          0 :         const struct intel_gt *gt = &ctx->i915->gt;
     267                 :          0 :         struct intel_engine_cs *engine;
     268                 :          0 :         struct i915_gem_engines *e;
     269                 :          0 :         enum intel_engine_id id;
     270                 :            : 
     271                 :          0 :         e = kzalloc(struct_size(e, engines, I915_NUM_ENGINES), GFP_KERNEL);
     272         [ #  # ]:          0 :         if (!e)
     273                 :            :                 return ERR_PTR(-ENOMEM);
     274                 :            : 
     275                 :            :         init_rcu_head(&e->rcu);
     276   [ #  #  #  # ]:          0 :         for_each_engine(engine, gt, id) {
     277                 :          0 :                 struct intel_context *ce;
     278                 :            : 
     279         [ #  # ]:          0 :                 if (engine->legacy_idx == INVALID_ENGINE)
     280                 :          0 :                         continue;
     281                 :            : 
     282                 :          0 :                 GEM_BUG_ON(engine->legacy_idx >= I915_NUM_ENGINES);
     283                 :          0 :                 GEM_BUG_ON(e->engines[engine->legacy_idx]);
     284                 :            : 
     285                 :          0 :                 ce = intel_context_create(engine);
     286         [ #  # ]:          0 :                 if (IS_ERR(ce)) {
     287                 :          0 :                         __free_engines(e, e->num_engines + 1);
     288                 :          0 :                         return ERR_CAST(ce);
     289                 :            :                 }
     290                 :            : 
     291                 :          0 :                 intel_context_set_gem(ce, ctx);
     292                 :            : 
     293                 :          0 :                 e->engines[engine->legacy_idx] = ce;
     294                 :          0 :                 e->num_engines = max(e->num_engines, engine->legacy_idx);
     295                 :            :         }
     296                 :          0 :         e->num_engines++;
     297                 :            : 
     298                 :          0 :         return e;
     299                 :            : }
     300                 :            : 
     301                 :          0 : static void i915_gem_context_free(struct i915_gem_context *ctx)
     302                 :            : {
     303                 :          0 :         GEM_BUG_ON(!i915_gem_context_is_closed(ctx));
     304                 :            : 
     305                 :          0 :         spin_lock(&ctx->i915->gem.contexts.lock);
     306                 :          0 :         list_del(&ctx->link);
     307                 :          0 :         spin_unlock(&ctx->i915->gem.contexts.lock);
     308                 :            : 
     309                 :          0 :         free_engines(rcu_access_pointer(ctx->engines));
     310         [ #  # ]:          0 :         mutex_destroy(&ctx->engines_mutex);
     311                 :            : 
     312         [ #  # ]:          0 :         if (ctx->timeline)
     313                 :          0 :                 intel_timeline_put(ctx->timeline);
     314                 :            : 
     315                 :          0 :         put_pid(ctx->pid);
     316         [ #  # ]:          0 :         mutex_destroy(&ctx->mutex);
     317                 :            : 
     318         [ #  # ]:          0 :         kfree_rcu(ctx, rcu);
     319                 :          0 : }
     320                 :            : 
     321                 :          0 : static void contexts_free_all(struct llist_node *list)
     322                 :            : {
     323                 :          0 :         struct i915_gem_context *ctx, *cn;
     324                 :            : 
     325         [ #  # ]:          0 :         llist_for_each_entry_safe(ctx, cn, list, free_link)
     326                 :          0 :                 i915_gem_context_free(ctx);
     327                 :            : }
     328                 :            : 
     329                 :          0 : static void contexts_flush_free(struct i915_gem_contexts *gc)
     330                 :            : {
     331                 :          0 :         contexts_free_all(llist_del_all(&gc->free_list));
     332                 :          0 : }
     333                 :            : 
     334                 :          0 : static void contexts_free_worker(struct work_struct *work)
     335                 :            : {
     336                 :          0 :         struct i915_gem_contexts *gc =
     337                 :          0 :                 container_of(work, typeof(*gc), free_work);
     338                 :            : 
     339                 :          0 :         contexts_flush_free(gc);
     340                 :          0 : }
     341                 :            : 
     342                 :          0 : void i915_gem_context_release(struct kref *ref)
     343                 :            : {
     344                 :          0 :         struct i915_gem_context *ctx = container_of(ref, typeof(*ctx), ref);
     345                 :          0 :         struct i915_gem_contexts *gc = &ctx->i915->gem.contexts;
     346                 :            : 
     347                 :          0 :         trace_i915_context_free(ctx);
     348         [ #  # ]:          0 :         if (llist_add(&ctx->free_link, &gc->free_list))
     349                 :          0 :                 schedule_work(&gc->free_work);
     350                 :          0 : }
     351                 :            : 
     352                 :            : static inline struct i915_gem_engines *
     353                 :          0 : __context_engines_static(const struct i915_gem_context *ctx)
     354                 :            : {
     355                 :          0 :         return rcu_dereference_protected(ctx->engines, true);
     356                 :            : }
     357                 :            : 
     358                 :          0 : static bool __reset_engine(struct intel_engine_cs *engine)
     359                 :            : {
     360                 :          0 :         struct intel_gt *gt = engine->gt;
     361                 :          0 :         bool success = false;
     362                 :            : 
     363         [ #  # ]:          0 :         if (!intel_has_reset_engine(gt))
     364                 :            :                 return false;
     365                 :            : 
     366         [ #  # ]:          0 :         if (!test_and_set_bit(I915_RESET_ENGINE + engine->id,
     367                 :          0 :                               &gt->reset.flags)) {
     368                 :          0 :                 success = intel_engine_reset(engine, NULL) == 0;
     369                 :          0 :                 clear_and_wake_up_bit(I915_RESET_ENGINE + engine->id,
     370                 :            :                                       &gt->reset.flags);
     371                 :            :         }
     372                 :            : 
     373                 :            :         return success;
     374                 :            : }
     375                 :            : 
     376                 :          0 : static void __reset_context(struct i915_gem_context *ctx,
     377                 :            :                             struct intel_engine_cs *engine)
     378                 :            : {
     379                 :          0 :         intel_gt_handle_error(engine->gt, engine->mask, 0,
     380                 :          0 :                               "context closure in %s", ctx->name);
     381                 :          0 : }
     382                 :            : 
     383                 :          0 : static bool __cancel_engine(struct intel_engine_cs *engine)
     384                 :            : {
     385                 :            :         /*
     386                 :            :          * Send a "high priority pulse" down the engine to cause the
     387                 :            :          * current request to be momentarily preempted. (If it fails to
     388                 :            :          * be preempted, it will be reset). As we have marked our context
     389                 :            :          * as banned, any incomplete request, including any running, will
     390                 :            :          * be skipped following the preemption.
     391                 :            :          *
     392                 :            :          * If there is no hangchecking (one of the reasons why we try to
     393                 :            :          * cancel the context) and no forced preemption, there may be no
     394                 :            :          * means by which we reset the GPU and evict the persistent hog.
     395                 :            :          * Ergo if we are unable to inject a preemptive pulse that can
     396                 :            :          * kill the banned context, we fallback to doing a local reset
     397                 :            :          * instead.
     398                 :            :          */
     399         [ #  # ]:          0 :         if (IS_ACTIVE(CONFIG_DRM_I915_PREEMPT_TIMEOUT) &&
     400                 :          0 :             !intel_engine_pulse(engine))
     401                 :            :                 return true;
     402                 :            : 
     403                 :            :         /* If we are unable to send a pulse, try resetting this engine. */
     404                 :          0 :         return __reset_engine(engine);
     405                 :            : }
     406                 :            : 
     407                 :          0 : static struct intel_engine_cs *__active_engine(struct i915_request *rq)
     408                 :            : {
     409                 :          0 :         struct intel_engine_cs *engine, *locked;
     410                 :            : 
     411                 :            :         /*
     412                 :            :          * Serialise with __i915_request_submit() so that it sees
     413                 :            :          * is-banned?, or we know the request is already inflight.
     414                 :            :          */
     415                 :          0 :         locked = READ_ONCE(rq->engine);
     416                 :          0 :         spin_lock_irq(&locked->active.lock);
     417         [ #  # ]:          0 :         while (unlikely(locked != (engine = READ_ONCE(rq->engine)))) {
     418                 :          0 :                 spin_unlock(&locked->active.lock);
     419                 :          0 :                 spin_lock(&engine->active.lock);
     420                 :          0 :                 locked = engine;
     421                 :            :         }
     422                 :            : 
     423                 :          0 :         engine = NULL;
     424   [ #  #  #  # ]:          0 :         if (i915_request_is_active(rq) && !rq->fence.error)
     425                 :          0 :                 engine = rq->engine;
     426                 :            : 
     427                 :          0 :         spin_unlock_irq(&locked->active.lock);
     428                 :            : 
     429                 :          0 :         return engine;
     430                 :            : }
     431                 :            : 
     432                 :            : static struct intel_engine_cs *active_engine(struct intel_context *ce)
     433                 :            : {
     434                 :            :         struct intel_engine_cs *engine = NULL;
     435                 :            :         struct i915_request *rq;
     436                 :            : 
     437                 :            :         if (!ce->timeline)
     438                 :            :                 return NULL;
     439                 :            : 
     440                 :            :         mutex_lock(&ce->timeline->mutex);
     441                 :            :         list_for_each_entry_reverse(rq, &ce->timeline->requests, link) {
     442                 :            :                 if (i915_request_completed(rq))
     443                 :            :                         break;
     444                 :            : 
     445                 :            :                 /* Check with the backend if the request is inflight */
     446                 :            :                 engine = __active_engine(rq);
     447                 :            :                 if (engine)
     448                 :            :                         break;
     449                 :            :         }
     450                 :            :         mutex_unlock(&ce->timeline->mutex);
     451                 :            : 
     452                 :            :         return engine;
     453                 :            : }
     454                 :            : 
     455                 :          0 : static void kill_context(struct i915_gem_context *ctx)
     456                 :            : {
     457                 :          0 :         struct i915_gem_engines_iter it;
     458                 :          0 :         struct intel_context *ce;
     459                 :            : 
     460                 :            :         /*
     461                 :            :          * Map the user's engine back to the actual engines; one virtual
     462                 :            :          * engine will be mapped to multiple engines, and using ctx->engine[]
     463                 :            :          * the same engine may be have multiple instances in the user's map.
     464                 :            :          * However, we only care about pending requests, so only include
     465                 :            :          * engines on which there are incomplete requests.
     466                 :            :          */
     467         [ #  # ]:          0 :         for_each_gem_engine(ce, __context_engines_static(ctx), it) {
     468                 :          0 :                 struct intel_engine_cs *engine;
     469                 :            : 
     470         [ #  # ]:          0 :                 if (intel_context_set_banned(ce))
     471                 :          0 :                         continue;
     472                 :            : 
     473                 :            :                 /*
     474                 :            :                  * Check the current active state of this context; if we
     475                 :            :                  * are currently executing on the GPU we need to evict
     476                 :            :                  * ourselves. On the other hand, if we haven't yet been
     477                 :            :                  * submitted to the GPU or if everything is complete,
     478                 :            :                  * we have nothing to do.
     479                 :            :                  */
     480                 :          0 :                 engine = active_engine(ce);
     481                 :            : 
     482                 :            :                 /* First attempt to gracefully cancel the context */
     483   [ #  #  #  # ]:          0 :                 if (engine && !__cancel_engine(engine))
     484                 :            :                         /*
     485                 :            :                          * If we are unable to send a preemptive pulse to bump
     486                 :            :                          * the context from the GPU, we have to resort to a full
     487                 :            :                          * reset. We hope the collateral damage is worth it.
     488                 :            :                          */
     489                 :          0 :                         __reset_context(ctx, engine);
     490                 :            :         }
     491                 :          0 : }
     492                 :            : 
     493                 :          0 : static void set_closed_name(struct i915_gem_context *ctx)
     494                 :            : {
     495                 :          0 :         char *s;
     496                 :            : 
     497                 :            :         /* Replace '[]' with '<>' to indicate closed in debug prints */
     498                 :            : 
     499                 :          0 :         s = strrchr(ctx->name, '[');
     500         [ #  # ]:          0 :         if (!s)
     501                 :            :                 return;
     502                 :            : 
     503                 :          0 :         *s = '<';
     504                 :            : 
     505                 :          0 :         s = strchr(s + 1, ']');
     506         [ #  # ]:          0 :         if (s)
     507                 :          0 :                 *s = '>';
     508                 :            : }
     509                 :            : 
     510                 :          0 : static void context_close(struct i915_gem_context *ctx)
     511                 :            : {
     512                 :          0 :         struct i915_address_space *vm;
     513                 :            : 
     514                 :          0 :         i915_gem_context_set_closed(ctx);
     515                 :          0 :         set_closed_name(ctx);
     516                 :            : 
     517                 :          0 :         mutex_lock(&ctx->mutex);
     518                 :            : 
     519         [ #  # ]:          0 :         vm = i915_gem_context_vm(ctx);
     520         [ #  # ]:          0 :         if (vm)
     521                 :          0 :                 i915_vm_close(vm);
     522                 :            : 
     523                 :          0 :         ctx->file_priv = ERR_PTR(-EBADF);
     524                 :            : 
     525                 :            :         /*
     526                 :            :          * The LUT uses the VMA as a backpointer to unref the object,
     527                 :            :          * so we need to clear the LUT before we close all the VMA (inside
     528                 :            :          * the ppgtt).
     529                 :            :          */
     530                 :          0 :         lut_close(ctx);
     531                 :            : 
     532                 :          0 :         mutex_unlock(&ctx->mutex);
     533                 :            : 
     534                 :            :         /*
     535                 :            :          * If the user has disabled hangchecking, we can not be sure that
     536                 :            :          * the batches will ever complete after the context is closed,
     537                 :            :          * keeping the context and all resources pinned forever. So in this
     538                 :            :          * case we opt to forcibly kill off all remaining requests on
     539                 :            :          * context close.
     540                 :            :          */
     541         [ #  # ]:          0 :         if (!i915_gem_context_is_persistent(ctx) ||
     542         [ #  # ]:          0 :             !i915_modparams.enable_hangcheck)
     543                 :          0 :                 kill_context(ctx);
     544                 :            : 
     545                 :          0 :         i915_gem_context_put(ctx);
     546                 :          0 : }
     547                 :            : 
     548                 :          0 : static int __context_set_persistence(struct i915_gem_context *ctx, bool state)
     549                 :            : {
     550         [ #  # ]:          0 :         if (i915_gem_context_is_persistent(ctx) == state)
     551                 :            :                 return 0;
     552                 :            : 
     553         [ #  # ]:          0 :         if (state) {
     554                 :            :                 /*
     555                 :            :                  * Only contexts that are short-lived [that will expire or be
     556                 :            :                  * reset] are allowed to survive past termination. We require
     557                 :            :                  * hangcheck to ensure that the persistent requests are healthy.
     558                 :            :                  */
     559         [ #  # ]:          0 :                 if (!i915_modparams.enable_hangcheck)
     560                 :            :                         return -EINVAL;
     561                 :            : 
     562                 :          0 :                 i915_gem_context_set_persistence(ctx);
     563                 :            :         } else {
     564                 :            :                 /* To cancel a context we use "preempt-to-idle" */
     565         [ #  # ]:          0 :                 if (!(ctx->i915->caps.scheduler & I915_SCHEDULER_CAP_PREEMPTION))
     566                 :            :                         return -ENODEV;
     567                 :            : 
     568                 :            :                 /*
     569                 :            :                  * If the cancel fails, we then need to reset, cleanly!
     570                 :            :                  *
     571                 :            :                  * If the per-engine reset fails, all hope is lost! We resort
     572                 :            :                  * to a full GPU reset in that unlikely case, but realistically
     573                 :            :                  * if the engine could not reset, the full reset does not fare
     574                 :            :                  * much better. The damage has been done.
     575                 :            :                  *
     576                 :            :                  * However, if we cannot reset an engine by itself, we cannot
     577                 :            :                  * cleanup a hanging persistent context without causing
     578                 :            :                  * colateral damage, and we should not pretend we can by
     579                 :            :                  * exposing the interface.
     580                 :            :                  */
     581         [ #  # ]:          0 :                 if (!intel_has_reset_engine(&ctx->i915->gt))
     582                 :            :                         return -ENODEV;
     583                 :            : 
     584                 :          0 :                 i915_gem_context_clear_persistence(ctx);
     585                 :            :         }
     586                 :            : 
     587                 :            :         return 0;
     588                 :            : }
     589                 :            : 
     590                 :            : static struct i915_gem_context *
     591                 :          0 : __create_context(struct drm_i915_private *i915)
     592                 :            : {
     593                 :          0 :         struct i915_gem_context *ctx;
     594                 :          0 :         struct i915_gem_engines *e;
     595                 :          0 :         int err;
     596                 :          0 :         int i;
     597                 :            : 
     598                 :          0 :         ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
     599         [ #  # ]:          0 :         if (!ctx)
     600                 :            :                 return ERR_PTR(-ENOMEM);
     601                 :            : 
     602                 :          0 :         kref_init(&ctx->ref);
     603                 :          0 :         ctx->i915 = i915;
     604                 :          0 :         ctx->sched.priority = I915_USER_PRIORITY(I915_PRIORITY_NORMAL);
     605                 :          0 :         mutex_init(&ctx->mutex);
     606                 :            : 
     607                 :          0 :         mutex_init(&ctx->engines_mutex);
     608                 :          0 :         e = default_engines(ctx);
     609         [ #  # ]:          0 :         if (IS_ERR(e)) {
     610                 :          0 :                 err = PTR_ERR(e);
     611                 :          0 :                 goto err_free;
     612                 :            :         }
     613         [ #  # ]:          0 :         RCU_INIT_POINTER(ctx->engines, e);
     614                 :            : 
     615         [ #  # ]:          0 :         INIT_RADIX_TREE(&ctx->handles_vma, GFP_KERNEL);
     616                 :            : 
     617                 :            :         /* NB: Mark all slices as needing a remap so that when the context first
     618                 :            :          * loads it will restore whatever remap state already exists. If there
     619                 :            :          * is no remap info, it will be a NOP. */
     620   [ #  #  #  # ]:          0 :         ctx->remap_slice = ALL_L3_SLICES(i915);
     621                 :            : 
     622                 :          0 :         i915_gem_context_set_bannable(ctx);
     623                 :          0 :         i915_gem_context_set_recoverable(ctx);
     624                 :          0 :         __context_set_persistence(ctx, true /* cgroup hook? */);
     625                 :            : 
     626         [ #  # ]:          0 :         for (i = 0; i < ARRAY_SIZE(ctx->hang_timestamp); i++)
     627                 :          0 :                 ctx->hang_timestamp[i] = jiffies - CONTEXT_FAST_HANG_JIFFIES;
     628                 :            : 
     629                 :          0 :         spin_lock(&i915->gem.contexts.lock);
     630                 :          0 :         list_add_tail(&ctx->link, &i915->gem.contexts.list);
     631                 :          0 :         spin_unlock(&i915->gem.contexts.lock);
     632                 :            : 
     633                 :          0 :         return ctx;
     634                 :            : 
     635                 :            : err_free:
     636                 :          0 :         kfree(ctx);
     637                 :          0 :         return ERR_PTR(err);
     638                 :            : }
     639                 :            : 
     640                 :            : static void
     641                 :          0 : context_apply_all(struct i915_gem_context *ctx,
     642                 :            :                   void (*fn)(struct intel_context *ce, void *data),
     643                 :            :                   void *data)
     644                 :            : {
     645                 :          0 :         struct i915_gem_engines_iter it;
     646                 :          0 :         struct intel_context *ce;
     647                 :            : 
     648         [ #  # ]:          0 :         for_each_gem_engine(ce, i915_gem_context_lock_engines(ctx), it)
     649                 :          0 :                 fn(ce, data);
     650                 :          0 :         i915_gem_context_unlock_engines(ctx);
     651                 :          0 : }
     652                 :            : 
     653                 :          0 : static void __apply_ppgtt(struct intel_context *ce, void *vm)
     654                 :            : {
     655                 :          0 :         i915_vm_put(ce->vm);
     656                 :          0 :         ce->vm = i915_vm_get(vm);
     657                 :          0 : }
     658                 :            : 
     659                 :            : static struct i915_address_space *
     660                 :          0 : __set_ppgtt(struct i915_gem_context *ctx, struct i915_address_space *vm)
     661                 :            : {
     662                 :          0 :         struct i915_address_space *old = i915_gem_context_vm(ctx);
     663                 :            : 
     664                 :          0 :         GEM_BUG_ON(old && i915_vm_is_4lvl(vm) != i915_vm_is_4lvl(old));
     665                 :            : 
     666                 :          0 :         rcu_assign_pointer(ctx->vm, i915_vm_open(vm));
     667                 :          0 :         context_apply_all(ctx, __apply_ppgtt, vm);
     668                 :            : 
     669                 :          0 :         return old;
     670                 :            : }
     671                 :            : 
     672                 :          0 : static void __assign_ppgtt(struct i915_gem_context *ctx,
     673                 :            :                            struct i915_address_space *vm)
     674                 :            : {
     675         [ #  # ]:          0 :         if (vm == rcu_access_pointer(ctx->vm))
     676                 :            :                 return;
     677                 :            : 
     678                 :          0 :         vm = __set_ppgtt(ctx, vm);
     679         [ #  # ]:          0 :         if (vm)
     680                 :          0 :                 i915_vm_close(vm);
     681                 :            : }
     682                 :            : 
     683                 :          0 : static void __set_timeline(struct intel_timeline **dst,
     684                 :            :                            struct intel_timeline *src)
     685                 :            : {
     686                 :          0 :         struct intel_timeline *old = *dst;
     687                 :            : 
     688         [ #  # ]:          0 :         *dst = src ? intel_timeline_get(src) : NULL;
     689                 :            : 
     690         [ #  # ]:          0 :         if (old)
     691                 :          0 :                 intel_timeline_put(old);
     692                 :          0 : }
     693                 :            : 
     694                 :          0 : static void __apply_timeline(struct intel_context *ce, void *timeline)
     695                 :            : {
     696                 :          0 :         __set_timeline(&ce->timeline, timeline);
     697                 :          0 : }
     698                 :            : 
     699                 :          0 : static void __assign_timeline(struct i915_gem_context *ctx,
     700                 :            :                               struct intel_timeline *timeline)
     701                 :            : {
     702                 :          0 :         __set_timeline(&ctx->timeline, timeline);
     703                 :          0 :         context_apply_all(ctx, __apply_timeline, timeline);
     704                 :          0 : }
     705                 :            : 
     706                 :            : static struct i915_gem_context *
     707                 :          0 : i915_gem_create_context(struct drm_i915_private *i915, unsigned int flags)
     708                 :            : {
     709                 :          0 :         struct i915_gem_context *ctx;
     710                 :            : 
     711         [ #  # ]:          0 :         if (flags & I915_CONTEXT_CREATE_FLAGS_SINGLE_TIMELINE &&
     712         [ #  # ]:          0 :             !HAS_EXECLISTS(i915))
     713                 :            :                 return ERR_PTR(-EINVAL);
     714                 :            : 
     715                 :            :         /* Reap the stale contexts */
     716                 :          0 :         contexts_flush_free(&i915->gem.contexts);
     717                 :            : 
     718                 :          0 :         ctx = __create_context(i915);
     719         [ #  # ]:          0 :         if (IS_ERR(ctx))
     720                 :            :                 return ctx;
     721                 :            : 
     722         [ #  # ]:          0 :         if (HAS_FULL_PPGTT(i915)) {
     723                 :          0 :                 struct i915_ppgtt *ppgtt;
     724                 :            : 
     725                 :          0 :                 ppgtt = i915_ppgtt_create(&i915->gt);
     726         [ #  # ]:          0 :                 if (IS_ERR(ppgtt)) {
     727                 :          0 :                         DRM_DEBUG_DRIVER("PPGTT setup failed (%ld)\n",
     728                 :            :                                          PTR_ERR(ppgtt));
     729                 :          0 :                         context_close(ctx);
     730                 :          0 :                         return ERR_CAST(ppgtt);
     731                 :            :                 }
     732                 :            : 
     733                 :          0 :                 mutex_lock(&ctx->mutex);
     734                 :          0 :                 __assign_ppgtt(ctx, &ppgtt->vm);
     735                 :          0 :                 mutex_unlock(&ctx->mutex);
     736                 :            : 
     737                 :          0 :                 i915_vm_put(&ppgtt->vm);
     738                 :            :         }
     739                 :            : 
     740         [ #  # ]:          0 :         if (flags & I915_CONTEXT_CREATE_FLAGS_SINGLE_TIMELINE) {
     741                 :          0 :                 struct intel_timeline *timeline;
     742                 :            : 
     743                 :          0 :                 timeline = intel_timeline_create(&i915->gt, NULL);
     744         [ #  # ]:          0 :                 if (IS_ERR(timeline)) {
     745                 :          0 :                         context_close(ctx);
     746                 :          0 :                         return ERR_CAST(timeline);
     747                 :            :                 }
     748                 :            : 
     749                 :          0 :                 __assign_timeline(ctx, timeline);
     750                 :          0 :                 intel_timeline_put(timeline);
     751                 :            :         }
     752                 :            : 
     753                 :          0 :         trace_i915_context_create(ctx);
     754                 :            : 
     755                 :          0 :         return ctx;
     756                 :            : }
     757                 :            : 
     758                 :          0 : static void init_contexts(struct i915_gem_contexts *gc)
     759                 :            : {
     760                 :          0 :         spin_lock_init(&gc->lock);
     761         [ #  # ]:          0 :         INIT_LIST_HEAD(&gc->list);
     762                 :            : 
     763         [ #  # ]:          0 :         INIT_WORK(&gc->free_work, contexts_free_worker);
     764         [ #  # ]:          0 :         init_llist_head(&gc->free_list);
     765                 :            : }
     766                 :            : 
     767                 :          0 : void i915_gem_init__contexts(struct drm_i915_private *i915)
     768                 :            : {
     769         [ #  # ]:          0 :         init_contexts(&i915->gem.contexts);
     770         [ #  # ]:          0 :         DRM_DEBUG_DRIVER("%s context support initialized\n",
     771                 :            :                          DRIVER_CAPS(i915)->has_logical_contexts ?
     772                 :            :                          "logical" : "fake");
     773                 :          0 : }
     774                 :            : 
     775                 :          0 : void i915_gem_driver_release__contexts(struct drm_i915_private *i915)
     776                 :            : {
     777                 :          0 :         flush_work(&i915->gem.contexts.free_work);
     778                 :          0 : }
     779                 :            : 
     780                 :          0 : static int vm_idr_cleanup(int id, void *p, void *data)
     781                 :            : {
     782                 :          0 :         i915_vm_put(p);
     783                 :          0 :         return 0;
     784                 :            : }
     785                 :            : 
     786                 :          0 : static int gem_context_register(struct i915_gem_context *ctx,
     787                 :            :                                 struct drm_i915_file_private *fpriv,
     788                 :            :                                 u32 *id)
     789                 :            : {
     790                 :          0 :         struct i915_address_space *vm;
     791                 :          0 :         int ret;
     792                 :            : 
     793                 :          0 :         ctx->file_priv = fpriv;
     794                 :            : 
     795                 :          0 :         mutex_lock(&ctx->mutex);
     796         [ #  # ]:          0 :         vm = i915_gem_context_vm(ctx);
     797         [ #  # ]:          0 :         if (vm)
     798                 :          0 :                 WRITE_ONCE(vm->file, fpriv); /* XXX */
     799                 :          0 :         mutex_unlock(&ctx->mutex);
     800                 :            : 
     801                 :          0 :         ctx->pid = get_task_pid(current, PIDTYPE_PID);
     802         [ #  # ]:          0 :         snprintf(ctx->name, sizeof(ctx->name), "%s[%d]",
     803                 :          0 :                  current->comm, pid_nr(ctx->pid));
     804                 :            : 
     805                 :            :         /* And finally expose ourselves to userspace via the idr */
     806                 :          0 :         ret = xa_alloc(&fpriv->context_xa, id, ctx, xa_limit_32b, GFP_KERNEL);
     807         [ #  # ]:          0 :         if (ret)
     808                 :          0 :                 put_pid(fetch_and_zero(&ctx->pid));
     809                 :            : 
     810                 :          0 :         return ret;
     811                 :            : }
     812                 :            : 
     813                 :          0 : int i915_gem_context_open(struct drm_i915_private *i915,
     814                 :            :                           struct drm_file *file)
     815                 :            : {
     816                 :          0 :         struct drm_i915_file_private *file_priv = file->driver_priv;
     817                 :          0 :         struct i915_gem_context *ctx;
     818                 :          0 :         int err;
     819                 :          0 :         u32 id;
     820                 :            : 
     821                 :          0 :         xa_init_flags(&file_priv->context_xa, XA_FLAGS_ALLOC);
     822                 :            : 
     823                 :          0 :         mutex_init(&file_priv->vm_idr_lock);
     824                 :          0 :         idr_init_base(&file_priv->vm_idr, 1);
     825                 :            : 
     826                 :          0 :         ctx = i915_gem_create_context(i915, 0);
     827         [ #  # ]:          0 :         if (IS_ERR(ctx)) {
     828                 :          0 :                 err = PTR_ERR(ctx);
     829                 :          0 :                 goto err;
     830                 :            :         }
     831                 :            : 
     832                 :          0 :         err = gem_context_register(ctx, file_priv, &id);
     833         [ #  # ]:          0 :         if (err < 0)
     834                 :          0 :                 goto err_ctx;
     835                 :            : 
     836                 :            :         GEM_BUG_ON(id);
     837                 :            :         return 0;
     838                 :            : 
     839                 :            : err_ctx:
     840                 :          0 :         context_close(ctx);
     841                 :          0 : err:
     842                 :          0 :         idr_destroy(&file_priv->vm_idr);
     843                 :          0 :         xa_destroy(&file_priv->context_xa);
     844                 :          0 :         mutex_destroy(&file_priv->vm_idr_lock);
     845                 :          0 :         return err;
     846                 :            : }
     847                 :            : 
     848                 :          0 : void i915_gem_context_close(struct drm_file *file)
     849                 :            : {
     850                 :          0 :         struct drm_i915_file_private *file_priv = file->driver_priv;
     851                 :          0 :         struct drm_i915_private *i915 = file_priv->dev_priv;
     852                 :          0 :         struct i915_gem_context *ctx;
     853                 :          0 :         unsigned long idx;
     854                 :            : 
     855         [ #  # ]:          0 :         xa_for_each(&file_priv->context_xa, idx, ctx)
     856                 :          0 :                 context_close(ctx);
     857                 :          0 :         xa_destroy(&file_priv->context_xa);
     858                 :            : 
     859                 :          0 :         idr_for_each(&file_priv->vm_idr, vm_idr_cleanup, NULL);
     860                 :          0 :         idr_destroy(&file_priv->vm_idr);
     861                 :          0 :         mutex_destroy(&file_priv->vm_idr_lock);
     862                 :            : 
     863                 :          0 :         contexts_flush_free(&i915->gem.contexts);
     864                 :          0 : }
     865                 :            : 
     866                 :          0 : int i915_gem_vm_create_ioctl(struct drm_device *dev, void *data,
     867                 :            :                              struct drm_file *file)
     868                 :            : {
     869         [ #  # ]:          0 :         struct drm_i915_private *i915 = to_i915(dev);
     870                 :          0 :         struct drm_i915_gem_vm_control *args = data;
     871                 :          0 :         struct drm_i915_file_private *file_priv = file->driver_priv;
     872                 :          0 :         struct i915_ppgtt *ppgtt;
     873                 :          0 :         int err;
     874                 :            : 
     875         [ #  # ]:          0 :         if (!HAS_FULL_PPGTT(i915))
     876                 :            :                 return -ENODEV;
     877                 :            : 
     878         [ #  # ]:          0 :         if (args->flags)
     879                 :            :                 return -EINVAL;
     880                 :            : 
     881                 :          0 :         ppgtt = i915_ppgtt_create(&i915->gt);
     882         [ #  # ]:          0 :         if (IS_ERR(ppgtt))
     883                 :          0 :                 return PTR_ERR(ppgtt);
     884                 :            : 
     885                 :          0 :         ppgtt->vm.file = file_priv;
     886                 :            : 
     887         [ #  # ]:          0 :         if (args->extensions) {
     888                 :          0 :                 err = i915_user_extensions(u64_to_user_ptr(args->extensions),
     889                 :            :                                            NULL, 0,
     890                 :            :                                            ppgtt);
     891         [ #  # ]:          0 :                 if (err)
     892                 :          0 :                         goto err_put;
     893                 :            :         }
     894                 :            : 
     895                 :          0 :         err = mutex_lock_interruptible(&file_priv->vm_idr_lock);
     896         [ #  # ]:          0 :         if (err)
     897                 :          0 :                 goto err_put;
     898                 :            : 
     899                 :          0 :         err = idr_alloc(&file_priv->vm_idr, &ppgtt->vm, 0, 0, GFP_KERNEL);
     900         [ #  # ]:          0 :         if (err < 0)
     901                 :          0 :                 goto err_unlock;
     902                 :            : 
     903                 :          0 :         GEM_BUG_ON(err == 0); /* reserved for invalid/unassigned ppgtt */
     904                 :            : 
     905                 :          0 :         mutex_unlock(&file_priv->vm_idr_lock);
     906                 :            : 
     907                 :          0 :         args->vm_id = err;
     908                 :          0 :         return 0;
     909                 :            : 
     910                 :            : err_unlock:
     911                 :          0 :         mutex_unlock(&file_priv->vm_idr_lock);
     912                 :          0 : err_put:
     913                 :          0 :         i915_vm_put(&ppgtt->vm);
     914                 :          0 :         return err;
     915                 :            : }
     916                 :            : 
     917                 :          0 : int i915_gem_vm_destroy_ioctl(struct drm_device *dev, void *data,
     918                 :            :                               struct drm_file *file)
     919                 :            : {
     920                 :          0 :         struct drm_i915_file_private *file_priv = file->driver_priv;
     921                 :          0 :         struct drm_i915_gem_vm_control *args = data;
     922                 :          0 :         struct i915_address_space *vm;
     923                 :          0 :         int err;
     924                 :          0 :         u32 id;
     925                 :            : 
     926         [ #  # ]:          0 :         if (args->flags)
     927                 :            :                 return -EINVAL;
     928                 :            : 
     929         [ #  # ]:          0 :         if (args->extensions)
     930                 :            :                 return -EINVAL;
     931                 :            : 
     932                 :          0 :         id = args->vm_id;
     933         [ #  # ]:          0 :         if (!id)
     934                 :            :                 return -ENOENT;
     935                 :            : 
     936                 :          0 :         err = mutex_lock_interruptible(&file_priv->vm_idr_lock);
     937         [ #  # ]:          0 :         if (err)
     938                 :            :                 return err;
     939                 :            : 
     940                 :          0 :         vm = idr_remove(&file_priv->vm_idr, id);
     941                 :            : 
     942                 :          0 :         mutex_unlock(&file_priv->vm_idr_lock);
     943         [ #  # ]:          0 :         if (!vm)
     944                 :            :                 return -ENOENT;
     945                 :            : 
     946                 :          0 :         i915_vm_put(vm);
     947                 :          0 :         return 0;
     948                 :            : }
     949                 :            : 
     950                 :            : struct context_barrier_task {
     951                 :            :         struct i915_active base;
     952                 :            :         void (*task)(void *data);
     953                 :            :         void *data;
     954                 :            : };
     955                 :            : 
     956                 :            : __i915_active_call
     957                 :          0 : static void cb_retire(struct i915_active *base)
     958                 :            : {
     959                 :          0 :         struct context_barrier_task *cb = container_of(base, typeof(*cb), base);
     960                 :            : 
     961         [ #  # ]:          0 :         if (cb->task)
     962                 :          0 :                 cb->task(cb->data);
     963                 :            : 
     964                 :          0 :         i915_active_fini(&cb->base);
     965                 :          0 :         kfree(cb);
     966                 :          0 : }
     967                 :            : 
     968                 :            : I915_SELFTEST_DECLARE(static intel_engine_mask_t context_barrier_inject_fault);
     969                 :          0 : static int context_barrier_task(struct i915_gem_context *ctx,
     970                 :            :                                 intel_engine_mask_t engines,
     971                 :            :                                 bool (*skip)(struct intel_context *ce, void *data),
     972                 :            :                                 int (*emit)(struct i915_request *rq, void *data),
     973                 :            :                                 void (*task)(void *data),
     974                 :            :                                 void *data)
     975                 :            : {
     976                 :          0 :         struct context_barrier_task *cb;
     977                 :          0 :         struct i915_gem_engines_iter it;
     978                 :          0 :         struct intel_context *ce;
     979                 :          0 :         int err = 0;
     980                 :            : 
     981                 :          0 :         GEM_BUG_ON(!task);
     982                 :            : 
     983                 :          0 :         cb = kmalloc(sizeof(*cb), GFP_KERNEL);
     984         [ #  # ]:          0 :         if (!cb)
     985                 :            :                 return -ENOMEM;
     986                 :            : 
     987                 :          0 :         i915_active_init(&cb->base, NULL, cb_retire);
     988                 :          0 :         err = i915_active_acquire(&cb->base);
     989         [ #  # ]:          0 :         if (err) {
     990                 :          0 :                 kfree(cb);
     991                 :          0 :                 return err;
     992                 :            :         }
     993                 :            : 
     994         [ #  # ]:          0 :         for_each_gem_engine(ce, i915_gem_context_lock_engines(ctx), it) {
     995                 :          0 :                 struct i915_request *rq;
     996                 :            : 
     997                 :          0 :                 if (I915_SELFTEST_ONLY(context_barrier_inject_fault &
     998                 :            :                                        ce->engine->mask)) {
     999                 :            :                         err = -ENXIO;
    1000                 :            :                         break;
    1001                 :            :                 }
    1002                 :            : 
    1003         [ #  # ]:          0 :                 if (!(ce->engine->mask & engines))
    1004                 :          0 :                         continue;
    1005                 :            : 
    1006   [ #  #  #  # ]:          0 :                 if (skip && skip(ce, data))
    1007                 :          0 :                         continue;
    1008                 :            : 
    1009                 :          0 :                 rq = intel_context_create_request(ce);
    1010         [ #  # ]:          0 :                 if (IS_ERR(rq)) {
    1011                 :          0 :                         err = PTR_ERR(rq);
    1012                 :          0 :                         break;
    1013                 :            :                 }
    1014                 :            : 
    1015                 :          0 :                 err = 0;
    1016         [ #  # ]:          0 :                 if (emit)
    1017                 :          0 :                         err = emit(rq, data);
    1018         [ #  # ]:          0 :                 if (err == 0)
    1019                 :          0 :                         err = i915_active_add_request(&cb->base, rq);
    1020                 :            : 
    1021                 :          0 :                 i915_request_add(rq);
    1022         [ #  # ]:          0 :                 if (err)
    1023                 :            :                         break;
    1024                 :            :         }
    1025                 :          0 :         i915_gem_context_unlock_engines(ctx);
    1026                 :            : 
    1027         [ #  # ]:          0 :         cb->task = err ? NULL : task; /* caller needs to unwind instead */
    1028                 :          0 :         cb->data = data;
    1029                 :            : 
    1030                 :          0 :         i915_active_release(&cb->base);
    1031                 :            : 
    1032                 :          0 :         return err;
    1033                 :            : }
    1034                 :            : 
    1035                 :            : static int get_ppgtt(struct drm_i915_file_private *file_priv,
    1036                 :            :                      struct i915_gem_context *ctx,
    1037                 :            :                      struct drm_i915_gem_context_param *args)
    1038                 :            : {
    1039                 :            :         struct i915_address_space *vm;
    1040                 :            :         int ret;
    1041                 :            : 
    1042                 :            :         if (!rcu_access_pointer(ctx->vm))
    1043                 :            :                 return -ENODEV;
    1044                 :            : 
    1045                 :            :         rcu_read_lock();
    1046                 :            :         vm = context_get_vm_rcu(ctx);
    1047                 :            :         rcu_read_unlock();
    1048                 :            : 
    1049                 :            :         ret = mutex_lock_interruptible(&file_priv->vm_idr_lock);
    1050                 :            :         if (ret)
    1051                 :            :                 goto err_put;
    1052                 :            : 
    1053                 :            :         ret = idr_alloc(&file_priv->vm_idr, vm, 0, 0, GFP_KERNEL);
    1054                 :            :         GEM_BUG_ON(!ret);
    1055                 :            :         if (ret < 0)
    1056                 :            :                 goto err_unlock;
    1057                 :            : 
    1058                 :            :         i915_vm_open(vm);
    1059                 :            : 
    1060                 :            :         args->size = 0;
    1061                 :            :         args->value = ret;
    1062                 :            : 
    1063                 :            :         ret = 0;
    1064                 :            : err_unlock:
    1065                 :            :         mutex_unlock(&file_priv->vm_idr_lock);
    1066                 :            : err_put:
    1067                 :            :         i915_vm_put(vm);
    1068                 :            :         return ret;
    1069                 :            : }
    1070                 :            : 
    1071                 :          0 : static void set_ppgtt_barrier(void *data)
    1072                 :            : {
    1073                 :          0 :         struct i915_address_space *old = data;
    1074                 :            : 
    1075         [ #  # ]:          0 :         if (INTEL_GEN(old->i915) < 8)
    1076                 :          0 :                 gen6_ppgtt_unpin_all(i915_vm_to_ppgtt(old));
    1077                 :            : 
    1078                 :          0 :         i915_vm_close(old);
    1079                 :          0 : }
    1080                 :            : 
    1081                 :          0 : static int emit_ppgtt_update(struct i915_request *rq, void *data)
    1082                 :            : {
    1083                 :          0 :         struct i915_address_space *vm = rq->context->vm;
    1084                 :          0 :         struct intel_engine_cs *engine = rq->engine;
    1085                 :          0 :         u32 base = engine->mmio_base;
    1086                 :          0 :         u32 *cs;
    1087                 :          0 :         int i;
    1088                 :            : 
    1089         [ #  # ]:          0 :         if (i915_vm_is_4lvl(vm)) {
    1090                 :          0 :                 struct i915_ppgtt *ppgtt = i915_vm_to_ppgtt(vm);
    1091                 :          0 :                 const dma_addr_t pd_daddr = px_dma(ppgtt->pd);
    1092                 :            : 
    1093                 :          0 :                 cs = intel_ring_begin(rq, 6);
    1094         [ #  # ]:          0 :                 if (IS_ERR(cs))
    1095                 :          0 :                         return PTR_ERR(cs);
    1096                 :            : 
    1097                 :          0 :                 *cs++ = MI_LOAD_REGISTER_IMM(2);
    1098                 :            : 
    1099                 :          0 :                 *cs++ = i915_mmio_reg_offset(GEN8_RING_PDP_UDW(base, 0));
    1100                 :          0 :                 *cs++ = upper_32_bits(pd_daddr);
    1101                 :          0 :                 *cs++ = i915_mmio_reg_offset(GEN8_RING_PDP_LDW(base, 0));
    1102                 :          0 :                 *cs++ = lower_32_bits(pd_daddr);
    1103                 :            : 
    1104                 :          0 :                 *cs++ = MI_NOOP;
    1105                 :          0 :                 intel_ring_advance(rq, cs);
    1106         [ #  # ]:          0 :         } else if (HAS_LOGICAL_RING_CONTEXTS(engine->i915)) {
    1107                 :          0 :                 struct i915_ppgtt *ppgtt = i915_vm_to_ppgtt(vm);
    1108                 :          0 :                 int err;
    1109                 :            : 
    1110                 :            :                 /* Magic required to prevent forcewake errors! */
    1111                 :          0 :                 err = engine->emit_flush(rq, EMIT_INVALIDATE);
    1112         [ #  # ]:          0 :                 if (err)
    1113                 :            :                         return err;
    1114                 :            : 
    1115                 :          0 :                 cs = intel_ring_begin(rq, 4 * GEN8_3LVL_PDPES + 2);
    1116         [ #  # ]:          0 :                 if (IS_ERR(cs))
    1117                 :          0 :                         return PTR_ERR(cs);
    1118                 :            : 
    1119                 :          0 :                 *cs++ = MI_LOAD_REGISTER_IMM(2 * GEN8_3LVL_PDPES) | MI_LRI_FORCE_POSTED;
    1120         [ #  # ]:          0 :                 for (i = GEN8_3LVL_PDPES; i--; ) {
    1121         [ #  # ]:          0 :                         const dma_addr_t pd_daddr = i915_page_dir_dma_addr(ppgtt, i);
    1122                 :            : 
    1123                 :          0 :                         *cs++ = i915_mmio_reg_offset(GEN8_RING_PDP_UDW(base, i));
    1124                 :          0 :                         *cs++ = upper_32_bits(pd_daddr);
    1125                 :          0 :                         *cs++ = i915_mmio_reg_offset(GEN8_RING_PDP_LDW(base, i));
    1126                 :          0 :                         *cs++ = lower_32_bits(pd_daddr);
    1127                 :            :                 }
    1128                 :          0 :                 *cs++ = MI_NOOP;
    1129                 :          0 :                 intel_ring_advance(rq, cs);
    1130                 :            :         }
    1131                 :            : 
    1132                 :            :         return 0;
    1133                 :            : }
    1134                 :            : 
    1135                 :          0 : static bool skip_ppgtt_update(struct intel_context *ce, void *data)
    1136                 :            : {
    1137         [ #  # ]:          0 :         if (!test_bit(CONTEXT_ALLOC_BIT, &ce->flags))
    1138                 :            :                 return true;
    1139                 :            : 
    1140         [ #  # ]:          0 :         if (HAS_LOGICAL_RING_CONTEXTS(ce->engine->i915))
    1141                 :            :                 return false;
    1142                 :            : 
    1143         [ #  # ]:          0 :         if (!atomic_read(&ce->pin_count))
    1144                 :            :                 return true;
    1145                 :            : 
    1146                 :            :         /* ppGTT is not part of the legacy context image */
    1147         [ #  # ]:          0 :         if (gen6_ppgtt_pin(i915_vm_to_ppgtt(ce->vm)))
    1148                 :          0 :                 return true;
    1149                 :            : 
    1150                 :            :         return false;
    1151                 :            : }
    1152                 :            : 
    1153                 :            : static int set_ppgtt(struct drm_i915_file_private *file_priv,
    1154                 :            :                      struct i915_gem_context *ctx,
    1155                 :            :                      struct drm_i915_gem_context_param *args)
    1156                 :            : {
    1157                 :            :         struct i915_address_space *vm, *old;
    1158                 :            :         int err;
    1159                 :            : 
    1160                 :            :         if (args->size)
    1161                 :            :                 return -EINVAL;
    1162                 :            : 
    1163                 :            :         if (!rcu_access_pointer(ctx->vm))
    1164                 :            :                 return -ENODEV;
    1165                 :            : 
    1166                 :            :         if (upper_32_bits(args->value))
    1167                 :            :                 return -ENOENT;
    1168                 :            : 
    1169                 :            :         rcu_read_lock();
    1170                 :            :         vm = idr_find(&file_priv->vm_idr, args->value);
    1171                 :            :         if (vm && !kref_get_unless_zero(&vm->ref))
    1172                 :            :                 vm = NULL;
    1173                 :            :         rcu_read_unlock();
    1174                 :            :         if (!vm)
    1175                 :            :                 return -ENOENT;
    1176                 :            : 
    1177                 :            :         err = mutex_lock_interruptible(&ctx->mutex);
    1178                 :            :         if (err)
    1179                 :            :                 goto out;
    1180                 :            : 
    1181                 :            :         if (i915_gem_context_is_closed(ctx)) {
    1182                 :            :                 err = -ENOENT;
    1183                 :            :                 goto unlock;
    1184                 :            :         }
    1185                 :            : 
    1186                 :            :         if (vm == rcu_access_pointer(ctx->vm))
    1187                 :            :                 goto unlock;
    1188                 :            : 
    1189                 :            :         /* Teardown the existing obj:vma cache, it will have to be rebuilt. */
    1190                 :            :         lut_close(ctx);
    1191                 :            : 
    1192                 :            :         old = __set_ppgtt(ctx, vm);
    1193                 :            : 
    1194                 :            :         /*
    1195                 :            :          * We need to flush any requests using the current ppgtt before
    1196                 :            :          * we release it as the requests do not hold a reference themselves,
    1197                 :            :          * only indirectly through the context.
    1198                 :            :          */
    1199                 :            :         err = context_barrier_task(ctx, ALL_ENGINES,
    1200                 :            :                                    skip_ppgtt_update,
    1201                 :            :                                    emit_ppgtt_update,
    1202                 :            :                                    set_ppgtt_barrier,
    1203                 :            :                                    old);
    1204                 :            :         if (err) {
    1205                 :            :                 i915_vm_close(__set_ppgtt(ctx, old));
    1206                 :            :                 i915_vm_close(old);
    1207                 :            :         }
    1208                 :            : 
    1209                 :            : unlock:
    1210                 :            :         mutex_unlock(&ctx->mutex);
    1211                 :            : out:
    1212                 :            :         i915_vm_put(vm);
    1213                 :            :         return err;
    1214                 :            : }
    1215                 :            : 
    1216                 :            : static int gen8_emit_rpcs_config(struct i915_request *rq,
    1217                 :            :                                  struct intel_context *ce,
    1218                 :            :                                  struct intel_sseu sseu)
    1219                 :            : {
    1220                 :            :         u64 offset;
    1221                 :            :         u32 *cs;
    1222                 :            : 
    1223                 :            :         cs = intel_ring_begin(rq, 4);
    1224                 :            :         if (IS_ERR(cs))
    1225                 :            :                 return PTR_ERR(cs);
    1226                 :            : 
    1227                 :            :         offset = i915_ggtt_offset(ce->state) +
    1228                 :            :                  LRC_STATE_PN * PAGE_SIZE +
    1229                 :            :                  CTX_R_PWR_CLK_STATE * 4;
    1230                 :            : 
    1231                 :            :         *cs++ = MI_STORE_DWORD_IMM_GEN4 | MI_USE_GGTT;
    1232                 :            :         *cs++ = lower_32_bits(offset);
    1233                 :            :         *cs++ = upper_32_bits(offset);
    1234                 :            :         *cs++ = intel_sseu_make_rpcs(rq->i915, &sseu);
    1235                 :            : 
    1236                 :            :         intel_ring_advance(rq, cs);
    1237                 :            : 
    1238                 :            :         return 0;
    1239                 :            : }
    1240                 :            : 
    1241                 :            : static int
    1242                 :          0 : gen8_modify_rpcs(struct intel_context *ce, struct intel_sseu sseu)
    1243                 :            : {
    1244                 :          0 :         struct i915_request *rq;
    1245                 :          0 :         int ret;
    1246                 :            : 
    1247                 :          0 :         lockdep_assert_held(&ce->pin_mutex);
    1248                 :            : 
    1249                 :            :         /*
    1250                 :            :          * If the context is not idle, we have to submit an ordered request to
    1251                 :            :          * modify its context image via the kernel context (writing to our own
    1252                 :            :          * image, or into the registers directory, does not stick). Pristine
    1253                 :            :          * and idle contexts will be configured on pinning.
    1254                 :            :          */
    1255         [ #  # ]:          0 :         if (!intel_context_pin_if_active(ce))
    1256                 :            :                 return 0;
    1257                 :            : 
    1258                 :          0 :         rq = intel_engine_create_kernel_request(ce->engine);
    1259         [ #  # ]:          0 :         if (IS_ERR(rq)) {
    1260                 :          0 :                 ret = PTR_ERR(rq);
    1261                 :          0 :                 goto out_unpin;
    1262                 :            :         }
    1263                 :            : 
    1264                 :            :         /* Serialise with the remote context */
    1265                 :          0 :         ret = intel_context_prepare_remote_request(ce, rq);
    1266         [ #  # ]:          0 :         if (ret == 0)
    1267                 :          0 :                 ret = gen8_emit_rpcs_config(rq, ce, sseu);
    1268                 :            : 
    1269                 :          0 :         i915_request_add(rq);
    1270                 :          0 : out_unpin:
    1271                 :          0 :         intel_context_unpin(ce);
    1272                 :          0 :         return ret;
    1273                 :            : }
    1274                 :            : 
    1275                 :            : static int
    1276                 :          0 : intel_context_reconfigure_sseu(struct intel_context *ce, struct intel_sseu sseu)
    1277                 :            : {
    1278                 :          0 :         int ret;
    1279                 :            : 
    1280                 :          0 :         GEM_BUG_ON(INTEL_GEN(ce->engine->i915) < 8);
    1281                 :            : 
    1282                 :          0 :         ret = intel_context_lock_pinned(ce);
    1283         [ #  # ]:          0 :         if (ret)
    1284                 :            :                 return ret;
    1285                 :            : 
    1286                 :            :         /* Nothing to do if unmodified. */
    1287         [ #  # ]:          0 :         if (!memcmp(&ce->sseu, &sseu, sizeof(sseu)))
    1288                 :          0 :                 goto unlock;
    1289                 :            : 
    1290                 :          0 :         ret = gen8_modify_rpcs(ce, sseu);
    1291         [ #  # ]:          0 :         if (!ret)
    1292                 :          0 :                 ce->sseu = sseu;
    1293                 :            : 
    1294                 :          0 : unlock:
    1295                 :          0 :         intel_context_unlock_pinned(ce);
    1296                 :          0 :         return ret;
    1297                 :            : }
    1298                 :            : 
    1299                 :            : static int
    1300                 :          0 : user_to_context_sseu(struct drm_i915_private *i915,
    1301                 :            :                      const struct drm_i915_gem_context_param_sseu *user,
    1302                 :            :                      struct intel_sseu *context)
    1303                 :            : {
    1304                 :          0 :         const struct sseu_dev_info *device = &RUNTIME_INFO(i915)->sseu;
    1305                 :            : 
    1306                 :            :         /* No zeros in any field. */
    1307   [ #  #  #  # ]:          0 :         if (!user->slice_mask || !user->subslice_mask ||
    1308   [ #  #  #  # ]:          0 :             !user->min_eus_per_subslice || !user->max_eus_per_subslice)
    1309                 :            :                 return -EINVAL;
    1310                 :            : 
    1311                 :            :         /* Max > min. */
    1312         [ #  # ]:          0 :         if (user->max_eus_per_subslice < user->min_eus_per_subslice)
    1313                 :            :                 return -EINVAL;
    1314                 :            : 
    1315                 :            :         /*
    1316                 :            :          * Some future proofing on the types since the uAPI is wider than the
    1317                 :            :          * current internal implementation.
    1318                 :            :          */
    1319         [ #  # ]:          0 :         if (overflows_type(user->slice_mask, context->slice_mask) ||
    1320         [ #  # ]:          0 :             overflows_type(user->subslice_mask, context->subslice_mask) ||
    1321         [ #  # ]:          0 :             overflows_type(user->min_eus_per_subslice,
    1322                 :          0 :                            context->min_eus_per_subslice) ||
    1323         [ #  # ]:          0 :             overflows_type(user->max_eus_per_subslice,
    1324                 :            :                            context->max_eus_per_subslice))
    1325                 :            :                 return -EINVAL;
    1326                 :            : 
    1327                 :            :         /* Check validity against hardware. */
    1328         [ #  # ]:          0 :         if (user->slice_mask & ~device->slice_mask)
    1329                 :            :                 return -EINVAL;
    1330                 :            : 
    1331         [ #  # ]:          0 :         if (user->subslice_mask & ~device->subslice_mask[0])
    1332                 :            :                 return -EINVAL;
    1333                 :            : 
    1334         [ #  # ]:          0 :         if (user->max_eus_per_subslice > device->max_eus_per_subslice)
    1335                 :            :                 return -EINVAL;
    1336                 :            : 
    1337                 :          0 :         context->slice_mask = user->slice_mask;
    1338                 :          0 :         context->subslice_mask = user->subslice_mask;
    1339                 :          0 :         context->min_eus_per_subslice = user->min_eus_per_subslice;
    1340                 :          0 :         context->max_eus_per_subslice = user->max_eus_per_subslice;
    1341                 :            : 
    1342                 :            :         /* Part specific restrictions. */
    1343         [ #  # ]:          0 :         if (IS_GEN(i915, 11)) {
    1344         [ #  # ]:          0 :                 unsigned int hw_s = hweight8(device->slice_mask);
    1345         [ #  # ]:          0 :                 unsigned int hw_ss_per_s = hweight8(device->subslice_mask[0]);
    1346         [ #  # ]:          0 :                 unsigned int req_s = hweight8(context->slice_mask);
    1347         [ #  # ]:          0 :                 unsigned int req_ss = hweight8(context->subslice_mask);
    1348                 :            : 
    1349                 :            :                 /*
    1350                 :            :                  * Only full subslice enablement is possible if more than one
    1351                 :            :                  * slice is turned on.
    1352                 :            :                  */
    1353         [ #  # ]:          0 :                 if (req_s > 1 && req_ss != hw_ss_per_s)
    1354                 :            :                         return -EINVAL;
    1355                 :            : 
    1356                 :            :                 /*
    1357                 :            :                  * If more than four (SScount bitfield limit) subslices are
    1358                 :            :                  * requested then the number has to be even.
    1359                 :            :                  */
    1360   [ #  #  #  # ]:          0 :                 if (req_ss > 4 && (req_ss & 1))
    1361                 :            :                         return -EINVAL;
    1362                 :            : 
    1363                 :            :                 /*
    1364                 :            :                  * If only one slice is enabled and subslice count is below the
    1365                 :            :                  * device full enablement, it must be at most half of the all
    1366                 :            :                  * available subslices.
    1367                 :            :                  */
    1368         [ #  # ]:          0 :                 if (req_s == 1 && req_ss < hw_ss_per_s &&
    1369         [ #  # ]:          0 :                     req_ss > (hw_ss_per_s / 2))
    1370                 :            :                         return -EINVAL;
    1371                 :            : 
    1372                 :            :                 /* ABI restriction - VME use case only. */
    1373                 :            : 
    1374                 :            :                 /* All slices or one slice only. */
    1375         [ #  # ]:          0 :                 if (req_s != 1 && req_s != hw_s)
    1376                 :            :                         return -EINVAL;
    1377                 :            : 
    1378                 :            :                 /*
    1379                 :            :                  * Half subslices or full enablement only when one slice is
    1380                 :            :                  * enabled.
    1381                 :            :                  */
    1382         [ #  # ]:          0 :                 if (req_s == 1 &&
    1383         [ #  # ]:          0 :                     (req_ss != hw_ss_per_s && req_ss != (hw_ss_per_s / 2)))
    1384                 :            :                         return -EINVAL;
    1385                 :            : 
    1386                 :            :                 /* No EU configuration changes. */
    1387                 :          0 :                 if ((user->min_eus_per_subslice !=
    1388         [ #  # ]:          0 :                      device->max_eus_per_subslice) ||
    1389         [ #  # ]:          0 :                     (user->max_eus_per_subslice !=
    1390                 :            :                      device->max_eus_per_subslice))
    1391                 :          0 :                         return -EINVAL;
    1392                 :            :         }
    1393                 :            : 
    1394                 :            :         return 0;
    1395                 :            : }
    1396                 :            : 
    1397                 :            : static int set_sseu(struct i915_gem_context *ctx,
    1398                 :            :                     struct drm_i915_gem_context_param *args)
    1399                 :            : {
    1400                 :            :         struct drm_i915_private *i915 = ctx->i915;
    1401                 :            :         struct drm_i915_gem_context_param_sseu user_sseu;
    1402                 :            :         struct intel_context *ce;
    1403                 :            :         struct intel_sseu sseu;
    1404                 :            :         unsigned long lookup;
    1405                 :            :         int ret;
    1406                 :            : 
    1407                 :            :         if (args->size < sizeof(user_sseu))
    1408                 :            :                 return -EINVAL;
    1409                 :            : 
    1410                 :            :         if (!IS_GEN(i915, 11))
    1411                 :            :                 return -ENODEV;
    1412                 :            : 
    1413                 :            :         if (copy_from_user(&user_sseu, u64_to_user_ptr(args->value),
    1414                 :            :                            sizeof(user_sseu)))
    1415                 :            :                 return -EFAULT;
    1416                 :            : 
    1417                 :            :         if (user_sseu.rsvd)
    1418                 :            :                 return -EINVAL;
    1419                 :            : 
    1420                 :            :         if (user_sseu.flags & ~(I915_CONTEXT_SSEU_FLAG_ENGINE_INDEX))
    1421                 :            :                 return -EINVAL;
    1422                 :            : 
    1423                 :            :         lookup = 0;
    1424                 :            :         if (user_sseu.flags & I915_CONTEXT_SSEU_FLAG_ENGINE_INDEX)
    1425                 :            :                 lookup |= LOOKUP_USER_INDEX;
    1426                 :            : 
    1427                 :            :         ce = lookup_user_engine(ctx, lookup, &user_sseu.engine);
    1428                 :            :         if (IS_ERR(ce))
    1429                 :            :                 return PTR_ERR(ce);
    1430                 :            : 
    1431                 :            :         /* Only render engine supports RPCS configuration. */
    1432                 :            :         if (ce->engine->class != RENDER_CLASS) {
    1433                 :            :                 ret = -ENODEV;
    1434                 :            :                 goto out_ce;
    1435                 :            :         }
    1436                 :            : 
    1437                 :            :         ret = user_to_context_sseu(i915, &user_sseu, &sseu);
    1438                 :            :         if (ret)
    1439                 :            :                 goto out_ce;
    1440                 :            : 
    1441                 :            :         ret = intel_context_reconfigure_sseu(ce, sseu);
    1442                 :            :         if (ret)
    1443                 :            :                 goto out_ce;
    1444                 :            : 
    1445                 :            :         args->size = sizeof(user_sseu);
    1446                 :            : 
    1447                 :            : out_ce:
    1448                 :            :         intel_context_put(ce);
    1449                 :            :         return ret;
    1450                 :            : }
    1451                 :            : 
    1452                 :            : struct set_engines {
    1453                 :            :         struct i915_gem_context *ctx;
    1454                 :            :         struct i915_gem_engines *engines;
    1455                 :            : };
    1456                 :            : 
    1457                 :            : static int
    1458                 :          0 : set_engines__load_balance(struct i915_user_extension __user *base, void *data)
    1459                 :            : {
    1460                 :          0 :         struct i915_context_engines_load_balance __user *ext =
    1461                 :          0 :                 container_of_user(base, typeof(*ext), base);
    1462                 :          0 :         const struct set_engines *set = data;
    1463                 :          0 :         struct intel_engine_cs *stack[16];
    1464                 :          0 :         struct intel_engine_cs **siblings;
    1465                 :          0 :         struct intel_context *ce;
    1466                 :          0 :         u16 num_siblings, idx;
    1467                 :          0 :         unsigned int n;
    1468                 :          0 :         int err;
    1469                 :            : 
    1470         [ #  # ]:          0 :         if (!HAS_EXECLISTS(set->ctx->i915))
    1471                 :            :                 return -ENODEV;
    1472                 :            : 
    1473         [ #  # ]:          0 :         if (USES_GUC_SUBMISSION(set->ctx->i915))
    1474                 :            :                 return -ENODEV; /* not implement yet */
    1475                 :            : 
    1476         [ #  # ]:          0 :         if (get_user(idx, &ext->engine_index))
    1477                 :            :                 return -EFAULT;
    1478                 :            : 
    1479         [ #  # ]:          0 :         if (idx >= set->engines->num_engines) {
    1480                 :          0 :                 DRM_DEBUG("Invalid placement value, %d >= %d\n",
    1481                 :            :                           idx, set->engines->num_engines);
    1482                 :          0 :                 return -EINVAL;
    1483                 :            :         }
    1484                 :            : 
    1485                 :          0 :         idx = array_index_nospec(idx, set->engines->num_engines);
    1486         [ #  # ]:          0 :         if (set->engines->engines[idx]) {
    1487                 :          0 :                 DRM_DEBUG("Invalid placement[%d], already occupied\n", idx);
    1488                 :          0 :                 return -EEXIST;
    1489                 :            :         }
    1490                 :            : 
    1491         [ #  # ]:          0 :         if (get_user(num_siblings, &ext->num_siblings))
    1492                 :            :                 return -EFAULT;
    1493                 :            : 
    1494   [ #  #  #  # ]:          0 :         err = check_user_mbz(&ext->flags);
    1495                 :          0 :         if (err)
    1496                 :          0 :                 return err;
    1497                 :            : 
    1498   [ #  #  #  # ]:          0 :         err = check_user_mbz(&ext->mbz64);
    1499                 :          0 :         if (err)
    1500                 :          0 :                 return err;
    1501                 :            : 
    1502                 :          0 :         siblings = stack;
    1503         [ #  # ]:          0 :         if (num_siblings > ARRAY_SIZE(stack)) {
    1504                 :          0 :                 siblings = kmalloc_array(num_siblings,
    1505                 :            :                                          sizeof(*siblings),
    1506                 :            :                                          GFP_KERNEL);
    1507         [ #  # ]:          0 :                 if (!siblings)
    1508                 :            :                         return -ENOMEM;
    1509                 :            :         }
    1510                 :            : 
    1511         [ #  # ]:          0 :         for (n = 0; n < num_siblings; n++) {
    1512                 :          0 :                 struct i915_engine_class_instance ci;
    1513                 :            : 
    1514         [ #  # ]:          0 :                 if (copy_from_user(&ci, &ext->engines[n], sizeof(ci))) {
    1515                 :          0 :                         err = -EFAULT;
    1516                 :          0 :                         goto out_siblings;
    1517                 :            :                 }
    1518                 :            : 
    1519                 :          0 :                 siblings[n] = intel_engine_lookup_user(set->ctx->i915,
    1520                 :          0 :                                                        ci.engine_class,
    1521                 :          0 :                                                        ci.engine_instance);
    1522         [ #  # ]:          0 :                 if (!siblings[n]) {
    1523                 :          0 :                         DRM_DEBUG("Invalid sibling[%d]: { class:%d, inst:%d }\n",
    1524                 :            :                                   n, ci.engine_class, ci.engine_instance);
    1525                 :          0 :                         err = -EINVAL;
    1526                 :          0 :                         goto out_siblings;
    1527                 :            :                 }
    1528                 :            :         }
    1529                 :            : 
    1530                 :          0 :         ce = intel_execlists_create_virtual(siblings, n);
    1531         [ #  # ]:          0 :         if (IS_ERR(ce)) {
    1532                 :          0 :                 err = PTR_ERR(ce);
    1533                 :          0 :                 goto out_siblings;
    1534                 :            :         }
    1535                 :            : 
    1536                 :          0 :         intel_context_set_gem(ce, set->ctx);
    1537                 :            : 
    1538         [ #  # ]:          0 :         if (cmpxchg(&set->engines->engines[idx], NULL, ce)) {
    1539                 :          0 :                 intel_context_put(ce);
    1540                 :          0 :                 err = -EEXIST;
    1541                 :          0 :                 goto out_siblings;
    1542                 :            :         }
    1543                 :            : 
    1544                 :          0 : out_siblings:
    1545         [ #  # ]:          0 :         if (siblings != stack)
    1546                 :          0 :                 kfree(siblings);
    1547                 :            : 
    1548                 :            :         return err;
    1549                 :            : }
    1550                 :            : 
    1551                 :            : static int
    1552                 :          0 : set_engines__bond(struct i915_user_extension __user *base, void *data)
    1553                 :            : {
    1554                 :          0 :         struct i915_context_engines_bond __user *ext =
    1555                 :          0 :                 container_of_user(base, typeof(*ext), base);
    1556                 :          0 :         const struct set_engines *set = data;
    1557                 :          0 :         struct i915_engine_class_instance ci;
    1558                 :          0 :         struct intel_engine_cs *virtual;
    1559                 :          0 :         struct intel_engine_cs *master;
    1560                 :          0 :         u16 idx, num_bonds;
    1561                 :          0 :         int err, n;
    1562                 :            : 
    1563         [ #  # ]:          0 :         if (get_user(idx, &ext->virtual_index))
    1564                 :            :                 return -EFAULT;
    1565                 :            : 
    1566         [ #  # ]:          0 :         if (idx >= set->engines->num_engines) {
    1567                 :          0 :                 DRM_DEBUG("Invalid index for virtual engine: %d >= %d\n",
    1568                 :            :                           idx, set->engines->num_engines);
    1569                 :          0 :                 return -EINVAL;
    1570                 :            :         }
    1571                 :            : 
    1572                 :          0 :         idx = array_index_nospec(idx, set->engines->num_engines);
    1573         [ #  # ]:          0 :         if (!set->engines->engines[idx]) {
    1574                 :          0 :                 DRM_DEBUG("Invalid engine at %d\n", idx);
    1575                 :          0 :                 return -EINVAL;
    1576                 :            :         }
    1577                 :          0 :         virtual = set->engines->engines[idx]->engine;
    1578                 :            : 
    1579   [ #  #  #  # ]:          0 :         err = check_user_mbz(&ext->flags);
    1580                 :            :         if (err)
    1581                 :          0 :                 return err;
    1582                 :            : 
    1583         [ #  # ]:          0 :         for (n = 0; n < ARRAY_SIZE(ext->mbz64); n++) {
    1584   [ #  #  #  # ]:          0 :                 err = check_user_mbz(&ext->mbz64[n]);
    1585                 :          0 :                 if (err)
    1586                 :          0 :                         return err;
    1587                 :            :         }
    1588                 :            : 
    1589         [ #  # ]:          0 :         if (copy_from_user(&ci, &ext->master, sizeof(ci)))
    1590                 :            :                 return -EFAULT;
    1591                 :            : 
    1592                 :          0 :         master = intel_engine_lookup_user(set->ctx->i915,
    1593                 :          0 :                                           ci.engine_class, ci.engine_instance);
    1594         [ #  # ]:          0 :         if (!master) {
    1595                 :          0 :                 DRM_DEBUG("Unrecognised master engine: { class:%u, instance:%u }\n",
    1596                 :            :                           ci.engine_class, ci.engine_instance);
    1597                 :          0 :                 return -EINVAL;
    1598                 :            :         }
    1599                 :            : 
    1600         [ #  # ]:          0 :         if (get_user(num_bonds, &ext->num_bonds))
    1601                 :            :                 return -EFAULT;
    1602                 :            : 
    1603         [ #  # ]:          0 :         for (n = 0; n < num_bonds; n++) {
    1604                 :          0 :                 struct intel_engine_cs *bond;
    1605                 :            : 
    1606         [ #  # ]:          0 :                 if (copy_from_user(&ci, &ext->engines[n], sizeof(ci)))
    1607                 :            :                         return -EFAULT;
    1608                 :            : 
    1609                 :          0 :                 bond = intel_engine_lookup_user(set->ctx->i915,
    1610                 :          0 :                                                 ci.engine_class,
    1611                 :          0 :                                                 ci.engine_instance);
    1612         [ #  # ]:          0 :                 if (!bond) {
    1613                 :          0 :                         DRM_DEBUG("Unrecognised engine[%d] for bonding: { class:%d, instance: %d }\n",
    1614                 :            :                                   n, ci.engine_class, ci.engine_instance);
    1615                 :          0 :                         return -EINVAL;
    1616                 :            :                 }
    1617                 :            : 
    1618                 :            :                 /*
    1619                 :            :                  * A non-virtual engine has no siblings to choose between; and
    1620                 :            :                  * a submit fence will always be directed to the one engine.
    1621                 :            :                  */
    1622         [ #  # ]:          0 :                 if (intel_engine_is_virtual(virtual)) {
    1623                 :          0 :                         err = intel_virtual_engine_attach_bond(virtual,
    1624                 :            :                                                                master,
    1625                 :            :                                                                bond);
    1626         [ #  # ]:          0 :                         if (err)
    1627                 :          0 :                                 return err;
    1628                 :            :                 }
    1629                 :            :         }
    1630                 :            : 
    1631                 :            :         return 0;
    1632                 :            : }
    1633                 :            : 
    1634                 :            : static const i915_user_extension_fn set_engines__extensions[] = {
    1635                 :            :         [I915_CONTEXT_ENGINES_EXT_LOAD_BALANCE] = set_engines__load_balance,
    1636                 :            :         [I915_CONTEXT_ENGINES_EXT_BOND] = set_engines__bond,
    1637                 :            : };
    1638                 :            : 
    1639                 :            : static int
    1640                 :            : set_engines(struct i915_gem_context *ctx,
    1641                 :            :             const struct drm_i915_gem_context_param *args)
    1642                 :            : {
    1643                 :            :         struct i915_context_param_engines __user *user =
    1644                 :            :                 u64_to_user_ptr(args->value);
    1645                 :            :         struct set_engines set = { .ctx = ctx };
    1646                 :            :         unsigned int num_engines, n;
    1647                 :            :         u64 extensions;
    1648                 :            :         int err;
    1649                 :            : 
    1650                 :            :         if (!args->size) { /* switch back to legacy user_ring_map */
    1651                 :            :                 if (!i915_gem_context_user_engines(ctx))
    1652                 :            :                         return 0;
    1653                 :            : 
    1654                 :            :                 set.engines = default_engines(ctx);
    1655                 :            :                 if (IS_ERR(set.engines))
    1656                 :            :                         return PTR_ERR(set.engines);
    1657                 :            : 
    1658                 :            :                 goto replace;
    1659                 :            :         }
    1660                 :            : 
    1661                 :            :         BUILD_BUG_ON(!IS_ALIGNED(sizeof(*user), sizeof(*user->engines)));
    1662                 :            :         if (args->size < sizeof(*user) ||
    1663                 :            :             !IS_ALIGNED(args->size, sizeof(*user->engines))) {
    1664                 :            :                 DRM_DEBUG("Invalid size for engine array: %d\n",
    1665                 :            :                           args->size);
    1666                 :            :                 return -EINVAL;
    1667                 :            :         }
    1668                 :            : 
    1669                 :            :         /*
    1670                 :            :          * Note that I915_EXEC_RING_MASK limits execbuf to only using the
    1671                 :            :          * first 64 engines defined here.
    1672                 :            :          */
    1673                 :            :         num_engines = (args->size - sizeof(*user)) / sizeof(*user->engines);
    1674                 :            : 
    1675                 :            :         set.engines = kmalloc(struct_size(set.engines, engines, num_engines),
    1676                 :            :                               GFP_KERNEL);
    1677                 :            :         if (!set.engines)
    1678                 :            :                 return -ENOMEM;
    1679                 :            : 
    1680                 :            :         init_rcu_head(&set.engines->rcu);
    1681                 :            :         for (n = 0; n < num_engines; n++) {
    1682                 :            :                 struct i915_engine_class_instance ci;
    1683                 :            :                 struct intel_engine_cs *engine;
    1684                 :            :                 struct intel_context *ce;
    1685                 :            : 
    1686                 :            :                 if (copy_from_user(&ci, &user->engines[n], sizeof(ci))) {
    1687                 :            :                         __free_engines(set.engines, n);
    1688                 :            :                         return -EFAULT;
    1689                 :            :                 }
    1690                 :            : 
    1691                 :            :                 if (ci.engine_class == (u16)I915_ENGINE_CLASS_INVALID &&
    1692                 :            :                     ci.engine_instance == (u16)I915_ENGINE_CLASS_INVALID_NONE) {
    1693                 :            :                         set.engines->engines[n] = NULL;
    1694                 :            :                         continue;
    1695                 :            :                 }
    1696                 :            : 
    1697                 :            :                 engine = intel_engine_lookup_user(ctx->i915,
    1698                 :            :                                                   ci.engine_class,
    1699                 :            :                                                   ci.engine_instance);
    1700                 :            :                 if (!engine) {
    1701                 :            :                         DRM_DEBUG("Invalid engine[%d]: { class:%d, instance:%d }\n",
    1702                 :            :                                   n, ci.engine_class, ci.engine_instance);
    1703                 :            :                         __free_engines(set.engines, n);
    1704                 :            :                         return -ENOENT;
    1705                 :            :                 }
    1706                 :            : 
    1707                 :            :                 ce = intel_context_create(engine);
    1708                 :            :                 if (IS_ERR(ce)) {
    1709                 :            :                         __free_engines(set.engines, n);
    1710                 :            :                         return PTR_ERR(ce);
    1711                 :            :                 }
    1712                 :            : 
    1713                 :            :                 intel_context_set_gem(ce, ctx);
    1714                 :            : 
    1715                 :            :                 set.engines->engines[n] = ce;
    1716                 :            :         }
    1717                 :            :         set.engines->num_engines = num_engines;
    1718                 :            : 
    1719                 :            :         err = -EFAULT;
    1720                 :            :         if (!get_user(extensions, &user->extensions))
    1721                 :            :                 err = i915_user_extensions(u64_to_user_ptr(extensions),
    1722                 :            :                                            set_engines__extensions,
    1723                 :            :                                            ARRAY_SIZE(set_engines__extensions),
    1724                 :            :                                            &set);
    1725                 :            :         if (err) {
    1726                 :            :                 free_engines(set.engines);
    1727                 :            :                 return err;
    1728                 :            :         }
    1729                 :            : 
    1730                 :            : replace:
    1731                 :            :         mutex_lock(&ctx->engines_mutex);
    1732                 :            :         if (args->size)
    1733                 :            :                 i915_gem_context_set_user_engines(ctx);
    1734                 :            :         else
    1735                 :            :                 i915_gem_context_clear_user_engines(ctx);
    1736                 :            :         set.engines = rcu_replace_pointer(ctx->engines, set.engines, 1);
    1737                 :            :         mutex_unlock(&ctx->engines_mutex);
    1738                 :            : 
    1739                 :            :         call_rcu(&set.engines->rcu, free_engines_rcu);
    1740                 :            : 
    1741                 :            :         return 0;
    1742                 :            : }
    1743                 :            : 
    1744                 :            : static struct i915_gem_engines *
    1745                 :          0 : __copy_engines(struct i915_gem_engines *e)
    1746                 :            : {
    1747                 :          0 :         struct i915_gem_engines *copy;
    1748                 :          0 :         unsigned int n;
    1749                 :            : 
    1750         [ #  # ]:          0 :         copy = kmalloc(struct_size(e, engines, e->num_engines), GFP_KERNEL);
    1751         [ #  # ]:          0 :         if (!copy)
    1752                 :            :                 return ERR_PTR(-ENOMEM);
    1753                 :            : 
    1754                 :          0 :         init_rcu_head(&copy->rcu);
    1755         [ #  # ]:          0 :         for (n = 0; n < e->num_engines; n++) {
    1756         [ #  # ]:          0 :                 if (e->engines[n])
    1757                 :          0 :                         copy->engines[n] = intel_context_get(e->engines[n]);
    1758                 :            :                 else
    1759                 :          0 :                         copy->engines[n] = NULL;
    1760                 :            :         }
    1761                 :          0 :         copy->num_engines = n;
    1762                 :            : 
    1763                 :          0 :         return copy;
    1764                 :            : }
    1765                 :            : 
    1766                 :            : static int
    1767                 :            : get_engines(struct i915_gem_context *ctx,
    1768                 :            :             struct drm_i915_gem_context_param *args)
    1769                 :            : {
    1770                 :            :         struct i915_context_param_engines __user *user;
    1771                 :            :         struct i915_gem_engines *e;
    1772                 :            :         size_t n, count, size;
    1773                 :            :         int err = 0;
    1774                 :            : 
    1775                 :            :         err = mutex_lock_interruptible(&ctx->engines_mutex);
    1776                 :            :         if (err)
    1777                 :            :                 return err;
    1778                 :            : 
    1779                 :            :         e = NULL;
    1780                 :            :         if (i915_gem_context_user_engines(ctx))
    1781                 :            :                 e = __copy_engines(i915_gem_context_engines(ctx));
    1782                 :            :         mutex_unlock(&ctx->engines_mutex);
    1783                 :            :         if (IS_ERR_OR_NULL(e)) {
    1784                 :            :                 args->size = 0;
    1785                 :            :                 return PTR_ERR_OR_ZERO(e);
    1786                 :            :         }
    1787                 :            : 
    1788                 :            :         count = e->num_engines;
    1789                 :            : 
    1790                 :            :         /* Be paranoid in case we have an impedance mismatch */
    1791                 :            :         if (!check_struct_size(user, engines, count, &size)) {
    1792                 :            :                 err = -EINVAL;
    1793                 :            :                 goto err_free;
    1794                 :            :         }
    1795                 :            :         if (overflows_type(size, args->size)) {
    1796                 :            :                 err = -EINVAL;
    1797                 :            :                 goto err_free;
    1798                 :            :         }
    1799                 :            : 
    1800                 :            :         if (!args->size) {
    1801                 :            :                 args->size = size;
    1802                 :            :                 goto err_free;
    1803                 :            :         }
    1804                 :            : 
    1805                 :            :         if (args->size < size) {
    1806                 :            :                 err = -EINVAL;
    1807                 :            :                 goto err_free;
    1808                 :            :         }
    1809                 :            : 
    1810                 :            :         user = u64_to_user_ptr(args->value);
    1811                 :            :         if (!access_ok(user, size)) {
    1812                 :            :                 err = -EFAULT;
    1813                 :            :                 goto err_free;
    1814                 :            :         }
    1815                 :            : 
    1816                 :            :         if (put_user(0, &user->extensions)) {
    1817                 :            :                 err = -EFAULT;
    1818                 :            :                 goto err_free;
    1819                 :            :         }
    1820                 :            : 
    1821                 :            :         for (n = 0; n < count; n++) {
    1822                 :            :                 struct i915_engine_class_instance ci = {
    1823                 :            :                         .engine_class = I915_ENGINE_CLASS_INVALID,
    1824                 :            :                         .engine_instance = I915_ENGINE_CLASS_INVALID_NONE,
    1825                 :            :                 };
    1826                 :            : 
    1827                 :            :                 if (e->engines[n]) {
    1828                 :            :                         ci.engine_class = e->engines[n]->engine->uabi_class;
    1829                 :            :                         ci.engine_instance = e->engines[n]->engine->uabi_instance;
    1830                 :            :                 }
    1831                 :            : 
    1832                 :            :                 if (copy_to_user(&user->engines[n], &ci, sizeof(ci))) {
    1833                 :            :                         err = -EFAULT;
    1834                 :            :                         goto err_free;
    1835                 :            :                 }
    1836                 :            :         }
    1837                 :            : 
    1838                 :            :         args->size = size;
    1839                 :            : 
    1840                 :            : err_free:
    1841                 :            :         free_engines(e);
    1842                 :            :         return err;
    1843                 :            : }
    1844                 :            : 
    1845                 :            : static int
    1846                 :          0 : set_persistence(struct i915_gem_context *ctx,
    1847                 :            :                 const struct drm_i915_gem_context_param *args)
    1848                 :            : {
    1849                 :          0 :         if (args->size)
    1850                 :            :                 return -EINVAL;
    1851                 :            : 
    1852                 :          0 :         return __context_set_persistence(ctx, args->value);
    1853                 :            : }
    1854                 :            : 
    1855                 :          0 : static void __apply_priority(struct intel_context *ce, void *arg)
    1856                 :            : {
    1857                 :          0 :         struct i915_gem_context *ctx = arg;
    1858                 :            : 
    1859         [ #  # ]:          0 :         if (!intel_engine_has_semaphores(ce->engine))
    1860                 :            :                 return;
    1861                 :            : 
    1862         [ #  # ]:          0 :         if (ctx->sched.priority >= I915_PRIORITY_NORMAL)
    1863                 :          0 :                 intel_context_set_use_semaphores(ce);
    1864                 :            :         else
    1865                 :          0 :                 intel_context_clear_use_semaphores(ce);
    1866                 :            : }
    1867                 :            : 
    1868                 :            : static int set_priority(struct i915_gem_context *ctx,
    1869                 :            :                         const struct drm_i915_gem_context_param *args)
    1870                 :            : {
    1871                 :            :         s64 priority = args->value;
    1872                 :            : 
    1873                 :            :         if (args->size)
    1874                 :            :                 return -EINVAL;
    1875                 :            : 
    1876                 :            :         if (!(ctx->i915->caps.scheduler & I915_SCHEDULER_CAP_PRIORITY))
    1877                 :            :                 return -ENODEV;
    1878                 :            : 
    1879                 :            :         if (priority > I915_CONTEXT_MAX_USER_PRIORITY ||
    1880                 :            :             priority < I915_CONTEXT_MIN_USER_PRIORITY)
    1881                 :            :                 return -EINVAL;
    1882                 :            : 
    1883                 :            :         if (priority > I915_CONTEXT_DEFAULT_PRIORITY &&
    1884                 :            :             !capable(CAP_SYS_NICE))
    1885                 :            :                 return -EPERM;
    1886                 :            : 
    1887                 :            :         ctx->sched.priority = I915_USER_PRIORITY(priority);
    1888                 :            :         context_apply_all(ctx, __apply_priority, ctx);
    1889                 :            : 
    1890                 :            :         return 0;
    1891                 :            : }
    1892                 :            : 
    1893                 :          0 : static int ctx_setparam(struct drm_i915_file_private *fpriv,
    1894                 :            :                         struct i915_gem_context *ctx,
    1895                 :            :                         struct drm_i915_gem_context_param *args)
    1896                 :            : {
    1897                 :          0 :         int ret = 0;
    1898                 :            : 
    1899   [ #  #  #  #  :          0 :         switch (args->param) {
          #  #  #  #  #  
                      # ]
    1900                 :          0 :         case I915_CONTEXT_PARAM_NO_ZEROMAP:
    1901         [ #  # ]:          0 :                 if (args->size)
    1902                 :            :                         ret = -EINVAL;
    1903         [ #  # ]:          0 :                 else if (args->value)
    1904                 :          0 :                         set_bit(UCONTEXT_NO_ZEROMAP, &ctx->user_flags);
    1905                 :            :                 else
    1906                 :          0 :                         clear_bit(UCONTEXT_NO_ZEROMAP, &ctx->user_flags);
    1907                 :            :                 break;
    1908                 :            : 
    1909                 :          0 :         case I915_CONTEXT_PARAM_NO_ERROR_CAPTURE:
    1910         [ #  # ]:          0 :                 if (args->size)
    1911                 :            :                         ret = -EINVAL;
    1912         [ #  # ]:          0 :                 else if (args->value)
    1913                 :          0 :                         i915_gem_context_set_no_error_capture(ctx);
    1914                 :            :                 else
    1915                 :          0 :                         i915_gem_context_clear_no_error_capture(ctx);
    1916                 :            :                 break;
    1917                 :            : 
    1918                 :          0 :         case I915_CONTEXT_PARAM_BANNABLE:
    1919         [ #  # ]:          0 :                 if (args->size)
    1920                 :            :                         ret = -EINVAL;
    1921   [ #  #  #  # ]:          0 :                 else if (!capable(CAP_SYS_ADMIN) && !args->value)
    1922                 :            :                         ret = -EPERM;
    1923         [ #  # ]:          0 :                 else if (args->value)
    1924                 :          0 :                         i915_gem_context_set_bannable(ctx);
    1925                 :            :                 else
    1926                 :          0 :                         i915_gem_context_clear_bannable(ctx);
    1927                 :            :                 break;
    1928                 :            : 
    1929                 :          0 :         case I915_CONTEXT_PARAM_RECOVERABLE:
    1930         [ #  # ]:          0 :                 if (args->size)
    1931                 :            :                         ret = -EINVAL;
    1932         [ #  # ]:          0 :                 else if (args->value)
    1933                 :          0 :                         i915_gem_context_set_recoverable(ctx);
    1934                 :            :                 else
    1935                 :          0 :                         i915_gem_context_clear_recoverable(ctx);
    1936                 :            :                 break;
    1937                 :            : 
    1938                 :          0 :         case I915_CONTEXT_PARAM_PRIORITY:
    1939                 :          0 :                 ret = set_priority(ctx, args);
    1940                 :          0 :                 break;
    1941                 :            : 
    1942                 :          0 :         case I915_CONTEXT_PARAM_SSEU:
    1943                 :          0 :                 ret = set_sseu(ctx, args);
    1944                 :          0 :                 break;
    1945                 :            : 
    1946                 :          0 :         case I915_CONTEXT_PARAM_VM:
    1947                 :          0 :                 ret = set_ppgtt(fpriv, ctx, args);
    1948                 :          0 :                 break;
    1949                 :            : 
    1950                 :          0 :         case I915_CONTEXT_PARAM_ENGINES:
    1951                 :          0 :                 ret = set_engines(ctx, args);
    1952                 :          0 :                 break;
    1953                 :            : 
    1954                 :          0 :         case I915_CONTEXT_PARAM_PERSISTENCE:
    1955         [ #  # ]:          0 :                 ret = set_persistence(ctx, args);
    1956                 :            :                 break;
    1957                 :            : 
    1958                 :            :         case I915_CONTEXT_PARAM_BAN_PERIOD:
    1959                 :            :         default:
    1960                 :            :                 ret = -EINVAL;
    1961                 :            :                 break;
    1962                 :            :         }
    1963                 :            : 
    1964                 :          0 :         return ret;
    1965                 :            : }
    1966                 :            : 
    1967                 :            : struct create_ext {
    1968                 :            :         struct i915_gem_context *ctx;
    1969                 :            :         struct drm_i915_file_private *fpriv;
    1970                 :            : };
    1971                 :            : 
    1972                 :          0 : static int create_setparam(struct i915_user_extension __user *ext, void *data)
    1973                 :            : {
    1974                 :          0 :         struct drm_i915_gem_context_create_ext_setparam local;
    1975                 :          0 :         const struct create_ext *arg = data;
    1976                 :            : 
    1977         [ #  # ]:          0 :         if (copy_from_user(&local, ext, sizeof(local)))
    1978                 :            :                 return -EFAULT;
    1979                 :            : 
    1980         [ #  # ]:          0 :         if (local.param.ctx_id)
    1981                 :            :                 return -EINVAL;
    1982                 :            : 
    1983                 :          0 :         return ctx_setparam(arg->fpriv, arg->ctx, &local.param);
    1984                 :            : }
    1985                 :            : 
    1986                 :          0 : static int clone_engines(struct i915_gem_context *dst,
    1987                 :            :                          struct i915_gem_context *src)
    1988                 :            : {
    1989                 :          0 :         struct i915_gem_engines *e = i915_gem_context_lock_engines(src);
    1990                 :          0 :         struct i915_gem_engines *clone;
    1991                 :          0 :         bool user_engines;
    1992                 :          0 :         unsigned long n;
    1993                 :            : 
    1994         [ #  # ]:          0 :         clone = kmalloc(struct_size(e, engines, e->num_engines), GFP_KERNEL);
    1995         [ #  # ]:          0 :         if (!clone)
    1996                 :          0 :                 goto err_unlock;
    1997                 :            : 
    1998                 :          0 :         init_rcu_head(&clone->rcu);
    1999         [ #  # ]:          0 :         for (n = 0; n < e->num_engines; n++) {
    2000                 :          0 :                 struct intel_engine_cs *engine;
    2001                 :            : 
    2002         [ #  # ]:          0 :                 if (!e->engines[n]) {
    2003                 :          0 :                         clone->engines[n] = NULL;
    2004                 :          0 :                         continue;
    2005                 :            :                 }
    2006                 :          0 :                 engine = e->engines[n]->engine;
    2007                 :            : 
    2008                 :            :                 /*
    2009                 :            :                  * Virtual engines are singletons; they can only exist
    2010                 :            :                  * inside a single context, because they embed their
    2011                 :            :                  * HW context... As each virtual context implies a single
    2012                 :            :                  * timeline (each engine can only dequeue a single request
    2013                 :            :                  * at any time), it would be surprising for two contexts
    2014                 :            :                  * to use the same engine. So let's create a copy of
    2015                 :            :                  * the virtual engine instead.
    2016                 :            :                  */
    2017         [ #  # ]:          0 :                 if (intel_engine_is_virtual(engine))
    2018                 :          0 :                         clone->engines[n] =
    2019                 :          0 :                                 intel_execlists_clone_virtual(engine);
    2020                 :            :                 else
    2021                 :          0 :                         clone->engines[n] = intel_context_create(engine);
    2022   [ #  #  #  # ]:          0 :                 if (IS_ERR_OR_NULL(clone->engines[n])) {
    2023                 :          0 :                         __free_engines(clone, n);
    2024                 :          0 :                         goto err_unlock;
    2025                 :            :                 }
    2026                 :            : 
    2027                 :          0 :                 intel_context_set_gem(clone->engines[n], dst);
    2028                 :            :         }
    2029                 :          0 :         clone->num_engines = n;
    2030                 :            : 
    2031                 :          0 :         user_engines = i915_gem_context_user_engines(src);
    2032                 :          0 :         i915_gem_context_unlock_engines(src);
    2033                 :            : 
    2034                 :            :         /* Serialised by constructor */
    2035                 :          0 :         free_engines(__context_engines_static(dst));
    2036         [ #  # ]:          0 :         RCU_INIT_POINTER(dst->engines, clone);
    2037         [ #  # ]:          0 :         if (user_engines)
    2038                 :          0 :                 i915_gem_context_set_user_engines(dst);
    2039                 :            :         else
    2040                 :          0 :                 i915_gem_context_clear_user_engines(dst);
    2041                 :            :         return 0;
    2042                 :            : 
    2043                 :          0 : err_unlock:
    2044                 :          0 :         i915_gem_context_unlock_engines(src);
    2045                 :          0 :         return -ENOMEM;
    2046                 :            : }
    2047                 :            : 
    2048                 :          0 : static int clone_flags(struct i915_gem_context *dst,
    2049                 :            :                        struct i915_gem_context *src)
    2050                 :            : {
    2051                 :          0 :         dst->user_flags = src->user_flags;
    2052                 :          0 :         return 0;
    2053                 :            : }
    2054                 :            : 
    2055                 :          0 : static int clone_schedattr(struct i915_gem_context *dst,
    2056                 :            :                            struct i915_gem_context *src)
    2057                 :            : {
    2058                 :          0 :         dst->sched = src->sched;
    2059                 :          0 :         return 0;
    2060                 :            : }
    2061                 :            : 
    2062                 :          0 : static int clone_sseu(struct i915_gem_context *dst,
    2063                 :            :                       struct i915_gem_context *src)
    2064                 :            : {
    2065                 :          0 :         struct i915_gem_engines *e = i915_gem_context_lock_engines(src);
    2066                 :          0 :         struct i915_gem_engines *clone;
    2067                 :          0 :         unsigned long n;
    2068                 :          0 :         int err;
    2069                 :            : 
    2070                 :            :         /* no locking required; sole access under constructor*/
    2071                 :          0 :         clone = __context_engines_static(dst);
    2072         [ #  # ]:          0 :         if (e->num_engines != clone->num_engines) {
    2073                 :          0 :                 err = -EINVAL;
    2074                 :          0 :                 goto unlock;
    2075                 :            :         }
    2076                 :            : 
    2077         [ #  # ]:          0 :         for (n = 0; n < e->num_engines; n++) {
    2078                 :          0 :                 struct intel_context *ce = e->engines[n];
    2079                 :            : 
    2080         [ #  # ]:          0 :                 if (clone->engines[n]->engine->class != ce->engine->class) {
    2081                 :            :                         /* Must have compatible engine maps! */
    2082                 :          0 :                         err = -EINVAL;
    2083                 :          0 :                         goto unlock;
    2084                 :            :                 }
    2085                 :            : 
    2086                 :            :                 /* serialises with set_sseu */
    2087                 :          0 :                 err = intel_context_lock_pinned(ce);
    2088         [ #  # ]:          0 :                 if (err)
    2089                 :          0 :                         goto unlock;
    2090                 :            : 
    2091                 :          0 :                 clone->engines[n]->sseu = ce->sseu;
    2092                 :          0 :                 intel_context_unlock_pinned(ce);
    2093                 :            :         }
    2094                 :            : 
    2095                 :            :         err = 0;
    2096                 :          0 : unlock:
    2097                 :          0 :         i915_gem_context_unlock_engines(src);
    2098                 :          0 :         return err;
    2099                 :            : }
    2100                 :            : 
    2101                 :          0 : static int clone_timeline(struct i915_gem_context *dst,
    2102                 :            :                           struct i915_gem_context *src)
    2103                 :            : {
    2104         [ #  # ]:          0 :         if (src->timeline)
    2105                 :          0 :                 __assign_timeline(dst, src->timeline);
    2106                 :            : 
    2107                 :          0 :         return 0;
    2108                 :            : }
    2109                 :            : 
    2110                 :          0 : static int clone_vm(struct i915_gem_context *dst,
    2111                 :            :                     struct i915_gem_context *src)
    2112                 :            : {
    2113                 :          0 :         struct i915_address_space *vm;
    2114                 :          0 :         int err = 0;
    2115                 :            : 
    2116         [ #  # ]:          0 :         if (!rcu_access_pointer(src->vm))
    2117                 :            :                 return 0;
    2118                 :            : 
    2119                 :          0 :         rcu_read_lock();
    2120                 :          0 :         vm = context_get_vm_rcu(src);
    2121                 :          0 :         rcu_read_unlock();
    2122                 :            : 
    2123         [ #  # ]:          0 :         if (!mutex_lock_interruptible(&dst->mutex)) {
    2124                 :          0 :                 __assign_ppgtt(dst, vm);
    2125                 :          0 :                 mutex_unlock(&dst->mutex);
    2126                 :            :         } else {
    2127                 :            :                 err = -EINTR;
    2128                 :            :         }
    2129                 :            : 
    2130                 :          0 :         i915_vm_put(vm);
    2131                 :          0 :         return err;
    2132                 :            : }
    2133                 :            : 
    2134                 :          0 : static int create_clone(struct i915_user_extension __user *ext, void *data)
    2135                 :            : {
    2136                 :          0 :         static int (* const fn[])(struct i915_gem_context *dst,
    2137                 :            :                                   struct i915_gem_context *src) = {
    2138                 :            : #define MAP(x, y) [ilog2(I915_CONTEXT_CLONE_##x)] = y
    2139                 :            :                 MAP(ENGINES, clone_engines),
    2140                 :            :                 MAP(FLAGS, clone_flags),
    2141                 :            :                 MAP(SCHEDATTR, clone_schedattr),
    2142                 :            :                 MAP(SSEU, clone_sseu),
    2143                 :            :                 MAP(TIMELINE, clone_timeline),
    2144                 :            :                 MAP(VM, clone_vm),
    2145                 :            : #undef MAP
    2146                 :            :         };
    2147                 :          0 :         struct drm_i915_gem_context_create_ext_clone local;
    2148                 :          0 :         const struct create_ext *arg = data;
    2149                 :          0 :         struct i915_gem_context *dst = arg->ctx;
    2150                 :          0 :         struct i915_gem_context *src;
    2151                 :          0 :         int err, bit;
    2152                 :            : 
    2153         [ #  # ]:          0 :         if (copy_from_user(&local, ext, sizeof(local)))
    2154                 :            :                 return -EFAULT;
    2155                 :            : 
    2156                 :          0 :         BUILD_BUG_ON(GENMASK(BITS_PER_TYPE(local.flags) - 1, ARRAY_SIZE(fn)) !=
    2157                 :            :                      I915_CONTEXT_CLONE_UNKNOWN);
    2158                 :            : 
    2159         [ #  # ]:          0 :         if (local.flags & I915_CONTEXT_CLONE_UNKNOWN)
    2160                 :            :                 return -EINVAL;
    2161                 :            : 
    2162         [ #  # ]:          0 :         if (local.rsvd)
    2163                 :            :                 return -EINVAL;
    2164                 :            : 
    2165                 :          0 :         rcu_read_lock();
    2166                 :          0 :         src = __i915_gem_context_lookup_rcu(arg->fpriv, local.clone_id);
    2167                 :          0 :         rcu_read_unlock();
    2168         [ #  # ]:          0 :         if (!src)
    2169                 :            :                 return -ENOENT;
    2170                 :            : 
    2171                 :            :         GEM_BUG_ON(src == dst);
    2172                 :            : 
    2173         [ #  # ]:          0 :         for (bit = 0; bit < ARRAY_SIZE(fn); bit++) {
    2174         [ #  # ]:          0 :                 if (!(local.flags & BIT(bit)))
    2175                 :          0 :                         continue;
    2176                 :            : 
    2177                 :          0 :                 err = fn[bit](dst, src);
    2178         [ #  # ]:          0 :                 if (err)
    2179                 :          0 :                         return err;
    2180                 :            :         }
    2181                 :            : 
    2182                 :            :         return 0;
    2183                 :            : }
    2184                 :            : 
    2185                 :            : static const i915_user_extension_fn create_extensions[] = {
    2186                 :            :         [I915_CONTEXT_CREATE_EXT_SETPARAM] = create_setparam,
    2187                 :            :         [I915_CONTEXT_CREATE_EXT_CLONE] = create_clone,
    2188                 :            : };
    2189                 :            : 
    2190                 :          0 : static bool client_is_banned(struct drm_i915_file_private *file_priv)
    2191                 :            : {
    2192                 :          0 :         return atomic_read(&file_priv->ban_score) >= I915_CLIENT_SCORE_BANNED;
    2193                 :            : }
    2194                 :            : 
    2195                 :          0 : int i915_gem_context_create_ioctl(struct drm_device *dev, void *data,
    2196                 :            :                                   struct drm_file *file)
    2197                 :            : {
    2198         [ #  # ]:          0 :         struct drm_i915_private *i915 = to_i915(dev);
    2199                 :          0 :         struct drm_i915_gem_context_create_ext *args = data;
    2200                 :          0 :         struct create_ext ext_data;
    2201                 :          0 :         int ret;
    2202                 :          0 :         u32 id;
    2203                 :            : 
    2204         [ #  # ]:          0 :         if (!DRIVER_CAPS(i915)->has_logical_contexts)
    2205                 :            :                 return -ENODEV;
    2206                 :            : 
    2207         [ #  # ]:          0 :         if (args->flags & I915_CONTEXT_CREATE_FLAGS_UNKNOWN)
    2208                 :            :                 return -EINVAL;
    2209                 :            : 
    2210                 :          0 :         ret = intel_gt_terminally_wedged(&i915->gt);
    2211         [ #  # ]:          0 :         if (ret)
    2212                 :            :                 return ret;
    2213                 :            : 
    2214                 :          0 :         ext_data.fpriv = file->driver_priv;
    2215         [ #  # ]:          0 :         if (client_is_banned(ext_data.fpriv)) {
    2216                 :          0 :                 DRM_DEBUG("client %s[%d] banned from creating ctx\n",
    2217                 :            :                           current->comm, task_pid_nr(current));
    2218                 :          0 :                 return -EIO;
    2219                 :            :         }
    2220                 :            : 
    2221                 :          0 :         ext_data.ctx = i915_gem_create_context(i915, args->flags);
    2222         [ #  # ]:          0 :         if (IS_ERR(ext_data.ctx))
    2223                 :          0 :                 return PTR_ERR(ext_data.ctx);
    2224                 :            : 
    2225         [ #  # ]:          0 :         if (args->flags & I915_CONTEXT_CREATE_FLAGS_USE_EXTENSIONS) {
    2226                 :          0 :                 ret = i915_user_extensions(u64_to_user_ptr(args->extensions),
    2227                 :            :                                            create_extensions,
    2228                 :            :                                            ARRAY_SIZE(create_extensions),
    2229                 :            :                                            &ext_data);
    2230         [ #  # ]:          0 :                 if (ret)
    2231                 :          0 :                         goto err_ctx;
    2232                 :            :         }
    2233                 :            : 
    2234                 :          0 :         ret = gem_context_register(ext_data.ctx, ext_data.fpriv, &id);
    2235         [ #  # ]:          0 :         if (ret < 0)
    2236                 :          0 :                 goto err_ctx;
    2237                 :            : 
    2238                 :          0 :         args->ctx_id = id;
    2239                 :          0 :         DRM_DEBUG("HW context %d created\n", args->ctx_id);
    2240                 :            : 
    2241                 :          0 :         return 0;
    2242                 :            : 
    2243                 :          0 : err_ctx:
    2244                 :          0 :         context_close(ext_data.ctx);
    2245                 :          0 :         return ret;
    2246                 :            : }
    2247                 :            : 
    2248                 :          0 : int i915_gem_context_destroy_ioctl(struct drm_device *dev, void *data,
    2249                 :            :                                    struct drm_file *file)
    2250                 :            : {
    2251                 :          0 :         struct drm_i915_gem_context_destroy *args = data;
    2252                 :          0 :         struct drm_i915_file_private *file_priv = file->driver_priv;
    2253                 :          0 :         struct i915_gem_context *ctx;
    2254                 :            : 
    2255         [ #  # ]:          0 :         if (args->pad != 0)
    2256                 :            :                 return -EINVAL;
    2257                 :            : 
    2258         [ #  # ]:          0 :         if (!args->ctx_id)
    2259                 :            :                 return -ENOENT;
    2260                 :            : 
    2261                 :          0 :         ctx = xa_erase(&file_priv->context_xa, args->ctx_id);
    2262         [ #  # ]:          0 :         if (!ctx)
    2263                 :            :                 return -ENOENT;
    2264                 :            : 
    2265                 :          0 :         context_close(ctx);
    2266                 :          0 :         return 0;
    2267                 :            : }
    2268                 :            : 
    2269                 :            : static int get_sseu(struct i915_gem_context *ctx,
    2270                 :            :                     struct drm_i915_gem_context_param *args)
    2271                 :            : {
    2272                 :            :         struct drm_i915_gem_context_param_sseu user_sseu;
    2273                 :            :         struct intel_context *ce;
    2274                 :            :         unsigned long lookup;
    2275                 :            :         int err;
    2276                 :            : 
    2277                 :            :         if (args->size == 0)
    2278                 :            :                 goto out;
    2279                 :            :         else if (args->size < sizeof(user_sseu))
    2280                 :            :                 return -EINVAL;
    2281                 :            : 
    2282                 :            :         if (copy_from_user(&user_sseu, u64_to_user_ptr(args->value),
    2283                 :            :                            sizeof(user_sseu)))
    2284                 :            :                 return -EFAULT;
    2285                 :            : 
    2286                 :            :         if (user_sseu.rsvd)
    2287                 :            :                 return -EINVAL;
    2288                 :            : 
    2289                 :            :         if (user_sseu.flags & ~(I915_CONTEXT_SSEU_FLAG_ENGINE_INDEX))
    2290                 :            :                 return -EINVAL;
    2291                 :            : 
    2292                 :            :         lookup = 0;
    2293                 :            :         if (user_sseu.flags & I915_CONTEXT_SSEU_FLAG_ENGINE_INDEX)
    2294                 :            :                 lookup |= LOOKUP_USER_INDEX;
    2295                 :            : 
    2296                 :            :         ce = lookup_user_engine(ctx, lookup, &user_sseu.engine);
    2297                 :            :         if (IS_ERR(ce))
    2298                 :            :                 return PTR_ERR(ce);
    2299                 :            : 
    2300                 :            :         err = intel_context_lock_pinned(ce); /* serialises with set_sseu */
    2301                 :            :         if (err) {
    2302                 :            :                 intel_context_put(ce);
    2303                 :            :                 return err;
    2304                 :            :         }
    2305                 :            : 
    2306                 :            :         user_sseu.slice_mask = ce->sseu.slice_mask;
    2307                 :            :         user_sseu.subslice_mask = ce->sseu.subslice_mask;
    2308                 :            :         user_sseu.min_eus_per_subslice = ce->sseu.min_eus_per_subslice;
    2309                 :            :         user_sseu.max_eus_per_subslice = ce->sseu.max_eus_per_subslice;
    2310                 :            : 
    2311                 :            :         intel_context_unlock_pinned(ce);
    2312                 :            :         intel_context_put(ce);
    2313                 :            : 
    2314                 :            :         if (copy_to_user(u64_to_user_ptr(args->value), &user_sseu,
    2315                 :            :                          sizeof(user_sseu)))
    2316                 :            :                 return -EFAULT;
    2317                 :            : 
    2318                 :            : out:
    2319                 :            :         args->size = sizeof(user_sseu);
    2320                 :            : 
    2321                 :            :         return 0;
    2322                 :            : }
    2323                 :            : 
    2324                 :          0 : int i915_gem_context_getparam_ioctl(struct drm_device *dev, void *data,
    2325                 :            :                                     struct drm_file *file)
    2326                 :            : {
    2327                 :          0 :         struct drm_i915_file_private *file_priv = file->driver_priv;
    2328                 :          0 :         struct drm_i915_gem_context_param *args = data;
    2329                 :          0 :         struct i915_gem_context *ctx;
    2330                 :          0 :         int ret = 0;
    2331                 :            : 
    2332                 :          0 :         ctx = i915_gem_context_lookup(file_priv, args->ctx_id);
    2333         [ #  # ]:          0 :         if (!ctx)
    2334                 :            :                 return -ENOENT;
    2335                 :            : 
    2336   [ #  #  #  #  :          0 :         switch (args->param) {
          #  #  #  #  #  
                   #  # ]
    2337                 :          0 :         case I915_CONTEXT_PARAM_NO_ZEROMAP:
    2338                 :          0 :                 args->size = 0;
    2339                 :          0 :                 args->value = test_bit(UCONTEXT_NO_ZEROMAP, &ctx->user_flags);
    2340                 :          0 :                 break;
    2341                 :            : 
    2342                 :          0 :         case I915_CONTEXT_PARAM_GTT_SIZE:
    2343                 :          0 :                 args->size = 0;
    2344                 :          0 :                 rcu_read_lock();
    2345         [ #  # ]:          0 :                 if (rcu_access_pointer(ctx->vm))
    2346                 :          0 :                         args->value = rcu_dereference(ctx->vm)->total;
    2347                 :            :                 else
    2348                 :          0 :                         args->value = to_i915(dev)->ggtt.vm.total;
    2349                 :          0 :                 rcu_read_unlock();
    2350                 :            :                 break;
    2351                 :            : 
    2352                 :          0 :         case I915_CONTEXT_PARAM_NO_ERROR_CAPTURE:
    2353                 :          0 :                 args->size = 0;
    2354                 :          0 :                 args->value = i915_gem_context_no_error_capture(ctx);
    2355                 :          0 :                 break;
    2356                 :            : 
    2357                 :          0 :         case I915_CONTEXT_PARAM_BANNABLE:
    2358                 :          0 :                 args->size = 0;
    2359                 :          0 :                 args->value = i915_gem_context_is_bannable(ctx);
    2360                 :          0 :                 break;
    2361                 :            : 
    2362                 :          0 :         case I915_CONTEXT_PARAM_RECOVERABLE:
    2363                 :          0 :                 args->size = 0;
    2364                 :          0 :                 args->value = i915_gem_context_is_recoverable(ctx);
    2365                 :          0 :                 break;
    2366                 :            : 
    2367                 :          0 :         case I915_CONTEXT_PARAM_PRIORITY:
    2368                 :          0 :                 args->size = 0;
    2369                 :          0 :                 args->value = ctx->sched.priority >> I915_USER_PRIORITY_SHIFT;
    2370                 :          0 :                 break;
    2371                 :            : 
    2372                 :          0 :         case I915_CONTEXT_PARAM_SSEU:
    2373                 :          0 :                 ret = get_sseu(ctx, args);
    2374                 :          0 :                 break;
    2375                 :            : 
    2376                 :          0 :         case I915_CONTEXT_PARAM_VM:
    2377                 :          0 :                 ret = get_ppgtt(file_priv, ctx, args);
    2378                 :          0 :                 break;
    2379                 :            : 
    2380                 :          0 :         case I915_CONTEXT_PARAM_ENGINES:
    2381                 :          0 :                 ret = get_engines(ctx, args);
    2382                 :          0 :                 break;
    2383                 :            : 
    2384                 :          0 :         case I915_CONTEXT_PARAM_PERSISTENCE:
    2385                 :          0 :                 args->size = 0;
    2386                 :          0 :                 args->value = i915_gem_context_is_persistent(ctx);
    2387                 :          0 :                 break;
    2388                 :            : 
    2389                 :            :         case I915_CONTEXT_PARAM_BAN_PERIOD:
    2390                 :            :         default:
    2391                 :            :                 ret = -EINVAL;
    2392                 :            :                 break;
    2393                 :            :         }
    2394                 :            : 
    2395                 :          0 :         i915_gem_context_put(ctx);
    2396                 :          0 :         return ret;
    2397                 :            : }
    2398                 :            : 
    2399                 :          0 : int i915_gem_context_setparam_ioctl(struct drm_device *dev, void *data,
    2400                 :            :                                     struct drm_file *file)
    2401                 :            : {
    2402                 :          0 :         struct drm_i915_file_private *file_priv = file->driver_priv;
    2403                 :          0 :         struct drm_i915_gem_context_param *args = data;
    2404                 :          0 :         struct i915_gem_context *ctx;
    2405                 :          0 :         int ret;
    2406                 :            : 
    2407                 :          0 :         ctx = i915_gem_context_lookup(file_priv, args->ctx_id);
    2408         [ #  # ]:          0 :         if (!ctx)
    2409                 :            :                 return -ENOENT;
    2410                 :            : 
    2411                 :          0 :         ret = ctx_setparam(file_priv, ctx, args);
    2412                 :            : 
    2413                 :          0 :         i915_gem_context_put(ctx);
    2414                 :          0 :         return ret;
    2415                 :            : }
    2416                 :            : 
    2417                 :          0 : int i915_gem_context_reset_stats_ioctl(struct drm_device *dev,
    2418                 :            :                                        void *data, struct drm_file *file)
    2419                 :            : {
    2420         [ #  # ]:          0 :         struct drm_i915_private *i915 = to_i915(dev);
    2421                 :          0 :         struct drm_i915_reset_stats *args = data;
    2422                 :          0 :         struct i915_gem_context *ctx;
    2423                 :          0 :         int ret;
    2424                 :            : 
    2425   [ #  #  #  # ]:          0 :         if (args->flags || args->pad)
    2426                 :            :                 return -EINVAL;
    2427                 :            : 
    2428                 :          0 :         ret = -ENOENT;
    2429                 :          0 :         rcu_read_lock();
    2430                 :          0 :         ctx = __i915_gem_context_lookup_rcu(file->driver_priv, args->ctx_id);
    2431         [ #  # ]:          0 :         if (!ctx)
    2432                 :          0 :                 goto out;
    2433                 :            : 
    2434                 :            :         /*
    2435                 :            :          * We opt for unserialised reads here. This may result in tearing
    2436                 :            :          * in the extremely unlikely event of a GPU hang on this context
    2437                 :            :          * as we are querying them. If we need that extra layer of protection,
    2438                 :            :          * we should wrap the hangstats with a seqlock.
    2439                 :            :          */
    2440                 :            : 
    2441         [ #  # ]:          0 :         if (capable(CAP_SYS_ADMIN))
    2442                 :          0 :                 args->reset_count = i915_reset_count(&i915->gpu_error);
    2443                 :            :         else
    2444                 :          0 :                 args->reset_count = 0;
    2445                 :            : 
    2446                 :          0 :         args->batch_active = atomic_read(&ctx->guilty_count);
    2447                 :          0 :         args->batch_pending = atomic_read(&ctx->active_count);
    2448                 :            : 
    2449                 :          0 :         ret = 0;
    2450                 :          0 : out:
    2451                 :          0 :         rcu_read_unlock();
    2452                 :          0 :         return ret;
    2453                 :            : }
    2454                 :            : 
    2455                 :            : /* GEM context-engines iterator: for_each_gem_engine() */
    2456                 :            : struct intel_context *
    2457                 :          0 : i915_gem_engines_iter_next(struct i915_gem_engines_iter *it)
    2458                 :            : {
    2459                 :          0 :         const struct i915_gem_engines *e = it->engines;
    2460                 :          0 :         struct intel_context *ctx;
    2461                 :            : 
    2462                 :          0 :         do {
    2463   [ #  #  #  #  :          0 :                 if (it->idx >= e->num_engines)
             #  #  #  # ]
    2464                 :            :                         return NULL;
    2465                 :            : 
    2466                 :          0 :                 ctx = e->engines[it->idx++];
    2467   [ #  #  #  #  :          0 :         } while (!ctx);
             #  #  #  # ]
    2468                 :            : 
    2469                 :            :         return ctx;
    2470                 :            : }
    2471                 :            : 
    2472                 :            : #if IS_ENABLED(CONFIG_DRM_I915_SELFTEST)
    2473                 :            : #include "selftests/mock_context.c"
    2474                 :            : #include "selftests/i915_gem_context.c"
    2475                 :            : #endif
    2476                 :            : 
    2477                 :          0 : static void i915_global_gem_context_shrink(void)
    2478                 :            : {
    2479                 :          0 :         kmem_cache_shrink(global.slab_luts);
    2480                 :          0 : }
    2481                 :            : 
    2482                 :          0 : static void i915_global_gem_context_exit(void)
    2483                 :            : {
    2484                 :          0 :         kmem_cache_destroy(global.slab_luts);
    2485                 :          0 : }
    2486                 :            : 
    2487                 :            : static struct i915_global_gem_context global = { {
    2488                 :            :         .shrink = i915_global_gem_context_shrink,
    2489                 :            :         .exit = i915_global_gem_context_exit,
    2490                 :            : } };
    2491                 :            : 
    2492                 :         21 : int __init i915_global_gem_context_init(void)
    2493                 :            : {
    2494                 :         21 :         global.slab_luts = KMEM_CACHE(i915_lut_handle, 0);
    2495         [ +  - ]:         21 :         if (!global.slab_luts)
    2496                 :            :                 return -ENOMEM;
    2497                 :            : 
    2498                 :         21 :         i915_global_register(&global.base);
    2499                 :         21 :         return 0;
    2500                 :            : }

Generated by: LCOV version 1.14