* [PATCH v5 01/20] [DO NOT MERGE] arm64/coco: Add pKVM as a CC platform
From: Aneesh Kumar K.V (Arm) @ 2026-05-22 4:27 UTC (permalink / raw)
To: iommu, linux-arm-kernel, linux-kernel, linux-coco
Cc: Aneesh Kumar K.V (Arm), Robin Murphy, Marek Szyprowski,
Will Deacon, Marc Zyngier, Steven Price, Suzuki K Poulose,
Catalin Marinas, Jiri Pirko, Jason Gunthorpe, Mostafa Saleh,
Petr Tesarik, Alexey Kardashevskiy, Dan Williams, Xu Yilun,
linuxppc-dev, linux-s390, Madhavan Srinivasan, Michael Ellerman,
Nicholas Piggin, Christophe Leroy (CS GROUP), Alexander Gordeev,
Gerald Schaefer, Heiko Carstens, Vasily Gorbik,
Christian Borntraeger, Sven Schnelle, x86
In-Reply-To: <20260522042815.370873-1-aneesh.kumar@kernel.org>
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.
Signed-off-by: Mostafa Saleh <smostafa@google.com>
Signed-off-by: Aneesh Kumar K.V (Arm) <aneesh.kumar@kernel.org>
---
arch/arm64/include/asm/hypervisor.h | 6 ++++++
arch/arm64/include/asm/mem_encrypt.h | 3 ++-
arch/arm64/kernel/rsi.c | 12 ------------
arch/arm64/mm/init.c | 13 +++++++++++++
drivers/virt/coco/pkvm-guest/arm-pkvm-guest.c | 5 +++++
5 files changed, 26 insertions(+), 13 deletions(-)
diff --git a/arch/arm64/include/asm/hypervisor.h b/arch/arm64/include/asm/hypervisor.h
index a12fd897c877..1b0e15f290be 100644
--- a/arch/arm64/include/asm/hypervisor.h
+++ b/arch/arm64/include/asm/hypervisor.h
@@ -10,8 +10,14 @@ void kvm_arm_target_impl_cpu_init(void);
#ifdef CONFIG_ARM_PKVM_GUEST
void pkvm_init_hyp_services(void);
+bool is_protected_kvm_guest(void);
#else
static inline void pkvm_init_hyp_services(void) { };
+
+static inline bool is_protected_kvm_guest(void)
+{
+ return false;
+}
#endif
static inline void kvm_arch_init_hyp_services(void)
diff --git a/arch/arm64/include/asm/mem_encrypt.h b/arch/arm64/include/asm/mem_encrypt.h
index 314b2b52025f..636f45b4d8af 100644
--- a/arch/arm64/include/asm/mem_encrypt.h
+++ b/arch/arm64/include/asm/mem_encrypt.h
@@ -2,6 +2,7 @@
#ifndef __ASM_MEM_ENCRYPT_H
#define __ASM_MEM_ENCRYPT_H
+#include <asm/hypervisor.h>
#include <asm/rsi.h>
struct device;
@@ -20,7 +21,7 @@ int realm_register_memory_enc_ops(void);
static inline bool force_dma_unencrypted(struct device *dev)
{
- return is_realm_world();
+ return is_realm_world() || is_protected_kvm_guest();
}
/*
diff --git a/arch/arm64/kernel/rsi.c b/arch/arm64/kernel/rsi.c
index 92160f2e57ff..25ca75ce1a4d 100644
--- a/arch/arm64/kernel/rsi.c
+++ b/arch/arm64/kernel/rsi.c
@@ -7,7 +7,6 @@
#include <linux/memblock.h>
#include <linux/psci.h>
#include <linux/swiotlb.h>
-#include <linux/cc_platform.h>
#include <linux/platform_device.h>
#include <asm/io.h>
@@ -23,17 +22,6 @@ EXPORT_SYMBOL(prot_ns_shared);
DEFINE_STATIC_KEY_FALSE_RO(rsi_present);
EXPORT_SYMBOL(rsi_present);
-bool cc_platform_has(enum cc_attr attr)
-{
- switch (attr) {
- case CC_ATTR_MEM_ENCRYPT:
- return is_realm_world();
- default:
- return false;
- }
-}
-EXPORT_SYMBOL_GPL(cc_platform_has);
-
static bool rsi_version_matches(void)
{
unsigned long ver_lower, ver_higher;
diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
index 97987f850a33..c1b223e7cc8e 100644
--- a/arch/arm64/mm/init.c
+++ b/arch/arm64/mm/init.c
@@ -12,6 +12,7 @@
#include <linux/swap.h>
#include <linux/init.h>
#include <linux/cache.h>
+#include <linux/cc_platform.h>
#include <linux/mman.h>
#include <linux/nodemask.h>
#include <linux/initrd.h>
@@ -36,6 +37,7 @@
#include <asm/boot.h>
#include <asm/fixmap.h>
+#include <asm/hypervisor.h>
#include <asm/kasan.h>
#include <asm/kernel-pgtable.h>
#include <asm/kvm_host.h>
@@ -416,6 +418,17 @@ void dump_mem_limit(void)
}
}
+bool cc_platform_has(enum cc_attr attr)
+{
+ switch (attr) {
+ case CC_ATTR_MEM_ENCRYPT:
+ return is_realm_world() || is_protected_kvm_guest();
+ default:
+ return false;
+ }
+}
+EXPORT_SYMBOL_GPL(cc_platform_has);
+
#ifdef CONFIG_EXECMEM
static u64 module_direct_base __ro_after_init = 0;
static u64 module_plt_base __ro_after_init = 0;
diff --git a/drivers/virt/coco/pkvm-guest/arm-pkvm-guest.c b/drivers/virt/coco/pkvm-guest/arm-pkvm-guest.c
index 4230b817a80b..297e6d6019b8 100644
--- a/drivers/virt/coco/pkvm-guest/arm-pkvm-guest.c
+++ b/drivers/virt/coco/pkvm-guest/arm-pkvm-guest.c
@@ -95,6 +95,11 @@ static int mmio_guard_ioremap_hook(phys_addr_t phys, size_t size,
return 0;
}
+bool is_protected_kvm_guest(void)
+{
+ return !!pkvm_granule;
+}
+
void pkvm_init_hyp_services(void)
{
int i;
--
2.43.0
^ permalink raw reply related
* [PATCH v5 00/20] dma-mapping: Use DMA_ATTR_CC_SHARED through direct, pool and swiotlb paths
From: Aneesh Kumar K.V (Arm) @ 2026-05-22 4:27 UTC (permalink / raw)
To: iommu, linux-arm-kernel, linux-kernel, linux-coco
Cc: Aneesh Kumar K.V (Arm), Robin Murphy, Marek Szyprowski,
Will Deacon, Marc Zyngier, Steven Price, Suzuki K Poulose,
Catalin Marinas, Jiri Pirko, Jason Gunthorpe, Mostafa Saleh,
Petr Tesarik, Alexey Kardashevskiy, Dan Williams, Xu Yilun,
linuxppc-dev, linux-s390, Madhavan Srinivasan, Michael Ellerman,
Nicholas Piggin, Christophe Leroy (CS GROUP), Alexander Gordeev,
Gerald Schaefer, Heiko Carstens, Vasily Gorbik,
Christian Borntraeger, Sven Schnelle, x86
This series propagates DMA_ATTR_CC_SHARED through the dma-direct,
dma-pool, and swiotlb paths so that encrypted and decrypted DMA buffers
are handled consistently.
Today, the direct DMA path mostly relies on force_dma_unencrypted() for
shared/decrypted buffer handling. This series consolidates the
force_dma_unencrypted() checks in the top-level functions and ensures
that the remaining DMA interfaces use DMA attributes to make the correct
decisions.
The series:
- moves swiotlb-backed allocations out of __dma_direct_alloc_pages(),
- propagates DMA_ATTR_CC_SHARED through the dma-direct alloc/free
paths
- teaches the atomic DMA pools to track encrypted versus decrypted
state
- tracks swiotlb pool encryption state and enforces strict pool
selection
- centralizes encrypted/decrypted pgprot handling in dma_pgprot() using
DMA attributes
- passes DMA attributes down to dma_capable() so capability checks can
validate whether the selected DMA address encoding matches
DMA_ATTR_CC_SHARED
- makes dma_direct_map_phys() choose the DMA address encoding from
DMA_ATTR_CC_SHARED and fall back to swiotlb when a shared DMA request
cannot use the direct mapping, which lets arm64 and x86 CCA guests stop
relying on SWIOTLB_FORCE for DMA mappings
- use the selected swiotlb pool state to derive the returned DMA
address.
Changes since v4:
https://lore.kernel.org/all/20260512090408.794195-1-aneesh.kumar@kernel.org
* Add new patches based on Sashiko review:
swiotlb: Preserve allocation virtual address for dynamic pools
dma: free atomic pool pages by physical address
dma: swiotlb: handle set_memory_decrypted() failures
dma: swiotlb: free dynamic pools from process context
iommu/dma: Check atomic pool allocation result directly
* Include pKVM and s390 changes as dependent patches. These are not yet
ready to merge and are waiting for subsystem testing feedback.
* Drop the AMD GART patch because it requires wider testing.
* Update swiotlb_tbl_map_single() to take attrs by reference.
* Switch swiotlb_free() to use rcu_work.
* Avoid calling swiotlb_find_pool() multiple times in the free path.
* Make DMA_ATTR_MMIO imply DMA_ATTR_CC_SHARED for devices requiring unencrypted DMA.
Changes from v3:
https://lore.kernel.org/all/20260427055509.898190-1-aneesh.kumar@kernel.org
* Handle DMA_ATTR_MMIO correctly in dma_direct_map_phys()
* Address most of sashiko review
* Rebase to latest kernel
* drop SWIOTLB_FORCE for s390 and powerpc secure guest.
Changes from v2:
https://lore.kernel.org/all/20260420061415.3650870-1-aneesh.kumar@kernel.org
* pass attrs to dma_capable() and update direct, swiotlb, Xen swiotlb, and
x86 GART paths so the capability checks see the DMA address attr value
DMA_ATTR_CC_SHARED.
* rework dma_direct_map_phys() so DMA_ATTR_CC_SHARED selects
phys_to_dma_unencrypted() while the default path uses
phys_to_dma_encrypted(), with swiotlb fallback when the requested
shared/private state cannot be satisfied by a direct DMA address.
* stop relying on SWIOTLB_FORCE for arm64 and x86 CC guest DMA mappings;
swiotlb is still enabled there, but shared mappings is now selected
through the generic dma_direct_map_phys()/dma_capable() decision instead
of a global force-bounce flag.
Changes from v1:
https://lore.kernel.org/all/20260417085900.3062416-1-aneesh.kumar@kernel.org
* rebased to latest kernel (change from DMA_ATTR_CC_DECRYPTED -> DMA_ATTR_CC_SHARED)
* update the alloc path so DMA_ATTR_CC_SHARED is not a caller-visible attribute.
Cc: Robin Murphy <robin.murphy@arm.com>
Cc: Marek Szyprowski <m.szyprowski@samsung.com>
Cc: Will Deacon <will@kernel.org>
Cc: Marc Zyngier <maz@kernel.org>
Cc: Steven Price <steven.price@arm.com>
Cc: Suzuki K Poulose <Suzuki.Poulose@arm.com>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Jiri Pirko <jiri@resnulli.us>
Cc: Jason Gunthorpe <jgg@ziepe.ca>
Cc: Mostafa Saleh <smostafa@google.com>
Cc: Petr Tesarik <ptesarik@suse.com>
Cc: Alexey Kardashevskiy <aik@amd.com>
Cc: Dan Williams <dan.j.williams@intel.com>
Cc: Xu Yilun <yilun.xu@linux.intel.com>
Cc: linuxppc-dev@lists.ozlabs.org
Cc: linux-s390@vger.kernel.org
Cc: Madhavan Srinivasan <maddy@linux.ibm.com>
Cc: Michael Ellerman <mpe@ellerman.id.au>
Cc: Nicholas Piggin <npiggin@gmail.com>
Cc: "Christophe Leroy (CS GROUP)" <chleroy@kernel.org>
Cc: Alexander Gordeev <agordeev@linux.ibm.com>
Cc: Gerald Schaefer <gerald.schaefer@linux.ibm.com>
Cc: Heiko Carstens <hca@linux.ibm.com>
Cc: Vasily Gorbik <gor@linux.ibm.com>
Cc: Christian Borntraeger <borntraeger@linux.ibm.com>
Cc: Sven Schnelle <svens@linux.ibm.com>
Cc: x86@kernel.org
Aneesh Kumar K.V (Arm) (20):
[DO NOT MERGE] arm64/coco: Add pKVM as a CC platform
[DO NOT MERGE] s390: Expose protected virtualization through
cc_platform_has()
dma-direct: swiotlb: handle swiotlb alloc/free outside
__dma_direct_alloc_pages
dma-direct: use DMA_ATTR_CC_SHARED in alloc/free paths
dma-pool: track decrypted atomic pools and select them via attrs
dma: swiotlb: pass mapping attributes by reference
dma: swiotlb: track pool encryption state and honor DMA_ATTR_CC_SHARED
dma-mapping: make dma_pgprot() honor DMA_ATTR_CC_SHARED
dma-direct: pass attrs to dma_capable() for DMA_ATTR_CC_SHARED checks
dma-direct: make dma_direct_map_phys() honor DMA_ATTR_CC_SHARED
dma-direct: set decrypted flag for remapped DMA allocations
dma-direct: select DMA address encoding from DMA_ATTR_CC_SHARED
dma-pool: fix page leak in atomic_pool_expand() cleanup
dma-direct: rename ret to cpu_addr in alloc helpers
dma-direct: return struct page from dma_direct_alloc_from_pool()
iommu/dma: Check atomic pool allocation result directly
dma: swiotlb: free dynamic pools from process context
dma: swiotlb: handle set_memory_decrypted() failures
dma: free atomic pool pages by physical address
swiotlb: Preserve allocation virtual address for dynamic pools
arch/arm64/include/asm/hypervisor.h | 6 +
arch/arm64/include/asm/mem_encrypt.h | 3 +-
arch/arm64/kernel/rsi.c | 12 -
arch/arm64/mm/init.c | 17 +-
arch/powerpc/platforms/pseries/svm.c | 2 +-
arch/s390/Kconfig | 1 +
arch/s390/mm/init.c | 16 +-
arch/x86/kernel/amd_gart_64.c | 30 +-
arch/x86/kernel/pci-dma.c | 4 +-
drivers/iommu/dma-iommu.c | 15 +-
drivers/virt/coco/pkvm-guest/arm-pkvm-guest.c | 5 +
drivers/xen/swiotlb-xen.c | 8 +-
include/linux/dma-direct.h | 20 +-
include/linux/dma-map-ops.h | 3 +-
include/linux/swiotlb.h | 20 +-
kernel/dma/direct.c | 275 +++++++++++++-----
kernel/dma/direct.h | 47 +--
kernel/dma/mapping.c | 16 +-
kernel/dma/pool.c | 221 ++++++++++----
kernel/dma/swiotlb.c | 270 +++++++++++++----
20 files changed, 717 insertions(+), 274 deletions(-)
base-commit: 50897c955902c93ae71c38698abb910525ebdc89
--
2.43.0
^ permalink raw reply
* [soc:soc/defconfig] BUILD SUCCESS 9f86df230e276e5c24f5c6800f3ee63ab33167f7
From: kernel test robot @ 2026-05-22 3:54 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/defconfig
branch HEAD: 9f86df230e276e5c24f5c6800f3ee63ab33167f7 Merge tag 'cix-defconfig-v7.2-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/peter.chen/cix into soc/defconfig
elapsed time: 727m
configs tested: 135
configs skipped: 133
The following configs have been built successfully.
More configs may be tested in the coming days.
tested configs:
alpha allnoconfig gcc-15.2.0
arc allmodconfig clang-16
arc allnoconfig gcc-15.2.0
arc allyesconfig clang-23
arc randconfig-001-20260522 clang-23
arc randconfig-002-20260522 clang-23
arm allnoconfig gcc-15.2.0
arm allyesconfig clang-16
arm randconfig-001-20260522 clang-23
arm randconfig-002-20260522 clang-23
arm randconfig-003-20260522 clang-23
arm randconfig-004-20260522 clang-23
arm64 allmodconfig clang-23
arm64 allnoconfig gcc-15.2.0
arm64 randconfig-001 gcc-14.3.0
arm64 randconfig-001-20260522 gcc-14.3.0
arm64 randconfig-002 gcc-14.3.0
arm64 randconfig-002-20260522 gcc-14.3.0
arm64 randconfig-003 gcc-14.3.0
arm64 randconfig-003-20260522 gcc-14.3.0
arm64 randconfig-004 gcc-14.3.0
arm64 randconfig-004-20260522 gcc-14.3.0
csky allmodconfig gcc-15.2.0
csky allnoconfig gcc-15.2.0
csky randconfig-001 gcc-14.3.0
csky randconfig-001-20260522 gcc-14.3.0
csky randconfig-002 gcc-14.3.0
csky randconfig-002-20260522 gcc-14.3.0
hexagon allnoconfig gcc-15.2.0
i386 allnoconfig gcc-15.2.0
i386 buildonly-randconfig-001-20260522 clang-20
i386 buildonly-randconfig-002-20260522 clang-20
i386 buildonly-randconfig-003-20260522 clang-20
i386 buildonly-randconfig-004-20260522 clang-20
i386 buildonly-randconfig-005-20260522 clang-20
i386 buildonly-randconfig-006-20260522 clang-20
i386 randconfig-011-20260522 clang-20
i386 randconfig-012-20260522 clang-20
i386 randconfig-013-20260522 clang-20
i386 randconfig-014-20260522 clang-20
i386 randconfig-015-20260522 clang-20
i386 randconfig-016-20260522 clang-20
i386 randconfig-017-20260522 clang-20
loongarch allmodconfig clang-23
loongarch allnoconfig gcc-15.2.0
loongarch defconfig clang-19
m68k allmodconfig gcc-15.2.0
m68k allnoconfig gcc-15.2.0
m68k allyesconfig clang-16
m68k defconfig clang-19
m68k m5272c3_defconfig gcc-15.2.0
microblaze allnoconfig gcc-15.2.0
microblaze allyesconfig gcc-15.2.0
microblaze defconfig clang-19
mips allmodconfig gcc-15.2.0
mips allnoconfig gcc-15.2.0
mips allyesconfig gcc-15.2.0
nios2 allmodconfig clang-23
nios2 allnoconfig clang-23
nios2 defconfig clang-19
openrisc allmodconfig clang-23
openrisc allnoconfig clang-23
openrisc defconfig gcc-15.2.0
parisc allmodconfig gcc-15.2.0
parisc allnoconfig clang-23
parisc allyesconfig clang-19
parisc defconfig gcc-15.2.0
parisc randconfig-001-20260522 gcc-12.5.0
parisc randconfig-002-20260522 gcc-12.5.0
parisc64 defconfig clang-19
powerpc allmodconfig gcc-15.2.0
powerpc allnoconfig clang-23
powerpc randconfig-001-20260522 gcc-12.5.0
powerpc randconfig-002-20260522 gcc-12.5.0
powerpc64 randconfig-001-20260522 gcc-12.5.0
powerpc64 randconfig-002-20260522 gcc-12.5.0
riscv allmodconfig clang-23
riscv allnoconfig clang-23
riscv allyesconfig clang-16
riscv defconfig gcc-15.2.0
s390 allmodconfig clang-19
s390 allnoconfig clang-23
s390 allyesconfig gcc-15.2.0
s390 defconfig gcc-15.2.0
sh allnoconfig clang-23
sh allyesconfig clang-19
sh defconfig gcc-14
sparc allnoconfig clang-23
sparc defconfig gcc-15.2.0
sparc randconfig-001-20260522 gcc-9.5.0
sparc randconfig-002-20260522 gcc-9.5.0
sparc64 allmodconfig clang-23
sparc64 defconfig gcc-14
sparc64 randconfig-001-20260522 gcc-9.5.0
sparc64 randconfig-002-20260522 gcc-9.5.0
um allmodconfig clang-19
um allnoconfig clang-23
um defconfig gcc-14
um i386_defconfig gcc-14
um randconfig-001-20260522 gcc-9.5.0
um randconfig-002-20260522 gcc-9.5.0
um x86_64_defconfig gcc-14
x86_64 allnoconfig clang-23
x86_64 buildonly-randconfig-001-20260522 gcc-14
x86_64 buildonly-randconfig-002-20260522 gcc-14
x86_64 buildonly-randconfig-003-20260522 gcc-14
x86_64 buildonly-randconfig-004-20260522 gcc-14
x86_64 buildonly-randconfig-005-20260522 gcc-14
x86_64 buildonly-randconfig-006-20260522 gcc-14
x86_64 defconfig gcc-14
x86_64 randconfig-001-20260522 gcc-14
x86_64 randconfig-002-20260522 gcc-14
x86_64 randconfig-003-20260522 gcc-14
x86_64 randconfig-004-20260522 gcc-14
x86_64 randconfig-005-20260522 gcc-14
x86_64 randconfig-006-20260522 gcc-14
x86_64 randconfig-011-20260522 gcc-14
x86_64 randconfig-012-20260522 gcc-14
x86_64 randconfig-013-20260522 gcc-14
x86_64 randconfig-014-20260522 gcc-14
x86_64 randconfig-015-20260522 gcc-14
x86_64 randconfig-016-20260522 gcc-14
x86_64 randconfig-071-20260522 clang-20
x86_64 randconfig-072-20260522 clang-20
x86_64 randconfig-073-20260522 clang-20
x86_64 randconfig-074-20260522 clang-20
x86_64 randconfig-075-20260522 clang-20
x86_64 randconfig-076-20260522 clang-20
x86_64 rhel-9.4-bpf gcc-14
x86_64 rhel-9.4-kunit gcc-14
x86_64 rhel-9.4-ltp gcc-14
xtensa allnoconfig clang-23
xtensa allyesconfig clang-23
xtensa randconfig-001-20260522 gcc-9.5.0
xtensa randconfig-002-20260522 gcc-9.5.0
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
^ permalink raw reply
* Re: [PATCH v2] ARM: dts: aspeed: Enable networking for Asus Kommando IPMI Card
From: Anirudh Srinivasan @ 2026-05-22 3:49 UTC (permalink / raw)
To: Andrew Jeffery
Cc: Andrew Lunn, devicetree, linux-arm-kernel, linux-aspeed,
linux-kernel, Rob Herring, Conor Dooley, Krzysztof Kozlowski,
Joel Stanley
In-Reply-To: <20260331-asus-kommando-networking-v2-1-f7d72ae5d40d@gmail.com>
Hi Andrew,
On Tue, Mar 31, 2026 at 9:18 AM Anirudh Srinivasan
<anirudhsriniv@gmail.com> wrote:
>
> Adds the DT nodes needed for ethernet support for Asus Kommando, with
> phy mode set to rgmii-id.
>
> When this DT was originally added, the phy mode was set to rgmii (which
> was incorrect). It was suggested to remove networking support from the
> DT till the Aspeed networking driver was patched so that the correct phy
> mode could be used.
>
> The discussion in [1] mentions that u-boot was inserting clk delays that
> weren't needed, which resulted in needing to set the phy mode in linux
> to rgmii incorrectly. The solution suggested there was to patch u-boot to
> no longer insert these clk delays and use rgmii-id as the phy mode for
> any future DTs added to linux.
>
> This DT was tested (on the OpenBMC u-boot fork [2]) with a u-boot DT
> modified to insert clk delays of 0 (instead of patching u-boot itself).
> [3] adds a u-boot DT for this device (without networking) and describes
> how to patch it to add networking support. If this patched DT is used,
> then networking works with rgmii-id phy mode in both u-boot and linux.
>
> [1] https://lore.kernel.org/linux-aspeed/ef88bb50-9f2c-458d-a7e5-dc5ecb9c777a@lunn.ch/
> [2] https://github.com/openbmc/u-boot/tree/v2019.04-aspeed-openbmc
> [3] https://lore.kernel.org/openbmc/20260328-asus-kommando-v2-1-2a656f8cd314@gmail.com/
>
> Signed-off-by: Anirudh Srinivasan <anirudhsriniv@gmail.com>
> ---
> This patch is based off aspeed/arm/dt from bmc tree
> ---
> Changes in v2:
> - Commit message now mentions that the u-boot tested against is the
> openbmc u-boot fork
> - Link to v1: https://lore.kernel.org/r/20260328-asus-kommando-networking-v1-1-66d308b88536@gmail.com
> ---
> .../dts/aspeed/aspeed-bmc-asus-kommando-ipmi-card.dts | 18 ++++++++++++++++++
> 1 file changed, 18 insertions(+)
>
> diff --git a/arch/arm/boot/dts/aspeed/aspeed-bmc-asus-kommando-ipmi-card.dts b/arch/arm/boot/dts/aspeed/aspeed-bmc-asus-kommando-ipmi-card.dts
> index ab7ad320067c1ddc0fea9ac386fd488c8ef28184..e0f7d92efa18ccbad2c336236c3b9d01b7de1bba 100644
> --- a/arch/arm/boot/dts/aspeed/aspeed-bmc-asus-kommando-ipmi-card.dts
> +++ b/arch/arm/boot/dts/aspeed/aspeed-bmc-asus-kommando-ipmi-card.dts
> @@ -107,6 +107,24 @@ &gpio1 {
> /*18E0 32*/ "","","","","","","","";
> };
>
> +&mac2 {
> + status = "okay";
> +
> + phy-mode = "rgmii-id";
> + phy-handle = <ðphy2>;
> + pinctrl-names = "default";
> + pinctrl-0 = <&pinctrl_rgmii3_default>;
> +};
> +
> +&mdio2 {
> + status = "okay";
> +
> + ethphy2: ethernet-phy@0 {
> + compatible = "ethernet-phy-ieee802.3-c22";
> + reg = <0>;
> + };
> +};
> +
> &vhub {
> status = "okay";
> };
>
> ---
> base-commit: 76b4ec8efdc3887cdbf730da2e55881fc1a18770
> change-id: 20260328-asus-kommando-networking-5c0612aa6b8c
>
> Best regards,
> --
> Anirudh Srinivasan <anirudhsriniv@gmail.com>
>
While we're figuring out what to do with u-boot, what are your
thoughts on getting this patch in so that the kernel DTS changes
needed for networking land in this cycle?
The current commit message might become somewhat outdated if the
u-boot patch changes though, so not sure if that's okay.
--
Regards
Anirudh Srinivasan
^ permalink raw reply
* [PATCH 2/2] PCI: imx6: Add imx_pcie_perst_found() to inspect the parsed result
From: Sherry Sun (OSS) @ 2026-05-22 3:43 UTC (permalink / raw)
To: hongxing.zhu, l.stach, Frank.Li, bhelgaas, lpieralisi,
kwilczynski, mani, robh, s.hauer, kernel, festevam, will
Cc: imx, linux-pci, linux-arm-kernel, linux-kernel, sherry.sun
In-Reply-To: <20260522034344.1147775-1-sherry.sun@oss.nxp.com>
From: Sherry Sun <sherry.sun@nxp.com>
Since pci_host_common_parse_port() doesn't return failure for "property
not found"(-ENODEV), the caller should inspect the parsed result and
decide whether to fall back to the legacy binding.
Add imx_pcie_perst_found() to inspect the parsed result.
Signed-off-by: Sherry Sun <sherry.sun@nxp.com>
---
drivers/pci/controller/dwc/pci-imx6.c | 25 +++++++++++++++++--------
1 file changed, 17 insertions(+), 8 deletions(-)
diff --git a/drivers/pci/controller/dwc/pci-imx6.c b/drivers/pci/controller/dwc/pci-imx6.c
index b137551871fc..34756f28fcc6 100644
--- a/drivers/pci/controller/dwc/pci-imx6.c
+++ b/drivers/pci/controller/dwc/pci-imx6.c
@@ -1287,6 +1287,18 @@ static void imx_pcie_assert_perst(struct imx_pcie *imx_pcie, bool assert)
}
}
+static bool imx_pcie_perst_found(struct pci_host_bridge *bridge)
+{
+ struct pci_host_port *port;
+
+ list_for_each_entry(port, &bridge->ports, list) {
+ if (!list_empty(&port->perst))
+ return true;
+ }
+
+ return false;
+}
+
static int imx_pcie_host_init(struct dw_pcie_rp *pp)
{
struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
@@ -1299,15 +1311,12 @@ static int imx_pcie_host_init(struct dw_pcie_rp *pp)
/* Parse Root Port nodes if present */
ret = pci_host_common_parse_ports(dev, bridge);
if (ret) {
- if (ret != -ENODEV) {
- dev_err(dev, "Failed to parse Root Port nodes: %d\n", ret);
- return ret;
- }
+ dev_err(dev, "Failed to parse Root Port nodes: %d\n", ret);
+ return ret;
+ }
- /*
- * Fall back to legacy binding for DT backwards
- * compatibility
- */
+ /* Fallback to legacy binding for DT backwards compatibility. */
+ if (!imx_pcie_perst_found(bridge)) {
ret = imx_pcie_parse_legacy_binding(imx_pcie);
if (ret)
return ret;
--
2.37.1
^ permalink raw reply related
* [PATCH 1/2] PCI: host-generic: Simplify return value handling in pci_host_common_parse_port(s)
From: Sherry Sun (OSS) @ 2026-05-22 3:43 UTC (permalink / raw)
To: hongxing.zhu, l.stach, Frank.Li, bhelgaas, lpieralisi,
kwilczynski, mani, robh, s.hauer, kernel, festevam, will
Cc: imx, linux-pci, linux-arm-kernel, linux-kernel, sherry.sun
In-Reply-To: <20260522034344.1147775-1-sherry.sun@oss.nxp.com>
From: Sherry Sun <sherry.sun@nxp.com>
The pci_host_common_parse_port() shouldn't check the RC-level binding.
That's a policy decision that belongs to the caller, not this common
helper.
Simplify pci_host_common_parse_port() to only parses properties from the
Root Port(and its children) without checking the RC node. Also change
pci_host_common_parse_ports() to return 0 when no ports are found, since
it is not an error.
So now both functions won't return failure for "property not found" or
"port not found", they purely returns 0 on success and a negative error
code on real failures.
Signed-off-by: Sherry Sun <sherry.sun@nxp.com>
---
drivers/pci/controller/pci-host-common.c | 29 ++++--------------------
1 file changed, 5 insertions(+), 24 deletions(-)
diff --git a/drivers/pci/controller/pci-host-common.c b/drivers/pci/controller/pci-host-common.c
index 67455caaf9e6..7ce5a939e3d9 100644
--- a/drivers/pci/controller/pci-host-common.c
+++ b/drivers/pci/controller/pci-host-common.c
@@ -108,8 +108,7 @@ static int pci_host_common_parse_perst(struct device *dev,
* dependencies and the driver may fail to operate if required resources
* are missing.
*
- * Return: 0 on success, -ENODEV if PERST# found in RC node (legacy binding
- * should be used), Other negative error codes on failure.
+ * Return: 0 on success, negative error codes on failure.
*/
static int pci_host_common_parse_port(struct device *dev,
struct pci_host_bridge *bridge,
@@ -128,22 +127,6 @@ static int pci_host_common_parse_port(struct device *dev,
if (ret)
return ret;
- /*
- * 1. PERST# found in RP or its child nodes - list is not empty,
- * continue
- *
- * 2. PERST# not found in RP/children, but found in RC node -
- * return -ENODEV to fallback legacy binding
- *
- * 3. PERST# not found anywhere - list is empty, continue (optional
- * PERST#)
- */
- if (list_empty(&port->perst)) {
- if (of_property_present(dev->of_node, "reset-gpios") ||
- of_property_present(dev->of_node, "reset-gpio"))
- return -ENODEV;
- }
-
INIT_LIST_HEAD(&port->list);
list_add_tail(&port->list, &bridge->ports);
@@ -158,13 +141,11 @@ static int pci_host_common_parse_port(struct device *dev,
* Iterate through child nodes of the host bridge and parse Root Port
* properties (currently only reset GPIOs).
*
- * Return: 0 on success, -ENODEV if no ports found or PERST# found in RC
- * node (legacy binding should be used), Other negative error codes on
- * failure.
+ * Return: 0 on success, negative error codes on failure.
*/
int pci_host_common_parse_ports(struct device *dev, struct pci_host_bridge *bridge)
{
- int ret = -ENODEV;
+ int ret = 0;
for_each_available_child_of_node_scoped(dev->of_node, of_port) {
if (!of_node_is_type(of_port, "pci"))
@@ -174,8 +155,8 @@ int pci_host_common_parse_ports(struct device *dev, struct pci_host_bridge *brid
goto err_cleanup;
}
- if (ret)
- return ret;
+ if (list_empty(&bridge->ports))
+ return 0;
return devm_add_action_or_reset(dev, pci_host_common_delete_ports,
&bridge->ports);
--
2.37.1
^ permalink raw reply related
* [PATCH 0/2] PCI: imx6: Improve PERST# fallback logic
From: Sherry Sun (OSS) @ 2026-05-22 3:43 UTC (permalink / raw)
To: hongxing.zhu, l.stach, Frank.Li, bhelgaas, lpieralisi,
kwilczynski, mani, robh, s.hauer, kernel, festevam, will
Cc: imx, linux-pci, linux-arm-kernel, linux-kernel, sherry.sun
From: Sherry Sun <sherry.sun@nxp.com>
The pci_host_common_parse_port() shouldn't decide whether to fall back
to the legacy RC-level binding by checking for "reset-gpios/reset-gpio"
properties on the RC node and returning -ENODEV. That's a policy
decision belongs to the caller, not this common helper.
This patch set improves the PERST# (PCIe reset) GPIO fallback logic
across the generic PCI host bridge helper and the i.MX6 PCIe driver.
Sherry Sun (2):
PCI: host-generic: Simplify return value handling in
pci_host_common_parse_port(s)
PCI: imx6: Add imx_pcie_perst_found() to inspect the parsed result
drivers/pci/controller/dwc/pci-imx6.c | 25 +++++++++++++-------
drivers/pci/controller/pci-host-common.c | 29 ++++--------------------
2 files changed, 22 insertions(+), 32 deletions(-)
base-commit: 550604d6c9b9efc8d068aff94dc301694a7afdee
--
2.37.1
^ permalink raw reply
* [GIT PULL] CIX dts changes for v7.2-rc1
From: Peter Chen @ 2026-05-22 3:21 UTC (permalink / raw)
To: soc, arm, soc; +Cc: fugang.duan, linux-arm-kernel, cix-kernel-upstream
The following changes since commit 254f49634ee16a731174d2ae34bc50bd5f45e731:
Linux 7.1-rc1 (2026-04-26 14:19:00 -0700)
are available in the Git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/peter.chen/cix.git/ tags/cix-dt-v7.2-rc1
for you to fetch changes up to 89d0ad7f3a60d3076da2d90ece8d78d0eb60bb91:
arm64: dts: cix: Add CPU idle states for Sky1 (2026-05-11 11:36:40 +0800)
----------------------------------------------------------------
- Add cpuidle and cpufreq support for Sky1
----------------------------------------------------------------
Devin Li (2):
arm64: dts: cix: Add SCMI performance domains for CPUFreq on Sky1
arm64: dts: cix: Add CPU idle states for Sky1
arch/arm64/boot/dts/cix/sky1-power.h | 13 +++++++
arch/arm64/boot/dts/cix/sky1.dtsi | 70 ++++++++++++++++++++++++++++++++++++
2 files changed, 83 insertions(+)
--
Best regards,
Peter
^ permalink raw reply
* Re: [PATCH v6 01/10] dt-bindings: display: rockchip: analogix-dp: Fix hclk as third clock for RK3588
From: Damon Ding @ 2026-05-22 3:02 UTC (permalink / raw)
To: Conor Dooley
Cc: hjc, heiko, andy.yan, maarten.lankhorst, mripard, tzimmermann,
airlied, simona, robh, krzk+dt, conor+dt, andrzej.hajda,
neil.armstrong, rfoss, Laurent.pinchart, jonas, jernej.skrabec,
nicolas.frattaroli, cristian.ciocaltea, sebastian.reichel,
dmitry.baryshkov, luca.ceresoli, dianders, m.szyprowski,
dri-devel, devicetree, linux-arm-kernel, linux-rockchip,
linux-kernel
In-Reply-To: <20260521-waking-case-cd709f0a7712@spud>
Hi Conor,
On 5/22/2026 3:54 AM, Conor Dooley wrote:
> On Thu, May 21, 2026 at 04:08:26PM +0800, Damon Ding wrote:
>> RK3588 eDP controller requires HCLK_VO1 to access the VO1 GRF
>> registers and enable the video datapath.
>>
>> Previously, the clock was enabled implicitly via the 'rockchip,vo-grf'
>> phandle reference, which allowed the eDP to work without explicitly
>> managing the hclk_vo1 clock. However, this is not safe or explicit.
>>
>> To make the clock dependency explicit, enforce per-SoC clock-names
>> requirements:
>> - RK3288: 2 clocks (dp, pclk)
>> - RK3399: 3 clocks (dp, pclk, grf)
>> - RK3588: 3 clocks (dp, pclk, hclk)
>>
>> Do not reuse the 'grf' clock name for RK3588 because it represents
>> a different clock with distinct control logic:
>> - The 'grf' clock is only for GRF register access and is toggled
>> dynamically during register access.
>> - The 'hclk' clock controls both GRF access and video datapath
>> gating, and must remain enabled during probe.
>>
>> Fixes: f855146263b1 ("dt-bindings: display: rockchip: analogix-dp: Add support for RK3588")
>> Signed-off-by: Damon Ding <damon.ding@rock-chips.com>
>>
>> ---
>>
>> Changes in v4:
>> - Modify the commit msg.
>>
>> Changes in v5:
>> - Enforce the correct third clock name on a per-compatible basis.
>> - Modify the commit msg simultaneously.
>>
>> Changes in v6:
>> - Expand more detail commit msg about using hclk instead of grf clock.
>> ---
>> .../rockchip/rockchip,analogix-dp.yaml | 37 +++++++++++++++++--
>> 1 file changed, 33 insertions(+), 4 deletions(-)
>>
>> diff --git a/Documentation/devicetree/bindings/display/rockchip/rockchip,analogix-dp.yaml b/Documentation/devicetree/bindings/display/rockchip/rockchip,analogix-dp.yaml
>> index d99b23b88cc5..8001c1facf98 100644
>> --- a/Documentation/devicetree/bindings/display/rockchip/rockchip,analogix-dp.yaml
>> +++ b/Documentation/devicetree/bindings/display/rockchip/rockchip,analogix-dp.yaml
>> @@ -23,10 +23,7 @@ properties:
>>
>> clock-names:
>> minItems: 2
>> - items:
>> - - const: dp
>> - - const: pclk
>> - - const: grf
>
> Instead of removing this, you can make it
>
> items:
> - const: dp
> - const pclk
> - enum:
> - grf
> - hclk
>
>> + maxItems: 3
>
> And delete this.
>
Oh I see, thanks for clarifying.
The idea is to keep all valid clock names at the top level, and use only
minItems/maxItems in allOf to differentiate platforms.
>>
>> power-domains:
>> maxItems: 1
>> @@ -60,6 +57,33 @@ required:
>> allOf:
>> - $ref: /schemas/display/bridge/analogix,dp.yaml#
>>
>> + - if:
>> + properties:
>> + compatible:
>> + contains:
>> + enum:
>> + - rockchip,rk3288-dp
>> + then:
>> + properties:
>> + clock-names:
>> + items:
>> + - const: dp
>> + - const: pclk
>
> Then this becomes
> clock-names:
> maxItems: 2
> clocks:
> maxItems: 2
>
>> +
>> + - if:
>> + properties:
>> + compatible:
>> + contains:
>> + enum:
>> + - rockchip,rk3399-edp
>> + then:
>> + properties:
>> + clock-names:
>> + items:
>> + - const: dp
>> + - const: pclk
>> + - const: grf
>
> maybe this needs a minItems: 3? Depends on if the grf clock is
> mandatory. Also probably needs a
> clocks:
> minItems: 3
> if that's the case.
>
Yes, the minItems should be 3 for both clocks and clock-names.
>> +
>> - if:
>> properties:
>> compatible:
>> @@ -68,6 +92,11 @@ allOf:
>> - rockchip,rk3588-edp
>> then:
>> properties:
>> + clock-names:
>> + items:
>> + - const: dp
>> + - const: pclk
>> + - const: hclk
>
> And the same here as for the 3399.
>
Will update in v7.
Best regards,
Damon
^ permalink raw reply
* Re: [PATCH v9 3/4] coresight: cti: add Qualcomm extended CTI identification and quirks
From: Jie Gan @ 2026-05-22 2:38 UTC (permalink / raw)
To: Yingchao Deng, Suzuki K Poulose, Mike Leach, James Clark, Leo Yan,
Alexander Shishkin
Cc: coresight, linux-arm-kernel, linux-kernel, linux-arm-msm,
jinlong.mao, quic_yingdeng, tingwei.zhang
In-Reply-To: <20260521-extended_cti-v9-3-d21f4f92c51e@oss.qualcomm.com>
On 5/21/2026 8:16 PM, Yingchao Deng wrote:
> Qualcomm implements an extended variant of the ARM CoreSight CTI with a
> different register layout and vendor-specific behavior. While the
> programming model remains largely compatible, the register offsets differ
> from the standard ARM CTI and require explicit handling.
>
> Detect Qualcomm CTIs via the DEVARCH register and record this in the CTI
> driver data. Introduce a small mapping layer to translate standard CTI
> register offsets to Qualcomm-specific offsets, allowing the rest of the
> driver to use a common register access path.
>
> Additionally, handle a Qualcomm-specific quirk where the CLAIMSET
> register is incorrectly initialized to a non-zero value, which can cause
> tools or drivers to assume the component is already claimed. Clear the
> register during probe to reflect the actual unclaimed state.
>
> No functional change is intended for standard ARM CTI devices.
>
> Co-developed-by: Jinlong Mao <jinlong.mao@oss.qualcomm.com>
> Signed-off-by: Jinlong Mao <jinlong.mao@oss.qualcomm.com>
> Signed-off-by: Yingchao Deng <yingchao.deng@oss.qualcomm.com>
> ---
> drivers/hwtracing/coresight/coresight-cti-core.c | 27 +++++++++-
> drivers/hwtracing/coresight/coresight-cti.h | 7 ++-
> drivers/hwtracing/coresight/qcom-cti.h | 65 ++++++++++++++++++++++++
> 3 files changed, 97 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/hwtracing/coresight/coresight-cti-core.c b/drivers/hwtracing/coresight/coresight-cti-core.c
> index c5cc2706e241..2dac5eb4ecca 100644
> --- a/drivers/hwtracing/coresight/coresight-cti-core.c
> +++ b/drivers/hwtracing/coresight/coresight-cti-core.c
> @@ -21,6 +21,7 @@
>
> #include "coresight-priv.h"
> #include "coresight-cti.h"
> +#include "qcom-cti.h"
>
> /*
> * CTI devices can be associated with a PE, or be connected to CoreSight
> @@ -45,6 +46,9 @@ static DEFINE_MUTEX(ect_mutex);
> static void __iomem *__reg_addr(struct cti_drvdata *drvdata, u32 off,
> u32 index)
> {
> + if (unlikely(rvdata->is_qcom_cti))
typo.
s/rvdata/drvdata
Thanks,
Jie
> + off = cti_qcom_reg_off(off);
> +
> return drvdata->base + off + sizeof(u32) * index;
> }
>
> @@ -172,6 +176,9 @@ void cti_write_intack(struct device *dev, u32 ackval)
> /* DEVID[19:16] - number of CTM channels */
> #define CTI_DEVID_CTMCHANNELS(devid_val) ((int) BMVAL(devid_val, 16, 19))
>
> +/* DEVARCH[31:21] - ARCHITECT */
> +#define CTI_DEVARCH_ARCHITECT(devarch_val) ((int)BMVAL(devarch_val, 21, 31))
> +
> static int cti_set_default_config(struct device *dev,
> struct cti_drvdata *drvdata)
> {
> @@ -702,6 +709,7 @@ static int cti_probe(struct amba_device *adev, const struct amba_id *id)
> struct coresight_desc cti_desc;
> struct coresight_platform_data *pdata = NULL;
> struct resource *res = &adev->res;
> + u32 devarch;
>
> /* driver data*/
> drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL);
> @@ -726,6 +734,22 @@ static int cti_probe(struct amba_device *adev, const struct amba_id *id)
>
> raw_spin_lock_init(&drvdata->spinlock);
>
> + devarch = readl_relaxed(drvdata->base + CORESIGHT_DEVARCH);
> + if (CTI_DEVARCH_ARCHITECT(devarch) == ARCHITECT_QCOM) {
> + drvdata->is_qcom_cti = true;
> + /*
> + * QCOM CTI does not implement Claimtag functionality as
> + * per CoreSight specification, but its CLAIMSET register
> + * is incorrectly initialized to 0xF. This can mislead
> + * tools or drivers into thinking the component is claimed.
> + *
> + * Reset CLAIMSET to 0 to reflect that no claims are active.
> + */
> + CS_UNLOCK(drvdata->base);
> + writel_relaxed(0, drvdata->base + CORESIGHT_CLAIMSET);
> + CS_LOCK(drvdata->base);
> + }
> +
> /* initialise CTI driver config values */
> ret = cti_set_default_config(dev, drvdata);
> if (ret)
> @@ -782,7 +806,8 @@ static int cti_probe(struct amba_device *adev, const struct amba_id *id)
>
> /* all done - dec pm refcount */
> pm_runtime_put(&adev->dev);
> - dev_info(&drvdata->csdev->dev, "CTI initialized\n");
> + dev_info(&drvdata->csdev->dev,
> + "%sCTI initialized\n", drvdata->is_qcom_cti ? "QCOM " : "");
> return 0;
> }
>
> diff --git a/drivers/hwtracing/coresight/coresight-cti.h b/drivers/hwtracing/coresight/coresight-cti.h
> index 98b8de8a3687..08ea6daf5b3c 100644
> --- a/drivers/hwtracing/coresight/coresight-cti.h
> +++ b/drivers/hwtracing/coresight/coresight-cti.h
> @@ -54,10 +54,11 @@ struct fwnode_handle;
> /*
> * CTI CSSoc 600 has a max of 32 trigger signals per direction.
> * CTI CSSoc 400 has 8 IO triggers - other CTIs can be impl def.
> + * QCOM CTI supports up to 128 trigger signals per direction.
> * Max of in and out defined in the DEVID register.
> * - pick up actual number used from .dts parameters if present.
> */
> -#define CTIINOUTEN_MAX 32
> +#define CTIINOUTEN_MAX 128
>
> /**
> * Group of related trigger signals
> @@ -168,6 +169,9 @@ struct cti_config {
> * @spinlock: Control data access to one at a time.
> * @config: Configuration data for this CTI device.
> * @node: List entry of this device in the list of CTI devices.
> + * @is_qcom_cti: True if this CTI is a Qualcomm vendor-specific
> + * variant that requires register offset translation
> + * via cti_qcom_reg_off().
> */
> struct cti_drvdata {
> void __iomem *base;
> @@ -176,6 +180,7 @@ struct cti_drvdata {
> raw_spinlock_t spinlock;
> struct cti_config config;
> struct list_head node;
> + bool is_qcom_cti;
> };
>
> /*
> diff --git a/drivers/hwtracing/coresight/qcom-cti.h b/drivers/hwtracing/coresight/qcom-cti.h
> new file mode 100644
> index 000000000000..d3846613a0de
> --- /dev/null
> +++ b/drivers/hwtracing/coresight/qcom-cti.h
> @@ -0,0 +1,65 @@
> +/* SPDX-License-Identifier: GPL-2.0-only */
> +/*
> + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
> + */
> +
> +#ifndef _CORESIGHT_QCOM_CTI_H
> +#define _CORESIGHT_QCOM_CTI_H
> +
> +#include "coresight-cti.h"
> +
> +#define ARCHITECT_QCOM 0x477
> +
> +/* CTI programming registers */
> +#define QCOM_CTIINTACK 0x020
> +#define QCOM_CTIAPPSET 0x004
> +#define QCOM_CTIAPPCLEAR 0x008
> +#define QCOM_CTIAPPPULSE 0x00C
> +#define QCOM_CTIINEN 0x400
> +#define QCOM_CTIOUTEN 0x800
> +#define QCOM_CTITRIGINSTATUS 0x040
> +#define QCOM_CTITRIGOUTSTATUS 0x060
> +#define QCOM_CTICHINSTATUS 0x080
> +#define QCOM_CTICHOUTSTATUS 0x084
> +#define QCOM_CTIGATE 0x088
> +#define QCOM_ASICCTL 0x08C
> +/* Integration test registers */
> +#define QCOM_ITCHINACK 0xE70
> +#define QCOM_ITTRIGINACK 0xE80
> +#define QCOM_ITCHOUT 0xE74
> +#define QCOM_ITTRIGOUT 0xEA0
> +#define QCOM_ITCHOUTACK 0xE78
> +#define QCOM_ITTRIGOUTACK 0xEC0
> +#define QCOM_ITCHIN 0xE7C
> +#define QCOM_ITTRIGIN 0xEE0
> +
> +static inline u32 cti_qcom_reg_off(u32 offset)
> +{
> + switch (offset) {
> + case CTIINTACK: return QCOM_CTIINTACK;
> + case CTIAPPSET: return QCOM_CTIAPPSET;
> + case CTIAPPCLEAR: return QCOM_CTIAPPCLEAR;
> + case CTIAPPPULSE: return QCOM_CTIAPPPULSE;
> + case CTIINEN: return QCOM_CTIINEN;
> + case CTIOUTEN: return QCOM_CTIOUTEN;
> + case CTITRIGINSTATUS: return QCOM_CTITRIGINSTATUS;
> + case CTITRIGOUTSTATUS: return QCOM_CTITRIGOUTSTATUS;
> + case CTICHINSTATUS: return QCOM_CTICHINSTATUS;
> + case CTICHOUTSTATUS: return QCOM_CTICHOUTSTATUS;
> + case CTIGATE: return QCOM_CTIGATE;
> + case ASICCTL: return QCOM_ASICCTL;
> + case ITCHINACK: return QCOM_ITCHINACK;
> + case ITTRIGINACK: return QCOM_ITTRIGINACK;
> + case ITCHOUT: return QCOM_ITCHOUT;
> + case ITTRIGOUT: return QCOM_ITTRIGOUT;
> + case ITCHOUTACK: return QCOM_ITCHOUTACK;
> + case ITTRIGOUTACK: return QCOM_ITTRIGOUTACK;
> + case ITCHIN: return QCOM_ITCHIN;
> + case ITTRIGIN: return QCOM_ITTRIGIN;
> +
> + default:
> + return offset;
> + }
> +}
> +
> +#endif /* _CORESIGHT_QCOM_CTI_H */
>
^ permalink raw reply
* Re: [PATCH v2 0/5] mm: reduce mmap_lock contention and improve page fault performance
From: Barry Song (Xiaomi) @ 2026-05-22 2:33 UTC (permalink / raw)
To: willy
Cc: akpm, baohua, bhe, chentao, chrisl, david, jack, kasong,
kunwu.chan, liam, lianux.mm, linux-arm-kernel, linux-kernel,
linux-mm, linux-riscv, linux-s390, linuxppc-dev, liyangouwen1,
ljs, loongarch, mhocko, nphamcs, nzzhao, pfalcato, rppt,
shikemeng, surenb, vbabka, wanglian, youngjun.park
In-Reply-To: <ag4kj84EcKqamdB-@casper.infradead.org>
On Thu, May 21, 2026 at 5:16 AM Matthew Wilcox <willy@infradead.org> wrote:
>
> On Thu, May 21, 2026 at 05:14:20AM +0800, Barry Song wrote:
> > My understanding is that we should not blame applications here. This is 2026:
> > there are basically only two kinds of applications — single-threaded and
> > multi-threaded — and single-threaded applications are nearly extinct.
>
> all of the applications i run are either single threaded or don't fork.
> what multithreaded applications call fork?
As I replied to David [1], we cannot control what those apps do.
Technically, I agree with you that calling fork() within a
multithreaded app may not be a good idea. But in such a complex
ecosystem, we cannot simply say no to those apps.
Especially when our phones are improving the kernel with this fix,
our customers may instead complain that our phones regress their
apps first. That feels unfair.
I can offer a two-step plan. For the first step, we keep the
current approach of dropping the VMA lock and retrying page faults,
while trying to make the smallest possible change.
As discussed with Suren, the draft code is being changed from a
whitelist approach to a blacklist approach. This way, we do not
need to touch `filemap.c` at all (probably because you are already
maintaining `filemap.c` perfectly):
diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c
index 63de8e8684f2..4101d5fa7a82 100644
--- a/arch/x86/mm/fault.c
+++ b/arch/x86/mm/fault.c
@@ -1322,6 +1322,7 @@ void do_user_addr_fault(struct pt_regs *regs,
if (!(flags & FAULT_FLAG_USER))
goto lock_mmap;
+retry_vma:
vma = lock_vma_under_rcu(mm, address);
if (!vma)
goto lock_mmap;
@@ -1351,6 +1352,8 @@ void do_user_addr_fault(struct pt_regs *regs,
ARCH_DEFAULT_PKEY);
return;
}
+ if (!(fault & VM_FAULT_RETRY_HARD))
+ goto retry_vma;
lock_mmap:
retry:
diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h
index a308e2c23b82..eeb7d6091bef 100644
--- a/include/linux/mm_types.h
+++ b/include/linux/mm_types.h
@@ -1659,6 +1659,7 @@ typedef __bitwise unsigned int vm_fault_t;
* @VM_FAULT_NOPAGE: ->fault installed the pte, not return page
* @VM_FAULT_LOCKED: ->fault locked the returned page
* @VM_FAULT_RETRY: ->fault blocked, must retry
+ * @VM_FAULT_RETRY_HARD: ->fault blocked, must retry via mmap_lock
* @VM_FAULT_FALLBACK: huge page fault failed, fall back to small
* @VM_FAULT_DONE_COW: ->fault has fully handled COW
* @VM_FAULT_NEEDDSYNC: ->fault did not modify page tables and needs
@@ -1678,10 +1679,11 @@ enum vm_fault_reason {
VM_FAULT_NOPAGE = (__force vm_fault_t)0x000100,
VM_FAULT_LOCKED = (__force vm_fault_t)0x000200,
VM_FAULT_RETRY = (__force vm_fault_t)0x000400,
- VM_FAULT_FALLBACK = (__force vm_fault_t)0x000800,
- VM_FAULT_DONE_COW = (__force vm_fault_t)0x001000,
- VM_FAULT_NEEDDSYNC = (__force vm_fault_t)0x002000,
- VM_FAULT_COMPLETED = (__force vm_fault_t)0x004000,
+ VM_FAULT_RETRY_HARD = (__force vm_fault_t)0x000800,
+ VM_FAULT_FALLBACK = (__force vm_fault_t)0x001000,
+ VM_FAULT_DONE_COW = (__force vm_fault_t)0x002000,
+ VM_FAULT_NEEDDSYNC = (__force vm_fault_t)0x004000,
+ VM_FAULT_COMPLETED = (__force vm_fault_t)0x008000,
VM_FAULT_HINDEX_MASK = (__force vm_fault_t)0x0f0000,
};
diff --git a/mm/memory.c b/mm/memory.c
index 7c020995eafc..b3e7ffdd83f9 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -3797,7 +3797,7 @@ static inline vm_fault_t vmf_can_call_fault(const struct vm_fault *vmf)
if (vma->vm_ops->map_pages || !(vmf->flags & FAULT_FLAG_VMA_LOCK))
return 0;
vma_end_read(vma);
- return VM_FAULT_RETRY;
+ return VM_FAULT_RETRY | VM_FAULT_RETRY_HARD;
}
/**
@@ -3824,7 +3824,7 @@ vm_fault_t __vmf_anon_prepare(struct vm_fault *vmf)
return 0;
if (vmf->flags & FAULT_FLAG_VMA_LOCK) {
if (!mmap_read_trylock(vma->vm_mm))
- return VM_FAULT_RETRY;
+ return VM_FAULT_RETRY | VM_FAULT_RETRY_HARD;
}
if (__anon_vma_prepare(vma))
ret = VM_FAULT_OOM;
@@ -4778,7 +4778,7 @@ vm_fault_t do_swap_page(struct vm_fault *vmf)
* under VMA lock.
*/
vma_end_read(vma);
- ret = VM_FAULT_RETRY;
+ ret = VM_FAULT_RETRY | VM_FAULT_RETRY_HARD;
goto out;
}
For the second step, we can move forward with your approach of
ripping out the PF retry code, after getting in touch with the
owners of those popular apps one by one to understand why they are
doing this and whether they can find a different approach. In
short, this would allow for a one- or two-year transition period.
What do you think about that?
[1] https://lore.kernel.org/linux-mm/CAGsJ_4xC5LdhuoWV1=tK-RZ5rkjc8aOKOkmb1L_8BG_3gtJhDg@mail.gmail.com/
^ permalink raw reply related
* [PATCH] ASoC: rockchip: i2s: Use managed hclk and runtime PM cleanup
From: Cássio Gabriel @ 2026-05-22 2:30 UTC (permalink / raw)
To: Liam Girdwood, Mark Brown, Takashi Iwai, Jaroslav Kysela,
Heiko Stuebner
Cc: linux-sound, linux-arm-kernel, linux-rockchip, linux-kernel,
Cássio Gabriel
The Rockchip I2S driver mixes devm-managed probe resources with manual
runtime PM and hclk cleanup. This leaves the remove path doing runtime PM
shutdown and clock disable before devm-managed ASoC and PCM resources are
released.
Keep the bus clock enabled for the device lifetime with
devm_clk_get_enabled(), and move the runtime PM teardown into devres so the
unwind order matches the managed registrations. This also removes the
remove callback, which only existed for cleanup.
Use a devm action for the final runtime suspend and register it before the
managed runtime PM action, so teardown disables runtime PM before forcing
the device into the suspended state.
Signed-off-by: Cássio Gabriel <cassiogabrielcontato@gmail.com>
---
sound/soc/rockchip/rockchip_i2s.c | 68 +++++++++++++++------------------------
1 file changed, 26 insertions(+), 42 deletions(-)
diff --git a/sound/soc/rockchip/rockchip_i2s.c b/sound/soc/rockchip/rockchip_i2s.c
index 49ff86b35ef1..4e3af0f37941 100644
--- a/sound/soc/rockchip/rockchip_i2s.c
+++ b/sound/soc/rockchip/rockchip_i2s.c
@@ -664,6 +664,14 @@ static const struct of_device_id rockchip_i2s_match[] __maybe_unused = {
};
MODULE_DEVICE_TABLE(of, rockchip_i2s_match);
+static void rockchip_i2s_suspend(void *data)
+{
+ struct device *dev = data;
+
+ if (!pm_runtime_status_suspended(dev))
+ i2s_runtime_suspend(dev);
+}
+
static int rockchip_i2s_init_dai(struct rk_i2s_dev *i2s, struct resource *res,
struct snd_soc_dai_driver **dp)
{
@@ -758,37 +766,28 @@ static int rockchip_i2s_probe(struct platform_device *pdev)
}
/* try to prepare related clocks */
- i2s->hclk = devm_clk_get(&pdev->dev, "i2s_hclk");
+ i2s->hclk = devm_clk_get_enabled(&pdev->dev, "i2s_hclk");
if (IS_ERR(i2s->hclk)) {
dev_err(&pdev->dev, "Can't retrieve i2s bus clock\n");
return PTR_ERR(i2s->hclk);
}
- ret = clk_prepare_enable(i2s->hclk);
- if (ret) {
- dev_err(i2s->dev, "hclock enable failed %d\n", ret);
- return ret;
- }
i2s->mclk = devm_clk_get(&pdev->dev, "i2s_clk");
if (IS_ERR(i2s->mclk)) {
dev_err(&pdev->dev, "Can't retrieve i2s master clock\n");
- ret = PTR_ERR(i2s->mclk);
- goto err_clk;
+ return PTR_ERR(i2s->mclk);
}
regs = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
- if (IS_ERR(regs)) {
- ret = PTR_ERR(regs);
- goto err_clk;
- }
+ if (IS_ERR(regs))
+ return PTR_ERR(regs);
i2s->regmap = devm_regmap_init_mmio(&pdev->dev, regs,
&rockchip_i2s_regmap_config);
if (IS_ERR(i2s->regmap)) {
dev_err(&pdev->dev,
"Failed to initialise managed register map\n");
- ret = PTR_ERR(i2s->regmap);
- goto err_clk;
+ return PTR_ERR(i2s->regmap);
}
i2s->bclk_ratio = 64;
@@ -799,8 +798,7 @@ static int rockchip_i2s_probe(struct platform_device *pdev)
i2s->bclk_off = pinctrl_lookup_state(i2s->pinctrl, "bclk_off");
if (IS_ERR_OR_NULL(i2s->bclk_off)) {
dev_err(&pdev->dev, "failed to find i2s bclk_off\n");
- ret = -EINVAL;
- goto err_clk;
+ return -EINVAL;
}
}
} else {
@@ -811,16 +809,23 @@ static int rockchip_i2s_probe(struct platform_device *pdev)
dev_set_drvdata(&pdev->dev, i2s);
- pm_runtime_enable(&pdev->dev);
+ ret = devm_add_action(&pdev->dev, rockchip_i2s_suspend, &pdev->dev);
+ if (ret)
+ return ret;
+
+ ret = devm_pm_runtime_enable(&pdev->dev);
+ if (ret)
+ return ret;
+
if (!pm_runtime_enabled(&pdev->dev)) {
ret = i2s_runtime_resume(&pdev->dev);
if (ret)
- goto err_pm_disable;
+ return ret;
}
ret = rockchip_i2s_init_dai(i2s, res, &dai);
if (ret)
- goto err_pm_disable;
+ return ret;
ret = devm_snd_soc_register_component(&pdev->dev,
&rockchip_i2s_component,
@@ -828,36 +833,16 @@ static int rockchip_i2s_probe(struct platform_device *pdev)
if (ret) {
dev_err(&pdev->dev, "Could not register DAI\n");
- goto err_suspend;
+ return ret;
}
ret = devm_snd_dmaengine_pcm_register(&pdev->dev, NULL, 0);
if (ret) {
dev_err(&pdev->dev, "Could not register PCM\n");
- goto err_suspend;
+ return ret;
}
return 0;
-
-err_suspend:
- if (!pm_runtime_status_suspended(&pdev->dev))
- i2s_runtime_suspend(&pdev->dev);
-err_pm_disable:
- pm_runtime_disable(&pdev->dev);
-err_clk:
- clk_disable_unprepare(i2s->hclk);
- return ret;
-}
-
-static void rockchip_i2s_remove(struct platform_device *pdev)
-{
- struct rk_i2s_dev *i2s = dev_get_drvdata(&pdev->dev);
-
- pm_runtime_disable(&pdev->dev);
- if (!pm_runtime_status_suspended(&pdev->dev))
- i2s_runtime_suspend(&pdev->dev);
-
- clk_disable_unprepare(i2s->hclk);
}
static const struct dev_pm_ops rockchip_i2s_pm_ops = {
@@ -866,7 +851,6 @@ static const struct dev_pm_ops rockchip_i2s_pm_ops = {
static struct platform_driver rockchip_i2s_driver = {
.probe = rockchip_i2s_probe,
- .remove = rockchip_i2s_remove,
.driver = {
.name = DRV_NAME,
.of_match_table = of_match_ptr(rockchip_i2s_match),
---
base-commit: 40cc9602caf2539369bd3dd7d66ee67e204e75ef
change-id: 20260521-asoc-rockchip-i2s-devm-cleanup-6cade5f495e5
Best regards,
--
Cássio Gabriel <cassiogabrielcontato@gmail.com>
^ permalink raw reply related
* Re: [PATCH v3 5/9] KVM: arm64: selftests: Add shadow_stage2 test
From: Itaru Kitayama @ 2026-05-22 2:02 UTC (permalink / raw)
To: Wei-Lin Chang
Cc: linux-kernel, kvm, linux-kselftest, linux-arm-kernel, kvmarm,
Paolo Bonzini, Shuah Khan, Marc Zyngier, Oliver Upton, Joey Gouly,
Suzuki K Poulose, Zenghui Yu, Catalin Marinas, Will Deacon
In-Reply-To: <20260516183003.799058-6-weilin.chang@arm.com>
On Sat, May 16, 2026 at 07:29:59PM +0100, Wei-Lin Chang wrote:
> The shadow_stage2 test is aimed to exercise the shadow page table
> management code in KVM. In this first patch a basic test similar to
> hello_nested is created. Right now it doesn't turn on stage-2 for the
> nested guest (L2) yet, therefore the shadow page table code in KVM will
> only be triggered minimally now.
>
> Signed-off-by: Wei-Lin Chang <weilin.chang@arm.com>
> ---
> tools/testing/selftests/kvm/Makefile.kvm | 1 +
> .../selftests/kvm/arm64/shadow_stage2.c | 128 ++++++++++++++++++
> 2 files changed, 129 insertions(+)
> create mode 100644 tools/testing/selftests/kvm/arm64/shadow_stage2.c
>
> diff --git a/tools/testing/selftests/kvm/Makefile.kvm b/tools/testing/selftests/kvm/Makefile.kvm
> index e8c108e0c487..c0fac2ba1339 100644
> --- a/tools/testing/selftests/kvm/Makefile.kvm
> +++ b/tools/testing/selftests/kvm/Makefile.kvm
> @@ -176,6 +176,7 @@ TEST_GEN_PROGS_arm64 += arm64/page_fault_test
> TEST_GEN_PROGS_arm64 += arm64/psci_test
> TEST_GEN_PROGS_arm64 += arm64/sea_to_user
> TEST_GEN_PROGS_arm64 += arm64/set_id_regs
> +TEST_GEN_PROGS_arm64 += arm64/shadow_stage2
> TEST_GEN_PROGS_arm64 += arm64/smccc_filter
> TEST_GEN_PROGS_arm64 += arm64/vcpu_width_config
> TEST_GEN_PROGS_arm64 += arm64/vgic_init
> diff --git a/tools/testing/selftests/kvm/arm64/shadow_stage2.c b/tools/testing/selftests/kvm/arm64/shadow_stage2.c
> new file mode 100644
> index 000000000000..cf76a2b0582d
> --- /dev/null
> +++ b/tools/testing/selftests/kvm/arm64/shadow_stage2.c
> @@ -0,0 +1,128 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/*
> + * shadow_stage2 - Test correctness of shadow stage 2
> + */
> +
> +#include "nested.h"
> +#include "processor.h"
> +#include "test_util.h"
> +#include "ucall.h"
> +
> +#define XLATE2GPA (0xABCD)
> +#define L2STACKSZ (0x100)
> +
> +#define L2SUCCESS (0x0)
> +#define L2FAILED (0x1)
> +#define L2SYNC (0x2)
> +
> +/*
> + * TPIDR_EL2 is used to store vcpu id, so save and restore it.
> + */
> +static gpa_t ucall_translate_to_gpa(void *gva)
> +{
> + gpa_t gpa;
> + u64 vcpu_id = read_sysreg(tpidr_el2);
> +
> + GUEST_SYNC2(XLATE2GPA, gva);
> +
> + /* get the result from userspace */
> + gpa = read_sysreg(tpidr_el2);
> +
> + write_sysreg(vcpu_id, tpidr_el2);
> +
> + return gpa;
> +}
> +
> +static void l2_guest_code(void)
> +{
> + do_hvc(L2SYNC, 10, 0);
> + do_hvc(L2SYNC, 20, 0);
> + do_hvc(L2SYNC, 30, 0);
> +
> + do_hvc(L2SUCCESS, 0, 0);
> +}
> +
> +static void guest_code(void)
> +{
> + struct vcpu vcpu;
> + struct hyp_data hyp_data;
> + int ret, i = 0;
> + gpa_t l2_pc, l2_stack_top;
> + /* force 16-byte alignment for the stack pointer */
> + u8 l2_stack[L2STACKSZ] __attribute__((aligned(16)));
> +
> + GUEST_ASSERT_EQ(get_current_el(), 2);
> + GUEST_PRINTF("vEL2 entry\n");
> +
> + l2_pc = ucall_translate_to_gpa(l2_guest_code);
> + l2_stack_top = ucall_translate_to_gpa(&l2_stack[L2STACKSZ]);
> +
> + init_vcpu(&vcpu, l2_pc, l2_stack_top);
> + prepare_hyp();
> +
> + while (true) {
> + GUEST_PRINTF("L2 enter\n");
> + ret = run_l2(&vcpu, &hyp_data);
> + GUEST_PRINTF("L2 exit\n");
> + GUEST_ASSERT_EQ(ret, ARM_EXCEPTION_TRAP);
> + GUEST_ASSERT_EQ(ESR_ELx_EC(read_sysreg(esr_el2)), ESR_ELx_EC_HVC64);
> +
> + if (vcpu.context.regs.regs[0] == L2SYNC)
> + GUEST_SYNC3(L2SYNC, i++, vcpu.context.regs.regs[1]);
> + else
> + break;
> + }
> +
> + if (vcpu.context.regs.regs[0] != L2SUCCESS)
> + GUEST_FAIL("L2 failed\n");
> +
> + GUEST_PRINTF("L2 success!\n");
> + GUEST_DONE();
> +}
> +
> +int main(void)
> +{
> + struct kvm_vcpu_init init;
> + struct kvm_vcpu *vcpu;
> + struct kvm_vm *vm;
> + struct ucall uc;
> + gpa_t gpa;
> +
> + TEST_REQUIRE(kvm_check_cap(KVM_CAP_ARM_EL2));
> + vm = vm_create(1);
This assumes the default P40V48 4KB guest creation, so perhaps you'd
want to change this to __vm_create(VM_SHAPE(), 1, 0) so the test runs too on other
16KB and 64KB kernels? I've been testing it with your stage 2 unmapping
optimization series together with this v3 KVM selftest series.
Thanks,
Itaru.
> +
> + kvm_get_default_vcpu_target(vm, &init);
> + init.features[0] |= BIT(KVM_ARM_VCPU_HAS_EL2);
> + vcpu = aarch64_vcpu_add(vm, 0, &init, guest_code);
> + kvm_arch_vm_finalize_vcpus(vm);
> +
> + while (true) {
> + vcpu_run(vcpu);
> +
> + switch (get_ucall(vcpu, &uc)) {
> + case UCALL_SYNC:
> + if (uc.args[0] == XLATE2GPA) {
> + gpa = addr_gva2gpa(vm, (gva_t)uc.args[1]);
> + vcpu_set_reg(vcpu, KVM_ARM64_SYS_REG(SYS_TPIDR_EL2), gpa);
> + }
> + if (uc.args[0] == L2SYNC)
> + pr_info("L2SYNC, L1 info: %ld, L2 info: %ld\n", uc.args[1], uc.args[2]);
> + break;
> + case UCALL_PRINTF:
> + pr_info("[L1] %s", uc.buffer);
> + break;
> + case UCALL_DONE:
> + pr_info("DONE!\n");
> + goto end;
> + case UCALL_ABORT:
> + REPORT_GUEST_ASSERT(uc);
> + fallthrough;
> + default:
> + TEST_FAIL("Unhandled ucall: %ld\n", uc.cmd);
> + }
> + }
> +
> +end:
> + kvm_vm_free(vm);
> + return 0;
> +}
> --
> 2.43.0
>
^ permalink raw reply
* [PATCH v3 2/8] bpf: Recover arena kernel faults with scratch page
From: Tejun Heo @ 2026-05-22 1:59 UTC (permalink / raw)
To: David Vernet, Andrea Righi, Changwoo Min, Alexei Starovoitov,
Andrii Nakryiko, Daniel Borkmann, Martin KaFai Lau,
Kumar Kartikeya Dwivedi
Cc: Peter Zijlstra, Catalin Marinas, Will Deacon, Thomas Gleixner,
Ingo Molnar, Borislav Petkov, Dave Hansen, Andrew Morton,
David Hildenbrand, Mike Rapoport, Emil Tsalapatis,
kernel test robot, sched-ext, bpf, x86, linux-arm-kernel,
linux-mm, linux-kernel, Tejun Heo
In-Reply-To: <20260520235052.4180316-1-tj@kernel.org>
From: Kumar Kartikeya Dwivedi <memxor@gmail.com>
BPF arena usage is becoming more prevalent, but kernel <-> BPF communication
over arena memory is awkward today. Data has to be staged through a trusted
kernel pointer with extra code and copying on the BPF side. While reads
through arena pointers can use a fault-safe helper, writes don't have a good
solution. The in-line alternative would need instruction emulation or asm
fixup labels.
Enable direct kernel-side reads and writes within GUARD_SZ / 2 of any
handed-in arena pointer, without bounds checking. A per-arena scratch page
is installed by the arch fault path into empty arena kernel PTEs - x86 from
page_fault_oops() for not-present faults, arm64 from __do_kernel_fault() for
translation faults, both after the existing exception-table and KFENCE
handling. The faulting instruction retries and the access is also reported
through the program's BPF stream, preserving error reporting.
bpf_prog_find_from_stack() resolves the current BPF program (and its arena)
from the kernel stack - no new bpf_run_ctx state is added. Recovery covers
the 4 GiB arena plus the upper half-guard (GUARD_SZ / 2). The lower
half-guard is excluded because well-behaved kfuncs only access forward from
arena pointers. The kfunc-author contract - access at most GUARD_SZ / 2 past
a handed-in pointer - is documented in Documentation/bpf/kfuncs.rst.
The install is lock-free via ptep_try_set(). On race-loss the winning
installer's PTE is already valid, so the access retry succeeds. The arena
clear path uses ptep_get_and_clear() so installer and clearer race through
atomic accessors. No flush_tlb_kernel_range() afterwards. Stale "not mapped"
entries just cause one extra re-fault, cheaper than a global IPI on every
install.
Scratch exists only to keep the kernel from oopsing on an in-line arena
access. Its presence at a PTE means the BPF program has already
malfunctioned, and the violation is reported through the program's BPF
stream. The only requirement for behavior on a scratched PTE is that the
kernel doesn't crash. In particular, any user-side access through such a PTE
may segfault. The shared scratch page is freed once during map destruction.
BPF instruction faults continue to use the existing JIT exception-table
path. This patch changes only the kernel-text fault path. No UAPI flag is
added. The new behavior is the default.
v2: Use ptep_get_and_clear() in apply_range_clear_cb(). (David)
v3: Stub bpf_arena_handle_page_fault() for !CONFIG_BPF_SYSCALL. (lkp)
Suggested-by: Alexei Starovoitov <ast@kernel.org>
Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
Signed-off-by: Tejun Heo <tj@kernel.org>
Cc: David Hildenbrand <david@kernel.org>
---
Re-posting just patch 2/8 of the v3 series with the build fix. Will post
a full v4 rolling up all patches later if needed.
Documentation/bpf/kfuncs.rst | 14 +++
arch/arm64/mm/fault.c | 10 +-
arch/x86/mm/fault.c | 12 ++-
include/linux/bpf.h | 1 +
include/linux/bpf_defs.h | 19 ++++
kernel/bpf/arena.c | 177 +++++++++++++++++++++++++++--------
kernel/bpf/core.c | 5 +
7 files changed, 191 insertions(+), 47 deletions(-)
create mode 100644 include/linux/bpf_defs.h
diff --git a/Documentation/bpf/kfuncs.rst b/Documentation/bpf/kfuncs.rst
index 75e6c078e0e7..6d497e720998 100644
--- a/Documentation/bpf/kfuncs.rst
+++ b/Documentation/bpf/kfuncs.rst
@@ -462,6 +462,20 @@ In order to accommodate such requirements, the verifier will enforce strict
PTR_TO_BTF_ID type matching if two types have the exact same name, with one
being suffixed with ``___init``.
+2.8 Accessing arena memory through kfunc arguments
+--------------------------------------------------
+
+A read or write at any address inside an arena does not oops the kernel.
+Unallocated arena pages are lazily backed by a scratch page and the
+access is reported through the program's BPF stream as an error. Only
+the BPF program's correctness is affected; the kernel itself remains
+intact.
+
+The arena is followed by a ``GUARD_SZ / 2`` (32 KiB) guard region that
+is also covered by this recovery. A kfunc handed an arena pointer may
+therefore access up to ``GUARD_SZ / 2`` past it without bounds-checking
+against the arena. Larger accesses must verify the range explicitly.
+
.. _BPF_kfunc_lifecycle_expectations:
3. kfunc lifecycle expectations
diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c
index 920a8b244d59..0d58d667fcd8 100644
--- a/arch/arm64/mm/fault.c
+++ b/arch/arm64/mm/fault.c
@@ -9,6 +9,7 @@
#include <linux/acpi.h>
#include <linux/bitfield.h>
+#include <linux/bpf_defs.h>
#include <linux/extable.h>
#include <linux/kfence.h>
#include <linux/signal.h>
@@ -416,9 +417,12 @@ static void __do_kernel_fault(unsigned long addr, unsigned long esr,
} else if (addr < PAGE_SIZE) {
msg = "NULL pointer dereference";
} else {
- if (esr_fsc_is_translation_fault(esr) &&
- kfence_handle_page_fault(addr, esr & ESR_ELx_WNR, regs))
- return;
+ if (esr_fsc_is_translation_fault(esr)) {
+ if (kfence_handle_page_fault(addr, esr & ESR_ELx_WNR, regs))
+ return;
+ if (bpf_arena_handle_page_fault(addr, esr & ESR_ELx_WNR, regs->pc))
+ return;
+ }
msg = "paging request";
}
diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c
index f0e77e084482..b0f103ddbd23 100644
--- a/arch/x86/mm/fault.c
+++ b/arch/x86/mm/fault.c
@@ -8,6 +8,7 @@
#include <linux/sched/task_stack.h> /* task_stack_*(), ... */
#include <linux/kdebug.h> /* oops_begin/end, ... */
#include <linux/memblock.h> /* max_low_pfn */
+#include <linux/bpf_defs.h> /* bpf_arena_handle_page_fault */
#include <linux/kfence.h> /* kfence_handle_page_fault */
#include <linux/kprobes.h> /* NOKPROBE_SYMBOL, ... */
#include <linux/mmiotrace.h> /* kmmio_handler, ... */
@@ -688,10 +689,13 @@ page_fault_oops(struct pt_regs *regs, unsigned long error_code,
if (IS_ENABLED(CONFIG_EFI))
efi_crash_gracefully_on_page_fault(address);
- /* Only not-present faults should be handled by KFENCE. */
- if (!(error_code & X86_PF_PROT) &&
- kfence_handle_page_fault(address, error_code & X86_PF_WRITE, regs))
- return;
+ /* Only not-present faults should be handled by KFENCE or BPF arena. */
+ if (!(error_code & X86_PF_PROT)) {
+ if (kfence_handle_page_fault(address, error_code & X86_PF_WRITE, regs))
+ return;
+ if (bpf_arena_handle_page_fault(address, error_code & X86_PF_WRITE, regs->ip))
+ return;
+ }
oops:
/*
diff --git a/include/linux/bpf.h b/include/linux/bpf.h
index 0136a108d083..831996c411cf 100644
--- a/include/linux/bpf.h
+++ b/include/linux/bpf.h
@@ -6,6 +6,7 @@
#include <uapi/linux/bpf.h>
#include <uapi/linux/filter.h>
+#include <linux/bpf_defs.h>
#include <crypto/sha2.h>
#include <linux/workqueue.h>
diff --git a/include/linux/bpf_defs.h b/include/linux/bpf_defs.h
new file mode 100644
index 000000000000..2185cd3966d4
--- /dev/null
+++ b/include/linux/bpf_defs.h
@@ -0,0 +1,19 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Subset of bpf.h declarations, split out so files that need only these
+ * declarations can avoid bpf.h's full include cost.
+ */
+#ifndef _LINUX_BPF_DEFS_H
+#define _LINUX_BPF_DEFS_H
+
+#ifdef CONFIG_BPF_SYSCALL
+bool bpf_arena_handle_page_fault(unsigned long addr, bool is_write, unsigned long fault_ip);
+#else
+static inline bool bpf_arena_handle_page_fault(unsigned long addr, bool is_write,
+ unsigned long fault_ip)
+{
+ return false;
+}
+#endif
+
+#endif /* _LINUX_BPF_DEFS_H */
diff --git a/kernel/bpf/arena.c b/kernel/bpf/arena.c
index 08d008cc471e..1c0b87ecc817 100644
--- a/kernel/bpf/arena.c
+++ b/kernel/bpf/arena.c
@@ -53,6 +53,7 @@ struct bpf_arena {
u64 user_vm_start;
u64 user_vm_end;
struct vm_struct *kern_vm;
+ struct page *scratch_page;
struct range_tree rt;
/* protects rt */
rqspinlock_t spinlock;
@@ -118,6 +119,11 @@ struct apply_range_data {
int i;
};
+struct clear_range_data {
+ struct llist_head *free_pages;
+ struct page *scratch_page;
+};
+
static int apply_range_set_cb(pte_t *pte, unsigned long addr, void *data)
{
struct apply_range_data *d = data;
@@ -144,33 +150,59 @@ static void flush_vmap_cache(unsigned long start, unsigned long size)
flush_cache_vmap(start, start + size);
}
-static int apply_range_clear_cb(pte_t *pte, unsigned long addr, void *free_pages)
+static int apply_range_clear_cb(pte_t *pte, unsigned long addr, void *data)
{
+ struct clear_range_data *d = data;
pte_t old_pte;
struct page *page;
- /* sanity check */
- old_pte = ptep_get(pte);
+ /*
+ * Pairs with ptep_try_set() in the kernel-fault scratch installer.
+ * Both sides must be atomic.
+ */
+ old_pte = ptep_get_and_clear(&init_mm, addr, pte);
if (pte_none(old_pte) || !pte_present(old_pte))
- return 0; /* nothing to do */
+ return 0;
page = pte_page(old_pte);
if (WARN_ON_ONCE(!page))
return -EINVAL;
- pte_clear(&init_mm, addr, pte);
+ /*
+ * Skip the per-arena scratch page. A kernel fault on an unallocated uaddr
+ * scratches its PTE. A later bpf_arena_free_pages() over that range walks
+ * here. Without the skip, scratch_page would be freed.
+ */
+ if (page == d->scratch_page)
+ return 0;
+
+ __llist_add(&page->pcp_llist, d->free_pages);
+ return 0;
+}
- /* Add page to the list so it is freed later */
- if (free_pages)
- __llist_add(&page->pcp_llist, free_pages);
+static int apply_range_set_scratch_cb(pte_t *pte, unsigned long addr, void *data)
+{
+ struct page *scratch_page = data;
+ if (!pte_none(ptep_get(pte)))
+ return 0;
+ /*
+ * Best-effort install. ptep_try_set() returns false only if another
+ * installer (real allocation or concurrent fault) won the cmpxchg.
+ * Their PTE is already valid, so the access retry succeeds.
+ *
+ * No flush_tlb_kernel_range() needed. Stale "not mapped" entries just
+ * cause one extra re-fault through this same path.
+ */
+ ptep_try_set(pte, mk_pte(scratch_page, PAGE_KERNEL));
return 0;
}
static int populate_pgtable_except_pte(struct bpf_arena *arena)
{
+ /* Populate intermediates for the recovery range (4 GiB + upper half-guard). */
return apply_to_page_range(&init_mm, bpf_arena_get_kern_vm_start(arena),
- KERN_VM_SZ - GUARD_SZ, apply_range_set_cb, NULL);
+ SZ_4G + GUARD_SZ / 2, apply_range_set_cb, NULL);
}
static struct bpf_map *arena_map_alloc(union bpf_attr *attr)
@@ -221,22 +253,29 @@ static struct bpf_map *arena_map_alloc(union bpf_attr *attr)
init_irq_work(&arena->free_irq, arena_free_irq);
INIT_WORK(&arena->free_work, arena_free_worker);
bpf_map_init_from_attr(&arena->map, attr);
+
+ err = bpf_map_alloc_pages(&arena->map, NUMA_NO_NODE, 1, &arena->scratch_page);
+ if (err)
+ goto err_free_arena;
+
range_tree_init(&arena->rt);
err = range_tree_set(&arena->rt, 0, attr->max_entries);
- if (err) {
- bpf_map_area_free(arena);
- goto err;
- }
+ if (err)
+ goto err_free_scratch;
mutex_init(&arena->lock);
raw_res_spin_lock_init(&arena->spinlock);
err = populate_pgtable_except_pte(arena);
- if (err) {
- range_tree_destroy(&arena->rt);
- bpf_map_area_free(arena);
- goto err;
- }
+ if (err)
+ goto err_destroy_rt;
return &arena->map;
+
+err_destroy_rt:
+ range_tree_destroy(&arena->rt);
+err_free_scratch:
+ __free_page(arena->scratch_page);
+err_free_arena:
+ bpf_map_area_free(arena);
err:
free_vm_area(kern_vm);
return ERR_PTR(err);
@@ -244,6 +283,7 @@ static struct bpf_map *arena_map_alloc(union bpf_attr *attr)
static int existing_page_cb(pte_t *ptep, unsigned long addr, void *data)
{
+ struct bpf_arena *arena = data;
struct page *page;
pte_t pte;
@@ -251,6 +291,12 @@ static int existing_page_cb(pte_t *ptep, unsigned long addr, void *data)
if (!pte_present(pte)) /* sanity check */
return 0;
page = pte_page(pte);
+ /*
+ * Skip the scratch page. The walk is page-table-driven, not range-tree-driven,
+ * so it can visit scratch PTEs at uaddrs the BPF program never allocated.
+ */
+ if (page == arena->scratch_page)
+ return 0;
/*
* We do not update pte here:
* 1. Nobody should be accessing bpf_arena's range outside of a kernel bug
@@ -286,9 +332,10 @@ static void arena_map_free(struct bpf_map *map)
* free those pages.
*/
apply_to_existing_page_range(&init_mm, bpf_arena_get_kern_vm_start(arena),
- KERN_VM_SZ - GUARD_SZ, existing_page_cb, NULL);
+ SZ_4G + GUARD_SZ / 2, existing_page_cb, arena);
free_vm_area(arena->kern_vm);
range_tree_destroy(&arena->rt);
+ __free_page(arena->scratch_page);
bpf_map_area_free(arena);
}
@@ -374,33 +421,37 @@ static vm_fault_t arena_vm_fault(struct vm_fault *vmf)
return VM_FAULT_RETRY;
page = vmalloc_to_page((void *)kaddr);
- if (page)
+ if (page) {
+ if (page == arena->scratch_page)
+ /* BPF triggered scratch here; don't lazy-alloc over it */
+ goto out_sigsegv;
/* already have a page vmap-ed */
goto out;
+ }
bpf_map_memcg_enter(&arena->map, &old_memcg, &new_memcg);
if (arena->map.map_flags & BPF_F_SEGV_ON_FAULT)
/* User space requested to segfault when page is not allocated by bpf prog */
- goto out_unlock_sigsegv;
+ goto out_sigsegv_memcg;
ret = range_tree_clear(&arena->rt, vmf->pgoff, 1);
if (ret)
- goto out_unlock_sigsegv;
+ goto out_sigsegv_memcg;
struct apply_range_data data = { .pages = &page, .i = 0 };
/* Account into memcg of the process that created bpf_arena */
ret = bpf_map_alloc_pages(map, NUMA_NO_NODE, 1, &page);
if (ret) {
range_tree_set(&arena->rt, vmf->pgoff, 1);
- goto out_unlock_sigsegv;
+ goto out_sigsegv_memcg;
}
ret = apply_to_page_range(&init_mm, kaddr, PAGE_SIZE, apply_range_set_cb, &data);
if (ret) {
range_tree_set(&arena->rt, vmf->pgoff, 1);
free_pages_nolock(page, 0);
- goto out_unlock_sigsegv;
+ goto out_sigsegv_memcg;
}
flush_vmap_cache(kaddr, PAGE_SIZE);
bpf_map_memcg_exit(old_memcg, new_memcg);
@@ -409,8 +460,9 @@ static vm_fault_t arena_vm_fault(struct vm_fault *vmf)
raw_res_spin_unlock_irqrestore(&arena->spinlock, flags);
vmf->page = page;
return 0;
-out_unlock_sigsegv:
+out_sigsegv_memcg:
bpf_map_memcg_exit(old_memcg, new_memcg);
+out_sigsegv:
raw_res_spin_unlock_irqrestore(&arena->spinlock, flags);
return VM_FAULT_SIGSEGV;
}
@@ -668,6 +720,7 @@ static void arena_free_pages(struct bpf_arena *arena, long uaddr, long page_cnt,
struct llist_head free_pages;
struct llist_node *pos, *t;
struct arena_free_span *s;
+ struct clear_range_data cdata;
unsigned long flags;
int ret = 0;
@@ -696,9 +749,11 @@ static void arena_free_pages(struct bpf_arena *arena, long uaddr, long page_cnt,
range_tree_set(&arena->rt, pgoff, page_cnt);
init_llist_head(&free_pages);
+ cdata.free_pages = &free_pages;
+ cdata.scratch_page = arena->scratch_page;
/* clear ptes and collect struct pages */
apply_to_existing_page_range(&init_mm, kaddr, page_cnt << PAGE_SHIFT,
- apply_range_clear_cb, &free_pages);
+ apply_range_clear_cb, &cdata);
/* drop the lock to do the tlb flush and zap pages */
raw_res_spin_unlock_irqrestore(&arena->spinlock, flags);
@@ -788,6 +843,7 @@ static void arena_free_worker(struct work_struct *work)
struct arena_free_span *s;
u64 arena_vm_start, user_vm_start;
struct llist_head free_pages;
+ struct clear_range_data cdata;
struct page *page;
unsigned long full_uaddr;
long kaddr, page_cnt, pgoff;
@@ -801,6 +857,8 @@ static void arena_free_worker(struct work_struct *work)
bpf_map_memcg_enter(&arena->map, &old_memcg, &new_memcg);
init_llist_head(&free_pages);
+ cdata.free_pages = &free_pages;
+ cdata.scratch_page = arena->scratch_page;
arena_vm_start = bpf_arena_get_kern_vm_start(arena);
user_vm_start = bpf_arena_get_user_vm_start(arena);
@@ -813,7 +871,7 @@ static void arena_free_worker(struct work_struct *work)
/* clear ptes and collect pages in free_pages llist */
apply_to_existing_page_range(&init_mm, kaddr, page_cnt << PAGE_SHIFT,
- apply_range_clear_cb, &free_pages);
+ apply_range_clear_cb, &cdata);
range_tree_set(&arena->rt, pgoff, page_cnt);
}
@@ -928,23 +986,12 @@ static int __init kfunc_init(void)
}
late_initcall(kfunc_init);
-void bpf_prog_report_arena_violation(bool write, unsigned long addr, unsigned long fault_ip)
+static void __bpf_prog_report_arena_violation(struct bpf_prog *prog, bool write,
+ unsigned long addr, unsigned long fault_ip)
{
struct bpf_stream_stage ss;
- struct bpf_prog *prog;
u64 user_vm_start;
- /*
- * The RCU read lock is held to safely traverse the latch tree, but we
- * don't need its protection when accessing the prog, since it will not
- * disappear while we are handling the fault.
- */
- rcu_read_lock();
- prog = bpf_prog_ksym_find(fault_ip);
- rcu_read_unlock();
- if (!prog)
- return;
-
/* Use main prog for stream access */
prog = prog->aux->main_prog_aux->prog;
@@ -957,3 +1004,53 @@ void bpf_prog_report_arena_violation(bool write, unsigned long addr, unsigned lo
bpf_stream_dump_stack(ss);
}));
}
+
+bool bpf_arena_handle_page_fault(unsigned long addr, bool is_write, unsigned long fault_ip)
+{
+ struct bpf_arena *arena;
+ struct bpf_prog *prog;
+ unsigned long kbase;
+ unsigned long page_addr = addr & PAGE_MASK;
+
+ prog = bpf_prog_find_from_stack();
+ if (!prog)
+ return false;
+
+ arena = prog->aux->arena;
+ /* a prog not using arena may be on stack, so arena can be NULL */
+ if (!arena)
+ return false;
+
+ kbase = bpf_arena_get_kern_vm_start(arena);
+
+ /*
+ * Recovery covers the 4 GiB mappable band plus the upper half-guard.
+ * Lower guard is unreachable from kfuncs; an address there indicates
+ * a different bug class - leave it to the regular kernel oops path.
+ */
+ if (page_addr < kbase || page_addr >= kbase + SZ_4G + GUARD_SZ / 2)
+ return false;
+
+ apply_to_page_range(&init_mm, page_addr, PAGE_SIZE,
+ apply_range_set_scratch_cb, arena->scratch_page);
+ flush_vmap_cache(page_addr, PAGE_SIZE);
+ __bpf_prog_report_arena_violation(prog, is_write, page_addr - kbase, fault_ip);
+ return true;
+}
+
+void bpf_prog_report_arena_violation(bool write, unsigned long addr, unsigned long fault_ip)
+{
+ struct bpf_prog *prog;
+
+ /*
+ * The RCU read lock is held to safely traverse the latch tree, but we
+ * don't need its protection when accessing the prog, since it will not
+ * disappear while we are handling the fault.
+ */
+ rcu_read_lock();
+ prog = bpf_prog_ksym_find(fault_ip);
+ rcu_read_unlock();
+ if (!prog)
+ return;
+ __bpf_prog_report_arena_violation(prog, write, addr, fault_ip);
+}
diff --git a/kernel/bpf/core.c b/kernel/bpf/core.c
index 066b86e7233c..fa368d8920d9 100644
--- a/kernel/bpf/core.c
+++ b/kernel/bpf/core.c
@@ -3290,6 +3290,11 @@ __weak u64 bpf_arena_get_kern_vm_start(struct bpf_arena *arena)
{
return 0;
}
+__weak bool bpf_arena_handle_page_fault(unsigned long addr, bool is_write,
+ unsigned long fault_ip)
+{
+ return false;
+}
#ifdef CONFIG_BPF_SYSCALL
static int __init bpf_global_ma_init(void)
--
2.54.0
^ permalink raw reply related
* RE: [PATCH v4 4/6] media: synopsys: Add PHY stopstate wait for i.MX93
From: G.N. Zhou (OSS) @ 2026-05-22 1:58 UTC (permalink / raw)
To: Alexander Stein, Michael Riesch, Mauro Carvalho Chehab,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Heiko Stuebner,
Laurent Pinchart, Frank Li, Sakari Ailus, Bryan O'Donoghue,
Mehdi Djait, Hans Verkuil, G.N. Zhou (OSS), G.N. Zhou (OSS)
Cc: linux-media@vger.kernel.org, linux-kernel@vger.kernel.org,
devicetree@vger.kernel.org, imx@lists.linux.dev,
linux-arm-kernel@lists.infradead.org,
linux-rockchip@lists.infradead.org, G.N. Zhou (OSS)
In-Reply-To: <3606153.44csPzL39Z@steina-w>
Hi Alexander,
> -----Original Message-----
> From: Alexander Stein <alexander.stein@ew.tq-group.com>
> Sent: Thursday, May 21, 2026 7:53 PM
> To: Michael Riesch <michael.riesch@collabora.com>; Mauro Carvalho Chehab
> <mchehab@kernel.org>; Rob Herring <robh@kernel.org>; Krzysztof Kozlowski
> <krzk+dt@kernel.org>; Conor Dooley <conor+dt@kernel.org>; Heiko Stuebner
> <heiko@sntech.de>; Laurent Pinchart <laurent.pinchart@ideasonboard.com>;
> Frank Li <frank.li@nxp.com>; Sakari Ailus <sakari.ailus@linux.intel.com>; Bryan
> O'Donoghue <bryan.odonoghue@linaro.org>; Mehdi Djait
> <mehdi.djait@linux.intel.com>; Hans Verkuil <hverkuil+cisco@kernel.org>;
> G.N. Zhou (OSS) <guoniu.zhou@oss.nxp.com>; G.N. Zhou (OSS)
> <guoniu.zhou@oss.nxp.com>
> Cc: linux-media@vger.kernel.org; linux-kernel@vger.kernel.org;
> devicetree@vger.kernel.org; imx@lists.linux.dev; linux-arm-
> kernel@lists.infradead.org; linux-rockchip@lists.infradead.org; G.N. Zhou (OSS)
> <guoniu.zhou@oss.nxp.com>
> Subject: Re: [PATCH v4 4/6] media: synopsys: Add PHY stopstate wait for
> i.MX93
>
> Hi,
>
> thanks for the replay.
>
> Am Donnerstag, 21. Mai 2026, 11:29:39 CEST schrieb G.N. Zhou (OSS):
> > Hi Alexander,
> >
> > > -----Original Message-----
> > > From: Alexander Stein <alexander.stein@ew.tq-group.com>
> > > Sent: Wednesday, May 20, 2026 7:12 PM
> > > To: Michael Riesch <michael.riesch@collabora.com>; Mauro Carvalho
> > > Chehab <mchehab@kernel.org>; Rob Herring <robh@kernel.org>;
> > > Krzysztof Kozlowski <krzk+dt@kernel.org>; Conor Dooley
> > > <conor+dt@kernel.org>; Heiko Stuebner <heiko@sntech.de>; Laurent
> > > Pinchart <laurent.pinchart@ideasonboard.com>;
> > > Frank Li <frank.li@nxp.com>; Sakari Ailus
> > > <sakari.ailus@linux.intel.com>; Bryan O'Donoghue
> > > <bryan.odonoghue@linaro.org>; Mehdi Djait
> > > <mehdi.djait@linux.intel.com>; Hans Verkuil
> > > <hverkuil+cisco@kernel.org>; G.N. Zhou (OSS)
> > > <guoniu.zhou@oss.nxp.com>
> > > Cc: linux-media@vger.kernel.org; linux-kernel@vger.kernel.org;
> > > devicetree@vger.kernel.org; imx@lists.linux.dev; linux-arm-
> > > kernel@lists.infradead.org; linux-rockchip@lists.infradead.org; G.N.
> > > Zhou (OSS) <guoniu.zhou@oss.nxp.com>
> > > Subject: Re: [PATCH v4 4/6] media: synopsys: Add PHY stopstate wait
> > > for
> > > i.MX93
> > >
> > > Hi,
> > >
> > > Am Dienstag, 19. Mai 2026, 04:07:41 CEST schrieb Guoniu Zhou:
> > > > Implement waiting for D-PHY lanes to enter stop state on i.MX93.
> > > > This ensures proper PHY initialization by verifying that the clock
> > > > lane and all active data lanes have entered the stop state before
> > > > proceeding with further operations.
> > > >
> > > > Reviewed-by: Frank Li <Frank.Li@nxp.com>
> > > > Signed-off-by: Guoniu Zhou <guoniu.zhou@oss.nxp.com>
> > > > ---
> > > > Changes in v2:
> > > > - Removes redundant register availability check
> > > > - Uses read_poll_timeout() with dw_mipi_csi2rx_read() instead of
> > > > readl_poll_timeout() with direct register address
> > > > - Fixes stopstate condition logic
> > > > - Check PHY stopstate after sensor enable instead of before to ensure
> > > > correct timing.
> > > > - Optimize PHY stopstate polling parameters (1000us->10us, 2s->1ms) to
> > > > balance performance and responsiveness.
> > > > ---
> > > > drivers/media/platform/synopsys/dw-mipi-csi2rx.c | 36
> > > > ++++++++++++++++++++++++
> > > > 1 file changed, 36 insertions(+)
> > > >
> > > > diff --git a/drivers/media/platform/synopsys/dw-mipi-csi2rx.c
> > > > b/drivers/media/platform/synopsys/dw-mipi-csi2rx.c
> > > > index 92178a3dec5d..8a34aec550ad 100644
> > > > --- a/drivers/media/platform/synopsys/dw-mipi-csi2rx.c
> > > > +++ b/drivers/media/platform/synopsys/dw-mipi-csi2rx.c
> > > > @@ -11,6 +11,7 @@
> > > > #include <linux/clk.h>
> > > > #include <linux/delay.h>
> > > > #include <linux/io.h>
> > > > +#include <linux/iopoll.h>
> > > > #include <linux/module.h>
> > > > #include <linux/of.h>
> > > > #include <linux/phy/phy.h>
> > > > @@ -35,6 +36,8 @@
> > > > #define DW_REG_EXIST BIT(31)
> > > > #define DW_REG(x) (DW_REG_EXIST | (x))
> > > >
> > > > +#define DPHY_STOPSTATE_CLK_LANE BIT(16)
> > > > +
> > > > #define DPHY_TEST_CTRL0_TEST_CLR BIT(0)
> > > >
> > > > #define IPI_VCID_VC(x) FIELD_PREP(GENMASK(1, 0),
> > > (x))
> > > > @@ -65,6 +68,7 @@ enum dw_mipi_csi2rx_regs_index {
> > > > DW_MIPI_CSI2RX_PHY_TST_CTRL0,
> > > > DW_MIPI_CSI2RX_PHY_TST_CTRL1,
> > > > DW_MIPI_CSI2RX_PHY_SHUTDOWNZ,
> > > > + DW_MIPI_CSI2RX_PHY_STOPSTATE,
> > > > DW_MIPI_CSI2RX_IPI_DATATYPE,
> > > > DW_MIPI_CSI2RX_IPI_MEM_FLUSH,
> > > > DW_MIPI_CSI2RX_IPI_MODE,
> > > > @@ -87,6 +91,7 @@ struct dw_mipi_csi2rx_drvdata {
> > > > void (*dphy_assert_reset)(struct dw_mipi_csi2rx_device *csi2);
> > > > void (*dphy_deassert_reset)(struct dw_mipi_csi2rx_device *csi2);
> > > > void (*ipi_enable)(struct dw_mipi_csi2rx_device *csi2);
> > > > + int (*wait_for_phy_stopstate)(struct dw_mipi_csi2rx_device
> > > > +*csi2);
> > > > };
> > > >
> > > > struct dw_mipi_csi2rx_format {
> > > > @@ -139,6 +144,7 @@ static const u32
> > > > imx93_regs[DW_MIPI_CSI2RX_MAX]
> > > = {
> > > > [DW_MIPI_CSI2RX_PHY_SHUTDOWNZ] = DW_REG(0x40),
> > > > [DW_MIPI_CSI2RX_DPHY_RSTZ] = DW_REG(0x44),
> > > > [DW_MIPI_CSI2RX_PHY_STATE] = DW_REG(0x48),
> > > > + [DW_MIPI_CSI2RX_PHY_STOPSTATE] = DW_REG(0x4c),
> > > > [DW_MIPI_CSI2RX_PHY_TST_CTRL0] = DW_REG(0x50),
> > > > [DW_MIPI_CSI2RX_PHY_TST_CTRL1] = DW_REG(0x54),
> > > > [DW_MIPI_CSI2RX_IPI_MODE] = DW_REG(0x80), @@ -556,10 +562,19
> > > @@
> > > > static int dw_mipi_csi2rx_enable_streams(struct v4l2_subdev *sd,
> > > > if (ret)
> > > > goto err_csi_stop;
> > > >
> > > > + if (!csi2->enabled_streams &&
> > > > + csi2->drvdata->wait_for_phy_stopstate) {
> > > > + ret = csi2->drvdata->wait_for_phy_stopstate(csi2);
> > > > + if (ret)
> > > > + goto err_disable_streams;
> > > > + }
> > > > +
> > > > csi2->enabled_streams |= streams_mask;
> > > >
> > > > return 0;
> > > >
> > > > +err_disable_streams:
> > > > + v4l2_subdev_disable_streams(remote_sd, remote_pad->index, mask);
> > > > err_csi_stop:
> > > > /* Stop CSI hardware if no streams are enabled */
> > > > if (!csi2->enabled_streams)
> > > > @@ -871,11 +886,32 @@ static void
> > > > imx93_csi2rx_dphy_ipi_enable(struct
> > > dw_mipi_csi2rx_device *csi2)
> > > > dw_mipi_csi2rx_write(csi2, DW_MIPI_CSI2RX_IPI_MODE, val); }
> > > >
> > > > +static int imx93_csi2rx_wait_for_phy_stopstate(struct
> > > > +dw_mipi_csi2rx_device *csi2) {
> > > > + struct device *dev = csi2->dev;
> > > > + u32 stopstate_mask;
> > > > + u32 val;
> > > > + int ret;
> > > > +
> > > > + stopstate_mask = DPHY_STOPSTATE_CLK_LANE | GENMASK(csi2-
> > > >lanes_num -
> > > > +1, 0);
> > > > +
> > > > + ret = read_poll_timeout(dw_mipi_csi2rx_read, val,
> > > > + (val & stopstate_mask) == stopstate_mask,
> > > > + 10, 1000, true,
> > > > + csi2, DW_MIPI_CSI2RX_PHY_STOPSTATE);
> > > > + if (ret)
> > > > + dev_err(dev, "lanes are not in stop state: %#x,
> > > expected %#x\n",
> > > > + val, stopstate_mask);
> > >
> > > Did you actually test this on imx93? I'm trying to get my imx327
> > > sensor to run, but only run into this error message:
> > > dw-mipi-csi2rx 4ae00000.mipi-csi: lanes are not in stop state: 0x0,
> > > expected
> > > 0x10003
> >
> > Thanks for testing. Regarding the lane stop state error on i.MX93 with
> imx327:
> >
> > This error indicates the CSI-2 lanes are not in LP-11 (stop) state
> > when expected. Please check:
> >
> > 1) Verify the sensor PHY is in LP-11 state before returning from the sensor's
> > s_stream(1) call. The CSI-2 receiver expects lanes to be in stop state
> > initially.
>
> Well, this might be tricky as I don't have D-PHY capable scopes.
> I can successfully use this sensor on a imx8mp, so I am expecting this to be
> okay.
>
> > 2) Check if the imx327 driver has a delay between starting the stream and
> > returning from s_stream(). If the sensor transitions PHY out of LP-11
> > state during this delay, the CSI driver's lane state check will fail
> > when it runs later. The sensor should remain in LP-11 until the CSI
> > controller completes its initialization.
>
> In imx290_set_stream() and subsequently imx290_start_streaming() setting
> IMX290_XMSTA starts the stream. I expect this is the point when the sensors
> switches from LP-11 to HS. But again, I can't verify.
As mentioned in #2, I reviewed drivers/media/i2c/imx290.c and identified a 30ms
delay that appears to be the root cause of this issue.
The problem occurs because:
The sensor exits LP-11 state and transitions to HS mode after IMX290_XMSTA is written
The 30ms delay in s_stream() causes the function to return late
By the time the CSI controller performs its lane state check, the sensor has already switched
from LP-11 to HS mode, causing the check to fail。
Proposed fix:
diff --git a/drivers/media/i2c/imx290.c b/drivers/media/i2c/imx290.c
index 21cbc81cb2ed..519aa336249a 100644
--- a/drivers/media/i2c/imx290.c
+++ b/drivers/media/i2c/imx290.c
@@ -1059,7 +1059,6 @@ static int imx290_start_streaming(struct imx290 *imx290,
cci_write(imx290->regmap, IMX290_STANDBY, 0x00, &ret);
- msleep(30);
/* Start streaming */
return cci_write(imx290->regmap, IMX290_XMSTA, 0x00, &ret);
Removing this delay allows s_stream() to return immediately, giving the CSI controller
time to complete its initialization before the sensor transitions PHY state.
Could you test this patch and confirm if it resolves the lane state check failure?
Best Regards
G.N Zhou
>
> With enabling debug
> > echo "module videodev +p" > /sys/kernel/debug/dynamic_debug/control
> > echo 0xff > /sys/class/video4linux/video0/dev_debug
>
> After I setup the media pipeline, running the command
> > v4l2-ctl -z "platform:4ae40000.isi" -d "mxc_isi.0.capture"
> > --stream-mmap --stream-count=1 --stream-to=imx93.raw
> I get the following debug output:
>
> --8<--
> plane 0: bytesperline=3840 sizeimage=4147200 mxc-isi 4ae40000.isi:
> validating link "crossbar":2 -> "mxc_isi.0":0 mxc-isi 4ae40000.isi: validating
> stream "crossbar":2:0 -> "mxc_isi.0":0:0 mxc-isi 4ae40000.isi: validating link
> "dw-mipi-csi2rx 4ae00000.mipi-csi":1 -> "crossbar":0 mxc-isi 4ae40000.isi:
> validating stream "dw-mipi-csi2rx 4ae00000.mipi-csi":1:0 -> "crossbar":0:0
> mxc-isi 4ae40000.isi: validating link "imx327 4-001a":0 -> "dw-mipi-csi2rx
> 4ae00000.mipi-csi":0 mxc-isi 4ae40000.isi: validating stream "imx327 4-
> 001a":0:0 -> "dw-mipi-csi2rx 4ae00000.mipi-csi":0:0 mxc-isi 4ae40000.isi:
> enable streams "crossbar":2/0x1 mxc-isi 4ae40000.isi: collect_streams:
> "crossbar":2: found 0x1 enabled 0x0
> imx290 4-001a: Frame descriptor on pad 0, type CSI-2
> imx290 4-001a: stream 0, code 0x300f, length 0, flags 0x0000, vc 0, dt 0x2b
> dw-mipi-csi2rx 4ae00000.mipi-csi: Frame descriptor on pad 1, type CSI-2
> dw-mipi-csi2rx 4ae00000.mipi-csi: stream 0, code 0x300f, length 0, flags
> 0x0000, vc 0, dt 0x2b
> mxc-isi 4ae40000.isi: enable streams "dw-mipi-csi2rx 4ae00000.mipi-
> csi":1/0x1 dw-mipi-csi2rx 4ae00000.mipi-csi: collect_streams: "dw-mipi-csi2rx
> 4ae00000.mipi-csi":1: found 0x1 enabled 0x0 mxc-isi 4ae40000.isi: enable
> streams "imx327 4-001a":0/0x1
> imx290 4-001a: collect_streams: sub-device "imx327 4-001a" does not support
> streams dw-mipi-csi2rx 4ae00000.mipi-csi: lanes are not in stop state: 0x0,
> expected 0x10003 mxc-isi 4ae40000.isi: disable streams "imx327 4-
> 001a":0/0x1
> imx290 4-001a: collect_streams: sub-device "imx327 4-001a" does not support
> streams mxc-isi 4ae40000.isi: enable streams 1:0x1 failed: -110 mxc-isi
> 4ae40000.isi: failed to enable streams 0x1 on 'dw-mipi-csi2rx 4ae00000.mipi-
> csi':1: -110 mxc-isi 4ae40000.isi: enable streams 2:0x1 failed: -110 mxc-isi
> 4ae40000.isi: Failed to enable pipe 0
> video0: VIDIOC_STREAMON: error -110: type=vid-cap-mplane
> videodev: v4l2_release: video0: release
> --8<--
>
> For completeness this is my media device config
> --8<--
> # media-ctl -p
> Media controller API version 7.1.0
>
> Media device information
> ------------------------
> driver mxc-isi
> model FSL Capture Media Device
> serial
> bus info platform:4ae40000.isi
> hw revision 0x0
> driver version 7.1.0
>
> Device topology
> - entity 1: crossbar (3 pads, 2 links, 1 route)
> type V4L2 subdev subtype Unknown flags 0
> device node name /dev/v4l-subdev0
> routes:
> 0/0 -> 2/0 [ACTIVE]
> pad0: SINK,MUST_CONNECT
> [stream:0 fmt:SRGGB10_1X10/1920x1080 field:none colorspace:raw]
> <- "dw-mipi-csi2rx 4ae00000.mipi-cs":1 [ENABLED,IMMUTABLE]
> pad1: SINK,MUST_CONNECT
> pad2: SOURCE
> [stream:0 fmt:SRGGB10_1X10/1920x1080 field:none colorspace:raw]
> -> "mxc_isi.0":0 [ENABLED,IMMUTABLE]
>
> - entity 5: mxc_isi.0 (2 pads, 2 links, 0 routes)
> type V4L2 subdev subtype Unknown flags 0
> device node name /dev/v4l-subdev1
> pad0: SINK
> [stream:0 fmt:SRGGB10_1X10/1920x1080 field:none colorspace:raw
> compose.bounds:(0,0)/1920x1080
> compose:(0,0)/1920x1080]
> <- "crossbar":2 [ENABLED,IMMUTABLE]
> pad1: SOURCE
> [stream:0 fmt:SRGGB10_1X10/1920x1080 field:none colorspace:jpeg
> xfer:srgb ycbcr:601 quantization:full-range
> crop.bounds:(0,0)/1920x1080
> crop:(0,0)/1920x1080]
> -> "mxc_isi.0.capture":0 [ENABLED,IMMUTABLE]
>
> - entity 8: mxc_isi.0.capture (1 pad, 1 link)
> type Node subtype V4L flags 0
> device node name /dev/video0
> pad0: SINK
> <- "mxc_isi.0":1 [ENABLED,IMMUTABLE]
>
> - entity 16: dw-mipi-csi2rx 4ae00000.mipi-cs (2 pads, 2 links, 1 route)
> type V4L2 subdev subtype Unknown flags 0
> device node name /dev/v4l-subdev2
> routes:
> 0/0 -> 1/0 [ACTIVE]
> pad0: SINK,MUST_CONNECT
> [stream:0 fmt:SRGGB10_1X10/1920x1080 field:none colorspace:raw
> xfer:none ycbcr:601 quantization:full-range]
> <- "imx327 4-001a":0 [ENABLED]
> pad1: SOURCE
> [stream:0 fmt:SRGGB10_1X10/1920x1080 field:none colorspace:raw
> xfer:none ycbcr:601 quantization:full-range]
> -> "crossbar":0 [ENABLED,IMMUTABLE]
>
> - entity 21: imx327 4-001a (1 pad, 1 link, 0 routes)
> type V4L2 subdev subtype Sensor flags 0
> device node name /dev/v4l-subdev3
> pad0: SOURCE
> [stream:0 fmt:SRGGB10_1X10/1920x1080 field:none colorspace:raw
> xfer:none ycbcr:601 quantization:full-range
> crop.bounds:(0,0)/1945x1097
> crop:(12,8)/1920x1080]
> -> "dw-mipi-csi2rx 4ae00000.mipi-cs":0 [ENABLED]
> --8<--
>
> Anything odd here?
>
> > You may need to remove any delays in the imx327 s_stream
> > implementation, or ensure the sensor stays in LP-11 state until the CSI
> receiver is ready.
> >
> > If possible, could you share the imx327 driver code or check its s_stream
> implementation?
>
> It's essentially upstream in drivers/media/i2c/imx290.c.
> I only have a dummy implementation for get_frame_desc and a small
> adjustement for my camera module regarding i2c access.
>
> --8<--
> static int imx290_get_frame_desc(struct v4l2_subdev *sd, unsigned int pad,
> struct v4l2_mbus_frame_desc *fd)
> {
> const struct v4l2_mbus_framefmt *format;
> struct v4l2_subdev_state *state;
>
> state = v4l2_subdev_lock_and_get_active_state(sd);
> format = v4l2_subdev_state_get_format(state, pad);
> v4l2_subdev_unlock_state(state);
>
> fd->type = V4L2_MBUS_FRAME_DESC_TYPE_CSI2;
> fd->num_entries = 1;
> fd->entry[0].pixelcode = format->code;
> fd->entry[0].stream = 0;
> fd->entry[0].bus.csi2.vc = 0;
> fd->entry[0].bus.csi2.dt = MIPI_CSI2_DT_RAW10; //TODO:
> get_data_type_by_code(format->code);
>
> return 0;
> }
> --8<--
>
> Another thing. I use https://lore.kernel.org/imx/20250701-95_cam-v1-2-
> c5172bab387b@nxp.com/
> for the D-PHY. Is there any update/progress on that driver?
>
> Best regards,
> Alexander
> --
> TQ-Systems GmbH | Mühlstraße 2, Gut Delling | 82229 Seefeld, Germany
> Amtsgericht München, HRB 105018
> Geschäftsführer: Detlef Schneider, Rüdiger Stahl, Stefan Schneider
> http://www.tq-group.com/
>
^ permalink raw reply related
* [PATCHv2] ASoC: mediatek: mt2701: fix snprintf bounds
From: Rosen Penev @ 2026-05-22 1:45 UTC (permalink / raw)
To: linux-sound
Cc: Liam Girdwood, Mark Brown, Jaroslav Kysela, Takashi Iwai,
Matthias Brugger, AngeloGioacchino Del Regno,
open list:ARM/Mediatek SoC support,
moderated list:ARM/Mediatek SoC support,
moderated list:ARM/Mediatek SoC support
For whatever reason, GCC is unable to figure out that i2s_num is a
single digit number, with MT2701_BASE_CLK_NUM being the maximum value it
represents. Add a min() call to help it out and fix W=1 errors regarding
snprintf bounds.
Signed-off-by: Rosen Penev <rosenp@gmail.com>
---
v2: swap min arguments
sound/soc/mediatek/mt2701/mt2701-afe-clock-ctrl.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/sound/soc/mediatek/mt2701/mt2701-afe-clock-ctrl.c b/sound/soc/mediatek/mt2701/mt2701-afe-clock-ctrl.c
index 5a2bcf027b4f..d217f9320ad2 100644
--- a/sound/soc/mediatek/mt2701/mt2701-afe-clock-ctrl.c
+++ b/sound/soc/mediatek/mt2701/mt2701-afe-clock-ctrl.c
@@ -25,6 +25,7 @@ static const char *const base_clks[] = {
int mt2701_init_clock(struct mtk_base_afe *afe)
{
struct mt2701_afe_private *afe_priv = afe->platform_priv;
+ int i2s_num;
int i;
for (i = 0; i < MT2701_BASE_CLK_NUM; i++) {
@@ -35,8 +36,9 @@ int mt2701_init_clock(struct mtk_base_afe *afe)
}
}
+ i2s_num = min(afe_priv->soc->i2s_num, MT2701_BASE_CLK_NUM);
/* Get I2S related clocks */
- for (i = 0; i < afe_priv->soc->i2s_num; i++) {
+ for (i = 0; i < i2s_num; i++) {
struct mt2701_i2s_path *i2s_path = &afe_priv->i2s_path[i];
struct clk *i2s_ck;
char name[13];
--
2.54.0
^ permalink raw reply related
* Re: [PATCH v2 1/3] dt-bindings: display: bridge: analogix-dp: Add data-lanes support for endpoint
From: Damon Ding @ 2026-05-22 1:32 UTC (permalink / raw)
To: Conor Dooley
Cc: hjc, heiko, andy.yan, maarten.lankhorst, mripard, tzimmermann,
airlied, simona, robh, krzk+dt, conor+dt, andrzej.hajda,
neil.armstrong, rfoss, Laurent.pinchart, jonas, jernej.skrabec,
nicolas.frattaroli, cristian.ciocaltea, sebastian.reichel,
dmitry.baryshkov, luca.ceresoli, dianders, m.szyprowski,
dri-devel, devicetree, linux-arm-kernel, linux-rockchip,
linux-kernel
In-Reply-To: <20260521-modify-quadrant-8d6a2e36727c@spud>
On 5/22/2026 3:50 AM, Conor Dooley wrote:
> On Thu, May 21, 2026 at 07:44:57PM +0800, Damon Ding wrote:
>> Add data-lanes property support to the port@1 endpoint for physical
>> lane mapping configuration.
>>
>> Lane mapping is mainly used for below scenarios:
>> 1. Correct PCB lane swap and differential line routing crossover
>> without hardware changes;
>> 2. Adapt mismatched lane pin definitions between SoC and eDP panel;
>> 3. Support multiple panel hardware variants on the same board
>> by configuring data-lanes in device tree only.
>>
>> Signed-off-by: Damon Ding <damon.ding@rock-chips.com>
>
> Sashiko complaint here looks valid.
> pw-bot: changes-requested
>
Yes, unevaluatedProperties: false should be added to both the port@1
and endpoint nodes.
Will fix in v3.
Best regards,
Damon
>
>>
>> ---
>>
>> Changes in v2:
>> - Add lane mapping application scenarios in commit message.
>> - Remove redundant deprecated property 'data-lanes' for eDP node.
>> - Update port@1 $ref to /schemas/graph.yaml#/$defs/port-base.
>> ---
>> .../bindings/display/bridge/analogix,dp.yaml | 17 ++++++++++++-----
>> 1 file changed, 12 insertions(+), 5 deletions(-)
>>
>> diff --git a/Documentation/devicetree/bindings/display/bridge/analogix,dp.yaml b/Documentation/devicetree/bindings/display/bridge/analogix,dp.yaml
>> index 62f0521b0924..e34fdb21adb4 100644
>> --- a/Documentation/devicetree/bindings/display/bridge/analogix,dp.yaml
>> +++ b/Documentation/devicetree/bindings/display/bridge/analogix,dp.yaml
>> @@ -42,13 +42,20 @@ properties:
>> properties:
>> port@0:
>> $ref: /schemas/graph.yaml#/properties/port
>> - description:
>> - Input node to receive pixel data.
>> + description: Input node to receive pixel data.
>>
>> port@1:
>> - $ref: /schemas/graph.yaml#/properties/port
>> - description:
>> - Port node with one endpoint connected to a dp-connector node.
>> + $ref: /schemas/graph.yaml#/$defs/port-base
>> + description: Port node with one endpoint connected to sink device node.
>> + properties:
>> + endpoint:
>> + $ref: /schemas/media/video-interfaces.yaml#
>> + properties:
>> + data-lanes:
>> + minItems: 1
>> + maxItems: 4
>> + items:
>> + enum: [ 0, 1, 2, 3 ]
>>
>> required:
>> - port@0
>> --
>> 2.34.1
>>
^ permalink raw reply
* Re: [PATCH v1 3/4] arm64/vdso: Enable SFrame generation in vDSO
From: Dylan Hatch @ 2026-05-22 1:31 UTC (permalink / raw)
To: Jens Remus
Cc: Catalin Marinas, Will Deacon, Steven Rostedt, Josh Poimboeuf,
Indu Bhagat, Peter Zijlstra, Weinan Liu, linux-arm-kernel,
linux-kernel, Heiko Carstens, Ilya Leoshkevich
In-Reply-To: <20260417150827.1183376-4-jremus@linux.ibm.com>
Hi Jens,
Sorry for the slow reply on this.
On Fri, Apr 17, 2026 at 8:08 AM Jens Remus <jremus@linux.ibm.com> wrote:
>
> This replicates Josh's x86 patch "x86/vdso: Enable sframe generation
> in VDSO" [1] for arm64.
>
> Enable .sframe generation in the vDSO library so kernel and user space
> can unwind through it. Keep all function symbols in the vDSO .symtab
> for stack trace purposes. This enables perf to lookup these function
> symbols in addition to those already exported in vDSO .dynsym.
>
> Starting with binutils 2.46 both GNU assembler and GNU linker
> exclusively support generating and merging .sframe in SFrame V3 format.
> For vDSO, only if supported by the assembler, generate .sframe, collect
> it, mark it as KEEP, and generate a GNU_SFRAME program table entry.
> Otherwise explicitly discard any .sframe.
>
> [1]: x86/vdso: Enable sframe generation in VDSO,
> https://lore.kernel.org/all/20260211141357.271402-7-jremus@linux.ibm.com/
>
> Signed-off-by: Jens Remus <jremus@linux.ibm.com>
> ---
>
> Notes (jremus):
> @Dylan: Adding -Wa,--gsframe-3 to the VDSO CC_FLAGS_ADD_VDSO (and
> AS_FLAGS_ADD_VDSO) may clash with your patch [1] that adds likewise
> to the CC_FLAGS_REMOVE_VDSO. Any idea how to resolve?
>
> [1]: [PATCH v3 2/8] arm64, unwind: build kernel with sframe V3 info,
> https://lore.kernel.org/all/20260406185000.1378082-3-dylanbhatch@google.com/
In a kernel tree with both your patch and my [1] patch merged, I
believe we'd want to hold two invariants true:
1. If HAVE_UNWIND_KERNEL_SFRAME=n, we must not build the kernel with .sframe.
2. If AS_SFRAME3=y, we must build vDSO with .sframe.
Since HAVE_UNWIND_KERNEL_SFRAME=y implies AS_SFRAME3=y, I wonder if we
should be able to drop CC_FLAGS_SFRAME from CC_FLAGS_REMOVE_VDSO and
move some definitions:
diff --git a/Makefile b/Makefile
index 227fda16deb1..ef059bccb8c1 100644
--- a/Makefile
+++ b/Makefile
@@ -1147,12 +1147,15 @@ endif
# Ensure compilers do not transform certain loops into calls to wcslen()
KBUILD_CFLAGS += -fno-builtin-wcslen
+ifeq ($(CONFIG_AS_SFRAME3),y)
+CC_FLAGS_SFRAME := -Wa,--gsframe-3
+export CC_FLAGS_SFRAME
+endif
+
# build with sframe table
ifdef CONFIG_HAVE_UNWIND_KERNEL_SFRAME
-CC_FLAGS_SFRAME := -Wa,--gsframe-3
KBUILD_CFLAGS += $(CC_FLAGS_SFRAME)
KBUILD_AFLAGS += $(CC_FLAGS_SFRAME)
-export CC_FLAGS_SFRAME
endif
# change __FILE__ to the relative path to the source directory
diff --git a/arch/arm64/kernel/vdso/Makefile b/arch/arm64/kernel/vdso/Makefile
index e90427a8d0f6..f03cac27857c 100644
--- a/arch/arm64/kernel/vdso/Makefile
+++ b/arch/arm64/kernel/vdso/Makefile
@@ -15,10 +15,6 @@ obj-vdso := vgettimeofday.o note.o sigreturn.o
vgetrandom.o vgetrandom-chacha.o
targets := $(obj-vdso) vdso.so vdso.so.dbg
obj-vdso := $(addprefix $(obj)/, $(obj-vdso))
-ifeq ($(CONFIG_AS_SFRAME3),y)
- SFRAME_CFLAGS := -Wa,--gsframe-3
-endif
-
btildflags-$(CONFIG_ARM64_BTI_KERNEL) += -z force-bti
# -Bsymbolic has been added for consistency with arm, the compat vDSO and
@@ -42,12 +38,12 @@ ccflags-y += -DDISABLE_BRANCH_PROFILING -DBUILD_VDSO
CC_FLAGS_REMOVE_VDSO := $(CC_FLAGS_FTRACE) -Os $(CC_FLAGS_SCS) \
$(RANDSTRUCT_CFLAGS) $(KSTACK_ERASE_CFLAGS) \
$(GCC_PLUGINS_CFLAGS) \
- $(CC_FLAGS_LTO) $(CC_FLAGS_CFI) $(CC_FLAGS_SFRAME) \
+ $(CC_FLAGS_LTO) $(CC_FLAGS_CFI) \
-Wmissing-prototypes -Wmissing-declarations
-CC_FLAGS_ADD_VDSO := -O2 -mcmodel=tiny -fasynchronous-unwind-tables
$(SFRAME_CFLAGS)
+CC_FLAGS_ADD_VDSO := -O2 -mcmodel=tiny -fasynchronous-unwind-tables
$(CC_FLAGS_SFRAME)
-AS_FLAGS_ADD_VDSO := $(SFRAME_CFLAGS)
+AS_FLAGS_ADD_VDSO := $(CC_FLAGS_SFRAME)
CFLAGS_REMOVE_vgettimeofday.o = $(CC_FLAGS_REMOVE_VDSO)
CFLAGS_REMOVE_vgetrandom.o = $(CC_FLAGS_REMOVE_VDSO)
If done this way I think we will add the -Wa,--gsframe-3 twice when
HAVE_UNWIND_KERNEL_SFRAME=y, but maybe that's not a problem? This
could probably be folded into either this patch or mine [1], depending
which is applied first. I'm happy to rebase my unwind-for-kernel
patches onto this series, or we can do the other way around if that
works better.
What do you think?
Thanks,
Dylan
^ permalink raw reply related
* Re: [PATCH v2 2/3] dt-bindings: rockchip: analogix-dp: Add data-lanes example
From: Damon Ding @ 2026-05-22 1:25 UTC (permalink / raw)
To: Conor Dooley
Cc: hjc, heiko, andy.yan, maarten.lankhorst, mripard, tzimmermann,
airlied, simona, robh, krzk+dt, conor+dt, andrzej.hajda,
neil.armstrong, rfoss, Laurent.pinchart, jonas, jernej.skrabec,
nicolas.frattaroli, cristian.ciocaltea, sebastian.reichel,
dmitry.baryshkov, luca.ceresoli, dianders, m.szyprowski,
dri-devel, devicetree, linux-arm-kernel, linux-rockchip,
linux-kernel
In-Reply-To: <20260521-powdery-tux-22a7cf4fadc3@spud>
On 5/22/2026 3:47 AM, Conor Dooley wrote:
> On Thu, May 21, 2026 at 07:44:58PM +0800, Damon Ding wrote:
>> Add data-lanes setting in endpoint example to show actual lane mapping
>> usage.
>>
>> Signed-off-by: Damon Ding <damon.ding@rock-chips.com>
>
> Squash this with patch 1.
> pw-bot: changes-requested
>
Yes, will fix in v3
Best regards,
Damon
>
>> ---
>> .../bindings/display/rockchip/rockchip,analogix-dp.yaml | 1 +
>> 1 file changed, 1 insertion(+)
>>
>> diff --git a/Documentation/devicetree/bindings/display/rockchip/rockchip,analogix-dp.yaml b/Documentation/devicetree/bindings/display/rockchip/rockchip,analogix-dp.yaml
>> index bb75d898a5c5..cf75c926318b 100644
>> --- a/Documentation/devicetree/bindings/display/rockchip/rockchip,analogix-dp.yaml
>> +++ b/Documentation/devicetree/bindings/display/rockchip/rockchip,analogix-dp.yaml
>> @@ -151,6 +151,7 @@ examples:
>> reg = <1>;
>>
>> edp_out_panel: endpoint {
>> + data-lanes = <0 1>;
>> remote-endpoint = <&panel_in_edp>;
>> };
>> };
>> --
>> 2.34.1
>>
^ permalink raw reply
* Re: [PATCH 01/19] btrfs: require at least 4 devices for RAID 6
From: Qu Wenruo @ 2026-05-22 0:27 UTC (permalink / raw)
To: Andrew Morton, Qu Wenruo
Cc: Christoph Hellwig, H. Peter Anvin, kreijack, David Sterba,
Catalin Marinas, Will Deacon, Ard Biesheuvel, Huacai Chen,
WANG Xuerui, Madhavan Srinivasan, Michael Ellerman,
Nicholas Piggin, Christophe Leroy (CS GROUP), Paul Walmsley,
Palmer Dabbelt, Albert Ou, Alexandre Ghiti, Heiko Carstens,
Vasily Gorbik, Alexander Gordeev, Christian Borntraeger,
Sven Schnelle, Thomas Gleixner, Ingo Molnar, Borislav Petkov,
Dave Hansen, x86, Herbert Xu, Dan Williams, Chris Mason,
David Sterba, Arnd Bergmann, Song Liu, Yu Kuai, Li Nan,
linux-kernel, linux-arm-kernel, loongarch, linuxppc-dev,
linux-riscv, linux-s390, linux-crypto, linux-btrfs, linux-arch,
linux-raid
In-Reply-To: <20260521171730.7872482df453975cf60ce7dc@linux-foundation.org>
在 2026/5/22 09:47, Andrew Morton 写道:
> On Wed, 20 May 2026 18:11:09 +0930 Qu Wenruo <quwenruo.btrfs@gmx.com> wrote:
>
>>
>>
>> 在 2026/5/18 14:42, Christoph Hellwig 写道:
>>> On Fri, May 15, 2026 at 12:59:34PM -0700, H. Peter Anvin wrote:
>>>> I don't think this is a good idea. Error out; it is the btrfs maintainers' job to ensure user data isn't lost.
>>>>
>>>> The RAID-6 code has *never* supported only 3 units, and if it ever worked for *any* of the implementations it was purely by accident. Speaking as the original author I should know; this was deliberate as in some cases the degenerate case (3) would have required extra trays in the code to no user benefit.
>>>>
>>>> I would not be surprised if the kernel crashed or corrupted the page cache in that case.
>>>
>>> It does, that's why I wanted to exclude it. Anyway, for the about to be
>>> resent version I'll drop this btrfs patch over the stated objection and
>>> will otherwise not change anything. This means the (IMHO hypothetical)
>>> users of this configuration will get a WARN_ON_ONCE triggered, but
>>> otherwise keep working (or rather not working) as before.
>>>
>>
>> For the btrfs part, I believe I can get the current 2-disk-raid5 and
>> 3-disk-raid6 to fallback to raid1 inside btrfs.
>>
>> I hope the btrfs part can be finished and reach the next merge window,
>> but I'm not 100% sure.
>>
>> What is the planned cycle to merge this raid5/6 cleanup?
>
> At present it's on track for the 7.2-rc1 merge window. Does that suit?
The current btrfs fix (*) is pretty small, I believe we can get it into
the next merge window, as long as we got enough review on it.
*:
https://lore.kernel.org/linux-btrfs/a1d63733465229936351804f3760803d5894a962.1779274630.git.wqu@suse.com/T/#u
^ permalink raw reply
* Re: [PATCH 01/19] btrfs: require at least 4 devices for RAID 6
From: Andrew Morton @ 2026-05-22 0:17 UTC (permalink / raw)
To: Qu Wenruo
Cc: Christoph Hellwig, H. Peter Anvin, kreijack, David Sterba,
Catalin Marinas, Will Deacon, Ard Biesheuvel, Huacai Chen,
WANG Xuerui, Madhavan Srinivasan, Michael Ellerman,
Nicholas Piggin, Christophe Leroy (CS GROUP), Paul Walmsley,
Palmer Dabbelt, Albert Ou, Alexandre Ghiti, Heiko Carstens,
Vasily Gorbik, Alexander Gordeev, Christian Borntraeger,
Sven Schnelle, Thomas Gleixner, Ingo Molnar, Borislav Petkov,
Dave Hansen, x86, Herbert Xu, Dan Williams, Chris Mason,
David Sterba, Arnd Bergmann, Song Liu, Yu Kuai, Li Nan,
linux-kernel, linux-arm-kernel, loongarch, linuxppc-dev,
linux-riscv, linux-s390, linux-crypto, linux-btrfs, linux-arch,
linux-raid
In-Reply-To: <f46636c8-80ba-4802-a6a0-74cbc35e7bee@gmx.com>
On Wed, 20 May 2026 18:11:09 +0930 Qu Wenruo <quwenruo.btrfs@gmx.com> wrote:
>
>
> 在 2026/5/18 14:42, Christoph Hellwig 写道:
> > On Fri, May 15, 2026 at 12:59:34PM -0700, H. Peter Anvin wrote:
> >> I don't think this is a good idea. Error out; it is the btrfs maintainers' job to ensure user data isn't lost.
> >>
> >> The RAID-6 code has *never* supported only 3 units, and if it ever worked for *any* of the implementations it was purely by accident. Speaking as the original author I should know; this was deliberate as in some cases the degenerate case (3) would have required extra trays in the code to no user benefit.
> >>
> >> I would not be surprised if the kernel crashed or corrupted the page cache in that case.
> >
> > It does, that's why I wanted to exclude it. Anyway, for the about to be
> > resent version I'll drop this btrfs patch over the stated objection and
> > will otherwise not change anything. This means the (IMHO hypothetical)
> > users of this configuration will get a WARN_ON_ONCE triggered, but
> > otherwise keep working (or rather not working) as before.
> >
>
> For the btrfs part, I believe I can get the current 2-disk-raid5 and
> 3-disk-raid6 to fallback to raid1 inside btrfs.
>
> I hope the btrfs part can be finished and reach the next merge window,
> but I'm not 100% sure.
>
> What is the planned cycle to merge this raid5/6 cleanup?
At present it's on track for the 7.2-rc1 merge window. Does that suit?
^ permalink raw reply
* Re: [PATCH] arm64: mm: call pagetable dtor when freeing hot-removed page tables
From: Alistair Popple @ 2026-05-21 23:50 UTC (permalink / raw)
To: Andrew Morton
Cc: linux-arm-kernel, linux-kernel, linux-mm, catalin.marinas, will,
david
In-Reply-To: <20260521153130.d7d5cd060f7522f894252333@linux-foundation.org>
On 2026-05-22 at 08:31 +1000, Andrew Morton <akpm@linux-foundation.org> wrote...
> On Thu, 21 May 2026 13:27:30 +1000 Alistair Popple <apopple@nvidia.com> wrote:
>
> > Since 5e8eb9aeeda3 ("arm64: mm: always call PTE/PMD ctor in
> > __create_pgd_mapping()") page-table allocation on ARM64 always
> > calls pagetable_{pte,pmd,pud,p4d}_ctor(). This sets the page_type
> > to PGTY_table, increments NR_PAGETABLE and possible allocates a PTL.
> > However the matching pagetable_dtor() calls were never added.
> >
> > With DEBUG_VM enabled on kernel versions prior to v6.17 without
> > 2dfcd1608f3a9 ("mm/page_alloc: let page freeing clear any set page
> > type") this leads to the following warning when freeing these pages due
> > to page->page_type sharing page->_mapcount:
> >
> > BUG: Bad page state in process ... pfn:284fbb
> > page: refcount:0 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x284fbb
> > flags: 0x17fffc000000000(node=0|zone=2|lastcpupid=0x1ffff)
> > page_type: f2(table)
> > page dumped because: nonzero mapcount
> > Call trace:
> > bad_page+0x13c/0x160
> > __free_frozen_pages+0x6cc/0x860
> > ___free_pages+0xf4/0x180
> > free_pages+0x54/0x80
> > free_hotplug_page_range.part.0+0x58/0x90
> > free_empty_tables+0x438/0x500
> > __remove_pgd_mapping.constprop.0+0x60/0xa8
> > arch_remove_memory+0x48/0x80
> > try_remove_memory+0x158/0x1d8
> > offline_and_remove_memory+0x138/0x180
> >
> > It can also lead to leaking the ptl allocation if ALLOC_SPLIT_PTLOCKS
> > is defined and incorrect NR_PAGETABLE stats. Fix this by calling
> > pagetable_dtor() in free_hotplug_pgtable_page() prior to freeing the
> > page to undo the effects of calling pagetable_*_ctor().
> >
> > Fixes: 5e8eb9aeeda3 ("arm64: mm: always call PTE/PMD ctor in __create_pgd_mapping()")
>
> 6.16+, so I assume we want cc:stable here.
Yes indeed. Sorry I forgot to do that but I can see you added it so thanks for
that.
- Alistair
> > arch/arm64/mm/mmu.c | 1 +
> > 1 file changed, 1 insertion(+)
> >
> > diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c
> > index 8e1d80a7033e..0c24fe650e95 100644
> > --- a/arch/arm64/mm/mmu.c
> > +++ b/arch/arm64/mm/mmu.c
> > @@ -1422,6 +1422,7 @@ static void free_hotplug_page_range(struct page *page, size_t size,
> >
> > static void free_hotplug_pgtable_page(struct page *page)
> > {
> > + pagetable_dtor(page_ptdesc(page));
> > free_hotplug_page_range(page, PAGE_SIZE, NULL);
> > }
>
> I'd of course prefer that arm maintainers handle this. But
> 5e8eb9aeeda3 came via myself so convention kinda-dictates that I get to
> fix it.
>
^ permalink raw reply
* Re: [PATCH] [RFC] arm64: mmu: use range based TLB flushing when hot unplugging memory
From: Alistair Popple @ 2026-05-21 23:48 UTC (permalink / raw)
To: Ryan Roberts
Cc: Balbir Singh, linux-arm-kernel, linux-kernel, linux-mm,
catalin.marinas, will, david, anshuman.khandual, dev.jain,
jhubbard
In-Reply-To: <60542cd7-d01c-4247-8957-8423b54ae99d@arm.com>
On 2026-05-21 at 21:24 +1000, Ryan Roberts <ryan.roberts@arm.com> wrote...
> On 21/05/2026 11:46, Balbir Singh wrote:
> > On Thu, May 21, 2026 at 09:50:04AM +0100, Ryan Roberts wrote:
> >> On 21/05/2026 05:24, Alistair Popple wrote:
> >>> Hot unplugging memory on ARM64 requires a TLB invalidate after unmapping
> >>> the page to be hot unplugged from the direct map. Currently that happens
> >>> one page at a time, meaning range based invalidates cannot be used. The
> >>> result of this is that removing large amounts of memory takes a long
> >>> time and in some cases can trigger an RCU stall warning.
> >>>
> >>> For example on one system hot unplugging 480GB of memory takes ~1
> >>> minute. With this change the same operation took ~1 second, a 60x
> >>> improvement.
> >>>
> >>> Signed-off-by: Alistair Popple <apopple@nvidia.com>
> >>>
> >>> ---
> >>>
> >>> This is an RFC, because I'm not sure the change is correct as it frees
> >>> the PTE page before flushing the TLB. I'm not familiar enough with ARM64
> >>> architecture to be sure this is safe, for example I don't know if HW
> >>> can update PTE bits such as access/dirty in the page through a stale
> >>> TLB entry.
> >>>
> >>> If so this would open a window during which the page is free but could
> >>> still be written to. Likely the safe option would be to collect all the
> >>> pages to be free on a list and free them after doing the range based TLB
> >>> flush, but wanted to get feedback on the approach before implementing it
> >>> which is the goal of this RFC.
> >>
> >> Hi Alistair,
> >>
> >> This patch doesn't apply on v7.1-rc4 because it conflicts with this patch:
> >>
> >> Commit 48478b9f79137 ("arm64/mm: Enable batched TLB flush in unmap_hotplug_range()")
> >>
> >> which has a very similar performance improvement, so hopefully it solves your
> >> problem?
Yes it does. This issue has been niggling me for a while, so how coincidental
that I finally try and do something about it just after someone has fixed it :-)
> >> There are two paths which use this logic; unmapping the linear map and unmapping
> >> the corresponding vmemmap. In the latter case, the memory is also freed, so we
> >> can't safely do the range optimizaiton there since the TLB needs to be flushed
> >> before freeing the memory. But the linear map is the big, slow bit so hopefully
> >> it's sufficent for you?
> >>
> >
> > I assume vmemmap path is for tearing down the struct pages corresponding
> > to the physical memory and vmemmap teardowns taking a flush should be
> > OK. It is worth checking if the issue is already fixed.
>
> Yes, exactly. Assuming you're using 64K pages, I think vmemmap is mapped using
> base pages. So you'd get 1024 struct pages on a page, so 1 TLBI per 64M of
> memory that is being unplugged on the vmemmap path.
>
> On the linear map path, it's a single range tlbi operation to over the entire range.
>
> Alistair's patch is doing it per 512M in both cases, but is unsafe for vmemmap
> as currently written.
Right - hence the RFC. This was somewhat sent in the spirit of it being wrong
in the hope that somebody could help me figure out how to do it properly. As
it turns out though it's already been fixed which is an even better outcome so
thanks for pointing that out.
So this patch can be ignored, I see a similar offlining performance improvement
on my system (~1m -> ~1s) with 48478b9f79137 applied.
Thanks.
- Alistair
> >
> > Balbir
> > <snip>
>
^ permalink raw reply
* Re: [PATCH] ARM: zte: clean up zx297520v3 doc. warnings
From: Bagas Sanjaya @ 2026-05-21 23:26 UTC (permalink / raw)
To: Randy Dunlap, linux-kernel
Cc: Stefan Dösinger, Linus Walleij, Krzysztof Kozlowski,
linux-arm-kernel, Jonathan Corbet, Shuah Khan, linux-doc
In-Reply-To: <20260521191458.177046-1-rdunlap@infradead.org>
[-- Attachment #1: Type: text/plain, Size: 310 bytes --]
On Thu, May 21, 2026 at 12:14:57PM -0700, Randy Dunlap wrote:
> Fix multiple documentation build warnings.
> Improve punctuation and formatting of the rendered output.
Much better, thanks!
Reviewed-by: Bagas Sanjaya <bagasdotme@gmail.com>
--
An old man doll... just what I always wanted! - Clara
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
^ permalink raw reply
* [PATCH ath-next] wifi: ath9k: owl: remove misleading error message
From: Rosen Penev @ 2026-05-21 23:21 UTC (permalink / raw)
To: linux-wireless
Cc: Toke Høiland-Jørgensen, Andreas Färber,
Manivannan Sadhasivam,
moderated list:ARM/ACTIONS SEMI ARCHITECTURE,
moderated list:ARM/ACTIONS SEMI ARCHITECTURE, open list
The error is about the firmware failing to be requested, not calibration
data. Just return directly anyways.
Signed-off-by: Rosen Penev <rosenp@gmail.com>
---
drivers/net/wireless/ath/ath9k/ath9k_pci_owl_loader.c | 6 +-----
1 file changed, 1 insertion(+), 5 deletions(-)
diff --git a/drivers/net/wireless/ath/ath9k/ath9k_pci_owl_loader.c b/drivers/net/wireless/ath/ath9k/ath9k_pci_owl_loader.c
index b9ef34709202..4460ee7f44e1 100644
--- a/drivers/net/wireless/ath/ath9k/ath9k_pci_owl_loader.c
+++ b/drivers/net/wireless/ath/ath9k/ath9k_pci_owl_loader.c
@@ -204,12 +204,8 @@ static int owl_probe(struct pci_dev *pdev,
scnprintf(eeprom_name, sizeof(eeprom_name), "ath9k-eeprom-pci-%s.bin",
dev_name(dev));
- err = request_firmware_nowait(THIS_MODULE, true, eeprom_name,
+ return request_firmware_nowait(THIS_MODULE, true, eeprom_name,
&pdev->dev, GFP_KERNEL, ctx, owl_fw_cb);
- if (err)
- dev_err(&pdev->dev, "failed to request caldata (%d).\n", err);
-
- return err;
}
static void owl_remove(struct pci_dev *pdev)
--
2.54.0
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox