Commit 3f53d7e4 authored by Simona Vetter's avatar Simona Vetter
Browse files

Merge tag 'drm-intel-gt-next-2024-08-23' of...

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: default avatarDaniel Vetter <daniel.vetter@ffwll.ch>
From: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/ZshcfSqgfnl8Mh4P@jlahtine-mobl.ger.corp.intel.com
parents f9ae00b1 255fc170
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -1533,7 +1533,7 @@ static int eb_relocate_vma(struct i915_execbuffer *eb, struct eb_vma *ev)
		u64_to_user_ptr(entry->relocs_ptr);
	unsigned long remain = entry->relocation_count;

	if (unlikely(remain > N_RELOC(ULONG_MAX)))
	if (unlikely(remain > N_RELOC(INT_MAX)))
		return -EINVAL;

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

	if (size > N_RELOC(ULONG_MAX))
	if (size > N_RELOC(INT_MAX))
		return -EINVAL;

	addr = u64_to_user_ptr(entry->relocs_ptr);
+63 −10
Original line number Diff line number Diff line
@@ -252,6 +252,7 @@ static vm_fault_t vm_fault_cpu(struct vm_fault *vmf)
	struct vm_area_struct *area = vmf->vma;
	struct i915_mmap_offset *mmo = area->vm_private_data;
	struct drm_i915_gem_object *obj = mmo->obj;
	unsigned long obj_offset;
	resource_size_t iomap;
	int err;

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

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

	if (area->vm_flags & VM_WRITE) {
		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)
	return i915_error_to_vmf_fault(err);
}

static void set_address_limits(struct vm_area_struct *area,
			       struct i915_vma *vma,
			       unsigned long obj_offset,
			       resource_size_t gmadr_start,
			       unsigned long *start_vaddr,
			       unsigned long *end_vaddr,
			       unsigned long *pfn)
{
	unsigned long vm_start, vm_end, vma_size; /* user's memory parameters */
	long start, end; /* memory boundaries */

	/*
	 * Let's move into the ">> PAGE_SHIFT"
	 * domain to be sure not to lose bits
	 */
	vm_start = area->vm_start >> PAGE_SHIFT;
	vm_end = area->vm_end >> PAGE_SHIFT;
	vma_size = vma->size >> PAGE_SHIFT;

	/*
	 * Calculate the memory boundaries by considering the offset
	 * provided by the user during memory mapping and the offset
	 * provided for the partial mapping.
	 */
	start = vm_start;
	start -= obj_offset;
	start += vma->gtt_view.partial.offset;
	end = start + vma_size;

	start = max_t(long, start, vm_start);
	end = min_t(long, end, vm_end);

	/* Let's move back into the "<< PAGE_SHIFT" domain */
	*start_vaddr = (unsigned long)start << PAGE_SHIFT;
	*end_vaddr = (unsigned long)end << PAGE_SHIFT;

	*pfn = (gmadr_start + i915_ggtt_offset(vma)) >> PAGE_SHIFT;
	*pfn += (*start_vaddr - area->vm_start) >> PAGE_SHIFT;
	*pfn += obj_offset - vma->gtt_view.partial.offset;
}

