diff options
| author | Dmitry Torokhov <[email protected]> | 2023-08-30 16:06:38 -0700 | 
|---|---|---|
| committer | Dmitry Torokhov <[email protected]> | 2023-08-30 16:06:38 -0700 | 
| commit | 1ac731c529cd4d6adbce134754b51ff7d822b145 (patch) | |
| tree | 143ab3f35ca5f3b69f583c84e6964b17139c2ec1 /drivers/gpu/drm/i915/gt/intel_ggtt.c | |
| parent | 07b4c950f27bef0362dc6ad7ee713aab61d58149 (diff) | |
| parent | 54116d442e001e1b6bd482122043b1870998a1f3 (diff) | |
Merge branch 'next' into for-linus
Prepare input updates for 6.6 merge window.
Diffstat (limited to 'drivers/gpu/drm/i915/gt/intel_ggtt.c')
| -rw-r--r-- | drivers/gpu/drm/i915/gt/intel_ggtt.c | 43 | 
1 files changed, 39 insertions, 4 deletions
diff --git a/drivers/gpu/drm/i915/gt/intel_ggtt.c b/drivers/gpu/drm/i915/gt/intel_ggtt.c index 842e69c7b21e..3c7f1ed92f5b 100644 --- a/drivers/gpu/drm/i915/gt/intel_ggtt.c +++ b/drivers/gpu/drm/i915/gt/intel_ggtt.c @@ -291,6 +291,27 @@ static void gen8_ggtt_insert_entries(struct i915_address_space *vm,  	ggtt->invalidate(ggtt);  } +static void gen8_ggtt_clear_range(struct i915_address_space *vm, +				  u64 start, u64 length) +{ +	struct i915_ggtt *ggtt = i915_vm_to_ggtt(vm); +	unsigned int first_entry = start / I915_GTT_PAGE_SIZE; +	unsigned int num_entries = length / I915_GTT_PAGE_SIZE; +	const gen8_pte_t scratch_pte = vm->scratch[0]->encode; +	gen8_pte_t __iomem *gtt_base = +		(gen8_pte_t __iomem *)ggtt->gsm + first_entry; +	const int max_entries = ggtt_total_entries(ggtt) - first_entry; +	int i; + +	if (WARN(num_entries > max_entries, +		 "First entry = %d; Num entries = %d (max=%d)\n", +		 first_entry, num_entries, max_entries)) +		num_entries = max_entries; + +	for (i = 0; i < num_entries; i++) +		gen8_set_pte(>t_base[i], scratch_pte); +} +  static void gen6_ggtt_insert_page(struct i915_address_space *vm,  				  dma_addr_t addr,  				  u64 offset, @@ -551,8 +572,12 @@ static int init_ggtt(struct i915_ggtt *ggtt)  		 * paths, and we trust that 0 will remain reserved. However,  		 * the only likely reason for failure to insert is a driver  		 * bug, which we expect to cause other failures... +		 * +		 * Since CPU can perform speculative reads on error capture +		 * (write-combining allows it) add scratch page after error +		 * capture to avoid DMAR errors.  		 */ -		ggtt->error_capture.size = I915_GTT_PAGE_SIZE; +		ggtt->error_capture.size = 2 * I915_GTT_PAGE_SIZE;  		ggtt->error_capture.color = I915_COLOR_UNEVICTABLE;  		if (drm_mm_reserve_node(&ggtt->vm.mm, &ggtt->error_capture))  			drm_mm_insert_node_in_range(&ggtt->vm.mm, @@ -562,11 +587,15 @@ static int init_ggtt(struct i915_ggtt *ggtt)  						    0, ggtt->mappable_end,  						    DRM_MM_INSERT_LOW);  	} -	if (drm_mm_node_allocated(&ggtt->error_capture)) +	if (drm_mm_node_allocated(&ggtt->error_capture)) { +		u64 start = ggtt->error_capture.start; +		u64 size = ggtt->error_capture.size; + +		ggtt->vm.scratch_range(&ggtt->vm, start, size);  		drm_dbg(&ggtt->vm.i915->drm,  			"Reserved GGTT:[%llx, %llx] for use by error capture\n", -			ggtt->error_capture.start, -			ggtt->error_capture.start + ggtt->error_capture.size); +			start, start + size); +	}  	/*  	 * The upper portion of the GuC address space has a sizeable hole @@ -919,6 +948,7 @@ static int gen8_gmch_probe(struct i915_ggtt *ggtt)  	ggtt->vm.cleanup = gen6_gmch_remove;  	ggtt->vm.insert_page = gen8_ggtt_insert_page;  	ggtt->vm.clear_range = nop_clear_range; +	ggtt->vm.scratch_range = gen8_ggtt_clear_range;  	ggtt->vm.insert_entries = gen8_ggtt_insert_entries; @@ -1082,6 +1112,7 @@ static int gen6_gmch_probe(struct i915_ggtt *ggtt)  	ggtt->vm.clear_range = nop_clear_range;  	if (!HAS_FULL_PPGTT(i915))  		ggtt->vm.clear_range = gen6_ggtt_clear_range; +	ggtt->vm.scratch_range = gen6_ggtt_clear_range;  	ggtt->vm.insert_page = gen6_ggtt_insert_page;  	ggtt->vm.insert_entries = gen6_ggtt_insert_entries;  	ggtt->vm.cleanup = gen6_gmch_remove; @@ -1257,6 +1288,10 @@ void i915_ggtt_resume(struct i915_ggtt *ggtt)  	flush = i915_ggtt_resume_vm(&ggtt->vm); +	if (drm_mm_node_allocated(&ggtt->error_capture)) +		ggtt->vm.scratch_range(&ggtt->vm, ggtt->error_capture.start, +				       ggtt->error_capture.size); +  	ggtt->invalidate(ggtt);  	if (flush)  |