From: sashiko-bot@kernel.org
To: "Ryan Roberts" <ryan.roberts@arm.com>
Cc: kvmarm@lists.linux.dev, kvm@vger.kernel.org,
devicetree@vger.kernel.org, dri-devel@lists.freedesktop.org,
robh@kernel.org, conor+dt@kernel.org,
"Oliver Upton" <oupton@kernel.org>,
"Marc Zyngier" <maz@kernel.org>
Subject: Re: [RFC PATCH v2 06/15] misc/arm-cla: Accelerator context save and restore
Date: Thu, 15 Oct 2026 14:41:42 +0000 [thread overview]
Message-ID: <sashiko-outbox-172972@kernel.org> (raw)
In-Reply-To: <20261015142552.4128028-7-ryan.roberts@arm.com>
Thank you for your contribution! Sashiko AI review found 4 potential issue(s) to consider:
- [High] misc: arm-cla: max_regidx truncated to 0 on 32-bit architectures
- [High] misc: arm-cla: partially overwritten context state left valid on error
- [High] misc: arm-cla: NULL pointer dereference in cla_ctx_free_regs()
- [High] misc: arm-cla: ctx->regs indexed by ctx_id instead of device index
--
commit 3663e5cba865127a89c5cdad88c78f8b24a13ae0
Author: Jean-Philippe Brucker <jpb@kernel.org>
misc/arm-cla: Accelerator context save and restore
Add helpers to save and restore CLA context for later domain switching.
The saved state includes DATA registers, LRESP, per-accelerator SRSTATE
and any implementation-defined internal accelerator state exposed
through the IAS register window.
> diff --git a/drivers/misc/arm-cla/cla-regs.c b/drivers/misc/arm-cla/cla-regs.c
> new file mode 100644
> index 0000000000000..2452a7601990f
> --- /dev/null
> +++ b/drivers/misc/arm-cla/cla-regs.c
[ ... ]
> +static int cla_regs_save_accel(struct cla_dev *dev, unsigned int accid,
> + struct cla_regs_pl0 *regs, size_t *regstate_off)
> +{
[ ... ]
> + if (regstate_size) {
> + ret = cla_op_regread(dev, accid, CLA_REG_IASn, regstate_size,
> + regs->regstate + *regstate_off);
[Severity: High]
Does this code unconditionally fail on 32-bit architectures?
cla_op_regread() calls cla_op_access_reg(). In that function:
drivers/misc/arm-cla/cla-ops.c:cla_op_access_reg() {
...
unsigned long max_regidx;
...
case CLA_LAUNCH_OP_REGREAD:
case CLA_LAUNCH_OP_REGWRITE:
max_regidx = 0x100000000;
break;
...
if (WARN_ON(regidx + nregs > max_regidx))
return -EINVAL;
}
max_regidx is declared as an unsigned long and assigned the 33-bit constant
0x100000000. On 32-bit platforms, unsigned long is 32 bits wide, so the
assignment silently truncates the value to 0.
With max_regidx being 0, the bounds check regidx + nregs > 0 is
unconditionally true since nregs must be greater than zero. This causes
cla_op_access_reg() to unconditionally fail with -EINVAL, completely breaking
the newly added context save and restore features here.
> + if (ret) {
> + cla_err(dev, "failed to save regstate: %d\n", ret);
> + return ret;
> + }
> + }
[ ... ]
> +static int cla_regs_uninstall_pl0(struct cla_dev *dev, struct cla_ctx *ctx,
> + unsigned int ctx_id)
> +{
> + int i;
> + int ret;
> + unsigned int accid;
> + size_t regstate_off = 0;
> + struct cla_regs_pl0 *regs = ctx->regs[ctx_id];
[Severity: High]
Does this code index the ctx->regs array with the wrong identifier?
cla_ctx_alloc_regs() allocates ctx->regs as an array of size domain->nr_devs,
where each element index corresponds directly to a specific device in the
domain (domain->devs[i]).
However, this uses ctx_id to index the array. ctx_id represents the logical
context number within the domain, not the hardware device index.
If a user allocates more contexts than the number of hardware devices
(ctx_id >= domain->nr_devs), this causes an immediate out-of-bounds array
access. Even if ctx_id is within bounds, using it instead of the device index
results in reading and writing state to the wrong device's register array.
> +
> + /*
> + * When we interrupt the user process in the middle of launching a
> + * command, we have to wait for LRESP_PENDING to clear before we can
> + * launch a new command or save the DATA registers.
> + */
> + ret = cla_op_wait_lresp(dev, ®s->lresp);
> + if (ret)
> + return ret;
> +
> + for (i = 0; i < CLA_NUM_DATA_REGS; i++)
> + regs->data[i] = cla_reg_read(dev, CLA_REG_DATA(i));
> +
> + cla_for_each_accid(dev, accid) {
> + ret = cla_regs_save_accel(dev, accid, regs, ®state_off);
> + if (ret)
> + return ret;
> + }
> +
> + regs->accel_valid = true;
[Severity: High]
Does this leave a partially overwritten context state marked as valid on error?
If cla_regs_save_accel() fails for an accelerator (e.g., due to a hardware
timeout), the function returns the error immediately. Because
regs->accel_valid is not cleared to false at the start of the function, it
retains its prior value.
If the context was previously successfully saved (regs->accel_valid == true),
it remains marked as valid, despite the buffer now holding a torn,
inconsistent mix of old state and newly overwritten partial data.
On the next context switch, cla_regs_install_pl0() will see
accel_valid == true and silently restore this corrupted partial state into the
hardware, leading to unpredictable hardware behavior and data corruption.
> +
> + /*
> + * "If the accelerator is non idle when ENTERSR is launched, then a
[ ... ]
> +static int cla_regs_install_pl0(struct cla_dev *dev, struct cla_ctx *ctx,
> + unsigned int ctx_id)
> +{
> + int i;
> + int ret;
> + unsigned int accid;
> + size_t regstate_off = 0;
> + struct cla_regs_pl0 *regs = ctx->regs[ctx_id];
[Severity: High]
As with cla_regs_uninstall_pl0() above, does this code also index the
ctx->regs array with the wrong identifier?
Using ctx_id instead of the device index will cause an out-of-bounds array
access or access the wrong device's register array.
> +
> + cla_for_each_accid(dev, accid) {
[ ... ]
> +void cla_ctx_free_regs(struct cla_domain *domain, struct cla_ctx *ctx)
> +{
> + int i;
> +
> + for (i = 0; i < domain->nr_devs; i++)
> + kvfree(ctx->regs[i]);
[Severity: High]
Can this code cause a NULL pointer dereference?
In cla_ctx_alloc_regs(), if the initial memory allocation for regs_ptrs fails,
the function returns -ENOMEM without assigning a value to ctx->regs. Assuming
ctx was zero-initialized by the caller, ctx->regs remains NULL.
When the caller handles this failure by invoking this common teardown path, it
iterates and unconditionally executes kvfree(ctx->regs[i]). Since ctx->regs is
NULL, array indexing results in a NULL pointer dereference.
> + kfree(ctx->regs);
> +}
--
Sashiko AI review · https://sashiko.dev/#/patchset/20261015142552.4128028-1-ryan.roberts@arm.com?part=6
next prev parent reply other threads:[~2026-10-15 14:41 UTC|newest]
Thread overview: 32+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-15 14:25 [RFC PATCH v2 00/15] Arm Core Local Accelerator Driver Ryan Roberts
2026-10-15 14:25 ` [RFC PATCH v2 01/15] misc/arm-cla: Add driver skeleton and documentation Ryan Roberts
2026-10-15 14:35 ` sashiko-bot
2026-10-15 14:25 ` [RFC PATCH v2 02/15] misc/arm-cla: Add launch operation helpers Ryan Roberts
2026-10-15 14:42 ` sashiko-bot
2026-10-15 16:17 ` Greg Kroah-Hartman
2026-10-15 16:32 ` Ryan Roberts
2026-10-15 14:25 ` [RFC PATCH v2 03/15] dt-bindings: misc: Add Arm Core Local Accelerator Ryan Roberts
2026-10-15 14:25 ` [RFC PATCH v2 04/15] misc/arm-cla: Probe firmware-described devices Ryan Roberts
2026-10-15 14:37 ` sashiko-bot
2026-10-15 14:25 ` [RFC PATCH v2 05/15] misc/arm-cla: Initialize devices on CPU bringup Ryan Roberts
2026-10-15 14:25 ` [RFC PATCH v2 06/15] misc/arm-cla: Accelerator context save and restore Ryan Roberts
2026-10-15 14:41 ` sashiko-bot [this message]
2026-10-15 14:25 ` [RFC PATCH v2 07/15] misc/arm-cla: Set up memory translation context Ryan Roberts
2026-10-15 14:25 ` [RFC PATCH v2 08/15] misc/arm-cla: Manage domain contexts Ryan Roberts
2026-10-15 14:38 ` sashiko-bot
2026-10-15 14:25 ` [RFC PATCH v2 09/15] misc/arm-cla: Add userspace interface Ryan Roberts
2026-10-15 14:47 ` sashiko-bot
2026-10-15 14:25 ` [RFC PATCH v2 10/15] KVM: arm64: Introduce support to pin VMIDs Ryan Roberts
2026-10-15 14:38 ` sashiko-bot
2026-10-15 14:25 ` [RFC PATCH v2 11/15] KVM: arm64: Export stage-2 MMU config Ryan Roberts
2026-10-15 14:43 ` sashiko-bot
2026-10-15 14:25 ` [RFC PATCH v2 12/15] vfio: Support VFIO devices that access the CPU MMU Ryan Roberts
2026-10-15 14:44 ` sashiko-bot
2026-10-15 16:44 ` Jason Gunthorpe
2026-10-15 14:25 ` [RFC PATCH v2 13/15] misc/arm-cla: Add stage-2 MTC and VM context switch Ryan Roberts
2026-10-15 14:40 ` sashiko-bot
2026-10-15 14:25 ` [RFC PATCH v2 14/15] misc/arm-cla: Support exclusive context assignment Ryan Roberts
2026-10-15 14:41 ` sashiko-bot
2026-10-15 14:25 ` [RFC PATCH v2 15/15] misc/arm-cla: Add vfio-mdev user interface Ryan Roberts
2026-10-15 14:49 ` sashiko-bot
2026-10-15 16:41 ` Jason Gunthorpe
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=sashiko-outbox-172972@kernel.org \
--to=sashiko-bot@kernel.org \
--cc=conor+dt@kernel.org \
--cc=devicetree@vger.kernel.org \
--cc=dri-devel@lists.freedesktop.org \
--cc=kvm@vger.kernel.org \
--cc=kvmarm@lists.linux.dev \
--cc=maz@kernel.org \
--cc=oupton@kernel.org \
--cc=robh@kernel.org \
--cc=ryan.roberts@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.