All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 0/3] drm/panthor: Report fault information to userspace
@ 2026-11-04  7:52 Christian Gmeiner
  2026-11-04  7:52 ` [PATCH v2 1/3] drm/panthor: Report the last VM fault through VM_GET_STATE Christian Gmeiner
                   ` (2 more replies)
  0 siblings, 3 replies; 5+ messages in thread
From: Christian Gmeiner @ 2026-11-04  7:52 UTC (permalink / raw)
  To: Boris Brezillon, Steven Price, Liviu Dudau, Maarten Lankhorst,
	Maxime Ripard, Thomas Zimmermann, David Airlie, Simona Vetter,
	Daniel Almeida, Alice Ryhl
  Cc: Lukas Zapolskas, Paul Toadere, dri-devel, linux-kernel,
	rust-for-linux, Christian Gmeiner

The Panthor CSF firmware and hardware report extra information when a
fault happens. Two kinds of faults matter here:
* faults raised at the address space level. These are fatal for every
  group bound to that VM.
* fatal faults raised on one of the queues of a group. They stop
  further submissions on that group.

This series exposes that information to userspace, so the
VK_KHR_device_fault extension can be implemented on top of it.

VM faults are reported through VM_GET_STATE. The VM keeps the raw
AS_FAULTSTATUS and AS_FAULTADDRESS of its last fault. Queue fatal
errors are reported through GROUP_GET_STATE. Each queue keeps its raw
CS_FATAL and CS_FATAL_INFO, and the ioctl returns them in an array
indexed by queue. The kernel does not decode the values, userspace
does. Nothing is allocated in the fault paths.

Changes in v2:
- Report VM faults through VM_GET_STATE instead of copying them into
  every group bound to the VM.
- Pass the raw register values to userspace instead of decoded fields.
- Keep one fatal slot per queue. A queue stops at its first fatal
  error, so no allocation is needed.
- Store the uAPI structs directly in the kernel objects.
- Dropped the recoverable CS_FAULT reporting for now.
- Bump the driver version to 1.10 in a separate patch.
- Rebased on drm-misc-next. The queue fatal info is protected by
  events_lock now that fatal events are processed under it.

Link to v1: https://lore.kernel.org/r/20251215115457.2137485-1-lukas.zapolskas@arm.com

Signed-off-by: Christian Gmeiner <cgmeiner@igalia.com>
---
Christian Gmeiner (3):
      drm/panthor: Report the last VM fault through VM_GET_STATE
      drm/panthor: Report the CS fatal errors through GROUP_GET_STATE
      drm/panthor: Bump the driver version to 1.10

 drivers/gpu/drm/panthor/panthor_drv.c   | 26 +++++++++++++++--
 drivers/gpu/drm/panthor/panthor_mmu.c   | 33 +++++++++++++++++++--
 drivers/gpu/drm/panthor/panthor_mmu.h   |  2 ++
 drivers/gpu/drm/panthor/panthor_sched.c | 32 +++++++++++++++++++-
 drivers/gpu/drm/panthor/panthor_sched.h |  5 +++-
 include/uapi/drm/panthor_drm.h          | 52 +++++++++++++++++++++++++++++++++
 6 files changed, 143 insertions(+), 7 deletions(-)
---
base-commit: 6f7098738fff3ec7393f924343188cb8e6ebc5d2
change-id: 20261014-panthor-fault-info-v2-330a9f771fd3

Best regards,
-- 
Christian Gmeiner <cgmeiner@igalia.com>


^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH v2 1/3] drm/panthor: Report the last VM fault through VM_GET_STATE
  2026-11-04  7:52 [PATCH v2 0/3] drm/panthor: Report fault information to userspace Christian Gmeiner
@ 2026-11-04  7:52 ` Christian Gmeiner
  2026-11-04  7:52 ` [PATCH v2 2/3] drm/panthor: Report the CS fatal errors through GROUP_GET_STATE Christian Gmeiner
  2026-11-04  7:52 ` [PATCH v2 3/3] drm/panthor: Bump the driver version to 1.10 Christian Gmeiner
  2 siblings, 0 replies; 5+ messages in thread
From: Christian Gmeiner @ 2026-11-04  7:52 UTC (permalink / raw)
  To: Boris Brezillon, Steven Price, Liviu Dudau, Maarten Lankhorst,
	Maxime Ripard, Thomas Zimmermann, David Airlie, Simona Vetter,
	Daniel Almeida, Alice Ryhl
  Cc: Lukas Zapolskas, Paul Toadere, dri-devel, linux-kernel,
	rust-for-linux, Christian Gmeiner

From: Christian Gmeiner <cgmeiner@igalia.com>

Keep the raw AS_FAULTSTATUS and AS_FAULTADDRESS of the last fault in
the VM and return them through VM_GET_STATE. Userspace decodes the
values. No memory is allocated in the fault path.

The MMU irq handler records the fault under the AS slots lock. The
ioctl reads it under the same lock. The VM stores the fault as a
struct drm_panthor_vm_fault, which is the uAPI struct, so the ioctl
can copy it with one assignment.

The unhandled_fault flag is cleared when the VM is re-activated. The
stored fault is not. So userspace can still query it after the group
that hit the fault was killed.

Old userspace that passes the shorter struct still works, the DRM core
zero-fills the missing tail.

Link: https://lore.kernel.org/r/20251215115457.2137485-4-lukas.zapolskas@arm.com
Signed-off-by: Christian Gmeiner <cgmeiner@igalia.com>
---
 drivers/gpu/drm/panthor/panthor_drv.c |  2 ++
 drivers/gpu/drm/panthor/panthor_mmu.c | 33 +++++++++++++++++++++++++++++++--
 drivers/gpu/drm/panthor/panthor_mmu.h |  2 ++
 include/uapi/drm/panthor_drm.h        | 22 ++++++++++++++++++++++
 4 files changed, 57 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/panthor/panthor_drv.c b/drivers/gpu/drm/panthor/panthor_drv.c
index dc8d0191aef4..7572cd7d6423 100644
--- a/drivers/gpu/drm/panthor/panthor_drv.c
+++ b/drivers/gpu/drm/panthor/panthor_drv.c
@@ -1471,6 +1471,8 @@ static int panthor_ioctl_vm_get_state(struct drm_device *ddev, void *data,
 	else
 		args->state = DRM_PANTHOR_VM_STATE_USABLE;
 
+	panthor_vm_get_fault(vm, &args->fault);
+
 	panthor_vm_put(vm);
 	return 0;
 }
diff --git a/drivers/gpu/drm/panthor/panthor_mmu.c b/drivers/gpu/drm/panthor/panthor_mmu.c
index d1c29eec46f2..6fc5f3d381c1 100644
--- a/drivers/gpu/drm/panthor/panthor_mmu.c
+++ b/drivers/gpu/drm/panthor/panthor_mmu.c
@@ -389,6 +389,15 @@ struct panthor_vm {
 	 */
 	bool unhandled_fault;
 
+	/**
+	 * @fault: Last fault on this VM.
+	 *
+	 * A new fault overwrites the previous one. Unlike @unhandled_fault,
+	 * this is not cleared when the VM is re-activated. Protected by
+	 * panthor_mmu::as::slots_lock.
+	 */
+	struct drm_panthor_vm_fault fault;
+
 	/** @locked_region: Information about the currently locked region currently. */
 	struct {
 		/** @locked_region.start: Start of the locked region. */
@@ -662,6 +671,19 @@ bool panthor_vm_has_unhandled_faults(struct panthor_vm *vm)
 	return vm->unhandled_fault;
 }
 
+/**
+ * panthor_vm_get_fault() - Get the last fault of a VM
+ * @vm: VM to query.
+ * @fault: Returns the last fault, with a zero status if no fault happened.
+ */
+void panthor_vm_get_fault(struct panthor_vm *vm, struct drm_panthor_vm_fault *fault)
+{
+	struct panthor_device *ptdev = vm->ptdev;
+
+	guard(mutex)(&ptdev->mmu->as.slots_lock);
+	*fault = vm->fault;
+}
+
 /**
  * panthor_vm_is_unusable() - Check if the VM is still usable
  * @vm: VM to check.
@@ -1855,6 +1877,7 @@ static void panthor_mmu_irq_handler(struct panthor_irq *pirq, u32 status)
 	while (status) {
 		u32 as = ffs(status | (status >> 16)) - 1;
 		u32 mask = MMU_INT_AS_FAULT(as);
+		struct panthor_vm *vm;
 		u64 addr;
 		u32 fault_status;
 		u32 exception_type;
@@ -1895,8 +1918,14 @@ static void panthor_mmu_irq_handler(struct panthor_irq *pirq, u32 status)
 		 */
 		gpu_write(mmu->irq.iomem, INT_CLEAR, mask);
 
-		if (ptdev->mmu->as.slots[as].vm)
-			ptdev->mmu->as.slots[as].vm->unhandled_fault = true;
+		vm = mmu->as.slots[as].vm;
+		if (vm) {
+			vm->unhandled_fault = true;
+			vm->fault = (struct drm_panthor_vm_fault){
+				.status = fault_status,
+				.address = addr,
+			};
+		}
 
 		/* Disable the MMU to kill jobs on this AS. */
 		panthor_mmu_as_disable(ptdev, as);
diff --git a/drivers/gpu/drm/panthor/panthor_mmu.h b/drivers/gpu/drm/panthor/panthor_mmu.h
index abc36e7204be..74f9f5d98c94 100644
--- a/drivers/gpu/drm/panthor/panthor_mmu.h
+++ b/drivers/gpu/drm/panthor/panthor_mmu.h
@@ -11,6 +11,7 @@
 struct drm_exec;
 struct drm_sched_job;
 struct drm_memory_stats;
+struct drm_panthor_vm_fault;
 struct panthor_gem_object;
 struct panthor_heap_pool;
 struct panthor_vm;
@@ -74,6 +75,7 @@ struct panthor_vm *panthor_vm_pool_get_vm(struct panthor_vm_pool *pool, u32 hand
 
 bool panthor_vm_has_unhandled_faults(struct panthor_vm *vm);
 bool panthor_vm_is_unusable(struct panthor_vm *vm);
+void panthor_vm_get_fault(struct panthor_vm *vm, struct drm_panthor_vm_fault *fault);
 
 /*
  * PANTHOR_VM_KERNEL_AUTO_VA: Use this magic address when you want the GEM
diff --git a/include/uapi/drm/panthor_drm.h b/include/uapi/drm/panthor_drm.h
index a2ff0f4ec691..85e197d7a528 100644
--- a/include/uapi/drm/panthor_drm.h
+++ b/include/uapi/drm/panthor_drm.h
@@ -743,6 +743,20 @@ enum drm_panthor_vm_state {
 	DRM_PANTHOR_VM_STATE_UNUSABLE,
 };
 
+/**
+ * struct drm_panthor_vm_fault - Fault information of a VM.
+ */
+struct drm_panthor_vm_fault {
+	/** @status: Raw AS_FAULTSTATUS value, zero if no fault happened. */
+	__u32 status;
+
+	/** @pad: Will be zero on return. */
+	__u32 pad;
+
+	/** @address: Raw AS_FAULTADDRESS value, valid if @status is non-zero. */
+	__u64 address;
+};
+
 /**
  * struct drm_panthor_vm_get_state - Get VM state.
  */
@@ -756,6 +770,14 @@ struct drm_panthor_vm_get_state {
 	 * Must be one of the enum drm_panthor_vm_state values.
 	 */
 	__u32 state;
+
+	/**
+	 * @fault: Last fault on this VM.
+	 *
+	 * A new fault overwrites the previous one. It is not cleared when the
+	 * VM is re-activated or after a GPU reset.
+	 */
+	struct drm_panthor_vm_fault fault;
 };
 
 /**

-- 
2.56.0


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH v2 2/3] drm/panthor: Report the CS fatal errors through GROUP_GET_STATE
  2026-11-04  7:52 [PATCH v2 0/3] drm/panthor: Report fault information to userspace Christian Gmeiner
  2026-11-04  7:52 ` [PATCH v2 1/3] drm/panthor: Report the last VM fault through VM_GET_STATE Christian Gmeiner
@ 2026-11-04  7:52 ` Christian Gmeiner
  2026-11-04  8:13   ` sashiko-bot
  2026-11-04  7:52 ` [PATCH v2 3/3] drm/panthor: Bump the driver version to 1.10 Christian Gmeiner
  2 siblings, 1 reply; 5+ messages in thread
From: Christian Gmeiner @ 2026-11-04  7:52 UTC (permalink / raw)
  To: Boris Brezillon, Steven Price, Liviu Dudau, Maarten Lankhorst,
	Maxime Ripard, Thomas Zimmermann, David Airlie, Simona Vetter,
	Daniel Almeida, Alice Ryhl
  Cc: Lukas Zapolskas, Paul Toadere, dri-devel, linux-kernel,
	rust-for-linux, Christian Gmeiner

From: Christian Gmeiner <cgmeiner@igalia.com>

Keep the raw CS_FATAL and CS_FATAL_INFO in the queue that hit them and
return them through GROUP_GET_STATE in an array indexed by queue.
Userspace decodes the values. No memory is allocated in the fatal path.

A queue stops at its first fatal error, so one slot per queue is
enough. The slot is a struct drm_panthor_queue_fatal, which is the uAPI
struct, so the ioctl can copy it with one assignment. The CS_FATAL
event handler writes the slot under events_lock. The ioctl reads it
under the same lock. The slot is never cleared, so the values can be
read again after the call.

The ioctl copies the slots of all queues to a stack array while the
locks are held and copies them to userspace after the locks are
dropped. It fills at most one entry per queue of the group and leaves
the rest of the user array untouched.

A queue can be flagged in fatal_queues without a CS_FATAL, for example
when the group was killed by a VM fault. Its entry then has a zero
exception. The VM fault itself is available through VM_GET_STATE.

Old userspace that passes the shorter struct still works, the DRM core
zero-fills the missing tail. A zero count skips the array.

Link: https://lore.kernel.org/r/20251215115457.2137485-3-lukas.zapolskas@arm.com
Link: https://lore.kernel.org/r/20251215115457.2137485-6-lukas.zapolskas@arm.com
Signed-off-by: Christian Gmeiner <cgmeiner@igalia.com>
---
 drivers/gpu/drm/panthor/panthor_drv.c   | 20 ++++++++++++++++++--
 drivers/gpu/drm/panthor/panthor_sched.c | 32 +++++++++++++++++++++++++++++++-
 drivers/gpu/drm/panthor/panthor_sched.h |  5 ++++-
 include/uapi/drm/panthor_drm.h          | 30 ++++++++++++++++++++++++++++++
 4 files changed, 83 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/panthor/panthor_drv.c b/drivers/gpu/drm/panthor/panthor_drv.c
index 7572cd7d6423..fb5fdf848dec 100644
--- a/drivers/gpu/drm/panthor/panthor_drv.c
+++ b/drivers/gpu/drm/panthor/panthor_drv.c
@@ -181,7 +181,8 @@ panthor_get_uobj_array(const struct drm_panthor_obj_array *in, u32 min_stride,
 		 PANTHOR_UOBJ_DECL(struct drm_panthor_queue_submit, syncs), \
 		 PANTHOR_UOBJ_DECL(struct drm_panthor_queue_create, ringbuf_size), \
 		 PANTHOR_UOBJ_DECL(struct drm_panthor_vm_bind_op, syncs), \
-		 PANTHOR_UOBJ_DECL(struct drm_panthor_bo_sync_op, size))
+		 PANTHOR_UOBJ_DECL(struct drm_panthor_bo_sync_op, size), \
+		 PANTHOR_UOBJ_DECL(struct drm_panthor_queue_fatal, exception_info))
 
 /**
  * PANTHOR_UOBJ_SET() - Copy a kernel object to a user object.
@@ -1254,10 +1255,25 @@ static int panthor_ioctl_group_create(struct drm_device *ddev, void *data,
 static int panthor_ioctl_group_get_state(struct drm_device *ddev, void *data,
 					 struct drm_file *file)
 {
+	struct drm_panthor_queue_fatal fatals[MAX_CS_PER_CSG];
 	struct panthor_file *pfile = file->driver_priv;
 	struct drm_panthor_group_get_state *args = data;
+	u64 usr_ptr = args->queue_fatals.array;
+	u32 stride = args->queue_fatals.stride;
+	u32 count;
+	int ret;
 
-	return panthor_group_get_state(pfile, args);
+	ret = panthor_group_get_state(pfile, args, fatals, &count);
+	if (ret)
+		return ret;
+
+	for (u32 i = 0; i < count; i++) {
+		ret = PANTHOR_UOBJ_SET(usr_ptr + (u64)i * stride, stride, fatals[i]);
+		if (ret)
+			return ret;
+	}
+
+	return 0;
 }
 
 static int panthor_ioctl_tiler_heap_create(struct drm_device *ddev, void *data,
diff --git a/drivers/gpu/drm/panthor/panthor_sched.c b/drivers/gpu/drm/panthor/panthor_sched.c
index a343c5180e01..40400b2e4551 100644
--- a/drivers/gpu/drm/panthor/panthor_sched.c
+++ b/drivers/gpu/drm/panthor/panthor_sched.c
@@ -485,6 +485,15 @@ struct panthor_queue {
 		/** @profiling.seqno: Index of the next available profiling information slot. */
 		u32 seqno;
 	} profiling;
+
+	/**
+	 * @fatal: Last CS_FATAL reported on this queue.
+	 *
+	 * Never cleared, a later CS_FATAL overwrites it. A zero exception
+	 * means no CS_FATAL was reported. Protected by
+	 * panthor_scheduler::events_lock.
+	 */
+	struct drm_panthor_queue_fatal fatal;
 };
 
 /**
@@ -1412,10 +1421,20 @@ cs_slot_process_fatal_event_locked(struct panthor_device *ptdev,
 	info = cs_iface->output->fatal_info;
 
 	if (group) {
+		struct panthor_queue *queue = cs_id < group->queue_count ?
+					      group->queues[cs_id] : NULL;
+
 		drm_warn(&ptdev->base, "CS_FATAL: pid=%d, comm=%s\n",
 			 group->task_info.pid, group->task_info.comm);
 
 		atomic_or(BIT(cs_id), &group->fatal_queues);
+
+		if (queue) {
+			queue->fatal = (struct drm_panthor_queue_fatal){
+				.exception = fatal,
+				.exception_info = info,
+			};
+		}
 	}
 
 	if (CS_EXCEPTION_TYPE(fatal) == DRM_PANTHOR_EXCEPTION_CS_UNRECOVERABLE) {
@@ -3818,8 +3837,11 @@ static struct panthor_group *group_from_handle(struct panthor_group_pool *pool,
 }
 
 int panthor_group_get_state(struct panthor_file *pfile,
-			    struct drm_panthor_group_get_state *get_state)
+			    struct drm_panthor_group_get_state *get_state,
+			    struct drm_panthor_queue_fatal *fatals,
+			    u32 *fatal_count)
 {
+	struct drm_panthor_obj_array queue_fatals = get_state->queue_fatals;
 	struct panthor_group_pool *gpool = pfile->groups;
 	struct panthor_device *ptdev = pfile->ptdev;
 	struct panthor_scheduler *sched = ptdev->scheduler;
@@ -3833,6 +3855,9 @@ int panthor_group_get_state(struct panthor_file *pfile,
 		return -EINVAL;
 
 	memset(get_state, 0, sizeof(*get_state));
+	get_state->queue_fatals = queue_fatals;
+
+	*fatal_count = min(queue_fatals.count, group->queue_count);
 
 	mutex_lock(&sched->lock);
 	if (atomic_read(&group->timedout))
@@ -3844,6 +3869,11 @@ int panthor_group_get_state(struct panthor_file *pfile,
 
 	if (group->innocent)
 		get_state->state |= DRM_PANTHOR_GROUP_STATE_INNOCENT;
+
+	scoped_guard(spinlock, &sched->events_lock) {
+		for (u32 i = 0; i < *fatal_count; i++)
+			fatals[i] = group->queues[i]->fatal;
+	}
 	mutex_unlock(&sched->lock);
 
 	group_put(group);
diff --git a/drivers/gpu/drm/panthor/panthor_sched.h b/drivers/gpu/drm/panthor/panthor_sched.h
index d87cbdba4d40..dd3d31c06cf1 100644
--- a/drivers/gpu/drm/panthor/panthor_sched.h
+++ b/drivers/gpu/drm/panthor/panthor_sched.h
@@ -14,6 +14,7 @@ struct drm_minor;
 struct drm_panthor_group_create;
 struct drm_panthor_queue_create;
 struct drm_panthor_group_get_state;
+struct drm_panthor_queue_fatal;
 struct drm_panthor_queue_submit;
 struct panthor_device;
 struct panthor_file;
@@ -26,7 +27,9 @@ int panthor_group_create(struct panthor_file *pfile,
 			 u64 drm_client_id);
 int panthor_group_destroy(struct panthor_file *pfile, u32 group_handle);
 int panthor_group_get_state(struct panthor_file *pfile,
-			    struct drm_panthor_group_get_state *get_state);
+			    struct drm_panthor_group_get_state *get_state,
+			    struct drm_panthor_queue_fatal *fatals,
+			    u32 *fatal_count);
 
 struct drm_sched_job *
 panthor_job_create(struct panthor_file *pfile,
diff --git a/include/uapi/drm/panthor_drm.h b/include/uapi/drm/panthor_drm.h
index 85e197d7a528..c9a681762b96 100644
--- a/include/uapi/drm/panthor_drm.h
+++ b/include/uapi/drm/panthor_drm.h
@@ -1072,6 +1072,27 @@ enum drm_panthor_group_state_flags {
 	DRM_PANTHOR_GROUP_STATE_INNOCENT = 1 << 2,
 };
 
+/**
+ * struct drm_panthor_queue_fatal - Fatal error of a single queue.
+ */
+struct drm_panthor_queue_fatal {
+	/**
+	 * @exception: Raw CS_FATAL value.
+	 *
+	 * Zero if no CS_FATAL was reported on this queue. A queue can be
+	 * flagged in drm_panthor_group_get_state::fatal_queues without a
+	 * CS_FATAL, for instance when the group was killed by a VM fault.
+	 * A later CS_FATAL overwrites the previous one.
+	 */
+	__u32 exception;
+
+	/** @pad: Will be zero on return. */
+	__u32 pad;
+
+	/** @exception_info: Raw CS_FATAL_INFO value, valid if @exception is non-zero. */
+	__u64 exception_info;
+};
+
 /**
  * struct drm_panthor_group_get_state - Arguments passed to DRM_IOCTL_PANTHOR_GROUP_GET_STATE
  *
@@ -1093,6 +1114,15 @@ struct drm_panthor_group_get_state {
 
 	/** @pad: MBZ */
 	__u32 pad;
+
+	/**
+	 * @queue_fatals: Array of struct drm_panthor_queue_fatal, indexed by queue.
+	 *
+	 * Entry N describes the queue at index N of the group creation array.
+	 * The driver fills at most as many entries as the group has queues and
+	 * leaves the rest untouched. A zero count skips the array.
+	 */
+	struct drm_panthor_obj_array queue_fatals;
 };
 
 /**

-- 
2.56.0


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH v2 3/3] drm/panthor: Bump the driver version to 1.10
  2026-11-04  7:52 [PATCH v2 0/3] drm/panthor: Report fault information to userspace Christian Gmeiner
  2026-11-04  7:52 ` [PATCH v2 1/3] drm/panthor: Report the last VM fault through VM_GET_STATE Christian Gmeiner
  2026-11-04  7:52 ` [PATCH v2 2/3] drm/panthor: Report the CS fatal errors through GROUP_GET_STATE Christian Gmeiner
@ 2026-11-04  7:52 ` Christian Gmeiner
  2 siblings, 0 replies; 5+ messages in thread
From: Christian Gmeiner @ 2026-11-04  7:52 UTC (permalink / raw)
  To: Boris Brezillon, Steven Price, Liviu Dudau, Maarten Lankhorst,
	Maxime Ripard, Thomas Zimmermann, David Airlie, Simona Vetter,
	Daniel Almeida, Alice Ryhl
  Cc: Lukas Zapolskas, Paul Toadere, dri-devel, linux-kernel,
	rust-for-linux, Christian Gmeiner

From: Christian Gmeiner <cgmeiner@igalia.com>

VM_GET_STATE now reports the last VM fault and GROUP_GET_STATE reports
the fatal error of each queue. Bump the driver version so userspace
can detect this.

Signed-off-by: Christian Gmeiner <cgmeiner@igalia.com>
---
 drivers/gpu/drm/panthor/panthor_drv.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/panthor/panthor_drv.c b/drivers/gpu/drm/panthor/panthor_drv.c
index fb5fdf848dec..139654628ec4 100644
--- a/drivers/gpu/drm/panthor/panthor_drv.c
+++ b/drivers/gpu/drm/panthor/panthor_drv.c
@@ -1803,6 +1803,8 @@ static void panthor_debugfs_init(struct drm_minor *minor)
  * - 1.8 - extends DEV_QUERY_TIMESTAMP_INFO with flags
  * - 1.9 - adds DRM_PANTHOR_DEV_QUERY_MMU_INFO query
  *       - adds DRM_PANTHOR_VM_BIND_OP_MAP_SPARSE flag
+ * - 1.10 - extends VM_GET_STATE with the last unhandled VM fault
+ *        - extends GROUP_GET_STATE with the fatal error of each queue
  */
 static const struct drm_driver panthor_drm_driver = {
 	.driver_features = DRIVER_RENDER | DRIVER_GEM | DRIVER_SYNCOBJ |
@@ -1816,7 +1818,7 @@ static const struct drm_driver panthor_drm_driver = {
 	.name = "panthor",
 	.desc = "Panthor DRM driver",
 	.major = 1,
-	.minor = 9,
+	.minor = 10,
 
 	.gem_prime_import_sg_table = panthor_gem_prime_import_sg_table,
 	.gem_prime_import = panthor_gem_prime_import,

-- 
2.56.0


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [PATCH v2 2/3] drm/panthor: Report the CS fatal errors through GROUP_GET_STATE
  2026-11-04  7:52 ` [PATCH v2 2/3] drm/panthor: Report the CS fatal errors through GROUP_GET_STATE Christian Gmeiner
@ 2026-11-04  8:13   ` sashiko-bot
  0 siblings, 0 replies; 5+ messages in thread
From: sashiko-bot @ 2026-11-04  8:13 UTC (permalink / raw)
  To: Christian Gmeiner; +Cc: dri-devel, ojeda, gary

Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Medium] drm/panthor: race reading fatal_queues in panthor_group_get_state()
--

commit 8ad04a984a0eee7e92a001d9035eba4354298f3e
Author: Christian Gmeiner <cgmeiner@igalia.com>

drm/panthor: Report the CS fatal errors through GROUP_GET_STATE

This commit stores the raw CS_FATAL and CS_FATAL_INFO values in the
panthor_queue that hit a fatal error and exposes them to userspace via
an array in DRM_IOCTL_PANTHOR_GROUP_GET_STATE.

Link: https://lore.kernel.org/r/20251215115457.2137485-3-lukas.zapolskas@arm.com
Link: https://lore.kernel.org/r/20251215115457.2137485-6-lukas.zapolskas@arm.com

> diff --git a/drivers/gpu/drm/panthor/panthor_sched.c b/drivers/gpu/drm/panthor/panthor_sched.c
> index a343c5180e01e..40400b2e45518 100644
> --- a/drivers/gpu/drm/panthor/panthor_sched.c
> +++ b/drivers/gpu/drm/panthor/panthor_sched.c

[ ... ]

> @@ -1412,10 +1421,20 @@ cs_slot_process_fatal_event_locked(struct panthor_device *ptdev,
>  	info = cs_iface->output->fatal_info;
>  
>  	if (group) {
> +		struct panthor_queue *queue = cs_id < group->queue_count ?
> +					      group->queues[cs_id] : NULL;
> +
>  		drm_warn(&ptdev->base, "CS_FATAL: pid=%d, comm=%s\n",
>  			 group->task_info.pid, group->task_info.comm);
>  
>  		atomic_or(BIT(cs_id), &group->fatal_queues);
> +
> +		if (queue) {
> +			queue->fatal = (struct drm_panthor_queue_fatal){
> +				.exception = fatal,
> +				.exception_info = info,
> +			};
> +		}
>  	}

[ ... ]

> @@ -3844,6 +3869,11 @@ int panthor_group_get_state(struct panthor_file *pfile,
>  
>  	if (group->innocent)
>  		get_state->state |= DRM_PANTHOR_GROUP_STATE_INNOCENT;
> +
> +	scoped_guard(spinlock, &sched->events_lock) {
> +		for (u32 i = 0; i < *fatal_count; i++)
> +			fatals[i] = group->queues[i]->fatal;
> +	}
>  	mutex_unlock(&sched->lock);

[Severity: Medium]
Can panthor_group_get_state() return an inconsistent snapshot to userspace
when racing with a CS_FATAL interrupt?

In the threaded interrupt path, panthor_job_irq_threaded_handler() ->
panthor_job_irq_handler() -> panthor_sched_report_fw_events() ->
sched_process_csg_irq_locked() -> cs_slot_process_fatal_event_locked() runs
under sched->events_lock without holding sched->lock, updating both
group->fatal_queues and queue->fatal.

Meanwhile, panthor_group_get_state() reads group->fatal_queues before taking
sched->events_lock:

drivers/gpu/drm/panthor/panthor_sched.c:panthor_group_get_state() {
	...
	mutex_lock(&sched->lock);
	if (atomic_read(&group->timedout))
		get_state->state |= DRM_PANTHOR_GROUP_STATE_TIMEDOUT;

	get_state->fatal_queues = atomic_read(&group->fatal_queues);
	if (get_state->fatal_queues)
		get_state->state |= DRM_PANTHOR_GROUP_STATE_FATAL_FAULT;

	if (group->innocent)
		get_state->state |= DRM_PANTHOR_GROUP_STATE_INNOCENT;

	scoped_guard(spinlock, &sched->events_lock) {
		for (u32 i = 0; i < *fatal_count; i++)
			fatals[i] = group->queues[i]->fatal;
	}
	...
}

If cs_slot_process_fatal_event_locked() runs on another CPU after
atomic_read(&group->fatal_queues) but before sched->events_lock is acquired,
get_state->fatal_queues and DRM_PANTHOR_GROUP_STATE_FATAL_FAULT will remain
unset while fatals[cs_id].exception contains a non-zero CS_FATAL value.

Should group->fatal_queues be read inside the sched->events_lock critical
section alongside group->queues[i]->fatal so that fatal_queues, state, and
fatals[] are consistent?

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20261104-panthor-fault-info-v2-v2-0-673b31f3840c@igalia.com?part=2

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2026-11-04  8:13 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-11-04  7:52 [PATCH v2 0/3] drm/panthor: Report fault information to userspace Christian Gmeiner
2026-11-04  7:52 ` [PATCH v2 1/3] drm/panthor: Report the last VM fault through VM_GET_STATE Christian Gmeiner
2026-11-04  7:52 ` [PATCH v2 2/3] drm/panthor: Report the CS fatal errors through GROUP_GET_STATE Christian Gmeiner
2026-11-04  8:13   ` sashiko-bot
2026-11-04  7:52 ` [PATCH v2 3/3] drm/panthor: Bump the driver version to 1.10 Christian Gmeiner

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.