Commit 73bc073d authored by Dave Airlie's avatar Dave Airlie
Browse files

Merge tag 'drm-xe-next-fixes-2025-10-03' of...

Merge tag 'drm-xe-next-fixes-2025-10-03' of https://gitlab.freedesktop.org/drm/xe/kernel

 into drm-next

Cross-subsystem Changes:
 - Fix userptr to not allow device private pages with SVM (Thomas
   Hellström)

Driver Changes:
 - Fix build with clang 16 (Michal Wajdeczko)
 - Fix handling of invalid configfs syntax usage and spell out the
   expected syntax in the documentation (Lucas De Marchi)
 - Do not try late bind firmware when running as VF since it
   shouldn't handle firmware loading (Michal Wajdeczko)
 - Fix idle assertion for local BOs (Thomas Hellström)
 - Fix uninitialized variable for late binding (Colin Ian King,
   Mallesh Koujalagi)
 - Do not require perfmon_capable to expose free memory at page
   granularity. Handle it like other drm drivers do (Matthew Auld)
 - Fix lock handling on suspend error path (Shuicheng Lin)
 - Fix I2C controller resume after S3 (Raag Jadav)

Signed-off-by: default avatarDave Airlie <airlied@redhat.com>

From: Lucas De Marchi <lucas.demarchi@intel.com>
Link: https://lore.kernel.org/r/q6yeyb7n2eqo5megxjqayooajirx5hhsntfo65m3y4myscz7oz@25qbabbbr4hj
parents bae04c96 1af59cd5
Loading
Loading
Loading
Loading
+13 −11
Original line number Diff line number Diff line
@@ -361,7 +361,6 @@ static const struct mmu_interval_notifier_ops drm_gpusvm_notifier_ops = {
 * @name: Name of the GPU SVM.
 * @drm: Pointer to the DRM device structure.
 * @mm: Pointer to the mm_struct for the address space.
 * @device_private_page_owner: Device private pages owner.
 * @mm_start: Start address of GPU SVM.
 * @mm_range: Range of the GPU SVM.
 * @notifier_size: Size of individual notifiers.
@@ -383,7 +382,7 @@ static const struct mmu_interval_notifier_ops drm_gpusvm_notifier_ops = {
 */
int drm_gpusvm_init(struct drm_gpusvm *gpusvm,
		    const char *name, struct drm_device *drm,
		    struct mm_struct *mm, void *device_private_page_owner,
		    struct mm_struct *mm,
		    unsigned long mm_start, unsigned long mm_range,
		    unsigned long notifier_size,
		    const struct drm_gpusvm_ops *ops,
@@ -395,15 +394,13 @@ int drm_gpusvm_init(struct drm_gpusvm *gpusvm,
		mmgrab(mm);
	} else {
		/* No full SVM mode, only core drm_gpusvm_pages API. */
		if (ops || num_chunks || mm_range || notifier_size ||
		    device_private_page_owner)
		if (ops || num_chunks || mm_range || notifier_size)
			return -EINVAL;
	}

	gpusvm->name = name;
	gpusvm->drm = drm;
	gpusvm->mm = mm;
	gpusvm->device_private_page_owner = device_private_page_owner;
	gpusvm->mm_start = mm_start;
	gpusvm->mm_range = mm_range;
	gpusvm->notifier_size = notifier_size;
@@ -684,6 +681,7 @@ static unsigned int drm_gpusvm_hmm_pfn_to_order(unsigned long hmm_pfn,
 * @notifier: Pointer to the GPU SVM notifier structure
 * @start: Start address
 * @end: End address
 * @dev_private_owner: The device private page owner
 *
 * Check if pages between start and end have been faulted in on the CPU. Use to
 * prevent migration of pages without CPU backing store.
@@ -692,14 +690,15 @@ static unsigned int drm_gpusvm_hmm_pfn_to_order(unsigned long hmm_pfn,
 */
static bool drm_gpusvm_check_pages(struct drm_gpusvm *gpusvm,
				   struct drm_gpusvm_notifier *notifier,
				   unsigned long start, unsigned long end)
				   unsigned long start, unsigned long end,
				   void *dev_private_owner)
{
	struct hmm_range hmm_range = {
		.default_flags = 0,
		.notifier = &notifier->notifier,
		.start = start,
		.end = end,
		.dev_private_owner = gpusvm->device_private_page_owner,
		.dev_private_owner = dev_private_owner,
	};
	unsigned long timeout =
		jiffies + msecs_to_jiffies(HMM_RANGE_DEFAULT_TIMEOUT);
@@ -753,6 +752,7 @@ static bool drm_gpusvm_check_pages(struct drm_gpusvm *gpusvm,
 * @gpuva_start: Start address of GPUVA which mirrors CPU
 * @gpuva_end: End address of GPUVA which mirrors CPU
 * @check_pages_threshold: Check CPU pages for present threshold
 * @dev_private_owner: The device private page owner
 *
 * This function determines the chunk size for the GPU SVM range based on the
 * fault address, GPU SVM chunk sizes, existing GPU SVM ranges, and the virtual
@@ -767,7 +767,8 @@ drm_gpusvm_range_chunk_size(struct drm_gpusvm *gpusvm,
			    unsigned long fault_addr,
			    unsigned long gpuva_start,
			    unsigned long gpuva_end,
			    unsigned long check_pages_threshold)
			    unsigned long check_pages_threshold,
			    void *dev_private_owner)
{
	unsigned long start, end;
	int i = 0;
@@ -814,7 +815,7 @@ drm_gpusvm_range_chunk_size(struct drm_gpusvm *gpusvm,
		 * process-many-malloc' mallocs at least 64k at a time.
		 */
		if (end - start <= check_pages_threshold &&
		    !drm_gpusvm_check_pages(gpusvm, notifier, start, end)) {
		    !drm_gpusvm_check_pages(gpusvm, notifier, start, end, dev_private_owner)) {
			++i;
			goto retry;
		}
@@ -957,7 +958,8 @@ drm_gpusvm_range_find_or_insert(struct drm_gpusvm *gpusvm,
	chunk_size = drm_gpusvm_range_chunk_size(gpusvm, notifier, vas,
						 fault_addr, gpuva_start,
						 gpuva_end,
						 ctx->check_pages_threshold);
						 ctx->check_pages_threshold,
						 ctx->device_private_page_owner);
	if (chunk_size == LONG_MAX) {
		err = -EINVAL;
		goto err_notifier_remove;
@@ -1268,7 +1270,7 @@ int drm_gpusvm_get_pages(struct drm_gpusvm *gpusvm,
		.notifier = notifier,
		.start = pages_start,
		.end = pages_end,
		.dev_private_owner = gpusvm->device_private_page_owner,
		.dev_private_owner = ctx->device_private_page_owner,
	};
	void *zdd;
	unsigned long timeout =
+6 −6
Original line number Diff line number Diff line
@@ -211,15 +211,15 @@ static void xe_ip_kunit_desc(const struct xe_ip *param, char *desc)
 * param generator can be used for both
 */
static const struct xe_ip pre_gmdid_graphics_ips[] = {
	graphics_ip_xelp,
	graphics_ip_xelpp,
	graphics_ip_xehpg,
	graphics_ip_xehpc,
	{ 1200, "Xe_LP", &graphics_xelp },
	{ 1210, "Xe_LP+", &graphics_xelp },
	{ 1255, "Xe_HPG", &graphics_xehpg },
	{ 1260, "Xe_HPC", &graphics_xehpc },
};

static const struct xe_ip pre_gmdid_media_ips[] = {
	media_ip_xem,
	media_ip_xehpm,
	{ 1200, "Xe_M", &media_xem },
	{ 1255, "Xe_HPM", &media_xem },
};

KUNIT_ARRAY_PARAM(pre_gmdid_graphics_ip, pre_gmdid_graphics_ips, xe_ip_kunit_desc);
+23 −11
Original line number Diff line number Diff line
@@ -1737,6 +1737,24 @@ static bool should_migrate_to_smem(struct xe_bo *bo)
	       bo->attr.atomic_access == DRM_XE_ATOMIC_CPU;
}

static int xe_bo_wait_usage_kernel(struct xe_bo *bo, struct ttm_operation_ctx *ctx)
{
	long lerr;

	if (ctx->no_wait_gpu)
		return dma_resv_test_signaled(bo->ttm.base.resv, DMA_RESV_USAGE_KERNEL) ?
			0 : -EBUSY;

	lerr = dma_resv_wait_timeout(bo->ttm.base.resv, DMA_RESV_USAGE_KERNEL,
				     ctx->interruptible, MAX_SCHEDULE_TIMEOUT);
	if (lerr < 0)
		return lerr;
	if (lerr == 0)
		return -EBUSY;

	return 0;
}

/* Populate the bo if swapped out, or migrate if the access mode requires that. */
static int xe_bo_fault_migrate(struct xe_bo *bo, struct ttm_operation_ctx *ctx,
			       struct drm_exec *exec)
@@ -1745,9 +1763,8 @@ static int xe_bo_fault_migrate(struct xe_bo *bo, struct ttm_operation_ctx *ctx,
	int err = 0;

	if (ttm_manager_type(tbo->bdev, tbo->resource->mem_type)->use_tt) {
		xe_assert(xe_bo_device(bo),
			  dma_resv_test_signaled(tbo->base.resv, DMA_RESV_USAGE_KERNEL) ||
			  (tbo->ttm && ttm_tt_is_populated(tbo->ttm)));
		err = xe_bo_wait_usage_kernel(bo, ctx);
		if (!err)
			err = ttm_bo_populate(&bo->ttm, ctx);
	} else if (should_migrate_to_smem(bo)) {
		xe_assert(xe_bo_device(bo), bo->flags & XE_BO_FLAG_SYSTEM);
@@ -1922,7 +1939,6 @@ static vm_fault_t xe_bo_cpu_fault(struct vm_fault *vmf)
			.no_wait_gpu = false,
			.gfp_retry_mayfail = retry_after_wait,
		};
		long lerr;

		err = drm_exec_lock_obj(&exec, &tbo->base);
		drm_exec_retry_on_contention(&exec);
@@ -1942,13 +1958,9 @@ static vm_fault_t xe_bo_cpu_fault(struct vm_fault *vmf)
			break;
		}

		lerr = dma_resv_wait_timeout(tbo->base.resv,
					     DMA_RESV_USAGE_KERNEL, true,
					     MAX_SCHEDULE_TIMEOUT);
		if (lerr < 0) {
			err = lerr;
		err = xe_bo_wait_usage_kernel(bo, &tctx);
		if (err)
			break;
		}

		if (!retry_after_wait)
			ret = __xe_bo_cpu_fault(vmf, xe, bo);
+18 −5
Original line number Diff line number Diff line
@@ -126,8 +126,20 @@
 * not intended for normal execution and will taint the kernel with TAINT_TEST
 * when used.
 *
 * Currently this is implemented only for post and mid context restore.
 * Examples:
 * The syntax allows to pass straight instructions to be executed by the engine
 * in a batch buffer or set specific registers.
 *
 * #. Generic instruction::
 *
 *	<engine-class> cmd <instr> [[dword0] [dword1] [...]]
 *
 * #. Simple register setting::
 *
 *	<engine-class> reg <address> <value>
 *
 * Commands are saved per engine class: all instances of that class will execute
 * those commands during context switch. The instruction, dword arguments,
 * addresses and values are in hex format like in the examples below.
 *
 * #. Execute a LRI command to write 0xDEADBEEF to register 0x4f10 after the
 *    normal context restore::
@@ -154,7 +166,8 @@
 *       When using multiple lines, make sure to use a command that is
 *       implemented with a single write syscall, like HEREDOC.
 *
 * These attributes can only be set before binding to the device.
 * Currently this is implemented only for post and mid context restore and
 * these attributes can only be set before binding to the device.
 *
 * Remove devices
 * ==============
@@ -324,8 +337,8 @@ static const struct engine_info *lookup_engine_info(const char *pattern, u64 *ma
			continue;

		pattern += strlen(engine_info[i].cls);
		if (!mask && !*pattern)
			return &engine_info[i];
		if (!mask)
			return *pattern ? NULL : &engine_info[i];

		if (!strcmp(pattern, "*")) {
			*mask = engine_info[i].mask;
+10 −9
Original line number Diff line number Diff line
@@ -685,17 +685,17 @@ static int wait_for_lmem_ready(struct xe_device *xe)
}
ALLOW_ERROR_INJECTION(wait_for_lmem_ready, ERRNO); /* See xe_pci_probe() */

static void sriov_update_device_info(struct xe_device *xe)
static void vf_update_device_info(struct xe_device *xe)
{
	xe_assert(xe, IS_SRIOV_VF(xe));
	/* disable features that are not available/applicable to VFs */
	if (IS_SRIOV_VF(xe)) {
	xe->info.probe_display = 0;
	xe->info.has_heci_cscfi = 0;
	xe->info.has_heci_gscfi = 0;
	xe->info.has_late_bind = 0;
	xe->info.skip_guc_pc = 1;
	xe->info.skip_pcode = 1;
}
}

static int xe_device_vram_alloc(struct xe_device *xe)
{
@@ -735,7 +735,8 @@ int xe_device_probe_early(struct xe_device *xe)

	xe_sriov_probe_early(xe);

	sriov_update_device_info(xe);
	if (IS_SRIOV_VF(xe))
		vf_update_device_info(xe);

	err = xe_pcode_probe_early(xe);
	if (err || xe_survivability_mode_is_requested(xe)) {
Loading