Unverified Commit 92ad9656 authored by openeuler-ci-bot's avatar openeuler-ci-bot Committed by Gitee
Browse files

!11377 drm/i915/gem: Fix Virtual Memory mapping boundaries calculation

parents b75c07df 8c52ac9e
Loading
Loading
Loading
Loading
+47 −6
Original line number Diff line number Diff line
@@ -272,6 +272,41 @@ 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,
			       unsigned long *start_vaddr,
			       unsigned long *end_vaddr)
{
	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->ggtt_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;
}

static vm_fault_t vm_fault_gtt(struct vm_fault *vmf)
{
#define MIN_CHUNK_PAGES (SZ_1M >> PAGE_SHIFT)
@@ -284,14 +319,18 @@ static vm_fault_t vm_fault_gtt(struct vm_fault *vmf)
	struct i915_ggtt *ggtt = &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);

@@ -362,12 +401,14 @@ static vm_fault_t vm_fault_gtt(struct vm_fault *vmf)
	if (ret)
		goto err_unpin;

	set_address_limits(area, vma, obj_offset, &start, &end);

	pfn = (ggtt->gmadr.start + i915_ggtt_offset(vma)) >> PAGE_SHIFT;
	pfn += (start - area->vm_start) >> PAGE_SHIFT;
	pfn += obj_offset - vma->ggtt_view.partial.offset;

	/* Finally, remap it using the new GTT offset */
	ret = remap_io_mapping(area,
			       area->vm_start + (vma->ggtt_view.partial.offset << PAGE_SHIFT),
			       (ggtt->gmadr.start + vma->node.start) >> 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;