Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* Re: [PATCH v4 04/13] dma: swiotlb: track pool encryption state and honor DMA_ATTR_CC_SHARED
From: Aneesh Kumar K.V @ 2026-05-20  3:57 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: Mostafa Saleh, iommu, linux-arm-kernel, linux-kernel, linux-coco,
	Robin Murphy, Marek Szyprowski, Will Deacon, Marc Zyngier,
	Steven Price, Suzuki K Poulose, Catalin Marinas, Jiri Pirko,
	Petr Tesarik, Alexey Kardashevskiy, Dan Williams, Xu Yilun,
	linuxppc-dev, linux-s390, Madhavan Srinivasan, Michael Ellerman,
	Nicholas Piggin, Christophe Leroy (CS GROUP), Alexander Gordeev,
	Gerald Schaefer, Heiko Carstens, Vasily Gorbik,
	Christian Borntraeger, Sven Schnelle, x86
In-Reply-To: <20260519161120.GO7702@ziepe.ca>

Jason Gunthorpe <jgg@ziepe.ca> writes:

> On Tue, May 19, 2026 at 09:35:30PM +0530, Aneesh Kumar K.V wrote:
>> Yes, that also resulted in simpler and cleaner code.
>> 
>> swiotlb_tbl_map_single
>> 	/*
>> 	 * If the physical address is encrypted but the device requires
>> 	 * decrypted DMA, use a decrypted io_tlb_mem and update the
>> 	 * attributes so the caller knows that a decrypted io_tlb_mem
>> 	 * was used.
>> 	 */
>> 	if (!(*attrs & DMA_ATTR_CC_SHARED) && force_dma_unencrypted(dev))
>> 		*attrs |= DMA_ATTR_CC_SHARED;
>> 
>> 	if (mem->unencrypted != !!(*attrs & DMA_ATTR_CC_SHARED))
>> 		return (phys_addr_t)DMA_MAPPING_ERROR;
>
> Yeah, exactly that is so much clearer now that the mem->unecrypted is
> tied directly.
>
> That logic is reversed though, the incoming ATTR_CC doesn't matter for
> swiotlb, that is just the source of the memcpy.
>
> /* swiotlb pool is incorrect for this device */
> if (mem->unencrypted != force_dma_unencrypted(dev))
>     return (phys_addr_t)DMA_MAPPING_ERROR;
>
> /* Force attrs to match the kind of memory in the pool */
> if (mem->unencrypted)
>      *attrs |= DMA_ATTR_CC_SHARED;
> else
>      *attrs &= ~DMA_ATTR_CC_SHARED;
>
>
> Attrs should be forced to whatever memory swiotlb selected.
>

But that will not handle a T=1 device that wants to use swiotlb to
bounce unencrypted memory. That is:

force_dma_unencrypted(dev) == 0  /* T=1 device */
attrs = DMA_ATTR_CC_SHARED;

In that case, it should use an unencrypted io_tlb_mem:
mem->unencrypted == 1

-aneesh


^ permalink raw reply

* RE: [PATCH v4 00/24] iommu/arm-smmu-v3: Quarantine device upon ATC invalidation timeout
From: Tian, Kevin @ 2026-05-20  3:59 UTC (permalink / raw)
  To: Nicolin Chen, Will Deacon, Robin Murphy, Joerg Roedel,
	Bjorn Helgaas, Jason Gunthorpe
  Cc: Rafael J . Wysocki, Len Brown, Pranjal Shrivastava, Mostafa Saleh,
	Lu Baolu, linux-arm-kernel@lists.infradead.org,
	iommu@lists.linux.dev, linux-kernel@vger.kernel.org,
	linux-acpi@vger.kernel.org, linux-pci@vger.kernel.org,
	Vikram Sethi, Shuai Xue
In-Reply-To: <cover.1779161849.git.nicolinc@nvidia.com>

> From: Nicolin Chen <nicolinc@nvidia.com>
> Sent: Tuesday, May 19, 2026 11:39 AM
>
> Changelog
> v4:
>  * Rebase on Joerg's IOMMU "fixes" branch
>  * Rebase on Jason's SMMUv3 cmd_ent series
>    https://lore.kernel.org/all/0-v2-47b2bf710ad5+716ac-
> smmu_no_cmdq_ent_jgg@nvidia.com/
>  * [PCI] Don't suspend IOMMU in probe mode
>  * [iommu] kfree_rcu() iommu_group
>  * [iommu] Convert gdev->blocked to enum gdev_blocked
>  * [iommu] Use disable_work_sync() to fix UAF and ref leak
>  * [iommu] Gate done() transitions to preserve BLOCKED_BROKEN
>  * [iommu] Decrement recovery_cnt when unplugging a blocked gdev
>  * [iommu] Drop racy dev_has_iommu() in iommu_report_device_broken()
>  * [iommu] Add gdev->broken_pending to skip worker after racing recovery
>  * [smmuv3] Add master->ats_invs scratch
>  * [smmuv3] Add arm_smmu_cmdq_batch_issue() wrapper
>  * [smmuv3] Force per-flush sync for has_ats batches
>  * [smmuv3] Serialize STE.EATS and ats_broken updates
>  * [smmuv3] Co-clear pending CMDQ_ERR from cmdq issuer
>  * [smmuv3] Add invs and has_ats to arm_smmu_cmdq_batch
>  * [smmuv3] Move arm_smmu_invs_for_each_entry to header
>  * [smmuv3] Set master->ats_broken after clearing STE.EATS
>  * [smmuv3] Issue CFGI_STE via arm_smmu_cmdq_issue_cmd_with_sync()
>  * [smmuv3] Keep "smmu" pointer in arm_smmu_inv but add "master" for
> ATS

Not check the detail yet, but this v4 more than doubles the number of
patches in v3. Are they all necessary to be in one series? any chance to
split to ease the review...


^ permalink raw reply

* Re: [PATCH] ARM64: remove unnecessary architecture-specific <asm/device.h>
From: Ethan Nelson-Moore @ 2026-05-20  4:03 UTC (permalink / raw)
  To: Will Deacon; +Cc: linux-arm-kernel, linux-kernel, Catalin Marinas
In-Reply-To: <agxToDJ6y_ciI1Oj@willie-the-truck>

Hi, Will,

On Tue, May 19, 2026 at 5:12 AM Will Deacon <will@kernel.org> wrote:
> Do we need to add a generic-y entry to arch/arm64/include/asm/Kbuild
> so that we pick up the asm-generic variant?

No, we don't, because device.h is in the list of mandatory headers in
include/asm-generic/Kbuild, which means a header including the generic
version will automatically be generated if an architecture-specific
version does not exist.

Ethan


^ permalink raw reply

* Re: [PATCH v2 1/4] dt-bindings: display: verisilicon, dc: generalize for single-output variants
From: Icenowy Zheng @ 2026-05-20  4:07 UTC (permalink / raw)
  To: Joey Lu, Conor Dooley
  Cc: maarten.lankhorst, mripard, tzimmermann, airlied, simona, robh,
	krzk+dt, conor+dt, ychuang3, schung, yclu4, dri-devel, devicetree,
	linux-arm-kernel, linux-kernel
In-Reply-To: <a112cb8b-21fb-4c33-89a3-14a4feb5e3f9@gmail.com>

在 2026-05-20三的 11:06 +0800,Joey Lu写道:
> On 5/20/2026 12:47 AM, Conor Dooley wrote:
> > On Tue, May 19, 2026 at 03:26:58PM +0800, Icenowy Zheng wrote:
> > > 在 2026-05-19二的 13:51 +0800,Joey Lu写道:
> > > > The existing schema assumes a fixed clock/reset topology and
> > > > dual-
> > > > output
> > > > port structure matching the DC8200 IP block.  This prevents
> > > > reuse for
> > > > single-output variants such as the Verisilicon DCU Lite used in
> > > > the
> > > > Nuvoton MA35D1 SoC.
> > > > 
> > > > Rework the schema so that variant-specific constraints are
> > > > expressed
> > > > via allOf/if-then-else:
> > > > 
> > > > - The thead,th1520-dc8200 compatible keeps its existing five-
> > > > clock,
> > > >    three-reset, dual-port requirements.
> > > > 
> > > > - A standalone verisilicon,dc compatible covers IPs whose
> > > > identity is
> > > >    discovered entirely through hardware registers; these have
> > > > flexible
> > > >    clock and reset counts, a single 'port' property, and no
> > > > 'ports'
> > > >    requirement.
> > > > 
> > > > Changes to the base schema:
> > > > - Replace the fixed clock/reset items lists with
> > > > minItems/maxItems
> > > >    ranges; variant sub-schemas tighten the constraints via if-
> > > > then-
> > > > else.
> > > > - Add a 'port' property (graph.yaml single-port alias)
> > > > alongside the
> > > >    existing 'ports', for single-output variants.
> > > > - Drop the unconditional 'ports' requirement; each if-branch
> > > > enforces
> > > >    its own port topology.
> > > > - Tighten additionalProperties to unevaluatedProperties to
> > > > allow
> > > >    per-variant schemas to add their own constraints cleanly.
> > > > - Fix a stray space in the port@0 description.
> > > > - Add a DT example for the generic verisilicon,dc compatible
> > > >    (Nuvoton MA35D1 DCU Lite).
> > > > 
> > > > Signed-off-by: Joey Lu <a0987203069@gmail.com>
> > > > ---
> > > >   .../bindings/display/verisilicon,dc.yaml      | 135
> > > > ++++++++++++++--
> > > > --
> > > >   1 file changed, 108 insertions(+), 27 deletions(-)
> > > > 
> > > > diff --git
> > > > a/Documentation/devicetree/bindings/display/verisilicon,dc.yaml
> > > > b/Documentation/devicetree/bindings/display/verisilicon,dc.yaml
> > > > index 9dc35ab973f2..3a814c2e083e 100644
> > > > ---
> > > > a/Documentation/devicetree/bindings/display/verisilicon,dc.yaml
> > > > +++
> > > > b/Documentation/devicetree/bindings/display/verisilicon,dc.yaml
> > > > @@ -14,10 +14,12 @@ properties:
> > > >       pattern: "^display@[0-9a-f]+$"
> > > >   
> > > >     compatible:
> > > > -    items:
> > > > -      - enum:
> > > > -          - thead,th1520-dc8200
> > > You should add a fallback compatible here for your SoC, in case
> > > its
> > > integration gets something quirky; this compatible is usually not
> > > consumed by the driver (see how thead,th1520-dc8200 exists in the
> > > binding but not the driver).
> > s/fallback compatible/soc-specific compatible/, but yes.
> > NAK to what's been done here, especially after the discussions on
> > earlier versions of this verisilicon binding.
> > pw-bot: changes-requested
> Understood. I will add `nuvoton,ma35d1-dcu` as the SoC-specific 
> compatible string paired with `verisilicon,dc` as the generic
> fallback, 
> matching the pattern used for `thead,th1520-dc8200`. The standalone 
> `verisilicon,dc` compatible will be removed from the binding. The
> driver 

No, please don't remove compatible strings from existing binding, and
the generic compatible is still used for driver binding.

The SoC-specific compatible is informative here, it needs to exist, but
it doesn't supersede "verisilicon,dc" .

In addition, the SoC-specific compatible is also used for verification
of the SoC device tree, which is the reason if clauses exist with
compatible match and additional constraints (e.g. for the nuvoton DCU
it's invalid to have a 2nd output port).

> match table is not changed since hardware detection is done via ID 
> registers.
> > > > -      - const: verisilicon,dc # DC IPs have discoverable
> > > > ID/revision
> > > > registers
> > > > +    oneOf:
> > > > +      - items:
> > > > +          - enum:
> > > > +              - thead,th1520-dc8200
> > > > +          - const: verisilicon,dc
> > > > +      - const: verisilicon,dc  # DC IPs have discoverable
> > > > ID/revision registers
> > > >   
> > > >     reg:
> > > >       maxItems: 1
> > > > @@ -26,32 +28,24 @@ properties:
> > > >       maxItems: 1
> > > >   
> > > >     clocks:
> > > > -    items:
> > > > -      - description: DC Core clock
> > > > -      - description: DMA AXI bus clock
> > > > -      - description: Configuration AHB bus clock
> > > > -      - description: Pixel clock of output 0
> > > > -      - description: Pixel clock of output 1
> > > > +    minItems: 2
> > > > +    maxItems: 5
> > > >   
> > > >     clock-names:
> > > > -    items:
> > > > -      - const: core
> > > > -      - const: axi
> > > > -      - const: ahb
> > > > -      - const: pix0
> > > > -      - const: pix1
> > > > +    minItems: 2
> > > > +    maxItems: 5
> > > >   
> > > >     resets:
> > > > -    items:
> > > > -      - description: DC Core reset
> > > > -      - description: DMA AXI bus reset
> > > > -      - description: Configuration AHB bus reset
> > > > +    minItems: 1
> > > > +    maxItems: 3
> > > >   
> > > >     reset-names:
> > > > -    items:
> > > > -      - const: core
> > > > -      - const: axi
> > > > -      - const: ahb
> > > > +    minItems: 1
> > > > +    maxItems: 3
> > > > +
> > > > +  port:
> > > > +    $ref: /schemas/graph.yaml#/properties/port
> > > > +    description: Single video output port for single-output
> > > > variants.
> > > Maybe the endpoint numbering rule needs a move to here? (I am not
> > > very
> > > sure).
> I will add a description to the `port` property noting that endpoint
> 0 
> is used for DPI output, which is the only output type for
> DCUltraLite.

Please note that DC8000 exists, which is single-port but supports both
DPI and DP.

> > > >   
> > > >     ports:
> > > >       $ref: /schemas/graph.yaml#/properties/ports
> > > > @@ -59,7 +53,7 @@ properties:
> > > >       properties:
> > > >         port@0:
> > > >           $ref: /schemas/graph.yaml#/properties/port
> > > > -        description: The first output channel , endpoint 0
> > > > should be
> > > > +        description: The first output channel, endpoint 0
> > > > should be
> > > >             used for DPI format output and endpoint 1 should be
> > > > used
> > > >             for DP format output.
> > > >   
> > > > @@ -75,9 +69,75 @@ required:
> > > >     - interrupts
> > > >     - clocks
> > > >     - clock-names
> > > > -  - ports
> > > >   
> > > > -additionalProperties: false
> > > > +allOf:
> > > > +  - if:
> > > > +      properties:
> > > > +        compatible:
> > > > +          contains:
> > > > +            const: thead,th1520-dc8200
> > > > +    then:
> > > > +      properties:
> > > > +        clocks:
> > > > +          items:
> > > > +            - description: DC Core clock
> > > > +            - description: DMA AXI bus clock
> > > > +            - description: Configuration AHB bus clock
> > > > +            - description: Pixel clock of output 0
> > > > +            - description: Pixel clock of output 1
> > > > +
> > > > +        clock-names:
> > > > +          items:
> > > > +            - const: core
> > > > +            - const: axi
> > > > +            - const: ahb
> > > > +            - const: pix0
> > > > +            - const: pix1
> > > > +
> > > > +        resets:
> > > > +          items:
> > > > +            - description: DC Core reset
> > > > +            - description: DMA AXI bus reset
> > > > +            - description: Configuration AHB bus reset
> > > > +
> > > > +        reset-names:
> > > > +          items:
> > > > +            - const: core
> > > > +            - const: axi
> > > > +            - const: ahb
> > > > +
> > > > +      required:
> > > > +        - ports
> > > > +
> > > > +    else:
> > > > +      properties:
> > > > +        clocks:
> > > > +          items:
> > > > +            - description: Bus clock that gates register
> > > > access
> > > > +            - description: Pixel clock divider for display
> > > > timing
> > > Please don't make compatible-specific description strings for
> > > individual compatibles, and keep these descriptions outside of
> > > the if.
> > > The compatible-specific part should be used to specify what's
> > > required
> > > for the specific SoC, for dt validation purpose.
> > > 
> > > BTW if the clock is both the working clock and bus clock for the
> > > controller, I suggest listing it twice, except if the IP core is
> > > provided without a dedicated core clock (in the case I suggest to
> > > use
> > > "bus" only).
> > I agree. If the same clock is provided to two+ ports on the IP,
> > that
> > should still be two+ clocks in the devicetree.
> > 
> > > Here's an example for "listing it twice":
> > > ```
> > > clocks = <&clk DCU_GATE>, <&clk DCU_GATE>, <&clk DCUP_DIV>;
> > > clock-names = "core", "bus", "pix0";
> > > ```
> > > 
> > > Well nonetheless the name "core" does not match the description
> > > "Bus
> > > clock that gates register access".
> > > 
> > > Thanks,
> > > Icenowy
> 
> Understood. I will remove all description strings from the if/else 
> branches; the if/then clauses will only constrain clock-names and 
> reset-names items (name values only, no descriptions). Regarding
> clock 

Well I think a required properties list is also needed in the if/then
clause, to prevent DT's from lacking properties.

> naming: DCU_GATE on MA35D1 is a peripheral gate clock without a
> separate 
> dedicated core working clock, so I will keep "core" as the name and

Do you mean there's no seperate dedicated bus clock? I find that in the
clock driver dcu_gate has no parent as bus clocks -- its parent is
dcu_mux, and dcu_mux's 2 parents are both pll ("epll_div2" and
"syspll").

Thanks,
Icenowy

> drop 
> the misleading description "Bus clock that gates register access".
> The 
> description mismatch was entirely in the if/else strings which are
> now 
> removed.
> 
> Thanks.
> 
> > > 
> > > > +
> > > > +        clock-names:
> > > > +          items:
> > > > +            - const: core
> > > > +            - const: pix0
> > > > +
> > > > +        resets:
> > > > +          maxItems: 1
> > > > +          description:
> > > > +            Reset line for the display controller.
> > > > +
> > > > +        reset-names:
> > > > +          items:
> > > > +            - const: core
> > > > +
> > > > +      required:
> > > > +        - port
> > > > +
> > > > +      not:
> > > > +        required:
> > > > +          - ports
> > > > +
> > > > +unevaluatedProperties: false
> > > >   
> > > >   examples:
> > > >     - |
> > > > @@ -120,3 +180,24 @@ examples:
> > > >           };
> > > >         };
> > > >       };
> > > > +
> > > > +  - |
> > > > +    #include <dt-bindings/interrupt-controller/arm-gic.h>
> > > > +    #include <dt-bindings/clock/nuvoton,ma35d1-clk.h>
> > > > +    #include <dt-bindings/reset/nuvoton,ma35d1-reset.h>
> > > > +
> > > > +    display@40260000 {
> > > > +        compatible = "verisilicon,dc";
> > > > +        reg = <0x40260000 0x20000>;
> > > > +        interrupts = <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>;
> > > > +        clocks = <&clk DCU_GATE>, <&clk DCUP_DIV>;
> > > > +        clock-names = "core", "pix0";
> > > > +        resets = <&sys MA35D1_RESET_DISP>;
> > > > +        reset-names = "core";
> > > > +
> > > > +        port {
> > > > +            dpi_out: endpoint {
> > > > +                remote-endpoint = <&panel_in>;
> > > > +            };
> > > > +        };
> > > > +    };



^ permalink raw reply

* [PATCH v2] ARM: PCI: merge pci_common_init_dev() into pci_common_init()
From: Ethan Nelson-Moore @ 2026-05-20  4:13 UTC (permalink / raw)
  To: linux-arm-kernel, linux-kernel
  Cc: Andrew Lunn, Ethan Nelson-Moore, Russell King, Bjorn Helgaas,
	Ilpo Järvinen, Kuninori Morimoto

pci_common_init() is a compatibility wrapper that simply calls
pci_common_init_dev() with an additional NULL argument. The comment
above it implies that it should be replaced by pci_common_init_dev(),
but that has never happened - there are no callers of
pci_common_init_dev() in the kernel. Make the PCI code more
straightforward by getting rid of the wrapper function and instead
removing the device argument from pci_common_init_dev() and renaming it
to pci_common_init().

Signed-off-by: Ethan Nelson-Moore <enelsonmoore@gmail.com>
---
Changes in v2: Instead of removing pci_common_init() and converting all
callers to use pci_common_init_dev(), simply remove
pci_common_init_dev() and the unused parent parameter in
pcibios_init_hw(). Suggested by Andrew Lunn.

 arch/arm/include/asm/mach/pci.h | 11 +----------
 arch/arm/kernel/bios32.c        |  8 +++-----
 2 files changed, 4 insertions(+), 15 deletions(-)

diff --git a/arch/arm/include/asm/mach/pci.h b/arch/arm/include/asm/mach/pci.h
index ece5283bdaec..83777d8c8e65 100644
--- a/arch/arm/include/asm/mach/pci.h
+++ b/arch/arm/include/asm/mach/pci.h
@@ -50,16 +50,7 @@ struct pci_sys_data {
 /*
  * Call this with your hw_pci struct to initialise the PCI system.
  */
-void pci_common_init_dev(struct device *, struct hw_pci *);
-
-/*
- * Compatibility wrapper for older platforms that do not care about
- * passing the parent device.
- */
-static inline void pci_common_init(struct hw_pci *hw)
-{
-	pci_common_init_dev(NULL, hw);
-}
+void pci_common_init(struct hw_pci *hw);
 
 /*
  * Setup early fixed I/O mapping.
diff --git a/arch/arm/kernel/bios32.c b/arch/arm/kernel/bios32.c
index ac0e890510da..a5d3c31bfa55 100644
--- a/arch/arm/kernel/bios32.c
+++ b/arch/arm/kernel/bios32.c
@@ -424,8 +424,7 @@ static int pcibios_init_resource(int busnr, struct pci_sys_data *sys)
 	return 0;
 }
 
-static void pcibios_init_hw(struct device *parent, struct hw_pci *hw,
-			    struct list_head *head)
+static void pcibios_init_hw(struct hw_pci *hw, struct list_head *head)
 {
 	struct pci_sys_data *sys = NULL;
 	int ret;
@@ -466,7 +465,6 @@ static void pcibios_init_hw(struct device *parent, struct hw_pci *hw,
 			else {
 				list_splice_init(&sys->resources,
 						 &bridge->windows);
-				bridge->dev.parent = parent;
 				bridge->sysdata = sys;
 				bridge->busnr = sys->busnr;
 				bridge->ops = hw->ops;
@@ -492,7 +490,7 @@ static void pcibios_init_hw(struct device *parent, struct hw_pci *hw,
 	}
 }
 
-void pci_common_init_dev(struct device *parent, struct hw_pci *hw)
+void pci_common_init(struct hw_pci *hw)
 {
 	struct pci_sys_data *sys;
 	LIST_HEAD(head);
@@ -500,7 +498,7 @@ void pci_common_init_dev(struct device *parent, struct hw_pci *hw)
 	pci_add_flags(PCI_REASSIGN_ALL_BUS);
 	if (hw->preinit)
 		hw->preinit();
-	pcibios_init_hw(parent, hw, &head);
+	pcibios_init_hw(hw, &head);
 	if (hw->postinit)
 		hw->postinit();
 
-- 
2.43.0



^ permalink raw reply related

* [PATCH v3] media: meson: vdec: Fix memory leak in error path of vdec_open
From: Anand Moon @ 2026-05-20  4:40 UTC (permalink / raw)
  To: Neil Armstrong, Mauro Carvalho Chehab, Greg Kroah-Hartman,
	Kevin Hilman, Jerome Brunet, Martin Blumenstingl, Maxime Jourdan,
	Hans Verkuil,
	open list:MESON VIDEO DECODER DRIVER FOR AMLOGIC SOCS,
	open list:MESON VIDEO DECODER DRIVER FOR AMLOGIC SOCS,
	open list:STAGING SUBSYSTEM,
	moderated list:ARM/Amlogic Meson SoC support, open list
  Cc: Nicolas Dufresne

The vdec_open() function previously jumped directly to
err_m2m_release when vdec_init_ctrls() failed, skipping
release of the m2m context. This caused a resource leak.

Fix it by introducing a proper err_m2m_ctx_release label
that calls v4l2_m2m_ctx_release(sess->m2m_ctx) before
releasing the m2m device.

This was identified via kmemleak:
unreferenced object 0xffff0000205d6878 (size 8):
  comm "v4l_id", pid 5289, jiffies 4294938580
  hex dump (first 8 bytes):
    40 d2 49 18 00 00 ff ff                          @.I.....
  backtrace (crc d3204599):
    kmemleak_alloc+0xc8/0xf0
    __kvmalloc_node_noprof+0x60c/0x850
    v4l2_ctrl_handler_init_class+0x1b4/0x2e8 [videodev]
    vdec_open+0x1f4/0x788 [meson_vdec]
    v4l2_open+0x144/0x460 [videodev]
    chrdev_open+0x1ac/0x500
    do_dentry_open+0x3f0/0xfe8
    vfs_open+0x68/0x320
    do_open+0x2d8/0x9a8
    path_openat+0x1d0/0x4f0
    do_filp_open+0x190/0x380
    do_sys_openat2+0xf8/0x1b0
    __arm64_sys_openat+0x13c/0x1e8
    invoke_syscall+0xdc/0x268
    el0_svc_common.constprop.0+0x178/0x258
    do_el0_svc+0x4c/0x70

Cc: Nicolas Dufresne <nicolas@ndufresne.ca>
Fixes: 3e7f51bd9607 ("media: meson: add v4l2 m2m video decoder driver")
Signed-off-by: Anand Moon <linux.amoon@gmail.com>
---
v2: https://lore.kernel.org/all/20260321065408.209723-1-linux.amoon@gmail.com/
   updated the commit message, applied the suggestion from sashiko
   below.
  [3] https://sashiko.dev/#/patchset/20260321065408.209723-1-linux.amoon%40gmail.com

v1: https://lore.kernel.org/all/20260304100557.126488-1-linux.amoon@gmail.com/
   tried to address the issue reported by Nicolas
   improve the commit message.
---
 drivers/staging/media/meson/vdec/vdec.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/staging/media/meson/vdec/vdec.c b/drivers/staging/media/meson/vdec/vdec.c
index 4b77ec1af5a7..a039d925c0fe 100644
--- a/drivers/staging/media/meson/vdec/vdec.c
+++ b/drivers/staging/media/meson/vdec/vdec.c
@@ -889,7 +889,7 @@ static int vdec_open(struct file *file)
 
 	ret = vdec_init_ctrls(sess);
 	if (ret)
-		goto err_m2m_release;
+		goto err_m2m_ctx_release;
 
 	sess->pixfmt_cap = formats[0].pixfmts_cap[0];
 	sess->fmt_out = &formats[0];
@@ -913,6 +913,8 @@ static int vdec_open(struct file *file)
 
 	return 0;
 
+err_m2m_ctx_release:
+	v4l2_m2m_ctx_release(sess->m2m_ctx);
 err_m2m_release:
 	v4l2_m2m_release(sess->m2m_dev);
 err_free_sess:

base-commit: 27fa82620cbaa89a7fc11ac3057701d598813e87
-- 
2.50.1



^ permalink raw reply related

* Re: [PATCH] ARM: mach-rpc: fix zImage build after recent font-related changes
From: Ethan Nelson-Moore @ 2026-05-20  4:49 UTC (permalink / raw)
  To: Helge Deller; +Cc: linux-arm-kernel, linux-fbdev, Russell King
In-Reply-To: <agwpPFGkN3zHKdCj@carbonx1>

Hi, Helge,

Thanks for investigating this issue.

On Tue, May 19, 2026 at 2:11 AM Helge Deller <deller@kernel.org> wrote:
> Ethan, does this compile-only-tested patch fix the issue?
It almost does - I also had to remove #include <linux/math.h> from
include/linux/font.h.
This is probably because of the following highly questionable code in
arch/arm/boot/compressed/Makefile:
CFLAGS_font.o := -Dstatic=
which is causing unused static functions to not be optimized out. (The
real purpose of it is to make the acorndata_8x8 array non-static so
the decompressor can use it.) Really, the decompressor should be fixed
to not use this hack.

> Maybe only the first hunk is necessary.
You're right. The kernel links successfully with only the #include
<linux/math.h> removal and the first hunk applied.

Have a nice day!

Ethan


^ permalink raw reply

* [PATCH] arm64: Add user and kernel page-fault tracepoints
From: Justinien Bouron @ 2026-05-20  4:55 UTC (permalink / raw)
  To: Catalin Marinas, Will Deacon, David Hildenbrand, Mark Rutland,
	Ryan Roberts, Ada Couprie Diaz, Kevin Brodsky, Lorenzo Stoakes,
	Quentin Perret, linux-arm-kernel, linux-kernel
  Cc: Justinien Bouron, Gunnar Kudrjavets

Those tracepoints were made generic in commit 06aa9378df01
("x86/tracing, x86/mm: Move page fault tracepoints to generic"), call
them from arm64's page fault handling routine.

Signed-off-by: Justinien Bouron <jbouron@amazon.com>
Reviewed-by: Gunnar Kudrjavets <gunnarku@amazon.com>
---
Benchmarking
============

Since the added code sits in the page-fault handling hot-path, I've also
ran some benchmarks to make sure this change is not accidentally
introducing a regression. All testing below was done on a c6g.metal EC2
instance (i.e. bare-metal) which is an ARM64 CPU with 64 cores and
128GiB of RAM.

First, a microbenchmark that maps anonymous memory and write to the
first four bytes of each page, thus running into page-fault for each
one:
```
#include <stdio.h>
#include <sys/mman.h>
#include <stdint.h>
#include <stdlib.h>
#include <unistd.h>
#include <assert.h>

int main(int argc, char **argv) {
    int npages = atoi(argv[1]);
    size_t size = npages * 4096;
    printf("pid = %d\n", getpid());
    char *p = mmap((void*)0xcafe0000,
            size,
            PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED,
            -1, 0);
    assert(p != MAP_FAILED);
    for (int i = 0; i < npages; i++)
        *(uint32_t *)(p + i * 4096) = 0xdeadbeef;
    munmap(p, size);
}
```

Compiled with: `gcc microbench.c -no-pie -o microbench` (GCC 15.2.0)

Before the change:
    $ hyperfine --runs 50 './microbench 100000'
    Benchmark 1: ./microbench 100000
      Time (mean +/- stddev):     174.3 ms +/-   3.4 ms    [User: 5.9 ms, System: 168.3 ms]
      Range (min ... max):   168.7 ms ... 185.1 ms    50 runs
After the change:
    $ hyperfine --runs 50 './microbench_orig 100000'
    Benchmark 1: ./microbench 100000
      Time (mean +/- stddev):     177.9 ms +/-   3.1 ms    [User: 6.3 ms, System: 171.6 ms]
      Range (min ... max):   173.3 ms ... 186.0 ms    50 runs

Second benchmark, linux kernel compilation benchmark with defconfig (on
commit 70390501):

Before the change:
    $ hyperfine --runs 3 --prepare 'make clean && sync && echo 3 | sudo tee /proc/sys/vm/drop_caches' 'make -j65'
    Benchmark 1: make -j65
      Time (mean +/- stddev):     155.744 s +/-  2.767 s    [User: 6812.900 s, System: 1156.095 s]
      Range (min ... max):   153.709 s ... 158.895 s    3 runs

After the change:
    $ hyperfine --runs 3 --prepare 'make clean && sync && echo 3 | sudo tee /proc/sys/vm/drop_caches' 'make -j65'
    Benchmark 1: make -j65
      Time (mean +/- stddev):     153.315 s +/-  0.179 s    [User: 6799.948 s, System: 1148.976 s]
      Range (min ... max):   153.119 s ... 153.471 s    3 runs

Testing
=======

Re-using the microbenchmark above, we can see the page-faults generated
by writing to each mmap'ed page (mmap'ed region starts at address
0xcafe0000):
```
$ sudo perf record -e exceptions:page_fault_user -- ./microbench 16
pid = 307352
[ perf record: Woken up 2 times to write data ]
[ perf record: Captured and wrote 0.015 MB perf.data (63 samples) ]
$ sudo perf script
      microbench  307352 [034] 29395.753387: exceptions:page_fault_user: address=0xfffff7fda640 ip=0xfffff7fda640 error_code=0x82000007
      microbench  307352 [034] 29395.753406: exceptions:page_fault_user: address=0xfffff7fff066 ip=0xfffff7fd60c4 error_code=0x92000007
      microbench  307352 [034] 29395.753407: exceptions:page_fault_user: address=0xfffff7fff066 ip=0xfffff7fd60cc error_code=0x9200004f
      microbench  307352 [034] 29395.753410: exceptions:page_fault_user: address=0xfffff7ffde28 ip=0xfffff7fd60d0 error_code=0x92000007
      microbench  307352 [034] 29395.753412: exceptions:page_fault_user: address=0xfffff7ffde70 ip=0xfffff7fd619c error_code=0x9200004f
      microbench  307352 [034] 29395.753416: exceptions:page_fault_user: address=0xfffff7fbeb38 ip=0xfffff7fd6304 error_code=0x92000007
      microbench  307352 [034] 29395.753419: exceptions:page_fault_user: address=0xfffff7ffcd28 ip=0xfffff7fd62f8 error_code=0x9200004f
      microbench  307352 [034] 29395.753422: exceptions:page_fault_user: address=0xffffffffeff0 ip=0xfffff7fcfa90 error_code=0x92000047
      microbench  307352 [034] 29395.753428: exceptions:page_fault_user: address=0xfffff7fe1b90 ip=0xfffff7fdc9b0 error_code=0x92000007
      microbench  307352 [034] 29395.753431: exceptions:page_fault_user: address=0x400040 ip=0xfffff7fd7160 error_code=0x92000007
      microbench  307352 [034] 29395.753432: exceptions:page_fault_user: address=0x41fdf8 ip=0xfffff7fd72f0 error_code=0x92000007
      microbench  307352 [034] 29395.753434: exceptions:page_fault_user: address=0xfffff7ffa020 ip=0xfffff7fd7548 error_code=0x92000007
      microbench  307352 [034] 29395.753437: exceptions:page_fault_user: address=0xfffff7ffb000 ip=0xfffff7fd7640 error_code=0x92000007
      microbench  307352 [034] 29395.753443: exceptions:page_fault_user: address=0xfffff7ff4008 ip=0xfffff7fc4848 error_code=0x92000047
      microbench  307352 [034] 29395.753446: exceptions:page_fault_user: address=0x41fec0 ip=0xfffff7fd7cd0 error_code=0x9200004f
      microbench  307352 [034] 29395.753464: exceptions:page_fault_user: address=0xfffff7fed000 ip=0xfffff7fd11c4 error_code=0x92000007
      microbench  307352 [034] 29395.753502: exceptions:page_fault_user: address=0xfffff7fa14d8 ip=0xfffff7fdcbe0 error_code=0x92000047
      microbench  307352 [034] 29395.753509: exceptions:page_fault_user: address=0xfffff7f9fa88 ip=0xfffff7fc54c0 error_code=0x92000007
      microbench  307352 [034] 29395.753512: exceptions:page_fault_user: address=0xfffff7f9fb20 ip=0xfffff7fc5534 error_code=0x9200004f
      microbench  307352 [034] 29395.753515: exceptions:page_fault_user: address=0xfffff7de02e0 ip=0xfffff7fc5704 error_code=0x92000006
      microbench  307352 [034] 29395.753519: exceptions:page_fault_user: address=0xfffff7f887c8 ip=0xfffff7fc4bb0 error_code=0x92000007
      microbench  307352 [034] 29395.753522: exceptions:page_fault_user: address=0xfffff7dffcef ip=0xfffff7fdc358 error_code=0x92000007
      microbench  307352 [034] 29395.753526: exceptions:page_fault_user: address=0xfffff7e01650 ip=0xfffff7fd027c error_code=0x92000007
      microbench  307352 [034] 29395.753530: exceptions:page_fault_user: address=0xfffff7ff5610 ip=0xfffff7fdcc10 error_code=0x92000047
      microbench  307352 [034] 29395.753534: exceptions:page_fault_user: address=0xfffff7f9d080 ip=0xfffff7fcb6a4 error_code=0x9200004f
      microbench  307352 [034] 29395.753538: exceptions:page_fault_user: address=0xfffff7f9e000 ip=0xfffff7fcb6fc error_code=0x9200004f
      microbench  307352 [034] 29395.753542: exceptions:page_fault_user: address=0xfffff7fa02d8 ip=0xfffff7fcb6a4 error_code=0x9200004f
      microbench  307352 [034] 29395.753568: exceptions:page_fault_user: address=0xfffff7e821c0 ip=0xfffff7e821c0 error_code=0x82000007
      microbench  307352 [034] 29395.753585: exceptions:page_fault_user: address=0xfffff7feb000 ip=0xfffff7fc1a40 error_code=0x92000047
      microbench  307352 [034] 29395.753594: exceptions:page_fault_user: address=0xfffff7f2b1e0 ip=0xfffff7f2b1e0 error_code=0x82000007
      microbench  307352 [034] 29395.753596: exceptions:page_fault_user: address=0xfffff7e1188c ip=0xfffff7e1188c error_code=0x82000007
      microbench  307352 [034] 29395.753597: exceptions:page_fault_user: address=0xfffff7fa7458 ip=0xfffff7f2b21c error_code=0x92000047
      microbench  307352 [034] 29395.753600: exceptions:page_fault_user: address=0xfffff7fade39 ip=0xfffff7f2b224 error_code=0x92000047
      microbench  307352 [034] 29395.753601: exceptions:page_fault_user: address=0xfffff7ecdd20 ip=0xfffff7ecdd20 error_code=0x82000007
      microbench  307352 [034] 29395.753603: exceptions:page_fault_user: address=0xfffff7fa6518 ip=0xfffff7f2b2a0 error_code=0x92000047
      microbench  307352 [034] 29395.753605: exceptions:page_fault_user: address=0xfffff7e6ec50 ip=0xfffff7e6ec50 error_code=0x82000007
      microbench  307352 [034] 29395.753607: exceptions:page_fault_user: address=0xfffff7fa2180 ip=0xfffff7e1c918 error_code=0x92000047
      microbench  307352 [034] 29395.753609: exceptions:page_fault_user: address=0xfffff7e7dac8 ip=0xfffff7e7dac8 error_code=0x82000007
      microbench  307352 [034] 29395.753623: exceptions:page_fault_user: address=0xfffff7ed6720 ip=0xfffff7ed6720 error_code=0x82000007
      microbench  307352 [034] 29395.753626: exceptions:page_fault_user: address=0xfffff7e28220 ip=0xfffff7e28220 error_code=0x82000007
      microbench  307352 [034] 29395.753627: exceptions:page_fault_user: address=0xfffff7f349e2 ip=0xfffff7e282b8 error_code=0x92000007
      microbench  307352 [034] 29395.753629: exceptions:page_fault_user: address=0xfffff7ead1c0 ip=0xfffff7ead1c0 error_code=0x82000007
      microbench  307352 [034] 29395.753631: exceptions:page_fault_user: address=0xfffff7e39e40 ip=0xfffff7e39e40 error_code=0x82000007
      microbench  307352 [034] 29395.753633: exceptions:page_fault_user: address=0xfffff7f453c4 ip=0xfffff7e37c58 error_code=0x92000007
      microbench  307352 [034] 29395.753635: exceptions:page_fault_user: address=0xfffff7f53412 ip=0xfffff7e2e788 error_code=0x92000007
      microbench  307352 [034] 29395.753636: exceptions:page_fault_user: address=0xfffff7e53bc0 ip=0xfffff7e53bc0 error_code=0x82000007
      microbench  307352 [034] 29395.753643: exceptions:page_fault_user: address=0x421008 ip=0xfffff7e7bbc8 error_code=0x92000047
      microbench  307352 [034] 29395.753658: exceptions:page_fault_user: address=0xcafe0000 ip=0x4008e4 error_code=0x92000045
      microbench  307352 [034] 29395.753663: exceptions:page_fault_user: address=0xcafe1000 ip=0x4008e4 error_code=0x92000047
      microbench  307352 [034] 29395.753664: exceptions:page_fault_user: address=0xcafe2000 ip=0x4008e4 error_code=0x92000047
      microbench  307352 [034] 29395.753666: exceptions:page_fault_user: address=0xcafe3000 ip=0x4008e4 error_code=0x92000047
      microbench  307352 [034] 29395.753675: exceptions:page_fault_user: address=0xcafe4000 ip=0x4008e4 error_code=0x92000047
      microbench  307352 [034] 29395.753676: exceptions:page_fault_user: address=0xcafe5000 ip=0x4008e4 error_code=0x92000047
      microbench  307352 [034] 29395.753678: exceptions:page_fault_user: address=0xcafe6000 ip=0x4008e4 error_code=0x92000047
      microbench  307352 [034] 29395.753679: exceptions:page_fault_user: address=0xcafe7000 ip=0x4008e4 error_code=0x92000047
      microbench  307352 [034] 29395.753681: exceptions:page_fault_user: address=0xcafe8000 ip=0x4008e4 error_code=0x92000047
      microbench  307352 [034] 29395.753682: exceptions:page_fault_user: address=0xcafe9000 ip=0x4008e4 error_code=0x92000047
      microbench  307352 [034] 29395.753684: exceptions:page_fault_user: address=0xcafea000 ip=0x4008e4 error_code=0x92000047
      microbench  307352 [034] 29395.753686: exceptions:page_fault_user: address=0xcafeb000 ip=0x4008e4 error_code=0x92000047
      microbench  307352 [034] 29395.753687: exceptions:page_fault_user: address=0xcafec000 ip=0x4008e4 error_code=0x92000047
      microbench  307352 [034] 29395.753689: exceptions:page_fault_user: address=0xcafed000 ip=0x4008e4 error_code=0x92000047
      microbench  307352 [034] 29395.753691: exceptions:page_fault_user: address=0xcafee000 ip=0x4008e4 error_code=0x92000047
      microbench  307352 [034] 29395.753692: exceptions:page_fault_user: address=0xcafef000 ip=0x4008e4 error_code=0x92000047
```

IP 0x4008e4 corresponds to the instruction where the write to each page
is performed:
```
   4008c8:       b9402be0        ldr     w0, [sp, #40]
   4008cc:       53144c00        lsl     w0, w0, #12
   4008d0:       93407c00        sxtw    x0, w0
   4008d4:       f9401fe1        ldr     x1, [sp, #56]
   4008d8:       8b000020        add     x0, x1, x0
   4008dc:       5297dde1        mov     w1, #0xbeef                     // #48879
   4008e0:       72bbd5a1        movk    w1, #0xdead, lsl #16
=> 4008e4:       b9000001        str     w1, [x0]
   4008e8:       b9402be0        ldr     w0, [sp, #40]
   4008ec:       11000400        add     w0, w0, #0x1
   4008f0:       b9002be0        str     w0, [sp, #40]
   4008f4:       b9402be1        ldr     w1, [sp, #40]
   4008f8:       b9402fe0        ldr     w0, [sp, #44]
   4008fc:       6b00003f        cmp     w1, w0
   400900:       54fffe4b        b.lt    4008c8 <main+0x9c>  // b.tstop
```

First error_code when writing to the mmap'ed region is 0x92000045 which,
as expected, corresponds to user-mode, write fault, at page-table level
1 (see https://esr.arm64.dev/#0x92000045). Following faults have similar
error_code but for page-table level 3 fault
(https://esr.arm64.dev/#0x92000047).

For kernel page-faults, tested using tracepoints directly:
```
# echo 1 > events/exceptions/page_fault_kernel/enable
# echo test
test
# cat trace_pipe
    ps-307392  [028] ..... 29802.331281: page_fault_kernel: address=0xaaaaaaae0280 ip=__arch_clear_user error_code=0x96000044
    ps-307392  [028] ..... 29802.331303: page_fault_kernel: address=0xfffff7ffe8e4 ip=__arch_clear_user error_code=0x96000046
    ps-307392  [028] ..... 29802.331851: page_fault_kernel: address=0xfffff7f13360 ip=strncpy_from_user error_code=0x96000007
    ps-307392  [028] ..... 29802.349787: page_fault_kernel: address=0xaaaaaab23000 ip=__arch_copy_to_user error_code=0x96000047
    ...
```

---
 arch/arm64/mm/fault.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c
index 0f3c5c7ca054..e75cc0348e74 100644
--- a/arch/arm64/mm/fault.c
+++ b/arch/arm64/mm/fault.c
@@ -45,6 +45,9 @@
 #include <asm/traps.h>
 #include <asm/virt.h>
 
+#define CREATE_TRACE_POINTS
+#include <trace/events/exceptions.h>
+
 struct fault_info {
 	int	(*fn)(unsigned long far, unsigned long esr,
 		      struct pt_regs *regs);
@@ -606,6 +609,11 @@ static int __kprobes do_page_fault(unsigned long far, unsigned long esr,
 	int si_code;
 	int pkey = -1;
 
+	if (user_mode(regs))
+		trace_page_fault_user(addr, regs, esr);
+	else
+		trace_page_fault_kernel(addr, regs, esr);
+
 	if (kprobe_page_fault(regs, esr))
 		return 0;
 
-- 
2.53.0



^ permalink raw reply related

* RE: [PATCH 2/5] dt-bindings: connector: Add fsl,io-connector binding
From: Chancel Liu (OSS) @ 2026-05-20  5:02 UTC (permalink / raw)
  To: Krzysztof Kozlowski, Chancel Liu
  Cc: robh@kernel.org, krzk+dt@kernel.org, conor+dt@kernel.org,
	Frank Li, s.hauer@pengutronix.de, festevam@gmail.com,
	mturquette@baylibre.com, sboyd@kernel.org, kernel@pengutronix.de,
	devicetree@vger.kernel.org, linux-kernel@vger.kernel.org,
	imx@lists.linux.dev, linux-arm-kernel@lists.infradead.org,
	linux-clk@vger.kernel.org, Chancel Liu (OSS)
In-Reply-To: <20260519-macho-degu-from-nibiru-960af2@quoll>

> > > >>> +description:
> > > >>> +  The NXP I/O connector represents a physically present I/O
> > > >>> +connector on the
> > > >>> +  base board. It acts as a nexus that exposes a constrained set
> of
> > > >>> +I/O
> > > >>> +  resources, such as GPIOs, clocks, PWMs and interrupts, through
> > > >>> +fixed
> > > >>> +  electrical wiring. All actual hardware providers reside on the
> base
> > > board.
> > > >>> +  The connector node only defines index-based mappings to those
> > > >> providers.
> > > >>> +
> > > >>> +properties:
> > > >>> +  compatible:
> > > >>> +    const: fsl,io-connector
> > > >>
> > > >> Everything is IO. Everything is connector, so your compatible does
> > > >> not match requirements from writing bindings.
> > > >>
> > > >
> > > > Yes, this compatible is too generic. I will rename the compatible to
> > > > fsl,aud-io-connector.
> > >
> > > aud is not much better. Which boards have it? What's the pinout?
> What's
> > > standard? Is it described anywhere? If so, provide reference to
> spec/docs.
> > >
> >
> > This is not an industry standard electrical interface. This connector
> 
> Then if you do not have standard, then you have board specific layouts
> thus you need board-specific compatibles. You can use fallbacks. Generic
> fallback could work, but both io-connector and aud-io-connector are just
> too generic. Every connector is "connector" and "io", thus absolutely
> anything can be "io-connector". "aud" improves it only a bit, thus
> honestly I would go with board specific fallback as well.
> 

How about board specific + common fallback compatible like this:
  compatible:
    items:
      - enum:
          - fsl,imx95-19x19-evk-aud-io-connector
          - fsl,imx952-evk-aud-io-connector
      - const: fsl,imx-aud-io-connector
Since the daughter board is named “IMX-AUD-IO” in publicly available
documentation, common compatible clearly indicates that this connector
is intended for that.

Also, I want to talk about the topic of generic connector. It's a common
design that daughter board is connected to base board through a
connector. This connector more often acts as a nexus that exposes a
constrained subset of GPIO, clock, PWM and interrupt resources to the
daughter board. Can we document this kind of connector as a generic
binding?

Regards, 
Chancel Liu

> > is present on i.MX95-19x19-EVK and i.MX952-EVK. For example, the
> > "i.MX 95 19mm x 19mm Evaluation Kit" homepage[1] publicly documents an
> > audio board connection through which IMX-AUD-IO card is connected. The
> > detailed user manual (UM12022) is listed as official documentation[2],
> > but it is behind an NXP login, so it is not suitable as a public
> > reference for upstream. Therefore I list it here to illustrate it's
> > mechanism:
> >
> > +-----------------------------+
> > |        Base Board           |
> > |   +-----+      +---------+  |           +---------+
> > |   | SPI +------+         |  |           |         |
> > |   +-----+      |         |  | GPIO MAP  |         |
> > |                |         +--|-----------+         |
> > |   +-----+      |         |  |           |         |
> > |   | I2C +------+         |  |           |         |
> > |   +-----+      |         |  | CLOCK MAP |  AUD-IO |
> > |                |connector+--|-----------+   CARD  |
> > |   +-----+      |         |  |           |         |
> > |   | I2S +------+         |  |           |         |
> > |   +-----+      |         |  |           |         |
> > |                |         |  | INT MAP   |         |
> > |   +-----+      |         +--|-----------+         |
> > |   | I/O +------+         |  |           |         |
> > |   +-----+      +---------+  |           +---------+
> > +-----------------------------+
> >
> > [1]https://www.nxp.com/design/design-center/development-boards-and-
> designs/IMX95LPD5EVK-19
> > [2]https://docs.nxp.com/bundle/UM12022/page/topics/pcie_interface1.html
> 
> Best regards,
> Krzysztof


^ permalink raw reply

* Re: [PATCH 8/8] arm64: dts: qcom: monaco: add AEST error nodes
From: Umang Chheda @ 2026-05-20  5:04 UTC (permalink / raw)
  To: Konrad Dybcio, Ruidong Tian, Tony Luck, Borislav Petkov,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley, Bjorn Andersson,
	Konrad Dybcio, catalin.marinas, will, lpieralisi, rafael,
	mark.rutland, Sudeep Holla
  Cc: linux-arm-msm, linux-acpi, linux-arm-kernel, linux-edac,
	linux-kernel, devicetree, Faruque Ansari
In-Reply-To: <71eee892-1c0b-49e7-a82d-9016c56e8592@oss.qualcomm.com>



On 5/12/2026 4:58 PM, Konrad Dybcio wrote:
> On 5/5/26 2:23 PM, Umang Chheda wrote:
>> Add AEST RAS error source nodes for the Monaco SoC.
>>
>> The DT describes a processor error source covering all CPU cores and a
>> shared L3 cache error source for the cluster. These nodes model the
>> hardware error reporting blocks and associated interrupts as required
>> by the Arm AEST specification.
>>
>> Co-developed-by: Faruque Ansari <faruque.ansari@oss.qualcomm.com>
>> Signed-off-by: Faruque Ansari <faruque.ansari@oss.qualcomm.com>
>> Signed-off-by: Umang Chheda <umang.chheda@oss.qualcomm.com>
>> ---
>>  arch/arm64/boot/dts/qcom/monaco.dtsi | 41 ++++++++++++++++++++++++++++++++++++
>>  1 file changed, 41 insertions(+)
>>
>> diff --git a/arch/arm64/boot/dts/qcom/monaco.dtsi b/arch/arm64/boot/dts/qcom/monaco.dtsi
>> index 7b1d57460f1e..8e43ceed7d84 100644
>> --- a/arch/arm64/boot/dts/qcom/monaco.dtsi
>> +++ b/arch/arm64/boot/dts/qcom/monaco.dtsi
>> @@ -3,6 +3,7 @@
>>   * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
>>   */
>>  
>> +#include <dt-bindings/arm/aest.h>
>>  #include <dt-bindings/clock/qcom,dsi-phy-28nm.h>
>>  #include <dt-bindings/clock/qcom,qcs8300-gcc.h>
>>  #include <dt-bindings/clock/qcom,rpmh.h>
>> @@ -29,6 +30,46 @@ / {
>>  	#address-cells = <2>;
>>  	#size-cells = <2>;
>>  
>> +	aest {
>> +		compatible = "arm,aest";
>> +		#address-cells = <2>;
>> +		#size-cells = <2>;
>> +		ranges;
> 
> These 3 properties aren't necessary if none of the subnodes have a
> 'reg' property
Ack

> 
> Konrad

Thanks,
Umang


^ permalink raw reply

* Re: [PATCH] arm64/mm: Rename ptdesc_t
From: David Hildenbrand (Arm) @ 2026-05-20  5:26 UTC (permalink / raw)
  To: Anshuman Khandual, Will Deacon, Mike Rapoport
  Cc: linux-arm-kernel, Catalin Marinas, linux-efi, linux-kernel
In-Reply-To: <2f60361d-43b9-4f7f-b786-7852d081f4a1@arm.com>

On 5/20/26 04:08, Anshuman Khandual wrote:
> 
> 
> On 19/05/26 4:32 PM, David Hildenbrand (Arm) wrote:
>> On 5/19/26 12:44, Will Deacon wrote:
>>>
>>> Yeah, the 'pxx' prefix really hurts my eyes. Please use something else!
>>
>> Fine with me as long as we don't call it something with "pte" in it.
>>
> 
> Seems like there are two choices here
> 
> (A) pxdval_t
> (B) ptval_t which Mike had suggested earlier
> 
> Unless there is a preference will probably go with pxdval_t

given it is ptdesc_t, ptval_t sounds better to me.

-- 
Cheers,

David


^ permalink raw reply

* Re: [PATCH v2 5/6] gpio: remove machine hogs
From: Dmitry Torokhov @ 2026-05-20  5:27 UTC (permalink / raw)
  To: Bartosz Golaszewski
  Cc: Linus Walleij, Bartosz Golaszewski, Geert Uytterhoeven,
	Frank Rowand, Mika Westerberg, Andy Shevchenko, Aaro Koskinen,
	Janusz Krzysztofik, Tony Lindgren, Russell King, Jonathan Corbet,
	Shuah Khan, linux-gpio, linux-kernel, linux-acpi,
	linux-arm-kernel, linux-omap, linux-doc
In-Reply-To: <ag0Dn66ZVnbTc7J2@google.com>

On Tue, May 19, 2026 at 05:46:50PM -0700, Dmitry Torokhov wrote:
> On Mon, Mar 09, 2026 at 01:42:41PM +0100, Bartosz Golaszewski wrote:
> > With no more users, remove legacy machine hog API from the kernel.
> > 
> > Reviewed-by: Linus Walleij <linusw@kernel.org>
> > Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
> > Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
> 
> Argh! What is the replacement for this? I have patches for rsk7203 to
> use them to get rid of legacy gpio use, like this:
> 
> diff --git a/arch/sh/boards/mach-rsk/devices-rsk7203.c b/arch/sh/boards/mach-rsk/devices-rsk7203.c
> index f8760a91e2f1..5bbd3b31cffb 100644
> --- a/arch/sh/boards/mach-rsk/devices-rsk7203.c
> +++ b/arch/sh/boards/mach-rsk/devices-rsk7203.c
> @@ -12,7 +12,7 @@
>  #include <linux/smsc911x.h>
>  #include <linux/input.h>
>  #include <linux/io.h>
> -#include <linux/gpio.h>
> +#include <linux/gpio/consumer.h>
>  #include <linux/gpio/machine.h>
>  #include <linux/gpio/property.h>
>  #include <asm/machvec.h>
> @@ -165,6 +165,19 @@ static const struct platform_device_info rsk7203_devices[] __initconst = {
>  	},
>  };
>  
> +/* The base of the function GPIOs in the flat enum */
> +#define SH7203_FN_BASE GPIO_FN_PINT7_PB
> +
> +static struct gpiod_hog rsk7203_gpio_hogs[] = {
> +	GPIO_HOG("sh7203_pfc-fn", GPIO_FN_TXD0 - SH7203_FN_BASE,
> +		 "TXD0", GPIO_ACTIVE_HIGH, GPIOD_ASIS),
> +	GPIO_HOG("sh7203_pfc-fn", GPIO_FN_RXD0 - SH7203_FN_BASE,
> +		 "RXD0", GPIO_ACTIVE_HIGH, GPIOD_ASIS),
> +	GPIO_HOG("sh7203_pfc-fn", GPIO_FN_IRQ0_PB - SH7203_FN_BASE,
> +		 "IRQ0_PB", GPIO_ACTIVE_HIGH, GPIOD_ASIS),
> +	{ }
> +};
> +
>  static int __init rsk7203_devices_setup(void)
>  {
>  	struct platform_device *pd;
> @@ -172,12 +185,10 @@ static int __init rsk7203_devices_setup(void)
>  	int i;
>  
>  	/* Select pins for SCIF0 */
> -	gpio_request(GPIO_FN_TXD0, NULL);
> -	gpio_request(GPIO_FN_RXD0, NULL);
> +	gpiod_add_hogs(rsk7203_gpio_hogs);
>  
>  	/* Setup LAN9118: CS1 in 16-bit Big Endian Mode, IRQ0 at Port B */
>  	__raw_writel(0x36db0400, 0xfffc0008); /* CS1BCR */
> -	gpio_request(GPIO_FN_IRQ0_PB, NULL);
>  
>  	error = software_node_register_node_group(rsk7203_swnodes);
>  	if (error) {
> 
> 
> If there is no replacement maybe we can resurrect this? Or shoudl we
> have add swnode support for hogs?

Hmm, I guess it is already there so I should simply switch. Sorry about
the noise.

Thanks.

-- 
Dmitry


^ permalink raw reply

* Re: [PATCH] arm64/mm: Rename ptdesc_t
From: Anshuman Khandual @ 2026-05-20  5:38 UTC (permalink / raw)
  To: David Hildenbrand (Arm), Will Deacon, Mike Rapoport
  Cc: linux-arm-kernel, Catalin Marinas, linux-efi, linux-kernel
In-Reply-To: <66031835-d9f9-4fcf-a720-baba1aaf45a1@kernel.org>



On 20/05/26 10:56 AM, David Hildenbrand (Arm) wrote:
> On 5/20/26 04:08, Anshuman Khandual wrote:
>>
>>
>> On 19/05/26 4:32 PM, David Hildenbrand (Arm) wrote:
>>> On 5/19/26 12:44, Will Deacon wrote:
>>>>
>>>> Yeah, the 'pxx' prefix really hurts my eyes. Please use something else!
>>>
>>> Fine with me as long as we don't call it something with "pte" in it.
>>>
>>
>> Seems like there are two choices here
>>
>> (A) pxdval_t
>> (B) ptval_t which Mike had suggested earlier
>>
>> Unless there is a preference will probably go with pxdval_t
> 
> given it is ptdesc_t, ptval_t sounds better to me.
> 

Sure - ptval_t it is.



^ permalink raw reply

* Re: [PATCH 07/10] clk: amlogic: Support POWER_OF_TWO for PLL pre-divider
From: Jian Hu @ 2026-05-20  5:47 UTC (permalink / raw)
  To: Jerome Brunet, Jian Hu via B4 Relay
  Cc: Michael Turquette, Stephen Boyd, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Neil Armstrong, Xianwei Zhao, Kevin Hilman,
	Martin Blumenstingl, linux-kernel, linux-clk, devicetree,
	linux-amlogic, linux-arm-kernel
In-Reply-To: <1jy0hm6n7e.fsf@starbuckisacylon.baylibre.com>

On 5/14/2026 11:11 PM, Jerome Brunet wrote:
> [ EXTERNAL EMAIL ]
>
> On lun. 11 mai 2026 at 20:47, Jian Hu via B4 Relay <devnull+jian.hu.amlogic.com@kernel.org> wrote:
>
>> From: Jian Hu <jian.hu@amlogic.com>
>>
>> The A9 PLL pre-divider uses a division factor of 2^n to ensure a clock
>> duty cycle of 50% after predivision.
>>
>> Add flag 'CLK_MESON_PLL_N_POWER_OF_TWO' to indicate that the PLL
>> pre-divider division factor is 2^n.
> I understand what you are doing here but I have to ask why this can't be
> implemented with independent dividers that already supports power of 2 ?


If we use independent dividers, the n member would have to be removed 
from meson_clk_pll_data.

However, n is referenced 35 times in clk-pll.c, which means we would 
need to modify all
related logic across the file. This would be a relatively large change.


Moreover, for all Amlogic chips, the n divider is an indispensable part 
of the DCO clock.
The difference between SoC generations is as follows:
     Previous SoCs PLL: n = 1, 2, 3, 4... (linear divider)
     A9 SoC PLL:            n = 2^0, 2^1, 2^2, 2^3, 2^4... (power-of-two 
divider)

Therefore, splitting out the n divider from the DCO clock might not be a 
good design choice.


[...]

Best regards,

Jian




^ permalink raw reply

* Re: [PATCH v2 0/5] mm: reduce mmap_lock contention and improve page fault performance
From: Suren Baghdasaryan @ 2026-05-20  5:51 UTC (permalink / raw)
  To: Lorenzo Stoakes
  Cc: Barry Song, Matthew Wilcox, akpm, linux-mm, david, liam, vbabka,
	rppt, mhocko, jack, pfalcato, wanglian, chentao, lianux.mm,
	kunwu.chan, liyangouwen1, chrisl, kasong, shikemeng, nphamcs, bhe,
	youngjun.park, linux-arm-kernel, linux-kernel, loongarch,
	linuxppc-dev, linux-riscv, linux-s390, Nanzhe Zhao
In-Reply-To: <agxbq1TxJdniMQT3@lucifer>

On Tue, May 19, 2026 at 12:53 PM Lorenzo Stoakes <ljs@kernel.org> wrote:
>
> On Mon, May 18, 2026 at 12:56:59PM -0700, Suren Baghdasaryan wrote:
>
> > >
> > > I think we either need to fix `fork()`, or keep the current
> > > behavior of dropping the VMA lock before performing I/O.
> >
> > I see. So, this problem arises from the fact that we are changing the
> > pagefaults requiring I/O operation to hold VMA lock...
> > And you want to lock VMA on fork only if vma_is_anonymous(vma) ||
> > is_cow_mapping(vma->vm_flags). So, we will be blocking page faults for
> > anonymous and COW VMAs only while holding mmap_write_lock, preventing
> > any VMA modification. On the surface, that looks ok to me but I might
> > be missing some corner cases. If nobody sees any obvious issues, I
> > think it's worth a try.
>
> Not sure if you noticed but I did raise concerns ;)

Sorry, I didn't realize your first comment was a conceptual objection
to this approach of allowing page faults to race with the fork.


>
> I wonder if you've confused the fault path and fork here, as I think Barry has
> been a little unclear on that.
>
> What's being suggested in this thread is to fundamentally change fork behaviour
> so it's different from the entire history of the kernel (or - presumably - at
> least recent history :) and permit concurrent page faults to occur on a forking
> process.
>
> I absolutely object to this for being pretty crazy. I mean I'm not sure we
> really want to be simultaneously modifying page tables while invoking
> copy_page_range()? No?
>
> OK you cover anon and MAP_PRIVATE file-backed but hang on there's
> VM_COPY_ON_FORK too.. so PFN mapped, mixed map and (the accursed) UFFD W/P as
> well as possibly-guard region containing VMAs now can have page tables raced.

Ugh, yeah, I realize now this is a minefield. Resolving all possible
races there would not be trivial and might introduce other performance
issues.

>
> That's not to mention anything else that relies on serialisation here (this
> would be changing how forking has been done in general) that we may or may not
> know about.
>
> The risk level is high, for what amounts to a hack to work around the fault
> issue.
>
> I suggest that if we have a problem with the fault path, let's look at the fault
> path :)
>
> So yeah I'm very opposed to this unless I'm somehow horribly mistaken here or a
> very convincing argument is made.

So, current approach of dropping locks during I/O sounds like still
the best solution.

>
>
> >
> >
> >
> >
> > >
> > > >
> > > > I'd also like to get Suren's input, however.
> > >
> > > Yes. of course.
> > >
> > > >
> > > > Thanks, Lorenzo
> > >
> > > Best Regards
> > > Barry
>
> Cheers, Lorenzo


^ permalink raw reply

* Re: [PATCH 0/8] ras: aest: extend AEST support to Device Tree frontend
From: Ruidong Tian @ 2026-05-20  5:54 UTC (permalink / raw)
  To: Umang Chheda, Tony Luck, Borislav Petkov, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Bjorn Andersson, Konrad Dybcio,
	catalin.marinas, will, lpieralisi, rafael, mark.rutland,
	Sudeep Holla
  Cc: linux-arm-msm, linux-acpi, linux-arm-kernel, linux-edac,
	linux-kernel, devicetree, Faruque Ansari
In-Reply-To: <f95584f8-220f-4bd1-a189-dc05ffd2a9bc@oss.qualcomm.com>



在 2026/5/12 14:45, Umang Chheda 写道:
> Hi Ruidong,
> 
> 
> On 5/6/2026 1:40 PM, Ruidong Tian wrote:
>> Hi Umang,
>>
>> Thanks for your patch.
>>
>> Would it be okay if I include this patch in the next version of the AEST
>> patch series? I will make sure to add your Signed-off-by line.
> 
> 
> Yes, you can include this patch in the next version - we will represent
> it and respond to all of the queries received on DT specific patches.
> 
> How should I be sharing the patch fixes based on comments received from
> maintainers to you ? so that you can include in your patch series ?
> 
> Also, when is your plan to post the next version fixing the comments
> received ?
> 
> 
> Thanks,
> Umang

Hi Umang,

Thanks for your feedback.

I plan to complete the development of the next version within the next 
two weeks. During this period, there may still be some issues or 
questions, and I will bring them up for discussion as they arise.

Once all the comments and related issues are resolved, I will post the 
updated version of the patch series.

Best regards,
Ruidong
> 
> 
>>
>> Best regards,
>> Ruidong
>>
>> 在 2026/5/5 20:23, Umang Chheda 写道:
>>> This series extends Tian Ruidong’s [1] ACPI-based AEST support series
>>> to also cover Device Tree based platforms.
>>>
>>> While the existing AEST driver relies on the AEST ACPI table [3], many
>>> embedded Arm platforms use Device Tree exclusively and cannot use the
>>> driver today. This series adds a DT frontend that mirrors the ACPI
>>> implementation and feeds the same core driver, keeping ACPI and DT
>>> paths functionally equivalent.
>>>
>>> Along the way, several correctness issues were identified in the core
>>> driver and are fixed in the first part of this series.
>>>
>>> The DT frontend is mutually exclusive with ACPI and does not introduce
>>> any DT-specific logic into the core.
>>>
>>> How to test with QEMU
>>> --------------------------
>>> Tian Ruidong's QEMU fork [2] emulates AEST MMIO error records on the
>>> virt machine.  To test the DT frontend:
>>>
>>> 1. Build QEMU:
>>>
>>>        git clone https://github.com/winterddd/qemu.git
>>>        cd qemu
>>>        git checkout c5e2d5dec9fd62ba622314c40bff0fbecb4dfb34
>>>        ./configure --target-list=aarch64-softmmu
>>>        make -j$(nproc)
>>>
>>> 2. Build the kernel with:
>>>
>>>        CONFIG_OF_AEST=y
>>>        CONFIG_AEST=y
>>>        CONFIG_ARM64_RAS_EXTN=y
>>>        CONFIG_RAS=y
>>>
>>> 3. Add the following DT node to your virt machine DTB.  The QEMU
>>>      fork maps DRAM error records at 0x090d0000 (SPI 44) and CMN
>>>      vendor records at 0x090e0000 (SPI 45):
>>>
>>>        aest {
>>>            compatible = "arm,aest";
>>>            #address-cells = <2>;
>>>            #size-cells = <2>;
>>>            ranges;
>>>            interrupt-parent = <&gic>;
>>>
>>>            /* DRAM memory node — MMIO at 0x090d0000, SPI 44 */
>>>            aest-dram0@90d0000 {
>>>                compatible               = "arm,aest-memory";
>>>                arm,interface-type       = <1>;
>>>                arm,group-format         = <0>;
>>>                arm,interface-flags      = <0x22>;
>>>                arm,num-records          = <4>;
>>>                arm,record-impl          = /bits/ 64 <0x0>;
>>>                arm,status-report        = /bits/ 64 <0x0>;
>>>                arm,addr-mode            = /bits/ 64 <0x0>;
>>>                arm,proximity-domain     = <0>;
>>>                reg                      = <0x0 0x090d0000 0x0 0x1000>,
>>>                                           <0x0 0x090d0800 0x0 0x200>,
>>>                                           <0x0 0x090d0e00 0x0 0x100>;
>>>                reg-names                = "errblock", "fault-inject",
>>>                                           "err-group";
>>>                interrupts               = <GIC_SPI 44
>>> IRQ_TYPE_LEVEL_HIGH>;
>>>                interrupt-names          = "fhi";
>>>            };
>>>      };
>>>
>>> 4. Boot QEMU with acpi=off:
>>>
>>>        ./qemu-system-aarch64 \
>>>          -machine virt,accel=tcg,gic-version=3 \
>>>          -cpu cortex-a57 -m 2G -smp 4 \
>>>          -kernel Image -dtb virt-aest.dtb \
>>>          -append "console=ttyAMA0 acpi=off earlycon" \
>>>          -nographic
>>>
>>> 5. Verify probe:
>>>
>>>        dmesg | grep "DT AEST"
>>>        # Expected: DT AEST: registered 1 AEST error source(s) from DT
>>>        ls /sys/kernel/debug/aest/
>>>
>>> 6. Inject a CE error via the QEMU MMIO fault injection registers.
>>>      The QEMU device accepts 64-bit accesses only (use devmem with
>>>      the 64-bit width flag):
>>>
>>>        devmem 0x090d0808 64 0x80000040   # CDOFF | CE inject
>>>
>>>      This triggers QEMU's error_record_inj_write() which sets
>>>      ERR<n>STATUS.V=1 and asserts the IRQ.  The kernel driver's
>>>      aest_irq_func() fires, reads the status, and logs:
>>>
>>>        AEST: {1}[Hardware Error]: Hardware error from AEST memory.90d0000
>>>        AEST: {1}[Hardware Error]: Error from memory at SRAT proximity
>>> domain 0x0
>>>
>>> Testing
>>> -------
>>> - Validated on Qualcomm's lemans-evk and monaco-evk board with DT boot.
>>> - Validated CE and UE injection via debugfs soft_inject.
>>> - Tested ACPI path is unaffected: ACPI boot continues to use
>>>     drivers/acpi/arm64/aest.c unchanged.
>>>
>>> [1] https://lore.kernel.org/lkml/20260122094656.73399-1-
>>> tianruidong@linux.alibaba.com/
>>> [2] https://github.com/winterddd/qemu/tree/error_record
>>> [3] https://developer.arm.com/documentation/den0085/0200/
>>>
>>> Signed-off-by: Umang Chheda <umang.chheda@oss.qualcomm.com>
>>> ---
>>> Umang Chheda (8):
>>>         ras: aest: Fix shared processor node handling and error log
>>> messages
>>>         ras: aest: Fix CE/UE error counts not incrementing in debugfs
>>>         ras: aest: Skip unimplemented records in debugfs
>>>         ras: aest: Add panic_on_ue module parameter
>>>         dt-bindings: arm: ras: Introduce bindings for ARM AEST
>>>         ras: aest: Add DT frontend for ARM AEST RAS error sources
>>>         arm64: dts: qcom: lemans: add AEST error nodes
>>>         arm64: dts: qcom: monaco: add AEST error nodes
>>>
>>>    .../devicetree/bindings/arm/arm,aest.yaml          | 406 +++++++++++++
>>>    arch/arm64/boot/dts/qcom/lemans.dtsi               |  41 ++
>>>    arch/arm64/boot/dts/qcom/monaco.dtsi               |  41 ++
>>>    drivers/ras/aest/Kconfig                           |  15 +-
>>>    drivers/ras/aest/Makefile                          |   2 +
>>>    drivers/ras/aest/aest-core.c                       |  63 +-
>>>    drivers/ras/aest/aest-of.c                         | 673 +++++++++++
>>> ++++++++++
>>>    drivers/ras/aest/aest-sysfs.c                      |  27 +-
>>>    drivers/ras/aest/aest.h                            |  15 +-
>>>    include/dt-bindings/arm/aest.h                     |  43 ++
>>>    10 files changed, 1310 insertions(+), 16 deletions(-)
>>> ---
>>> base-commit: a67b7fd0dd1f6ccf3d128dc2099cdb07af1f6a09
>>> change-id: 20260505-aest-devicetree-support-a3722d90e1f5
>>> prerequisite-message-id: <20260122094656.73399-1-
>>> tianruidong@linux.alibaba.com>
>>> prerequisite-patch-id: c5a7c6431c6c1e6351241e694ee053800039d41d
>>> prerequisite-patch-id: 1f6e2c20829eee41a210dd8a538f1e8efcc65872
>>> prerequisite-patch-id: 5556287e3f46c2ed2c0431c53c7782e87bcbd866
>>> prerequisite-patch-id: 2edae0a136d7779b8f686181720e71d044a73311
>>> prerequisite-patch-id: b5190b2844dcb01e72f87a59f3a29548795fdb82
>>> prerequisite-patch-id: 7ba848583708b2ae776a7ce847bb056e3de7f77b
>>> prerequisite-patch-id: 397e5b22802b67942435f4f2968f0b1e210ba0e8
>>> prerequisite-patch-id: 2169f4b65537eecbd0ccbd2ad6b28c64ec44655d
>>> prerequisite-patch-id: b626f85d98747595b3240bc49e6ad9c9dd5c0fa9
>>> prerequisite-patch-id: 1323dfd2eebad2ef6514dbbce58ba08e8859f894
>>> prerequisite-patch-id: 95b826e5e329408437a3ef336c4f45d4d74f82bb
>>> prerequisite-patch-id: b60ff489a5a33c5d5220fa8144af7b7511769cba
>>> prerequisite-patch-id: 43f35a52b8a3d13c938ff08083403c1d3bd0df8b
>>> prerequisite-patch-id: c55d4e9117ca36d3c2cba82d550a618cb82bb745
>>> prerequisite-patch-id: 3885e10f318ae8101d6909b35d92a976cc359e3c
>>> prerequisite-patch-id: 92958cde05577f069c5659018a274bb39cfb6b24
>>>
>>> Best regards,
>>> -- 
>>> Umang Chheda <umang.chheda@oss.qualcomm.com>
>>>
>>



^ permalink raw reply

* Re: [PATCH] KVM: arm64: vgic-its: reject restored DTE with out-of-range num_eventid_bits
From: Yao Yuan @ 2026-05-20  6:04 UTC (permalink / raw)
  To: Marc Zyngier
  Cc: Michael Bommarito, Oliver Upton, Joey Gouly, Suzuki K Poulose,
	Zenghui Yu, Catalin Marinas, Will Deacon, linux-arm-kernel,
	kvmarm, linux-kernel
In-Reply-To: <8633zpxh1v.wl-maz@kernel.org>

On Mon, May 18, 2026 at 09:23:08AM +0800, Marc Zyngier wrote:
> On Mon, 18 May 2026 07:05:13 +0100,
> Yao Yuan <yaoyuan@linux.alibaba.com> wrote:
> >
> > On Sun, May 17, 2026 at 01:49:55PM +0800, Michael Bommarito wrote:
>
> [...]
>
> > > diff --git a/arch/arm64/kvm/vgic/vgic-its.c b/arch/arm64/kvm/vgic/vgic-its.c
> > > index 2ea9f1c7ebcd0..a5dcf9a6a2854 100644
> > > --- a/arch/arm64/kvm/vgic/vgic-its.c
> > > +++ b/arch/arm64/kvm/vgic/vgic-its.c
> > > @@ -2307,6 +2307,15 @@ static int vgic_its_restore_dte(struct vgic_its *its, u32 id,
> > >  	/* dte entry is valid */
> > >  	offset = (entry & KVM_ITS_DTE_NEXT_MASK) >> KVM_ITS_DTE_NEXT_SHIFT;
> > >
> > > +	/*
> > > +	 * The MAPD command rejects this case; mirror the cap here so a
> > > +	 * restored DTE cannot install an out-of-range num_eventid_bits
> > > +	 * that vgic_its_restore_itt() would then convert into a
> > > +	 * sign-extended scan_its_table() length.
> > > +	 */
> > > +	if (num_eventid_bits > VITS_TYPER_IDBITS)
> > > +		return -EINVAL;
> >
> > Hi,
> >
> > IIUC, the same issue is still there when VITS_TYPER_IDBITS
> > change to >=28, I know it's limited to 16 in GITS_TYPER's
> > definition. I mean the issue is still there w/o really be
> > fixed.
>
> Change how? This is a hard-coded limit that reflect a practical use of
> the ITS (and is already 32 times larger than what PCIe allows).
>
> Are you suggesting a possibility of making this userspace
> configurable?

So far No, may until one day it has more than 16 definition :-)

>
> >
> > Change the scan_its_table() and other related code path to
> > avoid such date conversion issue is more reasonable
> > fixing to me, please also wait others' input yet.
>
> I don't think this is a reasonable course of action. scan_its_table()
> is generic (it doesn't know about any table in particular), and
> assumes that the scan parameters are validated upfront.

Ah I see.

I thought that even w/ chekcing VITS_TYPER_IDBITs, the
size_t -> int -> unsigned long conversion is still there, which is
big -> small -> big, looks odd to me, so I thought it should be fixed yet.
But it can't fix this issue directly.

>
> Thanks,
>
> 	M.
>
> --
> Without deviation from the norm, progress is not possible.


^ permalink raw reply

* Re: [PATCH] arm64/entry: Don't disable preemption in debug_exception_enter() with RT kernel
From: Sebastian Andrzej Siewior @ 2026-05-20  6:19 UTC (permalink / raw)
  To: Waiman Long
  Cc: Catalin Marinas, Will Deacon, Mark Rutland, Clark Williams,
	Steven Rostedt, linux-arm-kernel, linux-kernel, linux-rt-devel
In-Reply-To: <20260519222524.886454-1-longman@redhat.com>

On 2026-05-19 18:25:24 [-0400], Waiman Long wrote:
> Commit d8bb6718c4db ("arm64: Make debug exception handlers visible from
> RCU") introduces debug_exception_enter() and debug_exception_exit()
> where preemption is explicitly disabled. With a PREEMPT_RT debug kernel,
> the following bug report can happen.
…

What kernel is this? I have backport (which is being tested) for v6.6
and v6.12, the patches are from v6.17-rc1.

Sebastian


^ permalink raw reply

* [PATCH V2] arm64/mm: Rename ptdesc_t
From: Anshuman Khandual @ 2026-05-20  6:34 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: Anshuman Khandual, Catalin Marinas, Will Deacon,
	David Hildenbrand, Mike Rapoport, linux-efi, linux-kernel

ptdesc_t sounds very similar to the core MM struct ptdesc which is actually
the memory descriptor for page table allocations. Hence rename this typedef
element as ptval_t instead for better clarity and separation.

Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Will Deacon <will@kernel.org>
Cc: David Hildenbrand <david@kernel.org>
Cc: Mike Rapoport <rppt@kernel.org>
Cc: linux-efi@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
Cc: linux-arm-kernel@lists.infradead.org
Acked-by: Mike Rapoport (Microsoft) <rppt@kernel.org>
Acked-by: David Hildenbrand (Arm) <david@kernel.org>
Suggested-by: David Hildenbrand (Arm) <david@kernel.org>
Signed-off-by: Anshuman Khandual <anshuman.khandual@arm.com>
---
This patch applies on v7.1-rc4.

Changes in V2:

- Renamed pxxval_t as ptval_t per Mike and David

Changes in V1:

https://lore.kernel.org/all/20260430034933.541634-1-anshuman.khandual@arm.com/

 arch/arm64/include/asm/io.h            |  2 +-
 arch/arm64/include/asm/pgtable-types.h | 14 +++++++-------
 arch/arm64/include/asm/ptdump.h        |  8 ++++----
 arch/arm64/include/asm/tlbflush.h      |  4 ++--
 arch/arm64/kernel/efi.c                |  4 ++--
 arch/arm64/kernel/pi/map_kernel.c      |  2 +-
 arch/arm64/kernel/pi/map_range.c       |  4 ++--
 arch/arm64/kernel/pi/pi.h              |  2 +-
 arch/arm64/mm/mmap.c                   |  4 ++--
 arch/arm64/mm/pageattr.c               |  2 +-
 arch/arm64/mm/ptdump.c                 |  2 +-
 11 files changed, 24 insertions(+), 24 deletions(-)

diff --git a/arch/arm64/include/asm/io.h b/arch/arm64/include/asm/io.h
index 8cbd1e96fd50..21c8e400107c 100644
--- a/arch/arm64/include/asm/io.h
+++ b/arch/arm64/include/asm/io.h
@@ -270,7 +270,7 @@ static inline void __iomem *ioremap_prot(phys_addr_t phys, size_t size,
 					 pgprot_t user_prot)
 {
 	pgprot_t prot;
-	ptdesc_t user_prot_val = pgprot_val(user_prot);
+	ptval_t user_prot_val = pgprot_val(user_prot);
 
 	if (WARN_ON_ONCE(!(user_prot_val & PTE_USER)))
 		return NULL;
diff --git a/arch/arm64/include/asm/pgtable-types.h b/arch/arm64/include/asm/pgtable-types.h
index 265e8301d7ba..2f2f5527930f 100644
--- a/arch/arm64/include/asm/pgtable-types.h
+++ b/arch/arm64/include/asm/pgtable-types.h
@@ -17,13 +17,13 @@
  * Generic page table descriptor format from which
  * all level specific descriptors can be derived.
  */
-typedef u64 ptdesc_t;
+typedef u64 ptval_t;
 
-typedef ptdesc_t pteval_t;
-typedef ptdesc_t pmdval_t;
-typedef ptdesc_t pudval_t;
-typedef ptdesc_t p4dval_t;
-typedef ptdesc_t pgdval_t;
+typedef ptval_t pteval_t;
+typedef ptval_t pmdval_t;
+typedef ptval_t pudval_t;
+typedef ptval_t p4dval_t;
+typedef ptval_t pgdval_t;
 
 /*
  * These are used to make use of C type-checking..
@@ -54,7 +54,7 @@ typedef struct { pgdval_t pgd; } pgd_t;
 #define pgd_val(x)	((x).pgd)
 #define __pgd(x)	((pgd_t) { (x) } )
 
-typedef struct { ptdesc_t pgprot; } pgprot_t;
+typedef struct { ptval_t pgprot; } pgprot_t;
 #define pgprot_val(x)	((x).pgprot)
 #define __pgprot(x)	((pgprot_t) { (x) } )
 
diff --git a/arch/arm64/include/asm/ptdump.h b/arch/arm64/include/asm/ptdump.h
index baff24004459..5b374a6ab34a 100644
--- a/arch/arm64/include/asm/ptdump.h
+++ b/arch/arm64/include/asm/ptdump.h
@@ -26,8 +26,8 @@ struct ptdump_info {
 };
 
 struct ptdump_prot_bits {
-	ptdesc_t	mask;
-	ptdesc_t	val;
+	ptval_t	mask;
+	ptval_t	val;
 	const char	*set;
 	const char	*clear;
 };
@@ -36,7 +36,7 @@ struct ptdump_pg_level {
 	const struct ptdump_prot_bits *bits;
 	char name[4];
 	int num;
-	ptdesc_t mask;
+	ptval_t mask;
 };
 
 /*
@@ -53,7 +53,7 @@ struct ptdump_pg_state {
 	const struct mm_struct *mm;
 	unsigned long start_address;
 	int level;
-	ptdesc_t current_prot;
+	ptval_t current_prot;
 	bool check_wx;
 	unsigned long wx_pages;
 	unsigned long uxn_pages;
diff --git a/arch/arm64/include/asm/tlbflush.h b/arch/arm64/include/asm/tlbflush.h
index c0bf5b398041..d52ac8c17190 100644
--- a/arch/arm64/include/asm/tlbflush.h
+++ b/arch/arm64/include/asm/tlbflush.h
@@ -725,9 +725,9 @@ static inline void arch_tlbbatch_add_pending(struct arch_tlbflush_unmap_batch *b
 	sme_dvmsync_add_pending(batch, mm);
 }
 
-static inline bool __pte_flags_need_flush(ptdesc_t oldval, ptdesc_t newval)
+static inline bool __pte_flags_need_flush(ptval_t oldval, ptval_t newval)
 {
-	ptdesc_t diff = oldval ^ newval;
+	ptval_t diff = oldval ^ newval;
 
 	/* invalid to valid transition requires no flush */
 	if (!(oldval & PTE_VALID))
diff --git a/arch/arm64/kernel/efi.c b/arch/arm64/kernel/efi.c
index a81cb4aa4738..30cd7f804398 100644
--- a/arch/arm64/kernel/efi.c
+++ b/arch/arm64/kernel/efi.c
@@ -31,7 +31,7 @@ static bool region_is_misaligned(const efi_memory_desc_t *md)
  * executable, everything else can be mapped with the XN bits
  * set. Also take the new (optional) RO/XP bits into account.
  */
-static __init ptdesc_t create_mapping_protection(efi_memory_desc_t *md)
+static __init ptval_t create_mapping_protection(efi_memory_desc_t *md)
 {
 	u64 attr = md->attribute;
 	u32 type = md->type;
@@ -85,7 +85,7 @@ static __init ptdesc_t create_mapping_protection(efi_memory_desc_t *md)
 
 int __init efi_create_mapping(struct mm_struct *mm, efi_memory_desc_t *md)
 {
-	ptdesc_t prot_val = create_mapping_protection(md);
+	ptval_t prot_val = create_mapping_protection(md);
 	bool page_mappings_only = (md->type == EFI_RUNTIME_SERVICES_CODE ||
 				   md->type == EFI_RUNTIME_SERVICES_DATA);
 
diff --git a/arch/arm64/kernel/pi/map_kernel.c b/arch/arm64/kernel/pi/map_kernel.c
index a852264958c3..fb44cbdd2f29 100644
--- a/arch/arm64/kernel/pi/map_kernel.c
+++ b/arch/arm64/kernel/pi/map_kernel.c
@@ -165,7 +165,7 @@ static void noinline __section(".idmap.text") set_ttbr0_for_lpa2(phys_addr_t ttb
 static void __init remap_idmap_for_lpa2(void)
 {
 	/* clear the bits that change meaning once LPA2 is turned on */
-	ptdesc_t mask = PTE_SHARED;
+	ptval_t mask = PTE_SHARED;
 
 	/*
 	 * We have to clear bits [9:8] in all block or page descriptors in the
diff --git a/arch/arm64/kernel/pi/map_range.c b/arch/arm64/kernel/pi/map_range.c
index de52cd85c691..761b14893f74 100644
--- a/arch/arm64/kernel/pi/map_range.c
+++ b/arch/arm64/kernel/pi/map_range.c
@@ -31,7 +31,7 @@ void __init map_range(phys_addr_t *pte, u64 start, u64 end, phys_addr_t pa,
 		      u64 va_offset)
 {
 	u64 cmask = (level == 3) ? CONT_PTE_SIZE - 1 : U64_MAX;
-	ptdesc_t protval = pgprot_val(prot) & ~PTE_TYPE_MASK;
+	ptval_t protval = pgprot_val(prot) & ~PTE_TYPE_MASK;
 	int lshift = (3 - level) * PTDESC_TABLE_SHIFT;
 	u64 lmask = (PAGE_SIZE << lshift) - 1;
 
@@ -88,7 +88,7 @@ void __init map_range(phys_addr_t *pte, u64 start, u64 end, phys_addr_t pa,
 	}
 }
 
-asmlinkage phys_addr_t __init create_init_idmap(pgd_t *pg_dir, ptdesc_t clrmask)
+asmlinkage phys_addr_t __init create_init_idmap(pgd_t *pg_dir, ptval_t clrmask)
 {
 	phys_addr_t ptep = (phys_addr_t)pg_dir + PAGE_SIZE; /* MMU is off */
 	pgprot_t text_prot = PAGE_KERNEL_ROX;
diff --git a/arch/arm64/kernel/pi/pi.h b/arch/arm64/kernel/pi/pi.h
index aec3172d4003..5dfd8484d200 100644
--- a/arch/arm64/kernel/pi/pi.h
+++ b/arch/arm64/kernel/pi/pi.h
@@ -35,4 +35,4 @@ void map_range(phys_addr_t *pte, u64 start, u64 end, phys_addr_t pa,
 
 asmlinkage void early_map_kernel(u64 boot_status, phys_addr_t fdt);
 
-asmlinkage phys_addr_t create_init_idmap(pgd_t *pgd, ptdesc_t clrmask);
+asmlinkage phys_addr_t create_init_idmap(pgd_t *pgd, ptval_t clrmask);
diff --git a/arch/arm64/mm/mmap.c b/arch/arm64/mm/mmap.c
index 92b2f5097a96..32e0771d6477 100644
--- a/arch/arm64/mm/mmap.c
+++ b/arch/arm64/mm/mmap.c
@@ -34,7 +34,7 @@ static pgprot_t protection_map[16] __ro_after_init = {
 	[VM_SHARED | VM_EXEC | VM_WRITE | VM_READ]	= PAGE_SHARED_EXEC
 };
 
-static ptdesc_t gcs_page_prot __ro_after_init = _PAGE_GCS_RO;
+static ptval_t gcs_page_prot __ro_after_init = _PAGE_GCS_RO;
 
 /*
  * You really shouldn't be using read() or write() on /dev/mem.  This might go
@@ -87,7 +87,7 @@ arch_initcall(adjust_protection_map);
 
 pgprot_t vm_get_page_prot(vm_flags_t vm_flags)
 {
-	ptdesc_t prot;
+	ptval_t prot;
 
 	/* Short circuit GCS to avoid bloating the table. */
 	if (system_supports_gcs() && (vm_flags & VM_SHADOW_STACK)) {
diff --git a/arch/arm64/mm/pageattr.c b/arch/arm64/mm/pageattr.c
index ce035e1b4eaf..bbe98ac9ad8c 100644
--- a/arch/arm64/mm/pageattr.c
+++ b/arch/arm64/mm/pageattr.c
@@ -21,7 +21,7 @@ struct page_change_data {
 	pgprot_t clear_mask;
 };
 
-static ptdesc_t set_pageattr_masks(ptdesc_t val, struct mm_walk *walk)
+static ptval_t set_pageattr_masks(ptval_t val, struct mm_walk *walk)
 {
 	struct page_change_data *masks = walk->private;
 
diff --git a/arch/arm64/mm/ptdump.c b/arch/arm64/mm/ptdump.c
index ab9899ca1e5f..1c20144700d7 100644
--- a/arch/arm64/mm/ptdump.c
+++ b/arch/arm64/mm/ptdump.c
@@ -194,7 +194,7 @@ void note_page(struct ptdump_state *pt_st, unsigned long addr, int level,
 	struct ptdump_pg_state *st = container_of(pt_st, struct ptdump_pg_state, ptdump);
 	struct ptdump_pg_level *pg_level = st->pg_level;
 	static const char units[] = "KMGTPE";
-	ptdesc_t prot = 0;
+	ptval_t prot = 0;
 
 	/* check if the current level has been folded dynamically */
 	if (st->mm && ((level == 1 && mm_p4d_folded(st->mm)) ||
-- 
2.30.2



^ permalink raw reply related

* [PATCH 3/5] iommu/arm-smmu-v3: Add Stream Table Entry display to debugfs
From: Qinxin Xia @ 2026-05-20  6:37 UTC (permalink / raw)
  To: robin.murphy, nicolinc, will, jpb
  Cc: linux-arm-kernel, iommu, xiaqinxin, wangzhou1, prime.zeng,
	fanghao11, jonathan.cameron, wuyifan50, linuxarm, linux-kernel
In-Reply-To: <20260328101706.3448655-1-xiaqinxin@huawei.com>

Add Stream Table Entry (STE) display functionality to debugfs.
This allow inspecting STE contents for each device stream including:
- STE validity and configuration
- Stage 1 and Stage 2 context pointers
- Raw STE data

/sys/kernel/debug/iommu/arm_smmu_v3/smmu0/stream_table/
└── <sid>/
    └─── ste

Signed-off-by: Qinxin Xia <xiaqinxin@huawei.com>
---
 .../arm/arm-smmu-v3/arm-smmu-v3-debugfs.c     | 235 ++++++++++++++++++
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c   |  11 +-
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h   |  17 ++
 3 files changed, 261 insertions(+), 2 deletions(-)

diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-debugfs.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-debugfs.c
index a541476b7427..a5866f34264f 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-debugfs.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-debugfs.c
@@ -7,6 +7,9 @@
  * └── smmu<ioaddr>/
  *     ├── capabilities    # SMMU feature capabilities and configuration
  *     ├── registers       # SMMU Key registers
+ *     ├── stream_table
+ *         ├── <sid>/                                # Stream ID
+ *             ├── ste                               # Stream Table Entry
  *
  * The capabilities file provides detailed information about:
  * - translation stage support (Stage1/Stage2)
@@ -17,6 +20,11 @@
  * - CR0, CR1, CR2 control registers
  * - Command and Event queue pointers
  *
+ * The STE Information Displayed:
+ * - STE validity and configuration
+ * - Stage 1 and Stage 2 context pointers
+ * - Raw STE data
+ *
  * Copyright (C) 2026 HiSilicon Limited.
  * Author: Qinxin Xia <xiaqinxin@huawei.com>
  */
@@ -174,6 +182,231 @@ static const struct file_operations smmu_debugfs_registers_fops = {
 	.release = smmu_debugfs_registers_release,
 };
 
+/**
+ * smmu_debugfs_ste_show() - Dump STE details to seq_file
+ * @seq: seq_file to write to
+ * @unused: unused parameter
+ *
+ * Errors are reported via seq_puts, the function always returns 0
+ */
+static int smmu_debugfs_ste_show(struct seq_file *seq, void *unused)
+{
+	struct ste_context *ctx = seq->private;
+	struct arm_smmu_master *master = ctx->master;
+	struct arm_smmu_device *smmu;
+	struct arm_smmu_ste *ste;
+	u32 sid, cfg;
+	int i;
+
+	if (!master) {
+		seq_puts(seq, "No SMMU master data\n");
+		return 0;
+	}
+
+	smmu = master->smmu;
+	guard(mutex)(&smmu->streams_mutex);
+
+	sid = ctx->sid;
+
+	if (!arm_smmu_sid_in_range(smmu, sid)) {
+		seq_printf(seq, "Invalid Stream ID: %u (max %u)\n",
+			   sid, (1 << smmu->sid_bits) - 1);
+		return 0;
+	}
+
+	ste = arm_smmu_get_step_for_sid(smmu, sid);
+	if (!ste) {
+		seq_printf(seq, "STE not available for SID %u\n", sid);
+		return 0;
+	}
+
+	seq_printf(seq, "STE for Stream ID %u\n", sid);
+	seq_printf(seq, "  Valid: %s\n",
+		   le64_to_cpu(ste->data[0]) & STRTAB_STE_0_V ? "Yes" : "No");
+
+	seq_puts(seq, "  Config: ");
+
+	cfg = FIELD_GET(STRTAB_STE_0_CFG, le64_to_cpu(ste->data[0]));
+
+	switch (cfg) {
+	case STRTAB_STE_0_CFG_BYPASS:
+		seq_puts(seq, "BYPASS\n");
+		break;
+	case STRTAB_STE_0_CFG_S1_TRANS:
+		seq_puts(seq, "only S1_TRANS\n");
+		break;
+	case STRTAB_STE_0_CFG_S2_TRANS:
+		seq_puts(seq, "only S2_TRANS\n");
+		break;
+	case STRTAB_STE_0_CFG_NESTED:
+		seq_puts(seq, "S1+S2_TRANS\n");
+		break;
+	case STRTAB_STE_0_CFG_ABORT:
+		seq_puts(seq, "ABORT\n");
+		break;
+	default:
+		seq_puts(seq, "UNKNOWN\n");
+	}
+
+	if (cfg == STRTAB_STE_0_CFG_S1_TRANS || cfg == STRTAB_STE_0_CFG_NESTED) {
+		seq_printf(seq, "  S1ContextPtr: 0x%016llx\n",
+			   le64_to_cpu(ste->data[0]) & STRTAB_STE_0_S1CTXPTR_MASK);
+	}
+
+	if (cfg == STRTAB_STE_0_CFG_S2_TRANS || cfg == STRTAB_STE_0_CFG_NESTED) {
+		seq_printf(seq, "  S2TTB: 0x%016llx\n",
+			   le64_to_cpu(ste->data[3]) & STRTAB_STE_3_S2TTB_MASK);
+	}
+
+	/* Display raw STE data */
+	seq_puts(seq, "  Raw Data:\n");
+	for (i = 0; i < STRTAB_STE_DWORDS; i++)
+		seq_printf(seq, "    STE[%d]: 0x%016llx\n", i,
+			   le64_to_cpu(ste->data[i]));
+
+	return 0;
+}
+
+static int smmu_debugfs_ste_open(struct inode *inode, struct file *file)
+{
+	struct ste_context *ctx = inode->i_private;
+	int ret;
+
+	if (!ctx || !get_device(ctx->master->dev))
+		return -ENODEV;
+
+	ret = single_open(file, smmu_debugfs_ste_show, ctx);
+	if (ret)
+		put_device(ctx->master->dev);
+
+	return ret;
+}
+
+static int smmu_debugfs_ste_release(struct inode *inode, struct file *file)
+{
+	struct seq_file *seq = file->private_data;
+	struct ste_context *ctx = seq->private;
+
+	single_release(inode, file);
+	if (ctx)
+		put_device(ctx->master->dev);
+	return 0;
+}
+
+static const struct file_operations smmu_debugfs_ste_fops = {
+	.owner   = THIS_MODULE,
+	.open    = smmu_debugfs_ste_open,
+	.read    = seq_read,
+	.llseek  = seq_lseek,
+	.release = smmu_debugfs_ste_release,
+};
+
+/**
+ * arm_smmu_debugfs_create_stream_table() - Create debugfs entries for stream table
+ * @smmu: SMMU device
+ * @dev: device to create entries for
+ *
+ * Return: 0 on success, negative error code on failure
+ */
+int arm_smmu_debugfs_create_stream_table(struct arm_smmu_device *smmu,
+					 struct device *dev)
+{
+	struct dentry *stream_dir, *dev_dir;
+	struct arm_smmu_master *master;
+	struct ste_context *ctx;
+	char name[64];
+	u32 sid;
+	int i;
+
+	if (!smmu->debugfs)
+		return -ENODEV;
+
+	scoped_guard(mutex, &arm_smmu_debugfs_lock) {
+		if (!smmu->debugfs->stream_dir) {
+			stream_dir = debugfs_create_dir("stream_table",
+							smmu->debugfs->smmu_dir);
+			if (IS_ERR(stream_dir))
+				return PTR_ERR(stream_dir);
+
+			smmu->debugfs->stream_dir = stream_dir;
+		} else {
+			stream_dir = smmu->debugfs->stream_dir;
+		}
+	}
+
+	master = dev_iommu_priv_get(dev);
+	if (!master || !master->num_streams)
+		return -ENODEV;
+
+	for (i = 0; i < master->num_streams; i++) {
+		sid = master->streams[i].id;
+		snprintf(name, sizeof(name), "%u", sid);
+		dev_dir = debugfs_create_dir(name, stream_dir);
+		if (IS_ERR(dev_dir))
+			continue;
+
+		/* Create STE file */
+		ctx = kzalloc_obj(*ctx);
+		if (!ctx)
+			continue;
+
+		ctx->master = master;
+		ctx->sid = sid;
+		spin_lock(&smmu->debugfs->stream_lock);
+		list_add_tail(&ctx->node, &smmu->debugfs->stream_list);
+		spin_unlock(&smmu->debugfs->stream_lock);
+		debugfs_create_file("ste", 0444, dev_dir, ctx,
+				    &smmu_debugfs_ste_fops);
+	}
+
+	return 0;
+}
+
+/**
+ * arm_smmu_debugfs_remove_stream_table() - Remove debugfs entries for stream table
+ * @smmu: SMMU device
+ * @dev: device to remove entries for
+ *
+ * This function removes the debugfs directories created by
+ * arm_smmu_debugfs_create_stream_table().
+ */
+void arm_smmu_debugfs_remove_stream_table(struct arm_smmu_device *smmu,
+					  struct device *dev)
+{
+	struct dentry *stream_dir, *dev_dir;
+	struct arm_smmu_master *master;
+	struct ste_context *ctx, *tmp;
+	char name[64];
+	int i;
+
+	/* Check if stream_table directory exists */
+	if (!smmu->debugfs || !smmu->debugfs->stream_dir)
+		return;
+
+	stream_dir = smmu->debugfs->stream_dir;
+	master = dev_iommu_priv_get(dev);
+	if (!master)
+		return;
+
+	/* Remove directories for each stream ID */
+	for (i = 0; i < master->num_streams; i++) {
+		snprintf(name, sizeof(name), "%u", master->streams[i].id);
+		dev_dir = debugfs_lookup(name, stream_dir);
+		debugfs_remove_recursive(dev_dir);
+		dput(dev_dir);
+	}
+
+	/* Free stream context */
+	spin_lock(&smmu->debugfs->stream_lock);
+	list_for_each_entry_safe(ctx, tmp, &smmu->debugfs->stream_list, node) {
+		if (ctx->master->dev == dev) {
+			list_del(&ctx->node);
+			kfree(ctx);
+		}
+	}
+	spin_unlock(&smmu->debugfs->stream_lock);
+}
+
 /**
  * arm_smmu_debugfs_setup() - Initialize debugfs for SMMU device
  * @smmu: SMMU device to setup debugfs for
@@ -215,6 +448,8 @@ int arm_smmu_debugfs_setup(struct arm_smmu_device *smmu, const char *name)
 	}
 
 	debugfs->smmu_dir = smmu_dir;
+	INIT_LIST_HEAD(&debugfs->stream_list);
+	spin_lock_init(&debugfs->stream_lock);
 	smmu->debugfs = debugfs;
 
 	/* Create capabilities file */
diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
index 929b8ead95b0..ca0fa043c2ce 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
@@ -2992,7 +2992,7 @@ static int arm_smmu_domain_finalise(struct arm_smmu_domain *smmu_domain,
 	return 0;
 }
 
-static struct arm_smmu_ste *
+struct arm_smmu_ste *
 arm_smmu_get_step_for_sid(struct arm_smmu_device *smmu, u32 sid)
 {
 	struct arm_smmu_strtab_cfg *cfg = &smmu->strtab_cfg;
@@ -4090,7 +4090,7 @@ struct arm_smmu_device *arm_smmu_get_by_fwnode(struct fwnode_handle *fwnode)
 	return dev ? dev_get_drvdata(dev) : NULL;
 }
 
-static bool arm_smmu_sid_in_range(struct arm_smmu_device *smmu, u32 sid)
+bool arm_smmu_sid_in_range(struct arm_smmu_device *smmu, u32 sid)
 {
 	if (smmu->features & ARM_SMMU_FEAT_2_LVL_STRTAB)
 		return arm_smmu_strtab_l1_idx(sid) < smmu->strtab_cfg.l2.num_l1_ents;
@@ -4269,6 +4269,10 @@ static struct iommu_device *arm_smmu_probe_device(struct device *dev)
 		pci_prepare_ats(to_pci_dev(dev), stu);
 	}
 
+#ifdef CONFIG_ARM_SMMU_V3_DEBUGFS
+	arm_smmu_debugfs_create_stream_table(smmu, dev);
+#endif
+
 	return &smmu->iommu;
 
 err_free_master:
@@ -4282,6 +4286,9 @@ static void arm_smmu_release_device(struct device *dev)
 
 	WARN_ON(master->iopf_refcount);
 
+#ifdef CONFIG_ARM_SMMU_V3_DEBUGFS
+	arm_smmu_debugfs_remove_stream_table(master->smmu, dev);
+#endif
 	arm_smmu_disable_pasid(master);
 	arm_smmu_remove_master(master);
 	if (arm_smmu_cdtab_allocated(&master->cd_table))
diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
index 8e1c19b6831c..9c9be63dc9e2 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
@@ -821,12 +821,29 @@ struct arm_smmu_impl_ops {
 };
 
 #ifdef CONFIG_ARM_SMMU_V3_DEBUGFS
+struct ste_context {
+	struct arm_smmu_master		*master;
+	u32				sid;
+	struct list_head		node;
+};
+
 struct arm_smmu_debugfs {
+	struct list_head stream_list;
+	spinlock_t stream_lock;
 	struct dentry *smmu_dir;
+	struct dentry *stream_dir;
 };
 
 int arm_smmu_debugfs_setup(struct arm_smmu_device *smmu, const char *name);
 void arm_smmu_debugfs_remove(struct arm_smmu_device *smmu);
+int arm_smmu_debugfs_create_stream_table(struct arm_smmu_device *smmu,
+					 struct device *dev);
+void arm_smmu_debugfs_remove_stream_table(struct arm_smmu_device *smmu,
+					  struct device *dev);
+
+struct arm_smmu_ste *
+arm_smmu_get_step_for_sid(struct arm_smmu_device *smmu, u32 sid);
+bool arm_smmu_sid_in_range(struct arm_smmu_device *smmu, u32 sid);
 #endif
 
 /* An SMMUv3 instance */
-- 
2.33.0



^ permalink raw reply related

* [PATCH 4/5] iommu/arm-smmu-v3: Add device symlink in stream table debugfs
From: Qinxin Xia @ 2026-05-20  6:37 UTC (permalink / raw)
  To: robin.murphy, nicolinc, will, jpb
  Cc: linux-arm-kernel, iommu, xiaqinxin, wangzhou1, prime.zeng,
	fanghao11, jonathan.cameron, wuyifan50, linuxarm, linux-kernel
In-Reply-To: <20260328101706.3448655-1-xiaqinxin@huawei.com>

Add a symlink named  under each stream table entry directory pointing to
the sysfs directory of the actual device. This aids debugging
by providing direct access to device attributes.

/sys/kernel/debug/iommu/arm_smmu_v3/smmu0/stream_table/
└── <sid>/
    ├─── ste
    └─── <dev_name>

Signed-off-by: Qinxin Xia <xiaqinxin@huawei.com>
---
 .../iommu/arm/arm-smmu-v3/arm-smmu-v3-debugfs.c | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)

diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-debugfs.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-debugfs.c
index a5866f34264f..9babc7d640fd 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-debugfs.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-debugfs.c
@@ -10,6 +10,7 @@
  *     ├── stream_table
  *         ├── <sid>/                                # Stream ID
  *             ├── ste                               # Stream Table Entry
+ *             ├── <dev_name>                         # Symlink to device sysfs directory
  *
  * The capabilities file provides detailed information about:
  * - translation stage support (Stage1/Stage2)
@@ -31,6 +32,7 @@
 
 #include <linux/cleanup.h>
 #include <linux/debugfs.h>
+#include <linux/kobject.h>
 #include <linux/slab.h>
 #include "arm-smmu-v3.h"
 
@@ -314,6 +316,7 @@ int arm_smmu_debugfs_create_stream_table(struct arm_smmu_device *smmu,
 	struct dentry *stream_dir, *dev_dir;
 	struct arm_smmu_master *master;
 	struct ste_context *ctx;
+	char *path = NULL, *full_path;
 	char name[64];
 	u32 sid;
 	int i;
@@ -338,6 +341,9 @@ int arm_smmu_debugfs_create_stream_table(struct arm_smmu_device *smmu,
 	if (!master || !master->num_streams)
 		return -ENODEV;
 
+	/* Get device sysfs path once, reuse for all streams */
+	path = kobject_get_path(&dev->kobj, GFP_KERNEL);
+
 	for (i = 0; i < master->num_streams; i++) {
 		sid = master->streams[i].id;
 		snprintf(name, sizeof(name), "%u", sid);
@@ -357,8 +363,19 @@ int arm_smmu_debugfs_create_stream_table(struct arm_smmu_device *smmu,
 		spin_unlock(&smmu->debugfs->stream_lock);
 		debugfs_create_file("ste", 0444, dev_dir, ctx,
 				    &smmu_debugfs_ste_fops);
+
+		/* Create a symlink to the device's sysfs directory */
+		if (path) {
+			full_path = kasprintf(GFP_KERNEL, "/sys%s", path);
+			if (full_path) {
+				debugfs_create_symlink(dev_name(dev), dev_dir,
+						       full_path);
+				kfree(full_path);
+			}
+		}
 	}
 
+	kfree(path);
 	return 0;
 }
 
-- 
2.33.0



^ permalink raw reply related

* [PATCH 0/5] Add debugfs support for ARM SMMUv3
From: Qinxin Xia @ 2026-05-20  6:37 UTC (permalink / raw)
  To: robin.murphy, nicolinc, will, jpb
  Cc: linux-arm-kernel, iommu, xiaqinxin, wangzhou1, prime.zeng,
	fanghao11, jonathan.cameron, wuyifan50, linuxarm, linux-kernel

Add a comprehensive debugfs framework to the ARM SMMUv3 driver,
providing visibility into internal hardware state for debugging
and performance analysis. The debugfs entries are organized under
/sys/kernel/debug/iommu/arm_smmu_v3/, with per-SMMU instance directories
and per-device stream table entries.

Each SMMU instance provides:
- capabilities – static SMMU features and queue sizes.
- registers – SMMU key registers.
- stream_table/ – a directory per device with subdirectories per Stream ID.

Each Stream ID subdirectory contains:
- ste – the Stream Table Entry in decoded and raw format.
- cd – all valid Context Descriptors (Stage 1 translation tables) associated with the device.
- a symlink named with the device's BDF/name pointing to its sysfs directory for easy navigation.

/sys/kernel/debug/iommu/arm_smmu_v3/smmu0/stream_table/
    ├── <sid>/
    │   ├── ste
    │   ├── cd
    │   └── <dev_name>

Changes since RFCv2:
  Address review comments from Nicolin Chen, kernel test robot, and Sashiko
  automated review:

  Build & kerneldoc fixes (patches 1-3):
   - Add missing @unused parameter description to kerneldoc comments to fix
     clang W=1 warnings reported by kernel test robot.
   - Fix commit message: "driver.This" -> "driver. This" (patch 1).

  Correctness fixes:
   - Fix integer overflow: 1 << sid_bits -> 1ULL << sid_bits with %llu format,
     preventing undefined behavior when SIDSIZE = 32 (patch 1).
   - Fix EVTQ register access: use smmu->page1 instead of smmu->base for
     EVTQ_PROD/EVTQ_CONS, which reside in register page 1 (patch 2).
   - Fix STE config bit test: use proper cfg comparison instead of bitwise AND
     on non-mask enumeration values, and extract S1ContextPtr from data[0]
     instead of data[1] (patch 3).

  Resource leak fixes (patches 1-5):
   - Fix device reference leak: call put_device() when single_open() fails in
     all open() callbacks (capabilities, registers, ste, cd).
   - Fix dentry reference leak: add missing dput() after debugfs_lookup() in
     stream table remove path (patch 3).
   - Move kobject_get_path() outside the per-stream loop to avoid repeated
     allocation (patch 4).

  Locking & concurrency fixes:
   - arm_smmu_debugfs_remove(): use scoped_guard() and move
     debugfs_remove_recursive() outside the lock to avoid blocking other SMMU
     instances on active VFS operations (patch 1).
   - smmu_debugfs_ste_show(): change scoped_guard to guard(mutex) since the
     entire function body is within the lock scope (patch 3).
   - smmu_debugfs_cd_show(): change manual mutex_lock/unlock to
     guard(mutex)(&arm_smmu_asid_lock) (patch 5).

  Error handling fixes:
   - Replace if (!debugfs_create_dir(...)) with IS_ERR() checks throughout,
     since debugfs_create_dir() returns ERR_PTR on failure, not NULL
     (patches 1, 3).
   - Add NULL check for smmu->debugfs before dereference in stream table
     create path (patch 3).
   - Add NULL check for kzalloc_obj() result (patch 3).

  Code style & cleanup:
   - Directory tree comment: use ├── for last entry to avoid churn on
     subsequent patches (patches 1-5).
   - Fix tab/space alignment in directory tree comments (patches 1, 2).
   - Reorder function parameters: @smmu first, @dev second (patch 3).
   - Fix return statement indentation (patch 3).
   - Move function declarations from #ifndef-static pattern to header file
     (patch 3).
   - Move char name[32] and snprintf() to function top for reuse by
     iommu_device_sysfs_add() regardless of CONFIG_ARM_SMMU_V3_DEBUGFS
     (patch 1).
   - Adopt non-tab-aligned style for new struct members (patches 1, 3).
   - Remove useless comments: "DebugFS Info" and "Reserved for future
     extensions" (patches 1, 3).
   - Remove spurious blank line (patch 3).

- Link: https://lore.kernel.org/all/20260328101706.3448655-1-xiaqinxin@huawei.com/

Qinxin Xia (5):
  iommu/arm-smmu-v3: Add basic debugfs framework
  iommu/arm-smmu-v3: Add register display to debugfs
  iommu/arm-smmu-v3: Add Stream Table Entry display to debugfs
  iommu/arm-smmu-v3: Add device symlink in stream table debugfs
  iommu/arm-smmu-v3: Add Context Descriptor display to debugfs

 drivers/iommu/Kconfig                              |  11 +
 drivers/iommu/arm/arm-smmu-v3/Makefile             |   1 +
 .../iommu/arm/arm-smmu-v3/arm-smmu-v3-debugfs.c    | 609 +++++++++++++++++++++
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c        |  27 +-
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h        |  30 +
 5 files changed, 675 insertions(+), 3 deletions(-)
 create mode 100644 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-debugfs.c

--
2.51.0


^ permalink raw reply

* [PATCH 1/5] iommu/arm-smmu-v3: Add basic debugfs framework
From: Qinxin Xia @ 2026-05-20  6:37 UTC (permalink / raw)
  To: robin.murphy, nicolinc, will, jpb
  Cc: linux-arm-kernel, iommu, xiaqinxin, wangzhou1, prime.zeng,
	fanghao11, jonathan.cameron, wuyifan50, linuxarm, linux-kernel
In-Reply-To: <20260328101706.3448655-1-xiaqinxin@huawei.com>

Add basic debugfs framework for ARM SMMUv3 driver. This creates the
root directory structure and provides capability display functionality.

The debugfs hierarchy is organized as:
/sys/kernel/debug/iommu/arm_smmu_v3/
└── smmu<ioaddr>/
    └── capabilities

Signed-off-by: Qinxin Xia <xiaqinxin@huawei.com>
---
 drivers/iommu/Kconfig                         |  11 ++
 drivers/iommu/arm/arm-smmu-v3/Makefile        |   1 +
 .../arm/arm-smmu-v3/arm-smmu-v3-debugfs.c     | 172 ++++++++++++++++++
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c   |  16 +-
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h   |  13 ++
 5 files changed, 212 insertions(+), 1 deletion(-)
 create mode 100644 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-debugfs.c

diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig
index f86262b11416..f28f09adba03 100644
--- a/drivers/iommu/Kconfig
+++ b/drivers/iommu/Kconfig
@@ -93,6 +93,17 @@ config IOMMU_DEBUGFS
 	  debug/iommu directory, and then populate a subdirectory with
 	  entries as required.
 
+config ARM_SMMU_V3_DEBUGFS
+	bool "ARM SMMUv3 DebugFS support"
+	depends on ARM_SMMU_V3 && IOMMU_DEBUGFS
+	help
+	  Expose ARM SMMUv3 internal state via debugfs for debugging and
+	  diagnostics. This creates /sys/kernel/debug/iommu/arm_smmu_v3/
+	  with detailed information about SMMU configuration, stream tables,
+	  and context descriptors.
+
+	  Say N unless you are debugging SMMU issues.
+
 choice
 	prompt "IOMMU default domain type"
 	depends on IOMMU_API
diff --git a/drivers/iommu/arm/arm-smmu-v3/Makefile b/drivers/iommu/arm/arm-smmu-v3/Makefile
index 493a659cc66b..787538fb7054 100644
--- a/drivers/iommu/arm/arm-smmu-v3/Makefile
+++ b/drivers/iommu/arm/arm-smmu-v3/Makefile
@@ -4,5 +4,6 @@ arm_smmu_v3-y := arm-smmu-v3.o
 arm_smmu_v3-$(CONFIG_ARM_SMMU_V3_IOMMUFD) += arm-smmu-v3-iommufd.o
 arm_smmu_v3-$(CONFIG_ARM_SMMU_V3_SVA) += arm-smmu-v3-sva.o
 arm_smmu_v3-$(CONFIG_TEGRA241_CMDQV) += tegra241-cmdqv.o
+arm_smmu_v3-$(CONFIG_ARM_SMMU_V3_DEBUGFS) += arm-smmu-v3-debugfs.o
 
 obj-$(CONFIG_ARM_SMMU_V3_KUNIT_TEST) += arm-smmu-v3-test.o
diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-debugfs.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-debugfs.c
new file mode 100644
index 000000000000..1fc2cd1651b4
--- /dev/null
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-debugfs.c
@@ -0,0 +1,172 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * ARM SMMUv3 DebugFS Support
+ *
+ * Directory Structure:
+ * /sys/kernel/debug/iommu/arm_smmu_v3/
+ * └── smmu<ioaddr>/
+ *     ├── capabilities    # SMMU feature capabilities and configuration
+ *
+ * The capabilities file provides detailed information about:
+ * - translation stage support (Stage1/Stage2)
+ * - System coherency, ATS, and PRI feature availability
+ * - Stream table size and command/event queue depths
+ *
+ * Copyright (C) 2026 HiSilicon Limited.
+ * Author: Qinxin Xia <xiaqinxin@huawei.com>
+ */
+
+#include <linux/cleanup.h>
+#include <linux/debugfs.h>
+#include <linux/slab.h>
+#include "arm-smmu-v3.h"
+
+static struct dentry *smmu_debugfs_root;
+static DEFINE_MUTEX(arm_smmu_debugfs_lock);
+
+/**
+ * smmu_debugfs_capabilities_show() - Display SMMU capabilities
+ * @seq: seq_file to write to
+ * @unused: unused parameter
+ *
+ * Errors are reported via seq_puts, the function always returns 0
+ */
+static int smmu_debugfs_capabilities_show(struct seq_file *seq, void *unused)
+{
+	struct arm_smmu_device *smmu = seq->private;
+
+	if (!smmu) {
+		seq_puts(seq, "SMMU not available\n");
+		return 0;
+	}
+
+	seq_puts(seq, "SMMUv3 Capabilities:\n");
+	seq_printf(seq, "  Stage1 Translation: %s\n",
+		   smmu->features & ARM_SMMU_FEAT_TRANS_S1 ? "Yes" : "No");
+	seq_printf(seq, "  Stage2 Translation: %s\n",
+		   smmu->features & ARM_SMMU_FEAT_TRANS_S2 ? "Yes" : "No");
+	seq_printf(seq, "  Coherent Walk: %s\n",
+		   smmu->features & ARM_SMMU_FEAT_COHERENCY ? "Yes" : "No");
+	seq_printf(seq, "  ATS Support: %s\n",
+		   smmu->features & ARM_SMMU_FEAT_ATS ? "Yes" : "No");
+	seq_printf(seq, "  PRI Support: %s\n",
+		   smmu->features & ARM_SMMU_FEAT_PRI ? "Yes" : "No");
+	seq_printf(seq, "  Stream Table Size: %llu\n", 1ULL << smmu->sid_bits);
+	seq_printf(seq, "  Command Queue Depth: %d\n",
+		   1 << smmu->cmdq.q.llq.max_n_shift);
+	seq_printf(seq, "  Event Queue Depth: %d\n",
+		   1 << smmu->evtq.q.llq.max_n_shift);
+
+	return 0;
+}
+
+static int smmu_debugfs_capabilities_open(struct inode *inode, struct file *file)
+{
+	struct arm_smmu_device *smmu = inode->i_private;
+	int ret;
+
+	if (!smmu || !get_device(smmu->dev))
+		return -ENODEV;
+
+	ret = single_open(file, smmu_debugfs_capabilities_show, smmu);
+	if (ret)
+		put_device(smmu->dev);
+
+	return ret;
+}
+
+static int smmu_debugfs_capabilities_release(struct inode *inode, struct file *file)
+{
+	struct seq_file *seq = file->private_data;
+	struct arm_smmu_device *smmu = seq->private;
+
+	single_release(inode, file);
+	if (smmu)
+		put_device(smmu->dev);
+
+	return 0;
+}
+
+static const struct file_operations smmu_debugfs_capabilities_fops = {
+	.owner   = THIS_MODULE,
+	.open    = smmu_debugfs_capabilities_open,
+	.read    = seq_read,
+	.llseek  = seq_lseek,
+	.release = smmu_debugfs_capabilities_release,
+};
+
+/**
+ * arm_smmu_debugfs_setup() - Initialize debugfs for SMMU device
+ * @smmu: SMMU device to setup debugfs for
+ * @name: SMMU device name
+ *
+ * This function creates the basic debugfs directory structure for an SMMU device.
+ *
+ * Return: 0 on success, negative error code on failure
+ */
+int arm_smmu_debugfs_setup(struct arm_smmu_device *smmu, const char *name)
+{
+	struct arm_smmu_debugfs *debugfs;
+	struct dentry *smmu_dir;
+
+	/* Create root directory if it doesn't exist */
+	scoped_guard(mutex, &arm_smmu_debugfs_lock) {
+		if (!smmu_debugfs_root) {
+			/* Once created, it will not be removed */
+			smmu_debugfs_root = debugfs_create_dir("arm_smmu_v3",
+							       iommu_debugfs_dir);
+			if (IS_ERR(smmu_debugfs_root)) {
+				smmu_debugfs_root = NULL;
+				return -ENOMEM;
+			}
+		}
+	}
+
+	/* Allocate debugfs structure */
+	debugfs = kzalloc_obj(*debugfs);
+	if (!debugfs)
+		return -ENOMEM;
+
+	/* Create SMMU instance directory */
+	smmu_dir = debugfs_create_dir(name, smmu_debugfs_root);
+	if (IS_ERR(smmu_dir)) {
+		kfree(debugfs);
+		smmu->debugfs = NULL;
+		return PTR_ERR(smmu_dir);
+	}
+
+	debugfs->smmu_dir = smmu_dir;
+	smmu->debugfs = debugfs;
+
+	/* Create capabilities file */
+	debugfs_create_file("capabilities", 0444, smmu_dir, smmu,
+			    &smmu_debugfs_capabilities_fops);
+
+	dev_dbg(smmu->dev, "debugfs initialized for %s\n", name);
+	return 0;
+}
+
+/**
+ * arm_smmu_debugfs_remove() - Clean up debugfs entries for an SMMU device
+ * @smmu: SMMU device
+ *
+ * This function removes the debugfs directories created by setup.
+ */
+void arm_smmu_debugfs_remove(struct arm_smmu_device *smmu)
+{
+	struct arm_smmu_debugfs *debugfs;
+	struct dentry *smmu_dir;
+
+	scoped_guard(mutex, &arm_smmu_debugfs_lock) {
+		debugfs = smmu->debugfs;
+		if (!debugfs)
+			return;
+
+		smmu_dir = debugfs->smmu_dir;
+		kfree(debugfs);
+		smmu->debugfs = NULL;
+	}
+
+	/* Remove outside lock to avoid blocking on active VFS operations */
+	debugfs_remove_recursive(smmu_dir);
+}
diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
index e8d7dbe495f0..929b8ead95b0 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
@@ -5469,6 +5469,7 @@ static int arm_smmu_device_probe(struct platform_device *pdev)
 	resource_size_t ioaddr;
 	struct arm_smmu_device *smmu;
 	struct device *dev = &pdev->dev;
+	char name[32];
 
 	smmu = devm_kzalloc(dev, sizeof(*smmu), GFP_KERNEL);
 	if (!smmu)
@@ -5496,6 +5497,7 @@ static int arm_smmu_device_probe(struct platform_device *pdev)
 		return -EINVAL;
 	}
 	ioaddr = res->start;
+	snprintf(name, sizeof(name), "smmu3.%pa", &ioaddr);
 
 	/*
 	 * Don't map the IMPLEMENTATION DEFINED regions, since they may contain
@@ -5548,6 +5550,12 @@ static int arm_smmu_device_probe(struct platform_device *pdev)
 	/* Check for RMRs and install bypass STEs if any */
 	arm_smmu_rmr_install_bypass_ste(smmu);
 
+#ifdef CONFIG_ARM_SMMU_V3_DEBUGFS
+	ret = arm_smmu_debugfs_setup(smmu, name);
+	if (ret)
+		dev_warn(dev, "Failed to create debugfs!\n");
+#endif
+
 	/* Reset the device */
 	ret = arm_smmu_device_reset(smmu);
 	if (ret)
@@ -5555,7 +5563,7 @@ static int arm_smmu_device_probe(struct platform_device *pdev)
 
 	/* And we're up. Go go go! */
 	ret = iommu_device_sysfs_add(&smmu->iommu, dev, NULL,
-				     "smmu3.%pa", &ioaddr);
+				     "%s", name);
 	if (ret)
 		goto err_disable;
 
@@ -5570,6 +5578,9 @@ static int arm_smmu_device_probe(struct platform_device *pdev)
 err_free_sysfs:
 	iommu_device_sysfs_remove(&smmu->iommu);
 err_disable:
+#ifdef CONFIG_ARM_SMMU_V3_DEBUGFS
+	arm_smmu_debugfs_remove(smmu);
+#endif
 	arm_smmu_device_disable(smmu);
 err_free_iopf:
 	iopf_queue_free(smmu->evtq.iopf);
@@ -5582,6 +5593,9 @@ static void arm_smmu_device_remove(struct platform_device *pdev)
 
 	iommu_device_unregister(&smmu->iommu);
 	iommu_device_sysfs_remove(&smmu->iommu);
+#ifdef CONFIG_ARM_SMMU_V3_DEBUGFS
+	arm_smmu_debugfs_remove(smmu);
+#endif
 	arm_smmu_device_disable(smmu);
 	iopf_queue_free(smmu->evtq.iopf);
 	ida_destroy(&smmu->vmid_map);
diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
index ef42df4753ec..8e1c19b6831c 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
@@ -820,6 +820,15 @@ struct arm_smmu_impl_ops {
 			  const struct iommu_user_data *user_data);
 };
 
+#ifdef CONFIG_ARM_SMMU_V3_DEBUGFS
+struct arm_smmu_debugfs {
+	struct dentry *smmu_dir;
+};
+
+int arm_smmu_debugfs_setup(struct arm_smmu_device *smmu, const char *name);
+void arm_smmu_debugfs_remove(struct arm_smmu_device *smmu);
+#endif
+
 /* An SMMUv3 instance */
 struct arm_smmu_device {
 	struct device			*dev;
@@ -890,6 +899,10 @@ struct arm_smmu_device {
 
 	struct rb_root			streams;
 	struct mutex			streams_mutex;
+
+#ifdef CONFIG_ARM_SMMU_V3_DEBUGFS
+	struct arm_smmu_debugfs		*debugfs;
+#endif
 };
 
 struct arm_smmu_stream {
-- 
2.33.0



^ permalink raw reply related

* Re: [PATCH v4 00/24] iommu/arm-smmu-v3: Quarantine device upon ATC invalidation timeout
From: Nicolin Chen @ 2026-05-20  6:38 UTC (permalink / raw)
  To: Tian, Kevin
  Cc: Will Deacon, Robin Murphy, Joerg Roedel, Bjorn Helgaas,
	Jason Gunthorpe, Rafael J . Wysocki, Len Brown,
	Pranjal Shrivastava, Mostafa Saleh, Lu Baolu,
	linux-arm-kernel@lists.infradead.org, iommu@lists.linux.dev,
	linux-kernel@vger.kernel.org, linux-acpi@vger.kernel.org,
	linux-pci@vger.kernel.org, Vikram Sethi, Shuai Xue
In-Reply-To: <BN9PR11MB52761E126A213C6CD2CF77D68C012@BN9PR11MB5276.namprd11.prod.outlook.com>

On Wed, May 20, 2026 at 03:59:43AM +0000, Tian, Kevin wrote:
> > From: Nicolin Chen <nicolinc@nvidia.com>
> > Sent: Tuesday, May 19, 2026 11:39 AM
> >
> > Changelog
> > v4:
> >  * Rebase on Joerg's IOMMU "fixes" branch
> >  * Rebase on Jason's SMMUv3 cmd_ent series
> >    https://lore.kernel.org/all/0-v2-47b2bf710ad5+716ac-
> > smmu_no_cmdq_ent_jgg@nvidia.com/
> >  * [PCI] Don't suspend IOMMU in probe mode
> >  * [iommu] kfree_rcu() iommu_group
> >  * [iommu] Convert gdev->blocked to enum gdev_blocked
> >  * [iommu] Use disable_work_sync() to fix UAF and ref leak
> >  * [iommu] Gate done() transitions to preserve BLOCKED_BROKEN
> >  * [iommu] Decrement recovery_cnt when unplugging a blocked gdev
> >  * [iommu] Drop racy dev_has_iommu() in iommu_report_device_broken()
> >  * [iommu] Add gdev->broken_pending to skip worker after racing recovery
> >  * [smmuv3] Add master->ats_invs scratch
> >  * [smmuv3] Add arm_smmu_cmdq_batch_issue() wrapper
> >  * [smmuv3] Force per-flush sync for has_ats batches
> >  * [smmuv3] Serialize STE.EATS and ats_broken updates
> >  * [smmuv3] Co-clear pending CMDQ_ERR from cmdq issuer
> >  * [smmuv3] Add invs and has_ats to arm_smmu_cmdq_batch
> >  * [smmuv3] Move arm_smmu_invs_for_each_entry to header
> >  * [smmuv3] Set master->ats_broken after clearing STE.EATS
> >  * [smmuv3] Issue CFGI_STE via arm_smmu_cmdq_issue_cmd_with_sync()
> >  * [smmuv3] Keep "smmu" pointer in arm_smmu_inv but add "master" for
> > ATS
> 
> Not check the detail yet, but this v4 more than doubles the number of
> patches in v3. Are they all necessary to be in one series? any chance to
> split to ease the review...

Ah, sorry. Mostly these are dealing with racing and corner cases in
the async design...

Jason has suggested to drop quite a few things. So, I will respin a
v5 that should be much smaller. Let's ignore this v4 for now.

Thanks
Nicolin


^ permalink raw reply

* [PATCH 2/5] iommu/arm-smmu-v3: Add register display to debugfs
From: Qinxin Xia @ 2026-05-20  6:37 UTC (permalink / raw)
  To: robin.murphy, nicolinc, will, jpb
  Cc: linux-arm-kernel, iommu, xiaqinxin, wangzhou1, prime.zeng,
	fanghao11, jonathan.cameron, wuyifan50, linuxarm, linux-kernel
In-Reply-To: <20260328101706.3448655-1-xiaqinxin@huawei.com>

Add register display functionality to debugfs.This allows reading
and displaying key SMMU register values including control registers
and queue pointers.

The registers file shows:
- CR0, CR1, CR2 control registers
- Command and Event queue pointers

Signed-off-by: Qinxin Xia <xiaqinxin@huawei.com>
---
 .../arm/arm-smmu-v3/arm-smmu-v3-debugfs.c     | 82 +++++++++++++++++++
 1 file changed, 82 insertions(+)

diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-debugfs.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-debugfs.c
index 1fc2cd1651b4..a541476b7427 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-debugfs.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-debugfs.c
@@ -6,12 +6,17 @@
  * /sys/kernel/debug/iommu/arm_smmu_v3/
  * └── smmu<ioaddr>/
  *     ├── capabilities    # SMMU feature capabilities and configuration
+ *     ├── registers       # SMMU Key registers
  *
  * The capabilities file provides detailed information about:
  * - translation stage support (Stage1/Stage2)
  * - System coherency, ATS, and PRI feature availability
  * - Stream table size and command/event queue depths
  *
+ * The registers display provides crucial visibility into:
+ * - CR0, CR1, CR2 control registers
+ * - Command and Event queue pointers
+ *
  * Copyright (C) 2026 HiSilicon Limited.
  * Author: Qinxin Xia <xiaqinxin@huawei.com>
  */
@@ -95,6 +100,80 @@ static const struct file_operations smmu_debugfs_capabilities_fops = {
 	.release = smmu_debugfs_capabilities_release,
 };
 
+/**
+ * smmu_debugfs_registers_show() - Display SMMU register values
+ * @seq: seq_file to write to
+ * @unused: unused parameter
+ *
+ * Errors are reported via seq_puts, the function always returns 0
+ */
+static int smmu_debugfs_registers_show(struct seq_file *seq, void *unused)
+{
+	struct arm_smmu_device *smmu = seq->private;
+	void __iomem *base;
+
+	if (!smmu || !smmu->base) {
+		seq_puts(seq, "SMMU not available\n");
+		return 0;
+	}
+
+	base = smmu->base;
+
+	seq_puts(seq, "SMMUv3 Key Registers:\n");
+
+	/* 32-bit control registers */
+	seq_printf(seq, "CR0: 0x%08x\n", readl_relaxed(base + ARM_SMMU_CR0));
+	seq_printf(seq, "CR1: 0x%08x\n", readl_relaxed(base + ARM_SMMU_CR1));
+	seq_printf(seq, "CR2: 0x%08x\n", readl_relaxed(base + ARM_SMMU_CR2));
+
+	/* 32-bit queue pointer registers */
+	seq_printf(seq, "CMDQ_PROD: 0x%08x\n",
+		   readl_relaxed(base + ARM_SMMU_CMDQ_PROD));
+	seq_printf(seq, "CMDQ_CONS: 0x%08x\n",
+		   readl_relaxed(base + ARM_SMMU_CMDQ_CONS));
+	seq_printf(seq, "EVTQ_PROD: 0x%08x\n",
+		   smmu->page1 ? readl_relaxed(smmu->page1 + ARM_SMMU_EVTQ_PROD) : 0);
+	seq_printf(seq, "EVTQ_CONS: 0x%08x\n",
+		   smmu->page1 ? readl_relaxed(smmu->page1 + ARM_SMMU_EVTQ_CONS) : 0);
+
+	return 0;
+}
+
+static int smmu_debugfs_registers_open(struct inode *inode, struct file *file)
+{
+	struct arm_smmu_device *smmu = inode->i_private;
+	int ret;
+
+	if (!smmu || !get_device(smmu->dev))
+		return -ENODEV;
+
+	ret = single_open(file, smmu_debugfs_registers_show, smmu);
+	if (ret)
+		put_device(smmu->dev);
+
+	return ret;
+}
+
+static int smmu_debugfs_registers_release(struct inode *inode, struct file *file)
+{
+	struct seq_file *seq = file->private_data;
+	struct arm_smmu_device *smmu = seq->private;
+
+	single_release(inode, file);
+	if (smmu)
+		put_device(smmu->dev);
+
+	return 0;
+}
+
+static const struct file_operations smmu_debugfs_registers_fops = {
+	.owner   = THIS_MODULE,
+	.open    = smmu_debugfs_registers_open,
+	.read    = seq_read,
+	.llseek  = seq_lseek,
+	.release = smmu_debugfs_registers_release,
+};
+
 /**
  * arm_smmu_debugfs_setup() - Initialize debugfs for SMMU device
  * @smmu: SMMU device to setup debugfs for
@@ -142,6 +221,9 @@ int arm_smmu_debugfs_setup(struct arm_smmu_device *smmu, const char *name)
 	debugfs_create_file("capabilities", 0444, smmu_dir, smmu,
 			    &smmu_debugfs_capabilities_fops);
 
+	debugfs_create_file("registers", 0444, smmu_dir, smmu,
+			    &smmu_debugfs_registers_fops);
+
 	dev_dbg(smmu->dev, "debugfs initialized for %s\n", name);
 	return 0;
 }
-- 
2.33.0



^ permalink raw reply related


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox