Skip to content

Commit 3f53d7e

Browse files
committed
Merge tag 'drm-intel-gt-next-2024-08-23' of https://gitlab.freedesktop.org/drm/i915/kernel into drm-next
UAPI Changes: - Limit the number of relocations to INT_MAX (Tvrtko) Only impact should be synthetic tests. Driver Changes: - Fix for #11396: GPU Hang and rcs0 reset on Cherrytrail platform - Fix Virtual Memory mapping boundaries calculation (Andi) - Fix for #11255: Long hangs in buddy allocator with DG2/A380 without Resizable BAR since 6.9 (David) - Mark the GT as dead when mmio is unreliable (Chris, Andi) - Workaround additions / fixes for MTL, ARL and DG2 (John H, Nitin) - Enable partial memory mapping of GPU virtual memory (Andi, Chris) - Prevent NULL deref on intel_memory_regions_hw_probe (Jonathan, Dan) - Avoid UAF on intel_engines_release (Krzysztof) - Don't update PWR_CLK_STATE starting Gen12 (Umesh) - Code and dmesg cleanups (Andi, Jesus, Luca) Signed-off-by: Daniel Vetter <[email protected]> From: Joonas Lahtinen <[email protected]> Link: https://patchwork.freedesktop.org/patch/msgid/[email protected]
2 parents f9ae00b + 255fc17 commit 3f53d7e

20 files changed

+145
-41
lines changed

drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1533,7 +1533,7 @@ static int eb_relocate_vma(struct i915_execbuffer *eb, struct eb_vma *ev)
15331533
u64_to_user_ptr(entry->relocs_ptr);
15341534
unsigned long remain = entry->relocation_count;
15351535

1536-
if (unlikely(remain > N_RELOC(ULONG_MAX)))
1536+
if (unlikely(remain > N_RELOC(INT_MAX)))
15371537
return -EINVAL;
15381538

15391539
/*
@@ -1641,7 +1641,7 @@ static int check_relocations(const struct drm_i915_gem_exec_object2 *entry)
16411641
if (size == 0)
16421642
return 0;
16431643

1644-
if (size > N_RELOC(ULONG_MAX))
1644+
if (size > N_RELOC(INT_MAX))
16451645
return -EINVAL;
16461646

16471647
addr = u64_to_user_ptr(entry->relocs_ptr);

drivers/gpu/drm/i915/gem/i915_gem_mman.c

Lines changed: 63 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,7 @@ static vm_fault_t vm_fault_cpu(struct vm_fault *vmf)
252252
struct vm_area_struct *area = vmf->vma;
253253
struct i915_mmap_offset *mmo = area->vm_private_data;
254254
struct drm_i915_gem_object *obj = mmo->obj;
255+
unsigned long obj_offset;
255256
resource_size_t iomap;
256257
int err;
257258

@@ -273,10 +274,11 @@ static vm_fault_t vm_fault_cpu(struct vm_fault *vmf)
273274
iomap -= obj->mm.region->region.start;
274275
}
275276

277+
obj_offset = area->vm_pgoff - drm_vma_node_start(&mmo->vma_node);
276278
/* PTEs are revoked in obj->ops->put_pages() */
277279
err = remap_io_sg(area,
278280
area->vm_start, area->vm_end - area->vm_start,
279-
obj->mm.pages->sgl, iomap);
281+
obj->mm.pages->sgl, obj_offset, iomap);
280282

281283
if (area->vm_flags & VM_WRITE) {
282284
GEM_BUG_ON(!i915_gem_object_has_pinned_pages(obj));
@@ -290,6 +292,47 @@ static vm_fault_t vm_fault_cpu(struct vm_fault *vmf)
290292
return i915_error_to_vmf_fault(err);
291293
}
292294

295+
static void set_address_limits(struct vm_area_struct *area,
296+
struct i915_vma *vma,
297+
unsigned long obj_offset,
298+
resource_size_t gmadr_start,
299+
unsigned long *start_vaddr,
300+
unsigned long *end_vaddr,
301+
unsigned long *pfn)
302+
{
303+
unsigned long vm_start, vm_end, vma_size; /* user's memory parameters */
304+
long start, end; /* memory boundaries */
305+
306+
/*
307+
* Let's move into the ">> PAGE_SHIFT"
308+
* domain to be sure not to lose bits
309+
*/
310+
vm_start = area->vm_start >> PAGE_SHIFT;
311+
vm_end = area->vm_end >> PAGE_SHIFT;
312+
vma_size = vma->size >> PAGE_SHIFT;
313+
314+
/*
315+
* Calculate the memory boundaries by considering the offset
316+
* provided by the user during memory mapping and the offset
317+
* provided for the partial mapping.
318+
*/
319+
start = vm_start;
320+
start -= obj_offset;
321+
start += vma->gtt_view.partial.offset;
322+
end = start + vma_size;
323+
324+
start = max_t(long, start, vm_start);
325+
end = min_t(long, end, vm_end);
326+
327+
/* Let's move back into the "<< PAGE_SHIFT" domain */
328+
*start_vaddr = (unsigned long)start << PAGE_SHIFT;
329+
*end_vaddr = (unsigned long)end << PAGE_SHIFT;
330+
331+
*pfn = (gmadr_start + i915_ggtt_offset(vma)) >> PAGE_SHIFT;
332+
*pfn += (*start_vaddr - area->vm_start) >> PAGE_SHIFT;
333+
*pfn += obj_offset - vma->gtt_view.partial.offset;
334+
}
335+
293336
static vm_fault_t vm_fault_gtt(struct vm_fault *vmf)
294337
{
295338
#define MIN_CHUNK_PAGES (SZ_1M >> PAGE_SHIFT)
@@ -302,14 +345,18 @@ static vm_fault_t vm_fault_gtt(struct vm_fault *vmf)
302345
struct i915_ggtt *ggtt = to_gt(i915)->ggtt;
303346
bool write = area->vm_flags & VM_WRITE;
304347
struct i915_gem_ww_ctx ww;
348+
unsigned long obj_offset;
349+
unsigned long start, end; /* memory boundaries */
305350
intel_wakeref_t wakeref;
306351
struct i915_vma *vma;
307352
pgoff_t page_offset;
353+
unsigned long pfn;
308354
int srcu;
309355
int ret;
310356

311-
/* We don't use vmf->pgoff since that has the fake offset */
357+
obj_offset = area->vm_pgoff - drm_vma_node_start(&mmo->vma_node);
312358
page_offset = (vmf->address - area->vm_start) >> PAGE_SHIFT;
359+
page_offset += obj_offset;
313360

314361
trace_i915_gem_object_fault(obj, page_offset, true, write);
315362

@@ -402,12 +449,16 @@ static vm_fault_t vm_fault_gtt(struct vm_fault *vmf)
402449
if (ret)
403450
goto err_unpin;
404451

452+
/*
453+
* Dump all the necessary parameters in this function to perform the
454+
* arithmetic calculation for the virtual address start and end and
455+
* the PFN (Page Frame Number).
456+
*/
457+
set_address_limits(area, vma, obj_offset, ggtt->gmadr.start,
458+
&start, &end, &pfn);
459+
405460
/* Finally, remap it using the new GTT offset */
406-
ret = remap_io_mapping(area,
407-
area->vm_start + (vma->gtt_view.partial.offset << PAGE_SHIFT),
408-
(ggtt->gmadr.start + i915_ggtt_offset(vma)) >> PAGE_SHIFT,
409-
min_t(u64, vma->size, area->vm_end - area->vm_start),
410-
&ggtt->iomap);
461+
ret = remap_io_mapping(area, start, pfn, end - start, &ggtt->iomap);
411462
if (ret)
412463
goto err_fence;
413464

@@ -1030,9 +1081,9 @@ int i915_gem_mmap(struct file *filp, struct vm_area_struct *vma)
10301081

10311082
rcu_read_lock();
10321083
drm_vma_offset_lock_lookup(dev->vma_offset_manager);
1033-
node = drm_vma_offset_exact_lookup_locked(dev->vma_offset_manager,
1034-
vma->vm_pgoff,
1035-
vma_pages(vma));
1084+
node = drm_vma_offset_lookup_locked(dev->vma_offset_manager,
1085+
vma->vm_pgoff,
1086+
vma_pages(vma));
10361087
if (node && drm_vma_node_is_allowed(node, priv)) {
10371088
/*
10381089
* Skip 0-refcnted objects as it is in the process of being
@@ -1084,6 +1135,8 @@ int i915_gem_fb_mmap(struct drm_i915_gem_object *obj, struct vm_area_struct *vma
10841135
mmo = mmap_offset_attach(obj, mmap_type, NULL);
10851136
if (IS_ERR(mmo))
10861137
return PTR_ERR(mmo);
1138+
1139+
vma->vm_pgoff += drm_vma_node_start(&mmo->vma_node);
10871140
}
10881141

10891142
/*

drivers/gpu/drm/i915/gem/i915_gem_object_types.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -535,7 +535,7 @@ struct drm_i915_gem_object {
535535
* I915_CACHE_NONE. The only exception is userptr objects, where we
536536
* instead force I915_CACHE_LLC, but we also don't allow userspace to
537537
* ever change the @cache_level for such objects. Another special case
538-
* is dma-buf, which doesn't rely on @cache_dirty, but there we
538+
* is dma-buf, which doesn't rely on @cache_dirty, but there we
539539
* always do a forced flush when acquiring the pages, if there is a
540540
* chance that the pages can be read directly from main memory with
541541
* the GPU.

drivers/gpu/drm/i915/gem/i915_gem_ttm.c

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,6 @@ i915_ttm_placement_from_obj(const struct drm_i915_gem_object *obj,
165165
i915_ttm_place_from_region(num_allowed ? obj->mm.placements[0] :
166166
obj->mm.region, &places[0], obj->bo_offset,
167167
obj->base.size, flags);
168-
places[0].flags |= TTM_PL_FLAG_DESIRED;
169168

170169
/* Cache this on object? */
171170
for (i = 0; i < num_allowed; ++i) {
@@ -779,13 +778,16 @@ static int __i915_ttm_get_pages(struct drm_i915_gem_object *obj,
779778
.interruptible = true,
780779
.no_wait_gpu = false,
781780
};
782-
int real_num_busy;
781+
struct ttm_placement initial_placement;
782+
struct ttm_place initial_place;
783783
int ret;
784784

785785
/* First try only the requested placement. No eviction. */
786-
real_num_busy = placement->num_placement;
787-
placement->num_placement = 1;
788-
ret = ttm_bo_validate(bo, placement, &ctx);
786+
initial_placement.num_placement = 1;
787+
memcpy(&initial_place, placement->placement, sizeof(struct ttm_place));
788+
initial_place.flags |= TTM_PL_FLAG_DESIRED;
789+
initial_placement.placement = &initial_place;
790+
ret = ttm_bo_validate(bo, &initial_placement, &ctx);
789791
if (ret) {
790792
ret = i915_ttm_err_to_gem(ret);
791793
/*
@@ -800,7 +802,6 @@ static int __i915_ttm_get_pages(struct drm_i915_gem_object *obj,
800802
* If the initial attempt fails, allow all accepted placements,
801803
* evicting if necessary.
802804
*/
803-
placement->num_placement = real_num_busy;
804805
ret = ttm_bo_validate(bo, placement, &ctx);
805806
if (ret)
806807
return i915_ttm_err_to_gem(ret);

drivers/gpu/drm/i915/gt/intel_engine_cs.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -693,6 +693,8 @@ void intel_engines_release(struct intel_gt *gt)
693693

694694
memset(&engine->reset, 0, sizeof(engine->reset));
695695
}
696+
697+
llist_del_all(&gt->i915->uabi_engines_llist);
696698
}
697699

698700
void intel_engine_free_request_pool(struct intel_engine_cs *engine)

drivers/gpu/drm/i915/gt/intel_gpu_commands.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,7 @@
220220
#define GFX_OP_DESTBUFFER_INFO ((0x3<<29)|(0x1d<<24)|(0x8e<<16)|1)
221221
#define GFX_OP_DRAWRECT_INFO ((0x3<<29)|(0x1d<<24)|(0x80<<16)|(0x3))
222222
#define GFX_OP_DRAWRECT_INFO_I965 ((0x7900<<16)|0x2)
223+
#define CMD_3DSTATE_MESH_CONTROL ((0x3 << 29) | (0x3 << 27) | (0x0 << 24) | (0x77 << 16) | (0x3))
223224

224225
#define XY_CTRL_SURF_INSTR_SIZE 5
225226
#define MI_FLUSH_DW_SIZE 3

drivers/gpu/drm/i915/gt/intel_gt.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,6 @@ static inline bool intel_gt_is_wedged(const struct intel_gt *gt)
174174

175175
int intel_gt_probe_all(struct drm_i915_private *i915);
176176
int intel_gt_tiles_init(struct drm_i915_private *i915);
177-
void intel_gt_release_all(struct drm_i915_private *i915);
178177

179178
#define for_each_gt(gt__, i915__, id__) \
180179
for ((id__) = 0; \
@@ -208,4 +207,10 @@ enum i915_map_type intel_gt_coherent_map_type(struct intel_gt *gt,
208207
void intel_gt_bind_context_set_ready(struct intel_gt *gt);
209208
void intel_gt_bind_context_set_unready(struct intel_gt *gt);
210209
bool intel_gt_is_bind_context_ready(struct intel_gt *gt);
210+
211+
static inline void intel_gt_set_wedged_async(struct intel_gt *gt)
212+
{
213+
queue_work(system_highpri_wq, &gt->wedge);
214+
}
215+
211216
#endif /* __INTEL_GT_H__ */

drivers/gpu/drm/i915/gt/intel_gt_types.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -292,6 +292,8 @@ struct intel_gt {
292292
struct gt_defaults defaults;
293293
struct kobject *sysfs_defaults;
294294

295+
struct work_struct wedge;
296+
295297
struct i915_perf_gt perf;
296298

297299
/** link: &ggtt.gt_list */

drivers/gpu/drm/i915/gt/intel_reset.c

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1013,6 +1013,15 @@ static void __intel_gt_set_wedged(struct intel_gt *gt)
10131013
GT_TRACE(gt, "end\n");
10141014
}
10151015

1016+
static void set_wedged_work(struct work_struct *w)
1017+
{
1018+
struct intel_gt *gt = container_of(w, struct intel_gt, wedge);
1019+
intel_wakeref_t wf;
1020+
1021+
with_intel_runtime_pm(gt->uncore->rpm, wf)
1022+
__intel_gt_set_wedged(gt);
1023+
}
1024+
10161025
void intel_gt_set_wedged(struct intel_gt *gt)
10171026
{
10181027
intel_wakeref_t wakeref;
@@ -1614,6 +1623,7 @@ void intel_gt_init_reset(struct intel_gt *gt)
16141623
init_waitqueue_head(&gt->reset.queue);
16151624
mutex_init(&gt->reset.mutex);
16161625
init_srcu_struct(&gt->reset.backoff_srcu);
1626+
INIT_WORK(&gt->wedge, set_wedged_work);
16171627

16181628
/*
16191629
* While undesirable to wait inside the shrinker, complain anyway.
@@ -1640,7 +1650,7 @@ static void intel_wedge_me(struct work_struct *work)
16401650
struct intel_wedge_me *w = container_of(work, typeof(*w), work.work);
16411651

16421652
gt_err(w->gt, "%s timed out, cancelling all in-flight rendering.\n", w->name);
1643-
intel_gt_set_wedged(w->gt);
1653+
set_wedged_work(&w->gt->wedge);
16441654
}
16451655

16461656
void __intel_init_wedge(struct intel_wedge_me *w,

drivers/gpu/drm/i915/gt/intel_workarounds.c

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -974,7 +974,12 @@ int intel_engine_emit_ctx_wa(struct i915_request *rq)
974974
if (ret)
975975
return ret;
976976

977-
cs = intel_ring_begin(rq, (wal->count * 2 + 2));
977+
if ((IS_GFX_GT_IP_RANGE(rq->engine->gt, IP_VER(12, 70), IP_VER(12, 74)) ||
978+
IS_DG2(rq->i915)) && rq->engine->class == RENDER_CLASS)
979+
cs = intel_ring_begin(rq, (wal->count * 2 + 6));
980+
else
981+
cs = intel_ring_begin(rq, (wal->count * 2 + 2));
982+
978983
if (IS_ERR(cs))
979984
return PTR_ERR(cs);
980985

@@ -1004,6 +1009,15 @@ int intel_engine_emit_ctx_wa(struct i915_request *rq)
10041009
}
10051010
*cs++ = MI_NOOP;
10061011

1012+
/* Wa_14019789679 */
1013+
if ((IS_GFX_GT_IP_RANGE(rq->engine->gt, IP_VER(12, 70), IP_VER(12, 74)) ||
1014+
IS_DG2(rq->i915)) && rq->engine->class == RENDER_CLASS) {
1015+
*cs++ = CMD_3DSTATE_MESH_CONTROL;
1016+
*cs++ = 0;
1017+
*cs++ = 0;
1018+
*cs++ = MI_NOOP;
1019+
}
1020+
10071021
intel_uncore_forcewake_put__locked(uncore, fw);
10081022
spin_unlock(&uncore->lock);
10091023
intel_gt_mcr_unlock(wal->gt, flags);

0 commit comments

Comments
 (0)