History

Merge tag 'drm-intel-fixes-2023-02-02' of git://anongit.freedesktop.org/drm/drm-intel into drm-fixes

- Fixes for potential use-after-free and double-free (Rob) - GuC locking and refcount fixes (John) - Display's reference clock value fix (Chaitanya) Signed-off-by: Dave Airlie <airlied@redhat.com>

Dave Airlie committed 3 years ago

Commit 74d6c8e2 parents abf301e 47a2bd911 files · +112 −76Browse files

Unified · Split

11 files
  1. drivers/gpu/drm/i915/display/intel_cdclk.c +1 −1
  2. drivers/gpu/drm/i915/gem/i915_gem_context.c +11 −3
  3. drivers/gpu/drm/i915/gem/i915_gem_tiling.c +5 −4
  4. drivers/gpu/drm/i915/gt/intel_context.c +3 −1
  5. drivers/gpu/drm/i915/gt/intel_context.h +1 −2
  6. drivers/gpu/drm/i915/gt/intel_engine.h +2 −2
  7. drivers/gpu/drm/i915/gt/intel_engine_cs.c +39 −35
  8. drivers/gpu/drm/i915/gt/intel_execlists_submission.c +27 −0
  9. drivers/gpu/drm/i915/gt/intel_execlists_submission.h +4 −0
  10. drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c +13 −1
  11. drivers/gpu/drm/i915/i915_gpu_error.c +6 −27
drivers/gpu/drm/i915/display/intel_cdclk.c+1−1
@@ -1319,7 +1319,7 @@ static const struct intel_cdclk_vals adlp_cdclk_table[] = { · 1318 unmodified lines
1319 { .refclk = 24000, .cdclk = 192000, .divider = 2, .ratio = 16 },1319 { .refclk = 24000, .cdclk = 192000, .divider = 2, .ratio = 16 },
1320 { .refclk = 24000, .cdclk = 312000, .divider = 2, .ratio = 26 },1320 { .refclk = 24000, .cdclk = 312000, .divider = 2, .ratio = 26 },
1321 { .refclk = 24000, .cdclk = 552000, .divider = 2, .ratio = 46 },1321 { .refclk = 24000, .cdclk = 552000, .divider = 2, .ratio = 46 },
1322 { .refclk = 24400, .cdclk = 648000, .divider = 2, .ratio = 54 },1322 { .refclk = 24000, .cdclk = 648000, .divider = 2, .ratio = 54 },
1323 1323
1324 { .refclk = 38400, .cdclk = 179200, .divider = 3, .ratio = 14 },1324 { .refclk = 38400, .cdclk = 179200, .divider = 3, .ratio = 14 },
1325 { .refclk = 38400, .cdclk = 192000, .divider = 2, .ratio = 10 },1325 { .refclk = 38400, .cdclk = 192000, .divider = 2, .ratio = 10 },
drivers/gpu/drm/i915/gem/i915_gem_context.c+11−3
@@ -1861,11 +1861,19 @@ static int get_ppgtt(struct drm_i915_file_private *file_priv, · 1860 unmodified lines
1861 vm = ctx->vm;1861 vm = ctx->vm;
1862 GEM_BUG_ON(!vm);1862 GEM_BUG_ON(!vm);
1863 1863
1864 /*
1865 * Get a reference for the allocated handle. Once the handle is
1866 * visible in the vm_xa table, userspace could try to close it
1867 * from under our feet, so we need to hold the extra reference
1868 * first.
1869 */
1870 i915_vm_get(vm);
1871
1864 err = xa_alloc(&file_priv->vm_xa, &id, vm, xa_limit_32b, GFP_KERNEL);1872 err = xa_alloc(&file_priv->vm_xa, &id, vm, xa_limit_32b, GFP_KERNEL);
1865 if (err)1873 if (err) {
1874 i915_vm_put(vm);
1866 return err;1875 return err;
1867 1876 }
1868 i915_vm_get(vm);
1869 1877
1870 GEM_BUG_ON(id == 0); /* reserved for invalid/unassigned ppgtt */1878 GEM_BUG_ON(id == 0); /* reserved for invalid/unassigned ppgtt */
1871 args->value = id;1879 args->value = id;
drivers/gpu/drm/i915/gem/i915_gem_tiling.c+5−4
@@ -305,10 +305,6 @@ i915_gem_object_set_tiling(struct drm_i915_gem_object *obj, · 304 unmodified lines
305 spin_unlock(&obj->vma.lock);305 spin_unlock(&obj->vma.lock);
306 306
307 obj->tiling_and_stride = tiling | stride;307 obj->tiling_and_stride = tiling | stride;
308 i915_gem_object_unlock(obj);
309
310 /* Force the fence to be reacquired for GTT access */
311 i915_gem_object_release_mmap_gtt(obj);
312 308
313 /* Try to preallocate memory required to save swizzling on put-pages */309 /* Try to preallocate memory required to save swizzling on put-pages */
314 if (i915_gem_object_needs_bit17_swizzle(obj)) {310 if (i915_gem_object_needs_bit17_swizzle(obj)) {
@@ -321,6 +317,11 @@ i915_gem_object_set_tiling(struct drm_i915_gem_object *obj, · 6 unmodified lines
321 obj->bit_17 = NULL;317 obj->bit_17 = NULL;
322 }318 }
323 319
320 i915_gem_object_unlock(obj);
321
322 /* Force the fence to be reacquired for GTT access */
323 i915_gem_object_release_mmap_gtt(obj);
324
324 return 0;325 return 0;
325}326}
326 327
drivers/gpu/drm/i915/gt/intel_context.c+3−1
@@ -528,7 +528,7 @@ retry: · 527 unmodified lines
528 return rq;528 return rq;
529}529}
530 530
531struct i915_request *intel_context_find_active_request(struct intel_context *ce)531struct i915_request *intel_context_get_active_request(struct intel_context *ce)
532{532{
533 struct intel_context *parent = intel_context_to_parent(ce);533 struct intel_context *parent = intel_context_to_parent(ce);
534 struct i915_request *rq, *active = NULL;534 struct i915_request *rq, *active = NULL;
@@ -552,6 +552,8 @@ struct i915_request *intel_context_find_active_request(struct intel_context *ce) · 17 unmodified lines
552 552
553 active = rq;553 active = rq;
554 }554 }
555 if (active)
556 active = i915_request_get_rcu(active);
555 spin_unlock_irqrestore(&parent->guc_state.lock, flags);557 spin_unlock_irqrestore(&parent->guc_state.lock, flags);
556 558
557 return active;559 return active;
drivers/gpu/drm/i915/gt/intel_context.h+1−2
@@ -268,8 +268,7 @@ int intel_context_prepare_remote_request(struct intel_context *ce, · 267 unmodified lines
268 268
269struct i915_request *intel_context_create_request(struct intel_context *ce);269struct i915_request *intel_context_create_request(struct intel_context *ce);
270 270
271struct i915_request *271struct i915_request *intel_context_get_active_request(struct intel_context *ce);
272intel_context_find_active_request(struct intel_context *ce);
273 272
274static inline bool intel_context_is_barrier(const struct intel_context *ce)273static inline bool intel_context_is_barrier(const struct intel_context *ce)
275{274{
drivers/gpu/drm/i915/gt/intel_engine.h+2−2
@@ -248,8 +248,8 @@ void intel_engine_dump_active_requests(struct list_head *requests, · 247 unmodified lines
248ktime_t intel_engine_get_busy_time(struct intel_engine_cs *engine,248ktime_t intel_engine_get_busy_time(struct intel_engine_cs *engine,
249 ktime_t *now);249 ktime_t *now);
250 250
251struct i915_request *251void intel_engine_get_hung_entity(struct intel_engine_cs *engine,
252intel_engine_execlist_find_hung_request(struct intel_engine_cs *engine);252 struct intel_context **ce, struct i915_request **rq);
253 253
254u32 intel_engine_context_size(struct intel_gt *gt, u8 class);254u32 intel_engine_context_size(struct intel_gt *gt, u8 class);
255struct intel_context *255struct intel_context *
drivers/gpu/drm/i915/gt/intel_engine_cs.c+39−35
@@ -2094,17 +2094,6 @@ static void print_request_ring(struct drm_printer *m, struct i915_request *rq) · 2093 unmodified lines
2094 }2094 }
2095}2095}
2096 2096
2097static unsigned long list_count(struct list_head *list)
2098{
2099 struct list_head *pos;
2100 unsigned long count = 0;
2101
2102 list_for_each(pos, list)
2103 count++;
2104
2105 return count;
2106}
2107
2108static unsigned long read_ul(void *p, size_t x)2097static unsigned long read_ul(void *p, size_t x)
2109{2098{
2110 return *(unsigned long *)(p + x);2099 return *(unsigned long *)(p + x);
@@ -2196,11 +2185,11 @@ void intel_engine_dump_active_requests(struct list_head *requests, · 85 unmodified lines
2196 }2185 }
2197}2186}
2198 2187
2199static void engine_dump_active_requests(struct intel_engine_cs *engine, struct drm_printer *m)2188static void engine_dump_active_requests(struct intel_engine_cs *engine,
2189 struct drm_printer *m)
2200{2190{
2191 struct intel_context *hung_ce = NULL;
2201 struct i915_request *hung_rq = NULL;2192 struct i915_request *hung_rq = NULL;
2202 struct intel_context *ce;
2203 bool guc;
2204 2193
2205 /*2194 /*
2206 * No need for an engine->irq_seqno_barrier() before the seqno reads.2195 * No need for an engine->irq_seqno_barrier() before the seqno reads.
@@ -2209,27 +2198,22 @@ static void engine_dump_active_requests(struct intel_engine_cs *engine, struct d · 2 unmodified lines
2209 * But the intention here is just to report an instantaneous snapshot2198 * But the intention here is just to report an instantaneous snapshot
2210 * so that's fine.2199 * so that's fine.
2211 */2200 */
2212 lockdep_assert_held(&engine->sched_engine->lock);2201 intel_engine_get_hung_entity(engine, &hung_ce, &hung_rq);
2213 2202
2214 drm_printf(m, "\tRequests:\n");2203 drm_printf(m, "\tRequests:\n");
2215 2204
2216 guc = intel_uc_uses_guc_submission(&engine->gt->uc);
2217 if (guc) {
2218 ce = intel_engine_get_hung_context(engine);
2219 if (ce)
2220 hung_rq = intel_context_find_active_request(ce);
2221 } else {
2222 hung_rq = intel_engine_execlist_find_hung_request(engine);
2223 }
2224
2225 if (hung_rq)2205 if (hung_rq)
2226 engine_dump_request(hung_rq, m, "\t\thung");2206 engine_dump_request(hung_rq, m, "\t\thung");
2207 else if (hung_ce)
2208 drm_printf(m, "\t\tGot hung ce but no hung rq!\n");
2227 2209
2228 if (guc)2210 if (intel_uc_uses_guc_submission(&engine->gt->uc))
2229 intel_guc_dump_active_requests(engine, hung_rq, m);2211 intel_guc_dump_active_requests(engine, hung_rq, m);
2230 else2212 else
2231 intel_engine_dump_active_requests(&engine->sched_engine->requests,2213 intel_execlists_dump_active_requests(engine, hung_rq, m);
2232 hung_rq, m);2214
2215 if (hung_rq)
2216 i915_request_put(hung_rq);
2233}2217}
2234 2218
2235void intel_engine_dump(struct intel_engine_cs *engine,2219void intel_engine_dump(struct intel_engine_cs *engine,
@@ -2239,7 +2223,6 @@ void intel_engine_dump(struct intel_engine_cs *engine, · 3 unmodified lines
2239 struct i915_gpu_error * const error = &engine->i915->gpu_error;2223 struct i915_gpu_error * const error = &engine->i915->gpu_error;
2240 struct i915_request *rq;2224 struct i915_request *rq;
2241 intel_wakeref_t wakeref;2225 intel_wakeref_t wakeref;
2242 unsigned long flags;
2243 ktime_t dummy;2226 ktime_t dummy;
2244 2227
2245 if (header) {2228 if (header) {
@@ -2276,13 +2259,8 @@ void intel_engine_dump(struct intel_engine_cs *engine, · 30 unmodified lines
2276 i915_reset_count(error));2259 i915_reset_count(error));
2277 print_properties(engine, m);2260 print_properties(engine, m);
2278 2261
2279 spin_lock_irqsave(&engine->sched_engine->lock, flags);
2280 engine_dump_active_requests(engine, m);2262 engine_dump_active_requests(engine, m);
2281 2263
2282 drm_printf(m, "\tOn hold?: %lu\n",
2283 list_count(&engine->sched_engine->hold));
2284 spin_unlock_irqrestore(&engine->sched_engine->lock, flags);
2285
2286 drm_printf(m, "\tMMIO base: 0x%08x\n", engine->mmio_base);2264 drm_printf(m, "\tMMIO base: 0x%08x\n", engine->mmio_base);
2287 wakeref = intel_runtime_pm_get_if_in_use(engine->uncore->rpm);2265 wakeref = intel_runtime_pm_get_if_in_use(engine->uncore->rpm);
2288 if (wakeref) {2266 if (wakeref) {
@@ -2328,8 +2306,7 @@ intel_engine_create_virtual(struct intel_engine_cs **siblings, · 39 unmodified lines
2328 return siblings[0]->cops->create_virtual(siblings, count, flags);2306 return siblings[0]->cops->create_virtual(siblings, count, flags);
2329}2307}
2330 2308
2331struct i915_request *2309static struct i915_request *engine_execlist_find_hung_request(struct intel_engine_cs *engine)
2332intel_engine_execlist_find_hung_request(struct intel_engine_cs *engine)
2333{2310{
2334 struct i915_request *request, *active = NULL;2311 struct i915_request *request, *active = NULL;
2335 2312
@@ -2381,6 +2358,33 @@ intel_engine_execlist_find_hung_request(struct intel_engine_cs *engine) · 45 unmodified lines
2381 return active;2358 return active;
2382}2359}
2383 2360
2361void intel_engine_get_hung_entity(struct intel_engine_cs *engine,
2362 struct intel_context **ce, struct i915_request **rq)
2363{
2364 unsigned long flags;
2365
2366 *ce = intel_engine_get_hung_context(engine);
2367 if (*ce) {
2368 intel_engine_clear_hung_context(engine);
2369
2370 *rq = intel_context_get_active_request(*ce);
2371 return;
2372 }
2373
2374 /*
2375 * Getting here with GuC enabled means it is a forced error capture
2376 * with no actual hang. So, no need to attempt the execlist search.
2377 */
2378 if (intel_uc_uses_guc_submission(&engine->gt->uc))
2379 return;
2380
2381 spin_lock_irqsave(&engine->sched_engine->lock, flags);
2382 *rq = engine_execlist_find_hung_request(engine);
2383 if (*rq)
2384 *rq = i915_request_get_rcu(*rq);
2385 spin_unlock_irqrestore(&engine->sched_engine->lock, flags);
2386}
2387
2384void xehp_enable_ccs_engines(struct intel_engine_cs *engine)2388void xehp_enable_ccs_engines(struct intel_engine_cs *engine)
2385{2389{
2386 /*2390 /*
drivers/gpu/drm/i915/gt/intel_execlists_submission.c+27−0
@@ -4148,6 +4148,33 @@ void intel_execlists_show_requests(struct intel_engine_cs *engine, · 4147 unmodified lines
4148 spin_unlock_irqrestore(&sched_engine->lock, flags);4148 spin_unlock_irqrestore(&sched_engine->lock, flags);
4149}4149}
4150 4150
4151static unsigned long list_count(struct list_head *list)
4152{
4153 struct list_head *pos;
4154 unsigned long count = 0;
4155
4156 list_for_each(pos, list)
4157 count++;
4158
4159 return count;
4160}
4161
4162void intel_execlists_dump_active_requests(struct intel_engine_cs *engine,
4163 struct i915_request *hung_rq,
4164 struct drm_printer *m)
4165{
4166 unsigned long flags;
4167
4168 spin_lock_irqsave(&engine->sched_engine->lock, flags);
4169
4170 intel_engine_dump_active_requests(&engine->sched_engine->requests, hung_rq, m);
4171
4172 drm_printf(m, "\tOn hold?: %lu\n",
4173 list_count(&engine->sched_engine->hold));
4174
4175 spin_unlock_irqrestore(&engine->sched_engine->lock, flags);
4176}
4177
4151#if IS_ENABLED(CONFIG_DRM_I915_SELFTEST)4178#if IS_ENABLED(CONFIG_DRM_I915_SELFTEST)
4152#include "selftest_execlists.c"4179#include "selftest_execlists.c"
4153#endif4180#endif
drivers/gpu/drm/i915/gt/intel_execlists_submission.h+4−0
@@ -32,6 +32,10 @@ void intel_execlists_show_requests(struct intel_engine_cs *engine, · 31 unmodified lines
32 int indent),32 int indent),
33 unsigned int max);33 unsigned int max);
34 34
35void intel_execlists_dump_active_requests(struct intel_engine_cs *engine,
36 struct i915_request *hung_rq,
37 struct drm_printer *m);
38
35bool39bool
36intel_engine_in_execlists_submission_mode(const struct intel_engine_cs *engine);40intel_engine_in_execlists_submission_mode(const struct intel_engine_cs *engine);
37 41
drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c+13−1
@@ -1702,7 +1702,7 @@ static void __guc_reset_context(struct intel_context *ce, intel_engine_mask_t st · 1701 unmodified lines
1702 goto next_context;1702 goto next_context;
1703 1703
1704 guilty = false;1704 guilty = false;
1705 rq = intel_context_find_active_request(ce);1705 rq = intel_context_get_active_request(ce);
1706 if (!rq) {1706 if (!rq) {
1707 head = ce->ring->tail;1707 head = ce->ring->tail;
1708 goto out_replay;1708 goto out_replay;
@@ -1715,6 +1715,7 @@ static void __guc_reset_context(struct intel_context *ce, intel_engine_mask_t st · 6 unmodified lines
1715 head = intel_ring_wrap(ce->ring, rq->head);1715 head = intel_ring_wrap(ce->ring, rq->head);
1716 1716
1717 __i915_request_reset(rq, guilty);1717 __i915_request_reset(rq, guilty);
1718 i915_request_put(rq);
1718out_replay:1719out_replay:
1719 guc_reset_state(ce, head, guilty);1720 guc_reset_state(ce, head, guilty);
1720next_context:1721next_context:
@@ -4817,6 +4818,8 @@ void intel_guc_find_hung_context(struct intel_engine_cs *engine) · 3096 unmodified lines
4817 4818
4818 xa_lock_irqsave(&guc->context_lookup, flags);4819 xa_lock_irqsave(&guc->context_lookup, flags);
4819 xa_for_each(&guc->context_lookup, index, ce) {4820 xa_for_each(&guc->context_lookup, index, ce) {
4821 bool found;
4822
4820 if (!kref_get_unless_zero(&ce->ref))4823 if (!kref_get_unless_zero(&ce->ref))
4821 continue;4824 continue;
4822 4825
@@ -4833,10 +4836,18 @@ void intel_guc_find_hung_context(struct intel_engine_cs *engine) · 10 unmodified lines
4833 goto next;4836 goto next;
4834 }4837 }
4835 4838
4839 found = false;
4840 spin_lock(&ce->guc_state.lock);
4836 list_for_each_entry(rq, &ce->guc_state.requests, sched.link) {4841 list_for_each_entry(rq, &ce->guc_state.requests, sched.link) {
4837 if (i915_test_request_state(rq) != I915_REQUEST_ACTIVE)4842 if (i915_test_request_state(rq) != I915_REQUEST_ACTIVE)
4838 continue;4843 continue;
4839 4844
4845 found = true;
4846 break;
4847 }
4848 spin_unlock(&ce->guc_state.lock);
4849
4850 if (found) {
4840 intel_engine_set_hung_context(engine, ce);4851 intel_engine_set_hung_context(engine, ce);
4841 4852
4842 /* Can only cope with one hang at a time... */4853 /* Can only cope with one hang at a time... */
@@ -4844,6 +4855,7 @@ void intel_guc_find_hung_context(struct intel_engine_cs *engine) · 1 unmodified line
4844 xa_lock(&guc->context_lookup);4855 xa_lock(&guc->context_lookup);
4845 goto done;4856 goto done;
4846 }4857 }
4858
4847next:4859next:
4848 intel_context_put(ce);4860 intel_context_put(ce);
4849 xa_lock(&guc->context_lookup);4861 xa_lock(&guc->context_lookup);
drivers/gpu/drm/i915/i915_gpu_error.c+6−27
@@ -1596,43 +1596,20 @@ capture_engine(struct intel_engine_cs *engine, · 1595 unmodified lines
1596{1596{
1597 struct intel_engine_capture_vma *capture = NULL;1597 struct intel_engine_capture_vma *capture = NULL;
1598 struct intel_engine_coredump *ee;1598 struct intel_engine_coredump *ee;
1599 struct intel_context *ce;1599 struct intel_context *ce = NULL;
1600 struct i915_request *rq = NULL;1600 struct i915_request *rq = NULL;
1601 unsigned long flags;
1602 1601
1603 ee = intel_engine_coredump_alloc(engine, ALLOW_FAIL, dump_flags);1602 ee = intel_engine_coredump_alloc(engine, ALLOW_FAIL, dump_flags);
1604 if (!ee)1603 if (!ee)
1605 return NULL;1604 return NULL;
1606 1605
1607 ce = intel_engine_get_hung_context(engine);1606 intel_engine_get_hung_entity(engine, &ce, &rq);
1608 if (ce) {1607 if (!rq || !i915_request_started(rq))
1609 intel_engine_clear_hung_context(engine);
1610 rq = intel_context_find_active_request(ce);
1611 if (!rq || !i915_request_started(rq))
1612 goto no_request_capture;
1613 } else {
1614 /*
1615 * Getting here with GuC enabled means it is a forced error capture
1616 * with no actual hang. So, no need to attempt the execlist search.
1617 */
1618 if (!intel_uc_uses_guc_submission(&engine->gt->uc)) {
1619 spin_lock_irqsave(&engine->sched_engine->lock, flags);
1620 rq = intel_engine_execlist_find_hung_request(engine);
1621 spin_unlock_irqrestore(&engine->sched_engine->lock,
1622 flags);
1623 }
1624 }
1625 if (rq)
1626 rq = i915_request_get_rcu(rq);
1627
1628 if (!rq)
1629 goto no_request_capture;1608 goto no_request_capture;
1630 1609
1631 capture = intel_engine_coredump_add_request(ee, rq, ATOMIC_MAYFAIL);1610 capture = intel_engine_coredump_add_request(ee, rq, ATOMIC_MAYFAIL);
1632 if (!capture) {1611 if (!capture)
1633 i915_request_put(rq);
1634 goto no_request_capture;1612 goto no_request_capture;
1635 }
1636 if (dump_flags & CORE_DUMP_FLAG_IS_GUC_CAPTURE)1613 if (dump_flags & CORE_DUMP_FLAG_IS_GUC_CAPTURE)
1637 intel_guc_capture_get_matching_node(engine->gt, ee, ce);1614 intel_guc_capture_get_matching_node(engine->gt, ee, ce);
1638 1615
@@ -1642,6 +1619,8 @@ capture_engine(struct intel_engine_cs *engine, · 3 unmodified lines
1642 return ee;1619 return ee;
1643 1620
1644no_request_capture:1621no_request_capture:
1622 if (rq)
1623 i915_request_put(rq);
1645 kfree(ee);1624 kfree(ee);
1646 return NULL;1625 return NULL;
1647}1626}