static vm_fault_t vm_fault_gtt(struct vm_fault *vmf)
{
#define MIN_CHUNK_PAGES (SZ_1M >> PAGE_SHIFT)
@@ -302,14 +345,18 @@ static vm_fault_t vm_fault_gtt(struct vm_fault *vmf)
	struct i915_ggtt *ggtt = to_gt(i915)->ggtt;
	bool write = area->vm_flags & VM_WRITE;
	struct i915_gem_ww_ctx ww;
	unsigned long obj_offset;
	unsigned long start, end; /* memory boundaries */
	intel_wakeref_t wakeref;
	struct i915_vma *vma;
	pgoff_t page_offset;
	unsigned long pfn;
	int srcu;
	int ret;

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

	trace_i915_gem_object_fault(obj, page_offset, true, write);

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

	/*
	 * Dump all the necessary parameters in this function to perform the
	 * arithmetic calculation for the virtual address start and end and
	 * the PFN (Page Frame Number).
	 */
	set_address_limits(area, vma, obj_offset, ggtt->gmadr.start,
			   &start, &end, &pfn);

	/* Finally, remap it using the new GTT offset */
	ret = remap_io_mapping(area,
			       area->vm_start + (vma->gtt_view.partial.offset << PAGE_SHIFT),
			       (ggtt->gmadr.start + i915_ggtt_offset(vma)) >> PAGE_SHIFT,
			       min_t(u64, vma->size, area->vm_end - area->vm_start),
			       &ggtt->iomap);
	ret = remap_io_mapping(area, start, pfn, end - start, &ggtt->iomap);
	if (ret)
		goto err_fence;

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

	rcu_read_lock();
	drm_vma_offset_lock_lookup(dev->vma_offset_manager);
	node = drm_vma_offset_exact_lookup_locked(dev->vma_offset_manager,
	node = drm_vma_offset_lookup_locked(dev->vma_offset_manager,
					    vma->vm_pgoff,
					    vma_pages(vma));
	if (node && drm_vma_node_is_allowed(node, priv)) {
@@ -1084,6 +1135,8 @@ int i915_gem_fb_mmap(struct drm_i915_gem_object *obj, struct vm_area_struct *vma
		mmo = mmap_offset_attach(obj, mmap_type, NULL);
		if (IS_ERR(mmo))
			return PTR_ERR(mmo);

		vma->vm_pgoff += drm_vma_node_start(&mmo->vma_node);
	}

	/*
+7 −6
Original line number Diff line number Diff line
@@ -165,7 +165,6 @@ i915_ttm_placement_from_obj(const struct drm_i915_gem_object *obj,
	i915_ttm_place_from_region(num_allowed ? obj->mm.placements[0] :
				   obj->mm.region, &places[0], obj->bo_offset,
				   obj->base.size, flags);
	places[0].flags |= TTM_PL_FLAG_DESIRED;

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

	/* First try only the requested placement. No eviction. */
	real_num_busy = placement->num_placement;
	placement->num_placement = 1;
	ret = ttm_bo_validate(bo, placement, &ctx);
	initial_placement.num_placement = 1;
	memcpy(&initial_place, placement->placement, sizeof(struct ttm_place));
	initial_place.flags |= TTM_PL_FLAG_DESIRED;
	initial_placement.placement = &initial_place;
	ret = ttm_bo_validate(bo, &initial_placement, &ctx);
	if (ret) {
		ret = i915_ttm_err_to_gem(ret);
		/*
@@ -800,7 +802,6 @@ static int __i915_ttm_get_pages(struct drm_i915_gem_object *obj,
		 * If the initial attempt fails, allow all accepted placements,
		 * evicting if necessary.
		 */
		placement->num_placement = real_num_busy;
		ret = ttm_bo_validate(bo, placement, &ctx);
		if (ret)
			return i915_ttm_err_to_gem(ret);
+2 −0
Original line number Diff line number Diff line
@@ -693,6 +693,8 @@ void intel_engines_release(struct intel_gt *gt)

		memset(&engine->reset, 0, sizeof(engine->reset));
	}

	llist_del_all(&gt->i915->uabi_engines_llist);
}

void intel_engine_free_request_pool(struct intel_engine_cs *engine)
+1 −0
Original line number Diff line number Diff line
@@ -220,6 +220,7 @@
#define GFX_OP_DESTBUFFER_INFO	 ((0x3<<29)|(0x1d<<24)|(0x8e<<16)|1)
#define GFX_OP_DRAWRECT_INFO     ((0x3<<29)|(0x1d<<24)|(0x80<<16)|(0x3))
#define GFX_OP_DRAWRECT_INFO_I965  ((0x7900<<16)|0x2)
#define CMD_3DSTATE_MESH_CONTROL ((0x3 << 29) | (0x3 << 27) | (0x0 << 24) | (0x77 << 16) | (0x3))

#define XY_CTRL_SURF_INSTR_SIZE		5
#define MI_FLUSH_DW_SIZE		3
Loading