* [PATCH net-next] net: stmmac: Simplify ioctl handling
From: Maxime Chevallier @ 2026-07-18 14:38 UTC (permalink / raw)
To: Andrew Lunn, Jakub Kicinski, davem, Eric Dumazet, Paolo Abeni,
Simon Horman, Maxime Coquelin, Alexandre Torgue, Russell King
Cc: Maxime Chevallier, thomas.petazzoni, Alexis Lothoré, netdev,
linux-kernel, linux-arm-kernel, linux-stm32
Now that timestamping is controlled through an NDO, we can simply
call phylink_mii_ioctl() to handle ioctls.
The only functional difference is that phylink_mii_ioctl() ->
phy_mii_ioctl() can handle SIOCSHWTSTAMP, but this no longer happens
as this ioctl is not longer dispatched to the ndo_eth_ioctl().
Signed-off-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
---
Looking at this, I'm wondering if we can't just get rid of SIOCSHWTSTAMP
handling in phy_mii_ioctl(). Looks like we can ?
.../net/ethernet/stmicro/stmmac/stmmac_main.c | 17 +++--------------
1 file changed, 3 insertions(+), 14 deletions(-)
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index 2a0d7eff88d3..562d20830b94 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -6371,28 +6371,17 @@ static irqreturn_t stmmac_msi_intr_rx(int irq, void *data)
* @rq: An IOCTL specific structure, that can contain a pointer to
* a proprietary structure used to pass information to the driver.
* @cmd: IOCTL command
- * Description:
- * Currently it supports the phy_mii_ioctl(...) and HW time stamping.
+ * Description: Forward the PHY ioctls to phylink
+ * Return: Zero on success or negative error code.
*/
static int stmmac_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
{
struct stmmac_priv *priv = netdev_priv (dev);
- int ret = -EOPNOTSUPP;
if (!netif_running(dev))
return -EINVAL;
- switch (cmd) {
- case SIOCGMIIPHY:
- case SIOCGMIIREG:
- case SIOCSMIIREG:
- ret = phylink_mii_ioctl(priv->phylink, rq, cmd);
- break;
- default:
- break;
- }
-
- return ret;
+ return phylink_mii_ioctl(priv->phylink, rq, cmd);
}
static int stmmac_setup_tc_block_cb(enum tc_setup_type type, void *type_data,
--
2.55.0
^ permalink raw reply related
* Re: [PATCH 5/6] iommu: Add Broadcom BCM2712 IOMMU driver
From: Jason Gunthorpe @ 2026-07-18 14:32 UTC (permalink / raw)
To: Daniel Drake
Cc: Joerg Roedel (AMD), Will Deacon, Robin Murphy, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Florian Fainelli,
Broadcom internal kernel review list, iommu, linux-kernel,
devicetree, linux-rpi-kernel, linux-arm-kernel, nick.hollinghurst
In-Reply-To: <57f5675c-8bcd-4022-978b-9f7933bb0032@reactivated.net>
On Sat, Jul 18, 2026 at 09:39:48AM +0100, Daniel Drake wrote:
> I don't think I can use that because this setup uses an IOVA aperture at
> base 0xA00000000, whereas generic_pt assumes it is managing a 0-indexed
> virtual address space. So the driver has to intercept every incoming IOVA
> and translate for the aperture, see how map_pages calls:
When you say aperture here you mean we place an IOPTE at VA 0 but the
dma_addr_t for that has to be adjusted to 0xA00000000 ?
I wonder if DT can do this with dma-ranges or something, we have many
other conditions where the dma_addr_t and the internal physical have
offsets..
> I was wondering about making iommupt understand apertures and
> translate accordingly, but I imagine you would want to keep that
> kind of thing out of the generic fast path?
We already have pt_full_va_prefix() which isn't strictly an offset but
it it probably matches what this HW does.
You can implement it in the broadcom format and return the prefix value.
So long as the vasz fits within those trailing 0s. That's basically
free and has no runtime cost on other formats.
Jason
^ permalink raw reply
* Re: [PATCH mm-hotfixes v5 3/5] x86/mm/pat: acquire init_mm read lock on attribute change to avoid UAF
From: Lorenzo Stoakes (ARM) @ 2026-07-18 14:28 UTC (permalink / raw)
To: Mike Rapoport
Cc: Andrew Morton, Suren Baghdasaryan, Liam R. Howlett,
Vlastimil Babka, Shakeel Butt, David Hildenbrand, Michal Hocko,
Uladzislau Rezki, Toshi Kani, Dave Hansen, Andy Lutomirski,
Peter Zijlstra, Thomas Gleixner, Ingo Molnar, Borislav Petkov,
x86, H. Peter Anvin, Kiryl Shutsemau, Catalin Marinas,
Will Deacon, Dev Jain, Ryan Roberts, David Carlier, linux-mm,
linux-kernel, bpf, linux-arm-kernel, Denis V. Lunev, stable
In-Reply-To: <altbeuTZ0HCz_7HS@kernel.org>
On Sat, Jul 18, 2026 at 01:54:50PM +0300, Mike Rapoport wrote:
> On Fri, Jul 17, 2026 at 06:30:09PM +0100, Lorenzo Stoakes (ARM) wrote:
> > A previous commit protected us against races between ptdump and CPA
> > collapse, however one still exists between attribute changes and collapse
> > as reported by Denis V. Lunev (linked).
> >
> > When an attribute change arises, a lockless page table walker obtains a PTE
> > entry, which is later written to via set_pte_atomic():
> >
> > ...
> > -> change_page_attr_set_clr()
> > -> __change_page_attr_set_clr()
> > -> __change_page_attr()
> > -> _lookup_address_cpa()
> > -> lookup_address_in_pgd_attr()
> > -> [ lockless page table walker ]
> > -> set_pte_atomic()
> >
> > There is nothing preventing a concurrent CPA collapse which can free the
> > PTE that was retrieved here, resulting in a use-after-free.
> >
> > With the mmap write lock taken on init_mm over CPA collapse, we can now
> > resolve this race by acquiring an mmap read lock on init_mm over
> > __change_page_attr_set_clr().
> >
> > This locks across the whole operation over which the walk and the PTE entry
> > write occurs, solving the race.
> >
> > It is safe to do this here, as no spinlocks are held upon entry to
> > __change_page_attr_set_clr().
> >
> > The CPA_COLLAPSE flag is only set by set_memory_rox(), which exclusively
> > operates upon vmalloc ranges, and on x86 only within the module mapping
> > space.
> >
> > This is important, because some callers directly invoke
> > __change_page_attr_set_clr(), bypassing this lock. However, none of these
> > operate within the module mapping space.
> >
> > * cpa_process_alias() - a recursive helper called by
> > __change_page_attr_set_clr().
> > * __set_memory_enc_pgtable() - operates on the direct mapping and (via
> > __vmbus_establish_gpadl()) the vmalloc mapping space.
> > * __set_pages_[n]p() - called by set_direct_map_[invalid, default,
> > valid]_noflush(), __kernel_map_pages() - operates on the direct map.
> > * kernel_[un]map_pages_in_pgd() - operates on EFI ranges.
> >
> > This work is based upon Denis V. Lunev's excellent analysis of the bug with
> > gratitude.
> >
> > Link: https://lore.kernel.org/all/20260626163213.2284080-1-den@openvz.org/
> > Fixes: 41d88484c71c ("x86/mm/pat: restore large ROX pages after fragmentation")
> > Cc: stable@vger.kernel.org
> > Signed-off-by: Lorenzo Stoakes (ARM) <ljs@kernel.org>
> > ---
> > arch/x86/mm/pat/set_memory.c | 4 +++-
> > 1 file changed, 3 insertions(+), 1 deletion(-)
> >
> > diff --git a/arch/x86/mm/pat/set_memory.c b/arch/x86/mm/pat/set_memory.c
> > index d1e63f7d267f..301fb9e77d91 100644
> > --- a/arch/x86/mm/pat/set_memory.c
> > +++ b/arch/x86/mm/pat/set_memory.c
> > @@ -2122,7 +2122,9 @@ static int change_page_attr_set_clr(unsigned long *addr, int numpages,
> > cpa.curpage = 0;
> > cpa.force_split = force_split;
> >
> > - ret = __change_page_attr_set_clr(&cpa, 1);
> > + /* Avoid race with concurrent CPA collapse. */
> > + scoped_guard(mmap_read_lock, &init_mm)
> > + ret = __change_page_attr_set_clr(&cpa, 1);
>
> There's a small issue with this. debug_pagealloc_unmap_pages() ends up here
> and since it's called from __free_pages() it can be in an atomic context.
Not the case - the callstack is:
debug_pagealloc_unmap_pages()
-> __kernel_map_pages()
-> __set_pages_[n]p()
-> __change_page_attr_set_clr()
So it calls __change_page_attr_set_clr() not change_page_addr_set_clr()
and doesn't hit this code.
As per the commit msg, it (and all the other bare
__change_page_attr_set_clr() callers) do not hit ranges that can be
collapsed so the race doesn't exist there.
Also the CPA_NO_CHECK_ALIAS flag is set, meaning there's no weird aliasing
recursion via cpa_process_alias() (which in any case, also calls
__change_page_attr_set_clr() directly anyway).
>
> >
> > /*
> > * Check whether we really changed something:
> >
> > --
> > 2.55.0
> >
>
> --
> Sincerely yours,
> Mike.
Thanks, Lorenzo
^ permalink raw reply
* Re: [PATCH v12 02/29] arm64/fpsimd: Update FA64 and ZT0 enables when loading SME state
From: Mark Brown @ 2026-07-18 14:24 UTC (permalink / raw)
To: Fuad Tabba
Cc: Mark Rutland, Marc Zyngier, Joey Gouly, Catalin Marinas,
Suzuki K Poulose, Will Deacon, Paolo Bonzini, Jonathan Corbet,
Shuah Khan, Oliver Upton, Dave Martin, Ben Horgan,
Jean-Philippe Brucker, linux-arm-kernel, kvmarm, linux-kernel,
kvm, linux-doc, linux-kselftest, Peter Maydell, Eric Auger
In-Reply-To: <CA+EHjTw9rGvQyev-4i7zkO5bPPZKGYn858485dCs8iHmCi0t3w@mail.gmail.com>
[-- Attachment #1: Type: text/plain, Size: 1733 bytes --]
On Sat, Jul 18, 2026 at 02:30:04PM +0100, Fuad Tabba wrote:
> On Sat, 18 Jul 2026 at 01:35, Mark Brown <broonie@kernel.org> wrote:
> > Actually I remembered: while SCMR_EL1.LEN is self synchronising the
> > "without the need for explict synchronization" wording is not present
> > for SMCR_EL1.{FA64,EZT0} and this is no longer explicitly just an update
> > of LEN. It's possible I'm being overly paranoid here, I'll leave the
> > isb() and add a comment for the next version.
> I went through the ARM ARM (DDI 0487 M.c) on this and I don't think
> you're being overly paranoid, I believe the isb() is needed here.
Thanks for double checking so thoroughly.
> And task_fpsimd_load() does make indirect reads of both fields before
> the next context synchronization event: sme_load_state() executes LDR
> ZT0, whose execution at EL1 is trapped when SMCR_EL1.EZT0 is 0, and
> when PSTATE.SM is set sve_load_state() executes WRFFR, which is
> "illegal when executed in Streaming SVE mode, unless FEAT_SME_FA64 is
> implemented and enabled" (from the WRFFR description). The MSR SVCR in
> between doesn't provide the synchronization, since SVCR's
> self-synchronisation wording covers reads of its own SM and ZA fields
> only.
Yeah. We should be able to optimise this:
- If there is no change we don't need the isb().
- If only EZT0 changes and we load state where ZA is disabled then we
won't try to access ZT0.
- If only FA64 changes and we load state where streaming mode is
disabled then we won't try to access streaming mode FFR.
I've gone and implemented the first which will suppress the isb() for
current host kernel SME usage, the second two are starting to get more
fiddly than seems sensible to do right now.
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]
^ permalink raw reply
* Re: [PATCH v2 1/1] dt-bindings: soc: imx-iomuxc-gpr: allow bridge@18 as child node
From: Frank Li @ 2026-07-18 14:12 UTC (permalink / raw)
To: Rob Herring (Arm)
Cc: Fabio Estevam, imx, linux-arm-kernel, Pengutronix Kernel Team,
Conor Dooley, Frank Li, linux-kernel, Krzysztof Kozlowski,
Sascha Hauer, Peng Fan, devicetree, Shawn Guo
In-Reply-To: <178432353778.2692844.15138095566024676604.robh@kernel.org>
On Fri, Jul 17, 2026 at 04:25:37PM -0500, Rob Herring (Arm) wrote:
>
> On Fri, 17 Jul 2026 16:15:17 -0400, Frank.Li@oss.nxp.com wrote:
> > From: Frank Li <Frank.Li@nxp.com>
> >
> > The legacy i.MX6SX (>15 year) SoC imx-iomuxc-gpr contains one LDB_CTRL
> > register. Allow the LVDS Display Bridge(LDB) child node under
> > imx-iomuxc-gpr.
> >
> > Fix below CHECK_DTBS warnings:
> > arch/arm/boot/dts/nxp/imx/imx6sx-nitrogen6sx.dtb: syscon@20e4000 (fsl,imx6sx-iomuxc-gpr): '#address-cells', '#size-cells', 'bridge@18' do not match any of the regexes: '^ipu[12]_csi[01]_mux$', '^pinctrl-[0-9]+$
> >
> > Signed-off-by: Frank Li <Frank.Li@nxp.com>
> > ---
> > change in v2
> > - remove status = "disabled" at example
> > ---
> > .../bindings/soc/imx/fsl,imx-iomuxc-gpr.yaml | 58 +++++++++++++++++++
> > 1 file changed, 58 insertions(+)
> >
>
> My bot found errors running 'make dt_binding_check' on your patch:
I forget it is posted with other binding patch. please forget this one.
I will repost with whole serial.
Frank
>
> yamllint warnings/errors:
>
> dtschema/dtc warnings/errors:
> /builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/soc/imx/fsl,imx-iomuxc-gpr.example.dtb: syscon@20e4000 (fsl,imx6sx-iomuxc-gpr): bridge@18:reg: [[24, 4]] is too short
> from schema $id: http://devicetree.org/schemas/soc/imx/fsl,imx-iomuxc-gpr.yaml
> /builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/soc/imx/fsl,imx-iomuxc-gpr.example.dtb: bridge@18 (fsl,imx6sx-ldb): reg: [[24, 4]] is too short
> from schema $id: http://devicetree.org/schemas/display/bridge/fsl,ldb.yaml
>
> doc reference errors (make refcheckdocs):
>
> See https://patchwork.kernel.org/project/devicetree/patch/20260717201519.844259-1-Frank.Li@oss.nxp.com
>
> The base for the series is generally the latest rc1. A different dependency
> should be noted in *this* patch.
>
> If you already ran 'make dt_binding_check' and didn't see the above
> error(s), then make sure 'yamllint' is installed and dt-schema is up to
> date:
>
> pip3 install dtschema --upgrade
>
> Please check and re-submit after running the above command yourself. Note
> that DT_SCHEMA_FILES can be set to your schema file to speed up checking
> your schema. However, it must be unset to test all examples with your schema.
>
^ permalink raw reply
* Re: [PATCH] Bluetooth: hci_bcm4377: Use named initializers for pci_device_id array
From: Uwe Kleine-König (The Capable Hub) @ 2026-07-18 14:08 UTC (permalink / raw)
To: Luiz Augusto von Dentz
Cc: Sven Peter, Janne Grunau, Neal Gompa, Marcel Holtmann,
Markus Schneider-Pargmann, asahi, linux-arm-kernel,
linux-bluetooth, linux-kernel
In-Reply-To: <ainSCcYroJUIAuwr@monoceros>
[-- Attachment #1: Type: text/plain, Size: 2464 bytes --]
On Wed, Jun 10, 2026 at 11:08:49PM +0200, Uwe Kleine-König (The Capable Hub) wrote:
> Hello,
>
> On Wed, Jun 10, 2026 at 01:13:44PM -0400, Luiz Augusto von Dentz wrote:
> > On Wed, Jun 10, 2026 at 12:59 PM Uwe Kleine-König (The Capable Hub)
> > <u.kleine-koenig@baylibre.com> wrote:
> > >
> > > On Mon, May 04, 2026 at 06:09:40PM +0200, Uwe Kleine-König (The Capable Hub) wrote:
> > > > Initializing a struct using list initializers is hard to read, compared
> > > > to that using named initializers is more ideomatic. Convert the macro
> > > > used to assign values in the driver's pci_device_id array accordingly.
> > > >
> > > > This change doesn't introduce any changes to the compiled array on an
> > > > x86 and an arm64 build.
> > > >
> > > > Signed-off-by: Uwe Kleine-König (The Capable Hub) <u.kleine-koenig@baylibre.com>
> > > > ---
> > > > Hello,
> > > >
> > > > this is a preparing change for making struct pci_device_id::driver_data an
> > > > anonymous union (similar to
> > > > https://lore.kernel.org/all/cover.1776579304.git.u.kleine-koenig@baylibre.com/).
> > > > This requires named initializers for .driver_data. But even without that
> > > > this is a nice cleanup making the macro better readable.
> > > >
> > > > Gcc is happy with simplifying the assignment further using
> > > > PCI_VDEVICE(BROADCOM, BCM ## id ## _DEVICE_ID), but this is a bit fishy
> > > > because PCI_VDEVICE also assigns .class and .class_mask (using list
> > > > initializers), so I didn't convert that.
> > >
> > > In the meantime I learned that doing that would break W=1 builds, so it
> > > was a good choice to not go that path.
> > >
> > > > Once all pci_device_id use
> > > > named initializers, the two zeros can be dropped from PCI_VDEVICE and
> > > > this entry simplified accordingly.
> > >
> > > Is this patch still on someone's radar? Ideally for application in time
> > > for 7.2-rc1?
> >
> > It is no longer in patchwork so if you really want to get in please resend.
>
> Instead I unarchived the patch, so it appears in the patch list again. I
> hope this is easier for everyone (it is for me).
That didn't help, it is archived again. So I'll resend, but I still
wonder about the processes involved. Is there a bogous automation that
archives patches after a while? Or is someone archiving patches by hand
that look old? Both make patchwork as tracker somewhat useless ...
Best regards
Uwe
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]
^ permalink raw reply
* Re: [PATCH v4 2/2] iio: adc: add Axiado SARADC driver
From: Uwe Kleine-König @ 2026-07-18 13:51 UTC (permalink / raw)
To: Petar Stepanovic
Cc: Akhila Kavi, Prasad Bolisetty, Jonathan Cameron, David Lechner,
Nuno Sá, Andy Shevchenko, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Harshit Shah, linux-iio, devicetree,
linux-arm-kernel, linux-kernel
In-Reply-To: <20260716-axiado-ax3000-ax3005-saradc-v4-2-810527a9d27f@axiado.com>
[-- Attachment #1: Type: text/plain, Size: 333 bytes --]
Hello,
On Thu, Jul 16, 2026 at 10:53:02PM -0700, Petar Stepanovic wrote:
> +#include <linux/mod_devicetable.h>
> [...]
> +#include <linux/platform_device.h>
Please don't explicitly include <linux/mod_devicetable.h>. I'm working
on removing that header and <linux/platform_device.h> already provides
of_device_id.
Best regards
Uwe
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]
^ permalink raw reply
* Re: [PATCH v12 02/29] arm64/fpsimd: Update FA64 and ZT0 enables when loading SME state
From: Fuad Tabba @ 2026-07-18 13:30 UTC (permalink / raw)
To: Mark Brown
Cc: Mark Rutland, Marc Zyngier, Joey Gouly, Catalin Marinas,
Suzuki K Poulose, Will Deacon, Paolo Bonzini, Jonathan Corbet,
Shuah Khan, Oliver Upton, Dave Martin, Ben Horgan,
Jean-Philippe Brucker, linux-arm-kernel, kvmarm, linux-kernel,
kvm, linux-doc, linux-kselftest, Peter Maydell, Eric Auger
In-Reply-To: <3c76650f-ddda-47ae-a676-86016d8e39a6@sirena.org.uk>
On Sat, 18 Jul 2026 at 01:35, Mark Brown <broonie@kernel.org> wrote:
>
> On Thu, Jul 16, 2026 at 04:28:02PM +0100, Mark Brown wrote:
> > On Thu, Jul 16, 2026 at 11:52:36AM +0100, Mark Rutland wrote:
>
> > > > if (test_thread_flag(TIF_SME)) {
> > > > - unsigned long vq = sve_vq_from_vl(sme_vl);
> > > > - sysreg_clear_set_s(SYS_SMCR_EL1, SMCR_ELx_LEN, vq - 1);
> > > > + sysreg_cond_update_s(SYS_SMCR_EL1, task_smcr(current));
> > > > + isb();
> > > > }
>
> > > What's the ISB for? That mysteriously appeared in v11 without
> > > explanation. It wasn't in the original code, prior versions of the
> > > series, or my suggested rework with the task_smcr() helper.
>
> > > I don't believe it's necessary to add an ISB here.
>
> > I can't remember or figure it out, I'll delete.
>
> Actually I remembered: while SCMR_EL1.LEN is self synchronising the
> "without the need for explict synchronization" wording is not present
> for SMCR_EL1.{FA64,EZT0} and this is no longer explicitly just an update
> of LEN. It's possible I'm being overly paranoid here, I'll leave the
> isb() and add a comment for the next version.
I went through the ARM ARM (DDI 0487 M.c) on this and I don't think
you're being overly paranoid, I believe the isb() is needed here.
The self-synchronisation wording in the SMCR_EL1 description is
attached to the LEN field only: "An indirect read of SMCR_EL1.LEN
appears to occur in program order relative to a direct write of the
same register, without the need for explicit synchronization." There
is no equivalent wording for FA64 or EZT0, so they fall under the
general rule in D24.1.2.2: "Unless otherwise stated in its System
register definition, a direct write to a System register requires
synchronization before software can rely on the effects of that write
to affect instructions appearing in program order after the write."
Table D24-1 has direct write -> indirect read as "Required".
And task_fpsimd_load() does make indirect reads of both fields before
the next context synchronization event: sme_load_state() executes LDR
ZT0, whose execution at EL1 is trapped when SMCR_EL1.EZT0 is 0, and
when PSTATE.SM is set sve_load_state() executes WRFFR, which is
"illegal when executed in Streaming SVE mode, unless FEAT_SME_FA64 is
implemented and enabled" (from the WRFFR description). The MSR SVCR in
between doesn't provide the synchronization, since SVCR's
self-synchronisation wording covers reads of its own SM and ZA fields
only.
When the write does change FA64 or EZT0 (once KVM can disable them for
a guest, and possibly on the return from suspend path now that
sme_suspend_exit() no longer writes them), K1.2.4 "CONSTRAINED
UNPREDICTABLE behavior due to inadequate context synchronization"
applies without the isb(): "the behavior of the PE is consistent with
the unsynchronized control value being either the old value or the new
value", independently per use. So the ZT0 load or the FFR restore
could take an unexpected SME trap (EC 0x1D) in the kernel, depending
on the implementation.
FWIW the other call sites look consistent with only this one needing
it: in do_sme_acc() nothing ZT0 or FFR gated executes before the ERET,
which is the context synchronization event, and ZCR_EL1 only has LEN
allocated.
Cheers,
/fuad
^ permalink raw reply
* Re: [PATCH] char: mem: keep arch range checks overflow-safe
From: Yousef Alhouseen @ 2026-07-18 12:20 UTC (permalink / raw)
To: gregkh
Cc: arnd, linux, ysato, dalias, glaubitz, linux-kernel,
linux-arm-kernel, linux-sh
In-Reply-To: <2026071710-flanked-espresso-5b06@gregkh>
Yes, agreed. The ARM and SH fixes should be folded into the original
generic char/mem change rather than sent separately. I'll resend them
together as a single v2.
Thanks,
Yousef
On Fri, 17 Jul 2026 16:17:25 +0200, Greg Kroah-Hartman
<gregkh@linuxfoundation.org> wrote:
> On Thu, Jun 25, 2026 at 10:58:00AM +0200, Yousef Alhouseen wrote:
> > The generic /dev/mem physical range check now avoids validating
> > addr + size directly, but ARM and SH provide their own
> > valid_phys_addr_range() implementations with the same wrapped-addition
> > pattern.
> >
> > Use subtraction-based upper-bound checks in those overrides as well. Also
> > make the ARM mmap pfn check avoid overflowing the pfn plus page-count
> > expression.
> >
> > Suggested-by: Arnd Bergmann <arnd@arndb.de>
> > Signed-off-by: Yousef Alhouseen <alhouseenyousef@gmail.com>
> > ---
> > arch/arm/mm/mmap.c | 9 +++++++--
> > arch/sh/mm/mmap.c | 4 +++-
> > 2 files changed, 10 insertions(+), 3 deletions(-)
>
> This should be part of the char/mem patch, right?
>
> thanks,
>
> greg k-h
^ permalink raw reply
* [PATCH v2] media: mtk-jpeg: drain hardware completion before freeing context
From: Guangshuo Li @ 2026-07-18 11:24 UTC (permalink / raw)
To: Bin Liu, Mauro Carvalho Chehab, Matthias Brugger,
AngeloGioacchino Del Regno, Nicolas Dufresne, Hans Verkuil,
Fan Wu, linux-media, linux-kernel, linux-arm-kernel,
linux-mediatek
Cc: Guangshuo Li
The change referenced by the Fixes tag cancels ctx->jpeg_work before
freeing the JPEG context.
That prevents the worker itself from accessing the context after it has
been freed. However, the multi-core workers return after programming a
hardware instance. The IRQ handler or the per-hardware timeout work can
then continue to access the context through hw_param.curr_ctx after the
worker has completed.
If userspace closes the file while a hardware job is still pending,
cancel_work_sync() can return and mtk_jpeg_release() can free the
context before the IRQ or timeout path has finished using it.
Track the number of in-flight hardware jobs for each context and wait
for them to complete in mtk_jpeg_release().
Use a per-hardware active flag to ensure that only the IRQ handler or
the timeout work completes each job. Clear hw_param.curr_ctx and drop
the in-flight count only after the completion path has finished all
accesses to the context.
Fixes: 34c519feef3e ("media: mtk-jpeg: fix use-after-free in release path due to uncancelled work")
Signed-off-by: Guangshuo Li <lgs201920130244@gmail.com>
---
v2:
- Replace the undefined mtk_jpeg_release_hw() call with per-context
in-flight hardware job tracking.
- Ensure that only the IRQ or timeout path completes each hardware job.
- Clear hw_param.curr_ctx after the completion path stops using the
context.
- Keep hardware instances busy until the timeout path has finished
accessing their saved context and buffers.
.../platform/mediatek/jpeg/mtk_jpeg_core.c | 12 ++++++++-
.../platform/mediatek/jpeg/mtk_jpeg_core.h | 14 +++++++++++
.../platform/mediatek/jpeg/mtk_jpeg_dec_hw.c | 25 +++++++++++++------
.../platform/mediatek/jpeg/mtk_jpeg_enc_hw.c | 25 +++++++++++++------
4 files changed, 61 insertions(+), 15 deletions(-)
diff --git a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c
index d147ec483081..d41c0e0516b9 100644
--- a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c
+++ b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c
@@ -1161,6 +1161,8 @@ static int mtk_jpeg_open(struct file *file)
}
INIT_WORK(&ctx->jpeg_work, jpeg->variant->jpeg_worker);
+ atomic_set(&ctx->hw_jobs, 0);
+ init_waitqueue_head(&ctx->hw_jobs_wq);
INIT_LIST_HEAD(&ctx->dst_done_queue);
spin_lock_init(&ctx->done_queue_lock);
v4l2_fh_init(&ctx->fh, vfd);
@@ -1202,8 +1204,12 @@ static int mtk_jpeg_release(struct file *file)
struct mtk_jpeg_dev *jpeg = video_drvdata(file);
struct mtk_jpeg_ctx *ctx = mtk_jpeg_file_to_ctx(file);
- if (jpeg->variant->jpeg_worker)
+ if (jpeg->variant->jpeg_worker) {
cancel_work_sync(&ctx->jpeg_work);
+ wait_event(ctx->hw_jobs_wq,
+ atomic_read(&ctx->hw_jobs) == 0);
+ }
+
mutex_lock(&jpeg->lock);
v4l2_m2m_ctx_release(ctx->fh.m2m_ctx);
v4l2_ctrl_handler_free(&ctx->ctrl_hdl);
@@ -1640,6 +1646,8 @@ static void mtk_jpegenc_worker(struct work_struct *work)
v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx);
v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx);
+ atomic_inc(&ctx->hw_jobs);
+ atomic_set_release(&comp_jpeg[hw_id]->hw_param.job_active, 1);
schedule_delayed_work(&comp_jpeg[hw_id]->job_timeout_work,
msecs_to_jiffies(MTK_JPEG_HW_TIMEOUT_MSEC));
@@ -1759,6 +1767,8 @@ static void mtk_jpegdec_worker(struct work_struct *work)
goto setdst_end;
}
+ atomic_inc(&ctx->hw_jobs);
+ atomic_set_release(&comp_jpeg[hw_id]->hw_param.job_active, 1);
schedule_delayed_work(&comp_jpeg[hw_id]->job_timeout_work,
msecs_to_jiffies(MTK_JPEG_HW_TIMEOUT_MSEC));
diff --git a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.h b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.h
index 02ed0ed5b736..be8ada60782a 100644
--- a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.h
+++ b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.h
@@ -103,6 +103,7 @@ struct mtk_jpeg_hw_param {
struct vb2_v4l2_buffer *src_buffer;
struct vb2_v4l2_buffer *dst_buffer;
struct mtk_jpeg_ctx *curr_ctx;
+ atomic_t job_active;
};
enum mtk_jpegenc_hw_id {
@@ -282,6 +283,8 @@ struct mtk_jpeg_q_data {
* @restart_interval: jpeg encoder restart interval
* @ctrl_hdl: controls handler
* @jpeg_work: jpeg encoder workqueue
+ * @hw_jobs: number of hardware jobs still referencing this context
+ * @hw_jobs_wq: wait queue for hardware job completion
* @total_frame_num: encoded frame number
* @dst_done_queue: encoded frame buffer queue
* @done_queue_lock: encoded frame operation spinlock
@@ -299,6 +302,8 @@ struct mtk_jpeg_ctx {
struct v4l2_ctrl_handler ctrl_hdl;
struct work_struct jpeg_work;
+ atomic_t hw_jobs;
+ wait_queue_head_t hw_jobs_wq;
u32 total_frame_num;
struct list_head dst_done_queue;
/* spinlock protecting the encode done buffer */
@@ -306,4 +311,13 @@ struct mtk_jpeg_ctx {
u32 last_done_frame_num;
};
+static inline void
+mtk_jpeg_hw_job_done(struct mtk_jpeg_hw_param *hw_param,
+ struct mtk_jpeg_ctx *ctx)
+{
+ WRITE_ONCE(hw_param->curr_ctx, NULL);
+ if (atomic_dec_and_test(&ctx->hw_jobs))
+ wake_up(&ctx->hw_jobs_wq);
+}
+
#endif /* _MTK_JPEG_CORE_H */
diff --git a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_dec_hw.c b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_dec_hw.c
index 32372781daf5..c2d40653891a 100644
--- a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_dec_hw.c
+++ b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_dec_hw.c
@@ -527,7 +527,12 @@ static void mtk_jpegdec_timeout_work(struct work_struct *work)
job_timeout_work.work);
struct mtk_jpeg_dev *master_jpeg = cjpeg->master_dev;
struct vb2_v4l2_buffer *src_buf, *dst_buf;
+ struct mtk_jpeg_ctx *ctx;
+
+ if (atomic_cmpxchg(&cjpeg->hw_param.job_active, 1, 0) != 1)
+ return;
+ ctx = cjpeg->hw_param.curr_ctx;
src_buf = cjpeg->hw_param.src_buffer;
dst_buf = cjpeg->hw_param.dst_buffer;
v4l2_m2m_buf_copy_metadata(src_buf, dst_buf);
@@ -535,11 +540,13 @@ static void mtk_jpegdec_timeout_work(struct work_struct *work)
mtk_jpeg_dec_reset(cjpeg->reg_base);
clk_disable_unprepare(cjpeg->jdec_clk.clks->clk);
pm_runtime_put(cjpeg->dev);
+ v4l2_m2m_buf_done(src_buf, buf_state);
+ mtk_jpegdec_put_buf(cjpeg);
+ mtk_jpeg_hw_job_done(&cjpeg->hw_param, ctx);
+
cjpeg->hw_state = MTK_JPEG_HW_IDLE;
atomic_inc(&master_jpeg->hw_rdy);
wake_up(&master_jpeg->hw_wq);
- v4l2_m2m_buf_done(src_buf, buf_state);
- mtk_jpegdec_put_buf(cjpeg);
}
static irqreturn_t mtk_jpegdec_hw_irq_handler(int irq, void *priv)
@@ -555,12 +562,10 @@ static irqreturn_t mtk_jpegdec_hw_irq_handler(int irq, void *priv)
struct mtk_jpegdec_comp_dev *jpeg = priv;
struct mtk_jpeg_dev *master_jpeg = jpeg->master_dev;
- cancel_delayed_work(&jpeg->job_timeout_work);
+ if (atomic_cmpxchg(&jpeg->hw_param.job_active, 1, 0) != 1)
+ return IRQ_HANDLED;
- ctx = jpeg->hw_param.curr_ctx;
- src_buf = jpeg->hw_param.src_buffer;
- dst_buf = jpeg->hw_param.dst_buffer;
- v4l2_m2m_buf_copy_metadata(src_buf, dst_buf);
+ cancel_delayed_work(&jpeg->job_timeout_work);
irq_status = mtk_jpeg_dec_get_int_status(jpeg->reg_base);
dec_irq_ret = mtk_jpeg_dec_enum_result(irq_status);
@@ -570,6 +575,11 @@ static irqreturn_t mtk_jpegdec_hw_irq_handler(int irq, void *priv)
if (dec_irq_ret != MTK_JPEG_DEC_RESULT_EOF_DONE)
dev_warn(jpeg->dev, "Jpg Dec occurs unknown Err.");
+ ctx = jpeg->hw_param.curr_ctx;
+ src_buf = jpeg->hw_param.src_buffer;
+ dst_buf = jpeg->hw_param.dst_buffer;
+ v4l2_m2m_buf_copy_metadata(src_buf, dst_buf);
+
jpeg_src_buf =
container_of(src_buf, struct mtk_jpeg_src_buf, b);
@@ -582,6 +592,7 @@ static irqreturn_t mtk_jpegdec_hw_irq_handler(int irq, void *priv)
mtk_jpegdec_put_buf(jpeg);
pm_runtime_put(ctx->jpeg->dev);
clk_disable_unprepare(jpeg->jdec_clk.clks->clk);
+ mtk_jpeg_hw_job_done(&jpeg->hw_param, ctx);
jpeg->hw_state = MTK_JPEG_HW_IDLE;
wake_up(&master_jpeg->hw_wq);
diff --git a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_enc_hw.c b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_enc_hw.c
index b312a15d707b..b08f94845613 100644
--- a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_enc_hw.c
+++ b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_enc_hw.c
@@ -257,7 +257,12 @@ static void mtk_jpegenc_timeout_work(struct work_struct *work)
struct mtk_jpeg_dev *master_jpeg = cjpeg->master_dev;
enum vb2_buffer_state buf_state = VB2_BUF_STATE_ERROR;
struct vb2_v4l2_buffer *src_buf, *dst_buf;
+ struct mtk_jpeg_ctx *ctx;
+
+ if (atomic_cmpxchg(&cjpeg->hw_param.job_active, 1, 0) != 1)
+ return;
+ ctx = cjpeg->hw_param.curr_ctx;
src_buf = cjpeg->hw_param.src_buffer;
dst_buf = cjpeg->hw_param.dst_buffer;
v4l2_m2m_buf_copy_metadata(src_buf, dst_buf);
@@ -265,11 +270,13 @@ static void mtk_jpegenc_timeout_work(struct work_struct *work)
mtk_jpeg_enc_reset(cjpeg->reg_base);
clk_disable_unprepare(cjpeg->venc_clk.clks->clk);
pm_runtime_put(cjpeg->dev);
+ v4l2_m2m_buf_done(src_buf, buf_state);
+ mtk_jpegenc_put_buf(cjpeg);
+ mtk_jpeg_hw_job_done(&cjpeg->hw_param, ctx);
+
cjpeg->hw_state = MTK_JPEG_HW_IDLE;
atomic_inc(&master_jpeg->hw_rdy);
wake_up(&master_jpeg->hw_wq);
- v4l2_m2m_buf_done(src_buf, buf_state);
- mtk_jpegenc_put_buf(cjpeg);
}
static irqreturn_t mtk_jpegenc_hw_irq_handler(int irq, void *priv)
@@ -283,12 +290,10 @@ static irqreturn_t mtk_jpegenc_hw_irq_handler(int irq, void *priv)
struct mtk_jpegenc_comp_dev *jpeg = priv;
struct mtk_jpeg_dev *master_jpeg = jpeg->master_dev;
- cancel_delayed_work(&jpeg->job_timeout_work);
+ if (atomic_cmpxchg(&jpeg->hw_param.job_active, 1, 0) != 1)
+ return IRQ_HANDLED;
- ctx = jpeg->hw_param.curr_ctx;
- src_buf = jpeg->hw_param.src_buffer;
- dst_buf = jpeg->hw_param.dst_buffer;
- v4l2_m2m_buf_copy_metadata(src_buf, dst_buf);
+ cancel_delayed_work(&jpeg->job_timeout_work);
irq_status = readl(jpeg->reg_base + JPEG_ENC_INT_STS) &
JPEG_ENC_INT_STATUS_MASK_ALLIRQ;
@@ -297,6 +302,11 @@ static irqreturn_t mtk_jpegenc_hw_irq_handler(int irq, void *priv)
if (!(irq_status & JPEG_ENC_INT_STATUS_DONE))
dev_warn(jpeg->dev, "Jpg Enc occurs unknown Err.");
+ ctx = jpeg->hw_param.curr_ctx;
+ src_buf = jpeg->hw_param.src_buffer;
+ dst_buf = jpeg->hw_param.dst_buffer;
+ v4l2_m2m_buf_copy_metadata(src_buf, dst_buf);
+
result_size = mtk_jpeg_enc_get_file_size(jpeg->reg_base,
ctx->jpeg->variant->support_34bit);
vb2_set_plane_payload(&dst_buf->vb2_buf, 0, result_size);
@@ -305,6 +315,7 @@ static irqreturn_t mtk_jpegenc_hw_irq_handler(int irq, void *priv)
mtk_jpegenc_put_buf(jpeg);
pm_runtime_put(ctx->jpeg->dev);
clk_disable_unprepare(jpeg->venc_clk.clks->clk);
+ mtk_jpeg_hw_job_done(&jpeg->hw_param, ctx);
jpeg->hw_state = MTK_JPEG_HW_IDLE;
wake_up(&master_jpeg->hw_wq);
--
2.43.0
^ permalink raw reply related
* [RFC PATCH 2/2] drm/meson: add GXLX2 HDMI register support
From: Zinan Zhou @ 2026-07-18 11:15 UTC (permalink / raw)
To: Neil Armstrong
Cc: Zinan Zhou, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
Simona Vetter, Kevin Hilman, Jerome Brunet, Martin Blumenstingl,
dri-devel, linux-amlogic, devicetree, linux-arm-kernel,
linux-kernel
In-Reply-To: <20260718111527.119231-1-zinan@mieulab.com>
GXLX2 combines a GXL-like display pipeline and HDMI PHY with directly
mapped DesignWare and TOP registers. Reusing the indirect GX callbacks
returns an invalid HDMI controller ID and prevents the HDMI component from
binding.
Add GXLX2 match data using the existing direct register callbacks, while
retaining the GXL PHY initialization values. Do not enable APB3
fail-on-error through the legacy indirect control-register offsets for a
direct-register device. Add the compatible to the VPU component match list
and use the GXLX2-specific HHI_HDMI_PHY_CNTL0 value for the 297 MHz
pixel-clock bucket.
The register layout and the 297 MHz value were determined by analysis of
the HG680-LC vendor kernel. Public Amlogic-derived source independently
documents the direct access mechanism and the ordinary GXL PHY values; no
vendor code is copied by this change.
An equivalent Linux 6.6 implementation was tested on an HG680-LC with 1080p
HDMI video and two-channel HDMI audio. The Linux 6.12 port boots from eMMC
with working Ethernet, 1080p and native 1440p video, and two-channel HDMI
audio. This port has passed arm64 compilation; 4K30 physical validation of
the 297 MHz branch remains pending.
Assisted-by: Codex:gpt-5.6-sol
Signed-off-by: Zinan Zhou <zinan@mieulab.com>
---
drivers/gpu/drm/meson/meson_drv.c | 1 +
drivers/gpu/drm/meson/meson_dw_hdmi.c | 33 +++++++++++++++++++++++----
2 files changed, 29 insertions(+), 5 deletions(-)
diff --git a/drivers/gpu/drm/meson/meson_drv.c b/drivers/gpu/drm/meson/meson_drv.c
index 49ff9f1f16d3..5c136743e60c 100644
--- a/drivers/gpu/drm/meson/meson_drv.c
+++ b/drivers/gpu/drm/meson/meson_drv.c
@@ -469,6 +469,7 @@ static void meson_drv_shutdown(struct platform_device *pdev)
static const struct of_device_id components_dev_match[] = {
{ .compatible = "amlogic,meson-gxbb-dw-hdmi" },
{ .compatible = "amlogic,meson-gxl-dw-hdmi" },
+ { .compatible = "amlogic,meson-gxlx2-dw-hdmi" },
{ .compatible = "amlogic,meson-gxm-dw-hdmi" },
{ .compatible = "amlogic,meson-g12a-dw-hdmi" },
{}
diff --git a/drivers/gpu/drm/meson/meson_dw_hdmi.c b/drivers/gpu/drm/meson/meson_dw_hdmi.c
index 1004108fb7ca..f02d6a513dd3 100644
--- a/drivers/gpu/drm/meson/meson_dw_hdmi.c
+++ b/drivers/gpu/drm/meson/meson_dw_hdmi.c
@@ -136,6 +136,8 @@ struct meson_dw_hdmi_data {
unsigned int addr, unsigned int data);
u32 cntl0_init;
u32 cntl1_init;
+ u32 phy_cntl0_3g;
+ bool uses_direct_regs;
};
struct meson_dw_hdmi {
@@ -287,7 +289,9 @@ static void meson_hdmi_phy_setup_mode(struct meson_dw_hdmi *dw_hdmi,
/* For 420, pixel clock is half unlike venc clock */
if (mode_is_420) pixel_clock /= 2;
- if (dw_hdmi_is_compatible(dw_hdmi, "amlogic,meson-gxl-dw-hdmi") ||
+ if (dw_hdmi_is_compatible(dw_hdmi,
+ "amlogic,meson-gxlx2-dw-hdmi") ||
+ dw_hdmi_is_compatible(dw_hdmi, "amlogic,meson-gxl-dw-hdmi") ||
dw_hdmi_is_compatible(dw_hdmi, "amlogic,meson-gxm-dw-hdmi")) {
if (pixel_clock >= 371250) {
/* 5.94Gbps, 3.7125Gbps */
@@ -295,7 +299,8 @@ static void meson_hdmi_phy_setup_mode(struct meson_dw_hdmi *dw_hdmi,
regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL3, 0x2136315b);
} else if (pixel_clock >= 297000) {
/* 2.97Gbps */
- regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL0, 0x33303382);
+ regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL0,
+ dw_hdmi->data->phy_cntl0_3g);
regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL3, 0x2036315b);
} else if (pixel_clock >= 148500) {
/* 1.485Gbps */
@@ -586,6 +591,7 @@ static const struct meson_dw_hdmi_data meson_dw_hdmi_gxl_data = {
.dwc_write = dw_hdmi_dwc_write,
.cntl0_init = 0x0,
.cntl1_init = PHY_CNTL1_INIT,
+ .phy_cntl0_3g = 0x33303382,
};
static const struct meson_dw_hdmi_data meson_dw_hdmi_g12a_data = {
@@ -595,6 +601,19 @@ static const struct meson_dw_hdmi_data meson_dw_hdmi_g12a_data = {
.dwc_write = dw_hdmi_g12a_dwc_write,
.cntl0_init = 0x000b4242, /* Bandgap */
.cntl1_init = PHY_CNTL1_INIT,
+ .uses_direct_regs = true,
+};
+
+/* GXLX2 uses the direct register layout with the older GXL PHY setup. */
+static const struct meson_dw_hdmi_data meson_dw_hdmi_gxlx2_data = {
+ .top_read = dw_hdmi_g12a_top_read,
+ .top_write = dw_hdmi_g12a_top_write,
+ .dwc_read = dw_hdmi_g12a_dwc_read,
+ .dwc_write = dw_hdmi_g12a_dwc_write,
+ .cntl0_init = 0x0,
+ .cntl1_init = PHY_CNTL1_INIT,
+ .phy_cntl0_3g = 0x33353382,
+ .uses_direct_regs = true,
};
static void meson_dw_hdmi_init(struct meson_dw_hdmi *meson_dw_hdmi)
@@ -612,8 +631,8 @@ static void meson_dw_hdmi_init(struct meson_dw_hdmi *meson_dw_hdmi)
reset_control_reset(meson_dw_hdmi->hdmitx_ctrl);
reset_control_reset(meson_dw_hdmi->hdmitx_phy);
- /* Enable APB3 fail on error */
- if (!meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A)) {
+ /* The APB3 control registers exist only with the indirect interface. */
+ if (!meson_dw_hdmi->data->uses_direct_regs) {
writel_bits_relaxed(BIT(15), BIT(15),
meson_dw_hdmi->hdmitx + HDMITX_TOP_CTRL_REG);
writel_bits_relaxed(BIT(15), BIT(15),
@@ -769,7 +788,9 @@ static int meson_dw_hdmi_bind(struct device *dev, struct device *master,
dw_plat_data->disable_cec = true;
dw_plat_data->output_port = 1;
- if (dw_hdmi_is_compatible(meson_dw_hdmi, "amlogic,meson-gxl-dw-hdmi") ||
+ if (dw_hdmi_is_compatible(meson_dw_hdmi,
+ "amlogic,meson-gxlx2-dw-hdmi") ||
+ dw_hdmi_is_compatible(meson_dw_hdmi, "amlogic,meson-gxl-dw-hdmi") ||
dw_hdmi_is_compatible(meson_dw_hdmi, "amlogic,meson-gxm-dw-hdmi") ||
dw_hdmi_is_compatible(meson_dw_hdmi, "amlogic,meson-g12a-dw-hdmi"))
dw_plat_data->use_drm_infoframe = true;
@@ -854,6 +875,8 @@ static const struct of_device_id meson_dw_hdmi_of_table[] = {
.data = &meson_dw_hdmi_gxl_data },
{ .compatible = "amlogic,meson-gxm-dw-hdmi",
.data = &meson_dw_hdmi_gxl_data },
+ { .compatible = "amlogic,meson-gxlx2-dw-hdmi",
+ .data = &meson_dw_hdmi_gxlx2_data },
{ .compatible = "amlogic,meson-g12a-dw-hdmi",
.data = &meson_dw_hdmi_g12a_data },
{ }
--
2.43.0
^ permalink raw reply related
* [RFC PATCH 1/2] dt-bindings: display: meson-dw-hdmi: add GXLX2 compatible
From: Zinan Zhou @ 2026-07-18 11:15 UTC (permalink / raw)
To: Neil Armstrong
Cc: Zinan Zhou, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
Simona Vetter, Kevin Hilman, Jerome Brunet, Martin Blumenstingl,
dri-devel, linux-amlogic, devicetree, linux-arm-kernel,
linux-kernel
In-Reply-To: <20260718111527.119231-1-zinan@mieulab.com>
The GXLX2 HDMI transmitter uses the byte-addressed DesignWare controller
registers and directly mapped TOP window also present on G12A. Its display
pipeline and HDMI PHY programming remain GXL-like, however.
Add a dedicated compatible with no fallback. The generic
meson-gx-dw-hdmi interface uses indirect address/data registers and cannot
operate this hardware, while meson-g12a-dw-hdmi would select incompatible
PHY initialization values.
The one-resource representation is proposed for RFC review; DWC and TOP
occupy one contiguous MMIO range on the tested HG680-LC.
Assisted-by: Codex:gpt-5.6-sol
Signed-off-by: Zinan Zhou <zinan@mieulab.com>
---
.../devicetree/bindings/display/amlogic,meson-dw-hdmi.yaml | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/Documentation/devicetree/bindings/display/amlogic,meson-dw-hdmi.yaml b/Documentation/devicetree/bindings/display/amlogic,meson-dw-hdmi.yaml
index 416fe263ac92..4a17eccabea9 100644
--- a/Documentation/devicetree/bindings/display/amlogic,meson-dw-hdmi.yaml
+++ b/Documentation/devicetree/bindings/display/amlogic,meson-dw-hdmi.yaml
@@ -29,8 +29,10 @@ description: |
The HDMI TOP block only supports HPD sensing.
The Synopsys HDMI Controller interrupt is routed through the
TOP Block interrupt.
- Communication to the TOP Block and the Synopsys HDMI Controller is done
- via a pair of dedicated addr+read/write registers.
+ Communication with the TOP Block and the Synopsys HDMI Controller uses a pair
+ of dedicated address/data registers on GXBB, GXL and GXM. GXLX2 and G12A
+ instead expose byte-addressed controller registers and a directly mapped TOP
+ window.
The HDMI PHY is configured by registers in the HHI register block.
Pixel data arrives in "4:4:4" format from the VENC block and the VPU HDMI mux
@@ -54,6 +56,7 @@ properties:
- amlogic,meson-gxm-dw-hdmi # GXM (S912)
- const: amlogic,meson-gx-dw-hdmi
- enum:
+ - amlogic,meson-gxlx2-dw-hdmi # GXLX2 (S905L3)
- amlogic,meson-g12a-dw-hdmi # G12A (S905X2, S905Y2, S905D2)
reg:
--
2.43.0
^ permalink raw reply related
* [RFC PATCH 0/2] drm/meson: add HDMI support for GXLX2
From: Zinan Zhou @ 2026-07-18 11:15 UTC (permalink / raw)
To: Neil Armstrong
Cc: Zinan Zhou, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
Simona Vetter, Kevin Hilman, Jerome Brunet, Martin Blumenstingl,
dri-devel, linux-amlogic, devicetree, linux-arm-kernel,
linux-kernel
This RFC adds HDMI transmitter support for the Amlogic GXLX2 family,
observed as an S905L3 (CPU major ID 0x2a) in a FiberHome HG680-LC set-top
box.
GXLX2 is unusual in that the display pipeline, clocks and HDMI PHY follow
the older GXL path, while the HDMI controller register interface is
directly mapped: DWC registers are byte-addressed from 0xda800000 and TOP
registers are 32-bit registers at 0xda808000 + index * 4. The existing
G12A access callbacks implement this layout, but using all G12A match data
would select the wrong PHY initialization for GXLX2.
Patch 1 proposes a dedicated amlogic,meson-gxlx2-dw-hdmi compatible
without a meson-gx-dw-hdmi fallback. Patch 2 adds dedicated match data
combining direct register callbacks with GXL PHY behavior. It also handles
the GXLX2 value for the 297 MHz PHY bucket and adds the compatible to the
Meson DRM component match list.
This RFC depends on the separately posted common Meson DW-HDMI regmap fix:
drm/meson: constrain the DW-HDMI regmap range
https://lore.kernel.org/all/20260718090710.70534-1-zinan@mieulab.com/
That formal bug-fix patch bounds register iteration below the directly
mapped TOP block and prevents the legacy 16-bit indirect interface from
wrapping. It is intentionally not part of this RFC so it can be reviewed
and merged without waiting for agreement on the GXLX2 DT ABI.
I would particularly appreciate feedback on two DT ABI questions:
1. Is amlogic,meson-gxlx2-dw-hdmi the appropriate block compatible name?
2. Should the DWC and TOP windows be represented as one contiguous MMIO
resource, as in this RFC, or as two named resources?
Evidence and disclosure:
- The GXLX2 addresses and 297 MHz value are factual results of analysis of
the HG680-LC vendor kernel. Firmware SHA-256 and focused behavioral
evidence can be supplied if useful, but no firmware, kallsyms dump or
disassembly is part of this submission.
- Public Amlogic-derived GPL source documents the ordinary GXL 2.97 Gbps
values and public GPL-2.0+/MIT source documents the same direct DWC/TOP
access mechanism used on later SoCs. The implementation here does not
copy a vendor function body.
Testing:
- An equivalent Linux 6.6.18 implementation boots from eMMC on the
HG680-LC.
- 1920x1080 HDMI video was physically verified on an LG 27GL850.
- Two-channel HDMI LPCM through the display and analog stereo audio were
physically verified.
- The downstream 6.12 port boots from eMMC with working Ethernet/SSH and
has physically verified 1920x1080@60 video and HDMI LPCM.
- With the generic Meson non-CEA mode-range change already present in
current mainline, 2560x1440@59.95 video and HDMI LPCM were physically
verified on the display's native timing.
- The RFC port builds on arm64 and its binding passes dt_binding_check.
- 3840x2160 at 30 Hz has not yet been physically tested. That test is
required before a non-RFC PATCH v1 because it exercises the
GXLX2-specific 297 MHz branch. It is not a blocker for the verified
1080p/1440p use case.
- No other GXLX2 board has been tested yet.
The initial RFC intentionally contains no board DTS. A downstream-only
HG680-LC DTS is being kept as DO NOT MERGE until the compatible and resource
model have received initial feedback.
Assisted-by: Codex:gpt-5.6-sol
Zinan Zhou (2):
dt-bindings: display: meson-dw-hdmi: add GXLX2 compatible
drm/meson: add GXLX2 HDMI register support
.../display/amlogic,meson-dw-hdmi.yaml | 7 ++--
drivers/gpu/drm/meson/meson_drv.c | 1 +
drivers/gpu/drm/meson/meson_dw_hdmi.c | 33 ++++++++++++++++---
3 files changed, 34 insertions(+), 7 deletions(-)
base-commit: b0a652436b892eb9a036a031b33099dca036faaa
prerequisite-patch-id: 0a689485bbc3c1d77d52aeee0b81e4943d1e904a
--
2.43.0
^ permalink raw reply
* [PATCH v3] ARM: imx: Fix suspend/resume crash with Clang CFI
From: Yo'av Moshe @ 2026-07-18 11:13 UTC (permalink / raw)
To: Frank Li, Sascha Hauer, Russell King
Cc: Pengutronix Kernel Team, Fabio Estevam, Nathan Chancellor,
Nick Desaulniers, Bill Wendling, Justin Stitt, imx,
linux-arm-kernel, llvm, stable, linux-kernel, Yo'av Moshe
Relocated suspend code in OCRAM lacks compiler-generated CFI type
signatures. When CONFIG_CFI=y is active, the indirect call to
imx6_suspend_in_ocram_fn triggers a strict CFI violation panic.
To resolve this safely without reducing CFI protection scope:
1. Create a minimal wrapper function imx6_suspend_in_ocram annotated
with __nocfi to handle the unverified indirect call.
2. Remove the __nocfi annotation from the main imx6q_suspend_finish
function to preserve full CFI coverage for other indirect calls
in that scope (such as cpu_do_idle() and flush_cache_all()).
3. Mark global variables ccm_base, suspend_ocram_base, and the
imx6_suspend_in_ocram_fn pointer as __ro_after_init to prevent
them from being used as target vectors for CFI bypass exploits.
Cc: stable@vger.kernel.org
Signed-off-by: Yo'av Moshe <linux@yoavmoshe.com>
---
Tested on a Kobo Clara HD (i.MX6SLL SoC) running postmarketOS edge.
Before this patch, suspending the device caused an immediate silent
hang requiring a hard-reboot. With this patch applied, suspend and
resume work successfully.
Differences from v2:
- Restrained __nocfi scope by adding a dedicated, minimal 1-line
wrapper function (imx6_suspend_in_ocram) for the OCRAM call,
avoiding disabling CFI checks for cpu_do_idle() and flush_cache_all().
- Marked global pointers ccm_base and suspend_ocram_base as
__ro_after_init to fully neutralize Write-What-Where exploit bypasses.
arch/arm/mach-imx/pm-imx6.c | 13 +++++++++----
1 file changed, 9 insertions(+), 4 deletions(-)
diff --git a/arch/arm/mach-imx/pm-imx6.c b/arch/arm/mach-imx/pm-imx6.c
index a671ca498..3d5b960c5 100644
--- a/arch/arm/mach-imx/pm-imx6.c
+++ b/arch/arm/mach-imx/pm-imx6.c
@@ -61,9 +61,9 @@
#define MX6Q_SUSPEND_OCRAM_SIZE 0x1000
#define MX6_MAX_MMDC_IO_NUM 33
-static void __iomem *ccm_base;
-static void __iomem *suspend_ocram_base;
-static void (*imx6_suspend_in_ocram_fn)(void __iomem *ocram_vbase);
+static void __iomem *ccm_base __ro_after_init;
+static void __iomem *suspend_ocram_base __ro_after_init;
+static void (*imx6_suspend_in_ocram_fn)(void __iomem *ocram_vbase) __ro_after_init;
/*
* suspend ocram space layout:
@@ -360,6 +360,11 @@ int imx6_set_lpm(enum mxc_cpu_pwr_mode mode)
return 0;
}
+static void __nocfi imx6_suspend_in_ocram(void __iomem *ocram_vbase)
+{
+ imx6_suspend_in_ocram_fn(ocram_vbase);
+}
+
static int imx6q_suspend_finish(unsigned long val)
{
if (!imx6_suspend_in_ocram_fn) {
@@ -374,7 +379,7 @@ static int imx6q_suspend_finish(unsigned long val)
if (!((struct imx6_cpu_pm_info *)
suspend_ocram_base)->l2_base.vbase)
flush_cache_all();
- imx6_suspend_in_ocram_fn(suspend_ocram_base);
+ imx6_suspend_in_ocram(suspend_ocram_base);
}
return 0;
--
2.55.0
^ permalink raw reply related
* Re: [PATCH v3 3/4] arm64: dts: rockchip: add #sound-dai-cells to the RK3588 HDMI receiver
From: Igor Paunovic @ 2026-07-18 11:12 UTC (permalink / raw)
To: Dmitry Osipenko, Mauro Carvalho Chehab
Cc: Sebastian Reichel, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Heiko Stuebner, linux-media, linux-rockchip, linux-arm-kernel,
kernel, devicetree, linux-kernel
In-Reply-To: <20260718085728.6797-4-royalnet026@gmail.com>
A testing note for anyone trying this out, found while exercising
the series today:
after (re)connecting a source, audio capture currently requires the
video capture path to have been started once -- a cold
`arecord -D hw:...` right after plug-in fails with EIO (the I2S
interface gets no bit clock), while the same command succeeds after
one video STREAMON/STREAMOFF cycle, and keeps working from then on
until the source is re-plugged.
Setting DV timings alone is not sufficient; it does take a real
streaming cycle. So for testing audio, either run a video pipeline
first (e.g. v4l2src ! fakesink for a second) or capture both, which
is the normal use case anyway.
I'm investigating which part of the streaming path opens the audio
packet flow, and will either fix it in v4 (if it turns out to be a
missing enable in the audio path) or send it as a follow-up with a
proper analysis.
Igor
On Sat, Jul 18, 2026 at 10:57 AM Igor Paunovic <royalnet026@gmail.com> wrote:
>
> The Synopsys HDMI RX controller exposes two digital audio interfaces,
> one for I2S (0) and one for S/PDIF (1). Add the #sound-dai-cells
> property so audio cards can reference them as a codec, as documented
> by the snps,dw-hdmi-rx binding.
>
> Signed-off-by: Igor Paunovic <royalnet026@gmail.com>
> ---
> New in v3.
>
> arch/arm64/boot/dts/rockchip/rk3588-extra.dtsi | 1 +
> 1 file changed, 1 insertion(+)
>
> diff --git a/arch/arm64/boot/dts/rockchip/rk3588-extra.dtsi b/arch/arm64/boot/dts/rockchip/rk3588-extra.dtsi
> index a264001..fa100e3 100644
> --- a/arch/arm64/boot/dts/rockchip/rk3588-extra.dtsi
> +++ b/arch/arm64/boot/dts/rockchip/rk3588-extra.dtsi
> @@ -338,6 +338,7 @@
> reset-names = "axi", "apb", "ref", "biu";
> rockchip,grf = <&sys_grf>;
> rockchip,vo1-grf = <&vo1_grf>;
> + #sound-dai-cells = <1>;
> status = "disabled";
> };
>
> --
> 2.53.0
>
^ permalink raw reply
* Re: [PATCH v3 4/4] arm64: dts: rockchip: enable HDMI RX audio capture on Orange Pi 5 Plus
From: Igor Paunovic @ 2026-07-18 11:04 UTC (permalink / raw)
To: sashiko-reviews, Dmitry Osipenko, Mauro Carvalho Chehab,
Sebastian Reichel, Heiko Stübner, linux-media,
linux-rockchip, linux-arm-kernel, kernel, linux-kernel
Cc: media-ci, conor+dt, devicetree, robh
In-Reply-To: <20260718091200.65AE21F000E9@smtp.kernel.org>
> Does exposing this codec to the ALSA subsystem trigger a suspend
> regression in the hdmirx driver?
Good catch -- this one is real. The audio worker missed the pattern
the driver already applies to its hotplug and res_change works,
which hdmirx_disable_irq() cancels on the suspend path. Fixed for
v4: suspend cancels audio_work before the controller clocks are
gated, and resume re-arms it when a capture stream is active; the
worker's FIFO error path then resynchronizes the clock and the FIFO
on its first run after resume.
> Should swab32() be used here instead to ensure the byte swap happens
> unconditionally on all architectures?
Yes -- readl() already abstracts the bus endianness, so what this
code wants is an unconditional byte reversal, not an endian
conversion. Switched to swab32() for v4 (no functional change on
arm64, where this controller lives, but the right primitive
regardless).
Both changes are in my tree, compile-tested, and will be part of v4
together with whatever comes out of human review of the series.
Igor
On Sat, Jul 18, 2026 at 11:12 AM <sashiko-bot@kernel.org> wrote:
>
> Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
> - [High] The audio_work delayed work is not cancelled during system suspend, leading to a fatal bus fault.
> - [Medium] Incorrect use of be32_to_cpu() for unconditional byte swapping breaks audio capture on big-endian architectures.
> --
>
> --- Patch [4]: [PATCH v3 4/4] arm64: dts: rockchip: enable HDMI RX audio capture on Orange Pi 5 Plus ---
> commit 030cd8fd5334b79e1751dec57b1de1f5fa4e3df3
> Author: Igor Paunovic <royalnet026@gmail.com>
>
> arm64: dts: rockchip: enable HDMI RX audio capture on Orange Pi 5 Plus
>
> This patch routes the HDMI receiver audio to the i2s7_8ch interface. It creates
> a simple-audio-card configuration to expose a capture-only ALSA card driven
> by the HDMI input. The setup uses the receiver as the bitclock and frame master.
>
> > diff --git a/arch/arm64/boot/dts/rockchip/rk3588-orangepi-5-plus.dts b/arch/arm64/boot/dts/rockchip/rk3588-orangepi-5-plus.dts
> > index 145986695720a..2a68610cddbc3 100644
> > --- a/arch/arm64/boot/dts/rockchip/rk3588-orangepi-5-plus.dts
> > +++ b/arch/arm64/boot/dts/rockchip/rk3588-orangepi-5-plus.dts
> > @@ -37,6 +37,22 @@ hdmi1_con_in: endpoint {
> > };
> > };
> >
> > + hdmiin-sound {
> > + compatible = "simple-audio-card";
> > + simple-audio-card,name = "rockchip,hdmiin";
> > + simple-audio-card,format = "i2s";
> > + simple-audio-card,bitclock-master = <&hdmiin_codec>;
> > + simple-audio-card,frame-master = <&hdmiin_codec>;
> > +
> > + simple-audio-card,cpu {
> > + sound-dai = <&i2s7_8ch>;
> > + };
> > +
> > + hdmiin_codec: simple-audio-card,codec {
> > + sound-dai = <&hdmi_receiver 0>;
>
> [Severity: High]
> Does exposing this codec to the ALSA subsystem trigger a suspend regression in
> the hdmirx driver?
>
> Looking at the underlying codec driver hdmirx_suspend() in snps_hdmirx.c:
>
> drivers/media/platform/synopsys/hdmirx/snps_hdmirx.c:hdmirx_suspend()
> {
> struct snps_hdmirx_dev *hdmirx_dev = dev_get_drvdata(dev);
>
> hdmirx_disable_irq(dev);
>
> /* TODO store CEC HW state */
> disable_irq(hdmirx_dev->cec->irq);
>
> return hdmirx_disable(dev);
> }
>
> The audio_work delayed work is queued on system_unbound_wq, which is not
> freezable, but this suspend callback doesn't cancel it.
>
> If system suspend is initiated while audio capture is active, the worker
> could fire after clocks are disabled via hdmirx_disable(), resulting in
> a bus fault when it performs MMIO reads.
>
> [Severity: Medium]
> Will this audio capture work correctly on big-endian architectures?
>
> The underlying hdmirx_audio_fs() driver function uses be32_to_cpu() for an
> unconditional byte swap when calculating the ACR subpacket:
>
> drivers/media/platform/synopsys/hdmirx/snps_hdmirx.c:hdmirx_audio_fs()
> {
> ...
> acr_cts = be32_to_cpu((__force __be32)acr_pb3_0) & 0xfffff;
> acr_n = (be32_to_cpu((__force __be32)acr_pb7_4) & 0x0fffff00) >> 8;
> ...
> }
>
> Since be32_to_cpu() behaves as a no-op on big-endian CPUs, the bytes remain
> unswapped, causing the bitwise masking to extract the wrong bytes for the
> ACR CTS and N fields.
>
> Should swab32() be used here instead to ensure the byte swap happens
> unconditionally on all architectures?
>
> > + };
> > + };
> > +
>
> [ ... ]
>
> --
> Sashiko AI review · https://sashiko.dev/#/patchset/20260718085728.6797-1-royalnet026@gmail.com?part=4
^ permalink raw reply
* Re: [PATCH mm-hotfixes v5 3/5] x86/mm/pat: acquire init_mm read lock on attribute change to avoid UAF
From: Mike Rapoport @ 2026-07-18 10:54 UTC (permalink / raw)
To: Lorenzo Stoakes (ARM)
Cc: Andrew Morton, Suren Baghdasaryan, Liam R. Howlett,
Vlastimil Babka, Shakeel Butt, David Hildenbrand, Michal Hocko,
Uladzislau Rezki, Toshi Kani, Dave Hansen, Andy Lutomirski,
Peter Zijlstra, Thomas Gleixner, Ingo Molnar, Borislav Petkov,
x86, H. Peter Anvin, Kiryl Shutsemau, Catalin Marinas,
Will Deacon, Dev Jain, Ryan Roberts, David Carlier, linux-mm,
linux-kernel, bpf, linux-arm-kernel, Denis V. Lunev, stable
In-Reply-To: <20260717-series-vmap-race-fix-v5-3-606a0ac6d3e5@kernel.org>
On Fri, Jul 17, 2026 at 06:30:09PM +0100, Lorenzo Stoakes (ARM) wrote:
> A previous commit protected us against races between ptdump and CPA
> collapse, however one still exists between attribute changes and collapse
> as reported by Denis V. Lunev (linked).
>
> When an attribute change arises, a lockless page table walker obtains a PTE
> entry, which is later written to via set_pte_atomic():
>
> ...
> -> change_page_attr_set_clr()
> -> __change_page_attr_set_clr()
> -> __change_page_attr()
> -> _lookup_address_cpa()
> -> lookup_address_in_pgd_attr()
> -> [ lockless page table walker ]
> -> set_pte_atomic()
>
> There is nothing preventing a concurrent CPA collapse which can free the
> PTE that was retrieved here, resulting in a use-after-free.
>
> With the mmap write lock taken on init_mm over CPA collapse, we can now
> resolve this race by acquiring an mmap read lock on init_mm over
> __change_page_attr_set_clr().
>
> This locks across the whole operation over which the walk and the PTE entry
> write occurs, solving the race.
>
> It is safe to do this here, as no spinlocks are held upon entry to
> __change_page_attr_set_clr().
>
> The CPA_COLLAPSE flag is only set by set_memory_rox(), which exclusively
> operates upon vmalloc ranges, and on x86 only within the module mapping
> space.
>
> This is important, because some callers directly invoke
> __change_page_attr_set_clr(), bypassing this lock. However, none of these
> operate within the module mapping space.
>
> * cpa_process_alias() - a recursive helper called by
> __change_page_attr_set_clr().
> * __set_memory_enc_pgtable() - operates on the direct mapping and (via
> __vmbus_establish_gpadl()) the vmalloc mapping space.
> * __set_pages_[n]p() - called by set_direct_map_[invalid, default,
> valid]_noflush(), __kernel_map_pages() - operates on the direct map.
> * kernel_[un]map_pages_in_pgd() - operates on EFI ranges.
>
> This work is based upon Denis V. Lunev's excellent analysis of the bug with
> gratitude.
>
> Link: https://lore.kernel.org/all/20260626163213.2284080-1-den@openvz.org/
> Fixes: 41d88484c71c ("x86/mm/pat: restore large ROX pages after fragmentation")
> Cc: stable@vger.kernel.org
> Signed-off-by: Lorenzo Stoakes (ARM) <ljs@kernel.org>
> ---
> arch/x86/mm/pat/set_memory.c | 4 +++-
> 1 file changed, 3 insertions(+), 1 deletion(-)
>
> diff --git a/arch/x86/mm/pat/set_memory.c b/arch/x86/mm/pat/set_memory.c
> index d1e63f7d267f..301fb9e77d91 100644
> --- a/arch/x86/mm/pat/set_memory.c
> +++ b/arch/x86/mm/pat/set_memory.c
> @@ -2122,7 +2122,9 @@ static int change_page_attr_set_clr(unsigned long *addr, int numpages,
> cpa.curpage = 0;
> cpa.force_split = force_split;
>
> - ret = __change_page_attr_set_clr(&cpa, 1);
> + /* Avoid race with concurrent CPA collapse. */
> + scoped_guard(mmap_read_lock, &init_mm)
> + ret = __change_page_attr_set_clr(&cpa, 1);
There's a small issue with this. debug_pagealloc_unmap_pages() ends up here
and since it's called from __free_pages() it can be in an atomic context.
>
> /*
> * Check whether we really changed something:
>
> --
> 2.55.0
>
--
Sincerely yours,
Mike.
^ permalink raw reply
* Re: [PATCH v3 2/4] media: synopsys: hdmirx: add HDMI audio capture support
From: Igor Paunovic @ 2026-07-18 10:53 UTC (permalink / raw)
To: sashiko-reviews, Dmitry Osipenko, Mauro Carvalho Chehab,
Sebastian Reichel, Heiko Stübner, linux-media,
linux-rockchip, linux-arm-kernel, kernel, linux-kernel
Cc: conor+dt, robh, devicetree, media-ci
In-Reply-To: <20260718090955.A79E51F000E9@smtp.kernel.org>
> Does this byte-swapping logic scramble the extraction of the CTS and N
> values on little-endian architectures?
No. This is the same finding as in the v2 review, where it was already
answered, and the comment this v3 adds above the swap documents exactly
this. Two premises in the report don't match the ACR packet layout:
CTS does not live in PB0..PB2 and is not little-endian. Subpacket
byte 0 is reserved, CTS[19:16] sits in PB1[3:0], CTS[15:8] in PB2 and
CTS[7:0] in PB3 (MSB first), with N likewise in PB4..PB6. The packet
decoder stores PB0 in register bits [7:0], so the byte swap is
precisely what lines the bytes up before the 20-bit masks.
It is also the path validated on hardware: with a 44.1 kHz source the
card reports 44.1 kHz rather than falling back to the 48 kHz default,
and sample-rate switches are followed. Neither would work if the
extraction produced garbage.
> Can this lead to a use-after-free if the driver is unbound while an
> audio stream is active?
No -- the synchronization the report treats as missing is provided by
the ALSA core, and relying on it is why the v2 workaround was dropped
on Dmitry's review in the first place.
The worker is only ever armed between hw_params() and
audio_shutdown(). If a capture stream is still open when the codec
platform device is unregistered, teardown does not complete until the
stream is gone: soc_cleanup_card_resources() calls snd_card_free()
(sound/soc/soc-core.c), which blocks in wait_for_completion() until
the last file handle is closed (sound/core/init.c: "wait, until all
devices are ready for the free operation"). A disconnected card still
routes that final close through the original release path
(snd_disconnect_release() -> disconnected_f_op->release()), so
snd_pcm_release() runs soc_pcm_close() -> hdmi_codec shutdown ->
hdmirx_audio_shutdown(), which clears the streaming flag and
cancel_delayed_work_sync()s the worker.
platform_device_unregister() therefore cannot return with the worker
armed, and the devm-allocated state is freed only after remove()
returns. There is no window for the work to fire on freed memory.
Also exercised on the Orange Pi 5 Plus: unbinding the driver through
sysfs while arecord was actively capturing. The ALSA disconnect kicks
the reader out with ENODEV, the file handle is closed -- which is
where audio_shutdown() runs and cancels the worker -- and only then
does the unbind complete. A subsequent bind re-probes cleanly and the
card comes back. The kernel log stays free of warnings throughout.
Igor
On Sat, Jul 18, 2026 at 11:09 AM <sashiko-bot@kernel.org> wrote:
>
> Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
> - [High] Incorrect byte-swapping logic completely scrambles the extraction of Audio Clock Regeneration (ACR) CTS and N values, breaking sample rate recovery on little-endian architectures.
> - [High] The `audio_work` delayed work is not explicitly cancelled in `hdmirx_remove()`, leading to a Use-After-Free if the driver is unbound while an audio stream is active.
> --
>
> --- Patch [2]: [PATCH v3 2/4] media: synopsys: hdmirx: add HDMI audio capture support ---
> commit b04bcd22f40b424aac824100715c46f764531875
> Author: Igor Paunovic <royalnet026@gmail.com>
>
> media: synopsys: hdmirx: add HDMI audio capture support
>
> The Synopsys DesignWare HDMI RX controller extracts the audio stream
> embedded in the incoming HDMI signal and feeds it to an on-SoC I2S
> controller. Expose it as an ALSA capture device by registering the
> generic hdmi-codec as a child of the controller.
>
> > diff --git a/drivers/media/platform/synopsys/hdmirx/snps_hdmirx.c b/drivers/media/platform/synopsys/hdmirx/snps_hdmirx.c
> > index 25f8ca0d6d946..22f50cbf3fa7a 100644
> > --- a/drivers/media/platform/synopsys/hdmirx/snps_hdmirx.c
> > +++ b/drivers/media/platform/synopsys/hdmirx/snps_hdmirx.c
>
> [ ... ]
>
> > +/* Recover the incoming audio sample rate from the ACR N/CTS + TMDS clock. */
> > +static u32 hdmirx_audio_fs(struct snps_hdmirx_dev *hdmirx_dev)
> > +{
> > + u64 tmds_clk, fs_audio = 0;
> > + u32 acr_cts, acr_n, tmdsqpclk_freq;
> > + u32 acr_pb3_0, acr_pb7_4;
> > +
> > + tmdsqpclk_freq = hdmirx_readl(hdmirx_dev, CMU_TMDSQPCLK_FREQ);
> > + hdmirx_readl(hdmirx_dev, PKTDEC_ACR_PH2_1);
> > + acr_pb3_0 = hdmirx_readl(hdmirx_dev, PKTDEC_ACR_PB3_0);
> > + acr_pb7_4 = hdmirx_readl(hdmirx_dev, PKTDEC_ACR_PB7_4);
> > + /*
> > + * The packet decoder stores the ACR subpacket bytes with packet byte
> > + * 0 in register bits [7:0], so byte-swap each word to line the bytes
> > + * up: CTS is packet bytes 1-3 (PKTDEC_ACR_PB3_0) and N is packet
> > + * bytes 4-6 (PKTDEC_ACR_PB7_4), 20 bits each.
> > + */
> > + acr_cts = be32_to_cpu((__force __be32)acr_pb3_0) & 0xfffff;
> > + acr_n = (be32_to_cpu((__force __be32)acr_pb7_4) & 0x0fffff00) >> 8;
>
> [Severity: High]
> Does this byte-swapping logic scramble the extraction of the CTS and N values
> on little-endian architectures?
>
> Since the HDMI ACR packet transmits the 20-bit CTS value across PB0, PB1, and
> PB2, and because it is little-endian, applying a bitmask like
> acr_pb3_0 & 0xfffff natively yields the correct CTS value without any swaps.
>
> By byte-swapping the 32-bit register, the bytes are completely reversed.
> The subsequent bitmask extracts the lower 20 bits of the swapped word, which
> correspond to the lower nibble of PB1, all of PB2, and all of PB3, discarding
> PB0 entirely.
>
> The same applies to acr_pb7_4 to extract N. Will this regression result in
> garbage values for both acr_cts and acr_n, forcing the driver to blindly
> fall back to the default sample rate?
>
> [ ... ]
>
> > @@ -2784,6 +3052,9 @@ static void hdmirx_remove(struct platform_device *pdev)
> > struct device *dev = &pdev->dev;
> > struct snps_hdmirx_dev *hdmirx_dev = dev_get_drvdata(dev);
> >
> > + if (hdmirx_dev->audio_pdev)
> > + platform_device_unregister(hdmirx_dev->audio_pdev);
> > +
>
> [Severity: High]
> Can this lead to a use-after-free if the driver is unbound while an audio
> stream is active?
>
> The v3 changelog notes that the synchronous cancel for the audio_work
> delayed work was removed here under the assumption that audio_shutdown()
> handles it.
>
> However, ALSA does not synchronously invoke the PCM .shutdown callback
> when a device is unregistered if a userspace application holds the file
> descriptor open.
>
> Because hdmirx_dev is allocated using devm_kzalloc, it is freed immediately
> after hdmirx_remove() returns. Will the un-cancelled audio_work delayed work
> subsequently fire and access the freed hdmirx_dev memory?
>
> > v4l2_debugfs_if_free(hdmirx_dev->infoframes);
> > debugfs_remove_recursive(hdmirx_dev->debugfs_dir);
>
> --
> Sashiko AI review · https://sashiko.dev/#/patchset/20260718085728.6797-1-royalnet026@gmail.com?part=2
^ permalink raw reply
* [RFC PATCH v4 3/3] x86/mm: add set_direct_map_ro_noflush()
From: Xueyuan Chen @ 2026-07-18 9:56 UTC (permalink / raw)
To: linux-mm, Andrew Morton, David Hildenbrand, Lorenzo Stoakes
Cc: linux-kernel, linux-arm-kernel, Catalin Marinas, Will Deacon,
Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen, x86,
H . Peter Anvin, Andy Lutomirski, Peter Zijlstra, Lance Yang,
Usama Arif, Jann Horn, Yang Shi, Mike Rapoport, Zi Yan,
Baolin Wang, Liam R . Howlett, Nico Pache, Ryan Roberts, Dev Jain,
Barry Song, Xueyuan Chen
In-Reply-To: <20260718095647.182592-1-xueyuan.chen21@gmail.com>
Implement set_direct_map_ro_noflush() for x86 using CPA directly on the
passed direct-map address. Clear _PAGE_RW and _PAGE_DIRTY, keep alias
checks disabled like the existing direct-map _noflush helpers, and leave
TLB invalidation to the caller.
Co-developed-by: Lance Yang <lance.yang@linux.dev>
Signed-off-by: Lance Yang <lance.yang@linux.dev>
Signed-off-by: Xueyuan Chen <xueyuan.chen21@gmail.com>
---
arch/x86/include/asm/set_memory.h | 2 ++
arch/x86/mm/pat/set_memory.c | 15 +++++++++++++++
2 files changed, 17 insertions(+)
diff --git a/arch/x86/include/asm/set_memory.h b/arch/x86/include/asm/set_memory.h
index 4362c26aa992..bd3817e06052 100644
--- a/arch/x86/include/asm/set_memory.h
+++ b/arch/x86/include/asm/set_memory.h
@@ -89,6 +89,8 @@ int set_pages_rw(struct page *page, int numpages);
int set_direct_map_invalid_noflush(struct page *page);
int set_direct_map_default_noflush(struct page *page);
int set_direct_map_valid_noflush(struct page *page, unsigned nr, bool valid);
+int set_direct_map_ro_noflush(const void *addr, unsigned long nr_pages);
+#define set_direct_map_ro_noflush set_direct_map_ro_noflush
bool kernel_page_present(struct page *page);
extern int kernel_set_to_readonly;
diff --git a/arch/x86/mm/pat/set_memory.c b/arch/x86/mm/pat/set_memory.c
index d023a40a1e03..5987f4c84f6f 100644
--- a/arch/x86/mm/pat/set_memory.c
+++ b/arch/x86/mm/pat/set_memory.c
@@ -2662,6 +2662,21 @@ int set_direct_map_valid_noflush(struct page *page, unsigned nr, bool valid)
return __set_pages_np(page, nr);
}
+int set_direct_map_ro_noflush(const void *addr, unsigned long nr_pages)
+{
+ unsigned long tempaddr = (unsigned long)addr;
+ struct cpa_data cpa = {
+ .vaddr = &tempaddr,
+ .pgd = NULL,
+ .numpages = nr_pages,
+ .mask_set = __pgprot(0),
+ .mask_clr = __pgprot(_PAGE_RW | _PAGE_DIRTY),
+ .flags = CPA_NO_CHECK_ALIAS,
+ };
+
+ return __change_page_attr_set_clr(&cpa, 1);
+}
+
#ifdef CONFIG_DEBUG_PAGEALLOC
void __kernel_map_pages(struct page *page, int numpages, int enable)
{
--
2.47.3
^ permalink raw reply related
* [RFC PATCH v4 2/3] arm64/mm: add set_direct_map_ro_noflush()
From: Xueyuan Chen @ 2026-07-18 9:56 UTC (permalink / raw)
To: linux-mm, Andrew Morton, David Hildenbrand, Lorenzo Stoakes
Cc: linux-kernel, linux-arm-kernel, Catalin Marinas, Will Deacon,
Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen, x86,
H . Peter Anvin, Andy Lutomirski, Peter Zijlstra, Lance Yang,
Usama Arif, Jann Horn, Yang Shi, Mike Rapoport, Zi Yan,
Baolin Wang, Liam R . Howlett, Nico Pache, Ryan Roberts, Dev Jain,
Barry Song, Xueyuan Chen
In-Reply-To: <20260718095647.182592-1-xueyuan.chen21@gmail.com>
Implement set_direct_map_ro_noflush() for arm64 with update_range_prot() on
the linear map, setting PTE_RDONLY and clearing PTE_WRITE. Keep the
existing can_set_direct_map() guard and leave TLB invalidation to the
caller.
Co-developed-by: Lance Yang <lance.yang@linux.dev>
Signed-off-by: Lance Yang <lance.yang@linux.dev>
Signed-off-by: Xueyuan Chen <xueyuan.chen21@gmail.com>
---
arch/arm64/include/asm/set_memory.h | 2 ++
arch/arm64/mm/pageattr.c | 10 ++++++++++
2 files changed, 12 insertions(+)
diff --git a/arch/arm64/include/asm/set_memory.h b/arch/arm64/include/asm/set_memory.h
index 90f61b17275e..7083260303c3 100644
--- a/arch/arm64/include/asm/set_memory.h
+++ b/arch/arm64/include/asm/set_memory.h
@@ -14,6 +14,8 @@ int set_memory_valid(unsigned long addr, int numpages, int enable);
int set_direct_map_invalid_noflush(struct page *page);
int set_direct_map_default_noflush(struct page *page);
int set_direct_map_valid_noflush(struct page *page, unsigned nr, bool valid);
+int set_direct_map_ro_noflush(const void *addr, unsigned long nr_pages);
+#define set_direct_map_ro_noflush set_direct_map_ro_noflush
bool kernel_page_present(struct page *page);
int set_memory_encrypted(unsigned long addr, int numpages);
diff --git a/arch/arm64/mm/pageattr.c b/arch/arm64/mm/pageattr.c
index ce035e1b4eaf..c51236b61651 100644
--- a/arch/arm64/mm/pageattr.c
+++ b/arch/arm64/mm/pageattr.c
@@ -365,6 +365,16 @@ int set_direct_map_valid_noflush(struct page *page, unsigned nr, bool valid)
return set_memory_valid(addr, nr, valid);
}
+int set_direct_map_ro_noflush(const void *addr, unsigned long nr_pages)
+{
+ if (!can_set_direct_map())
+ return 0;
+
+ return update_range_prot((unsigned long)addr, PAGE_SIZE * nr_pages,
+ __pgprot(PTE_RDONLY),
+ __pgprot(PTE_WRITE));
+}
+
#ifdef CONFIG_DEBUG_PAGEALLOC
/*
* This is - apart from the return value - doing the same
--
2.47.3
^ permalink raw reply related
* [RFC PATCH v4 1/3] mm: make persistent huge zero folio read-only
From: Xueyuan Chen @ 2026-07-18 9:56 UTC (permalink / raw)
To: linux-mm, Andrew Morton, David Hildenbrand, Lorenzo Stoakes
Cc: linux-kernel, linux-arm-kernel, Catalin Marinas, Will Deacon,
Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen, x86,
H . Peter Anvin, Andy Lutomirski, Peter Zijlstra, Lance Yang,
Usama Arif, Jann Horn, Yang Shi, Mike Rapoport, Zi Yan,
Baolin Wang, Liam R . Howlett, Nico Pache, Ryan Roberts, Dev Jain,
Barry Song, Xueyuan Chen
In-Reply-To: <20260718095647.182592-1-xueyuan.chen21@gmail.com>
The persistent huge zero folio is shared globally and should stay zero
after initialization. As Jann Horn pointed out[1], kernel bugs have ended
up writing to pages that were meant to be read-only, including in
security-sensitive cases. Making the persistent huge zero folio read-only
in the direct map turns such writes into faults instead of silent zero-page
corruption.
Add set_direct_map_ro_noflush() so mm code can make a direct-map range
read-only. Use an address-based signature to match ongoing direct-map
helper work[2], where existing page-based helpers may move the same way.
The helper is direct-map specific and leaves TLB invalidation to its
caller. Architectures without direct-map permission support keep existing
behavior through the generic stub.
The folio is allocated and zeroed through the writable direct map before
thp_shrinker_init() changes its permissions. thp_shrinker_init() is called
from hugepage_init(), which is registered as a subsys_initcall and runs
after SMP initialization. Stale writable kernel TLB entries may therefore
exist. Flush the direct-map range immediately after the page-table update
so they cannot bypass the read-only mapping.
Treat the direct-map permission change as best-effort. Architectures that
do not implement the helper keep the existing behavior via the generic
stub.
Inspired by Jann Horn's read-only zero page work[1] and follow-up
discussion[3] with Yang Shi.
[1] https://lore.kernel.org/linux-mm/20260508-ro-zeropage-v1-1-9808abc20b49@google.com/
[2] https://lore.kernel.org/linux-mm/0e5b23a6-4895-454a-9dfa-6dc21adc2991@kernel.org/
[3] https://lore.kernel.org/linux-mm/CAHbLzkrXXe7r3n3jXgDKtwZhRqj=jDx9E6dLOULohnhBguvi9A@mail.gmail.com/
Suggested-by: David Hildenbrand <david@kernel.org>
Suggested-by: Usama Arif <usama.arif@linux.dev>
Co-developed-by: Lance Yang <lance.yang@linux.dev>
Signed-off-by: Lance Yang <lance.yang@linux.dev>
Signed-off-by: Xueyuan Chen <xueyuan.chen21@gmail.com>
---
include/linux/set_memory.h | 29 +++++++++++++++++++++++++++++
mm/huge_memory.c | 16 +++++++++++++++-
2 files changed, 44 insertions(+), 1 deletion(-)
diff --git a/include/linux/set_memory.h b/include/linux/set_memory.h
index 3030d9245f5a..e83ced6a3827 100644
--- a/include/linux/set_memory.h
+++ b/include/linux/set_memory.h
@@ -40,6 +40,24 @@ static inline int set_direct_map_valid_noflush(struct page *page,
return 0;
}
+/**
+ * set_direct_map_ro_noflush - make a direct-map range read-only
+ * @addr: start address in the direct map
+ * @nr_pages: number of pages starting at @addr
+ *
+ * Make the direct-map range starting at @addr read-only without invalidating
+ * TLBs. Callers must either ensure that no stale writable translations can
+ * be used, or treat the permission change as a best-effort hardening step.
+ *
+ * Return: 0 on success or when direct-map permission changes are unsupported,
+ * or a negative errno on failure.
+ */
+static inline int set_direct_map_ro_noflush(const void *addr,
+ unsigned long nr_pages)
+{
+ return 0;
+}
+
static inline bool kernel_page_present(struct page *page)
{
return true;
@@ -56,6 +74,17 @@ static inline bool can_set_direct_map(void)
}
#define can_set_direct_map can_set_direct_map
#endif
+
+#ifndef set_direct_map_ro_noflush
+/* See the comment above the generic fallback for the _noflush contract. */
+static inline int set_direct_map_ro_noflush(const void *addr,
+ unsigned long nr_pages)
+{
+ return 0;
+}
+
+#define set_direct_map_ro_noflush set_direct_map_ro_noflush
+#endif
#endif /* CONFIG_ARCH_HAS_SET_DIRECT_MAP */
#ifdef CONFIG_X86_64
diff --git a/mm/huge_memory.c b/mm/huge_memory.c
index 970e077019b7..4425ae5560cb 100644
--- a/mm/huge_memory.c
+++ b/mm/huge_memory.c
@@ -40,8 +40,10 @@
#include <linux/pgalloc.h>
#include <linux/pgalloc_tag.h>
#include <linux/pagewalk.h>
+#include <linux/set_memory.h>
#include <asm/tlb.h>
+#include <asm/tlbflush.h>
#include "internal.h"
#include "swap.h"
@@ -932,6 +934,8 @@ static int __init thp_shrinker_init(void)
shrinker_register(deferred_split_shrinker);
if (IS_ENABLED(CONFIG_PERSISTENT_HUGE_ZERO_FOLIO)) {
+ unsigned long addr;
+
/*
* Bump the reference of the huge_zero_folio and do not
* initialize the shrinker.
@@ -940,8 +944,18 @@ static int __init thp_shrinker_init(void)
* that get_huge_zero_folio() will most likely not fail as
* thp_shrinker_init() is invoked early on during boot.
*/
- if (!get_huge_zero_folio())
+ if (!get_huge_zero_folio()) {
pr_warn("Allocating persistent huge zero folio failed\n");
+ return 0;
+ }
+
+ addr = (unsigned long)folio_address(huge_zero_folio);
+ /*
+ * The folio was zeroed through the writable direct map. Flush
+ * after the page-table update to invalidate stale translations.
+ */
+ set_direct_map_ro_noflush((void *)addr, HPAGE_PMD_NR);
+ flush_tlb_kernel_range(addr, addr + HPAGE_PMD_SIZE);
return 0;
}
--
2.47.3
^ permalink raw reply related
* [RFC PATCH v4 0/3] make persistent huge zero folio read-only
From: Xueyuan Chen @ 2026-07-18 9:56 UTC (permalink / raw)
To: linux-mm, Andrew Morton, David Hildenbrand, Lorenzo Stoakes
Cc: linux-kernel, linux-arm-kernel, Catalin Marinas, Will Deacon,
Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen, x86,
H . Peter Anvin, Andy Lutomirski, Peter Zijlstra, Lance Yang,
Usama Arif, Jann Horn, Yang Shi, Mike Rapoport, Zi Yan,
Baolin Wang, Liam R . Howlett, Nico Pache, Ryan Roberts, Dev Jain,
Barry Song, Xueyuan Chen
The persistent huge zero folio is shared globally and should stay zero
after initialization. As Jann Horn pointed out[1], kernel bugs have ended
up writing to pages that were meant to be read-only, including in
security-sensitive cases. Making the folio read-only in the direct map
turns such writes into faults instead of silent zero-page corruption.
This series adds set_direct_map_ro_noflush() so mm code can make a
direct-map range read-only, then uses it for the persistent huge zero
folio. The helper is direct-map specific, takes an address-based range as
discussed for set_direct_map* helpers[2], and leaves TLB invalidation to
the caller.
The folio is allocated and zeroed through the writable direct map before
thp_shrinker_init() changes its permissions. thp_shrinker_init() is called
from hugepage_init(), which is registered as a subsys_initcall and runs
after SMP initialization. Writable TLB entries may therefore already be
cached when the page-table permissions change. v4 flushes the exact
direct-map range immediately after the noflush page-table update. Keeping
the flush at the call site preserves the helper's explicit noflush contract
and follows existing direct-map helper users such as secretmem and
hibernation.
Patches 2 and 3 add arm64 and x86 implementations.
[1]: https://lore.kernel.org/linux-mm/20260508-ro-zeropage-v1-1-9808abc20b49@google.com/
[2]: https://lore.kernel.org/linux-mm/0e5b23a6-4895-454a-9dfa-6dc21adc2991@kernel.org/
[3]: https://lore.kernel.org/linux-mm/CAHbLzkrXXe7r3n3jXgDKtwZhRqj=jDx9E6dLOULohnhBguvi9A@mail.gmail.com/
RFC v3 -> RFC v4:
- Patch #01: Flush the direct-map range after changing it read-only, since
the folio was cleared through writable mappings after SMP initialization
(per Usama, thanks!).
- Patch #01: Keep the flush in the caller to preserve the
set_direct_map_ro_noflush() contract and make the flushed range explicit.
- Patch #01: Clarify the noflush API contract and the reason stale writable
translations must be invalidated.
Link: https://lore.kernel.org/linux-mm/20260706130440.9295-1-xueyuan.chen21@gmail.com/
RFC v2 -> RFC v3:
- Patch #01: Replace arch_make_pages_readonly() with
set_direct_map_ro_noflush() in the existing set_direct_map* family
(per Mike and David, thanks!).
- Patch #01: Use a direct-map address and number of pages, and document the
direct-map-only and no-TLB-flush semantics (per David, thanks!).
- Patch #02 and #03: Update the arm64 and x86 implementations for
set_direct_map_ro_noflush().
Link: https://lore.kernel.org/linux-mm/20260609143801.7917-1-xueyuan.chen21@gmail.com/
RFC v1 -> RFC v2:
- Patch #01: Drop the READONLY_HUGE_ZERO_FOLIO Kconfig option
(per Dave, thanks!).
- Patch #01: Replace the huge-zero-folio-specific hook with a generic
page-range hook (per David, thanks!).
- Patch #02 and #03: Update the arm64 and x86 implementations for the new
hook.
Link: https://lore.kernel.org/linux-mm/20260527035607.14919-1-xueyuan.chen21@gmail.com/
Xueyuan Chen (3):
mm: make persistent huge zero folio read-only
arm64/mm: add set_direct_map_ro_noflush()
x86/mm: add set_direct_map_ro_noflush()
arch/arm64/include/asm/set_memory.h | 2 ++
arch/arm64/mm/pageattr.c | 10 ++++++++++
arch/x86/include/asm/set_memory.h | 2 ++
arch/x86/mm/pat/set_memory.c | 15 +++++++++++++++
include/linux/set_memory.h | 29 +++++++++++++++++++++++++++++
mm/huge_memory.c | 16 +++++++++++++++-
6 files changed, 73 insertions(+), 1 deletion(-)
--
2.47.3
^ permalink raw reply
* [PATCH v2] ARM: imx: Fix suspend/resume crash with Clang CFI
From: Yo'av Moshe @ 2026-07-18 9:19 UTC (permalink / raw)
To: Frank Li, Sascha Hauer, Russell King
Cc: Pengutronix Kernel Team, Fabio Estevam, Nathan Chancellor,
Nick Desaulniers, Bill Wendling, Justin Stitt, imx,
linux-arm-kernel, llvm, stable, linux-kernel, Yo'av Moshe
Relocated suspend code in OCRAM lacks compiler-generated CFI type
signatures. When CONFIG_CFI=y is active, the indirect call to
imx6_suspend_in_ocram_fn triggers a strict CFI violation panic.
Annotate imx6q_suspend_finish with __nocfi to bypass CFI checking
for this specific indirect call.
Additionally, protect the imx6_suspend_in_ocram_fn pointer by marking
it __ro_after_init to prevent it from being used as a CFI bypass
exploit vector.
Cc: stable@vger.kernel.org
Signed-off-by: Yo'av Moshe <linux@yoavmoshe.com>
---
Tested on a Kobo Clara HD (i.MX6SLL SoC) running postmarketOS edge.
Before this patch, suspending the device caused an immediate silent
hang requiring a hard-reboot. With this patch applied, suspend and
resume work successfully.
Differences from v1:
- Added __ro_after_init to imx6_suspend_in_ocram_fn to prevent it
from being exploited as a CFI bypass gadget.
arch/arm/mach-imx/pm-imx6.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/arm/mach-imx/pm-imx6.c b/arch/arm/mach-imx/pm-imx6.c
index a671ca498..b425a4701 100644
--- a/arch/arm/mach-imx/pm-imx6.c
+++ b/arch/arm/mach-imx/pm-imx6.c
@@ -63,7 +63,7 @@
static void __iomem *ccm_base;
static void __iomem *suspend_ocram_base;
-static void (*imx6_suspend_in_ocram_fn)(void __iomem *ocram_vbase);
+static void (*imx6_suspend_in_ocram_fn)(void __iomem *ocram_vbase) __ro_after_init;
/*
* suspend ocram space layout:
@@ -360,7 +360,7 @@ int imx6_set_lpm(enum mxc_cpu_pwr_mode mode)
return 0;
}
-static int imx6q_suspend_finish(unsigned long val)
+static int __nocfi imx6q_suspend_finish(unsigned long val)
{
if (!imx6_suspend_in_ocram_fn) {
cpu_do_idle();
--
2.55.0
^ permalink raw reply related
* [PATCH] ARM: smp: set current pointer in assembly before jumping into C
From: Karl Mehltretter @ 2026-07-18 9:16 UTC (permalink / raw)
To: Russell King
Cc: Karl Mehltretter, Ard Biesheuvel, linux-arm-kernel, linux-kernel,
stable
With CONFIG_KCOV_INSTRUMENT_ALL=y, secondary CPUs fail to come online
on ARMv6K/ARMv7 SMP:
CPU1: failed to boot: -38
The compiler inserts a call to __sanitizer_cov_trace_pc() at the entry
of secondary_start_kernel(), before set_current(task). The KCOV hook
dereferences current while TPIDRURO is still uninitialized, causing a
data abort before cpu_init() has installed the exception stacks. The
secondary CPU consequently never completes startup.
Initialize current in the secondary assembly handoff, as
__mmap_switched already does for the boot CPU.
Fixes: 50596b7559bf ("ARM: smp: Store current pointer in TPIDRURO register if available")
Cc: stable@vger.kernel.org
Assisted-by: Claude:claude-fable-5
Signed-off-by: Karl Mehltretter <kmehltretter@gmail.com>
---
Tested on QEMU vexpress-a15 (mainline and v6.12) and
realview-eb-mpcore with and without CONFIG_KCOV_INSTRUMENT_ALL.
The head-nommu.S change is untested because no currently reachable
Kconfig combination enables non-MMU SMP.
The redundant set_current(task) is retained to keep the fix minimal.
arch/arm/kernel/head-nommu.S | 1 +
arch/arm/kernel/head.S | 1 +
2 files changed, 2 insertions(+)
diff --git a/arch/arm/kernel/head-nommu.S b/arch/arm/kernel/head-nommu.S
index b9d6818f1ee1..f80bbfbd3a6f 100644
--- a/arch/arm/kernel/head-nommu.S
+++ b/arch/arm/kernel/head-nommu.S
@@ -116,6 +116,7 @@ ENTRY(secondary_startup)
ldr r7, __secondary_data @ reload r7
ldr sp, [r7, #12] @ set up the stack pointer
ldr r0, [r7, #16] @ set up task pointer
+ set_current r0, r1
mov fp, #0
b secondary_start_kernel
ENDPROC(secondary_startup)
diff --git a/arch/arm/kernel/head.S b/arch/arm/kernel/head.S
index f22c50d4bd41..a22403a629ef 100644
--- a/arch/arm/kernel/head.S
+++ b/arch/arm/kernel/head.S
@@ -442,6 +442,7 @@ ENTRY(__secondary_switched)
adr_l r7, secondary_data + 12 @ get secondary_data.stack
ldr sp, [r7]
ldr r0, [r7, #4] @ get secondary_data.task
+ set_current r0, r1
mov fp, #0
b secondary_start_kernel
ENDPROC(__secondary_switched)
--
2.43.0
^ permalink raw reply related
* [PATCH] drm/meson: constrain the DW-HDMI regmap range
From: Zinan Zhou @ 2026-07-18 9:07 UTC (permalink / raw)
To: Neil Armstrong
Cc: Zinan Zhou, Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
David Airlie, Simona Vetter, Kevin Hilman, Jerome Brunet,
Martin Blumenstingl, dri-devel, linux-amlogic, linux-arm-kernel,
linux-kernel
The DesignWare HDMI regmap declares 0x10000 as its inclusive maximum
register. A regmap traversal can consequently read one byte past the
directly mapped G12A 64 KiB resource. It also treats the Meson TOP window
from offset 0x8000 as DWC registers. On the older indirect interface, the
address is truncated to 16 bits and aliases register zero.
Limit the regmap to 0x7e12, the last register defined by the supported
Synopsys HDMI controller. This also keeps register iteration below the
Meson TOP register window at offset 0x8000.
Fixes: 3f68be7d8e96 ("drm/meson: Add support for HDMI encoder and DW-HDMI bridge + PHY")
Assisted-by: Codex:gpt-5.6-sol
Signed-off-by: Zinan Zhou <zinan@mieulab.com>
---
drivers/gpu/drm/meson/meson_dw_hdmi.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/meson/meson_dw_hdmi.c b/drivers/gpu/drm/meson/meson_dw_hdmi.c
index fef1702acb14..1004108fb7ca 100644
--- a/drivers/gpu/drm/meson/meson_dw_hdmi.c
+++ b/drivers/gpu/drm/meson/meson_dw_hdmi.c
@@ -100,6 +100,8 @@
#define HDMITX_DWC_ADDR_REG 0x10
#define HDMITX_DWC_DATA_REG 0x14
#define HDMITX_DWC_CTRL_REG 0x18
+/* Last DWC register; direct layouts place the TOP block at offset 0x8000. */
+#define HDMITX_DWC_MAX_REGISTER 0x7e12
/* HHI Registers */
#define HHI_MEM_PD_REG0 0x100 /* 0x40 */
@@ -564,7 +566,7 @@ static const struct regmap_config meson_dw_hdmi_regmap_config = {
.val_bits = 8,
.reg_read = meson_dw_hdmi_reg_read,
.reg_write = meson_dw_hdmi_reg_write,
- .max_register = 0x10000,
+ .max_register = HDMITX_DWC_MAX_REGISTER,
.fast_io = true,
};
base-commit: b0a652436b892eb9a036a031b33099dca036faaa
--
2.43.0
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox