From: sashiko-bot@kernel.org
To: leow149 <leow149@lucidmail.xyz>
Cc: dri-devel@lists.freedesktop.org, linux-sunxi@lists.linux.dev
Subject: Re: [RFC PATCH v8] arm64: allwinner: add TrimUI Smart Pro (A133) board support
Date: Sat, 12 Sep 2026 23:45:24 +0000 [thread overview]
Message-ID: <20260912234524.A02681F000FF@smtp.kernel.org> (raw)
In-Reply-To: <20260912233238.110960-1-leow149@lucidmail.xyz>
Thank you for your contribution! Sashiko AI review found 5 potential issue(s) to consider:
New issues:
- [High] Sleeping in Atomic Context Violation during DRM encoder callbacks.
- [High] Unbalanced DSI clock gate lifecycle during DPMS ON/OFF cycle permanently disables the display.
- [High] Denial of Service (CPU Hog) from defeating unhandled IRQ storm protection.
Pre-existing issues:
- [High] TOCTOU race condition causing lost interrupts due to RMW on a Write-0-to-Clear (W0C) register.
- [High] TOCTOU Use-After-Free race condition in TCON TOP driver data access.
--
commit 739730d576ddf8a50358b7451672c4a7b9d896ed
Author: leow149 <leow149@lucidmail.xyz>
arm64: allwinner: add TrimUI Smart Pro (A133) board support
Board bring-up for the TrimUI Smart Pro handheld (Allwinner A133 Plus). This
adds the new DTS, an OTM1289A DSI panel driver, a new PWM driver, and DRM
display pipeline configurations.
> diff --git a/drivers/gpu/drm/sun4i/sun4i_tcon.c b/drivers/gpu/drm/sun4i/sun4i_tcon.c
> index bf405a2aa3249..9d916efa8566b 100644
> --- a/drivers/gpu/drm/sun4i/sun4i_tcon.c
> +++ b/drivers/gpu/drm/sun4i/sun4i_tcon.c
> @@ -226,20 +226,40 @@ void sun4i_tcon_set_status(struct sun4i_tcon *tcon,
>
> sun4i_tcon_channel_set_status(tcon, channel, enabled);
>
> + /*
> + * On disable, stop the DSI/CPU-mode retrigger timer/IRQ. This is a
> + * backstop for boards where sun6i_dsi_encoder_disable() itself
> + * already did this (see sun4i_tcon_dsi_stop_retrigger()'s comment
> + * for why that earlier call site is the one that actually matters)
> + * -- harmless and idempotent to also do it here.
> + */
> + if (!enabled) {
> + sun4i_tcon_dsi_stop_retrigger(tcon);
> + /*
> + * sun4i_tcon0_mode_set() only ever calls
> + * sun4i_tcon0_set_dsi_gate(tcon, true) -- there was no
> + * matching false call anywhere, leaking this gate (and, via
> + * CLK_IGNORE_UNUSED, its CLK_MIPI_DSI parent) permanently on
> + * past this TCON's own disable. Ungate here instead; this
> + * call is a safe no-op on boards without a matching TCON TOP
> + * remote node (see its own comment), so it's fine to call
> + * unconditionally on every disable, not just DSI ones.
> + */
> + sun4i_tcon0_set_dsi_gate(tcon, false);
> + } else if (!tcon->dsi_cpu_mode && tcon->irq && !tcon->irq_enabled) {
> + /*
> + * Non-DSI boards: tcon->irq was requested IRQF_NO_AUTOEN for
> + * every board using this driver (needed for the DSI/CPU-mode
> + * path's delayed enable -- see the comment on
> + * sun4i_tcon_init_irq()), so it needs an explicit enable_irq()
> + * somewhere for boards that never take that path at all. This
> + * runs on every CRTC enable -- both a real modeset (paired
> + * with sun4i_tcon_mode_set() in the same commit) and a plain
> + * DPMS off/on cycle, which does NOT call mode_set_nofb/
> + * sun4i_tcon_mode_set() again.
> + */
> + enable_irq(tcon->irq);
> + tcon->irq_enabled = true;
> + }
> }
[Severity: High]
What re-enables the DSI gate when the display wakes up from DPMS OFF?
While sun4i_tcon0_set_dsi_gate(tcon, false) is called when enabled is false,
the true branch here lacks a corresponding sun4i_tcon0_set_dsi_gate(tcon, true).
Since the gate is only enabled in sun4i_tcon_mode_set(), a simple DPMS ON
that doesn't trigger a full modeset might leave the clock gate permanently off.
[ ... ]
> @@ -772,12 +772,16 @@ void sun4i_tcon_dsi_stop_retrigger(struct sun4i_tcon *tcon)
> {
> hrtimer_cancel(&tcon->dsi_retrigger_timer);
> /*
> * disable_irq() (which might_sleep()s internally) is safe here:
> * both call sites run in normal process/workqueue context, not a
> * genuinely atomic section -- see the comment on
> * sun4i_tcon_set_status()'s disable_irq() call for why (this
> * function is called from there too, unchanged reasoning).
> */
> if (tcon->irq_enabled) {
> disable_irq(tcon->irq);
> tcon->irq_enabled = false;
> }
> }
[Severity: High]
Is it entirely safe to invoke disable_irq() here?
Because disable_irq() can sleep, and this path can be reached from
sun6i_dsi_encoder_disable() during DRM non-blocking atomic commits, executing
it in an atomic context would lead to a scheduling-while-atomic violation.
[ ... ]
> @@ -1151,12 +1151,33 @@ static irqreturn_t sun4i_tcon_handler(int irq, void *private)
> {
> struct sun4i_tcon *tcon = private;
> struct drm_device *drm = tcon->drm;
> struct sun4i_crtc *scrtc = tcon->crtc;
> struct sunxi_engine *engine = scrtc->engine;
> unsigned int status;
> + bool handled;
>
> regmap_read(tcon->regs, SUN4I_TCON_GINT0_REG, &status);
>
> + handled = tcon->dsi_cpu_mode ||
> + (status & (SUN4I_TCON_GINT0_VBLANK_INT(0) |
> + SUN4I_TCON_GINT0_VBLANK_INT(1) |
> + SUN4I_TCON_GINT0_TCON0_TRI_FINISH_INT |
> + SUN4I_TCON_GINT0_TCON0_FSYNC_INT));
> +
> + if (!handled)
> + return IRQ_NONE;
[Severity: High]
Could this unconditional handled = true assignment in DSI/CPU mode defeat
the kernel's unhandled IRQ storm protection?
If a hardware glitch causes the line to remain asserted, or if another device
sharing this IRQ asserts, the kernel will never disable the line, potentially
causing an infinite interrupt loop and a complete system lockup.
> /* Acknowledge the interrupt */
> regmap_update_bits(tcon->regs, SUN4I_TCON_GINT0_REG,
> SUN4I_TCON_GINT0_VBLANK_INT(0) |
> SUN4I_TCON_GINT0_VBLANK_INT(1) |
> - SUN4I_TCON_GINT0_TCON0_TRI_FINISH_INT,
> + SUN4I_TCON_GINT0_TCON0_TRI_FINISH_INT |
> + SUN4I_TCON_GINT0_TCON0_TRI_COUNTER_INT |
> + SUN4I_TCON_GINT0_TCON0_FSYNC_INT,
> 0);
[Severity: High]
This is a pre-existing issue, but using regmap_update_bits() on a
Write-0-to-Clear (W0C) register like SUN4I_TCON_GINT0_REG seems to introduce
a TOCTOU race condition.
Because it performs a read-modify-write, if a new interrupt bit asserts between
the read and the write, writing 0 will silently clear it in hardware without
the handler ever processing it.
> diff --git a/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c b/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c
> index d504ae5832949..fae312e2ebf55 100644
> --- a/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c
> +++ b/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c
[ ... ]
> @@ -910,21 +910,34 @@ static void sun6i_dsi_encoder_enable(struct drm_encoder *encoder)
>
> sun6i_dsi_start(dsi, DSI_START_HSC);
>
> udelay(1000);
>
> + if (dsi->panel)
> + drm_panel_prepare(dsi->panel);
> +
> + if (dsi->panel)
> + drm_panel_enable(dsi->panel);
> +
> sun6i_dsi_start(dsi, DSI_START_HSD);
[Severity: High]
Since DRM encoder enable callbacks can execute in atomic context during
non-blocking commits, is it safe to invoke drm_panel_prepare() here?
drm_panel_prepare() internally uses sleeping functions like msleep() which
could lead to scheduling-while-atomic violations.
[ ... ]
> @@ -962,6 +962,21 @@ static void sun6i_dsi_encoder_disable(struct drm_encoder *encoder)
> {
> struct sun6i_dsi *dsi = encoder_to_sun6i_dsi(encoder);
>
> DRM_DEBUG_DRIVER("Disabling DSI output\n");
>
> + if (dsi->tcon)
> + sun4i_tcon_dsi_stop_retrigger(dsi->tcon);
> +
> if (dsi->panel) {
> drm_panel_disable(dsi->panel);
> drm_panel_unprepare(dsi->panel);
> }
[Severity: High]
Does executing drm_panel_disable() here conflict with atomic context
requirements?
Because this is invoked from the encoder disable path, which may run in atomic
context, it will eventually acquire mutexes in the PWM driver, causing the
process to sleep.
> diff --git a/drivers/gpu/drm/sun4i/sun8i_tcon_top.c b/drivers/gpu/drm/sun4i/sun8i_tcon_top.c
> index 9cbd655518b20..3f519df7d97dc 100644
> --- a/drivers/gpu/drm/sun4i/sun8i_tcon_top.c
> +++ b/drivers/gpu/drm/sun4i/sun8i_tcon_top.c
> @@ -157,6 +157,63 @@ int sun8i_tcon_top_set_dsi_gate(struct device *dev, bool enable)
> {
> struct sun8i_tcon_top *tcon_top = dev_get_drvdata(dev);
> unsigned long flags;
> u32 val;
>
> if (!sun8i_tcon_top_node_is_tcon_top(dev->of_node)) {
> dev_err(dev, "Device is not TCON TOP!\n");
> return -EINVAL;
> }
>
> + if (!tcon_top)
> + return -ENODEV;
> +
> + spin_lock_irqsave(&tcon_top->reg_lock, flags);
[Severity: High]
This isn't a bug introduced by this patch, but dereferencing tcon_top here
contains a TOCTOU Use-After-Free race condition.
If the TCON TOP driver is unbound concurrently, tcon_top might be freed
before the spin_lock_irqsave(&tcon_top->reg_lock, flags) call executes.
> diff --git a/drivers/pwm/pwm-sun50i-a133.c b/drivers/pwm/pwm-sun50i-a133.c
> new file mode 100644
> --- /dev/null
> +++ b/drivers/pwm/pwm-sun50i-a133.c
> @@ -140,6 +140,94 @@ static int pwm_a133_apply(struct pwm_chip *chip, struct pwm_device *pwm,
> const struct pwm_state *state)
> {
> struct pwm_a133 *pc = to_pwm_a133(chip);
> unsigned int ch = pwm->hwpwm;
> u32 entire_cycle, act_cycle, prescale_k, val;
> u32 pccr_reg = (ch < 2) ? PWM_A133_PCCR01_REG : PWM_A133_PCCR23_REG;
> int ret;
>
> if (!state->enabled) {
> mutex_lock(&pc->lock);
[Severity: High]
Can acquiring a mutex here be safely performed?
This function is invoked from panel disable/enable paths. Since those can
run during DRM non-blocking commits, acquiring a sleeping lock could cause
system deadlocks.
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260912233238.110960-1-leow149@lucidmail.xyz?part=1
next prev parent reply other threads:[~2026-09-12 23:45 UTC|newest]
Thread overview: 18+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-12 6:02 [RFC PATCH] arm64: allwinner: add TrimUI Smart Pro (A133) board support leow149
2026-09-12 6:27 ` sashiko-bot
2026-09-12 7:57 ` [RFC PATCH v2] " leow149
2026-09-12 8:14 ` sashiko-bot
2026-09-12 10:31 ` [RFC PATCH v3] " leow149
2026-09-12 10:46 ` sashiko-bot
2026-09-12 11:43 ` [RFC PATCH v4] " leow149
2026-09-12 11:58 ` sashiko-bot
2026-09-12 21:43 ` [RFC PATCH v5] " leow149
2026-09-12 22:01 ` sashiko-bot
2026-09-12 22:24 ` [RFC PATCH v6] " leow149
2026-09-12 22:38 ` sashiko-bot
2026-09-12 23:01 ` [RFC PATCH v7] " leow149
2026-09-12 23:14 ` sashiko-bot
2026-09-12 23:32 ` [RFC PATCH v8] " leow149
2026-09-12 23:45 ` sashiko-bot [this message]
2026-09-12 23:39 ` [RFC PATCH v7] " Andre Przywara
2026-09-13 0:08 ` leow149
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=20260912234524.A02681F000FF@smtp.kernel.org \
--to=sashiko-bot@kernel.org \
--cc=dri-devel@lists.freedesktop.org \
--cc=leow149@lucidmail.xyz \
--cc=linux-sunxi@lists.linux.dev \
--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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox