* [PATCH 1/4] dt-bindings: vendor-prefixes: Add Ugreen Group Limited
From: Alexey Charkov @ 2026-06-12 15:34 UTC (permalink / raw)
To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Lee Jones,
Heiko Stuebner, Liam Girdwood, Mark Brown
Cc: devicetree, linux-kernel, linux-arm-kernel, linux-rockchip,
Alexey Charkov
In-Reply-To: <20260612-dh2300-mcu-v1-0-ab8db1617bc0@flipper.net>
Add Ugreen Group Limited, a consumer technology company producing a range
of smart charging, office audio and visual, and smart storage products.
Link: https://www.ugreen.com/
Signed-off-by: Alexey Charkov <alchark@flipper.net>
---
Documentation/devicetree/bindings/vendor-prefixes.yaml | 2 ++
1 file changed, 2 insertions(+)
diff --git a/Documentation/devicetree/bindings/vendor-prefixes.yaml b/Documentation/devicetree/bindings/vendor-prefixes.yaml
index dd94c50e97f9..274e52421a5b 100644
--- a/Documentation/devicetree/bindings/vendor-prefixes.yaml
+++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml
@@ -1757,6 +1757,8 @@ patternProperties:
description: Ufi Space Co., Ltd.
"^ugoos,.*":
description: Ugoos Industrial Co., Ltd.
+ "^ugreen,.*":
+ description: Ugreen Group Limited
"^ultrapower,.*":
description: Beijing Ultrapower Software Co., Ltd.
"^uni-t,.*":
--
2.53.0
^ permalink raw reply related
* [PATCH 0/4] mfd: Add support for the MCU in the UGREEN DH2300 NAS
From: Alexey Charkov @ 2026-06-12 15:34 UTC (permalink / raw)
To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Lee Jones,
Heiko Stuebner, Liam Girdwood, Mark Brown
Cc: devicetree, linux-kernel, linux-arm-kernel, linux-rockchip,
Alexey Charkov
UGREEN DH2300 is a 2-bay SATA NAS based on the Rockchip RK3576 SoC. It
includes an embedded controller connected over I2C which won't let the
drives power up without its register being poked first, which precludes
the use of the device for its main purpose.
There is no public documentation or source code available, but apparently
the MCU is also responsible for a hardware watchdog function and some type
of wake functionality, so this series implements an MFD-regulator
separation right away to allow for adding these functions properly later
on.
For now though a single-bit write to the MCU seems to be sufficient to get
the drives to work with only a board DTS addition [1] - to be submitted
separately.
[1] https://github.com/flipperdevices/flipper-linux-kernel/blob/2c1c5ee609f6ed4c77e9e5428df91e98b3f50cce/arch/arm64/boot/dts/rockchip/rk3576-nasync-dh2300.dts
Signed-off-by: Alexey Charkov <alchark@flipper.net>
---
Alexey Charkov (4):
dt-bindings: vendor-prefixes: Add Ugreen Group Limited
dt-bindings: mfd: Add UGREEN NASync DH2300 MCU
mfd: Add support for UGREEN NASync DH2300 MCU
regulator: Add support for UGREEN NASync DH2300 MCU SATA power gate
.../devicetree/bindings/mfd/ugreen,dh2300-mcu.yaml | 62 +++++++++++++++++
.../devicetree/bindings/vendor-prefixes.yaml | 2 +
MAINTAINERS | 7 ++
drivers/mfd/Kconfig | 16 +++++
drivers/mfd/Makefile | 1 +
drivers/mfd/ugreen-dh2300-mcu.c | 60 ++++++++++++++++
drivers/regulator/Kconfig | 12 ++++
drivers/regulator/Makefile | 1 +
drivers/regulator/ugreen-dh2300-mcu-regulator.c | 80 ++++++++++++++++++++++
9 files changed, 241 insertions(+)
---
base-commit: ec039126b7fac4e3af35ebccaa7c6f9b6875ba81
change-id: 20260612-dh2300-mcu-5354d1f5f11a
Best regards,
--
Alexey Charkov <alchark@flipper.net>
^ permalink raw reply
* Re: [PATCH v6 5/6] KVM: arm64: Validate the offset to the mem access descriptor
From: Sebastian Ene @ 2026-06-12 15:20 UTC (permalink / raw)
To: Mostafa Saleh
Cc: op-tee, linux-kernel, kvmarm, linux-arm-kernel, maz, oupton,
joey.gouly, suzuki.poulose, catalin.marinas, jens.wiklander,
sumit.garg, vdonnefort, sudeep.holla
In-Reply-To: <20260527150236.1978655-6-smostafa@google.com>
On Wed, May 27, 2026 at 03:02:35PM +0000, Mostafa Saleh wrote:
> From: Sebastian Ene <sebastianene@google.com>
>
> Prevent the pKVM hypervisor from making assumptions that the
> endpoint memory access descriptor (EMAD) comes right after the
> FF-A memory region header.
> Prior to FF-A version 1.1 the header of the memory region
> didn't contain an offset to the endpoint memory access descriptor.
> The layout of a memory transaction looks like this from 1.1 onward:
> Type | Field name | Offset
> [ Header | ffa_mem_region | 0
> EMAD 1 | ffa_mem_region_attributes) | ffa_mem_region.ep_mem_offset
> ]
> Verify that the offset to the first endpoint memory access descriptor
> is within the mailbox buffer bounds.
>
> Also, fix one hardcoded sizeof(struct ffa_mem_region_attributes) that
> should be replaced ffa_emad_size_get() for compatibility with FFA v1.0.
>
> [@Mostafa, Add missing call to ffa_rx_release() and use fraglen
> as the max buffer size as it is the only intialised part]
>
> Fixes: 42fb33dde42b ("KVM: arm64: Use FF-A 1.1 with pKVM")
> Signed-off-by: Sebastian Ene <sebastianene@google.com>
> Signed-off-by: Mostafa Saleh <smostafa@google.com>
> ---
> arch/arm64/kvm/hyp/nvhe/ffa.c | 25 ++++++++++++++++++-------
> 1 file changed, 18 insertions(+), 7 deletions(-)
>
> diff --git a/arch/arm64/kvm/hyp/nvhe/ffa.c b/arch/arm64/kvm/hyp/nvhe/ffa.c
> index b6cf9ad82e12..a12e01883314 100644
> --- a/arch/arm64/kvm/hyp/nvhe/ffa.c
> +++ b/arch/arm64/kvm/hyp/nvhe/ffa.c
> @@ -476,10 +476,10 @@ static void __do_ffa_mem_xfer(const u64 func_id,
> DECLARE_REG(u32, fraglen, ctxt, 2);
> DECLARE_REG(u64, addr_mbz, ctxt, 3);
> DECLARE_REG(u32, npages_mbz, ctxt, 4);
> + u32 offset, nr_ranges, checked_offset, em_mem_access_off;
> struct ffa_mem_region_attributes *ep_mem_access;
> struct ffa_composite_mem_region *reg;
> struct ffa_mem_region *buf;
> - u32 offset, nr_ranges, checked_offset;
> int ret = 0;
>
> if (addr_mbz || npages_mbz || fraglen > len ||
> @@ -489,7 +489,7 @@ static void __do_ffa_mem_xfer(const u64 func_id,
> }
>
Hi Mostafa,
> if (fraglen < sizeof(struct ffa_mem_region) +
> - sizeof(struct ffa_mem_region_attributes)) {
> + ffa_emad_size_get(hyp_ffa_version)) {
> ret = FFA_RET_INVALID_PARAMETERS;
> goto out;
> }
Here sashiko complains about a compatibility break with v1.0 even though
it is not from this change. This is because the size of sizeof(struct
ffa_mem_region) was 36 bytes in v1.0 and now it is 48.
This check can cause "perfectly valid v1.0 memory transfers to be rejected"
(from sashiko).
Other than that this looks good. I will spin a new version of this
series.
> @@ -508,8 +508,13 @@ static void __do_ffa_mem_xfer(const u64 func_id,
> buf = hyp_buffers.tx;
> memcpy(buf, host_buffers.tx, fraglen);
>
> - ep_mem_access = (void *)buf +
> - ffa_mem_desc_offset(buf, 0, hyp_ffa_version);
> + em_mem_access_off = ffa_mem_desc_offset(buf, 0, hyp_ffa_version);
> + if ((u64)em_mem_access_off + ffa_emad_size_get(hyp_ffa_version) > fraglen) {
> + ret = FFA_RET_INVALID_PARAMETERS;
> + goto out_unlock;
> + }
> +
> + ep_mem_access = (void *)buf + em_mem_access_off;
> offset = ep_mem_access->composite_off;
> if (!offset || buf->ep_count != 1 || buf->sender_id != HOST_FFA_ID) {
> ret = FFA_RET_INVALID_PARAMETERS;
> @@ -574,9 +579,9 @@ static void do_ffa_mem_reclaim(struct arm_smccc_1_2_regs *res,
> DECLARE_REG(u32, handle_lo, ctxt, 1);
> DECLARE_REG(u32, handle_hi, ctxt, 2);
> DECLARE_REG(u32, flags, ctxt, 3);
> + u32 offset, len, fraglen, fragoff, em_mem_access_off;
> struct ffa_mem_region_attributes *ep_mem_access;
> struct ffa_composite_mem_region *reg;
> - u32 offset, len, fraglen, fragoff;
> struct ffa_mem_region *buf;
> int ret = 0;
> u64 handle;
> @@ -599,8 +604,14 @@ static void do_ffa_mem_reclaim(struct arm_smccc_1_2_regs *res,
> len = res->a1;
> fraglen = res->a2;
>
> - ep_mem_access = (void *)buf +
> - ffa_mem_desc_offset(buf, 0, hyp_ffa_version);
> + em_mem_access_off = ffa_mem_desc_offset(buf, 0, hyp_ffa_version);
> + if ((u64)em_mem_access_off + ffa_emad_size_get(hyp_ffa_version) > fraglen) {
> + ret = FFA_RET_INVALID_PARAMETERS;
> + ffa_rx_release(res);
> + goto out_unlock;
> + }
> +
> + ep_mem_access = (void *)buf + em_mem_access_off;
> offset = ep_mem_access->composite_off;
> /*
> * We can trust the SPMD to get this right, but let's at least
> --
> 2.54.0.746.g67dd491aae-goog
>
Thanks,
Sebastian
^ permalink raw reply
* Re: [PATCH v6 1/3] dt-bindings: imx6q-pcie: Add optional intr/aer/pme interrupts for i.MX95
From: Rob Herring @ 2026-06-12 15:13 UTC (permalink / raw)
To: hongxing.zhu
Cc: krzk+dt, conor+dt, bhelgaas, frank.li, l.stach, lpieralisi,
kwilczynski, mani, s.hauer, kernel, festevam, linux-pci,
linux-arm-kernel, devicetree, imx, linux-kernel, Richard Zhu
In-Reply-To: <20260603062510.3767610-2-hongxing.zhu@oss.nxp.com>
On Wed, Jun 03, 2026 at 02:25:08PM +0800, hongxing.zhu@oss.nxp.com wrote:
> From: Richard Zhu <hongxing.zhu@nxp.com>
>
> The i.MX95 PCIe controller introduces three additional dedicated hardware
> interrupt lines for specific events:
> - intr: general controller events
> - aer: Advanced Error Reporting events
> - pme: Power Management Events
>
> These interrupts are optional on i.MX95. PCIe basic functionality
> (enumeration, configuration, and data transfer) works correctly without
> them, as the controller can operate using only the existing msi interrupt.
>
> Earlier i.MX PCIe variants (imx6q, imx6sx, imx6qp, imx7d, imx8mm, imx8mp,
> imx8mq, imx8q) do not have these three dedicated interrupt lines.
>
> Update the binding to allow up to 5 interrupts for i.MX95, while
> restricting earlier variants to a maximum of 2 interrupts using
> conditional constraints (if/then schema). This ensures the schema
> accurately reflects the hardware capabilities of each SoC variant.
>
> Signed-off-by: Richard Zhu <hongxing.zhu@nxp.com>
> Reviewed-by: Frank Li <Frank.Li@nxp.com>
> ---
> .../bindings/pci/fsl,imx6q-pcie.yaml | 29 +++++++++++++++++++
> 1 file changed, 29 insertions(+)
>
> diff --git a/Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.yaml b/Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.yaml
> index e8b8131f5f23..9b5d4e59dfff 100644
> --- a/Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.yaml
> +++ b/Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.yaml
> @@ -58,12 +58,18 @@ properties:
> items:
> - description: builtin MSI controller.
> - description: builtin DMA controller.
> + - description: PCIe event interrupt.
> + - description: builtin AER SPI standalone interrupt line.
> + - description: builtin PME SPI standalone interrupt line.
>
> interrupt-names:
> minItems: 1
> items:
> - const: msi
> - const: dma
> + - const: intr
> + - const: aer
> + - const: pme
>
> reset-gpio:
> deprecated: true
> @@ -248,6 +254,29 @@ allOf:
> - const: pcie_aux
> - const: ref
> - const: extref # Optional
> + interrupts:
> + maxItems: 5
> + interrupt-names:
> + maxItems: 5
5 is already the max.
> +
> + - if:
> + properties:
> + compatible:
> + enum:
> + - fsl,imx6q-pcie
> + - fsl,imx6sx-pcie
> + - fsl,imx6qp-pcie
> + - fsl,imx7d-pcie
> + - fsl,imx8mm-pcie
> + - fsl,imx8mp-pcie
> + - fsl,imx8mq-pcie
> + - fsl,imx8q-pcie
> + then:
> + properties:
> + interrupts:
> + maxItems: 2
> + interrupt-names:
> + maxItems: 2
>
> unevaluatedProperties: false
>
> --
> 2.34.1
>
^ permalink raw reply
* Re: [PATCH v2 1/5] ASoC: dt-bindings: rockchip-spdif: Correct SPDIF clock descriptions
From: Rob Herring (Arm) @ 2026-06-12 15:12 UTC (permalink / raw)
To: phucduc.bui
Cc: Mark Brown, linux-kernel, Heiko Stuebner, Krzysztof Kozlowski,
linux-sound, Liam Girdwood, Jaroslav Kysela, Conor Dooley,
devicetree, linux-rockchip, linux-arm-kernel, Takashi Iwai
In-Reply-To: <20260602101608.45137-2-phucduc.bui@gmail.com>
On Tue, 02 Jun 2026 17:16:04 +0700, phucduc.bui@gmail.com wrote:
> From: bui duc phuc <phucduc.bui@gmail.com>
>
> Update the binding descriptions to match the actual clock usage, where
> 'mclk' is the controller clock and 'hclk' is the bus clock.
>
> Signed-off-by: bui duc phuc <phucduc.bui@gmail.com>
> ---
>
> Changes in v2:
> - Update commit message based on Krzysztof's review
>
> Documentation/devicetree/bindings/sound/rockchip-spdif.yaml | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
Acked-by: Rob Herring (Arm) <robh@kernel.org>
^ permalink raw reply
* Re: [PATCH 3/3] arm64/coco: Add pKVM as a CC platform
From: Aneesh Kumar K.V @ 2026-06-12 15:07 UTC (permalink / raw)
To: Mostafa Saleh
Cc: linux-arm-kernel, linux-kernel, akpm, catalin.marinas, will, rppt,
maz
In-Reply-To: <aivG1rEi3y4GN8kX@google.com>
Mostafa Saleh <smostafa@google.com> writes:
> On Thu, Jun 04, 2026 at 02:29:00PM +0530, Aneesh Kumar K.V wrote:
>> Mostafa Saleh <smostafa@google.com> writes:
>>
>> > pKVM does support memory encryption, expose that to the rest of
>> > the kernel through cc_platform_has()
>> >
>> > At the moment, all devices inside the guest are emulated which
>> > requires its memory to be shared back to the host (decrypted), so
>> > set force_dma_unencrypted() to always return true.
>> >
>> > Although, typically pKVM guests rely on restricted-dma-pools to
>> > bounce traffic, with this change, it is possible to solely rely on
>> > the default SWIOTLB for that (assuming the appropriate size is set
>> > from the command line)
>> >
>> > Signed-off-by: Mostafa Saleh <smostafa@google.com>
>> > ---
>> > This change is critical for the ongoing refactoring of the DMA-API[1]
>> > that will break protected guests under pKVM with this patch. That is
>> > due to this rework will make the state of the SWIOTLB and restricted
>> > dma pools depends on the value returned by cc_platform_has()
>> >
>> > [1] https://lore.kernel.org/all/20260522042815.370873-1-aneesh.kumar@kernel.org/
>> > ---
>> > arch/arm64/include/asm/hypervisor.h | 13 +++++++++++++
>> > arch/arm64/include/asm/mem_encrypt.h | 3 ++-
>> > arch/arm64/kernel/rsi.c | 12 ------------
>> > arch/arm64/mm/init.c | 15 ++++++++++++++-
>> > drivers/virt/coco/pkvm-guest/arm-pkvm-guest.c | 3 +++
>> > 5 files changed, 32 insertions(+), 14 deletions(-)
>> >
>> > index d66291def0f4..26fe9c3f22e3 100644
> [...]
>> > --- a/drivers/virt/coco/pkvm-guest/arm-pkvm-guest.c
>> > +++ b/drivers/virt/coco/pkvm-guest/arm-pkvm-guest.c
>> > @@ -17,6 +17,7 @@
>> > #include <asm/hypervisor.h>
>> >
>> > static size_t pkvm_granule;
>> > +DEFINE_STATIC_KEY_FALSE_RO(pkvm_guest);
>> >
>>
>> Do we need EXPORT_SYMBOL on this?
>
> I was not sure about that, all users of this are in tree, I saw RME
> code have the EXPORT but did not know why?
>
arm-cca-guest is one example. I was assuming is_protected_kvm_guest()
would be a helper that could get pulled into various code paths via
force_dma_unencrypted().
If we have not found any build failures for now, we can probably avoid
that change for now.
-aneesh
^ permalink raw reply
* Re: [PATCH 11/11] ASoC: fsl: mpc5200_psc_ac97: Use guard() for mutex locks
From: Mark Brown @ 2026-06-12 15:05 UTC (permalink / raw)
To: phucduc.bui
Cc: Liam Girdwood, Jaroslav Kysela, Takashi Iwai, Shengjiu Wang,
Xiubo Li, Frank Li, Fabio Estevam, Nicolin Chen, Sascha Hauer,
Pengutronix Kernel Team, linux-sound, linux-kernel,
linux-arm-kernel, imx, linuxppc-dev
In-Reply-To: <20260612132639.78086-12-phucduc.bui@gmail.com>
[-- Attachment #1: Type: text/plain, Size: 230 bytes --]
On Fri, Jun 12, 2026 at 08:26:39PM +0700, phucduc.bui@gmail.com wrote:
> - dev_dbg(psc_dma->dev, "cold reset\n");
> + scoped_guard(mutex_lock, &psc_dma->mutex) {
> + dev_dbg(psc_dma->dev, "cold reset\n");
mutex_lock not mutex?
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]
^ permalink raw reply
* Re: [PATCH 1/2] PCI: dwc: Guard RAS DES debugfs deinit
From: Shuvam Pandey @ 2026-06-12 14:53 UTC (permalink / raw)
To: Bjorn Helgaas
Cc: Jingoo Han, Manivannan Sadhasivam, Lorenzo Pieralisi,
Krzysztof Wilczyński, Bjorn Helgaas, Yue Wang,
Neil Armstrong, Rob Herring, Kevin Hilman, Jerome Brunet,
Martin Blumenstingl, Fan Ni, Shradha Todi, Hanjie Lin, linux-pci,
linux-amlogic, linux-arm-kernel, linux-kernel
In-Reply-To: <20260611221000.GA524832@bhelgaas>
Hi Bjorn,
> I guess this prevents a NULL pointer dereference, right?
Yes. This is in the CONFIG_PCIE_DW_DEBUGFS teardown path when the
controller does not advertise the RAS DES capability.
In that case dwc_pcie_rasdes_debugfs_init() returns 0 before allocating
pci->debugfs->rasdes_info or initializing reg_event_lock. Later,
dwc_pcie_debugfs_deinit() still calls dwc_pcie_rasdes_debugfs_deinit()
unconditionally.
With CONFIG_DEBUG_MUTEXES, mutex_destroy() dereferences the mutex, so
calling it via &rinfo->reg_event_lock when rinfo is NULL would
dereference NULL. Without CONFIG_DEBUG_MUTEXES, mutex_destroy() is a
no-op, but there is still no RAS DES state to tear down.
So the patch makes the deinit path match the init path: if no
rasdes_info was allocated, skip the RAS DES mutex teardown.
Thanks,
Shuvam
^ permalink raw reply
* Re: [PATCH v5 09/10] dt-bindings: firmware: add arm,ras-cper
From: Rob Herring @ 2026-06-12 14:49 UTC (permalink / raw)
To: Ahmed Tiba
Cc: Jonathan Cameron, will, xueshuai, saket.dumbre, mchehab, dave,
djbw, bp, tony.luck, guohanjun, lenb, skhan, vishal.l.verma,
rafael, corbet, ira.weiny, dave.jiang, krzk+dt, catalin.marinas,
alison.schofield, conor+dt, linux-arm-kernel, Michael.Zhao2,
linux-doc, linux-kernel, linux-cxl, Dmitry.Lamerov, devicetree,
linux-acpi, linux-edac, acpica-devel
In-Reply-To: <ceb19cb6-7083-44ad-a262-a8198f489257@arm.com>
On Thu, Jun 11, 2026 at 03:22:21PM +0100, Ahmed Tiba wrote:
> On 29/05/2026 17:44, Jonathan Cameron wrote:
> > On Fri, 29 May 2026 10:50:49 +0100
> > Ahmed Tiba<ahmed.tiba@arm.com> wrote:
> > > .../devicetree/bindings/firmware/arm,ras-cper.yaml | 54 ++++++++++++++++++++++
> > > MAINTAINERS | 5 ++
> > > 2 files changed, 59 insertions(+)
> > >
> > > diff --git a/Documentation/devicetree/bindings/firmware/arm,ras-cper.yaml b/Documentation/devicetree/bindings/firmware/arm,ras-cper.yaml
> > > new file mode 100644
> > > index 000000000000..3d4de096093f
> > > --- /dev/null
> > > +++ b/Documentation/devicetree/bindings/firmware/arm,ras-cper.yaml
> > > @@ -0,0 +1,54 @@
> > > +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> > > +%YAML 1.2
> > > +---
> > > +$id:http://devicetree.org/schemas/firmware/arm,ras-cper.yaml#
> > > +$schema:http://devicetree.org/meta-schemas/core.yaml#
> > > +
> > > +title: Arm RAS CPER provider
> > > +
> > > +maintainers:
> > > + - Ahmed Tiba<ahmed.tiba@arm.com>
> > > +
> > > +description:
> > > + Arm Reliability, Availability and Serviceability (RAS) firmware can expose
> > > + a firmware-first CPER error source directly via DeviceTree. Firmware
> > > + provides the CPER Generic Error Status block and notifies the OS through
> > > + an interrupt.
> > I'd like some spec references in here if possible.
> I can add a reference to the UEFI CPER specification for the Generic
> Error Status record format.
>
> For the firmware-first DT description itself I do not have a more specific
> public reference to cite.
Is there a platform actually using this with DT (FVP doesn't really
count)?
Rob
^ permalink raw reply
* Re: [PATCH v3 00/11] kdump: reduce vmcore size and capture time
From: Rob Herring @ 2026-06-12 14:42 UTC (permalink / raw)
To: Wandun Chen
Cc: linux-arm-kernel, linux-kernel, loongarch, linux-riscv,
devicetree, kexec, iommu, zhaomeijing, catalin.marinas, will,
chenhuacai, kernel, pjw, palmer, aou, alex, saravanak, akpm, bhe,
rppt, pasha.tatashin, pratyush, ruirui.yang, m.szyprowski,
robin.murphy, quic_obabatun
In-Reply-To: <20260527032917.3385849-1-chenwandun1@gmail.com>
On Wed, May 27, 2026 at 11:29:06AM +0800, Wandun Chen wrote:
> From: Wandun Chen <chenwandun@lixiang.com>
>
> On SoCs that carve out large firmware-owned reserved memory (GPU
> firmware, DSP, modem, camera ISP, NPU, ...), kdump currently dumps
> those carveouts as part of system RAM even though their contents are
> firmware state that is not useful for kernel crash analysis.
>
> This series introduces an opt-in 'dumpable' flag [1] on struct
> reserved_mem and uses it to filter the elfcorehdr PT_LOAD ranges on
> DT-based architectures (arm64, riscv, loongarch). By default reserved
> regions are treated as non-dumpable; CMA regions are explicitly opted
> in because their pages are returned to the buddy allocator and may
> carry key crash-analysis data.
>
> The series is organized as follows:
> Patches 1-3: Pre-existing fixes and a small prep change.
> Patches 4-5: Restructure to allow appending /memreserve/ entries.
> Patches 6-7: Add a dumpable flag and append /memreserve/ entries.
> Patch 8: Add generic kdump helpers.
> Patches 9-11: Wire the helpers into arm64, riscv and loongarch kdump
> elfcorehdr preparation.
>
> v2 --> v3:
> 1. Fix out-of-bounds issue if device tree lacks /reserved-memory node.[2]
> 2. Fix UAF issue when alloc_reserved_mem_array() fails.
> 3. Add some prepare patches.
>
> v1 --> v2:
> 1. v1 added an opt-out DT property ('linux,no-dump'). Per Rob's
> feedback [1], v2 drop that property and exclude reserve memory
> by default.
> 2. Split some prepared patches from the original patches.
> 3. Address coding-style comments on patch 5 from Rob.
>
> [1] https://lore.kernel.org/lkml/20260506144542.GA2072596-robh@kernel.org/
> [2] https://sashiko.dev/#/patchset/20260520091844.592753-1-chenwandun%40lixiang.com?part=4
>
> Wandun Chen (11):
> of: reserved_mem: handle NULL name in of_reserved_mem_lookup()
> of: reserved_mem: zero total_reserved_mem_cnt if no valid
> /reserved-memory entry
I applied these 2 for 7.2.
Rob
^ permalink raw reply
* Re: [PATCH v3 05/11] of: reserved_mem: split alloc_reserved_mem_array() from fdt_scan_reserved_mem_late()
From: Rob Herring @ 2026-06-12 14:41 UTC (permalink / raw)
To: Wandun Chen
Cc: linux-arm-kernel, linux-kernel, loongarch, linux-riscv,
devicetree, kexec, iommu, zhaomeijing, catalin.marinas, will,
chenhuacai, kernel, pjw, palmer, aou, alex, saravanak, akpm, bhe,
rppt, pasha.tatashin, pratyush, ruirui.yang, m.szyprowski,
robin.murphy, quic_obabatun
In-Reply-To: <20260527032917.3385849-6-chenwandun1@gmail.com>
On Wed, May 27, 2026 at 11:29:11AM +0800, Wandun Chen wrote:
> From: Wandun Chen <chenwandun@lixiang.com>
>
> Prepare for storing /memreserve/ entries in the reserved_mem array.
> alloc_reserved_mem_array is skipped if the device tree lacks a
> /reserved-memory node, pointer 'reserved_mem' continues to reference
> the reserved_mem_array which lives in __initdata, storing
> /memreserve/ entries into reserved_mem_array would result in metadata
> loss, and an out-of-bounds memory access will occur if the device
> tree contains more than MAX_RESERVED_REGIONS /memreserve/ entries.
>
> So split alloc_reserved_mem_array() from fdt_scan_reserved_mem_late(),
> and call alloc_reserved_mem_array() whether or not there is a
> /reserved-memory node.
>
> No functional change.
> The actual /memreserve/ population is added in a follow-up patch.
>
> Signed-off-by: Wandun Chen <chenwandun@lixiang.com>
> ---
> drivers/of/fdt.c | 7 +++++--
> drivers/of/of_private.h | 1 +
> drivers/of/of_reserved_mem.c | 6 +-----
> 3 files changed, 7 insertions(+), 7 deletions(-)
>
> diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c
> index 82f7327c59ea..83a2a474831e 100644
> --- a/drivers/of/fdt.c
> +++ b/drivers/of/fdt.c
> @@ -1284,8 +1284,11 @@ void __init unflatten_device_tree(void)
> {
> void *fdt = initial_boot_params;
>
> - /* Save the statically-placed regions in the reserved_mem array */
> - fdt_scan_reserved_mem_late();
> + /* Attempt dynamic allocation of a new reserved_mem array */
> + if (fdt && alloc_reserved_mem_array()) {
> + /* Save the statically-placed regions in the reserved_mem array */
> + fdt_scan_reserved_mem_late();
Can we make this just:
alloc_reserved_mem_array();
fdt_scan_reserved_mem_late();
We already check !fdt in fdt_scan_reserved_mem_late().
Rob
^ permalink raw reply
* Re: [PATCH 2/2] PCI: meson: Add missing remove callback
From: Shuvam Pandey @ 2026-06-12 14:39 UTC (permalink / raw)
To: Bjorn Helgaas
Cc: Jingoo Han, Manivannan Sadhasivam, Lorenzo Pieralisi,
Krzysztof Wilczyński, Bjorn Helgaas, Yue Wang,
Neil Armstrong, Rob Herring, Kevin Hilman, Jerome Brunet,
Martin Blumenstingl, Fan Ni, Shradha Todi, Hanjie Lin, linux-pci,
linux-amlogic, linux-arm-kernel, linux-kernel
In-Reply-To: <20260611222653.GA527114@bhelgaas>
Hi Bjorn,
> What's the user-visible effect of this? Does it avoid an oops?
> Reduce power usage?
I don't have hardware with this controller, so I have not observed an
oops from this.
The concrete effect is that driver unbind/module unload gets the
matching teardown for the successful probe path: the DesignWare host
bridge is unregistered with dw_pcie_host_deinit(), and the PHY is
powered off with meson_pcie_power_off() before devres releases the
driver's resources.
So yes, it should reduce power usage after unbind. The host bridge
teardown is also the matching cleanup for dw_pcie_host_init(), but I
don't have hardware evidence of an oops on unbind.
> Of the 34 instances of .probe() in drivers/pci/controller/dwc/, on 12
> implement .remove(), so if this fixes a problem, I'm wondering whether
> other drivers have the same problem.
Yes, that may deserve a broader driver-by-driver audit. I only checked
Meson for this patch. Some DWC drivers implement .remove(), and several
others set .suppress_bind_attrs, which affects the manual sysfs
bind/unbind path. Before this patch, the Meson driver had neither, while
meson_pcie_probe() calls meson_pcie_power_on() and registers the host
bridge with dw_pcie_host_init().
Thanks,
Shuvam
^ permalink raw reply
* Re: [PATCH] kbuild: Use --force-group-allocation when linking modules
From: Peter Collingbourne @ 2026-06-12 14:38 UTC (permalink / raw)
To: Petr Pavlu
Cc: Nathan Chancellor, Nicolas Schier, Catalin Marinas, Will Deacon,
Sami Tolvanen, Daniel Gomez, Luis Chamberlain, Aaron Tomlin,
linux-kbuild, linux-arm-kernel, linux-modules, linux-kernel
In-Reply-To: <20260612133139.1919042-1-petr.pavlu@suse.com>
On Fri, Jun 12, 2026 at 6:31 AM Petr Pavlu <petr.pavlu@suse.com> wrote:
>
> Specific code, such as outlined KASAN checks, may be placed in
> COMDAT-deduplicated sections. When linking modules as relocatable files,
> the linker by default preserves such groups, potentially leaving multiple
> copies in the resulting modules and unnecessary group metadata.
>
> Use --force-group-allocation to have the linker resolve the COMDAT groups
> and place their members as regular sections. The option is available from
> ld.bfd 2.29 and ld.lld 19.1.0.
>
> Remove the workaround in arch/arm64/include/asm/module.lds.h that was added
> for the same problem but limited to CONFIG_KASAN_SW_TAGS and .text.hot.
> Note that this code currently has no effect anyway because all .text.hot
> sections are placed in the .text output section by scripts/module.lds.S,
> since commit 1ba9f8979426 ("vmlinux.lds: Unify TEXT_MAIN, DATA_MAIN, and
> related macros").
>
> Signed-off-by: Petr Pavlu <petr.pavlu@suse.com>
Reviewed-by: Peter Collingbourne <pcc@google.com>
> ---
> Makefile | 6 ++++++
> arch/arm64/include/asm/module.lds.h | 13 -------------
> 2 files changed, 6 insertions(+), 13 deletions(-)
>
> diff --git a/Makefile b/Makefile
> index e156e2696efe..1729af0690b3 100644
> --- a/Makefile
> +++ b/Makefile
> @@ -1189,6 +1189,12 @@ KBUILD_RUSTFLAGS += $(KRUSTFLAGS)
> KBUILD_LDFLAGS_MODULE += --build-id=sha1
> LDFLAGS_vmlinux += --build-id=sha1
>
> +# Specific code, such as outlined KASAN checks, may be placed in
> +# COMDAT-deduplicated sections. Use --force-group-allocation to resolve these
> +# groups when linking modules. The option is available from ld.bfd 2.29 and
> +# ld.lld 19.1.0.
> +KBUILD_LDFLAGS_MODULE += $(call ld-option,--force-group-allocation)
> +
> KBUILD_LDFLAGS += -z noexecstack
> ifeq ($(CONFIG_LD_IS_BFD),y)
> KBUILD_LDFLAGS += $(call ld-option,--no-warn-rwx-segments)
> diff --git a/arch/arm64/include/asm/module.lds.h b/arch/arm64/include/asm/module.lds.h
> index fb944b46846d..792a0820757a 100644
> --- a/arch/arm64/include/asm/module.lds.h
> +++ b/arch/arm64/include/asm/module.lds.h
> @@ -4,19 +4,6 @@ SECTIONS {
> .text.ftrace_trampoline 0 : { BYTE(0) }
> .init.text.ftrace_trampoline 0 : { BYTE(0) }
>
> -#ifdef CONFIG_KASAN_SW_TAGS
> - /*
> - * Outlined checks go into comdat-deduplicated sections named .text.hot.
> - * Because they are in comdats they are not combined by the linker and
> - * we otherwise end up with multiple sections with the same .text.hot
> - * name in the .ko file. The kernel module loader warns if it sees
> - * multiple sections with the same name so we use this sections
> - * directive to force them into a single section and silence the
> - * warning.
> - */
> - .text.hot : { *(.text.hot) }
> -#endif
> -
> #ifdef CONFIG_UNWIND_TABLES
> /*
> * Currently, we only use unwind info at module load time, so we can
>
> base-commit: 4549871118cf616eecdd2d939f78e3b9e1dddc48
> --
> 2.54.0
>
^ permalink raw reply
* [soc:soc/arm] BUILD SUCCESS cb2c3b5e113f26f74ef05926c6ace0f83cc3d0b3
From: kernel test robot @ 2026-06-12 14:30 UTC (permalink / raw)
To: Arnd Bergmann; +Cc: linux-arm-kernel, arm
tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git soc/arm
branch HEAD: cb2c3b5e113f26f74ef05926c6ace0f83cc3d0b3 MAINTAINERS: Add Axiado reviewer and Maintainers
elapsed time: 761m
configs tested: 227
configs skipped: 2
The following configs have been built successfully.
More configs may be tested in the coming days.
tested configs:
alpha allnoconfig gcc-16.1.0
alpha allyesconfig gcc-16.1.0
alpha defconfig gcc-16.1.0
arc allmodconfig clang-23
arc allmodconfig gcc-16.1.0
arc allnoconfig gcc-16.1.0
arc allyesconfig clang-23
arc allyesconfig gcc-16.1.0
arc defconfig gcc-16.1.0
arc nsim_700_defconfig gcc-16.1.0
arc randconfig-001-20260612 gcc-13.4.0
arc randconfig-002-20260612 gcc-13.4.0
arm allnoconfig clang-23
arm allnoconfig gcc-16.1.0
arm allyesconfig clang-23
arm allyesconfig gcc-16.1.0
arm axm55xx_defconfig clang-23
arm defconfig gcc-16.1.0
arm randconfig-001-20260612 gcc-13.4.0
arm randconfig-002-20260612 gcc-13.4.0
arm randconfig-003-20260612 gcc-13.4.0
arm randconfig-004-20260612 gcc-13.4.0
arm64 allmodconfig clang-23
arm64 allnoconfig gcc-16.1.0
arm64 defconfig gcc-16.1.0
arm64 randconfig-001 gcc-13.4.0
arm64 randconfig-001-20260612 gcc-13.4.0
arm64 randconfig-002 gcc-13.4.0
arm64 randconfig-002-20260612 gcc-13.4.0
arm64 randconfig-003 gcc-13.4.0
arm64 randconfig-003-20260612 gcc-13.4.0
arm64 randconfig-004 gcc-13.4.0
arm64 randconfig-004-20260612 gcc-13.4.0
csky allmodconfig gcc-16.1.0
csky allnoconfig gcc-16.1.0
csky defconfig gcc-16.1.0
csky randconfig-001 gcc-13.4.0
csky randconfig-001-20260612 gcc-13.4.0
csky randconfig-002 gcc-13.4.0
csky randconfig-002-20260612 gcc-13.4.0
hexagon allmodconfig clang-23
hexagon allmodconfig gcc-16.1.0
hexagon allnoconfig clang-23
hexagon allnoconfig gcc-16.1.0
hexagon defconfig gcc-16.1.0
hexagon randconfig-001 gcc-11.5.0
hexagon randconfig-001-20260612 gcc-11.5.0
hexagon randconfig-002 gcc-11.5.0
hexagon randconfig-002-20260612 gcc-11.5.0
i386 allmodconfig clang-22
i386 allnoconfig gcc-14
i386 allnoconfig gcc-16.1.0
i386 allyesconfig clang-22
i386 buildonly-randconfig-001-20260612 gcc-14
i386 buildonly-randconfig-002-20260612 gcc-14
i386 buildonly-randconfig-003-20260612 gcc-14
i386 buildonly-randconfig-004-20260612 gcc-14
i386 buildonly-randconfig-005-20260612 gcc-14
i386 buildonly-randconfig-006-20260612 gcc-14
i386 defconfig gcc-16.1.0
i386 randconfig-001-20260612 clang-22
i386 randconfig-002-20260612 clang-22
i386 randconfig-003-20260612 clang-22
i386 randconfig-004-20260612 clang-22
i386 randconfig-005-20260612 clang-22
i386 randconfig-006-20260612 clang-22
i386 randconfig-007-20260612 clang-22
i386 randconfig-011-20260612 clang-22
i386 randconfig-012-20260612 clang-22
i386 randconfig-013-20260612 clang-22
i386 randconfig-014-20260612 clang-22
i386 randconfig-015-20260612 clang-22
i386 randconfig-016-20260612 clang-22
i386 randconfig-017-20260612 clang-22
loongarch allmodconfig clang-19
loongarch allmodconfig clang-23
loongarch allnoconfig clang-20
loongarch allnoconfig gcc-16.1.0
loongarch defconfig clang-23
loongarch randconfig-001 gcc-11.5.0
loongarch randconfig-001-20260612 gcc-11.5.0
loongarch randconfig-002 gcc-11.5.0
loongarch randconfig-002-20260612 gcc-11.5.0
m68k allmodconfig gcc-16.1.0
m68k allnoconfig gcc-16.1.0
m68k allyesconfig clang-23
m68k allyesconfig gcc-16.1.0
m68k defconfig clang-23
microblaze allnoconfig gcc-16.1.0
microblaze allyesconfig gcc-16.1.0
microblaze defconfig clang-23
mips allmodconfig gcc-16.1.0
mips allnoconfig gcc-16.1.0
mips allyesconfig gcc-16.1.0
nios2 allmodconfig clang-20
nios2 allmodconfig gcc-11.5.0
nios2 allnoconfig clang-23
nios2 allnoconfig gcc-11.5.0
nios2 defconfig clang-23
nios2 randconfig-001 gcc-11.5.0
nios2 randconfig-001-20260612 gcc-11.5.0
nios2 randconfig-002 gcc-11.5.0
nios2 randconfig-002-20260612 gcc-11.5.0
openrisc allmodconfig clang-20
openrisc allmodconfig gcc-16.1.0
openrisc allnoconfig clang-23
openrisc allnoconfig gcc-16.1.0
openrisc defconfig gcc-16.1.0
parisc allmodconfig gcc-16.1.0
parisc allnoconfig clang-23
parisc allnoconfig gcc-16.1.0
parisc allyesconfig clang-23
parisc allyesconfig gcc-16.1.0
parisc defconfig gcc-16.1.0
parisc64 defconfig clang-23
powerpc allmodconfig gcc-16.1.0
powerpc allnoconfig clang-23
powerpc allnoconfig gcc-16.1.0
powerpc ppc64e_defconfig gcc-16.1.0
riscv allmodconfig clang-23
riscv allnoconfig clang-23
riscv allnoconfig gcc-16.1.0
riscv allyesconfig clang-23
riscv defconfig clang-23
riscv defconfig gcc-16.1.0
riscv randconfig-001-20260612 gcc-11.5.0
riscv randconfig-002-20260612 gcc-11.5.0
s390 allmodconfig clang-23
s390 allnoconfig clang-23
s390 allyesconfig gcc-16.1.0
s390 defconfig clang-18
s390 defconfig gcc-16.1.0
s390 randconfig-001-20260612 gcc-11.5.0
s390 randconfig-002-20260612 gcc-11.5.0
sh allmodconfig gcc-16.1.0
sh allnoconfig clang-23
sh allnoconfig gcc-16.1.0
sh allyesconfig clang-23
sh allyesconfig gcc-16.1.0
sh defconfig gcc-14
sh defconfig gcc-16.1.0
sh randconfig-001-20260612 gcc-11.5.0
sh randconfig-002-20260612 gcc-11.5.0
sparc allnoconfig clang-23
sparc allnoconfig gcc-16.1.0
sparc defconfig gcc-16.1.0
sparc randconfig-001 gcc-8.5.0
sparc randconfig-001-20260612 gcc-8.5.0
sparc randconfig-002 gcc-8.5.0
sparc randconfig-002-20260612 gcc-8.5.0
sparc64 allmodconfig clang-20
sparc64 defconfig clang-23
sparc64 defconfig gcc-14
sparc64 randconfig-001 gcc-8.5.0
sparc64 randconfig-001-20260612 gcc-8.5.0
sparc64 randconfig-002 gcc-8.5.0
sparc64 randconfig-002-20260612 gcc-8.5.0
um allmodconfig clang-23
um allnoconfig clang-16
um allnoconfig clang-23
um allyesconfig gcc-14
um allyesconfig gcc-16.1.0
um defconfig clang-23
um defconfig gcc-14
um i386_defconfig gcc-14
um randconfig-001 gcc-8.5.0
um randconfig-001-20260612 gcc-8.5.0
um randconfig-002 gcc-8.5.0
um randconfig-002-20260612 gcc-8.5.0
um x86_64_defconfig clang-23
um x86_64_defconfig gcc-14
x86_64 allmodconfig clang-22
x86_64 allnoconfig clang-22
x86_64 allnoconfig clang-23
x86_64 allyesconfig clang-22
x86_64 buildonly-randconfig-001 gcc-14
x86_64 buildonly-randconfig-001-20260612 gcc-14
x86_64 buildonly-randconfig-002 gcc-14
x86_64 buildonly-randconfig-002-20260612 gcc-14
x86_64 buildonly-randconfig-003 gcc-14
x86_64 buildonly-randconfig-003-20260612 gcc-14
x86_64 buildonly-randconfig-004 gcc-14
x86_64 buildonly-randconfig-004-20260612 gcc-14
x86_64 buildonly-randconfig-005 gcc-14
x86_64 buildonly-randconfig-005-20260612 gcc-14
x86_64 buildonly-randconfig-006 gcc-14
x86_64 buildonly-randconfig-006-20260612 gcc-14
x86_64 defconfig gcc-14
x86_64 kexec clang-22
x86_64 randconfig-001-20260612 clang-22
x86_64 randconfig-002-20260612 clang-22
x86_64 randconfig-003-20260612 clang-22
x86_64 randconfig-004-20260612 clang-22
x86_64 randconfig-005-20260612 clang-22
x86_64 randconfig-006-20260612 clang-22
x86_64 randconfig-011 clang-22
x86_64 randconfig-011-20260612 clang-22
x86_64 randconfig-012 clang-22
x86_64 randconfig-012-20260612 clang-22
x86_64 randconfig-013 clang-22
x86_64 randconfig-013-20260612 clang-22
x86_64 randconfig-014 clang-22
x86_64 randconfig-014-20260612 clang-22
x86_64 randconfig-015 clang-22
x86_64 randconfig-015-20260612 clang-22
x86_64 randconfig-016 clang-22
x86_64 randconfig-016-20260612 clang-22
x86_64 randconfig-071-20260612 gcc-14
x86_64 randconfig-072-20260612 gcc-14
x86_64 randconfig-073-20260612 gcc-14
x86_64 randconfig-074-20260612 gcc-14
x86_64 randconfig-075-20260612 gcc-14
x86_64 randconfig-076-20260612 gcc-14
x86_64 rhel-9.4 clang-22
x86_64 rhel-9.4-bpf gcc-14
x86_64 rhel-9.4-func clang-22
x86_64 rhel-9.4-kselftests clang-22
x86_64 rhel-9.4-kunit gcc-14
x86_64 rhel-9.4-ltp gcc-14
x86_64 rhel-9.4-rust clang-22
xtensa allnoconfig clang-23
xtensa allnoconfig gcc-16.1.0
xtensa allyesconfig clang-20
xtensa randconfig-001 gcc-8.5.0
xtensa randconfig-001-20260612 gcc-8.5.0
xtensa randconfig-002 gcc-8.5.0
xtensa randconfig-002-20260612 gcc-8.5.0
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
^ permalink raw reply
* Re: [PATCH] net: macb: add TX stall timeout callback to recover from lost TSTART write
From: Théo Lebrun @ 2026-06-12 14:30 UTC (permalink / raw)
To: Andrea della Porta, Nicolai Buchwitz
Cc: netdev, Nicolas Ferre, Claudiu Beznea, Andrew Lunn,
David S . Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
linux-kernel, linux-arm-kernel, linux-rpi-kernel, Lukasz Raczylo,
Steffen Jaeckel
In-Reply-To: <DJ753ZA99KY1.1EH3EC5YWVB3@bootlin.com>
On Fri Jun 12, 2026 at 4:28 PM CEST, Théo Lebrun wrote:
> On Fri Jun 12, 2026 at 3:03 PM CEST, Andrea della Porta wrote:
>> On 14:53 Fri 12 Jun , Nicolai Buchwitz wrote:
>>> On 12.6.2026 14:51, Andrea della Porta wrote:
>>> > > The commit message describes it as RP1 specific, but it gets applied
>>> > > to all
>>> > > other variants?
>>> >
>>> > I've seen this issue happening only on RaspberryPi 5, but AFAIK it
>>> > could affect also other MACB blocks connected through PCIe, so it
>>> > may be widespread (even though it should have probably already been
>>> > noticed in the past). In the orginal driver there's no timeout callback
>>> > defined and this is much like pretgending the issue causing the timeout
>>> > to happen to go away without doing anything (whatever the cause ot the
>>> > specific hw are). So in my opinion we can just extend that to all MACB.
>>> > Or maybe we should execute the restart conditionally on
>>> > .compatible = "raspberrypi,rp1-gem"?
>>>
>>> I just observed the issue once, but other people reported it to be happen
>>> more
>>> frequently. If we can narrow down a reproducer, it would be good to test on
>>> other
>>> blocks too (like EyeQ at Théo's).|
>>>
>>> So maybe you can imagine a good repro for this issue?
>>
>> Sure, it's happening quite often during bulk dataflow, at least
>> on my RPi5.
>> It can be reproduced with the following, issued from the DUT:
>>
>> iperf -c <SERVER_IP> -P 10 -t 3000 -w 4M -i 1
>>
>> plus, of course, the related command on server side: iperf -s.
>>
>> It usually happens a couple of times withing a few hours.
>
> Thanks for the reproducer command; I'll run it next week.
> I'd be surprised if it reproduced on hardware that isn't the Pi 5.
Sorry for the two-step message. I forgot to mention I'd prefer to have
the timeout callback on all platforms: don't reserve it for Pi 5.
Thanks,
--
Théo Lebrun, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com
^ permalink raw reply
* Re: [PATCH v5 2/3] pwm: rp1: Add RP1 PWM controller driver
From: Sean Young @ 2026-06-12 14:29 UTC (permalink / raw)
To: Andrea della Porta
Cc: Uwe Kleine-König, linux-pwm, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Florian Fainelli,
Broadcom internal kernel review list, devicetree,
linux-rpi-kernel, linux-arm-kernel, linux-kernel, Naushir Patuck,
Stanimir Varbanov, mbrugger
In-Reply-To: <f8dd46a553351adaf9d29fbba9f98e803b672fe7.1780670224.git.andrea.porta@suse.com>
On Fri, Jun 12, 2026 at 04:01:27PM +0200, Andrea della Porta wrote:
> From: Naushir Patuck <naush@raspberrypi.com>
>
> The Raspberry Pi RP1 southbridge features an embedded PWM
> controller with 4 output channels, alongside an RPM interface
> to read the fan speed on the Raspberry Pi 5.
>
> Add the supporting driver.
>
> Signed-off-by: Naushir Patuck <naush@raspberrypi.com>
> Co-developed-by: Stanimir Varbanov <svarbanov@suse.de>
> Signed-off-by: Stanimir Varbanov <svarbanov@suse.de>
> Signed-off-by: Andrea della Porta <andrea.porta@suse.com>
> ---
> drivers/pwm/Kconfig | 9 +
> drivers/pwm/Makefile | 1 +
> drivers/pwm/pwm-rp1.c | 424 ++++++++++++++++++++++++++++++++++++++++++
> 3 files changed, 434 insertions(+)
> create mode 100644 drivers/pwm/pwm-rp1.c
>
> diff --git a/drivers/pwm/Kconfig b/drivers/pwm/Kconfig
> index 6f3147518376a..c3ddc0eb4774f 100644
> --- a/drivers/pwm/Kconfig
> +++ b/drivers/pwm/Kconfig
> @@ -625,6 +625,15 @@ config PWM_ROCKCHIP
> Generic PWM framework driver for the PWM controller found on
> Rockchip SoCs.
>
> +config PWM_RASPBERRYPI_RP1
> + tristate "RP1 PWM support"
> + depends on MISC_RP1 || COMPILE_TEST
> + depends on HAS_IOMEM
> + select REGMAP_MMIO
> + select MFD_SYSCON
> + help
> + PWM framework driver for Raspberry Pi RP1 controller.
> +
> config PWM_SAMSUNG
> tristate "Samsung PWM support"
> depends on PLAT_SAMSUNG || ARCH_S5PV210 || ARCH_EXYNOS || COMPILE_TEST
> diff --git a/drivers/pwm/Makefile b/drivers/pwm/Makefile
> index 0dc0d2b69025d..59f29f60f9123 100644
> --- a/drivers/pwm/Makefile
> +++ b/drivers/pwm/Makefile
> @@ -56,6 +56,7 @@ obj-$(CONFIG_PWM_RENESAS_RZG2L_GPT) += pwm-rzg2l-gpt.o
> obj-$(CONFIG_PWM_RENESAS_RZ_MTU3) += pwm-rz-mtu3.o
> obj-$(CONFIG_PWM_RENESAS_TPU) += pwm-renesas-tpu.o
> obj-$(CONFIG_PWM_ROCKCHIP) += pwm-rockchip.o
> +obj-$(CONFIG_PWM_RASPBERRYPI_RP1) += pwm-rp1.o
> obj-$(CONFIG_PWM_SAMSUNG) += pwm-samsung.o
> obj-$(CONFIG_PWM_SIFIVE) += pwm-sifive.o
> obj-$(CONFIG_PWM_SL28CPLD) += pwm-sl28cpld.o
> diff --git a/drivers/pwm/pwm-rp1.c b/drivers/pwm/pwm-rp1.c
> new file mode 100644
> index 0000000000000..6382a81a5ea0f
> --- /dev/null
> +++ b/drivers/pwm/pwm-rp1.c
> @@ -0,0 +1,424 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * pwm-rp1.c
> + *
> + * Raspberry Pi RP1 PWM.
> + *
> + * Copyright © 2026 Raspberry Pi Ltd.
> + *
> + * Author: Naushir Patuck (naush@raspberrypi.com)
> + *
> + * Based on the pwm-bcm2835 driver by:
> + * Bart Tanghe <bart.tanghe@thomasmore.be>
> + *
> + * Datasheet: https://pip-assets.raspberrypi.com/categories/892-raspberry-pi-5/documents/RP-008370-DS-1-rp1-peripherals.pdf?disposition=inline
> + *
> + * Limitations:
> + * - Channels can be enabled/disabled through a global update flag, while the
> + * period and duty per-channel registers are independently updatable, and
> + * they are latched on the end of (specific channel) period strobe.
> + * This means that period and duty changes might result in glitches if the
> + * period/duty is changed exactly during an end of period strobe.
> + * - Since the duty/period registers are freely updatable (do not depend on
> + * the global update flag), setting one of them close to the period end and
> + * the other right afterwards results in a mixed output for that cycle because
> + * the write ops are not atomic.
> + * - The global update flag prevents mis-sampling of multi-bit bus signals in
> + * the PWM clock domain. This ensures that all PWM channel settings update
> + * on the same PWM clock cycle. Channels start in sync only if they share the
> + * same period.
> + * - If both duty and period are set to 0, the output is a constant low signal
> + * if polarity is normal or a constant high signal if polarity is inversed.
> + * - When disabled the output is driven to 0 if polarity is normal, or to 1
> + * if polarity is inversed.
> + * - Disabling the PWM stops the output immediately, without waiting for current
> + * period to complete first.
> + * - Channels are phase-capable, but on RPi5, the firmware can use a channel
> + * phase register to report the RPM of the fan connected to that PWM
> + * channel. As a result, phase control will be ignored for now.
> + */
> +
> +#include <linux/bitops.h>
> +#include <linux/clk.h>
> +#include <linux/err.h>
> +#include <linux/io.h>
> +#include <linux/module.h>
> +#include <linux/of.h>
> +#include <linux/platform_device.h>
> +#include <linux/pwm.h>
> +#include <linux/regmap.h>
> +#include <linux/mfd/syscon.h>
> +#include <linux/units.h>
> +
> +#define RP1_PWM_GLB_CTRL 0x000
> +#define RP1_PWM_GLB_CTRL_CHANNEL_ENABLE(chan) BIT(chan)
> +#define RP1_PWM_GLB_CTRL_SET_UPDATE BIT(31)
> +
> +#define RP1_PWM_CHAN_CTRL(chan) (0x014 + ((chan) * 0x10))
> +#define RP1_PWM_CHAN_CTRL_POLARITY BIT(3)
> +#define RP1_PWM_CHAN_CTRL_FIFO_POP_MASK BIT(8)
> +#define RP1_PWM_CHAN_CTRL_MODE GENMASK(2, 0)
> +enum rp1_pwm_ctrl_mode {
> + RP1_PWM_CHAN_CTRL_MODE_ZERO,
> + RP1_PWM_CHAN_CTRL_MODE_TE_MS,
> + RP1_PWM_CHAN_CTRL_MODE_PC_MS,
> + RP1_PWM_CHAN_CTRL_MODE_PD_ENC,
> + RP1_PWM_CHAN_CTRL_MODE_MSB_SER,
> + RP1_PWM_CHAN_CTRL_MODE_PPM,
> + RP1_PWM_CHAN_CTRL_MODE_LE_MS,
> + RP1_PWM_CHAN_CTRL_MODE_LSB_SER,
> +};
> +
> +#define RP1_PWM_CHAN_CTRL_DEFAULT (RP1_PWM_CHAN_CTRL_FIFO_POP_MASK + \
> + FIELD_PREP(RP1_PWM_CHAN_CTRL_MODE, \
> + RP1_PWM_CHAN_CTRL_MODE_TE_MS))
> +
> +#define RP1_PWM_RANGE(chan) (0x018 + ((chan) * 0x10))
> +#define RP1_PWM_PHASE(chan) (0x01C + ((chan) * 0x10))
> +#define RP1_PWM_DUTY(chan) (0x020 + ((chan) * 0x10))
> +
> +#define RP1_PWM_NUM_PWMS 4
> +
> +struct rp1_pwm {
> + struct regmap *regmap;
> + struct clk *clk;
> + unsigned long clk_rate;
> + bool clk_enabled;
I don't understand the point of the clk_enabled field. If the probe
function succeeds, then clk_enabled = true. It is set to false during
suspend, but after suspend the only thing which can follow is resume,
I think. In resume, we set it in to true again unconditionally. So
it is always true, no?
> +};
> +
> +struct rp1_pwm_waveform {
> + u32 period_ticks;
> + u32 duty_ticks;
> + bool enabled;
> + bool inverted_polarity;
> +};
> +
> +static const struct regmap_config rp1_pwm_regmap_config = {
> + .reg_bits = 32,
> + .val_bits = 32,
> + .reg_stride = 4,
> + .max_register = 0x60,
> +};
> +
> +static void rp1_pwm_apply_config(struct pwm_chip *chip, struct pwm_device *pwm)
> +{
> + struct rp1_pwm *rp1 = pwmchip_get_drvdata(chip);
> + u32 value;
> +
> + /* update the changed registers on the next strobe to avoid glitches */
> + regmap_read(rp1->regmap, RP1_PWM_GLB_CTRL, &value);
> + value |= RP1_PWM_GLB_CTRL_SET_UPDATE;
> + regmap_write(rp1->regmap, RP1_PWM_GLB_CTRL, value);
> +}
> +
> +static int rp1_pwm_request(struct pwm_chip *chip, struct pwm_device *pwm)
> +{
> + struct rp1_pwm *rp1 = pwmchip_get_drvdata(chip);
> +
> + /* init channel to reset defaults, preserving the polarity bit */
> + regmap_update_bits(rp1->regmap, RP1_PWM_CHAN_CTRL(pwm->hwpwm),
> + ~(u32)RP1_PWM_CHAN_CTRL_POLARITY, RP1_PWM_CHAN_CTRL_DEFAULT);
> + return 0;
> +}
> +
> +static int rp1_pwm_round_waveform_tohw(struct pwm_chip *chip,
> + struct pwm_device *pwm,
> + const struct pwm_waveform *wf,
> + void *_wfhw)
> +{
> + struct rp1_pwm *rp1 = pwmchip_get_drvdata(chip);
> + u64 period_ticks, duty_ticks, offset_ticks;
> + struct rp1_pwm_waveform *wfhw = _wfhw;
> + u64 clk_rate = rp1->clk_rate;
> + int ret = 0;
> +
> + if (!wf->period_length_ns) {
> + wfhw->enabled = false;
> + return 0;
> + }
> +
> + period_ticks = mul_u64_u64_div_u64(wf->period_length_ns, clk_rate, NSEC_PER_SEC);
> +
> + /*
> + * The period is limited to U32_MAX, and it will be decremented by one later
> + * to allow 100% duty cycle.
> + */
> + if (period_ticks > U32_MAX) {
> + period_ticks = U32_MAX;
> + } else if (period_ticks < 2) {
> + period_ticks = 2;
> + ret = 1;
> + }
period_ticks = clamp(period_ticks, 2, U32_MAX);
Although that misses out the `ret = 1;` which I am not sure about anyway.
> +
> + duty_ticks = mul_u64_u64_div_u64(wf->duty_length_ns, clk_rate, NSEC_PER_SEC);
> + duty_ticks = min(duty_ticks, period_ticks);
> + offset_ticks = mul_u64_u64_div_u64(wf->duty_offset_ns, clk_rate, NSEC_PER_SEC);
> + if (offset_ticks >= period_ticks)
> + offset_ticks %= period_ticks;
> + if (duty_ticks && offset_ticks &&
> + duty_ticks + offset_ticks >= period_ticks) {
> + wfhw->duty_ticks = period_ticks - duty_ticks;
> + wfhw->inverted_polarity = true;
> + } else {
> + wfhw->duty_ticks = duty_ticks;
> + wfhw->inverted_polarity = false;
> + }
> + /* Account for the extra tick at the end of the period */
> + wfhw->period_ticks = period_ticks - 1;
> +
> + wfhw->enabled = true;
> +
> + return ret;
> +}
> +
> +static int rp1_pwm_round_waveform_fromhw(struct pwm_chip *chip,
> + struct pwm_device *pwm,
> + const void *_wfhw,
> + struct pwm_waveform *wf)
> +{
> + struct rp1_pwm *rp1 = pwmchip_get_drvdata(chip);
> + const struct rp1_pwm_waveform *wfhw = _wfhw;
> + u64 clk_rate = rp1->clk_rate;
> + u64 ticks;
> +
> + *wf = (struct pwm_waveform){ };
> +
> + if (!wfhw->enabled)
> + return 0;
> +
> + wf->period_length_ns = DIV_ROUND_UP_ULL(((u64)wfhw->period_ticks + 1) * NSEC_PER_SEC,
> + clk_rate);
> +
> + if (!wfhw->inverted_polarity) {
> + wf->duty_length_ns = DIV_ROUND_UP_ULL((u64)wfhw->duty_ticks * NSEC_PER_SEC,
> + clk_rate);
> + } else {
> + ticks = (u64)wfhw->period_ticks + 1 - wfhw->duty_ticks;
> + wf->duty_length_ns = DIV_ROUND_UP_ULL(ticks * NSEC_PER_SEC, clk_rate);
> + wf->duty_offset_ns = wf->period_length_ns - wf->duty_length_ns;
> + }
> +
> + return 0;
> +}
> +
> +static int rp1_pwm_write_waveform(struct pwm_chip *chip,
> + struct pwm_device *pwm,
> + const void *_wfhw)
> +{
> + struct rp1_pwm *rp1 = pwmchip_get_drvdata(chip);
> + const struct rp1_pwm_waveform *wfhw = _wfhw;
> + u32 value, ctrl;
> +
> + /* set polarity */
> + regmap_read(rp1->regmap, RP1_PWM_CHAN_CTRL(pwm->hwpwm), &value);
> + if (!wfhw->inverted_polarity)
> + value &= ~RP1_PWM_CHAN_CTRL_POLARITY;
> + else
> + value |= RP1_PWM_CHAN_CTRL_POLARITY;
> + regmap_write(rp1->regmap, RP1_PWM_CHAN_CTRL(pwm->hwpwm), value);
> +
> + /* early exit if disabled */
> + regmap_read(rp1->regmap, RP1_PWM_GLB_CTRL, &ctrl);
> + if (!wfhw->enabled) {
> + ctrl &= ~RP1_PWM_GLB_CTRL_CHANNEL_ENABLE(pwm->hwpwm);
> + goto exit_disable;
> + }
> +
> + /* set period and duty cycle */
> + regmap_write(rp1->regmap,
> + RP1_PWM_RANGE(pwm->hwpwm), wfhw->period_ticks);
> + regmap_write(rp1->regmap,
> + RP1_PWM_DUTY(pwm->hwpwm), wfhw->duty_ticks);
> +
> + /* enable the channel */
> + ctrl |= RP1_PWM_GLB_CTRL_CHANNEL_ENABLE(pwm->hwpwm);
> +exit_disable:
> + regmap_write(rp1->regmap, RP1_PWM_GLB_CTRL, ctrl);
> +
> + rp1_pwm_apply_config(chip, pwm);
> +
> + return 0;
> +}
> +
> +static int rp1_pwm_read_waveform(struct pwm_chip *chip,
> + struct pwm_device *pwm,
> + void *_wfhw)
> +{
> + struct rp1_pwm *rp1 = pwmchip_get_drvdata(chip);
> + struct rp1_pwm_waveform *wfhw = _wfhw;
> + u32 value;
> +
> + regmap_read(rp1->regmap, RP1_PWM_GLB_CTRL, &value);
> + wfhw->enabled = !!(value & RP1_PWM_GLB_CTRL_CHANNEL_ENABLE(pwm->hwpwm));
> +
> + regmap_read(rp1->regmap, RP1_PWM_CHAN_CTRL(pwm->hwpwm), &value);
> + wfhw->inverted_polarity = !!(value & RP1_PWM_CHAN_CTRL_POLARITY);
> +
> + if (wfhw->enabled) {
> + regmap_read(rp1->regmap, RP1_PWM_RANGE(pwm->hwpwm), &wfhw->period_ticks);
> + regmap_read(rp1->regmap, RP1_PWM_DUTY(pwm->hwpwm), &wfhw->duty_ticks);
> + } else {
> + wfhw->period_ticks = 0;
> + wfhw->duty_ticks = 0;
> + }
> +
> + return 0;
> +}
> +
> +static const struct pwm_ops rp1_pwm_ops = {
> + .sizeof_wfhw = sizeof(struct rp1_pwm_waveform),
> + .request = rp1_pwm_request,
> + .round_waveform_tohw = rp1_pwm_round_waveform_tohw,
> + .round_waveform_fromhw = rp1_pwm_round_waveform_fromhw,
> + .read_waveform = rp1_pwm_read_waveform,
> + .write_waveform = rp1_pwm_write_waveform,
> +};
> +
> +static int rp1_pwm_probe(struct platform_device *pdev)
> +{
> + struct device *dev = &pdev->dev;
> + struct device_node *np = dev->of_node;
> + unsigned long clk_rate;
> + struct pwm_chip *chip;
> + void __iomem *base;
> + struct rp1_pwm *rp1;
> + int ret;
> +
> + chip = devm_pwmchip_alloc(dev, RP1_PWM_NUM_PWMS, sizeof(*rp1));
> + if (IS_ERR(chip))
> + return PTR_ERR(chip);
> +
> + rp1 = pwmchip_get_drvdata(chip);
> +
> + base = devm_platform_ioremap_resource(pdev, 0);
> + if (IS_ERR(base))
> + return PTR_ERR(base);
> +
> + rp1->regmap = devm_regmap_init_mmio(dev, base, &rp1_pwm_regmap_config);
> + if (IS_ERR(rp1->regmap))
> + return dev_err_probe(dev, PTR_ERR(rp1->regmap), "Cannot initialize regmap\n");
> +
> + rp1->clk = devm_clk_get(dev, NULL);
> + if (IS_ERR(rp1->clk))
> + return dev_err_probe(dev, PTR_ERR(rp1->clk), "Clock not found\n");
> +
> + ret = clk_prepare_enable(rp1->clk);
> + if (ret)
> + return dev_err_probe(dev, ret, "Failed to enable clock\n");
> + rp1->clk_enabled = true;
> +
> + ret = devm_clk_rate_exclusive_get(dev, rp1->clk);
> + if (ret) {
> + dev_err_probe(dev, ret, "Failed to get exclusive rate\n");
> + goto err_disable_clk;
> + }
> +
> + clk_rate = clk_get_rate(rp1->clk);
> + if (!clk_rate) {
> + ret = dev_err_probe(dev, -EINVAL, "Failed to get clock rate\n");
> + goto err_disable_clk;
> + }
> + /*
> + * To prevent u64 overflow in period calculations:
> + * mul_u64_u64_div_u64(period_ns, clk_rate, NSEC_PER_SEC)
> + * If clk_rate > 1 GHz, the result can overflow.
> + */
> + if (clk_rate > HZ_PER_GHZ) {
> + ret = dev_err_probe(dev, -EINVAL, "Clock rate > 1 GHz is not supported\n");
> + goto err_disable_clk;
> + }
> + rp1->clk_rate = clk_rate;
> +
> + chip->ops = &rp1_pwm_ops;
Can we add the following please:
chip->atomic = true;
This means that the pwm can be controlled from atomic context (not process
context) using pwm_apply_atomic(). This is very helpful for the pwm-ir-tx
driver, which produces a much more faithful IR signal in atomic context.
Using pwm for infrared tx is much nicer than using gpio which bit bangs
the IR signal and holds the CPU with interrupts disabled for upto one second.
As far as I can see there is no sleeping code in these code paths, so we
should be fine.
Thanks,
Sean
> +
> + platform_set_drvdata(pdev, chip);
> +
> + ret = pwmchip_add(chip);
> + if (ret) {
> + dev_err_probe(dev, ret, "Failed to register PWM chip\n");
> + goto err_disable_clk;
> + }
> +
> + ret = of_syscon_register_regmap(np, rp1->regmap);
> + if (ret) {
> + dev_err_probe(dev, ret, "Failed to register syscon\n");
> + goto err_remove_chip;
> + }
> +
> + return 0;
> +
> +err_remove_chip:
> + pwmchip_remove(chip);
> +err_disable_clk:
> + clk_disable_unprepare(rp1->clk);
> +
> + return ret;
> +}
> +
> +static void rp1_pwm_remove(struct platform_device *pdev)
> +{
> + struct pwm_chip *chip = platform_get_drvdata(pdev);
> + struct rp1_pwm *rp1 = pwmchip_get_drvdata(chip);
> +
> + pwmchip_remove(chip);
> +
> + if (rp1->clk_enabled) {
> + clk_disable_unprepare(rp1->clk);
> + rp1->clk_enabled = false;
> + }
> +}
> +
> +static int rp1_pwm_suspend(struct device *dev)
> +{
> + struct pwm_chip *chip = dev_get_drvdata(dev);
> + struct rp1_pwm *rp1 = pwmchip_get_drvdata(chip);
> +
> + if (rp1->clk_enabled) {
> + clk_disable_unprepare(rp1->clk);
> + rp1->clk_enabled = false;
> + }
> +
> + return 0;
> +}
> +
> +static int rp1_pwm_resume(struct device *dev)
> +{
> + struct pwm_chip *chip = dev_get_drvdata(dev);
> + struct rp1_pwm *rp1 = pwmchip_get_drvdata(chip);
> + int ret;
> +
> + ret = clk_prepare_enable(rp1->clk);
> + if (ret) {
> + dev_err(dev, "Failed to enable clock on resume: %pe\n", ERR_PTR(ret));
> + return ret;
> + }
> +
> + rp1->clk_enabled = true;
> +
> + return 0;
> +}
> +
> +static DEFINE_SIMPLE_DEV_PM_OPS(rp1_pwm_pm_ops, rp1_pwm_suspend, rp1_pwm_resume);
> +
> +static const struct of_device_id rp1_pwm_of_match[] = {
> + { .compatible = "raspberrypi,rp1-pwm" },
> + { /* sentinel */ }
> +};
> +MODULE_DEVICE_TABLE(of, rp1_pwm_of_match);
> +
> +static struct platform_driver rp1_pwm_driver = {
> + .probe = rp1_pwm_probe,
> + .remove = rp1_pwm_remove,
> + .driver = {
> + .name = "rp1-pwm",
> + .of_match_table = rp1_pwm_of_match,
> + .pm = pm_ptr(&rp1_pwm_pm_ops),
> + .suppress_bind_attrs = true,
> + },
> +};
> +builtin_platform_driver(rp1_pwm_driver);
> +
> +MODULE_DESCRIPTION("RP1 PWM driver");
> +MODULE_AUTHOR("Naushir Patuck <naush@raspberrypi.com>");
> +MODULE_AUTHOR("Andrea della Porta <andrea.porta@suse.com>");
> +MODULE_LICENSE("GPL");
> --
> 2.35.3
>
^ permalink raw reply
* Re: [PATCH] net: macb: add TX stall timeout callback to recover from lost TSTART write
From: Théo Lebrun @ 2026-06-12 14:28 UTC (permalink / raw)
To: Andrea della Porta, Nicolai Buchwitz
Cc: netdev, Nicolas Ferre, Claudiu Beznea, Andrew Lunn,
David S . Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
linux-kernel, linux-arm-kernel, linux-rpi-kernel, Lukasz Raczylo,
Steffen Jaeckel
In-Reply-To: <aiwDsd-1IzeBzcaD@apocalypse>
On Fri Jun 12, 2026 at 3:03 PM CEST, Andrea della Porta wrote:
> On 14:53 Fri 12 Jun , Nicolai Buchwitz wrote:
>> On 12.6.2026 14:51, Andrea della Porta wrote:
>> > > The commit message describes it as RP1 specific, but it gets applied
>> > > to all
>> > > other variants?
>> >
>> > I've seen this issue happening only on RaspberryPi 5, but AFAIK it
>> > could affect also other MACB blocks connected through PCIe, so it
>> > may be widespread (even though it should have probably already been
>> > noticed in the past). In the orginal driver there's no timeout callback
>> > defined and this is much like pretgending the issue causing the timeout
>> > to happen to go away without doing anything (whatever the cause ot the
>> > specific hw are). So in my opinion we can just extend that to all MACB.
>> > Or maybe we should execute the restart conditionally on
>> > .compatible = "raspberrypi,rp1-gem"?
>>
>> I just observed the issue once, but other people reported it to be happen
>> more
>> frequently. If we can narrow down a reproducer, it would be good to test on
>> other
>> blocks too (like EyeQ at Théo's).|
>>
>> So maybe you can imagine a good repro for this issue?
>
> Sure, it's happening quite often during bulk dataflow, at least
> on my RPi5.
> It can be reproduced with the following, issued from the DUT:
>
> iperf -c <SERVER_IP> -P 10 -t 3000 -w 4M -i 1
>
> plus, of course, the related command on server side: iperf -s.
>
> It usually happens a couple of times withing a few hours.
Thanks for the reproducer command; I'll run it next week.
I'd be surprised if it reproduced on hardware that isn't the Pi 5.
Thanks,
--
Théo Lebrun, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com
^ permalink raw reply
* [PATCH v1 4/4] KVM: arm64: Add hyp_printk event to nVHE/pKVM hyp
From: Vincent Donnefort @ 2026-06-12 14:22 UTC (permalink / raw)
To: maz, oliver.upton, joey.gouly, suzuki.poulose, yuzenghui,
catalin.marinas, will, rostedt
Cc: linux-arm-kernel, kvmarm, kernel-team, tabba, qerret,
Vincent Donnefort
In-Reply-To: <20260612142245.1015744-1-vdonnefort@google.com>
Create an event to allow developers to log pretty much anything into the
hypervisor tracing buffer with trace_hyp_printk(), just like the kernel
tracing has the function trace_printk().
trace_hyp_printk("foobar");
trace_hyp_printk("foo=%d", foo);
trace_hyp_printk("foo=%d bar=0x%016llx", foo, bar);
To ensure writing into the tracing buffer is fast, store the string
format into a kernel-accessible ELF section. The hypervisor only has to
write into the event the string ID, which is the delta between the
hyp_string_fmt and the start of the ELF section.
To not waste tracing buffer data, use a dynamic size. Each
argument is 8 bytes and the in-kernel printing function can simply know
how many of them there are by looking at the event length.
Signed-off-by: Vincent Donnefort <vdonnefort@google.com>
diff --git a/arch/arm64/include/asm/kvm_hypevents.h b/arch/arm64/include/asm/kvm_hypevents.h
index 743c49bd878f..8465b523cb1d 100644
--- a/arch/arm64/include/asm/kvm_hypevents.h
+++ b/arch/arm64/include/asm/kvm_hypevents.h
@@ -57,4 +57,18 @@ HYP_EVENT(selftest,
),
RE_PRINTK("id=%llu", __entry->id)
);
+
+/*
+ * trace_hyp_printk() has too many specificities to be declared with HYP_EVENT().
+ * However, we can use a REMOTE_EVENT macro to automatically do the declaration
+ * for the kernel side.
+ */
+REMOTE_EVENT_CUSTOM_PRINTK(hyp_printk,
+ 0, /* id will be overwritten during hyp event init */
+ RE_STRUCT(
+ re_field(u16, fmt_id)
+ re_field(u64, args[])
+ ),
+ __hyp_trace_printk(evt, seq)
+);
#endif
diff --git a/arch/arm64/include/asm/kvm_hyptrace.h b/arch/arm64/include/asm/kvm_hyptrace.h
index de133b735f72..46097105fdd8 100644
--- a/arch/arm64/include/asm/kvm_hyptrace.h
+++ b/arch/arm64/include/asm/kvm_hyptrace.h
@@ -23,4 +23,12 @@ extern struct remote_event __hyp_events_end[];
extern struct hyp_event_id __hyp_event_ids_start[];
extern struct hyp_event_id __hyp_event_ids_end[];
+#define HYP_STRING_FMT_MAX_SIZE 128
+
+struct hyp_string_fmt {
+ const char fmt[HYP_STRING_FMT_MAX_SIZE];
+};
+
+extern struct hyp_string_fmt __hyp_string_fmts_start[];
+extern struct hyp_string_fmt __hyp_string_fmts_end[];
#endif
diff --git a/arch/arm64/kernel/image-vars.h b/arch/arm64/kernel/image-vars.h
index d4c7d45ae6bc..ec03621d7a81 100644
--- a/arch/arm64/kernel/image-vars.h
+++ b/arch/arm64/kernel/image-vars.h
@@ -141,6 +141,7 @@ KVM_NVHE_ALIAS(__hyp_rodata_end);
#ifdef CONFIG_NVHE_EL2_TRACING
KVM_NVHE_ALIAS(__hyp_event_ids_start);
KVM_NVHE_ALIAS(__hyp_event_ids_end);
+KVM_NVHE_ALIAS(__hyp_string_fmts_start);
#endif
/* pKVM static key */
diff --git a/arch/arm64/kernel/vmlinux.lds.S b/arch/arm64/kernel/vmlinux.lds.S
index e1ac876200a3..b6d62642b6bd 100644
--- a/arch/arm64/kernel/vmlinux.lds.S
+++ b/arch/arm64/kernel/vmlinux.lds.S
@@ -324,6 +324,10 @@ SECTIONS
__hyp_events_start = .;
*(SORT(_hyp_events.*))
__hyp_events_end = .;
+
+ __hyp_string_fmts_start = .;
+ *(_hyp_string_fmts)
+ __hyp_string_fmts_end = .;
}
#endif
/*
diff --git a/arch/arm64/kvm/hyp/include/nvhe/define_events.h b/arch/arm64/kvm/hyp/include/nvhe/define_events.h
index 776d4c6cb702..370e8c2d39fe 100644
--- a/arch/arm64/kvm/hyp/include/nvhe/define_events.h
+++ b/arch/arm64/kvm/hyp/include/nvhe/define_events.h
@@ -10,5 +10,3 @@
#define HYP_EVENT_MULTI_READ
#include <asm/kvm_hypevents.h>
#undef HYP_EVENT_MULTI_READ
-
-#undef HYP_EVENT
diff --git a/arch/arm64/kvm/hyp/include/nvhe/trace.h b/arch/arm64/kvm/hyp/include/nvhe/trace.h
index 8813ff250f8e..3d0b5c634bb3 100644
--- a/arch/arm64/kvm/hyp/include/nvhe/trace.h
+++ b/arch/arm64/kvm/hyp/include/nvhe/trace.h
@@ -46,6 +46,69 @@ static inline pid_t __tracing_get_vcpu_pid(struct kvm_cpu_context *host_ctxt)
void *tracing_reserve_entry(unsigned long length);
void tracing_commit_entry(void);
+/*
+ * The trace_hyp_printk boilerplate is too fiddly to be declared with
+ * HYP_EVENT():
+ *
+ * The string format is stored into a kernel-accessible ELF section. The
+ * hypervisor only writes the format ID.
+ *
+ * The function has a variadic prototype. We have no easy way to know each
+ * argument width so they must all cast to u64.
+ */
+#define REMOTE_EVENT_CUSTOM_PRINTK(...)
+
+#define __TO_U64_0()
+#define __TO_U64_1(x) , (u64)(x)
+#define __TO_U64_2(x, ...) , (u64)(x) __TO_U64_1(__VA_ARGS__)
+#define __TO_U64_3(x, ...) , (u64)(x) __TO_U64_2(__VA_ARGS__)
+#define __TO_U64_4(x, ...) , (u64)(x) __TO_U64_3(__VA_ARGS__)
+#define __TO_U64_5(x, ...) , (u64)(x) __TO_U64_4(__VA_ARGS__)
+#define __TO_U64_6(x, ...) , (u64)(x) __TO_U64_5(__VA_ARGS__)
+#define __TO_U64_7(x, ...) , (u64)(x) __TO_U64_6(__VA_ARGS__)
+#define __TO_U64_8(x, ...) , (u64)(x) __TO_U64_7(__VA_ARGS__)
+
+#define __TO_U64_X(N, ...) CONCATENATE(__TO_U64_, N)(__VA_ARGS__)
+#define __TO_U64(...) __TO_U64_X(COUNT_ARGS(__VA_ARGS__), ##__VA_ARGS__)
+
+REMOTE_EVENT_FORMAT(hyp_printk, HE_STRUCT(he_field(u16, fmt_id) he_field(u64, args[])));
+extern struct hyp_event_id hyp_event_id_hyp_printk;
+
+static __always_inline void __trace_hyp_printk(struct hyp_string_fmt *fmt, int nr_args, ...)
+{
+ struct remote_event_format_hyp_printk *entry;
+ va_list va;
+ int i;
+
+ if (!atomic_read(&hyp_event_id_hyp_printk.enabled))
+ return;
+
+ entry = tracing_reserve_entry(struct_size(entry, args, nr_args));
+ if (!entry)
+ return;
+
+ entry->hdr.id = hyp_event_id_hyp_printk.id;
+ entry->fmt_id = fmt - __hyp_string_fmts_start;
+
+ va_start(va, nr_args);
+ for (i = 0; i < nr_args; i++)
+ entry->args[i] = va_arg(va, u64);
+ va_end(va);
+
+ tracing_commit_entry();
+}
+
+
+#define trace_hyp_printk(__fmt, __args...) \
+do { \
+ static struct hyp_string_fmt __used __section("_hyp_string_fmts") fmt = { \
+ .fmt = __fmt \
+ }; \
+ BUILD_BUG_ON(sizeof(__fmt) > HYP_STRING_FMT_MAX_SIZE); \
+ /* __TO_U64 prepends a comma if there are arguments */ \
+ __trace_hyp_printk(&fmt, COUNT_ARGS(__args) __TO_U64(__args)); \
+} while (0)
+
int __tracing_load(unsigned long desc_va, size_t desc_size);
void __tracing_unload(void);
int __tracing_enable(bool enable);
@@ -58,6 +121,8 @@ static inline void *tracing_reserve_entry(unsigned long length) { return NULL; }
static inline void tracing_commit_entry(void) { }
#define HYP_EVENT(__name, __proto, __struct, __assign, __printk) \
static inline void trace_##__name(__proto) {}
+#define REMOTE_EVENT_CUSTOM_PRINTK(...)
+#define trace_hyp_printk(fmt, args...) do { } while (0)
static inline int __tracing_load(unsigned long desc_va, size_t desc_size) { return -ENODEV; }
static inline void __tracing_unload(void) { }
diff --git a/arch/arm64/kvm/hyp/nvhe/events.c b/arch/arm64/kvm/hyp/nvhe/events.c
index add9383aadb5..12223d2e3618 100644
--- a/arch/arm64/kvm/hyp/nvhe/events.c
+++ b/arch/arm64/kvm/hyp/nvhe/events.c
@@ -9,6 +9,12 @@
#include <nvhe/define_events.h>
+/*
+ * The hyp_printk event is not declared with HYP_EVENT in kvm_hypevents.h,
+ * so we manually add the boilerplate here.
+ */
+HYP_EVENT(hyp_printk, 0, 0, 0, 0);
+
int __tracing_enable_event(unsigned short id, bool enable)
{
struct hyp_event_id *event_id = &__hyp_event_ids_start[id];
diff --git a/arch/arm64/kvm/hyp_trace.c b/arch/arm64/kvm/hyp_trace.c
index 821bc93ecdd1..187a8a295d6f 100644
--- a/arch/arm64/kvm/hyp_trace.c
+++ b/arch/arm64/kvm/hyp_trace.c
@@ -391,6 +391,9 @@ static struct trace_remote_callbacks trace_remote_callbacks = {
static const char *__hyp_enter_exit_reason_str(u8 reason);
+struct remote_event_format_hyp_printk;
+static void __hyp_trace_printk(struct remote_event_format_hyp_printk *entry, struct trace_seq *seq);
+
#include "define_hypevents.h"
static const char *__hyp_enter_exit_reason_str(u8 reason)
@@ -409,6 +412,61 @@ static const char *__hyp_enter_exit_reason_str(u8 reason)
return strs[min(reason, HYP_REASON_UNKNOWN)];
}
+static void __hyp_trace_printk(struct remote_event_format_hyp_printk *entry, struct trace_seq *seq)
+{
+ const char *fmt = (const char *)(&__hyp_string_fmts_start[entry->fmt_id]);
+ struct ring_buffer_event *evt = (void *)entry - RB_EVNT_HDR_SIZE;
+ int nr_args;
+
+ trace_seq_putc(seq, ' ');
+
+ if ((void *)fmt >= (void *)__hyp_string_fmts_end) {
+ trace_seq_printf(seq, "Unknown hyp_string_fmt ID %d\n", entry->fmt_id);
+ return;
+ }
+
+ nr_args = (ring_buffer_event_length(evt) -
+ offsetof(struct remote_event_format_hyp_printk, args)) / sizeof(entry->args[0]);
+ switch (nr_args) {
+ case 0:
+ trace_seq_printf(seq, fmt);
+ break;
+ case 1:
+ trace_seq_printf(seq, fmt, entry->args[0]);
+ break;
+ case 2:
+ trace_seq_printf(seq, fmt, entry->args[0], entry->args[1]);
+ break;
+ case 3:
+ trace_seq_printf(seq, fmt, entry->args[0], entry->args[1], entry->args[2]);
+ break;
+ case 4:
+ trace_seq_printf(seq, fmt, entry->args[0], entry->args[1], entry->args[2],
+ entry->args[3]);
+ break;
+ case 5:
+ trace_seq_printf(seq, fmt, entry->args[0], entry->args[1], entry->args[2],
+ entry->args[3], entry->args[4]);
+ break;
+ case 6:
+ trace_seq_printf(seq, fmt, entry->args[0], entry->args[1], entry->args[2],
+ entry->args[3], entry->args[4], entry->args[5]);
+ break;
+ case 7:
+ trace_seq_printf(seq, fmt, entry->args[0], entry->args[1], entry->args[2],
+ entry->args[3], entry->args[4], entry->args[5], entry->args[6]);
+ break;
+ default:
+ trace_seq_printf(seq, fmt, entry->args[0], entry->args[1],
+ entry->args[2], entry->args[3], entry->args[4], entry->args[5],
+ entry->args[6], entry->args[7]);
+ break;
+ }
+
+ if (seq->buffer[trace_seq_used(seq) - 1] != '\n')
+ trace_seq_putc(seq, '\n');
+}
+
static void __init hyp_trace_init_events(void)
{
struct hyp_event_id *hyp_event_id = __hyp_event_ids_start;
--
2.54.0.1136.gdb2ca164c4-goog
^ permalink raw reply related
* [PATCH v1 1/4] KVM: arm64: Allow early calls to pKVM host_share/unshare_hyp
From: Vincent Donnefort @ 2026-06-12 14:22 UTC (permalink / raw)
To: maz, oliver.upton, joey.gouly, suzuki.poulose, yuzenghui,
catalin.marinas, will, rostedt
Cc: linux-arm-kernel, kvmarm, kernel-team, tabba, qerret,
Vincent Donnefort
In-Reply-To: <20260612142245.1015744-1-vdonnefort@google.com>
The hypervisor tracing for pKVM relies on the __pkvm_host_share_hyp and
__pkvm_host_unshare_hyp HVCs. In order to start tracing as early as
possible, allow those two HVCs before the host is deprivileged.
Signed-off-by: Vincent Donnefort <vdonnefort@google.com>
diff --git a/arch/arm64/include/asm/kvm_asm.h b/arch/arm64/include/asm/kvm_asm.h
index 043495f7fc78..fb049c40d04f 100644
--- a/arch/arm64/include/asm/kvm_asm.h
+++ b/arch/arm64/include/asm/kvm_asm.h
@@ -89,12 +89,12 @@ enum __kvm_host_smccc_func {
__KVM_HOST_SMCCC_FUNC___vgic_v3_restore_vmcr_aprs,
__KVM_HOST_SMCCC_FUNC___vgic_v5_save_apr,
__KVM_HOST_SMCCC_FUNC___vgic_v5_restore_vmcr_apr,
+ __KVM_HOST_SMCCC_FUNC___pkvm_host_share_hyp,
+ __KVM_HOST_SMCCC_FUNC___pkvm_host_unshare_hyp,
MARKER(__KVM_HOST_SMCCC_FUNC_PKVM_ONLY),
/* Hypercalls that are available only when pKVM has finalised. */
- __KVM_HOST_SMCCC_FUNC___pkvm_host_share_hyp,
- __KVM_HOST_SMCCC_FUNC___pkvm_host_unshare_hyp,
__KVM_HOST_SMCCC_FUNC___pkvm_host_donate_guest,
__KVM_HOST_SMCCC_FUNC___pkvm_host_share_guest,
__KVM_HOST_SMCCC_FUNC___pkvm_host_unshare_guest,
diff --git a/arch/arm64/kvm/hyp/nvhe/hyp-main.c b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
index 06db299c37a8..f0c52667cf52 100644
--- a/arch/arm64/kvm/hyp/nvhe/hyp-main.c
+++ b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
@@ -721,9 +721,9 @@ static const hcall_t host_hcall[] = {
HANDLE_FUNC(__vgic_v3_restore_vmcr_aprs),
HANDLE_FUNC(__vgic_v5_save_apr),
HANDLE_FUNC(__vgic_v5_restore_vmcr_apr),
-
HANDLE_FUNC(__pkvm_host_share_hyp),
HANDLE_FUNC(__pkvm_host_unshare_hyp),
+
HANDLE_FUNC(__pkvm_host_donate_guest),
HANDLE_FUNC(__pkvm_host_share_guest),
HANDLE_FUNC(__pkvm_host_unshare_guest),
--
2.54.0.1136.gdb2ca164c4-goog
^ permalink raw reply related
* [PATCH v1 3/4] tracing/remotes: Add REMOTE_EVENT_CUSTOM_PRINTK() helper
From: Vincent Donnefort @ 2026-06-12 14:22 UTC (permalink / raw)
To: maz, oliver.upton, joey.gouly, suzuki.poulose, yuzenghui,
catalin.marinas, will, rostedt
Cc: linux-arm-kernel, kvmarm, kernel-team, tabba, qerret,
Vincent Donnefort
In-Reply-To: <20260612142245.1015744-1-vdonnefort@google.com>
The current REMOTE_EVENT() takes as a __printk argument a string format
and a list of arguments, such as RE_STRUCT("foo=%d bar=%d", foo, bar).
Add a REMOTE_EVENT_CUSTOM_PRINTK() where the __printk argument can be a
function. This intends to support the creation of a "printk" event for
the arm64 nVHE/pKVM hypervisor with a dynamic prototype and by extension
a dynamic print format.
Signed-off-by: Vincent Donnefort <vdonnefort@google.com>
diff --git a/include/trace/define_remote_events.h b/include/trace/define_remote_events.h
index 676e803dc144..4f4d58e37b84 100644
--- a/include/trace/define_remote_events.h
+++ b/include/trace/define_remote_events.h
@@ -35,17 +35,26 @@ do { \
#define RE_PRINTK(__args...) __args
-#define REMOTE_EVENT(__name, __id, __struct, __printk) \
- REMOTE_EVENT_FORMAT(__name, __struct); \
+#define REMOTE_EVENT_PRINT_FUNC(__name, __printk) \
static void remote_event_print_##__name(void *evt, struct trace_seq *seq) \
{ \
struct remote_event_format_##__name __maybe_unused *__entry = evt; \
trace_seq_puts(seq, #__name); \
- remote_printk(__printk); \
+ __printk; \
}
+
+#define REMOTE_EVENT(__name, __id, __struct, __printk) \
+ REMOTE_EVENT_FORMAT(__name, __struct); \
+ REMOTE_EVENT_PRINT_FUNC(__name, remote_printk(__printk))
+
+#define REMOTE_EVENT_CUSTOM_PRINTK(__name, __id, __struct, __printk) \
+ REMOTE_EVENT_FORMAT(__name, __struct); \
+ REMOTE_EVENT_PRINT_FUNC(__name, __printk)
+
#include REMOTE_EVENT_INCLUDE(REMOTE_EVENT_INCLUDE_FILE)
#undef REMOTE_EVENT
+#undef REMOTE_EVENT_CUSTOM_PRINTK
#undef RE_PRINTK
#undef re_field
#define re_field(__type, __field) \
@@ -70,4 +79,8 @@ do { \
.print_fmt = remote_event_print_fmt_##__name, \
.print = remote_event_print_##__name, \
}
+
+#define REMOTE_EVENT_CUSTOM_PRINTK(__name, __id, __struct, __printk) \
+ REMOTE_EVENT(__name, __id, RE_STRUCT(__struct), "Unknown")
+
#include REMOTE_EVENT_INCLUDE(REMOTE_EVENT_INCLUDE_FILE)
--
2.54.0.1136.gdb2ca164c4-goog
^ permalink raw reply related
* [PATCH v1 2/4] KVM: arm64: Move kvm_define_hypevents.h to arch/arm64/kvm/
From: Vincent Donnefort @ 2026-06-12 14:22 UTC (permalink / raw)
To: maz, oliver.upton, joey.gouly, suzuki.poulose, yuzenghui,
catalin.marinas, will, rostedt
Cc: linux-arm-kernel, kvmarm, kernel-team, tabba, qerret,
Vincent Donnefort
In-Reply-To: <20260612142245.1015744-1-vdonnefort@google.com>
kvm_define_hypevents.h is used to define the kernel-side structures for
hypervisor events. It doesn't need to be used anywhere else than in
hyp_trace.c.
Move it to arch/arm64/kvm/
Signed-off-by: Vincent Donnefort <vdonnefort@google.com>
diff --git a/arch/arm64/include/asm/kvm_define_hypevents.h b/arch/arm64/kvm/define_hypevents.h
similarity index 100%
rename from arch/arm64/include/asm/kvm_define_hypevents.h
rename to arch/arm64/kvm/define_hypevents.h
diff --git a/arch/arm64/kvm/hyp_trace.c b/arch/arm64/kvm/hyp_trace.c
index c4b3ee552131..821bc93ecdd1 100644
--- a/arch/arm64/kvm/hyp_trace.c
+++ b/arch/arm64/kvm/hyp_trace.c
@@ -391,7 +391,7 @@ static struct trace_remote_callbacks trace_remote_callbacks = {
static const char *__hyp_enter_exit_reason_str(u8 reason);
-#include <asm/kvm_define_hypevents.h>
+#include "define_hypevents.h"
static const char *__hyp_enter_exit_reason_str(u8 reason)
{
--
2.54.0.1136.gdb2ca164c4-goog
^ permalink raw reply related
* [PATCH v1 0/4] trace_hyp_printk() for pKVM/nVHE hypervisor
From: Vincent Donnefort @ 2026-06-12 14:22 UTC (permalink / raw)
To: maz, oliver.upton, joey.gouly, suzuki.poulose, yuzenghui,
catalin.marinas, will, rostedt
Cc: linux-arm-kernel, kvmarm, kernel-team, tabba, qerret,
Vincent Donnefort
Hi all,
This series adds a hypervisor event "hyp_printk" which enables
developers to log pretty much anything into the hypervisor tracing
buffer, just like the kernel function trace_printk().
This enables rich logging from the hypervisor, while leaving all the
string parsing burden to the kernel. This has been the main way of
debugging pKVM in Android.
Even though not strictly related to trace_hyp_printk, I have added the
following two patches:
* KVM: arm64: Allow early calls to pKVM host_share/unshare_hyp
This one mainly intends to support one of the new features I have
posted here [1], which allows to enable tracing as early as
possible. I have added it here to limit cross-posting.
* KVM: arm64: Move kvm_define_hypevents.h to arch/arm64/kvm/
This one is just a cleanup.
[1] https://lore.kernel.org/all/20260605163825.1762953-1-vdonnefort@google.com/
Vincent Donnefort (4):
KVM: arm64: Allow early calls to pKVM host_share/unshare_hyp
KVM: arm64: Move kvm_define_hypevents.h to arch/arm64/kvm/
tracing/remotes: Add REMOTE_EVENT_CUSTOM_PRINTK() helper
KVM: arm64: Add hyp_printk event to nVHE/pKVM hyp
arch/arm64/include/asm/kvm_asm.h | 4 +-
arch/arm64/include/asm/kvm_hypevents.h | 14 ++++
arch/arm64/include/asm/kvm_hyptrace.h | 8 +++
arch/arm64/kernel/image-vars.h | 1 +
arch/arm64/kernel/vmlinux.lds.S | 4 ++
.../define_hypevents.h} | 0
.../kvm/hyp/include/nvhe/define_events.h | 2 -
arch/arm64/kvm/hyp/include/nvhe/trace.h | 65 +++++++++++++++++++
arch/arm64/kvm/hyp/nvhe/events.c | 6 ++
arch/arm64/kvm/hyp/nvhe/hyp-main.c | 2 +-
arch/arm64/kvm/hyp_trace.c | 60 ++++++++++++++++-
include/trace/define_remote_events.h | 19 +++++-
12 files changed, 176 insertions(+), 9 deletions(-)
rename arch/arm64/{include/asm/kvm_define_hypevents.h => kvm/define_hypevents.h} (100%)
base-commit: 4549871118cf616eecdd2d939f78e3b9e1dddc48
--
2.54.0.1136.gdb2ca164c4-goog
^ permalink raw reply
* Re: [PATCH v6 4/6] KVM: arm64: Fix bounds checking in do_ffa_mem_reclaim()
From: Sebastian Ene @ 2026-06-12 14:22 UTC (permalink / raw)
To: Mostafa Saleh
Cc: op-tee, linux-kernel, kvmarm, linux-arm-kernel, maz, oupton,
joey.gouly, suzuki.poulose, catalin.marinas, jens.wiklander,
sumit.garg, vdonnefort, sudeep.holla
In-Reply-To: <20260527150236.1978655-5-smostafa@google.com>
On Wed, May 27, 2026 at 03:02:34PM +0000, Mostafa Saleh wrote:
> Sashiko (locally) reports out of bound write possiblity if SPMD
> returns an invalid data.
>
> While SPMD is considered trusted, pKVM does some basic checks,
> for offset to be less than or equal len.
>
> However, that is incorrect as even if the offset is smaller than
> len pKVM can still access out of bound memory in the next
> ffa_host_unshare_ranges().
>
> Split this check into 2:
> 1- Check that the fixed portion of the descriptor fits.
> 2- After getting reg, check the variable array size addr_range_cnt
> fits.
>
> Also, drop the WARN_ONs as that will panic the kernel and in the
> next checks there are no WARNs, so that makes it consistent.
>
> Fixes: 0a9f15fd5674 ("KVM: arm64: pkvm: Add support for fragmented FF-A descriptors")
> Signed-off-by: Mostafa Saleh <smostafa@google.com>
> ---
> arch/arm64/kvm/hyp/nvhe/ffa.c | 9 +++++++--
> 1 file changed, 7 insertions(+), 2 deletions(-)
>
> diff --git a/arch/arm64/kvm/hyp/nvhe/ffa.c b/arch/arm64/kvm/hyp/nvhe/ffa.c
> index 1af722771178..b6cf9ad82e12 100644
> --- a/arch/arm64/kvm/hyp/nvhe/ffa.c
> +++ b/arch/arm64/kvm/hyp/nvhe/ffa.c
> @@ -607,8 +607,8 @@ static void do_ffa_mem_reclaim(struct arm_smccc_1_2_regs *res,
> * check that we end up with something that doesn't look _completely_
> * bogus.
> */
> - if (WARN_ON(offset > len ||
> - fraglen > KVM_FFA_MBOX_NR_PAGES * PAGE_SIZE)) {
> + if (offset + CONSTITUENTS_OFFSET(0) > len ||
> + fraglen > KVM_FFA_MBOX_NR_PAGES * PAGE_SIZE) {
> ret = FFA_RET_ABORTED;
> ffa_rx_release(res);
> goto out_unlock;
> @@ -641,6 +641,11 @@ static void do_ffa_mem_reclaim(struct arm_smccc_1_2_regs *res,
> goto out_unlock;
>
> reg = (void *)buf + offset;
> + if (offset + CONSTITUENTS_OFFSET(reg->addr_range_cnt) > len) {
> + ret = FFA_RET_ABORTED;
> + goto out_unlock;
> + }
> +
I wonder if we should do this check first and then mem_reclaim, the rational being that if the check fails
the page will be lost forever.
```
reg = (void *)buf + offset;
if (offset + CONSTITUENTS_OFFSET(reg->addr_range_cnt) > len) {
ret = FFA_RET_ABORTED;
goto out_unlock;
}
ffa_mem_reclaim(res, handle_lo, handle_hi, flags);
if (res->a0 != FFA_SUCCESS)
goto out_unlock;
```
> /* If the SPMD was happy, then we should be too. */
> WARN_ON(ffa_host_unshare_ranges(reg->constituents,
> reg->addr_range_cnt));
> --
> 2.54.0.746.g67dd491aae-goog
>
Sebastian
^ permalink raw reply
* Re: [PATCH net-next] net: airoha: better handle MIBs for GDM ports with multiple devs attached
From: Lorenzo Bianconi @ 2026-06-12 14:20 UTC (permalink / raw)
To: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni
Cc: linux-arm-kernel, linux-mediatek, netdev, Christian Marangi
In-Reply-To: <20260611-airoha-eth-multi-serdes-stats-v1-1-42442ae42064@kernel.org>
[-- Attachment #1: Type: text/plain, Size: 9780 bytes --]
> In the context of a GDM port that can have multiple net_devices attached
> (GDM3 and GDM4), the HW counters (MIBs) are global for the GDM port.
> This cause duplicated stats reported to the kernel for the related
> net_device.
> The SoC supports a split MIB feature where each counter is tracked based
> on the relevant HW channel (NBQ) to account for this scenario and
> provide a way to select the related counter on accessing the MIB
> registers.
> Enable this feature for GDM3 and GDM4 and configure the relevant HW
> channel before updating the HW stats to report correct HW counter to the
> kernel for the related interface.
> Move the stats struct from port to dev since HW counter are now specific
> to the network device instead of the GDM port. Refactor
> airoha_update_hw_stats() to take airoha_eth and airoha_gdm_port
> parameters since the function operates on the entire port.
>
> Co-developed-by: Christian Marangi <ansuelsmth@gmail.com>
> Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
> Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
> ---
> drivers/net/ethernet/airoha/airoha_eth.c | 191 +++++++++++++++++--------------
> drivers/net/ethernet/airoha/airoha_eth.h | 7 +-
> 2 files changed, 112 insertions(+), 86 deletions(-)
>
[...]
> - airoha_fe_set(eth, REG_FE_GDM_MIB_CLEAR(port->id),
> +static void airoha_update_hw_stats(struct airoha_gdm_dev *dev)
> +{
> + struct airoha_gdm_port *port = dev->port;
> + int i;
> +
> + spin_lock(&port->stats_lock);
> +
> + for (i = 0; i < ARRAY_SIZE(port->devs); i++) {
> + if (port->devs[i])
> + airoha_dev_get_hw_stats(port->devs[i]);
> + }
> +
> + /* Reset MIB counters */
> + airoha_fe_set(dev->eth, REG_FE_GDM_MIB_CLEAR(port->id),
> FE_GDM_MIB_RX_CLEAR_MASK | FE_GDM_MIB_TX_CLEAR_MASK);
commenting on sashiko's report:
https://netdev-ai.bots.linux.dev/sashiko/#/patchset/20260611-airoha-eth-multi-serdes-stats-v1-1-42442ae42064%40kernel.org
- With split MIB enabled on GDM3/GDM4, airoha_dev_get_hw_stats() programs
REG_FE_GDM_MIB_CFG with the device's nbq before reading per-channel
counters, so the FE_TX_MIB_ID/FE_RX_MIB_ID selector clearly gates the
counter reads.
After the loop in airoha_update_hw_stats(), MIB_CFG retains the last
iterated device's nbq, and a single airoha_fe_set() is issued against
REG_FE_GDM_MIB_CLEAR. REG_FE_GDM_MIB_CLEAR exposes only RX/TX bits with no
separate per-channel selector.
If, as is typical of split-MIB designs, the clear honors the same
FE_TX_MIB_ID/FE_RX_MIB_ID selector used for reads, will only the last
iterated device's HW counters be cleared each cycle?
Since airoha_dev_get_hw_stats() accumulates with += on each read, would
the un-cleared HW counters of the other devs keep being re-added to
dev->stats on every fetch, yielding inflated stats and eventual HW
counter overflow?
Would moving the MIB_CLEAR write inside the per-device loop, while that
device's nbq is still selected in MIB_CFG, address this if the clear is
indeed per-channel? Or can the datasheet confirm REG_FE_GDM_MIB_CLEAR is
strictly global and unaffected by split mode?
- This is the same report available in [0].
REG_FE_GDM_MIB_CLEAR is global and it clears all nbq counters for the port.
Regards,
Lorenzo
[0] https://sashiko.dev/#/patchset/20260611-airoha-eth-multi-serdes-stats-v1-1-42442ae42064%40kernel.org
>
> - u64_stats_update_end(&port->stats.syncp);
> - spin_unlock(&port->stats.lock);
> + spin_unlock(&port->stats_lock);
> }
>
> static int airoha_dev_open(struct net_device *netdev)
> @@ -2043,23 +2071,22 @@ static void airoha_dev_get_stats64(struct net_device *netdev,
> struct rtnl_link_stats64 *storage)
> {
> struct airoha_gdm_dev *dev = netdev_priv(netdev);
> - struct airoha_gdm_port *port = dev->port;
> unsigned int start;
>
> airoha_update_hw_stats(dev);
> do {
> - start = u64_stats_fetch_begin(&port->stats.syncp);
> - storage->rx_packets = port->stats.rx_ok_pkts;
> - storage->tx_packets = port->stats.tx_ok_pkts;
> - storage->rx_bytes = port->stats.rx_ok_bytes;
> - storage->tx_bytes = port->stats.tx_ok_bytes;
> - storage->multicast = port->stats.rx_multicast;
> - storage->rx_errors = port->stats.rx_errors;
> - storage->rx_dropped = port->stats.rx_drops;
> - storage->tx_dropped = port->stats.tx_drops;
> - storage->rx_crc_errors = port->stats.rx_crc_error;
> - storage->rx_over_errors = port->stats.rx_over_errors;
> - } while (u64_stats_fetch_retry(&port->stats.syncp, start));
> + start = u64_stats_fetch_begin(&dev->stats.syncp);
> + storage->rx_packets = dev->stats.rx_ok_pkts;
> + storage->tx_packets = dev->stats.tx_ok_pkts;
> + storage->rx_bytes = dev->stats.rx_ok_bytes;
> + storage->tx_bytes = dev->stats.tx_ok_bytes;
> + storage->multicast = dev->stats.rx_multicast;
> + storage->rx_errors = dev->stats.rx_errors;
> + storage->rx_dropped = dev->stats.rx_drops;
> + storage->tx_dropped = dev->stats.tx_drops;
> + storage->rx_crc_errors = dev->stats.rx_crc_error;
> + storage->rx_over_errors = dev->stats.rx_over_errors;
> + } while (u64_stats_fetch_retry(&dev->stats.syncp, start));
> }
>
> static int airoha_dev_change_mtu(struct net_device *netdev, int mtu)
> @@ -2310,20 +2337,19 @@ static void airoha_ethtool_get_mac_stats(struct net_device *netdev,
> struct ethtool_eth_mac_stats *stats)
> {
> struct airoha_gdm_dev *dev = netdev_priv(netdev);
> - struct airoha_gdm_port *port = dev->port;
> unsigned int start;
>
> airoha_update_hw_stats(dev);
> do {
> - start = u64_stats_fetch_begin(&port->stats.syncp);
> - stats->FramesTransmittedOK = port->stats.tx_ok_pkts;
> - stats->OctetsTransmittedOK = port->stats.tx_ok_bytes;
> - stats->MulticastFramesXmittedOK = port->stats.tx_multicast;
> - stats->BroadcastFramesXmittedOK = port->stats.tx_broadcast;
> - stats->FramesReceivedOK = port->stats.rx_ok_pkts;
> - stats->OctetsReceivedOK = port->stats.rx_ok_bytes;
> - stats->BroadcastFramesReceivedOK = port->stats.rx_broadcast;
> - } while (u64_stats_fetch_retry(&port->stats.syncp, start));
> + start = u64_stats_fetch_begin(&dev->stats.syncp);
> + stats->FramesTransmittedOK = dev->stats.tx_ok_pkts;
> + stats->OctetsTransmittedOK = dev->stats.tx_ok_bytes;
> + stats->MulticastFramesXmittedOK = dev->stats.tx_multicast;
> + stats->BroadcastFramesXmittedOK = dev->stats.tx_broadcast;
> + stats->FramesReceivedOK = dev->stats.rx_ok_pkts;
> + stats->OctetsReceivedOK = dev->stats.rx_ok_bytes;
> + stats->BroadcastFramesReceivedOK = dev->stats.rx_broadcast;
> + } while (u64_stats_fetch_retry(&dev->stats.syncp, start));
> }
>
> static const struct ethtool_rmon_hist_range airoha_ethtool_rmon_ranges[] = {
> @@ -2343,8 +2369,7 @@ airoha_ethtool_get_rmon_stats(struct net_device *netdev,
> const struct ethtool_rmon_hist_range **ranges)
> {
> struct airoha_gdm_dev *dev = netdev_priv(netdev);
> - struct airoha_gdm_port *port = dev->port;
> - struct airoha_hw_stats *hw_stats = &port->stats;
> + struct airoha_hw_stats *hw_stats = &dev->stats;
> unsigned int start;
>
> BUILD_BUG_ON(ARRAY_SIZE(airoha_ethtool_rmon_ranges) !=
> @@ -2357,7 +2382,7 @@ airoha_ethtool_get_rmon_stats(struct net_device *netdev,
> do {
> int i;
>
> - start = u64_stats_fetch_begin(&port->stats.syncp);
> + start = u64_stats_fetch_begin(&dev->stats.syncp);
> stats->fragments = hw_stats->rx_fragment;
> stats->jabbers = hw_stats->rx_jabber;
> for (i = 0; i < ARRAY_SIZE(airoha_ethtool_rmon_ranges) - 1;
> @@ -2365,7 +2390,7 @@ airoha_ethtool_get_rmon_stats(struct net_device *netdev,
> stats->hist[i] = hw_stats->rx_len[i];
> stats->hist_tx[i] = hw_stats->tx_len[i];
> }
> - } while (u64_stats_fetch_retry(&port->stats.syncp, start));
> + } while (u64_stats_fetch_retry(&dev->stats.syncp, start));
> }
>
> static int airoha_qdma_set_chan_tx_sched(struct net_device *netdev,
> @@ -3205,6 +3230,7 @@ static int airoha_alloc_gdm_device(struct airoha_eth *eth,
>
> netdev->dev.of_node = of_node_get(np);
> dev = netdev_priv(netdev);
> + u64_stats_init(&dev->stats.syncp);
> dev->port = port;
> dev->eth = eth;
> dev->nbq = nbq;
> @@ -3244,9 +3270,8 @@ static int airoha_alloc_gdm_port(struct airoha_eth *eth,
> if (!port)
> return -ENOMEM;
>
> - u64_stats_init(&port->stats.syncp);
> - spin_lock_init(&port->stats.lock);
> port->id = id;
> + spin_lock_init(&port->stats_lock);
> eth->ports[p] = port;
>
> err = airoha_metadata_dst_alloc(port);
> diff --git a/drivers/net/ethernet/airoha/airoha_eth.h b/drivers/net/ethernet/airoha/airoha_eth.h
> index 8f42973f9cf5..46b1c31939de 100644
> --- a/drivers/net/ethernet/airoha/airoha_eth.h
> +++ b/drivers/net/ethernet/airoha/airoha_eth.h
> @@ -215,8 +215,6 @@ struct airoha_tx_irq_queue {
> };
>
> struct airoha_hw_stats {
> - /* protect concurrent hw_stats accesses */
> - spinlock_t lock;
> struct u64_stats_sync syncp;
>
> /* get_stats64 */
> @@ -554,6 +552,8 @@ struct airoha_gdm_dev {
>
> u32 flags;
> int nbq;
> +
> + struct airoha_hw_stats stats;
> };
>
> struct airoha_gdm_port {
> @@ -561,7 +561,8 @@ struct airoha_gdm_port {
> int id;
> int users;
>
> - struct airoha_hw_stats stats;
> + /* protect concurrent hw_stats accesses */
> + spinlock_t stats_lock;
>
> struct metadata_dst *dsa_meta[AIROHA_MAX_DSA_PORTS];
> };
>
> ---
> base-commit: c8459ee2fef502d6ef6c063751c33d9ac7943eab
> change-id: 20260611-airoha-eth-multi-serdes-stats-df2dc16c2dd6
>
> Best regards,
> --
> Lorenzo Bianconi <lorenzo@kernel.org>
>
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
^ permalink raw reply
* [soc:imx/dt-binding] BUILD SUCCESS 88c0120853e96b66d57eff33e06409f49457eec5
From: kernel test robot @ 2026-06-12 14:18 UTC (permalink / raw)
To: Frank Li; +Cc: linux-arm-kernel, arm
tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git imx/dt-binding
branch HEAD: 88c0120853e96b66d57eff33e06409f49457eec5 dt-bindings: display/lvds-codec: add ti,sn65lvds93
elapsed time: 750m
configs tested: 221
configs skipped: 2
The following configs have been built successfully.
More configs may be tested in the coming days.
tested configs:
alpha allnoconfig gcc-16.1.0
alpha allyesconfig gcc-16.1.0
alpha defconfig gcc-16.1.0
arc allmodconfig clang-23
arc allmodconfig gcc-16.1.0
arc allnoconfig gcc-16.1.0
arc allyesconfig clang-23
arc allyesconfig gcc-16.1.0
arc defconfig gcc-16.1.0
arc nsim_700_defconfig gcc-16.1.0
arc randconfig-001-20260612 gcc-13.4.0
arc randconfig-002-20260612 gcc-13.4.0
arm allnoconfig clang-23
arm allnoconfig gcc-16.1.0
arm allyesconfig clang-23
arm allyesconfig gcc-16.1.0
arm axm55xx_defconfig clang-23
arm defconfig gcc-16.1.0
arm randconfig-001-20260612 gcc-13.4.0
arm randconfig-002-20260612 gcc-13.4.0
arm randconfig-003-20260612 gcc-13.4.0
arm randconfig-004-20260612 gcc-13.4.0
arm64 allmodconfig clang-23
arm64 allnoconfig gcc-16.1.0
arm64 defconfig gcc-16.1.0
arm64 randconfig-001 gcc-13.4.0
arm64 randconfig-001-20260612 gcc-13.4.0
arm64 randconfig-002 gcc-13.4.0
arm64 randconfig-002-20260612 gcc-13.4.0
arm64 randconfig-003 gcc-13.4.0
arm64 randconfig-003-20260612 gcc-13.4.0
arm64 randconfig-004 gcc-13.4.0
arm64 randconfig-004-20260612 gcc-13.4.0
csky allmodconfig gcc-16.1.0
csky allnoconfig gcc-16.1.0
csky defconfig gcc-16.1.0
csky randconfig-001 gcc-13.4.0
csky randconfig-001-20260612 gcc-13.4.0
csky randconfig-002 gcc-13.4.0
csky randconfig-002-20260612 gcc-13.4.0
hexagon allmodconfig clang-23
hexagon allmodconfig gcc-16.1.0
hexagon allnoconfig clang-23
hexagon allnoconfig gcc-16.1.0
hexagon defconfig gcc-16.1.0
hexagon randconfig-001 gcc-11.5.0
hexagon randconfig-001-20260612 gcc-11.5.0
hexagon randconfig-002 gcc-11.5.0
hexagon randconfig-002-20260612 gcc-11.5.0
i386 allmodconfig clang-22
i386 allnoconfig gcc-14
i386 allnoconfig gcc-16.1.0
i386 allyesconfig clang-22
i386 buildonly-randconfig-001-20260612 gcc-14
i386 buildonly-randconfig-002-20260612 gcc-14
i386 buildonly-randconfig-003-20260612 gcc-14
i386 buildonly-randconfig-004-20260612 gcc-14
i386 buildonly-randconfig-005-20260612 gcc-14
i386 buildonly-randconfig-006-20260612 gcc-14
i386 defconfig gcc-16.1.0
i386 randconfig-001-20260612 clang-22
i386 randconfig-002-20260612 clang-22
i386 randconfig-003-20260612 clang-22
i386 randconfig-004-20260612 clang-22
i386 randconfig-005-20260612 clang-22
i386 randconfig-006-20260612 clang-22
i386 randconfig-007-20260612 clang-22
i386 randconfig-011-20260612 clang-22
i386 randconfig-012-20260612 clang-22
i386 randconfig-013-20260612 clang-22
i386 randconfig-014-20260612 clang-22
i386 randconfig-015-20260612 clang-22
i386 randconfig-016-20260612 clang-22
i386 randconfig-017-20260612 clang-22
loongarch allmodconfig clang-19
loongarch allmodconfig clang-23
loongarch allnoconfig clang-20
loongarch allnoconfig gcc-16.1.0
loongarch defconfig clang-23
loongarch randconfig-001 gcc-11.5.0
loongarch randconfig-001-20260612 gcc-11.5.0
loongarch randconfig-002 gcc-11.5.0
loongarch randconfig-002-20260612 gcc-11.5.0
m68k allmodconfig gcc-16.1.0
m68k allnoconfig gcc-16.1.0
m68k allyesconfig clang-23
m68k allyesconfig gcc-16.1.0
m68k defconfig clang-23
microblaze allnoconfig gcc-16.1.0
microblaze allyesconfig gcc-16.1.0
microblaze defconfig clang-23
mips allmodconfig gcc-16.1.0
mips allnoconfig gcc-16.1.0
mips allyesconfig gcc-16.1.0
nios2 allmodconfig clang-20
nios2 allmodconfig gcc-11.5.0
nios2 allnoconfig clang-23
nios2 allnoconfig gcc-11.5.0
nios2 defconfig clang-23
nios2 randconfig-001 gcc-11.5.0
nios2 randconfig-001-20260612 gcc-11.5.0
nios2 randconfig-002 gcc-11.5.0
nios2 randconfig-002-20260612 gcc-11.5.0
openrisc allmodconfig clang-20
openrisc allmodconfig gcc-16.1.0
openrisc allnoconfig clang-23
openrisc allnoconfig gcc-16.1.0
openrisc defconfig gcc-16.1.0
parisc allmodconfig gcc-16.1.0
parisc allnoconfig clang-23
parisc allnoconfig gcc-16.1.0
parisc allyesconfig clang-23
parisc allyesconfig gcc-16.1.0
parisc defconfig gcc-16.1.0
parisc64 defconfig clang-23
powerpc allmodconfig gcc-16.1.0
powerpc allnoconfig clang-23
powerpc allnoconfig gcc-16.1.0
powerpc ppc64e_defconfig gcc-16.1.0
riscv allmodconfig clang-23
riscv allnoconfig clang-23
riscv allnoconfig gcc-16.1.0
riscv allyesconfig clang-23
riscv defconfig gcc-16.1.0
riscv randconfig-001-20260612 gcc-11.5.0
riscv randconfig-002-20260612 gcc-11.5.0
s390 allmodconfig clang-23
s390 allnoconfig clang-23
s390 allyesconfig gcc-16.1.0
s390 defconfig gcc-16.1.0
s390 randconfig-001-20260612 gcc-11.5.0
s390 randconfig-002-20260612 gcc-11.5.0
sh allmodconfig gcc-16.1.0
sh allnoconfig clang-23
sh allnoconfig gcc-16.1.0
sh allyesconfig clang-23
sh allyesconfig gcc-16.1.0
sh defconfig gcc-14
sh randconfig-001-20260612 gcc-11.5.0
sh randconfig-002-20260612 gcc-11.5.0
sparc allnoconfig clang-23
sparc allnoconfig gcc-16.1.0
sparc defconfig gcc-16.1.0
sparc randconfig-001 gcc-8.5.0
sparc randconfig-001-20260612 gcc-8.5.0
sparc randconfig-002 gcc-8.5.0
sparc randconfig-002-20260612 gcc-8.5.0
sparc64 allmodconfig clang-20
sparc64 defconfig gcc-14
sparc64 randconfig-001 gcc-8.5.0
sparc64 randconfig-001-20260612 gcc-8.5.0
sparc64 randconfig-002 gcc-8.5.0
sparc64 randconfig-002-20260612 gcc-8.5.0
um allmodconfig clang-23
um allnoconfig clang-16
um allnoconfig clang-23
um allyesconfig gcc-14
um allyesconfig gcc-16.1.0
um defconfig gcc-14
um i386_defconfig gcc-14
um randconfig-001 gcc-8.5.0
um randconfig-001-20260612 gcc-8.5.0
um randconfig-002 gcc-8.5.0
um randconfig-002-20260612 gcc-8.5.0
um x86_64_defconfig gcc-14
x86_64 allmodconfig clang-22
x86_64 allnoconfig clang-22
x86_64 allnoconfig clang-23
x86_64 allyesconfig clang-22
x86_64 buildonly-randconfig-001 gcc-14
x86_64 buildonly-randconfig-001-20260612 gcc-14
x86_64 buildonly-randconfig-002 gcc-14
x86_64 buildonly-randconfig-002-20260612 gcc-14
x86_64 buildonly-randconfig-003 gcc-14
x86_64 buildonly-randconfig-003-20260612 gcc-14
x86_64 buildonly-randconfig-004 gcc-14
x86_64 buildonly-randconfig-004-20260612 gcc-14
x86_64 buildonly-randconfig-005 gcc-14
x86_64 buildonly-randconfig-005-20260612 gcc-14
x86_64 buildonly-randconfig-006 gcc-14
x86_64 buildonly-randconfig-006-20260612 gcc-14
x86_64 defconfig gcc-14
x86_64 kexec clang-22
x86_64 randconfig-001-20260612 clang-22
x86_64 randconfig-002-20260612 clang-22
x86_64 randconfig-003-20260612 clang-22
x86_64 randconfig-004-20260612 clang-22
x86_64 randconfig-005-20260612 clang-22
x86_64 randconfig-006-20260612 clang-22
x86_64 randconfig-011 clang-22
x86_64 randconfig-011-20260612 clang-22
x86_64 randconfig-012 clang-22
x86_64 randconfig-012-20260612 clang-22
x86_64 randconfig-013 clang-22
x86_64 randconfig-013-20260612 clang-22
x86_64 randconfig-014 clang-22
x86_64 randconfig-014-20260612 clang-22
x86_64 randconfig-015 clang-22
x86_64 randconfig-015-20260612 clang-22
x86_64 randconfig-016 clang-22
x86_64 randconfig-016-20260612 clang-22
x86_64 randconfig-071-20260612 gcc-14
x86_64 randconfig-072-20260612 gcc-14
x86_64 randconfig-073-20260612 gcc-14
x86_64 randconfig-074-20260612 gcc-14
x86_64 randconfig-075-20260612 gcc-14
x86_64 randconfig-076-20260612 gcc-14
x86_64 rhel-9.4 clang-22
x86_64 rhel-9.4-bpf gcc-14
x86_64 rhel-9.4-func clang-22
x86_64 rhel-9.4-kselftests clang-22
x86_64 rhel-9.4-kunit gcc-14
x86_64 rhel-9.4-ltp gcc-14
x86_64 rhel-9.4-rust clang-22
xtensa allnoconfig clang-23
xtensa allnoconfig gcc-16.1.0
xtensa allyesconfig clang-20
xtensa randconfig-001 gcc-8.5.0
xtensa randconfig-001-20260612 gcc-8.5.0
xtensa randconfig-002 gcc-8.5.0
xtensa randconfig-002-20260612 gcc-8.5.0
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox