All of lore.kernel.org
 help / color / mirror / Atom feed
From: sashiko-bot@kernel.org
To: "Ketil Johnsen" <ketil.johnsen@arm.com>
Cc: dri-devel@lists.freedesktop.org
Subject: Re: [PATCH v3 6/6] drm/panthor: Expose protected rendering features
Date: Fri, 11 Sep 2026 11:55:02 +0000	[thread overview]
Message-ID: <20260911115502.B177F1F000FF@smtp.kernel.org> (raw)
In-Reply-To: <20260911114014.79139-7-ketil.johnsen@arm.com>

Thank you for your contribution! Sashiko AI review found 4 potential issue(s) to consider:
- [High] An unprivileged userspace process can trigger a full GPU reset by omitting the protected suspend buffer during group creation and then submitting commands that switch to protected mode.
- [High] Slow reset path triggers a NULL pointer dereference on the uninitialized protected firmware section in `panthor_fw_init_section_mem`.
- [Low] Data race on the `ptdev->protm.info.state` flag.
- [Low] Mixing `guard()` and `goto`-based cleanup in `panthor_fw_protm_init` violates subsystem cleanup guidelines.
--

commit b7ec40f4bb5c3ae17349c8d0c7a683e90abc16c4
Author: Boris Brezillon <boris.brezillon@collabora.com>
Subject: drm/panthor: Expose protected rendering features

This commit introduces extensions to the Panthor uAPI to support protected
rendering. It adds a new IOCTL for providing protected firmware memory and
extends group creation to allow userspace to provide a protected suspend
buffer.

> diff --git a/drivers/gpu/drm/panthor/panthor_fw.c b/drivers/gpu/drm/panthor/panthor_fw.c
> index 96770ce34da84..4b44baf82a037 100644
> --- a/drivers/gpu/drm/panthor/panthor_fw.c
> +++ b/drivers/gpu/drm/panthor/panthor_fw.c

[ ... ]

> @@ -644,35 +677,36 @@ static int panthor_fw_load_section_entry(struct panthor_device *ptdev,
>  		section->name = name;
>  	}
>  
> -	if (section_size) {
> -		u32 cache_mode = hdr.flags & CSF_FW_BINARY_IFACE_ENTRY_CACHE_MODE_MASK;
> -		u32 vm_map_flags = 0;
> -		u64 va = hdr.va.start;
> +	section->size = section_size;
> +	section->va = hdr.va.start;
>  
> -		if (!(hdr.flags & CSF_FW_BINARY_IFACE_ENTRY_WR))
> -			vm_map_flags |= DRM_PANTHOR_VM_BIND_OP_MAP_READONLY;
> +	if (hdr.flags & CSF_FW_BINARY_IFACE_ENTRY_PROT) {
> +		if (ptdev->fw->protm_section) {
> +			drm_err(&ptdev->base,
> +				"Only one protected section supported\n");
> +			return -EINVAL;
> +		}
>  
> -		if (!(hdr.flags & CSF_FW_BINARY_IFACE_ENTRY_EX))
> -			vm_map_flags |= DRM_PANTHOR_VM_BIND_OP_MAP_NOEXEC;
> +		ptdev->protm.info.fw_protected_sections_size =
> +			ALIGN(section->size, vm_pgsz);
> +		ptdev->fw->protm_section = section;
> +	}
>  
> -		/* TODO: CSF_FW_BINARY_IFACE_ENTRY_CACHE_MODE_*_COHERENT are mapped to
> -		 * non-cacheable for now. We might want to introduce a new
> -		 * IOMMU_xxx flag (or abuse IOMMU_MMIO, which maps to device
> -		 * memory and is currently not used by our driver) for
> -		 * AS_MEMATTR_AARCH64_SHARED memory, so we can take benefit
> -		 * of IO-coherent systems.
> -		 */
> -		if (cache_mode != CSF_FW_BINARY_IFACE_ENTRY_CACHE_MODE_CACHED)
> -			vm_map_flags |= DRM_PANTHOR_VM_BIND_OP_MAP_UNCACHED;
> +	/* Defer the section->mem creation if this is a protected entry.
> +	 * This will be populated when DRM_IOCTL_PANTHOR_PROTM_INIT is called.
> +	 */
> +	if (section->size && !(hdr.flags & CSF_FW_BINARY_IFACE_ENTRY_PROT)) {
> +		u32 vm_map_flags = section_vm_map_flags(section);

[Severity: High]
Can this cause a kernel panic if a GPU hang occurs before the protected mode
is initialized?

Because section->mem is intentionally left as NULL here for protected
sections, if an unprivileged user triggers a GPU hang before calling the
PROTM_INIT ioctl, the slow reset path will be invoked. When
panthor_reload_fw_sections() iterates over all sections, it calls
panthor_fw_init_section_mem() which dereferences section->mem without checking
if it is valid (e.g., bool was_mapped = !!section->mem->kmap). 

Would it make sense to skip uninitialized protected sections during reset?

[ ... ]

> @@ -1566,6 +1605,66 @@ int panthor_fw_protm_exit(struct panthor_device *ptdev, u32 timeout_ms)
>  	return ret;
>  }
>  
> +int panthor_fw_protm_init(struct drm_file *file,
> +			  struct drm_panthor_protm_init *args)
> +{
> +	struct panthor_file *pfile = file->driver_priv;
> +	struct panthor_device *ptdev = pfile->ptdev;
> +	struct panthor_fw_section *protm_section = ptdev->fw->protm_section;
> +	struct drm_gem_object *obj;
> +	u32 vm_map_flags;
> +	int cookie, ret = 0;
> +
> +	if (!capable(CAP_SYS_MODULE))
> +		return -EPERM;
> +
> +	if (args->pad)
> +		return -EINVAL;
> +
> +	if (!protm_section || !protm_section->size)
> +		return -EINVAL;
> +
> +	guard(mutex)(&ptdev->fw->protm_init_lock);

[Severity: Low]
Is it safe to mix guard() and goto-based cleanup in the same function?

The cleanup subsystem guidelines suggest avoiding the mixture of scope-based
locks like guard(mutex) with goto labels (such as out_gem_put and
out_dev_exit) in the same routine, as it can lead to confusing ownership
semantics and future maintenance bugs.

> +
> +	if (ptdev->protm.info.state & DRM_PANTHOR_PROTM_INITIALIZED)
> +		return 0;
> +
> +	if (!drm_dev_enter(&ptdev->base, &cookie))
> +		return -ENODEV;
> +
> +	obj = drm_gem_object_lookup(file,
> +				    args->fw_protected_sections_bo_handle);
> +	if (!obj) {
> +		ret = -ENOENT;
> +		goto out_dev_exit;
> +	}
> +
> +	if (obj->size < ptdev->protm.info.fw_protected_sections_size) {
> +		ret = -EINVAL;
> +		goto out_gem_put;
> +	}
> +
> +	vm_map_flags = section_vm_map_flags(protm_section);
> +
> +	protm_section->mem = panthor_kernel_bo_import(
> +		ptdev, panthor_fw_vm(ptdev), to_panthor_bo(obj), vm_map_flags,
> +		protm_section->va, protm_section->size);
> +	if (IS_ERR(protm_section->mem)) {
> +		ret = PTR_ERR(protm_section->mem);
> +		protm_section->mem = NULL;
> +		goto out_gem_put;
> +	}
> +
> +	ptdev->protm.info.state |= DRM_PANTHOR_PROTM_INITIALIZED;

[Severity: Low]
Could this non-atomic modification cause torn reads or compiler reordering
issues?

This updates ptdev->protm.info.state using a bitwise OR, but the same state
flag is read concurrently in cs_slot_process_protm_pending_event_locked()
without locks or READ_ONCE().

> +
> +out_gem_put:
> +	drm_gem_object_put(obj);
> +
> +out_dev_exit:
> +	drm_dev_exit(cookie);
> +	return ret;
> +}

[ ... ]

> diff --git a/drivers/gpu/drm/panthor/panthor_sched.c b/drivers/gpu/drm/panthor/panthor_sched.c
> index 1fe77e5c41995..d73fc2f6633a6 100644
> --- a/drivers/gpu/drm/panthor/panthor_sched.c
> +++ b/drivers/gpu/drm/panthor/panthor_sched.c

[ ... ]

> @@ -1429,10 +1429,15 @@ cs_slot_process_protm_pending_event_locked(struct panthor_device *ptdev,
>  	if (!group)
>  		return;
>  
> -	/* Do not allow user space work to switch into protected mode, as we
> -	 * do not fully support this quite yet.
> +	/* Do not allow user space work to switch into protected mode if we
> +	 * do not support protected mode on this device.
> +	 * User space should query (and init) this support before attempting
> +	 * to use such GPU instructions.
>  	 */
> -	atomic_or(BIT(cs_id), &group->fatal_queues);
> +	if (!(ptdev->protm.info.state & DRM_PANTHOR_PROTM_INITIALIZED))
> +		atomic_or(BIT(cs_id), &group->fatal_queues);
> +	else
> +		atomic_or(BIT(cs_id), &group->protm_pending_queues);
>  
>  	sched_queue_delayed_work(sched, tick, 0);
>  }

[Severity: High]
Does this allow an unprivileged userspace process to trigger a full
system-wide GPU reset?

The logic here approves a transition to protected mode by only checking the
global DRM_PANTHOR_PROTM_INITIALIZED flag. However, if a user creates a
group with protected_suspend_bo_handle set to 0 (resulting in
group->protm_suspend_buf being NULL), they can still submit a PROT_REGION
command. 

Because the scheduler does not verify if the specific group provided a valid
suspend buffer, the hardware interface gets programmed with a zero address
for the suspend buffer in panthor_group_bind_locked(). When the firmware
later attempts to suspend the group, it writes to address 0, causing an
unrecoverable exception and Denial of Service.

Should this also check if group->protm_suspend_buf is valid?

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260911114014.79139-1-ketil.johnsen@arm.com?part=6

  reply	other threads:[~2026-09-11 11:55 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-09-11 11:40 [PATCH v3 0/6] drm/panthor: Protected mode support for Mali CSF GPUs Ketil Johnsen
2026-09-11 11:40 ` [PATCH v3 1/6] drm/panthor: De-duplicate FW memory section sync Ketil Johnsen
2026-09-11 11:40 ` [PATCH v3 2/6] drm/panthor: Minor scheduler refactoring Ketil Johnsen
2026-09-11 14:23   ` Boris Brezillon
2026-09-11 11:40 ` [PATCH v3 3/6] drm/panthor: Pass drm_file instead of panthor_file Ketil Johnsen
2026-09-11 11:40 ` [PATCH v3 4/6] drm/panthor: Don't allocate protm_suspend_buf Ketil Johnsen
2026-09-11 11:40 ` [PATCH v3 5/6] drm/panthor: Add support for entering and exiting protected mode Ketil Johnsen
2026-09-11 11:56   ` sashiko-bot
2026-09-11 11:40 ` [PATCH v3 6/6] drm/panthor: Expose protected rendering features Ketil Johnsen
2026-09-11 11:55   ` sashiko-bot [this message]
2026-09-11 14:42   ` Boris Brezillon

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260911115502.B177F1F000FF@smtp.kernel.org \
    --to=sashiko-bot@kernel.org \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=ketil.johnsen@arm.com \
    --cc=sashiko-reviews@lists.linux.dev \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.