* [PATCH v6 1/4] media: dt-bindings: mediatek: Add AIE face detection support for MT8188
From: Sarang Chaudhari @ 2026-06-05 8:28 UTC (permalink / raw)
To: Rob Herring, AngeloGioacchino Del Regno, Mauro Carvalho Chehab,
linux-kernel, linux-arm-kernel, linux-mediatek
Cc: zhaoyuan.chen, Teddy.Chen, Project_Global_Chrome_Upstream_Group,
Sarang Chaudhari
Add YAML device tree bindings for the MediaTek AI Engine (AIE) hardware
accelerator found in MT8188 SoCs. The AIE provides hardware-accelerated
face detection, facial landmark detection, and face attribute analysis
capabilities.
Add a MAINTAINERS entry covering the binding, the UAPI header and the
driver directory.
Signed-off-by: Sarang Chaudhari <sarang.chaudhari@mediatek.com>
---
Changes in v6:
- Add ipe-smi-larb12 clock to the binding (was missing in v5 binding
but present in v5 dtsi).
- Remove iommus from required properties (made optional for platforms
that can operate without IOMMU).
- Add mediatek,larb as an optional property.
- Improve description text.
Changes in v5:
- Modify the description to make it more concise.
- Delete the description of reg.
- Modify the description of iommus and delete the maxItems of iommus.
- Delete all mediatek,larb.
- Modify the name of clock, change _ to -.
Changes in v4:
- Remove address-cells and size-cells.
- Remove larb12 related content.
- Update id content.
Changes in v3: None
Changes in v2:
- Fix coding style.
.../bindings/media/mediatek,mt8188-aie.yaml | 85 +++++++++++++++++++
MAINTAINERS | 10 +++
2 files changed, 95 insertions(+)
create mode 100644 Documentation/devicetree/bindings/media/mediatek,mt8188-aie.yaml
diff --git a/Documentation/devicetree/bindings/media/mediatek,mt8188-aie.yaml b/Documentation/devicetree/bindings/media/mediatek,mt8188-aie.yaml
new file mode 100644
index 0000000..ab888f0
--- /dev/null
+++ b/Documentation/devicetree/bindings/media/mediatek,mt8188-aie.yaml
@@ -0,0 +1,85 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/media/mediatek,mt8188-aie.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: MediaTek AI Engine (AIE) for Face Detection
+
+maintainers:
+ - Fish Wu <fish.wu@mediatek.com>
+ - Bo Kong <bo.kong@mediatek.com>
+
+description: |
+ The MediaTek AI Engine (AIE) provides hardware-accelerated face detection,
+ facial landmark detection, and face attribute analysis. It is found in the
+ IPE (Image Processing Engine) subsystem of MediaTek SoCs.
+
+properties:
+ compatible:
+ enum:
+ - mediatek,mt8188-aie
+
+ reg:
+ maxItems: 1
+
+ interrupts:
+ maxItems: 1
+
+ clocks:
+ items:
+ - description: clock for imgsys main ipe
+ - description: clock for ipe fdvt
+ - description: clock for ipe smi larb12
+ - description: clock for ipe top
+
+ clock-names:
+ items:
+ - const: img-ipe
+ - const: ipe-fdvt
+ - const: ipe-smi-larb12
+ - const: ipe-top
+
+ power-domains:
+ maxItems: 1
+
+ iommus:
+ maxItems: 1
+
+ mediatek,larb:
+ $ref: /schemas/types.yaml#/definitions/phandle
+ description: phandle to the local arbiter (LARB) node
+
+required:
+ - compatible
+ - reg
+ - interrupts
+ - clocks
+ - clock-names
+ - power-domains
+
+additionalProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/interrupt-controller/arm-gic.h>
+ #include <dt-bindings/clock/mediatek,mt8188-clk.h>
+ #include <dt-bindings/power/mediatek,mt8188-power.h>
+
+ soc {
+ #address-cells = <2>;
+ #size-cells = <2>;
+
+ aie@15310000 {
+ compatible = "mediatek,mt8188-aie";
+ reg = <0 0x15310000 0 0x1000>;
+ interrupts = <GIC_SPI 600 IRQ_TYPE_LEVEL_HIGH 0>;
+ clocks = <&imgsys CLK_IMGSYS_MAIN_IPE>,
+ <&ipesys CLK_IPE_FDVT>,
+ <&ipesys CLK_IPE_SMI_LARB12>,
+ <&ipesys CLK_IPESYS_TOP>;
+ clock-names = "img-ipe", "ipe-fdvt",
+ "ipe-smi-larb12", "ipe-top";
+ power-domains = <&spm MT8188_POWER_DOMAIN_IPE>;
+ };
+ };
diff --git a/MAINTAINERS b/MAINTAINERS
index afb7487..fa631d6 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -3,6 +3,16 @@ M: Felix Fietkau <nbd@nbd.name>
S: Maintained
F: drivers/net/ethernet/mediatek/
+MEDIATEK MT8188 AIE DRIVER
+M: Fish Wu <fish.wu@mediatek.com>
+M: Bo Kong <bo.kong@mediatek.com>
+L: linux-media@vger.kernel.org
+L: linux-mediatek@lists.infradead.org (moderated for non-subscribers)
+S: Maintained
+F: Documentation/devicetree/bindings/media/mediatek,mt8188-aie.yaml
+F: drivers/media/platform/mediatek/aie/
+F: include/uapi/linux/mtk_aie_v4l2_controls.h
+
MEDIATEK MDP DRIVER
M: Minghsiu Tsai <minghsiu.tsai@mediatek.com>
S: Supported
--
2.45.2
^ permalink raw reply related
* [PATCH v6 0/4] Add MT8188 AIE driver
From: Sarang Chaudhari @ 2026-06-05 8:20 UTC (permalink / raw)
To: Rob Herring, AngeloGioacchino Del Regno, Mauro Carvalho Chehab,
linux-kernel, linux-arm-kernel, linux-mediatek
Cc: zhaoyuan.chen, Teddy.Chen, Project_Global_Chrome_Upstream_Group,
Sarang Chaudhari
AIE (AI Engine) is one of the units in MT8188 ISP which provides
hardware-accelerated face detection function. It can detect different
sizes of faces in a raw image using pyramid-based multi-scale detection.
The AIE supports three operation modes:
- Face Detection (FD): Multi-scale face detection using 3-level pyramid
(640x480 base, 2x downscale per level).
- Attribute Analysis: Age, gender, and race classification.
- Facial Landmark Detection (FLD): 11-point landmark localization using
Binary Tree Traversal on FD results.
Changes in v6:
- DT binding: Add ipe-smi-larb12 clock, remove iommus from required
properties, add mediatek,larb as optional, improve description.
- DTS: Remove iommus and mediatek,larb properties, fix IRQ number.
- UAPI: Simplify header to control ID definitions only, drop custom
V4L2_CTRL_TYPE (use V4L2_CTRL_TYPE_U32 compound controls instead).
- Driver: Fix NULL pointer check inversion, fix resource leaks on error
path, remove debugfs return value checks, update clock names to hyphen
convention, remove freq_level per CK Hu's feedback.
Changes in v5:
- DT binding: Use hyphens in clock names, remove mediatek,larb.
- UAPI: Add feature_threshold docs, rename structures, move structures
from mtk_aie.h to uapi header.
- Driver: Update clock names, improve error handling in probe.
Changes in v4:
- DT binding: Remove address-cells/size-cells, remove larb12 content.
- UAPI: Add V4L2_META_FMT_MTFD_RESULT documentation.
- Driver: Remove larb12 related content.
Changes in v3:
- DTS: Remove non-MMIO nodes.
Changes in v2:
- Fix coding style issues throughout.
Sarang Chaudhari (4):
media: dt-bindings: mediatek: Add AIE face detection support for
MT8188
arm64: dts: mediatek: mt8188: Add AIE face detection node
media: uapi: mediatek: Add MT8188 AIE control definitions
media: platform: mediatek: Add MT8188 AIE driver
.../bindings/media/mediatek,mt8188-aie.yaml | 85 +
MAINTAINERS | 10 +
arch/arm64/boot/dts/mediatek/mt8188.dtsi | 13 +
drivers/media/platform/mediatek/Kconfig | 1 +
drivers/media/platform/mediatek/Makefile | 1 +
drivers/media/platform/mediatek/aie/Kconfig | 20 +
drivers/media/platform/mediatek/aie/Makefile | 5 +
drivers/media/platform/mediatek/aie/mtk_aie.h | 1045 +++++++++++
.../platform/mediatek/aie/mtk_aie_drv.c | 3667 +++++++++++++++++
.../platform/mediatek/aie/mtk_aie_v4l2.c | 1907 +++++++++
drivers/media/v4l2-core/v4l2-ioctl.c | 1 +
include/uapi/linux/mtk_aie_v4l2_controls.h | 23 +
include/uapi/linux/videodev2.h | 1 +
13 files changed, 6779 insertions(+)
create mode 100644 Documentation/devicetree/bindings/media/mediatek,mt8188-aie.yaml
create mode 100644 drivers/media/platform/mediatek/aie/Kconfig
create mode 100644 drivers/media/platform/mediatek/aie/Makefile
create mode 100644 drivers/media/platform/mediatek/aie/mtk_aie.h
create mode 100644 drivers/media/platform/mediatek/aie/mtk_aie_drv.c
create mode 100644 drivers/media/platform/mediatek/aie/mtk_aie_v4l2.c
create mode 100644 include/uapi/linux/mtk_aie_v4l2_controls.h
--
2.45.2
^ permalink raw reply
* [PATCH v2] KVM: arm64: Reassign nested_mmus array behind mmu_lock
From: Hyunwoo Kim @ 2026-06-05 8:27 UTC (permalink / raw)
To: maz, oupton, joey.gouly, seiden, suzuki.poulose, yuzenghui,
catalin.marinas, will, christoffer.dall
Cc: linux-arm-kernel, kvmarm, imv4bel
kvm->arch.nested_mmus[] is walked under kvm->mmu_lock, including from the
MMU notifier path (kvm_unmap_gfn_range() -> kvm_nested_s2_unmap()), which
can run at any time. kvm_vcpu_init_nested() reallocates the array and frees
the old buffer while holding only kvm->arch.config_lock, so such a walker
can reference the freed array.
Allocate the new array outside of mmu_lock, as the allocation can sleep.
Under the lock, copy the existing entries, fix up the back pointers and
reassign the array. Free the old buffer after dropping the lock, as
kvfree() can sleep as well.
Fixes: 4f128f8e1aaac ("KVM: arm64: nv: Support multiple nested Stage-2 mmu structures")
Signed-off-by: Hyunwoo Kim <imv4bel@gmail.com>
Reviewed-by: Oliver Upton <oupton@kernel.org>
---
Changes in v2:
- reword shortlog and changelog per review
(diff unchanged; kept Oliver's Reviewed-by)
- v1: https://lore.kernel.org/all/aiHEKOeZMVwsRlvP@v4bel/
---
arch/arm64/kvm/nested.c | 33 ++++++++++++++++++++-------------
1 file changed, 20 insertions(+), 13 deletions(-)
diff --git a/arch/arm64/kvm/nested.c b/arch/arm64/kvm/nested.c
index 38f672e94087..6f7bc9a9992e 100644
--- a/arch/arm64/kvm/nested.c
+++ b/arch/arm64/kvm/nested.c
@@ -89,21 +89,28 @@ int kvm_vcpu_init_nested(struct kvm_vcpu *vcpu)
* again, and there is no reason to affect the whole VM for this.
*/
num_mmus = atomic_read(&kvm->online_vcpus) * S2_MMU_PER_VCPU;
- tmp = kvrealloc(kvm->arch.nested_mmus,
- size_mul(sizeof(*kvm->arch.nested_mmus), num_mmus),
- GFP_KERNEL_ACCOUNT | __GFP_ZERO);
- if (!tmp)
- return -ENOMEM;
- swap(kvm->arch.nested_mmus, tmp);
+ if (num_mmus > kvm->arch.nested_mmus_size) {
+ tmp = kvcalloc(num_mmus, sizeof(*tmp), GFP_KERNEL_ACCOUNT);
+ if (!tmp)
+ return -ENOMEM;
- /*
- * If we went through a realocation, adjust the MMU back-pointers in
- * the previously initialised kvm_pgtable structures.
- */
- if (kvm->arch.nested_mmus != tmp)
- for (int i = 0; i < kvm->arch.nested_mmus_size; i++)
- kvm->arch.nested_mmus[i].pgt->mmu = &kvm->arch.nested_mmus[i];
+ write_lock(&kvm->mmu_lock);
+
+ if (kvm->arch.nested_mmus_size) {
+ memcpy(tmp, kvm->arch.nested_mmus,
+ size_mul(sizeof(*tmp), kvm->arch.nested_mmus_size));
+
+ for (int i = 0; i < kvm->arch.nested_mmus_size; i++)
+ tmp[i].pgt->mmu = &tmp[i];
+ }
+
+ swap(kvm->arch.nested_mmus, tmp);
+
+ write_unlock(&kvm->mmu_lock);
+
+ kvfree(tmp);
+ }
for (int i = kvm->arch.nested_mmus_size; !ret && i < num_mmus; i++)
ret = init_nested_s2_mmu(kvm, &kvm->arch.nested_mmus[i]);
--
2.43.0
^ permalink raw reply related
* Re: [PATCH] KVM: arm64: vgic: Use list_del_rcu() when flushing pending LPIs
From: Marc Zyngier @ 2026-06-05 8:17 UTC (permalink / raw)
To: Oliver Upton
Cc: Hyunwoo Kim, joey.gouly, seiden, suzuki.poulose, yuzenghui,
catalin.marinas, will, Sascha.Bischoff, jic23, linux-arm-kernel,
kvmarm
In-Reply-To: <aiJi5a3JJ-TbWL-s@kernel.org>
On Fri, 05 Jun 2026 06:47:17 +0100,
Oliver Upton <oupton@kernel.org> wrote:
>
> Hi Hyunwoo,
>
> On Fri, Jun 05, 2026 at 06:16:08AM +0900, Hyunwoo Kim wrote:
> > vgic_v3_fold_lr_state() walks the ap_list from last_lr_irq without holding
> > the ap_list_lock, relying on vgic_irq being freed via kfree_rcu() and on
> > interrupts being disabled. vgic_flush_pending_lpis() removes entries with
> > list_del(), which clobbers a node's next pointer, so when another vCPU
> > disables LPIs via GICR_CTLR the walk can follow the clobbered next pointer
> > from a removed node, or from the node that last_lr_irq points to.
> >
> > Remove entries with list_del_rcu() so that the next pointer stays valid
> > until the walk completes.
> >
> > Fixes: 3cfd59f81e0f ("KVM: arm64: GICv3: Handle LR overflow when EOImode==0")
> > Signed-off-by: Hyunwoo Kim <imv4bel@gmail.com>
>
> Changing only one of the writer paths to use the rculist helpers does
> not make the ap_list an rculist. Insertions are not RCU-safe, nor are
> deleations from vgic_prune_ap_list().
>
> And TBH, the real bug here is the fact that vgic_v3_fold_lr_state() isn't
> taking the ap_list_lock.
Yup, that'd be more sensible. I need to convince myself that there is
no possible path from vgic_v*_fold_lr() to vgic_irq_queue_unlock(),
because that one does actually acquire that lock.
M.
--
Jazz isn't dead. It just smells funny.
^ permalink raw reply
* Re: [PATCH v14 29/44] arm64: RMI: Runtime faulting of memory
From: Gavin Shan @ 2026-06-05 8:11 UTC (permalink / raw)
To: Lorenzo Pieralisi
Cc: Steven Price, kvm, kvmarm, Catalin Marinas, Marc Zyngier,
Will Deacon, James Morse, Oliver Upton, Suzuki K Poulose,
Zenghui Yu, linux-arm-kernel, linux-kernel, Joey Gouly,
Alexandru Elisei, Christoffer Dall, Fuad Tabba, linux-coco,
Ganapatrao Kulkarni, Shanker Donthineni, Alper Gun,
Aneesh Kumar K . V, Emi Kisanuki, Vishal Annapurve, WeiLin.Chang,
Lorenzo.Pieralisi2
In-Reply-To: <aiJ6u83O0nVUtPyv@lpieralisi>
On 6/5/26 5:28 PM, Lorenzo Pieralisi wrote:
> On Fri, Jun 05, 2026 at 04:23:15PM +1000, Gavin Shan wrote:
>
> [...]
>
>>> +static int realm_map_ipa(struct kvm *kvm, phys_addr_t ipa,
>>> + kvm_pfn_t pfn, unsigned long map_size,
>>> + enum kvm_pgtable_prot prot,
>>> + struct kvm_mmu_memory_cache *memcache)
>>> +{
>>> + struct realm *realm = &kvm->arch.realm;
>>> +
>>> + /*
>>> + * Write permission is required for now even though it's possible to
>>> + * map unprotected pages (granules) as read-only. It's impossible to
>>> + * map protected pages (granules) as read-only.
>>> + */
>>> + if (WARN_ON(!(prot & KVM_PGTABLE_PROT_W)))
>>> + return -EFAULT;
>>> +
>>
>> I'm a bit concerned with this. We don't have KVM_PGTABLE_PROT_W set in @prot
>> if the stage2 fault is raised due to memory read. With -EFAULT returned to VMM
>> (e.g. QEMU), the vCPU continuous execution is stopped and system won't be
>> working any more.
>>
>>> + ipa = ALIGN_DOWN(ipa, PAGE_SIZE);
>>> + if (!kvm_realm_is_private_address(realm, ipa))
>>> + return realm_map_non_secure(realm, ipa, pfn, map_size, prot,
>>> + memcache);
>>> +
>>> + return realm_map_protected(kvm, ipa, pfn, map_size, memcache);
>>> +}
>>> +
>>> static bool kvm_vma_is_cacheable(struct vm_area_struct *vma)
>>> {
>>> switch (FIELD_GET(PTE_ATTRINDX_MASK, pgprot_val(vma->vm_page_prot))) {
>>> @@ -1604,27 +1641,52 @@ static int gmem_abort(const struct kvm_s2_fault_desc *s2fd)
>>> bool write_fault, exec_fault;
>>> enum kvm_pgtable_walk_flags flags = KVM_PGTABLE_WALK_SHARED;
>>> enum kvm_pgtable_prot prot = KVM_PGTABLE_PROT_R;
>>> - struct kvm_pgtable *pgt = s2fd->vcpu->arch.hw_mmu->pgt;
>>> + struct kvm_vcpu *vcpu = s2fd->vcpu;
>>> + struct kvm_pgtable *pgt = vcpu->arch.hw_mmu->pgt;
>>> + gpa_t gpa = kvm_gpa_from_fault(vcpu->kvm, s2fd->fault_ipa);
>>> unsigned long mmu_seq;
>>> struct page *page;
>>> - struct kvm *kvm = s2fd->vcpu->kvm;
>>> + struct kvm *kvm = vcpu->kvm;
>>> void *memcache;
>>> kvm_pfn_t pfn;
>>> gfn_t gfn;
>>> int ret;
>>> - memcache = get_mmu_memcache(s2fd->vcpu);
>>> - ret = topup_mmu_memcache(s2fd->vcpu, memcache);
>>> + if (kvm_is_realm(vcpu->kvm)) {
>>> + /* check for memory attribute mismatch */
>>> + bool is_priv_gfn = kvm_mem_is_private(kvm, gpa >> PAGE_SHIFT);
>>> + /*
>>> + * For Realms, the shared address is an alias of the private
>>> + * PA with the top bit set. Thus if the fault address matches
>>> + * the GPA then it is the private alias.
>>> + */
>>> + bool is_priv_fault = (gpa == s2fd->fault_ipa);
>>> +
>>> + if (is_priv_gfn != is_priv_fault) {
>>> + kvm_prepare_memory_fault_exit(vcpu, gpa, PAGE_SIZE,
>>> + kvm_is_write_fault(vcpu),
>>> + false,
>>> + is_priv_fault);
>>> + /*
>>> + * KVM_EXIT_MEMORY_FAULT requires an return code of
>>> + * -EFAULT, see the API documentation
>>> + */
>>> + return -EFAULT;
>>> + }
>>> + }
>>> +
>>> + memcache = get_mmu_memcache(vcpu);
>>> + ret = topup_mmu_memcache(vcpu, memcache);
>>> if (ret)
>>> return ret;
>>> if (s2fd->nested)
>>> gfn = kvm_s2_trans_output(s2fd->nested) >> PAGE_SHIFT;
>>> else
>>> - gfn = s2fd->fault_ipa >> PAGE_SHIFT;
>>> + gfn = gpa >> PAGE_SHIFT;
>>> - write_fault = kvm_is_write_fault(s2fd->vcpu);
>>> - exec_fault = kvm_vcpu_trap_is_exec_fault(s2fd->vcpu);
>>> + write_fault = kvm_is_write_fault(vcpu);
>>> + exec_fault = kvm_vcpu_trap_is_exec_fault(vcpu);
>>> VM_WARN_ON_ONCE(write_fault && exec_fault);
>>> @@ -1634,7 +1696,7 @@ static int gmem_abort(const struct kvm_s2_fault_desc *s2fd)
>>> ret = kvm_gmem_get_pfn(kvm, s2fd->memslot, gfn, &pfn, &page, NULL);
>>> if (ret) {
>>> - kvm_prepare_memory_fault_exit(s2fd->vcpu, s2fd->fault_ipa, PAGE_SIZE,
>>> + kvm_prepare_memory_fault_exit(vcpu, gpa, PAGE_SIZE,
>>> write_fault, exec_fault, false);
>>> return ret;
>>> }
>>> @@ -1654,14 +1716,20 @@ static int gmem_abort(const struct kvm_s2_fault_desc *s2fd)
>>> kvm_fault_lock(kvm);
>>> if (mmu_invalidate_retry(kvm, mmu_seq)) {
>>> ret = -EAGAIN;
>>> - goto out_unlock;
>>> + goto out_release_page;
>>> + }
>>> +
>>> + if (kvm_is_realm(kvm)) {
>>> + ret = realm_map_ipa(kvm, s2fd->fault_ipa, pfn,
>>> + PAGE_SIZE, KVM_PGTABLE_PROT_R | KVM_PGTABLE_PROT_W, memcache);
>>> + goto out_release_page;
>>> }
>>> ret = KVM_PGT_FN(kvm_pgtable_stage2_map)(pgt, s2fd->fault_ipa, PAGE_SIZE,
>>> __pfn_to_phys(pfn), prot,
>>> memcache, flags);
>>> -out_unlock:
>>> +out_release_page:
>>> kvm_release_faultin_page(kvm, page, !!ret, prot & KVM_PGTABLE_PROT_W);
>>> kvm_fault_unlock(kvm);
>>> @@ -1847,7 +1915,7 @@ static int kvm_s2_fault_get_vma_info(const struct kvm_s2_fault_desc *s2fd,
>>> * mapping size to ensure we find the right PFN and lay down the
>>> * mapping in the right place.
>>> */
>>> - s2vi->gfn = ALIGN_DOWN(s2fd->fault_ipa, s2vi->vma_pagesize) >> PAGE_SHIFT;
>>> + s2vi->gfn = kvm_gpa_from_fault(kvm, ALIGN_DOWN(s2fd->fault_ipa, s2vi->vma_pagesize)) >> PAGE_SHIFT;
>>> s2vi->mte_allowed = kvm_vma_mte_allowed(vma);
>>> @@ -2056,6 +2124,9 @@ static int kvm_s2_fault_map(const struct kvm_s2_fault_desc *s2fd,
>>> prot &= ~KVM_NV_GUEST_MAP_SZ;
>>> ret = KVM_PGT_FN(kvm_pgtable_stage2_relax_perms)(pgt, gfn_to_gpa(gfn),
>>> prot, flags);
>>> + } else if (kvm_is_realm(kvm)) {
>>> + ret = realm_map_ipa(kvm, s2fd->fault_ipa, pfn, mapping_size,
>>> + prot, memcache);
>>> } else {
>>> ret = KVM_PGT_FN(kvm_pgtable_stage2_map)(pgt, gfn_to_gpa(gfn), mapping_size,
>>> __pfn_to_phys(pfn), prot,
>>
>> For the case kvm_is_realm(), need we adjust 's2fd->fault_ipa' for the sake of
>> huge pages. In kvm_s2_fault_map(), @gfn and @pfn may have been adjusted by
>> transparent_hugepage_adjust() to be aligned with huge page size. If the
>> adjustment happened in transparent_hugepage_adjust(), we need to align
>> s2fd->fault_ipa down to the huge page size either.
>
> All of the above + some RMM changes are needed to get QEmu VMM going
> with anon pages guest memory backing - currently testing various
> configurations in the background.
>
I tried to rebase Jean's latest QEMU series [1] to upstream QEMU, and found
that memory slots backed by THP are broken. With THP disabled on the host and
other fixes (mentioned in my prevous replies) applied on the top of this (v14)
series, I'm able to boot a realm guest with rebased QEMU series [2], plus more
fxies on the top.
[1] https://git.codelinaro.org/linaro/dcap/qemu.git (branch: cca/latest)
[2] https://git.qemu.org/git/qemu.git (branch: cca/gavin)
Lorenzo, You may be saying there is someone making QEMU to support ARM/CCA?
If so, I'm not sure if there is a QEMU repository for me to try?
Thanks,
Gavin
> Thanks,
> Lorenzo
>
>>> @@ -2214,6 +2285,13 @@ int kvm_handle_guest_sea(struct kvm_vcpu *vcpu)
>>> return 0;
>>> }
>>> +static bool shared_ipa_fault(struct kvm *kvm, phys_addr_t fault_ipa)
>>> +{
>>> + gpa_t gpa = kvm_gpa_from_fault(kvm, fault_ipa);
>>> +
>>> + return (gpa != fault_ipa);
>>> +}
>>> +
>>> /**
>>> * kvm_handle_guest_abort - handles all 2nd stage aborts
>>> * @vcpu: the VCPU pointer
>>> @@ -2324,8 +2402,9 @@ int kvm_handle_guest_abort(struct kvm_vcpu *vcpu)
>>> nested = &nested_trans;
>>> }
>>> - gfn = ipa >> PAGE_SHIFT;
>>> + gfn = kvm_gpa_from_fault(vcpu->kvm, ipa) >> PAGE_SHIFT;
>>> memslot = gfn_to_memslot(vcpu->kvm, gfn);
>>> +
>>> hva = gfn_to_hva_memslot_prot(memslot, gfn, &writable);
>>> write_fault = kvm_is_write_fault(vcpu);
>>> if (kvm_is_error_hva(hva) || (write_fault && !writable)) {
>>> @@ -2368,7 +2447,7 @@ int kvm_handle_guest_abort(struct kvm_vcpu *vcpu)
>>> * of the page size.
>>> */
>>> ipa |= FAR_TO_FIPA_OFFSET(kvm_vcpu_get_hfar(vcpu));
>>> - ret = io_mem_abort(vcpu, ipa);
>>> + ret = io_mem_abort(vcpu, kvm_gpa_from_fault(vcpu->kvm, ipa));
>>> goto out_unlock;
>>> }
>>> @@ -2396,7 +2475,7 @@ int kvm_handle_guest_abort(struct kvm_vcpu *vcpu)
>>> !write_fault &&
>>> !kvm_vcpu_trap_is_exec_fault(vcpu));
>>> - if (kvm_slot_has_gmem(memslot))
>>> + if (kvm_slot_has_gmem(memslot) && !shared_ipa_fault(vcpu->kvm, fault_ipa))
>>> ret = gmem_abort(&s2fd);
>>> else
>>> ret = user_mem_abort(&s2fd);
>>> @@ -2433,6 +2512,10 @@ bool kvm_age_gfn(struct kvm *kvm, struct kvm_gfn_range *range)
>>> if (!kvm->arch.mmu.pgt || kvm_vm_is_protected(kvm))
>>> return false;
>>> + /* We don't support aging for Realms */
>>> + if (kvm_is_realm(kvm))
>>> + return true;
>>> +
>>> return KVM_PGT_FN(kvm_pgtable_stage2_test_clear_young)(kvm->arch.mmu.pgt,
>>> range->start << PAGE_SHIFT,
>>> size, true);
>>> @@ -2449,6 +2532,10 @@ bool kvm_test_age_gfn(struct kvm *kvm, struct kvm_gfn_range *range)
>>> if (!kvm->arch.mmu.pgt || kvm_vm_is_protected(kvm))
>>> return false;
>>> + /* We don't support aging for Realms */
>>> + if (kvm_is_realm(kvm))
>>> + return true;
>>> +
>>> return KVM_PGT_FN(kvm_pgtable_stage2_test_clear_young)(kvm->arch.mmu.pgt,
>>> range->start << PAGE_SHIFT,
>>> size, false);
>>> @@ -2628,10 +2715,11 @@ int kvm_arch_prepare_memory_region(struct kvm *kvm,
>>> return -EFAULT;
>>> /*
>>> - * Only support guest_memfd backed memslots with mappable memory, since
>>> - * there aren't any CoCo VMs that support only private memory on arm64.
>>> + * Only support guest_memfd backed memslots with mappable memory,
>>> + * unless the guest is a CCA realm guest.
>>> */
>>> - if (kvm_slot_has_gmem(new) && !kvm_memslot_is_gmem_only(new))
>>> + if (kvm_slot_has_gmem(new) && !kvm_memslot_is_gmem_only(new) &&
>>> + !kvm_is_realm(kvm))
>>> return -EINVAL;
>>> hva = new->userspace_addr;
>>> diff --git a/arch/arm64/kvm/rmi.c b/arch/arm64/kvm/rmi.c
>>> index cae29fd3353c..761b38a4071c 100644
>>> --- a/arch/arm64/kvm/rmi.c
>>> +++ b/arch/arm64/kvm/rmi.c
>>> @@ -597,6 +597,179 @@ static int realm_data_map_init(struct kvm *kvm, unsigned long ipa,
>>> return ret;
>>> }
>>> +static unsigned long addr_range_desc(unsigned long phys, unsigned long size)
>>> +{
>>> + unsigned long out = 0;
>>> +
>>> + switch (size) {
>>> + case P4D_SIZE:
>>> + out = 3 | (1 << 2);
>>> + break;
>>> + case PUD_SIZE:
>>> + out = 2 | (1 << 2);
>>> + break;
>>> + case PMD_SIZE:
>>> + out = 1 | (1 << 2);
>>> + break;
>>> + case PAGE_SIZE:
>>> + out = 0 | (1 << 2);
>>> + break;
>>> + default:
>>> + /*
>>> + * Only support mapping at the page level granulatity when
>>> + * it's an unusual length. This should get us back onto a larger
>>> + * block size for the subsequent mappings.
>>> + */
>>> + out = 0 | ((MIN(size >> PAGE_SHIFT, PTRS_PER_PTE - 1)) << 2);
>>> + break;
>>> + }
>>> +
>>> + WARN_ON(phys & ~PAGE_MASK);
>>> +
>>> + out |= phys & PAGE_MASK;
>>> +
>>> + return out;
>>> +}
>>> +
>>> +int realm_map_protected(struct kvm *kvm,
>>> + unsigned long ipa,
>>> + kvm_pfn_t pfn,
>>> + unsigned long map_size,
>>> + struct kvm_mmu_memory_cache *memcache)
>>> +{
>>> + struct realm *realm = &kvm->arch.realm;
>>> + phys_addr_t phys = __pfn_to_phys(pfn);
>>> + phys_addr_t base_phys = phys;
>>> + phys_addr_t rd = virt_to_phys(realm->rd);
>>> + unsigned long base_ipa = ipa;
>>> + unsigned long ipa_top = ipa + map_size;
>>> + int ret = 0;
>>> +
>>> + if (WARN_ON(!IS_ALIGNED(map_size, PAGE_SIZE) ||
>>> + !IS_ALIGNED(ipa, map_size)))
>>> + return -EINVAL;
>>> +
>>> + if (rmi_delegate_range(phys, map_size)) {
>>> + /*
>>> + * It's likely we raced with another VCPU on the same
>>> + * fault. Assume the other VCPU has handled the fault
>>> + * and return to the guest.
>>> + */
>>> + return 0;
>>> + }
>>> +
>>> + while (ipa < ipa_top) {
>>> + unsigned long flags = RMI_ADDR_TYPE_SINGLE;
>>> + unsigned long range_desc = addr_range_desc(phys, ipa_top - ipa);
>>> + unsigned long out_top;
>>> +
>>> + ret = rmi_rtt_data_map(rd, ipa, ipa_top, flags, range_desc,
>>> + &out_top);
>>> +
>>> + if (RMI_RETURN_STATUS(ret) == RMI_ERROR_RTT) {
>>> + /* Create missing RTTs and retry */
>>> + int level = RMI_RETURN_INDEX(ret);
>>> +
>>> + WARN_ON(level == KVM_PGTABLE_LAST_LEVEL);
>>> + ret = realm_create_rtt_levels(realm, ipa, level,
>>> + KVM_PGTABLE_LAST_LEVEL,
>>> + memcache);
>>> + if (ret)
>>> + goto err_undelegate;
>>> +
>>> + ret = rmi_rtt_data_map(rd, ipa, ipa_top, flags,
>>> + range_desc, &out_top);
>>> + }
>>> +
>>> + if (WARN_ON(ret))
>>> + goto err_undelegate;
>>> +
>>> + phys += out_top - ipa;
>>> + ipa = out_top;
>>> + }
>>> +
>>> + return 0;
>>> +
>>> +err_undelegate:
>>> + realm_unmap_private_range(kvm, base_ipa, ipa, true);
>>> + if (WARN_ON(rmi_undelegate_range(base_phys, map_size))) {
>>> + /* Page can't be returned to NS world so is lost */
>>> + get_page(phys_to_page(base_phys));
>>> + }
>>> + return -ENXIO;
>>> +}
>>> +
>>> +int realm_map_non_secure(struct realm *realm,
>>> + unsigned long ipa,
>>> + kvm_pfn_t pfn,
>>> + unsigned long size,
>>> + enum kvm_pgtable_prot prot,
>>> + struct kvm_mmu_memory_cache *memcache)
>>> +{
>>> + unsigned long attr, flags = 0;
>>> + phys_addr_t rd = virt_to_phys(realm->rd);
>>> + phys_addr_t phys = __pfn_to_phys(pfn);
>>> + unsigned long ipa_top = ipa + size;
>>> + int ret;
>>> +
>>> + if (WARN_ON(!IS_ALIGNED(size, PAGE_SIZE) ||
>>> + !IS_ALIGNED(ipa, size)))
>>> + return -EINVAL;
>>> +
>>> + switch (prot & (KVM_PGTABLE_PROT_DEVICE | KVM_PGTABLE_PROT_NORMAL_NC)) {
>>> + case KVM_PGTABLE_PROT_DEVICE | KVM_PGTABLE_PROT_NORMAL_NC:
>>> + return -EINVAL;
>>> + case KVM_PGTABLE_PROT_DEVICE:
>>> + attr = MT_S2_FWB_DEVICE_nGnRE;
>>> + break;
>>> + case KVM_PGTABLE_PROT_NORMAL_NC:
>>> + attr = MT_S2_FWB_NORMAL_NC;
>>> + break;
>>> + default:
>>> + attr = MT_S2_FWB_NORMAL;
>>> + }
>>> +
>>> + flags |= FIELD_PREP(RMI_RTT_UNPROT_MAP_FLAGS_MEMATTR, attr);
>>> +
>>> + if (prot & KVM_PGTABLE_PROT_R)
>>> + flags |= FIELD_PREP(RMI_RTT_UNPROT_MAP_FLAGS_S2AP, RMI_S2AP_DIRECT_READ);
>>> + if (prot & KVM_PGTABLE_PROT_W)
>>> + flags |= FIELD_PREP(RMI_RTT_UNPROT_MAP_FLAGS_S2AP, RMI_S2AP_DIRECT_WRITE);
>>> +
>>> + flags |= RMI_ADDR_TYPE_SINGLE;
>>> +
>>> + while (ipa < ipa_top) {
>>> + unsigned long range_desc = addr_range_desc(phys, ipa_top - ipa);
>>> + unsigned long out_top;
>>> +
>>> + ret = rmi_rtt_unprot_map(rd, ipa, ipa_top, flags, range_desc,
>>> + &out_top);
>>> +
>>> + if (RMI_RETURN_STATUS(ret) == RMI_ERROR_RTT) {
>>> + /* Create missing RTTs and retry */
>>> + int level = RMI_RETURN_INDEX(ret);
>>> +
>>> + WARN_ON(level == KVM_PGTABLE_LAST_LEVEL);
>>> + ret = realm_create_rtt_levels(realm, ipa, level,
>>> + KVM_PGTABLE_LAST_LEVEL,
>>> + memcache);
>>> + if (ret)
>>> + return ret;
>>> +
>>> + ret = rmi_rtt_unprot_map(rd, ipa, ipa_top, flags,
>>> + range_desc, &out_top);
>>> + }
>>> +
>>> + if (WARN_ON(ret))
>>> + return ret;
>>> +
>>> + phys += out_top - ipa;
>>> + ipa = out_top;
>>> + }
>>> +
>>> + return 0;
>>> +}
>>> +
>>> static int populate_region_cb(struct kvm *kvm, gfn_t gfn, kvm_pfn_t pfn,
>>> struct page *src_page, void *opaque)
>>> {
>>
>> Thanks,
>> Gavin
>>
>
^ permalink raw reply
* Re: [PATCH v1] arm64: errata: Workaround NVIDIA Olympus device store/load ordering erratum
From: Catalin Marinas @ 2026-06-05 8:01 UTC (permalink / raw)
To: Shanker Donthineni
Cc: Will Deacon, linux-arm-kernel, Mark Rutland, linux-kernel,
linux-doc, Vikram Sethi, Jason Sequeira
In-Reply-To: <20260604231254.1904988-1-sdonthineni@nvidia.com>
On Thu, Jun 04, 2026 at 06:12:54PM -0500, Shanker Donthineni wrote:
> On systems with NVIDIA Olympus cores, a Device-nGnR* load can be
> observed by a peripheral before an older, non-overlapping Device-nGnR*
> store to the same peripheral. This breaks the program-order guarantee
> that software expects for Device-nGnR* accesses and can leave a
> peripheral in an incorrect state, as a load is observed before an
> earlier store takes effect.
>
> The erratum can occur only when all of the following apply:
>
> - A PE executes a Device-nGnR* store followed by a younger
> Device-nGnR* load.
> - The store is not a store-release.
> - The accesses target the same peripheral and do not overlap in bytes.
> - There is at most one intervening Device-nGnR* store in program
> order, and there are no intervening Device-nGnR* loads.
> - There is no DSB, and no DMB that orders loads, between the store and
> the load.
> - Specific micro-architectural and timing conditions occur.
>
> Two ways to restore ordering: insert a barrier (any DSB, or a DMB that
> orders loads) between the store and the load, or make the store a
> store-release. A load-acquire on the load side would not help, because
> acquire semantics do not prevent a load from being observed ahead of an
> older store; only the store side (release or a barrier) closes the
> window.
Ignoring Device-nGnR*, a store-release followed by a load (not
load-acquire) would not guarantee any ordering. I assume the
store-release behaviour is specific to this erratum - part of the
preconditions.
The patch looks fine to me.
Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>
^ permalink raw reply
* [PATCH] net: stmmac: prevent kernel panic during XDP program and XSK pool transitions
From: Carlos Fangmeier @ 2026-06-05 7:56 UTC (permalink / raw)
To: Alexei Starovoitov, Daniel Borkmann, David S. Miller,
Jakub Kicinski, Jesper Dangaard Brouer, John Fastabend,
Stanislav Fomichev, Andrew Lunn, Eric Dumazet, Paolo Abeni,
Maxime Coquelin, Alexandre Torgue, Ong Boon Leong
Cc: netdev, bpf, linux-stm32, linux-arm-kernel, linux-kernel,
Carlos Fangmeier
stmmac_xdp_set_prog() tears down and rebuilds all DMA channels via
stmmac_xdp_release()/stmmac_xdp_open() without pausing the netdev
TX path. Similarly, stmmac_xdp_enable_pool() and
stmmac_xdp_disable_pool() reconfigure individual queue DMA rings
while TX remains active.
If the kernel transmits a frame during these windows — for example an
MLD report queued by the IPv6 stack — stmmac_xmit() calls
dwmac4_set_addr() against an MMIO register whose mapping has been
torn down, triggering a level-3 translation fault:
Unable to handle kernel paging request at virtual address ffff8000840ec000
pc : dwmac4_set_addr+0x8/0x18
lr : stmmac_xmit+0x64c/0xb60
Call trace:
dwmac4_set_addr+0x8/0x18
dev_hard_start_xmit+0xb0/0x220
sch_direct_xmit+0x108/0x3f0
__dev_queue_xmit+0x844/0xd00
ip6_finish_output2+0x2d8/0x610
mld_sendpack+0x180/0x2e0
mld_ifc_work+0x1dc/0x480
The existing netif_tx_disable() in stmmac_xdp_release() is not
sufficient because stmmac_xdp_open() re-enables TX via
netif_tx_start_all_queues() before the caller regains control, leaving
a window where the freshly rebuilt rings can race with pending TX work.
Fix this by wrapping each reconfiguration path with
netif_tx_disable()/netif_tx_wake_all_queues():
- stmmac_xdp_set_prog(): hold TX disabled across the full
stmmac_xdp_release() + stmmac_xdp_open() sequence, only waking
TX after stmmac_xdp_open() returns.
- stmmac_xdp_enable_pool(): disable TX before tearing down the
queue, re-enable after the queue is rebuilt and NAPI is active.
- stmmac_xdp_disable_pool(): same pattern around the pool teardown
and queue rebuild.
Tested on Cortex-A55 (stmmac/dwmac4, kernel 6.6.60) with AF_XDP
zero-copy and IPv6 active — no panics observed across repeated
XDP attach/detach and XSK pool setup/teardown cycles.
Fixes: 132c32ee5bc0 ("net: stmmac: Add TX via XDP zero-copy socket")
Signed-off-by: Carlos Fangmeier <carlos.fangmeier@gmail.com>
---
drivers/net/ethernet/stmicro/stmmac/stmmac_xdp.c | 12 ++++++++++--
1 file changed, 10 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_xdp.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_xdp.c
index d7e4db7224b0..a6611aee687f 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_xdp.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_xdp.c
@@ -34,6 +34,7 @@ static int stmmac_xdp_enable_pool(struct stmmac_priv *priv,
need_update = netif_running(priv->dev) && stmmac_xdp_is_enabled(priv);
if (need_update) {
+ netif_tx_disable(priv->dev);
napi_disable(&ch->rx_napi);
napi_disable(&ch->tx_napi);
stmmac_disable_rx_queue(priv, queue);
@@ -46,6 +47,7 @@ static int stmmac_xdp_enable_pool(struct stmmac_priv *priv,
stmmac_enable_rx_queue(priv, queue);
stmmac_enable_tx_queue(priv, queue);
napi_enable(&ch->rxtx_napi);
+ netif_tx_wake_all_queues(priv->dev);
err = stmmac_xsk_wakeup(priv->dev, queue, XDP_WAKEUP_RX);
if (err)
@@ -72,6 +74,7 @@ static int stmmac_xdp_disable_pool(struct stmmac_priv *priv, u16 queue)
need_update = netif_running(priv->dev) && stmmac_xdp_is_enabled(priv);
if (need_update) {
+ netif_tx_disable(priv->dev);
napi_disable(&ch->rxtx_napi);
stmmac_disable_rx_queue(priv, queue);
stmmac_disable_tx_queue(priv, queue);
@@ -87,6 +90,7 @@ static int stmmac_xdp_disable_pool(struct stmmac_priv *priv, u16 queue)
stmmac_enable_tx_queue(priv, queue);
napi_enable(&ch->rx_napi);
napi_enable(&ch->tx_napi);
+ netif_tx_wake_all_queues(priv->dev);
}
return 0;
@@ -121,8 +125,10 @@ int stmmac_xdp_set_prog(struct stmmac_priv *priv, struct bpf_prog *prog,
xdp_features_clear_redirect_target(dev);
need_update = !!priv->xdp_prog != !!prog;
- if (if_running && need_update)
+ if (if_running && need_update) {
+ netif_tx_disable(dev);
stmmac_xdp_release(dev);
+ }
old_prog = xchg(&priv->xdp_prog, prog);
if (old_prog)
@@ -131,8 +137,10 @@ int stmmac_xdp_set_prog(struct stmmac_priv *priv, struct bpf_prog *prog,
/* Disable RX SPH for XDP operation */
priv->sph_active = priv->sph_capable && !stmmac_xdp_is_enabled(priv);
- if (if_running && need_update)
+ if (if_running && need_update) {
stmmac_xdp_open(dev);
+ netif_tx_wake_all_queues(dev);
+ }
if (prog)
xdp_features_set_redirect_target(dev, false);
---
base-commit: 4aacf509e537a711fa71bca9f234e5eb6968850e
change-id: 20260604-main-f69f9564a74b
Best regards,
--
Carlos Fangmeier <carlos.fangmeier@gmail.com>
^ permalink raw reply related
* Re: [Linux-stm32] [PATCH v3 13/14] arm64: dts: st: support Engicam MicroGEA-STM32MP257-RMM board
From: Amelie Delaunay @ 2026-06-05 7:55 UTC (permalink / raw)
To: Dario Binacchi, linux-kernel
Cc: Rob Herring, Conor Dooley, devicetree, francesco.utel,
domenico.acri, Maxime Coquelin, Krzysztof Kozlowski, michael,
linux-amarula, linux-stm32, linux-arm-kernel
In-Reply-To: <20260605062900.368376-14-dario.binacchi@amarulasolutions.com>
Hi Dario,
On 6/5/26 08:27, Dario Binacchi wrote:
> Support for Engicam MicroGEA-STM32MP257-RMM board with:
>
> - 8 GB eMMC Flash
> - 2 GB LPDDR4 DRAM
> - CAN
> - LEDs
> - LCD panel with touchscreen
> - Micro SD card connector
> - Audio codec
> - Buzzer
>
> Signed-off-by: Dario Binacchi <dario.binacchi@amarulasolutions.com>
>
> ---
>
> (no changes since v2)
>
> Changes in v2:
> - Drop the clocks property from the sai1 node in stm32mp257-engicam-microgea-rmm.dts
> to avoid overriding the peripheral bus clock reference defined in the base
> SoC device tree. Suggested by Sashiko.
> - Reference the existing labeled nodes directly at the root level using
> &sai1a and &sai1b in stm32mp257-engicam-microgea-rmm.dts instead of
> redefining the entire node structure and redeclaring the labels. Suggested by Sashiko.
> - Drop the #clock-cells property from sai1a and remove the reference to sai1a from
> the clocks array in sai1b, relying strictly on the st,sync property to handle
> internal synchronization.
>
> arch/arm64/boot/dts/st/Makefile | 1 +
> .../st/stm32mp257-engicam-microgea-rmm.dts | 319 ++++++++++++++++++
> 2 files changed, 320 insertions(+)
> create mode 100644 arch/arm64/boot/dts/st/stm32mp257-engicam-microgea-rmm.dts
>
> diff --git a/arch/arm64/boot/dts/st/Makefile b/arch/arm64/boot/dts/st/Makefile
> index 63908113ae36..386eca593c54 100644
> --- a/arch/arm64/boot/dts/st/Makefile
> +++ b/arch/arm64/boot/dts/st/Makefile
> @@ -2,5 +2,6 @@
> dtb-$(CONFIG_ARCH_STM32) += \
> stm32mp215f-dk.dtb \
> stm32mp235f-dk.dtb \
> + stm32mp257-engicam-microgea-rmm.dtb \
> stm32mp257f-dk.dtb \
> stm32mp257f-ev1.dtb
> diff --git a/arch/arm64/boot/dts/st/stm32mp257-engicam-microgea-rmm.dts b/arch/arm64/boot/dts/st/stm32mp257-engicam-microgea-rmm.dts
> new file mode 100644
> index 000000000000..0212c03aae1a
> --- /dev/null
> +++ b/arch/arm64/boot/dts/st/stm32mp257-engicam-microgea-rmm.dts
> @@ -0,0 +1,319 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (C) 2026 Amarula Solutions, Dario Binacchi <dario.binacchi@amarulasolutions.com>
> + * Copyright (C) 2026 Engicam srl
> + */
> +
> +/dts-v1/;
> +
> +#include <dt-bindings/gpio/gpio.h>
> +#include <dt-bindings/input/input.h>
> +#include <dt-bindings/leds/common.h>
> +
> +#include "stm32mp257-engicam-microgea.dtsi"
> +
> +/ {
> + model = "Engicam MicroGEA STM32MP257D RMM Board";
If the SoC is an STM32MP257D, as mentionned in the board model,
stm32mp25xf.dtsi should not be included in
stm32mp257-engicam-microgea.dtsi (in PATCH 12).
Unless the SoM can be fitted with any STM32MP257, in which case, when
stm32mp25xf.dtsi is populated, you will need to add /delete-node/
statements on the board side, to remove the HW crypto support.
Regards,
Amelie
> + compatible = "engicam,microgea-stm32mp257-rmm",
> + "engicam,microgea-stm32mp257", "st,stm32mp257";
> +
> + aliases {
> + mmc0 = &sdmmc1;
> + mmc1 = &sdmmc2;
> + serial0 = &usart2;
> + serial1 = &usart1;
> + };
> +
> + backlight: backlight {
> + compatible = "pwm-backlight";
> + brightness-levels = <0 100>;
> + num-interpolated-steps = <100>;
> + default-brightness-level = <85>;
> + pwms = <&pwm2 0 100000 0>;
> + };
> +
> + buzzer {
> + compatible = "pwm-beeper";
> + pwms = <&pwm4 0 1000000 0>;
> + };
> +
> + chosen {
> + stdout-path = "serial0:115200n8";
> + #address-cells = <2>;
> + #size-cells = <2>;
> + ranges;
> +
> + framebuffer {
> + compatible = "simple-framebuffer";
> + clocks = <&rcc CK_BUS_LTDC>, <&rcc CK_KER_LTDC>;
> + lcd-supply = <®_3v3>;
> + status = "disabled";
> + };
> + };
> +
> + leds {
> + compatible = "gpio-leds";
> +
> + led-0 {
> + gpios = <&gpioh 2 GPIO_ACTIVE_HIGH>;
> + default-state = "off";
> + status = "okay";
> + };
> +
> + led-1 {
> + gpios = <&gpioh 6 GPIO_ACTIVE_HIGH>;
> + default-state = "off";
> + status = "okay";
> + };
> + };
> +
> + mclk: clock-mclk {
> + compatible = "fixed-clock";
> + #clock-cells = <0>;
> + clock-frequency = <24000000>;
> + };
> +
> + reg_1v8: regulator-1v8 {
> + compatible = "regulator-fixed";
> + regulator-name = "1v8";
> + regulator-min-microvolt = <1800000>;
> + regulator-max-microvolt = <1800000>;
> + };
> +
> + reg_3v3: regulator-3v3 {
> + compatible = "regulator-fixed";
> + regulator-name = "3v3";
> + regulator-min-microvolt = <3300000>;
> + regulator-max-microvolt = <3300000>;
> + };
> +
> + reg_ext_pwr: regulator-ext-pwr {
> + compatible = "regulator-fixed";
> + regulator-name = "ext-pwr";
> + regulator-min-microvolt = <5000000>;
> + regulator-max-microvolt = <5000000>;
> + gpio = <&gpiog 0 GPIO_ACTIVE_HIGH>;
> + enable-active-high;
> + regulator-always-on;
> + };
> +
> + sound {
> + compatible = "audio-graph-card";
> + label = "STM32MP25-RMM";
> + widgets = "Headphone", "Headphone Jack",
> + "Microphone", "Microphone Jack";
> + routing = "Headphone Jack", "HP_OUT",
> + "MIC_IN", "Microphone Jack",
> + "Microphone Jack", "Mic Bias";
> + dais = <&sai1a_port &sai1b_port>;
> + status = "okay";
> + };
> +};
> +
> +&arm_wdt {
> + timeout-sec = <32>;
> + status = "okay";
> +};
> +
> +&i2c1 {
> + pinctrl-names = "default", "sleep";
> + pinctrl-0 = <&i2c1_pins_a>;
> + pinctrl-1 = <&i2c1_sleep_pins_a>;
> + i2c-scl-rising-time-ns = <185>;
> + i2c-scl-falling-time-ns = <20>;
> + status = "okay";
> + /* spare dmas for other usage */
> + /delete-property/dmas;
> + /delete-property/dma-names;
> +
> + touchscreen@38 {
> + compatible = "edt,edt-ft5306";
> + reg = <0x38>;
> + interrupt-parent = <&gpiob>;
> + interrupts = <0 IRQ_TYPE_EDGE_FALLING>;
> + reset-gpios = <&gpiod 1 GPIO_ACTIVE_LOW>;
> + touchscreen-size-x = <1280>;
> + touchscreen-size-y = <800>;
> + };
> +};
> +
> +&i2c2 {
> + pinctrl-names = "default", "sleep";
> + pinctrl-0 = <&i2c2_pins_a>;
> + pinctrl-1 = <&i2c2_sleep_pins_a>;
> + i2c-scl-rising-time-ns = <185>;
> + i2c-scl-falling-time-ns = <20>;
> + status = "okay";
> + /* spare dmas for other usage */
> + /delete-property/dmas;
> + /delete-property/dma-names;
> +
> + sgtl5000: codec@a {
> + compatible = "fsl,sgtl5000";
> + reg = <0x0a>;
> + #sound-dai-cells = <0>;
> + clocks = <&mclk>;
> +
> + VDDA-supply = <®_3v3>;
> + VDDIO-supply = <®_3v3>;
> + VDDD-supply = <®_1v8>;
> +
> + sgtl5000_port: port {
> + #address-cells = <1>;
> + #size-cells = <0>;
> +
> + sgtl5000_tx_endpoint: endpoint@0 {
> + reg = <0>;
> + remote-endpoint = <&sai1a_endpoint>;
> + frame-master = <&sgtl5000_tx_endpoint>;
> + bitclock-master = <&sgtl5000_tx_endpoint>;
> + };
> +
> + sgtl5000_rx_endpoint: endpoint@1 {
> + reg = <1>;
> + remote-endpoint = <&sai1b_endpoint>;
> + frame-master = <&sgtl5000_rx_endpoint>;
> + bitclock-master = <&sgtl5000_rx_endpoint>;
> + };
> + };
> + };
> +};
> +
> +<dc {
> + pinctrl-names = "default", "sleep";
> + pinctrl-0 = <<dc_pins_a>;
> + pinctrl-1 = <<dc_sleep_pins_a>;
> + status = "okay";
> +
> + port {
> + ltdc_out: endpoint {
> + remote-endpoint = <&panel_in>;
> + };
> + };
> +};
> +
> +&m_can1 {
> + pinctrl-names = "default", "sleep";
> + pinctrl-0 = <&m_can1_pins_a>;
> + pinctrl-1 = <&m_can1_sleep_pins_a>;
> + status = "okay";
> +};
> +
> +&sai1 {
> + pinctrl-names = "default", "sleep";
> + pinctrl-0 = <&sai1a_pins_a>, <&sai1b_pins_a>;
> + pinctrl-1 = <&sai1a_sleep_pins_a>, <&sai1b_sleep_pins_a>;
> + status = "okay";
> +};
> +
> +&sai1a {
> + dma-names = "tx";
> + status = "okay";
> +
> + sai1a_port: port {
> + sai1a_endpoint: endpoint {
> + remote-endpoint = <&sgtl5000_tx_endpoint>;
> + dai-format = "i2s";
> + mclk-fs = <512>;
> + };
> + };
> +};
> +
> +&sai1b {
> + dma-names = "rx";
> + st,sync = <&sai1a 2>;
> + clocks = <&rcc CK_KER_SAI1>;
> + clock-names = "sai_ck";
> + status = "okay";
> +
> + sai1b_port: port {
> + sai1b_endpoint: endpoint {
> + remote-endpoint = <&sgtl5000_rx_endpoint>;
> + dai-format = "i2s";
> + mclk-fs = <512>;
> + };
> + };
> +};
> +
> +/* MicroSD */
> +&sdmmc1 {
> + pinctrl-names = "default", "opendrain", "sleep";
> + pinctrl-0 = <&sdmmc1_b4_pins_a>;
> + pinctrl-1 = <&sdmmc1_b4_od_pins_a>;
> + pinctrl-2 = <&sdmmc1_b4_sleep_pins_a>;
> + broken-cd;
> + disable-wp;
> + st,neg-edge;
> + bus-width = <4>;
> + vmmc-supply = <&scmi_v3v3>;
> + vqmmc-supply = <&scmi_vddio1>;
> + no-1-8-v;
> + status = "okay";
> +};
> +
> +&spi1 {
> + pinctrl-names = "default", "sleep";
> + pinctrl-0 = <&spi1_pins_a>;
> + pinctrl-1 = <&spi1_sleep_pins_a>;
> + #address-cells = <1>;
> + #size-cells = <0>;
> + cs-gpios = <&gpioh 8 GPIO_ACTIVE_HIGH>, <&gpioh 3 GPIO_ACTIVE_HIGH>;
> + status = "okay";
> +
> + display: display@0 {
> + compatible = "rocktech,rk050hr345-ct106a", "ilitek,ili9806e";
> + reg = <0>;
> + vdd-supply = <®_3v3>;
> + spi-max-frequency = <10000000>;
> + reset-gpios = <&gpiob 6 GPIO_ACTIVE_LOW>;
> + backlight = <&backlight>;
> +
> + port {
> + panel_in: endpoint {
> + remote-endpoint = <<dc_out>;
> + };
> + };
> + };
> +};
> +
> +&timers2 {
> + status = "okay";
> +
> + pwm2: pwm {
> + pinctrl-0 = <&pwm2_pins_a>;
> + pinctrl-1 = <&pwm2_sleep_pins_a>;
> + pinctrl-names = "default", "sleep";
> + status = "okay";
> + };
> +};
> +
> +&timers4 {
> + status = "okay";
> +
> + pwm4: pwm {
> + pinctrl-names = "default", "sleep";
> + pinctrl-0 = <&pwm4_pins_a>;
> + pinctrl-1 = <&pwm4_sleep_pins_a>;
> + status = "okay";
> + };
> +};
> +
> +&usart1 {
> + pinctrl-names = "default", "idle", "sleep";
> + pinctrl-0 = <&usart1_pins_b>;
> + pinctrl-1 = <&usart1_idle_pins_b>;
> + pinctrl-2 = <&usart1_sleep_pins_b>;
> + /delete-property/ dmas;
> + /delete-property/ dma-names;
> + status = "okay";
> +};
> +
> +&usart2 {
> + pinctrl-names = "default", "idle", "sleep";
> + pinctrl-0 = <&usart2_pins_a>;
> + pinctrl-1 = <&usart2_idle_pins_a>;
> + pinctrl-2 = <&usart2_sleep_pins_a>;
> + /delete-property/ dmas;
> + /delete-property/ dma-names;
> + status = "okay";
> +};
^ permalink raw reply
* Re: [PATCH v01] mailbox/pcc.c: add query channel function
From: Sudeep Holla @ 2026-06-05 7:55 UTC (permalink / raw)
To: Adam Young
Cc: Jassi Brar, Rafael J. Wysocki, Saket Dumbre, Len Brown,
Sudeep Holla, linux-kernel, linux-hwmon, linux-acpi, Andi Shyti,
Guenter Roeck, Huisong Li, MyungJoo Ham, Kyungmin Park,
Chanwoo Choi, linux-arm-kernel
In-Reply-To: <20260604203749.168752-1-admiyo@os.amperecomputing.com>
On Thu, Jun 04, 2026 at 04:37:48PM -0400, Adam Young wrote:
> Drivers need information about a channel prior to creating a channel
> or they risk triggering message delivery on the remote side of a
> connection.
>
> One of those pieces of infomration is the type of channel.
>
> Add PCC channel type to records and expose PCC channel type to client.
>
Please point me to the user of this interface.
--
Regards,
Sudeep
^ permalink raw reply
* Re: [PATCH] KVM: arm64: Reallocate the nested_mmus array under the mmu_lock
From: Marc Zyngier @ 2026-06-05 7:51 UTC (permalink / raw)
To: Hyunwoo Kim
Cc: Oliver Upton, joey.gouly, seiden, suzuki.poulose, yuzenghui,
catalin.marinas, will, christoffer.dall, linux-arm-kernel, kvmarm
In-Reply-To: <aiJgGBv3OCPNJJPc@v4bel>
On Fri, 05 Jun 2026 06:35:20 +0100,
Hyunwoo Kim <imv4bel@gmail.com> wrote:
>
> On Thu, Jun 04, 2026 at 03:27:16PM -0700, Oliver Upton wrote:
> > Hi,
> >
> > The shortlog is very confusing, since "allocate behind $LOCK" is usually
> > something alarming. Maybe instead:
> >
> > KVM: arm64: Reassign nested_mmus array behind mmu_lock
>
> heh, that's confusing indeed. I'll change it that way.
>
> >
> > On Fri, Jun 05, 2026 at 03:30:00AM +0900, Hyunwoo Kim wrote:
> > > Code that walks kvm->arch.nested_mmus[] holds kvm->mmu_lock. By contrast,
> > > kvm_vcpu_init_nested() reallocates the array and frees the old buffer while
> > > holding only kvm->arch.config_lock, so a walker can reference the freed
> > > array.
> >
> > It wouldn't hurt to share slightly more information here. Are you
> > dealing with a concurrent MMU notifier?
>
> Yes. The MMU notifier path also walks nested_mmus[] under mmu_lock.
> kvm_vcpu_init_nested() holds only config_lock, so if a notifier fires
> during vCPU init, it races with the array realloc and free.
>
> Here's the reworked changelog. Should I send v2?
>
> kvm->arch.nested_mmus[] is walked under kvm->mmu_lock, including from the
> MMU notifier path (kvm_unmap_gfn_range() -> kvm_nested_s2_unmap()), which
> can run at any time. kvm_vcpu_init_nested() reallocates the array and frees
> the old buffer while holding only kvm->arch.config_lock, so such a walker
> can reference the freed array.
>
> Allocate the new array outside of mmu_lock, as the allocation can sleep.
> Under the lock, copy the existing entries, fix up the back pointers and
> reassign the array. Free the old buffer after dropping the lock, as
> kvfree() can sleep as well.
That's significantly better. Please send a v2 with this.
Thanks,
M.
--
Jazz isn't dead. It just smells funny.
^ permalink raw reply
* Re: [PATCH v2 4/5] clk: cix: add sky1 audss clock controller
From: Philipp Zabel @ 2026-06-05 7:42 UTC (permalink / raw)
To: joakim.zhang, mturquette, sboyd, bmasney, robh, krzk+dt, conor+dt,
gary.yang
Cc: cix-kernel-upstream, linux-clk, devicetree, linux-kernel,
linux-arm-kernel
In-Reply-To: <20260605032225.523669-5-joakim.zhang@cixtech.com>
On Fr, 2026-06-05 at 11:22 +0800, joakim.zhang@cixtech.com wrote:
> From: Joakim Zhang <joakim.zhang@cixtech.com>
>
> Add a platform driver for the Cix Sky1 Audio Subsystem (AUDSS) internal
> clock controller. The driver binds to a cix,sky1-audss-clock device tree
> node under the AUDSS syscon, obtains the parent regmap via
> syscon_node_to_regmap(), and registers mux/divider/gate composite clocks
> for DSP, SRAM, HDA, DMAC, watchdog, timer, mailbox and I2S outputs. Six
> SoC-level audio reference clocks are brought up as inputs to the tree.
>
> Signed-off-by: Joakim Zhang <joakim.zhang@cixtech.com>
> ---
> drivers/clk/Kconfig | 1 +
> drivers/clk/Makefile | 1 +
> drivers/clk/cix/Kconfig | 16 +
> drivers/clk/cix/Makefile | 3 +
> drivers/clk/cix/clk-sky1-audss.c | 1129 ++++++++++++++++++++++++++++++
> 5 files changed, 1150 insertions(+)
> create mode 100644 drivers/clk/cix/Kconfig
> create mode 100644 drivers/clk/cix/Makefile
> create mode 100644 drivers/clk/cix/clk-sky1-audss.c
>
[...]
> diff --git a/drivers/clk/cix/clk-sky1-audss.c b/drivers/clk/cix/clk-sky1-audss.c
> new file mode 100644
> index 000000000000..899452d5ed14
> --- /dev/null
> +++ b/drivers/clk/cix/clk-sky1-audss.c
> @@ -0,0 +1,1129 @@
[...]
> +/* register sky1 audio subsystem clocks */
> +static int sky1_audss_clk_probe(struct platform_device *pdev)
> +{
> + const struct sky1_audss_clks_devtype_data *devtype_data;
> + struct sky1_audss_clks_priv *priv;
> + struct device_node *parent_np;
> + struct device *dev = &pdev->dev;
> + struct reset_control *rst_noc;
> + struct clk_hw **clk_table;
> + struct regmap *regmap_cru;
> + int i, ret;
> +
> + parent_np = of_get_parent(pdev->dev.of_node);
> + regmap_cru = syscon_node_to_regmap(parent_np);
> + of_node_put(parent_np);
> + if (IS_ERR(regmap_cru))
> + return dev_err_probe(dev, PTR_ERR(regmap_cru),
> + "unable to get audss cru regmap");
> +
> + devtype_data = device_get_match_data(dev);
> + if (!devtype_data)
> + return -ENODEV;
> +
> + priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
> + if (!priv)
> + return -ENOMEM;
> +
> + spin_lock_init(&priv->lock);
> +
> + priv->clk_data = devm_kzalloc(&pdev->dev,
> + struct_size(priv->clk_data, hws, AUDSS_MAX_CLKS),
> + GFP_KERNEL);
> + if (!priv->clk_data)
> + return -ENOMEM;
> +
> + priv->clk_data->num = AUDSS_MAX_CLKS;
> + clk_table = priv->clk_data->hws;
> +
> + priv->dev = dev;
> + priv->regmap_cru = regmap_cru;
> + priv->devtype_data = devtype_data;
> +
> + ret = sky1_audss_clks_get(priv);
> + if (ret)
> + return ret;
> +
> + rst_noc = devm_reset_control_get(dev, NULL);
Please use devm_reset_control_get_exclusive() directly.
[...]
> +static int __maybe_unused sky1_audss_clk_runtime_suspend(struct device *dev)
> +{
> + struct sky1_audss_clks_priv *priv = dev_get_drvdata(dev);
> + const struct sky1_audss_clks_devtype_data *devtype_data = priv->devtype_data;
> + unsigned long flags;
> + int i;
> +
> + spin_lock_irqsave(&priv->lock, flags);
> + for (i = 0; i < devtype_data->reg_save_size; i++)
> + regmap_read(priv->regmap_cru,
> + devtype_data->reg_save[i][0], &devtype_data->reg_save[i][1]);
> + spin_unlock_irqrestore(&priv->lock, flags);
> +
> + sky1_audss_clks_disable(priv);
> +
> + return 0;
> +}
> +
> +static int __maybe_unused sky1_audss_clk_runtime_resume(struct device *dev)
> +{
> + struct sky1_audss_clks_priv *priv = dev_get_drvdata(dev);
> + const struct sky1_audss_clks_devtype_data *devtype_data = priv->devtype_data;
> + unsigned long flags;
> + int i, ret;
> +
> + ret = sky1_audss_clks_enable(priv);
> + if (ret) {
> + dev_err(dev, "failed to enable clocks\n");
> + return ret;
> + }
> +
> + reset_control_deassert(priv->rst_noc);
Deasserted on resume but not asserted on suspend, is this on purpose?
regards
Philipp
^ permalink raw reply
* Re: [PATCH] KVM: arm64: vgic: Check the interrupt is still ours before migrating it
From: Marc Zyngier @ 2026-06-05 7:42 UTC (permalink / raw)
To: Oliver Upton
Cc: Hyunwoo Kim, joey.gouly, seiden, suzuki.poulose, yuzenghui,
catalin.marinas, will, Sascha.Bischoff, jic23, timothy.hayes,
eric.auger, christoffer.dall, andre.przywara, linux-arm-kernel,
kvmarm
In-Reply-To: <aiJmBfXAxcytfGha@kernel.org>
On Fri, 05 Jun 2026 07:00:37 +0100,
Oliver Upton <oupton@kernel.org> wrote:
>
> On Fri, Jun 05, 2026 at 05:59:15AM +0900, Hyunwoo Kim wrote:
> > vgic_prune_ap_list() drops both ap_list_lock and irq_lock while migrating
> > an interrupt to another vCPU. After reacquiring the locks it only checks
> > that the affinity is unchanged (target_vcpu == vgic_target_oracle(irq))
> > before moving the interrupt, which assumes that an interrupt whose affinity
> > is preserved is still queued on this vCPU's ap_list.
> >
> > That assumption no longer holds if the interrupt is taken off the ap_list
> > while the locks are dropped. vgic_flush_pending_lpis() removes the
> > interrupt from the list and sets irq->vcpu to NULL, but leaves
> > enabled/pending/target_vcpu untouched. As the interrupt is still enabled
> > and pending, vgic_target_oracle() returns the same target_vcpu, so the
> > affinity check passes and list_del() is run a second time on an entry that
> > has already been removed.
> >
> > Also check that the interrupt is still assigned to this vCPU
> > (irq->vcpu == vcpu) before moving it.
> >
> > Fixes: 0919e84c0fc1 ("KVM: arm/arm64: vgic-new: Add IRQ sync/flush framework")
> > Signed-off-by: Hyunwoo Kim <imv4bel@gmail.com>
>
> Looking at this and the other VGIC patch you sent (which should've been
> a combined series), are you trying to deal with a vCPU writing to
> another vCPU's redistributor? I.e. vCPU B setting GICR_CTLR.EnableLPIs=0
> behind the back of vCPU A?
>
> That is extremely relevant information as the off-the-cuff reaction is
> that no race exists. But since the GIC architecture is awesome and
> allows for this sort of insanity, it obviously does....
>
> Anyway, for LPIs resident on a particular RD, there's zero expectation
> that the pending state is preserved when EnableLPIs=0. So I'd rather
> vgic_flush_pending_lpis() just invalidate the pending state.
Just clearing the pending state introduces a potential problem as we
now have an interrupt that is neither active nor pending on the AP
list. It is not impossible to solve (we now have similar behaviours
with SPI deactivation from another vcpu), but that requires posting a
KVM_REQ_VGIC_PROCESS_UPDATE to the target vcpu.
> Beyond that, I see two other fixes for lifetime issues around the
> vgic_irq in the middle of migration. I'd like to see explicit RCU
> protection around the release && reacquire of the ap_list_lock rather
> than depending on the precondition that IRQs are disabled.
I'm not sure I follow. Are you suggesting turning the AP list into an
RCU protected list?
Thanks,
M.
--
Jazz isn't dead. It just smells funny.
^ permalink raw reply
* Re: [PATCH v14 0/8] arm64: add ARCH_HAS_COPY_MC support
From: Ruidong Tian @ 2026-06-05 7:33 UTC (permalink / raw)
To: Kefeng Wang, catalin.marinas, will, rafael, tony.luck, guohanjun,
mchehab, xueshuai, tongtiangen, james.morse, robin.murphy,
andreyknvl, dvyukov, vincenzo.frascino, mpe, npiggin,
ryabinin.a.a, glider, christophe.leroy, aneesh.kumar,
naveen.n.rao, tglx, mingo
Cc: linux-arm-kernel, linux-mm, linuxppc-dev, linux-kernel, kasan-dev
In-Reply-To: <f115ceaa-4573-41c0-8c8d-5f4fb1b017f2@huawei.com>
在 2026/5/18 23:05, Kefeng Wang 写道:
>
>
> On 5/18/2026 4:49 PM, Ruidong Tian wrote:
>> This series continues Tong Tiangen's work on arm64 ARCH_HAS_COPY_MC
>> support. We encounter the same problem, and from a forward-looking
>> perspective, large-memory ARM machines such as Grace and Vera will suffer
>> more from this class of issues, which motivates us to push this feature
>> upstream.
>>
>> Problem
>> =========
>> With the increase of memory capacity and density, the probability of
>> memory
>> error also increases. The increasing size and density of server RAM in
>> data
>> centers and clouds have shown increased uncorrectable memory errors.
>>
>> Currently, more and more scenarios that can tolerate memory errors,
>> such as
>> COW[1,2], KSM copy[3], coredump copy[4], khugepaged[5,6], uaccess
>> copy[7],
>> etc.
>
> We have encountered more scenarios and have made more enhancements, eg,
>
> 658be46520ce mm: support poison recovery from copy_present_page()
> aa549f923f5e mm: support poison recovery from do_cow_fault()
> f00b295b9b61 fs: hugetlbfs: support poisoned recover from
> hugetlbfs_migrate_folio()
> 060913999d7a mm: migrate: support poisoned recover from migrate folio
>
> Hope that the architecture-related sections can receive relevant reviews
> and responses.
>
> Thanks.
Thanks for the additional examples and for bringing up these scenarios.
Ruidong.> > Solution
>> =========
>>
>> This patchset introduces a new processing framework on ARM64, which
>> enables
>> ARM64 to support error recovery in the above scenarios, and more
>> scenarios
>> can be expanded based on this in the future.
>>
>> In arm64, memory error handling in do_sea(), which is divided into two
>> cases:
>> 1. If the user state consumed the memory errors, the solution is to
>> kill
>> the user process and isolate the error page.
>> 2. If the kernel state consumed the memory errors, the solution is to
>> panic.
>>
>> For case 2, Undifferentiated panic may not be the optimal choice, as
>> it can
>> be handled better. In some scenarios, we can avoid panic, such as
>> uaccess,
>> if the uaccess fails due to memory error, only the user process will be
>> affected, returning an error to the caller and isolating the user page
>> with
>> hardware memory errors is a better choice.
>>
>> [1] commit d302c2398ba2 ("mm, hwpoison: when copy-on-write hits
>> poison, take page offline")
>> [2] commit 1cb9dc4b475c ("mm: hwpoison: support recovery from HugePage
>> copy-on-write faults")
>> [3] commit 6b970599e807 ("mm: hwpoison: support recovery from
>> ksm_might_need_to_copy()")
>> [4] commit 245f09226893 ("mm: hwpoison: coredump: support recovery
>> from dump_user_range()")
>> [5] commit 98c76c9f1ef7 ("mm/khugepaged: recover from poisoned
>> anonymous memory")
>> [6] commit 12904d953364 ("mm/khugepaged: recover from poisoned file-
>> backed memory")
>> [7] commit 278b917f8cb9 ("x86/mce: Add _ASM_EXTABLE_CPY for copy user
>> access")
>>
>> ------------------
>> Test result:
>>
>> Tested on Kunpeng 920.
>>
>> 1. copy_page(), copy_mc_page() basic function test pass, and the
>> disassembly
>> contents remains the same before and after refactor.
>>
>> 2. copy_to/from_user() access kernel NULL pointer raise translation fault
>> and dump error message then die(), test pass.
>>
>> 3. Test following scenarios: copy_from_user(), get_user(), COW.
>>
>> Before patched: trigger a hardware memory error then panic.
>> After patched: trigger a hardware memory error without panic.
>>
>> Testing step:
>> step1. start an user-process.
>> step2. poison(einj) the user-process's page.
>> step3: user-process access the poison page in kernel mode, then
>> trigger SEA.
>> step4: the kernel will not panic, only the user process is killed,
>> the poison
>> page is isolated. (before patched, the kernel will panic in
>> do_sea())
>>
>> The above tests can also be reproduced using ras-tools, which
>> provides
>> einj-based injection and validation for uaccess and COW scenarios.
>> Example usage:
>>
>> einj_mem_uc futex # get_user
>> einj_mem_uc copyin # copy_to_user
>> einj_mem_uc copy-on-write # COW
>>
>> Link: https://git.kernel.org/pub/scm/linux/kernel/git/aegl/ras-
>> tools.git
>>
>> ------------------
>>
>> Benefits
>> =========
>> According to Huawei's statistics from their storage products, memory
>> errors
>> triggered in kernel-mode by COW and page cache read (uaccess) scenarios
>> account for more than 50%. With this patchset deployed, all kernel panics
>> caused by COW and page cache memory errors are eliminated.
>> Alibaba Cloud has also observed memory errors occurring in uaccess
>> contexts.
>>
>> Since V13:
>> 1. Changed MC-safe functions to return an error rather than kill the user
>> process. When a user program invokes a syscall and the kernel
>> encounters
>> a memory error during uaccess, killing the process is unexpected; the
>> syscall should return an error.
>> 2. Added FEAT_MOPS support for the copy_page_mc paths.
>> 3. Refactored copy_page() and memcpy() on top of the shared
>> memcpy_template,
>> reducing duplicated assembly code.
>>
>> Since v12:
>> Thanks to the suggestions of Jonathan, Mark, and Mauro, the following
>> modifications
>> are made:
>> 1. Rebase to latest kernel version.
>> 2. Patch1, add Jonathan's and Mauro's review-by.
>> 3. Patch2, modified do_apei_claim_sea() according to Mark's and
>> Jonathan's suggestions,
>> and optimized the commit message according to Mark's
>> suggestions(Added description of
>> the impact on regular copy_to_user()).
>> 4. Patch3, optimized the commit message according to Mauro's
>> suggestions and add Jonathan's
>> review-by.
>> 5. Patch4, modified copy_mc_user_highpage() and Optimized the commit
>> message according to
>> Jonathan's suggestions(no functional changes).
>> 6. Patch5, optimized the commit message according to Mauro's suggestions.
>> 7. Patch4/5, FEAT_MOPS is added to the code logic. Currently, the
>> fixup is not performed
>> on the MOPS instruction.
>> 8. Remove patch6 in v12 according to Jonathan's suggestions.
>>
>> Since v11:
>> 1. Rebase to latest kernel version 6.9-rc1.
>> 2. Add patch 5, Since the problem described in "Since V10 Besides 3" has
>> been solved in a50026bdb867 ('iov_iter: get rid of 'copy_mc' flag').
>> 3. Add the benefit of applying the patch set to our company to the
>> description of patch0.
>>
>> Since V10:
>> Accroding Mark's suggestion:
>> 1. Merge V10's patch2 and patch3 to V11's patch2.
>> 2. Patch2(V11): use new fixup_type for ld* in copy_to_user(), fix fatal
>> issues (NULL kernel pointeraccess) been fixup incorrectly.
>> 3. Patch2(V11): refactoring the logic of do_sea().
>> 4. Patch4(V11): Remove duplicate assembly logic and remove do_mte().
>>
>> Besides:
>> 1. Patch2(V11): remove st* insn's fixup, st* generally not trigger
>> memory error.
>> 2. Split a part of the logic of patch2(V11) to patch5(V11), for detail,
>> see patch5(V11)'s commit msg.
>> 3. Remove patch6(v10) “arm64: introduce copy_mc_to_kernel()
>> implementation”.
>> During modification, some problems that cannot be solved in a short
>> period are found. The patch will be released after the problems are
>> solved.
>> 4. Add test result in this patch.
>> 5. Modify patchset title, do not use machine check and remove "-next".
>>
>> Since V9:
>> 1. Rebase to latest kernel version 6.8-rc2.
>> 2. Add patch 6/6 to support copy_mc_to_kernel().
>>
>> Since V8:
>> 1. Rebase to latest kernel version and fix topo in some of the patches.
>> 2. According to the suggestion of Catalin, I attempted to modify the
>> return value of function copy_mc_[user]_highpage() to bytes not
>> copied.
>> During the modification process, I found that it would be more
>> reasonable to return -EFAULT when copy error occurs (referring to
>> the
>> newly added patch 4).
>>
>> For ARM64, the implementation of copy_mc_[user]_highpage() needs to
>> consider MTE. Considering the scenario where data copying is
>> successful
>> but the MTE tag copying fails, it is also not reasonable to return
>> bytes not copied.
>> 3. Considering the recent addition of machine check safe support for
>> multiple scenarios, modify commit message for patch 5 (patch 4
>> for V8).
>>
>> Since V7:
>> Currently, there are patches supporting recover from poison
>> consumption for the cow scenario[1]. Therefore, Supporting cow
>> scenario under the arm64 architecture only needs to modify the relevant
>> code under the arch/.
>> [1]https://lore.kernel.org/lkml/20221031201029.102123-1-
>> tony.luck@intel.com/
>>
>> Since V6:
>> Resend patches that are not merged into the mainline in V6.
>>
>> Since V5:
>> 1. Add patch2/3 to add uaccess assembly helpers.
>> 2. Optimize the implementation logic of arm64_do_kernel_sea() in
>> patch8.
>> 3. Remove kernel access fixup in patch9.
>> All suggestion are from Mark.
>>
>> Since V4:
>> 1. According Michael's suggestion, add patch5.
>> 2. According Mark's suggestiog, do some restructuring to arm64
>> extable, then a new adaptation of machine check safe support is made
>> based
>> on this.
>> 3. According Mark's suggestion, support machine check safe in
>> do_mte() in
>> cow scene.
>> 4. In V4, two patches have been merged into -next, so V5 not send these
>> two patches.
>>
>> Since V3:
>> 1. According to Robin's suggestion, direct modify user_ldst and
>> user_ldp in asm-uaccess.h and modify mte.S.
>> 2. Add new macro USER_MC in asm-uaccess.h, used in copy_from_user.S
>> and copy_to_user.S.
>> 3. According to Robin's suggestion, using micro in copy_page_mc.S to
>> simplify code.
>> 4. According to KeFeng's suggestion, modify powerpc code in patch1.
>> 5. According to KeFeng's suggestion, modify mm/extable.c and some code
>> optimization.
>>
>> Since V2:
>> 1. According to Mark's suggestion, all uaccess can be recovered due to
>> memory error.
>> 2. Scenario pagecache reading is also supported as part of uaccess
>> (copy_to_user()) and duplication code problem is also solved.
>> Thanks for Robin's suggestion.
>> 3. According Mark's suggestion, update commit message of patch 2/5.
>> 4. According Borisllav's suggestion, update commit message of patch
>> 1/5.
>>
>> Since V1:
>> 1.Consistent with PPC/x86, Using CONFIG_ARCH_HAS_COPY_MC instead of
>> ARM64_UCE_KERNEL_RECOVERY.
>> 2.Add two new scenes, cow and pagecache reading.
>> 3.Fix two small bug(the first two patch).
>>
>> V1 in here:
>> https://lore.kernel.org/lkml/20220323033705.3966643-1-
>> tongtiangen@huawei.com/
>>
>> Ruidong Tian (3):
>> ACPI: APEI: GHES: use exception context to gate SIGBUS on poison
>> consumption
>> lib/test: memcpy_kunit: add copy_page() and copy_mc_page() tests
>> lib/tests: memcpy_kunit: add memcpy_mc() and memcpy_mc_large() test
>>
>> Tong Tiangen (5):
>> uaccess: add generic fallback version of copy_mc_to_user()
>> arm64: add support for ARCH_HAS_COPY_MC
>> mm/hwpoison: return -EFAULT when copy fail in
>> copy_mc_[user]_highpage()
>> arm64: support copy_mc_[user]_highpage()
>> arm64: introduce copy_mc_to_kernel() implementation
>>
>> arch/arm64/Kconfig | 1 +
>> arch/arm64/include/asm/asm-extable.h | 22 ++-
>> arch/arm64/include/asm/asm-uaccess.h | 4 +
>> arch/arm64/include/asm/extable.h | 1 +
>> arch/arm64/include/asm/mte.h | 9 +
>> arch/arm64/include/asm/page.h | 10 ++
>> arch/arm64/include/asm/string.h | 5 +
>> arch/arm64/include/asm/uaccess.h | 17 ++
>> arch/arm64/kernel/acpi.c | 2 +-
>> arch/arm64/lib/Makefile | 2 +
>> arch/arm64/lib/copy_mc_page.S | 44 +++++
>> arch/arm64/lib/copy_page.S | 62 +------
>> arch/arm64/lib/copy_page_template.S | 71 ++++++++
>> arch/arm64/lib/copy_to_user.S | 10 +-
>> arch/arm64/lib/memcpy.S | 253 ++-------------------------
>> arch/arm64/lib/memcpy_mc.S | 56 ++++++
>> arch/arm64/lib/memcpy_template.S | 249 ++++++++++++++++++++++++++
>> arch/arm64/lib/mte.S | 29 +++
>> arch/arm64/mm/copypage.c | 75 ++++++++
>> arch/arm64/mm/extable.c | 21 +++
>> arch/arm64/mm/fault.c | 30 +++-
>> arch/powerpc/include/asm/uaccess.h | 1 +
>> arch/x86/include/asm/uaccess.h | 1 +
>> drivers/acpi/apei/ghes.c | 36 ++--
>> include/acpi/ghes.h | 6 +-
>> include/linux/highmem.h | 16 +-
>> include/linux/uaccess.h | 8 +
>> lib/tests/memcpy_kunit.c | 178 ++++++++++++++++++-
>> mm/kasan/shadow.c | 12 ++
>> mm/khugepaged.c | 4 +-
>> 30 files changed, 904 insertions(+), 331 deletions(-)
>> create mode 100644 arch/arm64/lib/copy_mc_page.S
>> create mode 100644 arch/arm64/lib/copy_page_template.S
>> create mode 100644 arch/arm64/lib/memcpy_mc.S
>> create mode 100644 arch/arm64/lib/memcpy_template.S
>>
^ permalink raw reply
* Re: [PATCH v14 29/44] arm64: RMI: Runtime faulting of memory
From: Lorenzo Pieralisi @ 2026-06-05 7:28 UTC (permalink / raw)
To: Gavin Shan
Cc: Steven Price, kvm, kvmarm, Catalin Marinas, Marc Zyngier,
Will Deacon, James Morse, Oliver Upton, Suzuki K Poulose,
Zenghui Yu, linux-arm-kernel, linux-kernel, Joey Gouly,
Alexandru Elisei, Christoffer Dall, Fuad Tabba, linux-coco,
Ganapatrao Kulkarni, Shanker Donthineni, Alper Gun,
Aneesh Kumar K . V, Emi Kisanuki, Vishal Annapurve, WeiLin.Chang,
Lorenzo.Pieralisi2
In-Reply-To: <3359f788-07fa-41a1-9ac7-45c58577c1fa@redhat.com>
On Fri, Jun 05, 2026 at 04:23:15PM +1000, Gavin Shan wrote:
[...]
> > +static int realm_map_ipa(struct kvm *kvm, phys_addr_t ipa,
> > + kvm_pfn_t pfn, unsigned long map_size,
> > + enum kvm_pgtable_prot prot,
> > + struct kvm_mmu_memory_cache *memcache)
> > +{
> > + struct realm *realm = &kvm->arch.realm;
> > +
> > + /*
> > + * Write permission is required for now even though it's possible to
> > + * map unprotected pages (granules) as read-only. It's impossible to
> > + * map protected pages (granules) as read-only.
> > + */
> > + if (WARN_ON(!(prot & KVM_PGTABLE_PROT_W)))
> > + return -EFAULT;
> > +
>
> I'm a bit concerned with this. We don't have KVM_PGTABLE_PROT_W set in @prot
> if the stage2 fault is raised due to memory read. With -EFAULT returned to VMM
> (e.g. QEMU), the vCPU continuous execution is stopped and system won't be
> working any more.
>
> > + ipa = ALIGN_DOWN(ipa, PAGE_SIZE);
> > + if (!kvm_realm_is_private_address(realm, ipa))
> > + return realm_map_non_secure(realm, ipa, pfn, map_size, prot,
> > + memcache);
> > +
> > + return realm_map_protected(kvm, ipa, pfn, map_size, memcache);
> > +}
> > +
> > static bool kvm_vma_is_cacheable(struct vm_area_struct *vma)
> > {
> > switch (FIELD_GET(PTE_ATTRINDX_MASK, pgprot_val(vma->vm_page_prot))) {
> > @@ -1604,27 +1641,52 @@ static int gmem_abort(const struct kvm_s2_fault_desc *s2fd)
> > bool write_fault, exec_fault;
> > enum kvm_pgtable_walk_flags flags = KVM_PGTABLE_WALK_SHARED;
> > enum kvm_pgtable_prot prot = KVM_PGTABLE_PROT_R;
> > - struct kvm_pgtable *pgt = s2fd->vcpu->arch.hw_mmu->pgt;
> > + struct kvm_vcpu *vcpu = s2fd->vcpu;
> > + struct kvm_pgtable *pgt = vcpu->arch.hw_mmu->pgt;
> > + gpa_t gpa = kvm_gpa_from_fault(vcpu->kvm, s2fd->fault_ipa);
> > unsigned long mmu_seq;
> > struct page *page;
> > - struct kvm *kvm = s2fd->vcpu->kvm;
> > + struct kvm *kvm = vcpu->kvm;
> > void *memcache;
> > kvm_pfn_t pfn;
> > gfn_t gfn;
> > int ret;
> > - memcache = get_mmu_memcache(s2fd->vcpu);
> > - ret = topup_mmu_memcache(s2fd->vcpu, memcache);
> > + if (kvm_is_realm(vcpu->kvm)) {
> > + /* check for memory attribute mismatch */
> > + bool is_priv_gfn = kvm_mem_is_private(kvm, gpa >> PAGE_SHIFT);
> > + /*
> > + * For Realms, the shared address is an alias of the private
> > + * PA with the top bit set. Thus if the fault address matches
> > + * the GPA then it is the private alias.
> > + */
> > + bool is_priv_fault = (gpa == s2fd->fault_ipa);
> > +
> > + if (is_priv_gfn != is_priv_fault) {
> > + kvm_prepare_memory_fault_exit(vcpu, gpa, PAGE_SIZE,
> > + kvm_is_write_fault(vcpu),
> > + false,
> > + is_priv_fault);
> > + /*
> > + * KVM_EXIT_MEMORY_FAULT requires an return code of
> > + * -EFAULT, see the API documentation
> > + */
> > + return -EFAULT;
> > + }
> > + }
> > +
> > + memcache = get_mmu_memcache(vcpu);
> > + ret = topup_mmu_memcache(vcpu, memcache);
> > if (ret)
> > return ret;
> > if (s2fd->nested)
> > gfn = kvm_s2_trans_output(s2fd->nested) >> PAGE_SHIFT;
> > else
> > - gfn = s2fd->fault_ipa >> PAGE_SHIFT;
> > + gfn = gpa >> PAGE_SHIFT;
> > - write_fault = kvm_is_write_fault(s2fd->vcpu);
> > - exec_fault = kvm_vcpu_trap_is_exec_fault(s2fd->vcpu);
> > + write_fault = kvm_is_write_fault(vcpu);
> > + exec_fault = kvm_vcpu_trap_is_exec_fault(vcpu);
> > VM_WARN_ON_ONCE(write_fault && exec_fault);
> > @@ -1634,7 +1696,7 @@ static int gmem_abort(const struct kvm_s2_fault_desc *s2fd)
> > ret = kvm_gmem_get_pfn(kvm, s2fd->memslot, gfn, &pfn, &page, NULL);
> > if (ret) {
> > - kvm_prepare_memory_fault_exit(s2fd->vcpu, s2fd->fault_ipa, PAGE_SIZE,
> > + kvm_prepare_memory_fault_exit(vcpu, gpa, PAGE_SIZE,
> > write_fault, exec_fault, false);
> > return ret;
> > }
> > @@ -1654,14 +1716,20 @@ static int gmem_abort(const struct kvm_s2_fault_desc *s2fd)
> > kvm_fault_lock(kvm);
> > if (mmu_invalidate_retry(kvm, mmu_seq)) {
> > ret = -EAGAIN;
> > - goto out_unlock;
> > + goto out_release_page;
> > + }
> > +
> > + if (kvm_is_realm(kvm)) {
> > + ret = realm_map_ipa(kvm, s2fd->fault_ipa, pfn,
> > + PAGE_SIZE, KVM_PGTABLE_PROT_R | KVM_PGTABLE_PROT_W, memcache);
> > + goto out_release_page;
> > }
> > ret = KVM_PGT_FN(kvm_pgtable_stage2_map)(pgt, s2fd->fault_ipa, PAGE_SIZE,
> > __pfn_to_phys(pfn), prot,
> > memcache, flags);
> > -out_unlock:
> > +out_release_page:
> > kvm_release_faultin_page(kvm, page, !!ret, prot & KVM_PGTABLE_PROT_W);
> > kvm_fault_unlock(kvm);
> > @@ -1847,7 +1915,7 @@ static int kvm_s2_fault_get_vma_info(const struct kvm_s2_fault_desc *s2fd,
> > * mapping size to ensure we find the right PFN and lay down the
> > * mapping in the right place.
> > */
> > - s2vi->gfn = ALIGN_DOWN(s2fd->fault_ipa, s2vi->vma_pagesize) >> PAGE_SHIFT;
> > + s2vi->gfn = kvm_gpa_from_fault(kvm, ALIGN_DOWN(s2fd->fault_ipa, s2vi->vma_pagesize)) >> PAGE_SHIFT;
> > s2vi->mte_allowed = kvm_vma_mte_allowed(vma);
> > @@ -2056,6 +2124,9 @@ static int kvm_s2_fault_map(const struct kvm_s2_fault_desc *s2fd,
> > prot &= ~KVM_NV_GUEST_MAP_SZ;
> > ret = KVM_PGT_FN(kvm_pgtable_stage2_relax_perms)(pgt, gfn_to_gpa(gfn),
> > prot, flags);
> > + } else if (kvm_is_realm(kvm)) {
> > + ret = realm_map_ipa(kvm, s2fd->fault_ipa, pfn, mapping_size,
> > + prot, memcache);
> > } else {
> > ret = KVM_PGT_FN(kvm_pgtable_stage2_map)(pgt, gfn_to_gpa(gfn), mapping_size,
> > __pfn_to_phys(pfn), prot,
>
> For the case kvm_is_realm(), need we adjust 's2fd->fault_ipa' for the sake of
> huge pages. In kvm_s2_fault_map(), @gfn and @pfn may have been adjusted by
> transparent_hugepage_adjust() to be aligned with huge page size. If the
> adjustment happened in transparent_hugepage_adjust(), we need to align
> s2fd->fault_ipa down to the huge page size either.
All of the above + some RMM changes are needed to get QEmu VMM going
with anon pages guest memory backing - currently testing various
configurations in the background.
Thanks,
Lorenzo
> > @@ -2214,6 +2285,13 @@ int kvm_handle_guest_sea(struct kvm_vcpu *vcpu)
> > return 0;
> > }
> > +static bool shared_ipa_fault(struct kvm *kvm, phys_addr_t fault_ipa)
> > +{
> > + gpa_t gpa = kvm_gpa_from_fault(kvm, fault_ipa);
> > +
> > + return (gpa != fault_ipa);
> > +}
> > +
> > /**
> > * kvm_handle_guest_abort - handles all 2nd stage aborts
> > * @vcpu: the VCPU pointer
> > @@ -2324,8 +2402,9 @@ int kvm_handle_guest_abort(struct kvm_vcpu *vcpu)
> > nested = &nested_trans;
> > }
> > - gfn = ipa >> PAGE_SHIFT;
> > + gfn = kvm_gpa_from_fault(vcpu->kvm, ipa) >> PAGE_SHIFT;
> > memslot = gfn_to_memslot(vcpu->kvm, gfn);
> > +
> > hva = gfn_to_hva_memslot_prot(memslot, gfn, &writable);
> > write_fault = kvm_is_write_fault(vcpu);
> > if (kvm_is_error_hva(hva) || (write_fault && !writable)) {
> > @@ -2368,7 +2447,7 @@ int kvm_handle_guest_abort(struct kvm_vcpu *vcpu)
> > * of the page size.
> > */
> > ipa |= FAR_TO_FIPA_OFFSET(kvm_vcpu_get_hfar(vcpu));
> > - ret = io_mem_abort(vcpu, ipa);
> > + ret = io_mem_abort(vcpu, kvm_gpa_from_fault(vcpu->kvm, ipa));
> > goto out_unlock;
> > }
> > @@ -2396,7 +2475,7 @@ int kvm_handle_guest_abort(struct kvm_vcpu *vcpu)
> > !write_fault &&
> > !kvm_vcpu_trap_is_exec_fault(vcpu));
> > - if (kvm_slot_has_gmem(memslot))
> > + if (kvm_slot_has_gmem(memslot) && !shared_ipa_fault(vcpu->kvm, fault_ipa))
> > ret = gmem_abort(&s2fd);
> > else
> > ret = user_mem_abort(&s2fd);
> > @@ -2433,6 +2512,10 @@ bool kvm_age_gfn(struct kvm *kvm, struct kvm_gfn_range *range)
> > if (!kvm->arch.mmu.pgt || kvm_vm_is_protected(kvm))
> > return false;
> > + /* We don't support aging for Realms */
> > + if (kvm_is_realm(kvm))
> > + return true;
> > +
> > return KVM_PGT_FN(kvm_pgtable_stage2_test_clear_young)(kvm->arch.mmu.pgt,
> > range->start << PAGE_SHIFT,
> > size, true);
> > @@ -2449,6 +2532,10 @@ bool kvm_test_age_gfn(struct kvm *kvm, struct kvm_gfn_range *range)
> > if (!kvm->arch.mmu.pgt || kvm_vm_is_protected(kvm))
> > return false;
> > + /* We don't support aging for Realms */
> > + if (kvm_is_realm(kvm))
> > + return true;
> > +
> > return KVM_PGT_FN(kvm_pgtable_stage2_test_clear_young)(kvm->arch.mmu.pgt,
> > range->start << PAGE_SHIFT,
> > size, false);
> > @@ -2628,10 +2715,11 @@ int kvm_arch_prepare_memory_region(struct kvm *kvm,
> > return -EFAULT;
> > /*
> > - * Only support guest_memfd backed memslots with mappable memory, since
> > - * there aren't any CoCo VMs that support only private memory on arm64.
> > + * Only support guest_memfd backed memslots with mappable memory,
> > + * unless the guest is a CCA realm guest.
> > */
> > - if (kvm_slot_has_gmem(new) && !kvm_memslot_is_gmem_only(new))
> > + if (kvm_slot_has_gmem(new) && !kvm_memslot_is_gmem_only(new) &&
> > + !kvm_is_realm(kvm))
> > return -EINVAL;
> > hva = new->userspace_addr;
> > diff --git a/arch/arm64/kvm/rmi.c b/arch/arm64/kvm/rmi.c
> > index cae29fd3353c..761b38a4071c 100644
> > --- a/arch/arm64/kvm/rmi.c
> > +++ b/arch/arm64/kvm/rmi.c
> > @@ -597,6 +597,179 @@ static int realm_data_map_init(struct kvm *kvm, unsigned long ipa,
> > return ret;
> > }
> > +static unsigned long addr_range_desc(unsigned long phys, unsigned long size)
> > +{
> > + unsigned long out = 0;
> > +
> > + switch (size) {
> > + case P4D_SIZE:
> > + out = 3 | (1 << 2);
> > + break;
> > + case PUD_SIZE:
> > + out = 2 | (1 << 2);
> > + break;
> > + case PMD_SIZE:
> > + out = 1 | (1 << 2);
> > + break;
> > + case PAGE_SIZE:
> > + out = 0 | (1 << 2);
> > + break;
> > + default:
> > + /*
> > + * Only support mapping at the page level granulatity when
> > + * it's an unusual length. This should get us back onto a larger
> > + * block size for the subsequent mappings.
> > + */
> > + out = 0 | ((MIN(size >> PAGE_SHIFT, PTRS_PER_PTE - 1)) << 2);
> > + break;
> > + }
> > +
> > + WARN_ON(phys & ~PAGE_MASK);
> > +
> > + out |= phys & PAGE_MASK;
> > +
> > + return out;
> > +}
> > +
> > +int realm_map_protected(struct kvm *kvm,
> > + unsigned long ipa,
> > + kvm_pfn_t pfn,
> > + unsigned long map_size,
> > + struct kvm_mmu_memory_cache *memcache)
> > +{
> > + struct realm *realm = &kvm->arch.realm;
> > + phys_addr_t phys = __pfn_to_phys(pfn);
> > + phys_addr_t base_phys = phys;
> > + phys_addr_t rd = virt_to_phys(realm->rd);
> > + unsigned long base_ipa = ipa;
> > + unsigned long ipa_top = ipa + map_size;
> > + int ret = 0;
> > +
> > + if (WARN_ON(!IS_ALIGNED(map_size, PAGE_SIZE) ||
> > + !IS_ALIGNED(ipa, map_size)))
> > + return -EINVAL;
> > +
> > + if (rmi_delegate_range(phys, map_size)) {
> > + /*
> > + * It's likely we raced with another VCPU on the same
> > + * fault. Assume the other VCPU has handled the fault
> > + * and return to the guest.
> > + */
> > + return 0;
> > + }
> > +
> > + while (ipa < ipa_top) {
> > + unsigned long flags = RMI_ADDR_TYPE_SINGLE;
> > + unsigned long range_desc = addr_range_desc(phys, ipa_top - ipa);
> > + unsigned long out_top;
> > +
> > + ret = rmi_rtt_data_map(rd, ipa, ipa_top, flags, range_desc,
> > + &out_top);
> > +
> > + if (RMI_RETURN_STATUS(ret) == RMI_ERROR_RTT) {
> > + /* Create missing RTTs and retry */
> > + int level = RMI_RETURN_INDEX(ret);
> > +
> > + WARN_ON(level == KVM_PGTABLE_LAST_LEVEL);
> > + ret = realm_create_rtt_levels(realm, ipa, level,
> > + KVM_PGTABLE_LAST_LEVEL,
> > + memcache);
> > + if (ret)
> > + goto err_undelegate;
> > +
> > + ret = rmi_rtt_data_map(rd, ipa, ipa_top, flags,
> > + range_desc, &out_top);
> > + }
> > +
> > + if (WARN_ON(ret))
> > + goto err_undelegate;
> > +
> > + phys += out_top - ipa;
> > + ipa = out_top;
> > + }
> > +
> > + return 0;
> > +
> > +err_undelegate:
> > + realm_unmap_private_range(kvm, base_ipa, ipa, true);
> > + if (WARN_ON(rmi_undelegate_range(base_phys, map_size))) {
> > + /* Page can't be returned to NS world so is lost */
> > + get_page(phys_to_page(base_phys));
> > + }
> > + return -ENXIO;
> > +}
> > +
> > +int realm_map_non_secure(struct realm *realm,
> > + unsigned long ipa,
> > + kvm_pfn_t pfn,
> > + unsigned long size,
> > + enum kvm_pgtable_prot prot,
> > + struct kvm_mmu_memory_cache *memcache)
> > +{
> > + unsigned long attr, flags = 0;
> > + phys_addr_t rd = virt_to_phys(realm->rd);
> > + phys_addr_t phys = __pfn_to_phys(pfn);
> > + unsigned long ipa_top = ipa + size;
> > + int ret;
> > +
> > + if (WARN_ON(!IS_ALIGNED(size, PAGE_SIZE) ||
> > + !IS_ALIGNED(ipa, size)))
> > + return -EINVAL;
> > +
> > + switch (prot & (KVM_PGTABLE_PROT_DEVICE | KVM_PGTABLE_PROT_NORMAL_NC)) {
> > + case KVM_PGTABLE_PROT_DEVICE | KVM_PGTABLE_PROT_NORMAL_NC:
> > + return -EINVAL;
> > + case KVM_PGTABLE_PROT_DEVICE:
> > + attr = MT_S2_FWB_DEVICE_nGnRE;
> > + break;
> > + case KVM_PGTABLE_PROT_NORMAL_NC:
> > + attr = MT_S2_FWB_NORMAL_NC;
> > + break;
> > + default:
> > + attr = MT_S2_FWB_NORMAL;
> > + }
> > +
> > + flags |= FIELD_PREP(RMI_RTT_UNPROT_MAP_FLAGS_MEMATTR, attr);
> > +
> > + if (prot & KVM_PGTABLE_PROT_R)
> > + flags |= FIELD_PREP(RMI_RTT_UNPROT_MAP_FLAGS_S2AP, RMI_S2AP_DIRECT_READ);
> > + if (prot & KVM_PGTABLE_PROT_W)
> > + flags |= FIELD_PREP(RMI_RTT_UNPROT_MAP_FLAGS_S2AP, RMI_S2AP_DIRECT_WRITE);
> > +
> > + flags |= RMI_ADDR_TYPE_SINGLE;
> > +
> > + while (ipa < ipa_top) {
> > + unsigned long range_desc = addr_range_desc(phys, ipa_top - ipa);
> > + unsigned long out_top;
> > +
> > + ret = rmi_rtt_unprot_map(rd, ipa, ipa_top, flags, range_desc,
> > + &out_top);
> > +
> > + if (RMI_RETURN_STATUS(ret) == RMI_ERROR_RTT) {
> > + /* Create missing RTTs and retry */
> > + int level = RMI_RETURN_INDEX(ret);
> > +
> > + WARN_ON(level == KVM_PGTABLE_LAST_LEVEL);
> > + ret = realm_create_rtt_levels(realm, ipa, level,
> > + KVM_PGTABLE_LAST_LEVEL,
> > + memcache);
> > + if (ret)
> > + return ret;
> > +
> > + ret = rmi_rtt_unprot_map(rd, ipa, ipa_top, flags,
> > + range_desc, &out_top);
> > + }
> > +
> > + if (WARN_ON(ret))
> > + return ret;
> > +
> > + phys += out_top - ipa;
> > + ipa = out_top;
> > + }
> > +
> > + return 0;
> > +}
> > +
> > static int populate_region_cb(struct kvm *kvm, gfn_t gfn, kvm_pfn_t pfn,
> > struct page *src_page, void *opaque)
> > {
>
> Thanks,
> Gavin
>
^ permalink raw reply
* [PATCH] PCI: cadence: skip the link polling when endpoint not connected
From: Aksh Garg @ 2026-06-05 7:19 UTC (permalink / raw)
To: linux-pci, vigneshr, s-vadapalli, lpieralisi, kwilczynski, mani,
robh, bhelgaas, mpillai, unicorn_wang, me, 18255117159
Cc: linux-arm-kernel, linux-kernel, danishanwar, a-garg7
cdns_pcie_host_wait_for_link() polls on link-up for 10 retries with a
delay of 90-100ms each (~1 second). A call to cdns_pcie_host_link_setup()
during the resume operation blocks the resume operation unnecessarily for
~1s even when no endpoint device is connected.
Add skip_link_polling flag to track link state across suspend/resume
cycles. If link was down before suspend, skip the expensive polling
in resume since no endpoint was present.
Signed-off-by: Aksh Garg <a-garg7@ti.com>
---
drivers/pci/controller/cadence/pci-j721e.c | 5 +++++
drivers/pci/controller/cadence/pcie-cadence-host-hpa.c | 3 +++
drivers/pci/controller/cadence/pcie-cadence-host.c | 3 +++
drivers/pci/controller/cadence/pcie-cadence.h | 3 +++
4 files changed, 14 insertions(+)
diff --git a/drivers/pci/controller/cadence/pci-j721e.c b/drivers/pci/controller/cadence/pci-j721e.c
index bfdfe98d5aba..849eb8bb9e45 100644
--- a/drivers/pci/controller/cadence/pci-j721e.c
+++ b/drivers/pci/controller/cadence/pci-j721e.c
@@ -686,6 +686,11 @@ static int j721e_pcie_suspend_noirq(struct device *dev)
struct j721e_pcie *pcie = dev_get_drvdata(dev);
if (pcie->mode == PCI_MODE_RC) {
+ struct cdns_pcie_rc *rc = cdns_pcie_to_rc(pcie->cdns_pcie);
+
+ /* If link is down before suspend, skip polling in resume */
+ rc->skip_link_polling = !j721e_pcie_link_up(pcie->cdns_pcie);
+
gpiod_set_value_cansleep(pcie->reset_gpio, 0);
clk_disable_unprepare(pcie->refclk);
}
diff --git a/drivers/pci/controller/cadence/pcie-cadence-host-hpa.c b/drivers/pci/controller/cadence/pcie-cadence-host-hpa.c
index 0f540bed58e8..d78c1282a5ee 100644
--- a/drivers/pci/controller/cadence/pcie-cadence-host-hpa.c
+++ b/drivers/pci/controller/cadence/pcie-cadence-host-hpa.c
@@ -301,6 +301,9 @@ int cdns_pcie_hpa_host_link_setup(struct cdns_pcie_rc *rc)
return ret;
}
+ if (rc->skip_link_polling)
+ return 0;
+
ret = cdns_pcie_host_wait_for_link(pcie, cdns_pcie_hpa_link_up);
if (ret)
dev_dbg(dev, "PCIe link never came up\n");
diff --git a/drivers/pci/controller/cadence/pcie-cadence-host.c b/drivers/pci/controller/cadence/pcie-cadence-host.c
index 0bc9e6e90e0e..026414c21ee1 100644
--- a/drivers/pci/controller/cadence/pcie-cadence-host.c
+++ b/drivers/pci/controller/cadence/pcie-cadence-host.c
@@ -352,6 +352,9 @@ int cdns_pcie_host_link_setup(struct cdns_pcie_rc *rc)
return ret;
}
+ if (rc->skip_link_polling)
+ return 0;
+
ret = cdns_pcie_host_start_link(rc, cdns_pcie_link_up);
if (ret)
dev_dbg(dev, "PCIe link never came up\n");
diff --git a/drivers/pci/controller/cadence/pcie-cadence.h b/drivers/pci/controller/cadence/pcie-cadence.h
index 574e9cf4d003..01e49ecccc7b 100644
--- a/drivers/pci/controller/cadence/pcie-cadence.h
+++ b/drivers/pci/controller/cadence/pcie-cadence.h
@@ -117,6 +117,8 @@ struct cdns_pcie {
* @no_inbound_map: Whether inbound mapping is supported
* @quirk_broken_aspm_l0s: Disable ASPM L0s support as quirk
* @quirk_broken_aspm_l1: Disable ASPM L1 support as quirk
+ * @skip_link_polling: Skip link polling in resume if link was down before
+ * suspend, to avoid long delay in resume
*/
struct cdns_pcie_rc {
struct cdns_pcie pcie;
@@ -131,6 +133,7 @@ struct cdns_pcie_rc {
unsigned int no_inbound_map:1;
unsigned int quirk_broken_aspm_l0s:1;
unsigned int quirk_broken_aspm_l1:1;
+ unsigned int skip_link_polling:1;
};
/**
--
2.34.1
^ permalink raw reply related
* [PATCH] pinctrl: Move Airoha driver to dedicated directory
From: Christian Marangi @ 2026-06-05 7:12 UTC (permalink / raw)
To: Linus Walleij, Lorenzo Bianconi, Sean Wang, Matthias Brugger,
AngeloGioacchino Del Regno, Christian Marangi, linux-kernel,
linux-gpio, linux-mediatek, linux-arm-kernel
In preparation for additional SoC support, move the Airoha pinctrl driver
for AN7581 SoC to a dedicated directory.
This is to tidy things up and keep code organized without polluting the
Mediatek driver directory.
The driver doesn't depend on any generic or common code from the Mediatek
codebase so it can be safely moved without any modification.
Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
---
MAINTAINERS | 2 +-
drivers/pinctrl/Kconfig | 1 +
drivers/pinctrl/Makefile | 1 +
drivers/pinctrl/airoha/Kconfig | 20 +++++++++++++++++++
drivers/pinctrl/airoha/Makefile | 3 +++
.../{mediatek => airoha}/pinctrl-airoha.c | 0
drivers/pinctrl/mediatek/Kconfig | 17 +---------------
drivers/pinctrl/mediatek/Makefile | 1 -
8 files changed, 27 insertions(+), 18 deletions(-)
create mode 100644 drivers/pinctrl/airoha/Kconfig
create mode 100644 drivers/pinctrl/airoha/Makefile
rename drivers/pinctrl/{mediatek => airoha}/pinctrl-airoha.c (100%)
diff --git a/MAINTAINERS b/MAINTAINERS
index 21c0ef0b9ce5..38bf92149a15 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -21024,7 +21024,7 @@ M: Lorenzo Bianconi <lorenzo@kernel.org>
L: linux-mediatek@lists.infradead.org (moderated for non-subscribers)
S: Maintained
F: Documentation/devicetree/bindings/pinctrl/airoha,en7581-pinctrl.yaml
-F: drivers/pinctrl/mediatek/pinctrl-airoha.c
+F: drivers/pinctrl/airoha/pinctrl-airoha.c
PIN CONTROLLER - AMD
M: Basavaraj Natikar <Basavaraj.Natikar@amd.com>
diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig
index 03f2e3ee065f..e0babad31445 100644
--- a/drivers/pinctrl/Kconfig
+++ b/drivers/pinctrl/Kconfig
@@ -679,6 +679,7 @@ config PINCTRL_RP1
multi function device.
source "drivers/pinctrl/actions/Kconfig"
+source "drivers/pinctrl/airoha/Kconfig"
source "drivers/pinctrl/aspeed/Kconfig"
source "drivers/pinctrl/bcm/Kconfig"
source "drivers/pinctrl/berlin/Kconfig"
diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile
index f7d5d5f76d0c..36c55858801f 100644
--- a/drivers/pinctrl/Makefile
+++ b/drivers/pinctrl/Makefile
@@ -66,6 +66,7 @@ obj-$(CONFIG_PINCTRL_ZYNQMP) += pinctrl-zynqmp.o
obj-$(CONFIG_PINCTRL_ZYNQ) += pinctrl-zynq.o
obj-y += actions/
+obj-y += airoha/
obj-$(CONFIG_ARCH_ASPEED) += aspeed/
obj-y += bcm/
obj-$(CONFIG_PINCTRL_BERLIN) += berlin/
diff --git a/drivers/pinctrl/airoha/Kconfig b/drivers/pinctrl/airoha/Kconfig
new file mode 100644
index 000000000000..03adaeae8fc3
--- /dev/null
+++ b/drivers/pinctrl/airoha/Kconfig
@@ -0,0 +1,20 @@
+# SPDX-License-Identifier: GPL-2.0-only
+menu "Airoha pinctrl drivers"
+ depends on ARCH_AIROHA || COMPILE_TEST
+
+config PINCTRL_AIROHA
+ tristate "Airoha EN7581 pin control"
+ depends on OF
+ depends on ARM64 || COMPILE_TEST
+ select PINMUX
+ select GENERIC_PINCONF
+ select GENERIC_PINCTRL_GROUPS
+ select GENERIC_PINMUX_FUNCTIONS
+ select GPIOLIB
+ select GPIOLIB_IRQCHIP
+ select REGMAP_MMIO
+ help
+ Say yes here to support pin controller and gpio driver
+ on Airoha EN7581 SoC.
+
+endmenu
diff --git a/drivers/pinctrl/airoha/Makefile b/drivers/pinctrl/airoha/Makefile
new file mode 100644
index 000000000000..a25b744dd7a8
--- /dev/null
+++ b/drivers/pinctrl/airoha/Makefile
@@ -0,0 +1,3 @@
+# SPDX-License-Identifier: GPL-2.0
+
+obj-$(CONFIG_PINCTRL_AIROHA) += pinctrl-airoha.o
diff --git a/drivers/pinctrl/mediatek/pinctrl-airoha.c b/drivers/pinctrl/airoha/pinctrl-airoha.c
similarity index 100%
rename from drivers/pinctrl/mediatek/pinctrl-airoha.c
rename to drivers/pinctrl/airoha/pinctrl-airoha.c
diff --git a/drivers/pinctrl/mediatek/Kconfig b/drivers/pinctrl/mediatek/Kconfig
index 4819617d9368..97980cc28b9c 100644
--- a/drivers/pinctrl/mediatek/Kconfig
+++ b/drivers/pinctrl/mediatek/Kconfig
@@ -1,6 +1,6 @@
# SPDX-License-Identifier: GPL-2.0-only
menu "MediaTek pinctrl drivers"
- depends on ARCH_MEDIATEK || ARCH_AIROHA || RALINK || COMPILE_TEST
+ depends on ARCH_MEDIATEK || RALINK || COMPILE_TEST
config EINT_MTK
tristate "MediaTek External Interrupt Support"
@@ -126,21 +126,6 @@ config PINCTRL_MT8127
select PINCTRL_MTK
# For ARMv8 SoCs
-config PINCTRL_AIROHA
- tristate "Airoha EN7581 pin control"
- depends on OF
- depends on ARM64 || COMPILE_TEST
- select PINMUX
- select GENERIC_PINCONF
- select GENERIC_PINCTRL_GROUPS
- select GENERIC_PINMUX_FUNCTIONS
- select GPIOLIB
- select GPIOLIB_IRQCHIP
- select REGMAP_MMIO
- help
- Say yes here to support pin controller and gpio driver
- on Airoha EN7581 SoC.
-
config PINCTRL_MT2712
bool "MediaTek MT2712 pin control"
depends on OF
diff --git a/drivers/pinctrl/mediatek/Makefile b/drivers/pinctrl/mediatek/Makefile
index ae765bd99965..6dc17b0c23f9 100644
--- a/drivers/pinctrl/mediatek/Makefile
+++ b/drivers/pinctrl/mediatek/Makefile
@@ -8,7 +8,6 @@ obj-$(CONFIG_PINCTRL_MTK_MOORE) += pinctrl-moore.o
obj-$(CONFIG_PINCTRL_MTK_PARIS) += pinctrl-paris.o
# SoC Drivers
-obj-$(CONFIG_PINCTRL_AIROHA) += pinctrl-airoha.o
obj-$(CONFIG_PINCTRL_MT7620) += pinctrl-mt7620.o
obj-$(CONFIG_PINCTRL_MT7621) += pinctrl-mt7621.o
obj-$(CONFIG_PINCTRL_MT76X8) += pinctrl-mt76x8.o
--
2.53.0
^ permalink raw reply related
* [PATCH v4 1/7] arm64: defconfig: Enable Allwinner LRADC input driver
From: Alexander Sverdlin @ 2026-06-05 7:09 UTC (permalink / raw)
To: linux-arm-kernel, linux-sunxi
Cc: Alexander Sverdlin, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Chen-Yu Tsai, Jernej Skrabec, Samuel Holland,
Hans de Goede, Dmitry Torokhov, Andre Przywara, Jun Yan,
Lukas Schmid, J. Neuschäfer, Eric Biggers, Michal Simek,
Luca Weiss, Sven Peter, Maxime Ripard, devicetree, linux-kernel,
linux-input
In-Reply-To: <20260605070923.3045073-1-alexander.sverdlin@gmail.com>
Enable Allwinner LRADC input driver as module to support buttons on Baijie
HelperBoard A133.
Signed-off-by: Alexander Sverdlin <alexander.sverdlin@gmail.com>
---
Changelog:
v4:
- no changes
v3:
- new patch
arch/arm64/configs/defconfig | 1 +
1 file changed, 1 insertion(+)
diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index 96ce783f24e7..faf6d86d0555 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -479,6 +479,7 @@ CONFIG_KEYBOARD_GPIO=y
CONFIG_KEYBOARD_GPIO_POLLED=m
CONFIG_KEYBOARD_SNVS_PWRKEY=m
CONFIG_KEYBOARD_IMX_SC_KEY=m
+CONFIG_KEYBOARD_SUN4I_LRADC=m
CONFIG_KEYBOARD_CROS_EC=y
CONFIG_KEYBOARD_MTK_PMIC=m
CONFIG_MOUSE_ELAN_I2C=m
--
2.54.0
^ permalink raw reply related
* [PATCH v4 7/7] arm64: dts: allwinner: A133: add support for Baijie Helper A133 board
From: Alexander Sverdlin @ 2026-06-05 7:09 UTC (permalink / raw)
To: linux-arm-kernel, linux-sunxi
Cc: Alexander Sverdlin, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Chen-Yu Tsai, Jernej Skrabec, Samuel Holland,
Hans de Goede, Dmitry Torokhov, Andre Przywara, Jun Yan,
Lukas Schmid, J. Neuschäfer, Eric Biggers, Michal Simek,
Luca Weiss, Sven Peter, Maxime Ripard, devicetree, linux-kernel,
linux-input
In-Reply-To: <20260605070923.3045073-1-alexander.sverdlin@gmail.com>
Baijie Helper A133 board is a development board around Baijie A133 Core
SBC. Features:
- 1/2/4GiB LPDDR4 DRAM
- 8/16/32GiB eMMC
- AXP707 PMIC
- USB-C OTG port in peripheral mode (via onboard hub)
- 2 USB 2.0 ports
- MicroSD slot and on-board eMMC module
- Gigabit Ethernet
- Bluetooth
- WiFi
Add initial support for both the Helper and Core boards, including UART,
PMU, eMMC, USB, Ethernet, LRADC-connected buttons.
UART1 can only be used for Bluetooth module, but BT-WiFi combo Allwinner
AW869A chip has no mainline driver currently.
Signed-off-by: Alexander Sverdlin <alexander.sverdlin@gmail.com>
---
Changelog:
v4:
- renamed "sun50i-a133-baijie-helper.dtb" -> "sun50i-a133-helperboard.dtb"
- added "model" property into root of sun50i-a133-helperboard-core.dtsi
- added "cap-mmc-highspeed" and "max-frequency" into &mmc2
- added "x-powers,drive-vbus-en" and "*-supply" into &axp803
- dropped all "regulator-enable-ramp-delay" properties
- replaced ®_dcdc3 with a "polyphased" comment
- exact DRAM voltage in ®_dcdc5
- disabled ®_dcdc6 to avoid "[ 31.710641] dcdc6: disabling"
- added ®_vdd5v "root" regulator
- added "disable-wp" into &mmc0
- commented &usb_otg
- assigned usb1_vbus-supply in &usbphy
v3:
- added my copyrights into the newly introduced DTs
- all DT nodes sorted alphabetically
- all always-on regulators commented/propetly named
- all regulators got proper voltages (not default ranges)
- ADC-sensed buttons K1..K5 added
- re-labelled "eth_phy" -> "rgmii_phy"
- usbphy 0 switched from host into peripheral mode (downstream from an
onboard hub)
- typo sun50i-a133-baije-core.dtsi -> sun50i-a133-baijie-core.dtsi
v2:
- introduced baijie,helper-a133-core compatible for the Core (SoM) board
arch/arm64/boot/dts/allwinner/Makefile | 1 +
.../sun50i-a133-helperboard-core.dtsi | 197 ++++++++++++++++++
.../dts/allwinner/sun50i-a133-helperboard.dts | 148 +++++++++++++
3 files changed, 346 insertions(+)
create mode 100644 arch/arm64/boot/dts/allwinner/sun50i-a133-helperboard-core.dtsi
create mode 100644 arch/arm64/boot/dts/allwinner/sun50i-a133-helperboard.dts
diff --git a/arch/arm64/boot/dts/allwinner/Makefile b/arch/arm64/boot/dts/allwinner/Makefile
index d116864b6c2b..cf8434064b0d 100644
--- a/arch/arm64/boot/dts/allwinner/Makefile
+++ b/arch/arm64/boot/dts/allwinner/Makefile
@@ -18,6 +18,7 @@ dtb-$(CONFIG_ARCH_SUNXI) += sun50i-a64-sopine-baseboard.dtb
dtb-$(CONFIG_ARCH_SUNXI) += sun50i-a64-teres-i.dtb
dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h64-remix-mini-pc.dtb
dtb-$(CONFIG_ARCH_SUNXI) += sun50i-a100-allwinner-perf1.dtb
+dtb-$(CONFIG_ARCH_SUNXI) += sun50i-a133-helperboard.dtb
dtb-$(CONFIG_ARCH_SUNXI) += sun50i-a133-liontron-h-a133l.dtb
dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h5-bananapi-m2-plus.dtb
dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h5-bananapi-m2-plus-v1.2.dtb
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a133-helperboard-core.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-a133-helperboard-core.dtsi
new file mode 100644
index 000000000000..545972d2324a
--- /dev/null
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a133-helperboard-core.dtsi
@@ -0,0 +1,197 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2025 Arm Ltd.
+ * Copyright (c) 2026 Alexander Sverdlin <alexander.sverdlin@gmail.com>
+ */
+
+/dts-v1/;
+
+#include "sun50i-a100.dtsi"
+#include "sun50i-a100-cpu-opp.dtsi"
+
+/{
+ model = "Baijie A133 HelperBoard Core";
+ compatible = "baijie,helperboard-a133-core",
+ "allwinner,sun50i-a100";
+
+ aliases {
+ serial1 = &uart1; /* BT module */
+ };
+};
+
+&cpu0 {
+ cpu-supply = <®_dcdc2>;
+};
+
+&lradc {
+ vref-supply = <®_aldo1>;
+};
+
+&mmc2 {
+ vmmc-supply = <®_dcdc1>;
+ vqmmc-supply = <®_eldo1>;
+ cap-mmc-highspeed;
+ cap-mmc-hw-reset;
+ max-frequency = <100000000>;
+ non-removable;
+ bus-width = <8>;
+ mmc-ddr-1_8v;
+ mmc-hs200-1_8v;
+ status = "okay";
+};
+
+&pio {
+ vcc-pb-supply = <®_dcdc1>;
+ vcc-pc-supply = <®_eldo1>;
+ vcc-pd-supply = <®_dcdc1>;
+ vcc-pe-supply = <®_dldo2>;
+ vcc-pf-supply = <®_dcdc1>;
+ vcc-pg-supply = <®_dldo1>;
+ vcc-ph-supply = <®_dcdc1>;
+ /*
+ * PL0/PL1 are the I2C connection to PMIC, but it would create a
+ * circular dependency:
+ * vcc-pl-supply = <®_aldo3>;
+ */
+};
+
+&r_i2c0 {
+ status = "okay";
+
+ axp803: pmic@34 {
+ compatible = "x-powers,axp803";
+ reg = <0x34>;
+ interrupt-parent = <&r_intc>;
+ interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
+ x-powers,drive-vbus-en; /* set N_VBUSEN as output pin */
+ aldoin-supply = <®_vdd5v>;
+ dldoin-supply = <®_vdd5v>;
+ eldoin-supply = <®_vdd5v>;
+ fldoin-supply = <®_dcdc5>;
+ vin1-supply = <®_vdd5v>;
+ vin2-supply = <®_vdd5v>;
+ vin3-supply = <®_vdd5v>;
+ vin4-supply = <®_vdd5v>;
+ vin5-supply = <®_vdd5v>;
+ vin6-supply = <®_vdd5v>;
+ drivevbus-supply = <®_vdd5v>;
+ };
+};
+
+#include "axp803.dtsi"
+
+&ac_power_supply {
+ status = "okay";
+};
+
+®_aldo1 {
+ /* PLL + LRADC analog reference */
+ regulator-always-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-name = "vcc-pll";
+};
+
+®_aldo2 {
+ /* LPDDR */
+ regulator-always-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-name = "vdd18-lpddr";
+};
+
+®_aldo3 {
+ /*
+ * Port L, but linking it to &pio node would create a circular
+ * dependency because of PL0/PL1 I2C connection to PMIC
+ */
+ regulator-always-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-name = "vcc-pl";
+};
+
+®_dcdc1 {
+ /* Besides Port D it also powers analog part of USB IP and SoC I/O */
+ regulator-always-on;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-name = "vcc-3v3";
+};
+
+®_dcdc2 {
+ regulator-always-on;
+ regulator-min-microvolt = <810000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-name = "vdd-cpu";
+};
+
+/* DCDC3 is polyphased with DCDC2 */
+
+®_dcdc4 {
+ /* Digital part of USB IP, "System" SoC power rail */
+ regulator-always-on;
+ regulator-min-microvolt = <950000>;
+ regulator-max-microvolt = <950000>;
+ regulator-name = "vdd-sys";
+};
+
+®_dcdc5 {
+ regulator-always-on;
+ regulator-min-microvolt = <1100000>;
+ regulator-max-microvolt = <1100000>;
+ regulator-name = "vcc-dram";
+};
+
+/* DCDC6 unused */
+®_dcdc6 {
+ status = "disabled";
+};
+
+®_dldo1 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-name = "vcc-pg";
+};
+
+®_dldo2 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-name = "vcc-pe";
+};
+
+®_dldo3 {
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ regulator-name = "avdd-csi";
+};
+
+®_dldo4 {
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ regulator-name = "afvcc-csi";
+};
+
+®_eldo1 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-name = "vcc-pc";
+};
+
+®_eldo2 {
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-name = "dvdd-csi";
+};
+
+/* ELDO3 unused */
+
+®_fldo1 {
+ /* CPUS power rail */
+ regulator-always-on;
+ regulator-min-microvolt = <900000>;
+ regulator-max-microvolt = <900000>;
+ regulator-name = "vdd-cpus";
+};
+
+/* reg_drivevbus unused */
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a133-helperboard.dts b/arch/arm64/boot/dts/allwinner/sun50i-a133-helperboard.dts
new file mode 100644
index 000000000000..694c0cacf906
--- /dev/null
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a133-helperboard.dts
@@ -0,0 +1,148 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2025 Arm Ltd.
+ * Copyright (c) 2026 Alexander Sverdlin <alexander.sverdlin@gmail.com>
+ */
+
+/dts-v1/;
+
+#include "sun50i-a133-helperboard-core.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/linux-event-codes.h>
+#include <dt-bindings/leds/common.h>
+
+/{
+ model = "Baijie HelperBoard A133";
+ compatible = "baijie,helperboard-a133",
+ "baijie,helperboard-a133-core",
+ "allwinner,sun50i-a100";
+
+ aliases {
+ serial0 = &uart0;
+ };
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+
+ leds {
+ compatible = "gpio-leds";
+
+ led {
+ function = LED_FUNCTION_INDICATOR;
+ color = <LED_COLOR_ID_GREEN>;
+ gpios = <&pio 7 13 GPIO_ACTIVE_LOW>; /* PH13 */
+ };
+ };
+
+ reg_vdd5v: vdd5v {
+ /* board wide 5V supply from a 12V->5V regulator */
+ compatible = "regulator-fixed";
+ regulator-name = "vdd-5v";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ regulator-always-on;
+ };
+};
+
+&ehci1 {
+ status = "okay";
+};
+
+&emac0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&rgmii0_pins>;
+ phy-handle = <&rgmii_phy>;
+ phy-mode = "rgmii-id";
+ allwinner,rx-delay-ps = <200>;
+ allwinner,tx-delay-ps = <200>;
+ status = "okay";
+};
+
+&lradc {
+ wakeup-source;
+ status = "okay";
+
+ button-115 {
+ label = "K1";
+ linux,code = <KEY_1>;
+ channel = <0>;
+ voltage = <114607>;
+ };
+
+ button-235 {
+ label = "K2";
+ linux,code = <KEY_2>;
+ channel = <0>;
+ voltage = <234783>;
+ };
+
+ button-360 {
+ label = "K3";
+ linux,code = <KEY_3>;
+ channel = <0>;
+ voltage = <360000>;
+ };
+
+ button-476 {
+ label = "K4";
+ linux,code = <KEY_4>;
+ channel = <0>;
+ voltage = <476471>;
+ };
+
+ button-592 {
+ label = "K5";
+ linux,code = <KEY_5>;
+ channel = <0>;
+ voltage = <591946>;
+ };
+};
+
+&mdio0 {
+ reset-gpios = <&pio 7 11 GPIO_ACTIVE_LOW>; /* PH11 */
+ reset-delay-us = <10000>;
+ reset-post-delay-us = <150000>;
+
+ rgmii_phy: ethernet-phy@1 {
+ compatible = "ethernet-phy-ieee802.3-c22";
+ reg = <1>;
+ };
+};
+
+&mmc0 {
+ vmmc-supply = <®_dcdc1>;
+ cd-gpios = <&pio 5 6 GPIO_ACTIVE_LOW>; /* PF6 */
+ bus-width = <4>;
+ disable-wp;
+ status = "okay";
+};
+
+&ohci1 {
+ status = "okay";
+};
+
+&rgmii0_pins {
+ drive-strength = <30>;
+};
+
+&uart0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart0_pb_pins>;
+ status = "okay";
+};
+
+&usb_otg {
+ /*
+ * Connected to a downstream port of an onboard hub, therefore only
+ * "peripheral" mode will work here.
+ */
+ dr_mode = "peripheral";
+ status = "okay";
+};
+
+&usbphy {
+ usb1_vbus-supply = <®_vdd5v>;
+ status = "okay";
+};
--
2.54.0
^ permalink raw reply related
* [PATCH v4 5/7] arm64: dts: allwinner: a100: Add LRADC node
From: Alexander Sverdlin @ 2026-06-05 7:09 UTC (permalink / raw)
To: linux-arm-kernel, linux-sunxi
Cc: Alexander Sverdlin, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Chen-Yu Tsai, Jernej Skrabec, Samuel Holland,
Hans de Goede, Dmitry Torokhov, Andre Przywara, Jun Yan,
Lukas Schmid, J. Neuschäfer, Eric Biggers, Michal Simek,
Luca Weiss, Sven Peter, Maxime Ripard, devicetree, linux-kernel,
linux-input
In-Reply-To: <20260605070923.3045073-1-alexander.sverdlin@gmail.com>
A100/A133 SoCs feature a Low Rate ADC (LRADC) for Key application.
Specs:
- Power supply voltage: 1.8 V
- Reference voltage: 1.35 V
- Interrupt support
- Support Hold Key and General Key
- Support normal, continue and single work mode
- 6-bits resolution, sample rate up to 2 kHz
- Voltage input range between 0 and 1.35 V
Signed-off-by: Alexander Sverdlin <alexander.sverdlin@gmail.com>
---
Changelog:
v4:
- added allwinner,sun50i-a100-lradc compatible
v3:
- new patch
arch/arm64/boot/dts/allwinner/sun50i-a100.dtsi | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a100.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-a100.dtsi
index b3fb1e0ee796..7cb06b19b5a5 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-a100.dtsi
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a100.dtsi
@@ -466,6 +466,15 @@ ths: thermal-sensor@5070400 {
#thermal-sensor-cells = <1>;
};
+ lradc: lradc@5070800 {
+ compatible = "allwinner,sun50i-a100-lradc", "allwinner,sun50i-r329-lradc";
+ reg = <0x05070800 0x400>;
+ interrupts = <GIC_SPI 22 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&ccu CLK_BUS_LRADC>;
+ resets = <&ccu RST_BUS_LRADC>;
+ status = "disabled";
+ };
+
usb_otg: usb@5100000 {
compatible = "allwinner,sun50i-a100-musb",
"allwinner,sun8i-a33-musb";
--
2.54.0
^ permalink raw reply related
* [PATCH v4 6/7] arm64: dts: allwinner: a100: reserve RAM for ATF
From: Alexander Sverdlin @ 2026-06-05 7:09 UTC (permalink / raw)
To: linux-arm-kernel, linux-sunxi
Cc: Alexander Sverdlin, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Chen-Yu Tsai, Jernej Skrabec, Samuel Holland,
Hans de Goede, Dmitry Torokhov, Andre Przywara, Jun Yan,
Lukas Schmid, J. Neuschäfer, Eric Biggers, Michal Simek,
Luca Weiss, Sven Peter, Maxime Ripard, devicetree, linux-kernel,
linux-input
In-Reply-To: <20260605070923.3045073-1-alexander.sverdlin@gmail.com>
Add reserved-memory node carving out Trusted Firmware-A region spanning
fixed 256K from physical address 0x40000000. Even though Allwinner ATF
itself passes the address range in the fdt to U-Boot, U-Boot currently
only reserves this memory internally, but doesn't carve out the region
in the fdt passed to Linux.
Signed-off-by: Alexander Sverdlin <alexander.sverdlin@gmail.com>
---
Changelog:
v4:
- new patch
arch/arm64/boot/dts/allwinner/sun50i-a100.dtsi | 16 ++++++++++++++++
1 file changed, 16 insertions(+)
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a100.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-a100.dtsi
index 7cb06b19b5a5..d8391663fd1d 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-a100.dtsi
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a100.dtsi
@@ -87,6 +87,22 @@ osc32k: osc32k-clk {
#clock-cells = <0>;
};
+ reserved-memory {
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+ /*
+ * 256 KiB reserved for Trusted Firmware-A (BL31).
+ * This is added by BL31 itself, but some bootloaders fail
+ * to propagate this into the DTB handed to kernels.
+ */
+ secmon@40000000 {
+ reg = <0x0 0x40000000 0x0 0x40000>;
+ no-map;
+ };
+ };
+
timer {
compatible = "arm,armv8-timer";
interrupts = <GIC_PPI 13
--
2.54.0
^ permalink raw reply related
* [PATCH v4 4/7] dt-bindings: input: sun4i-lradc-keys: Add A100/A133 compatible
From: Alexander Sverdlin @ 2026-06-05 7:09 UTC (permalink / raw)
To: linux-arm-kernel, linux-sunxi
Cc: Alexander Sverdlin, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Chen-Yu Tsai, Jernej Skrabec, Samuel Holland,
Hans de Goede, Dmitry Torokhov, Andre Przywara, Jun Yan,
Lukas Schmid, J. Neuschäfer, Eric Biggers, Michal Simek,
Luca Weiss, Sven Peter, Maxime Ripard, devicetree, linux-kernel,
linux-input
In-Reply-To: <20260605070923.3045073-1-alexander.sverdlin@gmail.com>
The Allwinner A100/A133 SoCs have an LRADC which is compatible with the
versions in existing SoCs. Add a compatible string for A100, with the R329
fallback.
Signed-off-by: Alexander Sverdlin <alexander.sverdlin@gmail.com>
---
Changelog:
v4:
- new patch
.../bindings/input/allwinner,sun4i-a10-lradc-keys.yaml | 1 +
1 file changed, 1 insertion(+)
diff --git a/Documentation/devicetree/bindings/input/allwinner,sun4i-a10-lradc-keys.yaml b/Documentation/devicetree/bindings/input/allwinner,sun4i-a10-lradc-keys.yaml
index 6bdb8040be65..524c8b51f53f 100644
--- a/Documentation/devicetree/bindings/input/allwinner,sun4i-a10-lradc-keys.yaml
+++ b/Documentation/devicetree/bindings/input/allwinner,sun4i-a10-lradc-keys.yaml
@@ -23,6 +23,7 @@ properties:
- const: allwinner,sun50i-r329-lradc
- items:
- enum:
+ - allwinner,sun50i-a100-lradc
- allwinner,sun50i-h616-lradc
- allwinner,sun20i-d1-lradc
- const: allwinner,sun50i-r329-lradc
--
2.54.0
^ permalink raw reply related
* [PATCH v4 2/7] dt-bindings: vendor-prefixes: Add Shenzhen Baijie Technology Co., Ltd.
From: Alexander Sverdlin @ 2026-06-05 7:09 UTC (permalink / raw)
To: linux-arm-kernel, linux-sunxi
Cc: Alexander Sverdlin, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Chen-Yu Tsai, Jernej Skrabec, Samuel Holland,
Hans de Goede, Dmitry Torokhov, Andre Przywara, Jun Yan,
Lukas Schmid, J. Neuschäfer, Eric Biggers, Michal Simek,
Luca Weiss, Sven Peter, Maxime Ripard, devicetree, linux-kernel,
linux-input, Conor Dooley, Paul Kocialkowski
In-Reply-To: <20260605070923.3045073-1-alexander.sverdlin@gmail.com>
Shenzhen Baijie Technology Co., Ltd. focuses on R&D and production of
embedded products as well as customization of embedded solutions.
Link: https://szbaijie.com/
Acked-by: Conor Dooley <conor.dooley@microchip.com>
Reviewed-by: Paul Kocialkowski <paulk@sys-base.io>
Signed-off-by: Alexander Sverdlin <alexander.sverdlin@gmail.com>
---
Documentation/devicetree/bindings/vendor-prefixes.yaml | 2 ++
1 file changed, 2 insertions(+)
diff --git a/Documentation/devicetree/bindings/vendor-prefixes.yaml b/Documentation/devicetree/bindings/vendor-prefixes.yaml
index 28784d66ae7b..095cf654787f 100644
--- a/Documentation/devicetree/bindings/vendor-prefixes.yaml
+++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml
@@ -229,6 +229,8 @@ patternProperties:
description: Azoteq (Pty) Ltd
"^azw,.*":
description: Shenzhen AZW Technology Co., Ltd.
+ "^baijie,.*":
+ description: Shenzhen Baijie Technology Co., Ltd.
"^baikal,.*":
description: BAIKAL ELECTRONICS, JSC
"^bananapi,.*":
--
2.54.0
^ permalink raw reply related
* [PATCH v4 3/7] dt-bindings: arm: sunxi: Add Baijie HelperBoard A133 compatible
From: Alexander Sverdlin @ 2026-06-05 7:09 UTC (permalink / raw)
To: linux-arm-kernel, linux-sunxi
Cc: Alexander Sverdlin, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Chen-Yu Tsai, Jernej Skrabec, Samuel Holland,
Hans de Goede, Dmitry Torokhov, Andre Przywara, Jun Yan,
Lukas Schmid, J. Neuschäfer, Eric Biggers, Michal Simek,
Luca Weiss, Sven Peter, Maxime Ripard, devicetree, linux-kernel,
linux-input, Conor Dooley
In-Reply-To: <20260605070923.3045073-1-alexander.sverdlin@gmail.com>
Baijie HelperBoard A133 is a development board around their A133 Core
board. Introduce a compatible for both the Core and the development
boards.
Acked-by: Conor Dooley <conor.dooley@microchip.com>
Signed-off-by: Alexander Sverdlin <alexander.sverdlin@gmail.com>
---
Changelog:
v4:
- renamed "Baijie Helper A133" -> "Baijie A133 HelperBoard"
- renamed "baijie,helper-a133" -> "baijie,helperboard-a133"
v3:
- no separate section for "core" .dtsi
v2:
- introduced baijie,helper-a133-core compatible for the Core (SoM) board
Documentation/devicetree/bindings/arm/sunxi.yaml | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/Documentation/devicetree/bindings/arm/sunxi.yaml b/Documentation/devicetree/bindings/arm/sunxi.yaml
index e6443c266fa1..82dd58b95f8a 100644
--- a/Documentation/devicetree/bindings/arm/sunxi.yaml
+++ b/Documentation/devicetree/bindings/arm/sunxi.yaml
@@ -96,6 +96,12 @@ properties:
- const: allwinner,ba10-tvbox
- const: allwinner,sun4i-a10
+ - description: Baijie A133 HelperBoard
+ items:
+ - const: baijie,helperboard-a133
+ - const: baijie,helperboard-a133-core
+ - const: allwinner,sun50i-a100
+
- description: BananaPi
items:
- const: lemaker,bananapi
--
2.54.0
^ permalink raw reply related
* [PATCH v4 0/7] Add support for Baijie Helper A133 board
From: Alexander Sverdlin @ 2026-06-05 7:09 UTC (permalink / raw)
To: linux-arm-kernel, linux-sunxi
Cc: Alexander Sverdlin, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Chen-Yu Tsai, Jernej Skrabec, Samuel Holland,
Hans de Goede, Dmitry Torokhov, Andre Przywara, Jun Yan,
Lukas Schmid, J. Neuschäfer, Eric Biggers, Michal Simek,
Luca Weiss, Sven Peter, Maxime Ripard, devicetree, linux-kernel,
linux-input
Baijie Helper A133 board is a development board around Baijie A133 Core
SBC. Features:
- 1/2/4GiB LPDDR4 DRAM
- 8/16/32GiB eMMC
- AXP707 PMIC
- USB-C OTG port in peripheral mode (via onboard hub)
- 2 USB 2.0 ports
- MicroSD slot and on-board eMMC module
- Gigabit Ethernet
- Bluetooth
- WiFi
Add initial support for both the Helper and Core boards, including UART,
PMU, eMMC, USB, Ethernet, LRADC-connected buttons.
UART1 can only be used for Bluetooth module, but BT-WiFi combo Allwinner
AW869A chip has not mainline driver currently.
Link: https://szbaijie.com/index/product/product_detail.html?product_id=23&language=en
Changelog:
v4:
- reserve RAM for ATF
- sun4i-lradc-keys: Add A100/A133 compatible
- dt-bindings: renamed "Baijie Helper A133" -> "Baijie A133 HelperBoard"
- dt-bindings: renamed "baijie,helper-a133" -> "baijie,helperboard-a133"
- dt-bindings: introduced allwinner,sun50i-a100-lradc
- reserve RAM for ATF
- renamed "sun50i-a133-baijie-helper.dtb" -> "sun50i-a133-helperboard.dtb"
- added "model" property into root of sun50i-a133-helperboard-core.dtsi
- added "cap-mmc-highspeed" and "max-frequency" into &mmc2
- added "x-powers,drive-vbus-en" and "*-supply" into &axp803
- dropped all "regulator-enable-ramp-delay" properties
- replaced ®_dcdc3 with a "polyphased" comment
- exact DRAM voltage in ®_dcdc5
- disabled ®_dcdc6 to avoid "[ 31.710641] dcdc6: disabling"
- added ®_vdd5v "root" regulator
- added "disable-wp" into &mmc0
- commented &usb_otg
- assigned usb1_vbus-supply in &usbphy
v3:
- added lradc node to sun50i-a100.dtsi
- enabled LRADC driver in arm64 defconfig
- added my copyrights into the newly introduced DTs
- all DT nodes sorted alphabetically
- all always-on regulators commented/propetly named
- all regulators got proper voltages (not default ranges)
- ADC-sensed buttons K1..K5 added
- re-labelled "eth_phy" -> "rgmii_phy"
- usbphy 0 switched from host into peripheral mode (downstream from an
onboard hub)
- typo sun50i-a133-baije-core.dtsi -> sun50i-a133-baijie-core.dtsi
- https://lore.kernel.org/all/20260517234134.2737320-1-alexander.sverdlin@gmail.com/
v2:
- introduced baijie,helper-a133-core compatible for the Core (SoM) board
- https://lore.kernel.org/all/20260510201644.4143710-1-alexander.sverdlin@gmail.com/
v1:
- https://lore.kernel.org/all/20260503191842.2736130-1-alexander.sverdlin@gmail.com/
Alexander Sverdlin (7):
arm64: defconfig: Enable Allwinner LRADC input driver
dt-bindings: vendor-prefixes: Add Shenzhen Baijie Technology Co., Ltd.
dt-bindings: arm: sunxi: Add Baijie HelperBoard A133 compatible
dt-bindings: input: sun4i-lradc-keys: Add A100/A133 compatible
arm64: dts: allwinner: a100: Add LRADC node
arm64: dts: allwinner: a100: reserve RAM for ATF
arm64: dts: allwinner: A133: add support for Baijie Helper A133 board
.../devicetree/bindings/arm/sunxi.yaml | 6 +
.../input/allwinner,sun4i-a10-lradc-keys.yaml | 1 +
.../devicetree/bindings/vendor-prefixes.yaml | 2 +
arch/arm64/boot/dts/allwinner/Makefile | 1 +
.../arm64/boot/dts/allwinner/sun50i-a100.dtsi | 25 +++
.../sun50i-a133-helperboard-core.dtsi | 197 ++++++++++++++++++
.../dts/allwinner/sun50i-a133-helperboard.dts | 148 +++++++++++++
arch/arm64/configs/defconfig | 1 +
8 files changed, 381 insertions(+)
create mode 100644 arch/arm64/boot/dts/allwinner/sun50i-a133-helperboard-core.dtsi
create mode 100644 arch/arm64/boot/dts/allwinner/sun50i-a133-helperboard.dts
--
2.54.0
^ permalink raw reply
* Re: [PATCH v01] mailbox/pcc.c: add query channel function
From: kernel test robot @ 2026-06-05 6:54 UTC (permalink / raw)
To: Adam Young, Sudeep Holla, Jassi Brar, Rafael J. Wysocki,
Saket Dumbre, Len Brown
Cc: llvm, oe-kbuild-all, linux-kernel, linux-hwmon, linux-acpi,
Andi Shyti, Guenter Roeck, Huisong Li, MyungJoo Ham,
Kyungmin Park, Chanwoo Choi, linux-arm-kernel
In-Reply-To: <20260604203749.168752-1-admiyo@os.amperecomputing.com>
Hi Adam,
kernel test robot noticed the following build warnings:
[auto build test WARNING on jassibrar-mailbox/for-next]
[also build test WARNING on rafael-pm/linux-next rafael-pm/bleeding-edge soc/for-next linus/master v6.16-rc1 next-20260604]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]
url: https://github.com/intel-lab-lkp/linux/commits/Adam-Young/mailbox-pcc-c-add-query-channel-function/20260605-044323
base: https://git.kernel.org/pub/scm/linux/kernel/git/jassibrar/mailbox.git for-next
patch link: https://lore.kernel.org/r/20260604203749.168752-1-admiyo%40os.amperecomputing.com
patch subject: [PATCH v01] mailbox/pcc.c: add query channel function
config: x86_64-kexec (https://download.01.org/0day-ci/archive/20260605/202606050825.2uv1FZrY-lkp@intel.com/config)
compiler: clang version 22.0.0git (https://github.com/llvm/llvm-project f43d6834093b19baf79beda8c0337ab020ac5f17)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20260605/202606050825.2uv1FZrY-lkp@intel.com/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202606050825.2uv1FZrY-lkp@intel.com/
All warnings (new ones prefixed by >>):
>> Warning: drivers/mailbox/pcc.c:358 function parameter 'q_chan' not described in 'pcc_mbox_query_channel'
>> Warning: drivers/mailbox/pcc.c:358 function parameter 'subspace_id' not described in 'pcc_mbox_query_channel'
>> Warning: drivers/mailbox/pcc.c:358 function parameter 'q_chan' not described in 'pcc_mbox_query_channel'
>> Warning: drivers/mailbox/pcc.c:358 function parameter 'subspace_id' not described in 'pcc_mbox_query_channel'
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox