* Re: [patch 09/38] iommu/vt-d: Use sched_clock() instead of get_cycles()
From: Thomas Gleixner @ 2026-04-10 15:14 UTC (permalink / raw)
To: Baolu Lu, LKML
Cc: baolu.lu, x86, iommu, Arnd Bergmann, Michael Grzeschik, netdev,
linux-wireless, Herbert Xu, linux-crypto, Vlastimil Babka,
linux-mm, David Woodhouse, Bernie Thompson, linux-fbdev,
Theodore Tso, linux-ext4, Andrew Morton, Uladzislau Rezki,
Marco Elver, Dmitry Vyukov, kasan-dev, Andrey Ryabinin,
Thomas Sailer, linux-hams, Jason A. Donenfeld, Richard Henderson,
linux-alpha, Russell King, linux-arm-kernel, Catalin Marinas,
Huacai Chen, loongarch, Geert Uytterhoeven, linux-m68k,
Dinh Nguyen, Jonas Bonn, linux-openrisc, Helge Deller,
linux-parisc, Michael Ellerman, linuxppc-dev, Paul Walmsley,
linux-riscv, Heiko Carstens, linux-s390, David S. Miller,
sparclinux
In-Reply-To: <9db9515b-08e8-47bd-aced-206ac183195a@linux.intel.com>
On Fri, Apr 10 2026 at 21:45, Baolu Lu wrote:
> On 4/10/2026 8:19 PM, Thomas Gleixner wrote:
>> Calculating the timeout from get_cycles() is a historical leftover without
>> any functional requirement.
>>
>> Use ktime_get() instead.
>
> The subject line says "Use sched_clock() ...", but the implementation
> actually uses ktime_get(). Is it a typo or anything I misunderstood?
Indeed. Leftover from an earlier version.
Thanks,
tglx
^ permalink raw reply
* Re: [PATCH v13 46/48] KVM: arm64: Expose KVM_ARM_VCPU_REC to user space
From: Steven Price @ 2026-04-10 15:12 UTC (permalink / raw)
To: Suzuki K Poulose, kvm, kvmarm
Cc: Catalin Marinas, Marc Zyngier, Will Deacon, James Morse,
Oliver Upton, Zenghui Yu, linux-arm-kernel, linux-kernel,
Joey Gouly, Alexandru Elisei, Christoffer Dall, Fuad Tabba,
linux-coco, Ganapatrao Kulkarni, Gavin Shan, Shanker Donthineni,
Alper Gun, Aneesh Kumar K . V, Emi Kisanuki, Vishal Annapurve
In-Reply-To: <79564d59-032e-40c9-b4eb-f79f805b8238@arm.com>
On 19/03/2026 17:36, Suzuki K Poulose wrote:
> On 18/03/2026 15:54, Steven Price wrote:
>> Increment KVM_VCPU_MAX_FEATURES to expose the new capability to user
>> space.
>>
>> Signed-off-by: Steven Price <steven.price@arm.com>
>> Reviewed-by: Gavin Shan <gshan@redhat.com>
>
> Not needed any more as we don't need the VCPU feature.
This patch caused so much bother with rebasing in the past, I'd
completely forgotten it isn't actually needed! Thanks for spotting!
Thanks,
Steve
> Cheers
> Suzuki
>
>
>
>> ---
>> Changes since v8:
>> * Since NV is now merged and enabled, this no longer conflicts with it.
>> ---
>> arch/arm64/include/asm/kvm_host.h | 2 +-
>> 1 file changed, 1 insertion(+), 1 deletion(-)
>>
>> diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/
>> asm/kvm_host.h
>> index 1d5fb001408c..b02f97de4436 100644
>> --- a/arch/arm64/include/asm/kvm_host.h
>> +++ b/arch/arm64/include/asm/kvm_host.h
>> @@ -40,7 +40,7 @@
>> #define KVM_MAX_VCPUS VGIC_V3_MAX_CPUS
>> -#define KVM_VCPU_MAX_FEATURES 9
>> +#define KVM_VCPU_MAX_FEATURES 10
>> #define KVM_VCPU_VALID_FEATURES (BIT(KVM_VCPU_MAX_FEATURES) - 1)
>> #define KVM_REQ_SLEEP \
>
^ permalink raw reply
* Re: [PATCH v13 37/48] arm64: RMI: Prevent Device mappings for Realms
From: Steven Price @ 2026-04-10 15:12 UTC (permalink / raw)
To: Joey Gouly
Cc: kvm, kvmarm, Catalin Marinas, Marc Zyngier, Will Deacon,
James Morse, Oliver Upton, Suzuki K Poulose, Zenghui Yu,
linux-arm-kernel, linux-kernel, Alexandru Elisei,
Christoffer Dall, Fuad Tabba, linux-coco, Ganapatrao Kulkarni,
Gavin Shan, Shanker Donthineni, Alper Gun, Aneesh Kumar K . V,
Emi Kisanuki, Vishal Annapurve
In-Reply-To: <20260319102734.GC3942350@e124191.cambridge.arm.com>
On 19/03/2026 10:27, Joey Gouly wrote:
> On Wed, Mar 18, 2026 at 03:54:01PM +0000, Steven Price wrote:
>> Physical device assignment is not supported by RMM v1.0, so it
>
> But we're targetting 2.0 now!
Whoops ;) In my head it's still "in the future" but I guess the "future"
is now!
I'll update this to say:
Physical device assignment is not yet supported. RMM v2.0 does add the
relevant APIs, but device assignment is a big topic so will be handled
in a future patch series. For now prevent device mappings when the guest
is a realm.
Thanks,
Steve
> I guess just change it to something about device support being a later feature.
>
> Thanks,
> Joey
>
>> doesn't make much sense to allow device mappings within the realm.
>> Prevent them when the guest is a realm.
>>
>> Signed-off-by: Steven Price <steven.price@arm.com>
>> ---
>> Changes from v6:
>> * Fix the check in user_mem_abort() to prevent all pages that are not
>> guest_memfd() from being mapped into the protected half of the IPA.
>> Changes from v5:
>> * Also prevent accesses in user_mem_abort()
>> ---
>> arch/arm64/kvm/mmu.c | 13 +++++++++++++
>> 1 file changed, 13 insertions(+)
>>
>> diff --git a/arch/arm64/kvm/mmu.c b/arch/arm64/kvm/mmu.c
>> index ad1300f366df..7d7caab8f573 100644
>> --- a/arch/arm64/kvm/mmu.c
>> +++ b/arch/arm64/kvm/mmu.c
>> @@ -1222,6 +1222,10 @@ int kvm_phys_addr_ioremap(struct kvm *kvm, phys_addr_t guest_ipa,
>> if (is_protected_kvm_enabled())
>> return -EPERM;
>>
>> + /* We don't support mapping special pages into a Realm */
>> + if (kvm_is_realm(kvm))
>> + return -EPERM;
>> +
>> size += offset_in_page(guest_ipa);
>> guest_ipa &= PAGE_MASK;
>>
>> @@ -1965,6 +1969,15 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa,
>> return 1;
>> }
>>
>> + /*
>> + * For now we shouldn't be hitting protected addresses because they are
>> + * handled in private_memslot_fault(). In the future this check may be
>> + * relaxed to support e.g. protected devices.
>> + */
>> + if (vcpu_is_rec(vcpu) &&
>> + kvm_gpa_from_fault(kvm, fault_ipa) == fault_ipa)
>> + return -EINVAL;
>> +
>> if (nested)
>> adjust_nested_fault_perms(nested, &prot, &writable);
>>
>> --
>> 2.43.0
>>
>>
^ permalink raw reply
* Re: [PATCH v13 32/48] arm64: Don't expose stolen time for realm guests
From: Steven Price @ 2026-04-10 15:12 UTC (permalink / raw)
To: Suzuki K Poulose, kvm, kvmarm
Cc: Catalin Marinas, Marc Zyngier, Will Deacon, James Morse,
Oliver Upton, Zenghui Yu, linux-arm-kernel, linux-kernel,
Joey Gouly, Alexandru Elisei, Christoffer Dall, Fuad Tabba,
linux-coco, Ganapatrao Kulkarni, Gavin Shan, Shanker Donthineni,
Alper Gun, Aneesh Kumar K . V, Emi Kisanuki, Vishal Annapurve
In-Reply-To: <4a2ab5b0-dec6-4ee2-8790-f27c2501f653@arm.com>
On 30/03/2026 11:52, Suzuki K Poulose wrote:
> On 18/03/2026 15:53, Steven Price wrote:
>> It doesn't make much sense as a realm guest wouldn't want to trust the
>> host. It will also need some extra work to ensure that KVM will only
>> attempt to write into a shared memory region. So for now just disable
>> it.
>>
>> Reviewed-by: Suzuki K Poulose <suzuki.poulose@arm.com>
>> Reviewed-by: Gavin Shan <gshan@redhat.com>
>> Signed-off-by: Steven Price <steven.price@arm.com>
>> ---
>> Changes since v7:
>> * Update the documentation to add a note about stolen time being
>> unavailable in a realm.
>> ---
>> Documentation/virt/kvm/api.rst | 3 +++
>> arch/arm64/kvm/arm.c | 5 ++++-
>> 2 files changed, 7 insertions(+), 1 deletion(-)
>>
>> diff --git a/Documentation/virt/kvm/api.rst b/Documentation/virt/kvm/
>> api.rst
>> index bc180c853faf..70911fe6d435 100644
>> --- a/Documentation/virt/kvm/api.rst
>> +++ b/Documentation/virt/kvm/api.rst
>> @@ -9240,6 +9240,9 @@ is supported, than the other should as well and
>> vice versa. For arm64
>> see Documentation/virt/kvm/devices/vcpu.rst "KVM_ARM_VCPU_PVTIME_CTRL".
>> For x86 see Documentation/virt/kvm/x86/msr.rst "MSR_KVM_STEAL_TIME".
>> +Note that steal time accounting is not available when a guest is
>> running
>> +within a Arm CCA realm (machine type KVM_VM_TYPE_ARM_REALM).
>> +
>> 8.25 KVM_CAP_S390_DIAG318
>> -------------------------
>> diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
>> index 61182eb0cf70..7d92ddb06460 100644
>> --- a/arch/arm64/kvm/arm.c
>> +++ b/arch/arm64/kvm/arm.c
>> @@ -469,7 +469,10 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm,
>> long ext)
>> r = system_supports_mte();
>> break;
>> case KVM_CAP_STEAL_TIME:
>> - r = kvm_arm_pvtime_supported();
>> + if (kvm_is_realm(kvm))
>> + r = 0;
>> + else
>> + r = kvm_arm_pvtime_supported();
>
> Could this be handled in kvm_realm_ext_allowed() ?
Indeed it is already handled there. I'm not sure how I missed that, but
this patch is completely unnecessary now. Stolen time was an extension
that I knew about (having added it in the first place) and needed
disabling because it's implemented with the assumption that the host can
write into the guest.
In theory with some extra work it could be supported in a realm guest,
but it requires some extra plumbing to ensure the structures end up in
shared memory. My intention is that this can be revisited once the basic
CCA support is in.
Thanks,
Steve
> Suzuki
>
>
>> break;
>> case KVM_CAP_ARM_EL1_32BIT:
>> r = cpus_have_final_cap(ARM64_HAS_32BIT_EL1);
>
^ permalink raw reply
* Re: [PATCH v13 24/48] arm64: RMI: Allow populating initial contents
From: Steven Price @ 2026-04-10 15:12 UTC (permalink / raw)
To: Suzuki K Poulose, kvm, kvmarm
Cc: Catalin Marinas, Marc Zyngier, Will Deacon, James Morse,
Oliver Upton, Zenghui Yu, linux-arm-kernel, linux-kernel,
Joey Gouly, Alexandru Elisei, Christoffer Dall, Fuad Tabba,
linux-coco, Ganapatrao Kulkarni, Gavin Shan, Shanker Donthineni,
Alper Gun, Aneesh Kumar K . V, Emi Kisanuki, Vishal Annapurve
In-Reply-To: <7ab3dcd2-23b9-45a6-84ef-9617c4614c0a@arm.com>
On 23/03/2026 11:32, Suzuki K Poulose wrote:
> On 18/03/2026 15:53, Steven Price wrote:
>> The VMM needs to populate the realm with some data before starting (e.g.
>> a kernel and initrd). This is measured by the RMM and used as part of
>> the attestation later on.
>>
>> Signed-off-by: Steven Price <steven.price@arm.com>
>> ---
>> Changes since v12:
>> * The ioctl now updates the structure with the amount populated rather
>> than returning this through the ioctl return code.
>> * Use the new RMM v2.0 range based RMI calls.
>> * Adapt to upstream changes in kvm_gmem_populate().
>> Changes since v11:
>> * The multiplex CAP is gone and there's a new ioctl which makes use of
>> the generic kvm_gmem_populate() functionality.
>> Changes since v7:
>> * Improve the error codes.
>> * Other minor changes from review.
>> Changes since v6:
>> * Handle host potentially having a larger page size than the RMM
>> granule.
>> * Drop historic "par" (protected address range) from
>> populate_par_region() - it doesn't exist within the current
>> architecture.
>> * Add a cond_resched() call in kvm_populate_realm().
>> Changes since v5:
>> * Refactor to use PFNs rather than tracking struct page in
>> realm_create_protected_data_page().
>> * Pull changes from a later patch (in the v5 series) for accessing
>> pages from a guest memfd.
>> * Do the populate in chunks to avoid holding locks for too long and
>> triggering RCU stall warnings.
>> ---
>> arch/arm64/include/asm/kvm_rmi.h | 4 ++
>> arch/arm64/kvm/Kconfig | 1 +
>> arch/arm64/kvm/arm.c | 13 ++++
>> arch/arm64/kvm/rmi.c | 111 +++++++++++++++++++++++++++++++
>> 4 files changed, 129 insertions(+)
>>
>> diff --git a/arch/arm64/include/asm/kvm_rmi.h b/arch/arm64/include/
>> asm/kvm_rmi.h
>> index 46b0cbe6c202..bf663bb240c4 100644
>> --- a/arch/arm64/include/asm/kvm_rmi.h
>> +++ b/arch/arm64/include/asm/kvm_rmi.h
>> @@ -96,6 +96,10 @@ int kvm_rec_enter(struct kvm_vcpu *vcpu);
>> int kvm_rec_pre_enter(struct kvm_vcpu *vcpu);
>> int handle_rec_exit(struct kvm_vcpu *vcpu, int rec_run_status);
>> +struct kvm_arm_rmi_populate;
>> +
>> +int kvm_arm_rmi_populate(struct kvm *kvm,
>> + struct kvm_arm_rmi_populate *arg);
>> void kvm_realm_unmap_range(struct kvm *kvm,
>> unsigned long ipa,
>> unsigned long size,
>> diff --git a/arch/arm64/kvm/Kconfig b/arch/arm64/kvm/Kconfig
>> index 1cac6dfc0972..b495dfd3a8b4 100644
>> --- a/arch/arm64/kvm/Kconfig
>> +++ b/arch/arm64/kvm/Kconfig
>> @@ -39,6 +39,7 @@ menuconfig KVM
>> select GUEST_PERF_EVENTS if PERF_EVENTS
>> select KVM_GUEST_MEMFD
>> select KVM_GENERIC_MEMORY_ATTRIBUTES
>> + select HAVE_KVM_ARCH_GMEM_POPULATE
>> help
>> Support hosting virtualized guest machines.
>> diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
>> index badb94b398bc..43d05da7e694 100644
>> --- a/arch/arm64/kvm/arm.c
>> +++ b/arch/arm64/kvm/arm.c
>> @@ -2089,6 +2089,19 @@ int kvm_arch_vm_ioctl(struct file *filp,
>> unsigned int ioctl, unsigned long arg)
>> return -EFAULT;
>> return kvm_vm_ioctl_get_reg_writable_masks(kvm, &range);
>> }
>> + case KVM_ARM_RMI_POPULATE: {
>> + struct kvm_arm_rmi_populate req;
>> + int ret;
>> +
>> + if (!kvm_is_realm(kvm))
>> + return -ENXIO;
>> + if (copy_from_user(&req, argp, sizeof(req)))
>> + return -EFAULT;
>> + ret = kvm_arm_rmi_populate(kvm, &req);
>> + if (copy_to_user(argp, &req, sizeof(req)))
>> + return -EFAULT;
>> + return ret;
>> + }
>> default:
>> return -EINVAL;
>> }
>> diff --git a/arch/arm64/kvm/rmi.c b/arch/arm64/kvm/rmi.c
>> index 13eed6f0b9eb..b48f4e12e4e0 100644
>> --- a/arch/arm64/kvm/rmi.c
>> +++ b/arch/arm64/kvm/rmi.c
>> @@ -718,6 +718,80 @@ void kvm_realm_unmap_range(struct kvm *kvm,
>> unsigned long start,
>> realm_unmap_private_range(kvm, start, end, may_block);
>> }
>> +static int realm_create_protected_data_page(struct kvm *kvm,
>
> minor nit: To align with the RMM ABI, could we rename this to :
>
> realm_data_map_init() ?
Makes sense - I have to admit there is a bit of cruft in some of the
names because the spec keeps changing ;)
>> + unsigned long ipa,
>> + kvm_pfn_t dst_pfn,
>> + kvm_pfn_t src_pfn,
>> + unsigned long flags)
>> +{
>> + struct realm *realm = &kvm->arch.realm;
>> + phys_addr_t rd = virt_to_phys(realm->rd);
>> + phys_addr_t dst_phys, src_phys;
>> + int ret;
>> +
>> + dst_phys = __pfn_to_phys(dst_pfn);
>> + src_phys = __pfn_to_phys(src_pfn);
>> +
>> + if (delegate_page(dst_phys))
>> + return -ENXIO;
>> +
>> + ret = rmi_rtt_data_map_init(rd, dst_phys, ipa, src_phys, flags);
>> + if (RMI_RETURN_STATUS(ret) == RMI_ERROR_RTT) {
>> + /* Create missing RTTs and retry */
>> + int level = RMI_RETURN_INDEX(ret);
>> +
>> + KVM_BUG_ON(level == RMM_RTT_MAX_LEVEL, kvm);
>
> A buggy VMM can trigger this by calling RMI_POPULATE twice ? Should we
> return -ENXIO here rather ? The delegate_page() above could prevent
> normal cases, but is the VMM allowed to somehow trigger a "pfn" change
> backing the KVM ? Either way, this need not be Fatal ?
I believe KVM_BUG_ON is only fatal to the VM - it won't take down the
host (KVM_BUG_ON_DATA_CORRUPTION() is for that). AFAICT the
delegate_page() check should catch this case, but in the event that it
doesn't then this will kill the VM but otherwise recover.
Of course if it turns out there is a way of a VMM hitting this we might
need to tone down the error handling to something a bit quieter. But I
think it would also be good to get an understanding of how this can happen.
Thanks,
Steve
> Otherwise looks good to me.
>
> Suzuki
>
>
>> +
>> + ret = realm_create_rtt_levels(realm, ipa, level,
>> + RMM_RTT_MAX_LEVEL, NULL);
>> + if (!ret) {
>> + ret = rmi_rtt_data_map_init(rd, dst_phys, ipa, src_phys,
>> + flags);
>> + }
>> + }
>> +
>> + if (ret) {
>> + if (WARN_ON(undelegate_page(dst_phys))) {
>> + /* Undelegate failed, so we leak the page */
>> + get_page(pfn_to_page(dst_pfn));
>> + }
>> + }
>> +
>> + return ret;
>> +}
>> +
>> +static int populate_region_cb(struct kvm *kvm, gfn_t gfn, kvm_pfn_t pfn,
>> + struct page *src_page, void *opaque)
>> +{
>> + unsigned long data_flags = *(unsigned long *)opaque;
>> + phys_addr_t ipa = gfn_to_gpa(gfn);
>> +
>> + if (!src_page)
>> + return -EOPNOTSUPP;
>> +
>> + return realm_create_protected_data_page(kvm, ipa, pfn,
>> + page_to_pfn(src_page),
>> + data_flags);
>> +}
>> +
>> +static long populate_region(struct kvm *kvm,
>> + gfn_t base_gfn,
>> + unsigned long pages,
>> + u64 uaddr,
>> + unsigned long data_flags)
>> +{
>> + long ret = 0;
>> +
>> + mutex_lock(&kvm->slots_lock);
>> + mmap_read_lock(current->mm);
>> + ret = kvm_gmem_populate(kvm, base_gfn, u64_to_user_ptr(uaddr),
>> pages,
>> + populate_region_cb, &data_flags);
>> + mmap_read_unlock(current->mm);
>> + mutex_unlock(&kvm->slots_lock);
>> +
>> + return ret;
>> +}
>> +
>> enum ripas_action {
>> RIPAS_INIT,
>> RIPAS_SET,
>> @@ -815,6 +889,43 @@ static int realm_ensure_created(struct kvm *kvm)
>> return -ENXIO;
>> }
>> +int kvm_arm_rmi_populate(struct kvm *kvm,
>> + struct kvm_arm_rmi_populate *args)
>> +{
>> + unsigned long data_flags = 0;
>> + unsigned long ipa_start = args->base;
>> + unsigned long ipa_end = ipa_start + args->size;
>> + long pages_populated;
>> + int ret;
>> +
>> + if (args->reserved ||
>> + (args->flags & ~KVM_ARM_RMI_POPULATE_FLAGS_MEASURE) ||
>> + !IS_ALIGNED(ipa_start, PAGE_SIZE) ||
>> + !IS_ALIGNED(ipa_end, PAGE_SIZE) ||
>> + !IS_ALIGNED(args->source_uaddr, PAGE_SIZE))
>> + return -EINVAL;
>> +
>> + ret = realm_ensure_created(kvm);
>> + if (ret)
>> + return ret;
>> +
>> + if (args->flags & KVM_ARM_RMI_POPULATE_FLAGS_MEASURE)
>> + data_flags |= RMI_MEASURE_CONTENT;
>> +
>> + pages_populated = populate_region(kvm, gpa_to_gfn(ipa_start),
>> + args->size >> PAGE_SHIFT,
>> + args->source_uaddr, data_flags);
>> +
>> + if (pages_populated < 0)
>> + return pages_populated;
>> +
>> + args->size -= pages_populated << PAGE_SHIFT;
>> + args->source_uaddr += pages_populated << PAGE_SHIFT;
>> + args->base += pages_populated << PAGE_SHIFT;
>> +
>> + return 0;
>> +}
>> +
>> static void kvm_complete_ripas_change(struct kvm_vcpu *vcpu)
>> {
>> struct kvm *kvm = vcpu->kvm;
>
^ permalink raw reply
* Re: [PATCH v13 21/48] arm64: RMI: Handle RMI_EXIT_RIPAS_CHANGE
From: Steven Price @ 2026-04-10 15:12 UTC (permalink / raw)
To: Suzuki K Poulose, kvm, kvmarm
Cc: Catalin Marinas, Marc Zyngier, Will Deacon, James Morse,
Oliver Upton, Zenghui Yu, linux-arm-kernel, linux-kernel,
Joey Gouly, Alexandru Elisei, Christoffer Dall, Fuad Tabba,
linux-coco, Ganapatrao Kulkarni, Gavin Shan, Shanker Donthineni,
Alper Gun, Aneesh Kumar K . V, Emi Kisanuki, Vishal Annapurve
In-Reply-To: <59c83ace-c8be-4c71-99b6-cd5f085a3063@arm.com>
On 20/03/2026 11:15, Suzuki K Poulose wrote:
> Hi Steven
>
> On 18/03/2026 15:53, Steven Price wrote:
>> The guest can request that a region of it's protected address space is
>> switched between RIPAS_RAM and RIPAS_EMPTY (and back) using
>> RSI_IPA_STATE_SET. This causes a guest exit with the
>> RMI_EXIT_RIPAS_CHANGE code. We treat this as a request to convert a
>> protected region to unprotected (or back), exiting to the VMM to make
>> the necessary changes to the guest_memfd and memslot mappings. On the
>> next entry the RIPAS changes are committed by making RMI_RTT_SET_RIPAS
>> calls.
>>
>> The VMM may wish to reject the RIPAS change requested by the guest. For
>> now it can only do this by no longer scheduling the VCPU as we don't
>> currently have a usecase for returning that rejection to the guest, but
>> by postponing the RMI_RTT_SET_RIPAS changes to entry we leave the door
>> open for adding a new ioctl in the future for this purpose.
>
> I have been thinking about this. Today we do a KVM_MEMORY_FAULT_EXIT
> to the VMM to handle the request. The other option is to make this
> a KVM_EXIT_HYPERCALL with SMC_RSI_SET_RIPAS. But this would leak RSI
> implementation to the VMM. The advantage is that the VMM can provide
> a clear response RSI_ACCEPT vs RSI_REJECT (including accepting a partial
> range) and KVM can satisfy the RMI_RTT_SET_RIPAS.
Faking up hypercalls based on a very narrow interface seems like a bad
API design. The guest is of course perfectly allowed to have another
interface directly to the VMM to communicate intent.
> We may end up doing something similar for Device assignment too, where
> the VMM gets a chance to reject any inconsistent device mappings.
>
> Like you mentioned, the VMM can stop the Realm today as an alternate
> approach.
The intention here is that we start with a very basic interface and can
then extend it when we work out how to handle rejection. The ordering in
the kernel is explicitly to allow that extension. I get the impression
that device assignment has a much better justification for handling the
reject flow so it's probably best to leave that until device assignment
is implemented.
Thanks,
Steve
^ permalink raw reply
* Re: [PATCH v13 20/48] arm64: RMI: Handle realm enter/exit
From: Steven Price @ 2026-04-10 15:11 UTC (permalink / raw)
To: Suzuki K Poulose, kvm, kvmarm
Cc: Catalin Marinas, Marc Zyngier, Will Deacon, James Morse,
Oliver Upton, Zenghui Yu, linux-arm-kernel, linux-kernel,
Joey Gouly, Alexandru Elisei, Christoffer Dall, Fuad Tabba,
linux-coco, Ganapatrao Kulkarni, Gavin Shan, Shanker Donthineni,
Alper Gun, Aneesh Kumar K . V, Emi Kisanuki, Vishal Annapurve
In-Reply-To: <c4e30ad1-6fbe-448f-a9fe-6a2480581082@arm.com>
On 23/03/2026 10:03, Suzuki K Poulose wrote:
> On 20/03/2026 16:32, Steven Price wrote:
>> On 20/03/2026 14:08, Suzuki K Poulose wrote:
>>> On 18/03/2026 15:53, Steven Price wrote:
[...]
>>>> +int noinstr kvm_rec_enter(struct kvm_vcpu *vcpu)
>>>> +{
>>>> + struct realm_rec *rec = &vcpu->arch.rec;
>>>> + int ret;
>>>> +
>>>> + guest_state_enter_irqoff();
>>>> + ret = rmi_rec_enter(virt_to_phys(rec->rec_page),
>>>> + virt_to_phys(rec->run));
>>>
>>> In the normal VM case, we try to fixup some of the exits (e.g., GIC
>>> CPUIF register accesses) which may be applicable to Realms. Do we
>>> need such fixups here ? Given the cost of world switch, it is
>>> debatable whether it matters or not.
>>
>> I'm not really sure what you are referring to here. Can you point me at
>> the normal VM case? This function is the equivalent of
>> kvm_arm_vcpu_enter_exit().
>
> This happens via fixup_guest_exit() in either vhe/nvhe cases. The VGIC
> registers are emulated in the fast path for normal VMs (when trapping is
> enabled)
Ah, I see what you mean. Yes the VGIC emulation in theory could be
shortcut and speeded up slightly. I'd prefer to leave this sort of pure
optimisation until the basic support is merged to keep the size of the
series (vaguely) under control.
I think it would also be worth doing some benchmarking on a real
platform to see whether it really makes a meaningful difference (or
whether we need to push for an architectural change moving more
processing into the RMM).
Thanks,
Steve
^ permalink raw reply
* Re: [PATCH v13 15/48] arm64: RMI: RTT tear down
From: Steven Price @ 2026-04-10 15:11 UTC (permalink / raw)
To: Wei-Lin Chang, kvm, kvmarm
Cc: 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, Gavin Shan,
Shanker Donthineni, Alper Gun, Aneesh Kumar K . V, Emi Kisanuki,
Vishal Annapurve
In-Reply-To: <5chegrtlkmet4n5u53wmjbpyflul2dy5o6lpevvxo3hycvyszx@3ogzwuvsbvr3>
On 21/03/2026 13:04, Wei-Lin Chang wrote:
> On Fri, Mar 20, 2026 at 04:12:48PM +0000, Steven Price wrote:
>> On 19/03/2026 17:35, Wei-Lin Chang wrote:
>>> On Wed, Mar 18, 2026 at 03:53:39PM +0000, Steven Price wrote:
>>>> The RMM owns the stage 2 page tables for a realm, and KVM must request
>>>> that the RMM creates/destroys entries as necessary. The physical pages
>>>> to store the page tables are delegated to the realm as required, and can
>>>> be undelegated when no longer used.
>>>>
>>>> Creating new RTTs is the easy part, tearing down is a little more
>>>> tricky. The result of realm_rtt_destroy() can be used to effectively
>>>> walk the tree and destroy the entries (undelegating pages that were
>>>> given to the realm).
>>>>
>>>> Signed-off-by: Steven Price <steven.price@arm.com>
>>>> ---
>>>> Changes since v12:
>>>> * Simplify some functions now we know RMM page size is the same as the
>>>> host's.
>>>> Changes since v11:
>>>> * Moved some code from earlier in the series to this one so that it's
>>>> added when it's first used.
>>>> Changes since v10:
>>>> * RME->RMI rename.
>>>> * Some code to handle freeing stage 2 PGD moved into this patch where
>>>> it belongs.
>>>> Changes since v9:
>>>> * Add a comment clarifying that root level RTTs are not destroyed until
>>>> after the RD is destroyed.
>>>> Changes since v8:
>>>> * Introduce free_rtt() wrapper which calls free_delegated_granule()
>>>> followed by kvm_account_pgtable_pages(). This makes it clear where an
>>>> RTT is being freed rather than just a delegated granule.
>>>> Changes since v6:
>>>> * Move rme_rtt_level_mapsize() and supporting defines from kvm_rme.h
>>>> into rme.c as they are only used in that file.
>>>> Changes since v5:
>>>> * Rename some RME_xxx defines to do with page sizes as RMM_xxx - they are
>>>> a property of the RMM specification not the RME architecture.
>>>> Changes since v2:
>>>> * Moved {alloc,free}_delegated_page() and ensure_spare_page() to a
>>>> later patch when they are actually used.
>>>> * Some simplifications now rmi_xxx() functions allow NULL as an output
>>>> parameter.
>>>> * Improved comments and code layout.
>>>> ---
>>>> arch/arm64/include/asm/kvm_rmi.h | 7 ++
>>>> arch/arm64/kvm/mmu.c | 15 +++-
>>>> arch/arm64/kvm/rmi.c | 145 +++++++++++++++++++++++++++++++
>>>> 3 files changed, 166 insertions(+), 1 deletion(-)
>>>>
>>>> diff --git a/arch/arm64/include/asm/kvm_rmi.h b/arch/arm64/include/asm/kvm_rmi.h
>>>> index 0ada525af18f..16a297f3091a 100644
>>>> --- a/arch/arm64/include/asm/kvm_rmi.h
>>>> +++ b/arch/arm64/include/asm/kvm_rmi.h
>>>> @@ -68,5 +68,12 @@ u32 kvm_realm_ipa_limit(void);
>>>>
>>>> int kvm_init_realm_vm(struct kvm *kvm);
>>>> void kvm_destroy_realm(struct kvm *kvm);
>>>> +void kvm_realm_destroy_rtts(struct kvm *kvm);
>>>> +
>>>> +static inline bool kvm_realm_is_private_address(struct realm *realm,
>>>> + unsigned long addr)
>>>> +{
>>>> + return !(addr & BIT(realm->ia_bits - 1));
>>>> +}
>>>>
>>>> #endif /* __ASM_KVM_RMI_H */
>>>> diff --git a/arch/arm64/kvm/mmu.c b/arch/arm64/kvm/mmu.c
>>>> index 9dc242c3b9c8..41152abf55b2 100644
>>>> --- a/arch/arm64/kvm/mmu.c
>>>> +++ b/arch/arm64/kvm/mmu.c
>>>> @@ -1098,10 +1098,23 @@ void stage2_unmap_vm(struct kvm *kvm)
>>>> void kvm_free_stage2_pgd(struct kvm_s2_mmu *mmu)
>>>> {
>>>> struct kvm *kvm = kvm_s2_mmu_to_kvm(mmu);
>>>> - struct kvm_pgtable *pgt = NULL;
>>>> + struct kvm_pgtable *pgt;
>>>>
>>>> write_lock(&kvm->mmu_lock);
>>>> pgt = mmu->pgt;
>>>> + if (kvm_is_realm(kvm) &&
>>>> + (kvm_realm_state(kvm) != REALM_STATE_DEAD &&
>>>> + kvm_realm_state(kvm) != REALM_STATE_NONE)) {
>>>> + write_unlock(&kvm->mmu_lock);
>>>> + kvm_realm_destroy_rtts(kvm);
>>>> +
>>>> + /*
>>>> + * The PGD pages can be reclaimed only after the realm (RD) is
>>>> + * destroyed. We call this again from kvm_destroy_realm() after
>>>> + * the RD is destroyed.
>>>> + */
>>>> + return;
>>>> + }
>>>
>>> Hi,
>>>
>>> I see that kvm_free_stage2_pgd() will be called twice:
>>>
>>> kvm_destroy_vm()
>>> mmu_notifier_unregister()
>>> kvm_mmu_notifier_release()
>>> kvm_flush_shadow_all()
>>> kvm_arch_flush_shadow_all()
>>> kvm_uninit_stage2_mmu()
>>> kvm_free_stage2_pgd()
>>> kvm_arch_destroy_vm()
>>> kvm_destroy_realm()
>>> kvm_free_stage2_pgd()
>>>
>>> At the first call the realm state is REALM_STATE_ACTIVE, at the second
>>> it is REALM_STATE_DEAD. Reading the comment added to
>>> kvm_free_stage2_pgd() here, does it mean this function is called twice
>>> on purpose? If so do you think it's better to extract this and create
>>> another function instead, then use kvm_is_realm() to choose which to
>>> run? I think it is confusing to have this function run twice for a
>>> realm.
>>
>> So the issue here is that the RMM requires we do things in a different
>> order to a normal VM. For a realm the PGD cannot be destroyed until the
>> realm itself is destroyed - the RMM revent the host undelegating them.
>>
>> So the first call cannot actually do the free - this is the
>> REALM_STATE_ACTIVE case.
>>
>> In kvm_destroy_realm() we tear down the actual realm and undelegate the
>> granules. We then need to actually free the PGD - the "obvious" way of
>> doing that is calling kvm_free_stage2_pgd() as that handles the KVM
>> intricacies - e.g. updating the mmu object.
>>
>> I'm not sure how to structure the code better without causing
>> duplication - I don't want another copy of the cleanup from
>> kvm_free_stage2_pgd() in a CCA specific file because it will most likely
>> get out of sync with the normal VM case. There is a comment added
>> explaining "we call this again" which I hoped would make it less confusing.
>>
>
> Oh, I see, thanks for letting me know!
>
> During this I found in the first call of kvm_free_stage2_pgd() it's doing
> kvm_stage2_unmap_range() and kvm_realm_destroy_rtts(), but they are also
> called in kvm_destroy_realm(), is that intentional?
> If they can be called at kvm_destroy_realm() time, could we just not do
> kvm_free_stage2_pgd() in kvm_uninit_stage2_mmu() for realms?
> And if they should be called in kvm_free_stage2_pgd(), could we refactor
> it to something like:
> (just showing the idea, didn't try compiling or anything)
>
> diff --git a/arch/arm64/kvm/mmu.c b/arch/arm64/kvm/mmu.c
> index 7d7caab8f573..280d2bef8492 100644
> --- a/arch/arm64/kvm/mmu.c
> +++ b/arch/arm64/kvm/mmu.c
> @@ -1030,9 +1030,25 @@ int kvm_init_stage2_mmu(struct kvm *kvm, struct kvm_s2_mmu *mmu, unsigned long t
> return err;
> }
>
> +static void kvm_realm_uninit_stage2(struct kvm_s2_mmu *mmu)
> +{
> + struct kvm *kvm = kvm_s2_mmu_to_kvm(mmu);
> + struct realm *realm = &kvm->arch.realm;
> +
> + WARN_ON(kvm_realm_state(kvm) != REALM_STATE_ACTIVE);
> + write_lock(&kvm->mmu_lock);
> + kvm_stage2_unmap_range(mmu, 0, BIT(realm->ia_bits - 1), true);
> + write_unlock(&kvm->mmu_lock);
> + kvm_realm_destroy_rtts(kvm);
> +}
> +
> void kvm_uninit_stage2_mmu(struct kvm *kvm)
> {
> - kvm_free_stage2_pgd(&kvm->arch.mmu);
> + if (kvm_is_realm(kvm))
> + kvm_realm_uninit_stage2(&kvm->arch.mmu);
> + else
> + kvm_free_stage2_pgd(&kvm->arch.mmu);
> +
> kvm_mmu_free_memory_cache(&kvm->arch.mmu.split_page_cache);
> }
>
> @@ -1117,22 +1133,7 @@ void kvm_free_stage2_pgd(struct kvm_s2_mmu *mmu)
>
> write_lock(&kvm->mmu_lock);
> pgt = mmu->pgt;
> - if (kvm_is_realm(kvm) &&
> - (kvm_realm_state(kvm) != REALM_STATE_DEAD &&
> - kvm_realm_state(kvm) != REALM_STATE_NONE)) {
> - struct realm *realm = &kvm->arch.realm;
> -
> - kvm_stage2_unmap_range(mmu, 0, BIT(realm->ia_bits - 1), true);
> - write_unlock(&kvm->mmu_lock);
> - kvm_realm_destroy_rtts(kvm);
>
> - /*
> - * The PGD pages can be reclaimed only after the realm (RD) is
> - * destroyed. We call this again from kvm_destroy_realm() after
> - * the RD is destroyed.
> - */
> - return;
> - }
> if (pgt) {
> mmu->pgd_phys = 0;
> mmu->pgt = NULL;
>
> Sorry if I missed anything!
No I don't think you've missed anything, that actually does look nicer.
Thanks for the suggestion.
Thanks,
Steve
^ permalink raw reply
* Re: [PATCH v12 04/25] drm/bridge: Act on the DRM color format property
From: Nicolas Frattaroli @ 2026-04-10 14:21 UTC (permalink / raw)
To: Dmitry Baryshkov
Cc: Harry Wentland, Leo Li, Rodrigo Siqueira, Alex Deucher,
Christian König, David Airlie, Simona Vetter,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
Andrzej Hajda, Neil Armstrong, Robert Foss, Laurent Pinchart,
Jonas Karlman, Jernej Skrabec, Sandy Huang, Heiko Stübner,
Andy Yan, Jani Nikula, Rodrigo Vivi, Joonas Lahtinen,
Tvrtko Ursulin, Dmitry Baryshkov, Sascha Hauer, Rob Herring,
Jonathan Corbet, Shuah Khan, kernel, amd-gfx, dri-devel,
linux-kernel, linux-arm-kernel, linux-rockchip, intel-gfx,
intel-xe, linux-doc
In-Reply-To: <edeq6wxmwzvovfoo6pvih6dybwszf3tahg7nvqkjrw3qxllbfd@jwejh2sgb5eh>
On Friday, 10 April 2026 00:08:24 Central European Summer Time Dmitry Baryshkov wrote:
> On Thu, Apr 09, 2026 at 05:44:54PM +0200, Nicolas Frattaroli wrote:
> > The new DRM color format property allows userspace to request a specific
> > color format on a connector. In turn, this fills the connector state's
> > color_format member to switch color formats.
> >
> > Make drm_bridges consider the color_format set in the connector state
> > during the atomic bridge check. For bridges that represent HDMI bridges,
> > rely on whatever format the HDMI logic set. Reject any output bus
> > formats that do not correspond to the requested color format.
> >
> > Non-HDMI last bridges with DRM_CONNECTOR_COLOR_FORMAT_AUTO set will end
> > up choosing the first output format that functions to make a whole
> > recursive bridge chain format selection succeed.
> >
> > Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli@collabora.com>
> > ---
> > drivers/gpu/drm/drm_bridge.c | 89 +++++++++++++++++++++++++++++++++++++++++++-
> > 1 file changed, 88 insertions(+), 1 deletion(-)
> >
> > diff --git a/drivers/gpu/drm/drm_bridge.c b/drivers/gpu/drm/drm_bridge.c
> > index ba80bebb5685..7c1516864d96 100644
> > --- a/drivers/gpu/drm/drm_bridge.c
> > +++ b/drivers/gpu/drm/drm_bridge.c
> > @@ -1150,6 +1150,47 @@ static int select_bus_fmt_recursive(struct drm_bridge *first_bridge,
> > return ret;
> > }
> >
> > +static bool __pure bus_format_is_color_fmt(u32 bus_fmt, enum drm_connector_color_format fmt)
> > +{
> > + if (fmt == DRM_CONNECTOR_COLOR_FORMAT_AUTO)
> > + return true;
> > +
> > + switch (bus_fmt) {
> > + case MEDIA_BUS_FMT_FIXED:
> > + return true;
> > + case MEDIA_BUS_FMT_RGB888_1X24:
> > + case MEDIA_BUS_FMT_RGB101010_1X30:
> > + case MEDIA_BUS_FMT_RGB121212_1X36:
> > + case MEDIA_BUS_FMT_RGB161616_1X48:
> > + return fmt == DRM_CONNECTOR_COLOR_FORMAT_RGB444;
> > + case MEDIA_BUS_FMT_YUV8_1X24:
> > + case MEDIA_BUS_FMT_YUV10_1X30:
> > + case MEDIA_BUS_FMT_YUV12_1X36:
> > + case MEDIA_BUS_FMT_YUV16_1X48:
> > + return fmt == DRM_CONNECTOR_COLOR_FORMAT_YCBCR444;
> > + case MEDIA_BUS_FMT_UYVY8_1X16:
> > + case MEDIA_BUS_FMT_VYUY8_1X16:
> > + case MEDIA_BUS_FMT_YUYV8_1X16:
> > + case MEDIA_BUS_FMT_YVYU8_1X16:
> > + case MEDIA_BUS_FMT_UYVY10_1X20:
> > + case MEDIA_BUS_FMT_YUYV10_1X20:
> > + case MEDIA_BUS_FMT_VYUY10_1X20:
> > + case MEDIA_BUS_FMT_YVYU10_1X20:
> > + case MEDIA_BUS_FMT_UYVY12_1X24:
> > + case MEDIA_BUS_FMT_VYUY12_1X24:
> > + case MEDIA_BUS_FMT_YUYV12_1X24:
> > + case MEDIA_BUS_FMT_YVYU12_1X24:
> > + return fmt == DRM_CONNECTOR_COLOR_FORMAT_YCBCR422;
> > + case MEDIA_BUS_FMT_UYYVYY8_0_5X24:
> > + case MEDIA_BUS_FMT_UYYVYY10_0_5X30:
> > + case MEDIA_BUS_FMT_UYYVYY12_0_5X36:
> > + case MEDIA_BUS_FMT_UYYVYY16_0_5X48:
> > + return fmt == DRM_CONNECTOR_COLOR_FORMAT_YCBCR420;
> > + default:
> > + return false;
> > + }
> > +}
> > +
> > /*
> > * This function is called by &drm_atomic_bridge_chain_check() just before
> > * calling &drm_bridge_funcs.atomic_check() on all elements of the chain.
> > @@ -1193,6 +1234,7 @@ drm_atomic_bridge_chain_select_bus_fmts(struct drm_bridge *bridge,
> > struct drm_encoder *encoder = bridge->encoder;
> > struct drm_bridge_state *last_bridge_state;
> > unsigned int i, num_out_bus_fmts = 0;
> > + enum drm_connector_color_format fmt;
> > u32 *out_bus_fmts;
> > int ret = 0;
> >
> > @@ -1234,13 +1276,58 @@ drm_atomic_bridge_chain_select_bus_fmts(struct drm_bridge *bridge,
> > out_bus_fmts[0] = MEDIA_BUS_FMT_FIXED;
> > }
> >
> > + /*
> > + * On HDMI connectors, use the output format chosen by whatever does the
> > + * HDMI logic. For everyone else, just trust that the bridge out_bus_fmts
> > + * are sorted by preference for %DRM_CONNECTOR_COLOR_FORMAT_AUTO, as
> > + * bus_format_is_color_fmt() always returns true for AUTO.
> > + */
> > + if (last_bridge->type == DRM_MODE_CONNECTOR_HDMIA) {
>
> I still think this is misplaced (and misidentified). Consider HDMI
> bridge being routed to the DVI-D connector. The last bridge would have
> different type, but the HDMI-specific logic must still be applied. The
> bridge must use RGB444, but it must be handled in a generic way.
Thanks for the review. I was hoping that an HDMI bridge chain going to
a DVI connector would be a DRM_MODE_CONNECTOR_HDMIB thing, but apparently
not. I also don't know however how doing this in the drm bridge connector
helps us here. I guess we'd call into a drm_bridge_connector specific
function with the connector format and connector, and get an output
format in return, and said function checks that if any bridge in the
bridge connector is HDMI it uses the HDMI logic? That would conflict
with the following case from what I understand:
> Or other way around, a DVI bridge being routed through the HDMI
> connector (thinking about PandaBoard here). The combo should not go
> through the HDMI-specific color format selection although the last
> bridge in the chanin is the HDMI-A bridge.
In that case, wouldn't the recursive bridge bus format selection
take care of this? I assume the DVI bridge will only allow RGB444,
and one of the bridges that follow it is an HDMI bridge for the
HDMI connector that's physically on the board.
In such a case, if the HDMI state helpers came up with something
other than RGB444, the select_bus_fmt_recursive below would fail
as expected, since it won't be able to find an output that
satisfies the constraints given by the DVI bridge.
> I think all these cases should be handled by the connector, which knows
> if there is an OP_HDMI bridge in the chain or not.
Kind regards,
Nicolas Frattaroli
> > + drm_dbg_kms(last_bridge->dev,
> > + "HDMI bridge requests format %s\n",
> > + drm_hdmi_connector_get_output_format_name(
> > + conn_state->hdmi.output_format));
> > + switch (conn_state->hdmi.output_format) {
> > + case DRM_OUTPUT_COLOR_FORMAT_RGB444:
> > + fmt = DRM_CONNECTOR_COLOR_FORMAT_RGB444;
> > + break;
> > + case DRM_OUTPUT_COLOR_FORMAT_YCBCR444:
> > + fmt = DRM_CONNECTOR_COLOR_FORMAT_YCBCR444;
> > + break;
> > + case DRM_OUTPUT_COLOR_FORMAT_YCBCR422:
> > + fmt = DRM_CONNECTOR_COLOR_FORMAT_YCBCR422;
> > + break;
> > + case DRM_OUTPUT_COLOR_FORMAT_YCBCR420:
> > + fmt = DRM_CONNECTOR_COLOR_FORMAT_YCBCR420;
> > + break;
> > + default:
> > + ret = -EINVAL;
> > + goto out_free_bus_fmts;
> > + }
> > + } else {
> > + fmt = conn_state->color_format;
> > + drm_dbg_kms(last_bridge->dev, "Non-HDMI bridge requests format %d\n", fmt);
> > + }
> > +
> > for (i = 0; i < num_out_bus_fmts; i++) {
> > + if (!bus_format_is_color_fmt(out_bus_fmts[i], fmt)) {
> > + drm_dbg_kms(last_bridge->dev,
> > + "Skipping bus format 0x%04x as it doesn't match format %d\n",
> > + out_bus_fmts[i], fmt);
> > + ret = -ENOTSUPP;
> > + continue;
> > + }
> > ret = select_bus_fmt_recursive(bridge, last_bridge, crtc_state,
> > conn_state, out_bus_fmts[i]);
> > - if (ret != -ENOTSUPP)
> > + if (ret != -ENOTSUPP) {
> > + drm_dbg_kms(last_bridge->dev,
> > + "Found bridge chain ending with bus format 0x%04x\n",
> > + out_bus_fmts[i]);
> > break;
> > + }
> > }
> >
> > +out_free_bus_fmts:
> > kfree(out_bus_fmts);
> >
> > return ret;
> >
>
>
^ permalink raw reply
* [PATCH] PCI: host-common: Request bus reassignment when not probe-only
From: Ratheesh Kannoth @ 2026-04-10 14:21 UTC (permalink / raw)
To: linux-pci, linux-arm-kernel, linux-kernel, bhelgaas
Cc: will, lpieralisi, kwilczynski, mani, robh, vidyas,
Ratheesh Kannoth, Bjorn Helgaas
pci_host_common_init() is used by several generic ECAM host drivers.
After PCI core changes around pci_flags and preserve_config, these hosts
no longer opted into full bus number reassignment the way they did
before.
When PCI_PROBE_ONLY is not set, add PCI_REASSIGN_ALL_BUS so
pci_scan_bridge_extend() takes the reassignment path: bus numbers can be
assigned from firmware EA data (e.g. pci_ea_fixed_busnrs()). Skip the
flag in probe-only mode so existing assignments are not overridden.
CC: Bjorn Helgaas <helgaas@kernel.org>
CC: Vidya Sagar <vidyas@nvidia.com>
Fixes: 7246a4520b4b ("PCI: Use preserve_config in place of pci_flags")
Link: https://lore.kernel.org/netdev/adcXzcz2wWJFw4d7@rkannoth-OptiPlex-7090/
Signed-off-by: Ratheesh Kannoth <rkannoth@marvell.com>
---
drivers/pci/controller/pci-host-common.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/drivers/pci/controller/pci-host-common.c b/drivers/pci/controller/pci-host-common.c
index d6258c1cffe5..860783553cca 100644
--- a/drivers/pci/controller/pci-host-common.c
+++ b/drivers/pci/controller/pci-host-common.c
@@ -68,6 +68,10 @@ int pci_host_common_init(struct platform_device *pdev,
if (IS_ERR(cfg))
return PTR_ERR(cfg);
+ /* Do not reassign resources if probe only */
+ if (!pci_has_flag(PCI_PROBE_ONLY))
+ pci_add_flags(PCI_REASSIGN_ALL_BUS);
+
bridge->sysdata = cfg;
bridge->ops = (struct pci_ops *)&ops->pci_ops;
bridge->enable_device = ops->enable_device;
--
2.43.0
^ permalink raw reply related
* [PATCH v2 3/3] arm64: dts: broadcom: rpi-5: Add RP1 PWM node
From: Andrea della Porta @ 2026-04-10 14:09 UTC (permalink / raw)
To: Uwe Kleine-König, linux-pwm, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Florian Fainelli,
Broadcom internal kernel review list, Andrea della Porta,
devicetree, linux-rpi-kernel, linux-arm-kernel, linux-kernel,
Naushir Patuck, Stanimir Varbanov, mbrugger
In-Reply-To: <cover.1775829499.git.andrea.porta@suse.com>
From: Stanimir Varbanov <svarbanov@suse.de>
The RP1 chipset used on the Raspberry Pi 5 features an integrated
PWM controller to drive the cooling fan.
Add the corresponding DT node for this PWM controller.
Signed-off-by: Stanimir Varbanov <svarbanov@suse.de>
Co-developed-by: Andrea della Porta <andrea.porta@suse.com>
Signed-off-by: Andrea della Porta <andrea.porta@suse.com>
---
arch/arm64/boot/dts/broadcom/bcm2712-rpi-5-b.dts | 12 ++++++++++++
arch/arm64/boot/dts/broadcom/rp1-common.dtsi | 10 ++++++++++
2 files changed, 22 insertions(+)
diff --git a/arch/arm64/boot/dts/broadcom/bcm2712-rpi-5-b.dts b/arch/arm64/boot/dts/broadcom/bcm2712-rpi-5-b.dts
index 2856082814462..a4e5ba23bf536 100644
--- a/arch/arm64/boot/dts/broadcom/bcm2712-rpi-5-b.dts
+++ b/arch/arm64/boot/dts/broadcom/bcm2712-rpi-5-b.dts
@@ -64,12 +64,24 @@ phy1: ethernet-phy@1 {
};
&rp1_gpio {
+ fan_pwm_default_state: fan-pwm-default-state {
+ function = "pwm1";
+ pins = "gpio45";
+ bias-pull-down;
+ };
+
usb_vbus_default_state: usb-vbus-default-state {
function = "vbus1";
groups = "vbus1";
};
};
+&rp1_pwm {
+ pinctrl-0 = <&fan_pwm_default_state>;
+ pinctrl-names = "default";
+ status = "okay";
+};
+
&rp1_usb0 {
pinctrl-0 = <&usb_vbus_default_state>;
pinctrl-names = "default";
diff --git a/arch/arm64/boot/dts/broadcom/rp1-common.dtsi b/arch/arm64/boot/dts/broadcom/rp1-common.dtsi
index 5a815c3797945..d0f4d6be75500 100644
--- a/arch/arm64/boot/dts/broadcom/rp1-common.dtsi
+++ b/arch/arm64/boot/dts/broadcom/rp1-common.dtsi
@@ -26,6 +26,16 @@ rp1_clocks: clocks@40018000 {
<200000000>; // RP1_CLK_SYS
};
+ rp1_pwm: pwm@4009c000 {
+ compatible = "raspberrypi,rp1-pwm";
+ reg = <0x00 0x4009c000 0x0 0x100>;
+ clocks = <&rp1_clocks RP1_CLK_PWM1>;
+ assigned-clocks = <&rp1_clocks RP1_CLK_PWM1>;
+ assigned-clock-rates = <50000000>;
+ #pwm-cells = <3>;
+ status = "disabled";
+ };
+
rp1_gpio: pinctrl@400d0000 {
compatible = "raspberrypi,rp1-gpio";
reg = <0x00 0x400d0000 0x0 0xc000>,
--
2.35.3
^ permalink raw reply related
* [PATCH v2 1/3] dt-bindings: pwm: Add Raspberry Pi RP1 PWM controller
From: Andrea della Porta @ 2026-04-10 14:09 UTC (permalink / raw)
To: Uwe Kleine-König, linux-pwm, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Florian Fainelli,
Broadcom internal kernel review list, Andrea della Porta,
devicetree, linux-rpi-kernel, linux-arm-kernel, linux-kernel,
Naushir Patuck, Stanimir Varbanov, mbrugger
In-Reply-To: <cover.1775829499.git.andrea.porta@suse.com>
From: Naushir Patuck <naush@raspberrypi.com>
Add the devicetree binding documentation for the PWM
controller found in the Raspberry Pi RP1 chipset.
Signed-off-by: Naushir Patuck <naush@raspberrypi.com>
Co-developed-by: Stanimir Varbanov <svarbanov@suse.de>
Signed-off-by: Stanimir Varbanov <svarbanov@suse.de>
Signed-off-by: Andrea della Porta <andrea.porta@suse.com>
---
.../bindings/pwm/raspberrypi,rp1-pwm.yaml | 54 +++++++++++++++++++
1 file changed, 54 insertions(+)
create mode 100644 Documentation/devicetree/bindings/pwm/raspberrypi,rp1-pwm.yaml
diff --git a/Documentation/devicetree/bindings/pwm/raspberrypi,rp1-pwm.yaml b/Documentation/devicetree/bindings/pwm/raspberrypi,rp1-pwm.yaml
new file mode 100644
index 0000000000000..6f8461d0454f7
--- /dev/null
+++ b/Documentation/devicetree/bindings/pwm/raspberrypi,rp1-pwm.yaml
@@ -0,0 +1,54 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/pwm/raspberrypi,rp1-pwm.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Raspberry Pi RP1 PWM controller
+
+maintainers:
+ - Naushir Patuck <naush@raspberrypi.com>
+
+allOf:
+ - $ref: pwm.yaml#
+
+description: |
+ The PWM peripheral is a flexible waveform generator with a
+ variety of operational modes. It has the following features:
+ - four independent output channels
+ - 32-bit counter widths
+ - Seven output generation modes
+ - Optional per-channel output inversion
+ - Optional duty-cycle data FIFO with DMA support
+ - Optional sigma-delta noise shaping engine
+ Serves as a fan speed provider to other nodes for a PWM-connected
+ fan using shared registers (syscon).
+
+properties:
+ compatible:
+ const: raspberrypi,rp1-pwm
+
+ reg:
+ maxItems: 1
+
+ clocks:
+ maxItems: 1
+
+ "#pwm-cells":
+ const: 3
+
+required:
+ - compatible
+ - reg
+ - clocks
+
+unevaluatedProperties: false
+
+examples:
+ - |
+ pwm@98000 {
+ compatible = "raspberrypi,rp1-pwm";
+ reg = <0x98000 0x100>;
+ clocks = <&rp1_clocks 17>;
+ #pwm-cells = <3>;
+ };
--
2.35.3
^ permalink raw reply related
* [PATCH v2 2/3] pwm: rp1: Add RP1 PWM controller driver
From: Andrea della Porta @ 2026-04-10 14:09 UTC (permalink / raw)
To: Uwe Kleine-König, linux-pwm, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Florian Fainelli,
Broadcom internal kernel review list, Andrea della Porta,
devicetree, linux-rpi-kernel, linux-arm-kernel, linux-kernel,
Naushir Patuck, Stanimir Varbanov, mbrugger
In-Reply-To: <cover.1775829499.git.andrea.porta@suse.com>
From: Naushir Patuck <naush@raspberrypi.com>
The Raspberry Pi RP1 southbridge features an embedded PWM
controller with 4 output channels, alongside an RPM interface
to read the fan speed on the Raspberry Pi 5.
Add the supporting driver.
Signed-off-by: Naushir Patuck <naush@raspberrypi.com>
Co-developed-by: Stanimir Varbanov <svarbanov@suse.de>
Signed-off-by: Stanimir Varbanov <svarbanov@suse.de>
Signed-off-by: Andrea della Porta <andrea.porta@suse.com>
---
drivers/pwm/Kconfig | 9 ++
drivers/pwm/Makefile | 1 +
drivers/pwm/pwm-rp1.c | 344 ++++++++++++++++++++++++++++++++++++++++++
3 files changed, 354 insertions(+)
create mode 100644 drivers/pwm/pwm-rp1.c
diff --git a/drivers/pwm/Kconfig b/drivers/pwm/Kconfig
index 6f3147518376a..32031f2af75af 100644
--- a/drivers/pwm/Kconfig
+++ b/drivers/pwm/Kconfig
@@ -625,6 +625,15 @@ config PWM_ROCKCHIP
Generic PWM framework driver for the PWM controller found on
Rockchip SoCs.
+config PWM_RASPBERRYPI_RP1
+ bool "RP1 PWM support"
+ depends on MISC_RP1 || COMPILE_TEST
+ depends on HAS_IOMEM
+ select REGMAP_MMIO
+ select MFD_SYSCON
+ help
+ PWM framework driver for Raspberry Pi RP1 controller.
+
config PWM_SAMSUNG
tristate "Samsung PWM support"
depends on PLAT_SAMSUNG || ARCH_S5PV210 || ARCH_EXYNOS || COMPILE_TEST
diff --git a/drivers/pwm/Makefile b/drivers/pwm/Makefile
index 0dc0d2b69025d..59f29f60f9123 100644
--- a/drivers/pwm/Makefile
+++ b/drivers/pwm/Makefile
@@ -56,6 +56,7 @@ obj-$(CONFIG_PWM_RENESAS_RZG2L_GPT) += pwm-rzg2l-gpt.o
obj-$(CONFIG_PWM_RENESAS_RZ_MTU3) += pwm-rz-mtu3.o
obj-$(CONFIG_PWM_RENESAS_TPU) += pwm-renesas-tpu.o
obj-$(CONFIG_PWM_ROCKCHIP) += pwm-rockchip.o
+obj-$(CONFIG_PWM_RASPBERRYPI_RP1) += pwm-rp1.o
obj-$(CONFIG_PWM_SAMSUNG) += pwm-samsung.o
obj-$(CONFIG_PWM_SIFIVE) += pwm-sifive.o
obj-$(CONFIG_PWM_SL28CPLD) += pwm-sl28cpld.o
diff --git a/drivers/pwm/pwm-rp1.c b/drivers/pwm/pwm-rp1.c
new file mode 100644
index 0000000000000..b88c697d9567e
--- /dev/null
+++ b/drivers/pwm/pwm-rp1.c
@@ -0,0 +1,344 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * pwm-rp1.c
+ *
+ * Raspberry Pi RP1 PWM.
+ *
+ * Copyright © 2026 Raspberry Pi Ltd.
+ *
+ * Author: Naushir Patuck (naush@raspberrypi.com)
+ *
+ * Based on the pwm-bcm2835 driver by:
+ * Bart Tanghe <bart.tanghe@thomasmore.be>
+ *
+ * Datasheet: https://pip-assets.raspberrypi.com/categories/892-raspberry-pi-5/documents/RP-008370-DS-1-rp1-peripherals.pdf?disposition=inline
+ *
+ * Limitations:
+ * - Channels can be enabled/disabled and their duty cycle and period can
+ * be updated glitchlessly. Update are synchronized with the next strobe
+ * at the end of the current period of the respective channel, once the
+ * update bit is set. The update flag is global, not per-channel.
+ * - Channels are phase-capable, but on RPi5, the firmware can use a channel
+ * phase register to report the RPM of the fan connected to that PWM
+ * channel. As a result, phase control will be ignored for now.
+ */
+
+#include <linux/bitops.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/pwm.h>
+#include <linux/regmap.h>
+#include <linux/mfd/syscon.h>
+
+#define RP1_PWM_GLOBAL_CTRL 0x000
+#define RP1_PWM_CHANNEL_CTRL(x) (0x014 + ((x) * 0x10))
+#define RP1_PWM_RANGE(x) (0x018 + ((x) * 0x10))
+#define RP1_PWM_PHASE(x) (0x01C + ((x) * 0x10))
+#define RP1_PWM_DUTY(x) (0x020 + ((x) * 0x10))
+
+/* 8:FIFO_POP_MASK + 0:Trailing edge M/S modulation */
+#define RP1_PWM_CHANNEL_DEFAULT (BIT(8) + BIT(0))
+#define RP1_PWM_CHANNEL_ENABLE(x) BIT(x)
+#define RP1_PWM_POLARITY BIT(3)
+#define RP1_PWM_SET_UPDATE BIT(31)
+#define RP1_PWM_MODE_MASK GENMASK(1, 0)
+
+#define RP1_PWM_NUM_PWMS 4
+
+struct rp1_pwm {
+ struct regmap *regmap;
+ struct clk *clk;
+ unsigned long clk_rate;
+ bool clk_enabled;
+};
+
+struct rp1_pwm_waveform {
+ u32 period_ticks;
+ u32 duty_ticks;
+ bool enabled;
+ bool inverted_polarity;
+};
+
+static const struct regmap_config rp1_pwm_regmap_config = {
+ .reg_bits = 32,
+ .val_bits = 32,
+ .reg_stride = 4,
+ .max_register = 0x60,
+};
+
+static void rp1_pwm_apply_config(struct pwm_chip *chip, struct pwm_device *pwm)
+{
+ struct rp1_pwm *rp1 = pwmchip_get_drvdata(chip);
+ u32 value;
+
+ /* update the changed registers on the next strobe to avoid glitches */
+ regmap_read(rp1->regmap, RP1_PWM_GLOBAL_CTRL, &value);
+ value |= RP1_PWM_SET_UPDATE;
+ regmap_write(rp1->regmap, RP1_PWM_GLOBAL_CTRL, value);
+}
+
+static int rp1_pwm_request(struct pwm_chip *chip, struct pwm_device *pwm)
+{
+ struct rp1_pwm *rp1 = pwmchip_get_drvdata(chip);
+
+ /* init channel to reset defaults */
+ regmap_write(rp1->regmap, RP1_PWM_CHANNEL_CTRL(pwm->hwpwm), RP1_PWM_CHANNEL_DEFAULT);
+ return 0;
+}
+
+static int rp1_pwm_round_waveform_tohw(struct pwm_chip *chip,
+ struct pwm_device *pwm,
+ const struct pwm_waveform *wf,
+ void *_wfhw)
+{
+ struct rp1_pwm *rp1 = pwmchip_get_drvdata(chip);
+ struct rp1_pwm_waveform *wfhw = _wfhw;
+ u64 clk_rate = rp1->clk_rate;
+ u64 ticks;
+
+ ticks = mul_u64_u64_div_u64(wf->period_length_ns, clk_rate, NSEC_PER_SEC);
+
+ if (ticks > U32_MAX)
+ ticks = U32_MAX;
+ wfhw->period_ticks = ticks;
+
+ if (wf->duty_offset_ns + wf->duty_length_ns >= wf->period_length_ns) {
+ ticks = mul_u64_u64_div_u64(wf->period_length_ns - wf->duty_length_ns,
+ clk_rate, NSEC_PER_SEC);
+ wfhw->inverted_polarity = true;
+ } else {
+ ticks = mul_u64_u64_div_u64(wf->duty_length_ns, clk_rate, NSEC_PER_SEC);
+ wfhw->inverted_polarity = false;
+ }
+
+ if (ticks > wfhw->period_ticks)
+ ticks = wfhw->period_ticks;
+ wfhw->duty_ticks = ticks;
+
+ wfhw->enabled = !!wfhw->duty_ticks;
+
+ return 0;
+}
+
+static int rp1_pwm_round_waveform_fromhw(struct pwm_chip *chip,
+ struct pwm_device *pwm,
+ const void *_wfhw,
+ struct pwm_waveform *wf)
+{
+ struct rp1_pwm *rp1 = pwmchip_get_drvdata(chip);
+ const struct rp1_pwm_waveform *wfhw = _wfhw;
+ u64 clk_rate = rp1->clk_rate;
+ u32 ticks;
+
+ memset(wf, 0, sizeof(*wf));
+
+ if (!wfhw->enabled)
+ return 0;
+
+ wf->period_length_ns = DIV_ROUND_UP_ULL((u64)wfhw->period_ticks * NSEC_PER_SEC, clk_rate);
+
+ if (wfhw->inverted_polarity) {
+ wf->duty_length_ns = DIV_ROUND_UP_ULL((u64)wfhw->duty_ticks * NSEC_PER_SEC,
+ clk_rate);
+ } else {
+ wf->duty_offset_ns = DIV_ROUND_UP_ULL((u64)wfhw->duty_ticks * NSEC_PER_SEC,
+ clk_rate);
+ ticks = wfhw->period_ticks - wfhw->duty_ticks;
+ wf->duty_length_ns = DIV_ROUND_UP_ULL((u64)ticks * NSEC_PER_SEC, clk_rate);
+ }
+
+ return 0;
+}
+
+static int rp1_pwm_write_waveform(struct pwm_chip *chip,
+ struct pwm_device *pwm,
+ const void *_wfhw)
+{
+ struct rp1_pwm *rp1 = pwmchip_get_drvdata(chip);
+ const struct rp1_pwm_waveform *wfhw = _wfhw;
+ u32 value;
+
+ /* set period and duty cycle */
+ regmap_write(rp1->regmap,
+ RP1_PWM_RANGE(pwm->hwpwm), wfhw->period_ticks);
+ regmap_write(rp1->regmap,
+ RP1_PWM_DUTY(pwm->hwpwm), wfhw->duty_ticks);
+
+ /* set polarity */
+ regmap_read(rp1->regmap, RP1_PWM_CHANNEL_CTRL(pwm->hwpwm), &value);
+ if (!wfhw->inverted_polarity)
+ value &= ~RP1_PWM_POLARITY;
+ else
+ value |= RP1_PWM_POLARITY;
+ regmap_write(rp1->regmap, RP1_PWM_CHANNEL_CTRL(pwm->hwpwm), value);
+
+ /* enable/disable */
+ regmap_read(rp1->regmap, RP1_PWM_GLOBAL_CTRL, &value);
+ if (wfhw->enabled)
+ value |= RP1_PWM_CHANNEL_ENABLE(pwm->hwpwm);
+ else
+ value &= ~RP1_PWM_CHANNEL_ENABLE(pwm->hwpwm);
+ regmap_write(rp1->regmap, RP1_PWM_GLOBAL_CTRL, value);
+
+ rp1_pwm_apply_config(chip, pwm);
+
+ return 0;
+}
+
+static int rp1_pwm_read_waveform(struct pwm_chip *chip,
+ struct pwm_device *pwm,
+ void *_wfhw)
+{
+ struct rp1_pwm *rp1 = pwmchip_get_drvdata(chip);
+ struct rp1_pwm_waveform *wfhw = _wfhw;
+ u32 value;
+
+ regmap_read(rp1->regmap, RP1_PWM_GLOBAL_CTRL, &value);
+ wfhw->enabled = !!(value & RP1_PWM_CHANNEL_ENABLE(pwm->hwpwm));
+
+ regmap_read(rp1->regmap, RP1_PWM_CHANNEL_CTRL(pwm->hwpwm), &value);
+ wfhw->inverted_polarity = !!(value & RP1_PWM_POLARITY);
+
+ if (wfhw->enabled) {
+ regmap_read(rp1->regmap, RP1_PWM_RANGE(pwm->hwpwm), &wfhw->period_ticks);
+ regmap_read(rp1->regmap, RP1_PWM_DUTY(pwm->hwpwm), &wfhw->duty_ticks);
+ } else {
+ wfhw->period_ticks = 0;
+ wfhw->duty_ticks = 0;
+ }
+
+ return 0;
+}
+
+static const struct pwm_ops rp1_pwm_ops = {
+ .sizeof_wfhw = sizeof(struct rp1_pwm_waveform),
+ .request = rp1_pwm_request,
+ .round_waveform_tohw = rp1_pwm_round_waveform_tohw,
+ .round_waveform_fromhw = rp1_pwm_round_waveform_fromhw,
+ .read_waveform = rp1_pwm_read_waveform,
+ .write_waveform = rp1_pwm_write_waveform,
+};
+
+static int rp1_pwm_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct device_node *np = dev->of_node;
+ unsigned long clk_rate;
+ struct pwm_chip *chip;
+ void __iomem *base;
+ struct rp1_pwm *rp1;
+ int ret;
+
+ chip = devm_pwmchip_alloc(dev, RP1_PWM_NUM_PWMS, sizeof(*rp1));
+ if (IS_ERR(chip))
+ return PTR_ERR(chip);
+
+ rp1 = pwmchip_get_drvdata(chip);
+
+ base = devm_platform_ioremap_resource(pdev, 0);
+ if (IS_ERR(base))
+ return PTR_ERR(base);
+
+ rp1->regmap = devm_regmap_init_mmio(dev, base, &rp1_pwm_regmap_config);
+ if (IS_ERR(rp1->regmap))
+ return dev_err_probe(dev, PTR_ERR(rp1->regmap), "Cannot initialize regmap\n");
+
+ ret = of_syscon_register_regmap(np, rp1->regmap);
+ if (ret)
+ return dev_err_probe(dev, ret, "Failed to register syscon\n");
+
+ rp1->clk = devm_clk_get(dev, NULL);
+ if (IS_ERR(rp1->clk))
+ return dev_err_probe(dev, PTR_ERR(rp1->clk), "Clock not found\n");
+
+ ret = clk_prepare_enable(rp1->clk);
+ if (ret)
+ return dev_err_probe(dev, ret, "Failed to enable clock\n");
+ rp1->clk_enabled = true;
+
+ ret = devm_clk_rate_exclusive_get(dev, rp1->clk);
+ if (ret) {
+ dev_err_probe(dev, ret, "Fail to get exclusive rate\n");
+ goto err_disable_clk;
+ }
+
+ clk_rate = clk_get_rate(rp1->clk);
+ if (!clk_rate) {
+ ret = dev_err_probe(dev, -EINVAL, "Failed to get clock rate\n");
+ goto err_disable_clk;
+ }
+ rp1->clk_rate = clk_rate;
+
+ chip->ops = &rp1_pwm_ops;
+
+ platform_set_drvdata(pdev, chip);
+
+ ret = devm_pwmchip_add(dev, chip);
+ if (ret) {
+ dev_err_probe(dev, ret, "Failed to register PWM chip\n");
+ goto err_disable_clk;
+ }
+
+ return 0;
+
+err_disable_clk:
+ clk_disable_unprepare(rp1->clk);
+
+ return ret;
+}
+
+static int rp1_pwm_suspend(struct device *dev)
+{
+ struct rp1_pwm *rp1 = dev_get_drvdata(dev);
+
+ if (rp1->clk_enabled) {
+ clk_disable_unprepare(rp1->clk);
+ rp1->clk_enabled = false;
+ }
+
+ return 0;
+}
+
+static int rp1_pwm_resume(struct device *dev)
+{
+ struct rp1_pwm *rp1 = dev_get_drvdata(dev);
+ int ret;
+
+ ret = clk_prepare_enable(rp1->clk);
+ if (ret) {
+ dev_err(dev, "Failed to enable clock on resume: %d\n", ret);
+ return ret;
+ }
+
+ rp1->clk_enabled = true;
+
+ return 0;
+}
+
+static DEFINE_SIMPLE_DEV_PM_OPS(rp1_pwm_pm_ops, rp1_pwm_suspend, rp1_pwm_resume);
+
+static const struct of_device_id rp1_pwm_of_match[] = {
+ { .compatible = "raspberrypi,rp1-pwm" },
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, rp1_pwm_of_match);
+
+static struct platform_driver rp1_pwm_driver = {
+ .probe = rp1_pwm_probe,
+ .driver = {
+ .name = "rp1-pwm",
+ .of_match_table = rp1_pwm_of_match,
+ .pm = pm_ptr(&rp1_pwm_pm_ops),
+ .suppress_bind_attrs = true,
+ },
+};
+module_platform_driver(rp1_pwm_driver);
+
+MODULE_DESCRIPTION("RP1 PWM driver");
+MODULE_AUTHOR("Naushir Patuck <naush@raspberrypi.com>");
+MODULE_AUTHOR("Andrea della Porta <andrea.porta@suse.com>");
+MODULE_LICENSE("GPL");
--
2.35.3
^ permalink raw reply related
* [PATCH v2 0/3] Add RP1 PWM controller support
From: Andrea della Porta @ 2026-04-10 14:09 UTC (permalink / raw)
To: Uwe Kleine-König, linux-pwm, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Florian Fainelli,
Broadcom internal kernel review list, Andrea della Porta,
devicetree, linux-rpi-kernel, linux-arm-kernel, linux-kernel,
Naushir Patuck, Stanimir Varbanov, mbrugger
This patchset adds support for the PWM controller found on the
Raspberry Pi RP1 southbridge. This is necessary to operate the
cooling fan connected to one of the PWM channels.
The tachometer pin for the fan speed is managed by the firmware
running on the RP1's M-core. It uses the PHASE2 register
to report the RPM, which is then exported by this driver via
syscon registers. A subsequent patch will add a new device
and driver to read the RPM and export this value via hwmon.
Subsequent patches will also add the CPU thermal zone, which
acts as a consumer of the PWM device.
Best regards,
Andrea
CHANGES in V2:
- bindings: added syscon to the description
- bindings: changed additionalProperties to unevaluatedProperties
- dts: reordered pwm node to follow the unit address ordering
- Kconfig/Makefile: renamed config option to PWM_RASPBERRYPI_RP1
- Kconfig: added dependency for syscon/regmap
- driver: added 'Limitations' and 'Datasheet' paragraphs in top comment
- driver: all macros are now prefixed by RP1_PWM_
- driver: implemented waveform callbacks instead of legacy ones
- driver: dropped hwmon device registration for fan speed (this will be
handled in a separate patch with its own driver reading the value via
syscon)
- driver: added new regmap/syscon to export the registers.
- driver: added a comment in rp1_pwm_apply_config() to describe what it does
- driver: added a comment to rp1_pwm_request() to define the purpose of the
last write
- driver: new clk_enabled flag to deal with the clock on suspend/resume path
- driver: clk_rate is now obtained during probe right after exclusive_get()
- driver/Kconfig: module is now static only and has suppress_bind_attr to
avoid racing with syscon consumer drivers and with syscon unload issue
Naushir Patuck (2):
dt-bindings: pwm: Add Raspberry Pi RP1 PWM controller
pwm: rp1: Add RP1 PWM controller driver
Stanimir Varbanov (1):
arm64: dts: broadcom: rpi-5: Add RP1 PWM node
.../bindings/pwm/raspberrypi,rp1-pwm.yaml | 54 +++
.../boot/dts/broadcom/bcm2712-rpi-5-b.dts | 12 +
arch/arm64/boot/dts/broadcom/rp1-common.dtsi | 10 +
drivers/pwm/Kconfig | 9 +
drivers/pwm/Makefile | 1 +
drivers/pwm/pwm-rp1.c | 344 ++++++++++++++++++
6 files changed, 430 insertions(+)
create mode 100644 Documentation/devicetree/bindings/pwm/raspberrypi,rp1-pwm.yaml
create mode 100644 drivers/pwm/pwm-rp1.c
--
2.35.3
^ permalink raw reply
* Re: [PATCH v3 0/4] mm: improve large folio readahead and alignment for exec memory
From: David Hildenbrand (Arm) @ 2026-04-10 14:02 UTC (permalink / raw)
To: Lorenzo Stoakes, Usama Arif
Cc: Andrew Morton, willy, ryan.roberts, linux-mm, r, jack, ajd,
apopple, baohua, baolin.wang, brauner, catalin.marinas, dev.jain,
kees, kevin.brodsky, lance.yang, Liam.Howlett, linux-arm-kernel,
linux-fsdevel, linux-kernel, mhocko, npache, pasha.tatashin,
rmclure, rppt, surenb, vbabka, Al Viro, ziy, hannes, kas,
shakeel.butt, leitao, kernel-team
In-Reply-To: <adjrKwgiZwXR9epk@lucifer>
On 4/10/26 14:24, Lorenzo Stoakes wrote:
> On Fri, Apr 10, 2026 at 01:19:08PM +0100, Usama Arif wrote:
>>
>>
>> On 10/04/2026 12:57, Lorenzo Stoakes wrote:
>>>
>>> (Note that we're in a 'quiet period' from here until -rc1 of next cycle and
>>> won't be taking anything new until then. We plan to do this from around rc5 or
>>> rc6 of each cycle in future).
>>
>> Thanks! Just wanted to check, as I am always confused about this. Is it ok
>> to send patches for review for next release at this time? So that they
>> are in a good state when rc1 comes. I wanted to send PMD swap entries
>> for review after I am finished testing, but I want them for review for
>> next release.
>
> I think different people have different views on that :)
>
> I mean it's debateable whether having a glut of new material on day one of -rc1
> is preferable to having a bunch come in that might or might not get lost along
> the way :)
>
> I personally feel it'd be better to send during the cycle window rather than
> before but I suspect others disagree with that!
>
> So from your point of view, feel free to do what you like, but maybe David +
> others would want to chime in with their opinions?
I personally don't care that much. People just have to be prepared that
there will be little review on new (non-fix) material during the quiet
period.
It will sit in my inbox one way or the other :)
--
Cheers,
David
^ permalink raw reply
* Re: [PATCH v3 0/7] arm64: dts: ti: k3-am62a7-sk: Split r5f memory region
From: Markus Schneider-Pargmann @ 2026-04-10 13:54 UTC (permalink / raw)
To: Vignesh Raghavendra, Rob Herring, Markus Schneider-Pargmann (TI)
Cc: Nishanth Menon, devicetree, Conor Dooley, Tero Kristo,
Mathieu Poirier, Dhruva Gole, Akashdeep Kaur, Kevin Hilman,
Bjorn Andersson, linux-remoteproc, linux-kernel, Kendall Willis,
Vishal Mahaveer, Sebin Francis, Krzysztof Kozlowski,
linux-arm-kernel
In-Reply-To: <6a4aecff-f662-4620-8572-3309ea6a81e2@ti.com>
[-- Attachment #1: Type: text/plain, Size: 4163 bytes --]
Hi Vignesh,
On Thu Apr 9, 2026 at 11:46 AM CEST, Vignesh Raghavendra wrote:
> Hi Markus
>
> On 08/04/26 20:33, Rob Herring wrote:
>> On Wed, Mar 18, 2026 at 10:14 AM Markus Schneider-Pargmann (TI)
>> <msp@baylibre.com> wrote:
>>>
>>> Hi,
>>>
>>> Split the firmware memory region in more specific parts so it is better
>>> described where which information is stored. Specifically the LPM metadata
>>> region is important as bootloader software like U-Boot has to know where
>>> that data is to be able to read that data and resume from RAM.
>>>
>>> IO+DDR is a deep sleep state in which a few pins are set to be sensitive
>>> for wakeup while the DDR is kept in self refresh. Everything else is
>>> powered off.
>>>
>>> The changes in this series were suggested as part of the IO+DDR u-boot series:
>>> https://lore.kernel.org/r/814c211f-a9eb-4311-bb84-165b1a69755f@ti.com
>>>
>>> There are currently no real users of the memory-region that is split in
>>> this series. The size of the memory-region in total stays the same.
>>> The new layout is derived from the software running on the r5f
>>> processor:
>>> https://github.com/TexasInstruments/mcupsdk-core-k3/blob/k3_main/examples/drivers/ipc/ipc_rpmsg_echo_linux/am62ax-sk/r5fss0-0_freertos/ti-arm-clang/linker.cmd#L172
>>> https://github.com/TexasInstruments/mcupsdk-core-k3/blob/k3_main/source/drivers/device_manager/sciclient.h#L459
>>>
>>> Additionally the two important devicetree nodes for resuming from IO+DDR
>>> have the bootph-pre-ram flag added as this data needs to be read before
>>> the RAM is in use.
>>>
>>> Best
>>> Markus
>>>
>>> Signed-off-by: Markus Schneider-Pargmann (TI) <msp@baylibre.com>
>>> ---
>>> Changes in v3:
>>> - Squash the enforcement of the memory-region-names requirement in the
>>> patch adding the memory-region-names, as suggested.
>>> - Link to v2: https://lore.kernel.org/r/20260312-topic-am62a-ioddr-dt-v6-19-v2-0-37cb7ceec658@baylibre.com
>>>
>>> Changes in v2:
>>> - Make memory-region-names required if memory-region is present
>>> - Fixup memory-region and memory-region-names conditions. Require either
>>> 2 or 6 regions for memory-region and memory-region-names
>>> - Reword and restructure the binding documentation for memory-region and
>>> memory-region-names
>>> - Add memory-region-names to all uses of memory-region
>>> - Link to v1: https://lore.kernel.org/r/20260303-topic-am62a-ioddr-dt-v6-19-v1-0-12fe72bb40d2@baylibre.com
>>>
>>> ---
>>> Markus Schneider-Pargmann (TI) (7):
>>> dt-bindings: remoteproc: k3-r5f: Split up memory regions
>>> dt-bindings: remoteproc: k3-r5f: Add memory-region-names
>>> arm64: dts: ti: k3: Use memory-region-names for r5f
>>> arm64: dts: ti: k3-am62a7-sk: Split r5f memory region
>>> arm64: dts: ti: k3-am62p5-sk: Split r5f memory region
>>> arm64: dts: ti: k3-am62a7-sk: Add r5f nodes to pre-ram bootphase
>>> arm64: dts: ti: k3-am62p5-sk: Add r5f nodes to pre-ram bootphase
>>
>> TI folks, Please make sure these dts patches are picked up for 7.1.
>> There's now a crap load of warnings in next with the binding change:
>>
>> 58 (ti,am62-r5fss): r5f@78000000: 'memory-region-names' is a
>> required property
>
> [...]
>
>> If they aren't applied, making 'memory-region-names' required needs
>> to be dropped from the binding.
>>
>
> This breaks DT backward compatibility. Why is memory-region-names now a
> required item and cannot be assumed as "dma" and "firmware" as default?
> Is that intentional (should have at least had a Fixes tag then if the
> original definition was wrong)?
Conor suggested to make the memory-region-names required for easier
distinction of the layouts:
https://lore.kernel.org/all/20260303-payphone-pancake-b6068c545bc3@spud/
And a follow-up discussion here:
https://lore.kernel.org/all/20260313-kettle-craftily-aa087e6b74db@spud/
Also I don't think it really breaks backward compatibility. I don't
think there is any user for it and the previous binding documentation
only refers to it as reserved regions.
Best
Markus
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 289 bytes --]
^ permalink raw reply
* Re: [PATCH 07/14] KVM: arm64: Restrict host access to the ITS tables
From: Sebastian Ene @ 2026-04-10 13:52 UTC (permalink / raw)
To: Fuad Tabba
Cc: alexandru.elisei, kvmarm, linux-arm-kernel, linux-kernel,
android-kvm, catalin.marinas, joey.gouly, kees, mark.rutland, maz,
oupton, perlarsen, qperret, rananta, smostafa, suzuki.poulose,
tglx, vdonnefort, bgrzesik, will, yuzenghui
In-Reply-To: <CA+EHjTxUbLBnyBGg58wsJQvTXPN0FTbj53H5r3sC9_TizpjvdQ@mail.gmail.com>
On Mon, Mar 16, 2026 at 04:13:59PM +0000, Fuad Tabba wrote:
Hello Fuad,
> Hi Sebastian,
>
> On Tue, 10 Mar 2026 at 12:49, Sebastian Ene <sebastianene@google.com> wrote:
> >
> > Setup shadow structures for ITS indirect tables held in
> > the GITS_BASER<n> registers.
> > Make the last level of the Device Table and vPE Table
> > inacessible to the host.
>
> inacessible -> inaccessible
Applied fix, thanks.
> > In a direct layout configuration, donate the table to
> > the hypervisor since the software is not expected to
> > program them directly.
>
> This commit message is too brief and doesn't fully explain the
> problem, the impact, and the mechanism of the solution. It also
> appears to contradict the actual code changes.
>
> For example, could you elaborate why must the last level of indirect
> tables be inaccessible?
For device table, a malicious host can write the ITT address that points
to hyp memory and then use MAPTI to write over that memory.
>
> Can you also please explain the mechanism? You are parsing
> GITS_BASER_INDIRECT to determine if a shadow Level 1 table must be
> shared with the host, while unconditionally donating the original
> physical tables. You also explicitly exclude Collection tables. The
> msg should briefly justify why Collection tables are safe to leave
> accessible to the host.
>
> There is also a contradiction in the message. You state "In a direct
> layout configuration, donate the table...". However, your code donates
> the original hardware table unconditionally on every iteration of the
> loop, regardless of whether GITS_BASER_INDIRECT is set. Please ensure
> the commit log accurately reflects the code implementation.
>
I see no contradition, I only need to shadow the first layer of the
indirect tables. Shadowing implies donation and sharing:
because we are donating the original tables from host -> hyp and we sharing the
host view of the tables with the hypervisor (which is a copy).
> Maybe you could say that the problem is Host DMA attacks via ITS table
> manipulation. Whereas the mechanism is to unconditionally donate
This has nothing to do with Host DMA attacks, it is just the AP that can
write to memory.
> hardware tables to EL2. For indirect Device/vPE tables, share a L1
> shadow table with the host and strictly donate the L2 pages to prevent
> the host from writing malicious L2 pointers.
>
> >
> > Signed-off-by: Sebastian Ene <sebastianene@google.com>
> > ---
> > arch/arm64/kvm/hyp/nvhe/its_emulate.c | 143 ++++++++++++++++++++++++++
> > 1 file changed, 143 insertions(+)
> >
> > diff --git a/arch/arm64/kvm/hyp/nvhe/its_emulate.c b/arch/arm64/kvm/hyp/nvhe/its_emulate.c
> > index 4a3ccc90a1a9..865a5d6353ed 100644
> > --- a/arch/arm64/kvm/hyp/nvhe/its_emulate.c
> > +++ b/arch/arm64/kvm/hyp/nvhe/its_emulate.c
> > @@ -141,6 +141,145 @@ static struct pkvm_protected_reg *get_region(phys_addr_t dev_addr)
> > return NULL;
> > }
> >
> > +static int pkvm_host_unmap_last_level(void *shadow, size_t num_pages, u32 psz)
> > +{
> > + u64 *table = shadow;
> > + int ret, i, end = (num_pages << PAGE_SHIFT) / sizeof(table);
> > + phys_addr_t table_addr;
>
> RCT, mixing initialized variables and uninitialized variables, plus
> variables of conceptually different "types" in the same declaration.
>
> Please use sizeof(*table): sizeof(table) evaluates to the size of the
> pointer (8 bytes), NOT the size of the array element. In this case,
> this happens to be the same, but it's still wrong.
>
> Maybe the following is clearer:
> + int end = num_pages * (PAGE_SIZE / sizeof(*table));
>
>
Will use the suggestion and do the same for the
pkvm_host_map_last_level.
> > +
> > + for (i = 0; i < end; i++) {
> > + if (!(table[i] & GITS_BASER_VALID))
> > + continue;
> > +
> > + table_addr = table[i] & PHYS_MASK;
> > + ret = __pkvm_host_donate_hyp(hyp_phys_to_pfn(table_addr), psz >> PAGE_SHIFT);
>
> The ITS-configured page size and the host page size could be
> different, but the number of pages to donate for Level 2 tables is
> calculated based on psz (the ITS).
>
> If the ITS hardware is configured for 4KB pages, but the host kernel
> is using (e.g.,) 64KB pages, psz >> PAGE_SHIFT evaluates to 0.
I need to revisit this, thanks for pointing out.
>
> You need to account for mismatched page sizes, perhaps by using
> DIV_ROUND_UP(psz, PAGE_SIZE) (or something similar) to ensure the
> containing host page is donated.
>
> > + if (ret)
> > + goto err_donate;
> > + }
> > +
> > + return 0;
> > +err_donate:
> > + for (i = i - 1; i >= 0; i--) {
>
> Please use the while (i--) idiom for rollback loops.
>
>
> > + if (!(table[i] & GITS_BASER_VALID))
> > + continue;
> > +
> > + table_addr = table[i] & PHYS_MASK;
> > + __pkvm_hyp_donate_host(hyp_phys_to_pfn(table_addr), psz >> PAGE_SHIFT);
>
> Please wrap this in WARN_ON(...). If donating back to the host fails
> during a rollback, we have a fatal page leak that needs to be loudly
> flagged, similar to how you handle it in pkvm_unshare_shadow_table.
>
>
> > + }
> > + return ret;
> > +}
> > +
> > +static int pkvm_share_shadow_table(void *shadow, u64 nr_pages)
> > +{
> > + u64 i, ret, start_pfn = hyp_virt_to_pfn(shadow);
>
> Same comment as before with RCT and the mixing of declarations.
>
>
> > +
> > + for (i = 0; i < nr_pages; i++) {
> > + ret = __pkvm_host_share_hyp(start_pfn + i);
> > + if (ret)
> > + goto unshare;
> > + }
> > +
> > + ret = hyp_pin_shared_mem(shadow, shadow + (nr_pages << PAGE_SHIFT));
> > + if (ret)
> > + goto unshare;
> > +
> > + return ret;
> > +unshare:
>
> Please use the while (i--) idiom for rollback loops.
>
> Also, please use consistent naming conventions for the labels. Here
> you call it unshare, and earlier it was err_donate.
>
>
> > + for (i = i - 1; i >= 0; i--)
> > + __pkvm_host_unshare_hyp(start_pfn + i);
> > + return ret;
> > +}
> > +
> > +static void pkvm_unshare_shadow_table(void *shadow, u64 nr_pages)
> > +{
> > + u64 i, start_pfn = hyp_virt_to_pfn(shadow);
> > +
> > + hyp_unpin_shared_mem(shadow, shadow + (nr_pages << PAGE_SHIFT));
> > +
> > + for (i = 0; i < nr_pages; i++)
> > + WARN_ON(__pkvm_host_unshare_hyp(start_pfn + i));
> > +}
> > +
> > +static void pkvm_host_map_last_level(void *shadow, size_t num_pages, u32 psz)
> > +{
> > + u64 *table;
>
> RCT, and you forgot to initialize table:
> + u64 *table = shadow;
Fixed this, thanks. I never ended up on this code path during testing,
maybe I should create a test for it to trigger it.
>
> > + int i, end = (num_pages << PAGE_SHIFT) / sizeof(table);
>
> Same sizeof(table) pointer-size bug as above.
>
>
> > + phys_addr_t table_addr;
> > +
> > + for (i = 0; i < end; i++) {
> > + if (!(table[i] & GITS_BASER_VALID))
> > + continue;
> > +
> > + table_addr = table[i] & ~GITS_BASER_VALID;
>
> Inconsistent masking logic, since in pkvm_host_unmap_last_level you
> correctly used PHYS_MASK to extract the address, but here in the
> rollback path you use ~GITS_BASER_VALID.
>
> While both currently work because the upper bits and lower bits (below
> the page size) are defined as RES0 in the GIC spec, ~GITS_BASER_VALID
> is architecturally fragile. If a future hardware revision repurposes
> the upper RES0 bits [62:52] for new attributes (e.g., memory
> encryption flags), ~GITS_BASER_VALID will leak those attribute bits
> into the physical address calculation.
>
> Since PHYS_MASK correctly handles the address extraction across all
> page sizes (relying on the lower bits being RES0) and safely masks off
> future upper attribute bits, please standardize on using table_addr =
> table[i] & PHYS_MASK; for both functions.
>
>
Fixed the inconsistency and used PHYS_MASK everywhere.
> > + WARN_ON(__pkvm_hyp_donate_host(hyp_phys_to_pfn(table_addr), psz >> PAGE_SHIFT));
> > + }
> > +}
> > +
> > +static int pkvm_setup_its_shadow_baser(struct its_shadow_tables *shadow)
> > +{
> > + int i, ret;
> > + u64 baser_val, num_pages, type;
> > + void *base, *host_base;
> > +
> > + for (i = 0; i < GITS_BASER_NR_REGS; i++) {
> > + baser_val = shadow->tables[i].val;
> > + if (!(baser_val & GITS_BASER_VALID))
> > + continue;
> > +
> > + base = kern_hyp_va(shadow->tables[i].base);
> > + num_pages = (1 << shadow->tables[i].order);
> > +
> > + ret = __pkvm_host_donate_hyp(hyp_virt_to_pfn(base), num_pages);
> > + if (ret)
> > + goto err_donate;
> > +
> > + if (baser_val & GITS_BASER_INDIRECT) {
> > + host_base = kern_hyp_va(shadow->tables[i].shadow);
> > + ret = pkvm_share_shadow_table(host_base, num_pages);
> > + if (ret)
> > + goto err_with_donation;
> > +
> > + type = GITS_BASER_TYPE(baser_val);
> > + if (type == GITS_BASER_TYPE_COLLECTION)
> > + continue;
> > +
> > + ret = pkvm_host_unmap_last_level(base, num_pages,
> > + shadow->tables[i].psz);
> > + if (ret)
> > + goto err_with_share;
> > + }
> > + }
> > +
> > + return 0;
> > +err_with_share:
> > + pkvm_unshare_shadow_table(host_base, num_pages);
> > +err_with_donation:
> > + __pkvm_hyp_donate_host(hyp_virt_to_pfn(base), num_pages);
> > +err_donate:
> > + for (i = i - 1; i >= 0; i--) {
>
> Please use the while (i--) idiom for rollback loops.
>
>
> > + baser_val = shadow->tables[i].val;
> > + if (!(baser_val & GITS_BASER_VALID))
> > + continue;
> > +
> > + base = kern_hyp_va(shadow->tables[i].base);
> > + num_pages = (1 << shadow->tables[i].order);
> > +
> > + WARN_ON(__pkvm_hyp_donate_host(hyp_virt_to_pfn(base), num_pages));
>
> The sequence of rollback operations here creates a TOCTOU vulnerability.
>
There is a different problem here related to functionality rather than
this: donating the base to the host first and then iterating over it
will make the hypervisor explode. I fixed this.
> - First, you donate base (the Level 1 indirect table) back to the host.
> - Then, you pass base into pkvm_host_map_last_level().
> - Finally, pkvm_host_map_last_level() reads table[i] out of base to
> determine which Level 2 pages to donate back to the host.
>
> Because the host regains ownership of base _first_, it can be running
> concurrently on another CPU. A malicious host can overwrite the Level
> 1 table with pointers to arbitrary hypervisor-owned memory. The
> hypervisor will then read those malicious pointers and dutifully grant
> the host access to its own secure memory.
>
> The order of operations needs to be reversed: you must read base to
> roll back the L2 pages, unshare the shadow table, and *only then*
> donate base back to the host.
>
> Also, num_pages = (1 << shadow->tables[i].order); calculates a 32-bit
> signed integer because the literal 1 is a signed 32-bit int. If order
> is 31, this evaluates to a negative number. If order is 32 or higher,
> this is undefined behavior. Because num_pages is declared as a u64,
> you should use the standard kernel macro BIT_ULL().
>
> Here's my suggested fix (not tested). Reorder the operations to safely
> rollback L2 before donating L1, use the standard `while (i--)` loop,
> and fix the page calculation:
>
> + while (i--) {
> + baser_val = shadow->tables[i].val;
> + if (!(baser_val & GITS_BASER_VALID))
> + continue;
> +
> + base = kern_hyp_va(shadow->tables[i].base);
> + num_pages = BIT_ULL(shadow->tables[i].order);
> +
> + if (baser_val & GITS_BASER_INDIRECT) {
> + host_base = kern_hyp_va(shadow->tables[i].shadow);
> +
> + type = GITS_BASER_TYPE(baser_val);
> + if (type != GITS_BASER_TYPE_COLLECTION)
> + pkvm_host_map_last_level(base, num_pages,
> + shadow->tables[i].psz);
> +
> + pkvm_unshare_shadow_table(host_base, num_pages);
> + }
> +
> + WARN_ON(__pkvm_hyp_donate_host(hyp_virt_to_pfn(base), num_pages));
> + }
>
>
>
> > + if (baser_val & GITS_BASER_INDIRECT) {
> > + host_base = kern_hyp_va(shadow->tables[i].shadow);
> > + pkvm_unshare_shadow_table(host_base, num_pages);
> > +
> > + type = GITS_BASER_TYPE(baser_val);
> > + if (type == GITS_BASER_TYPE_COLLECTION)
> > + continue;
> > +
> > + pkvm_host_map_last_level(base, num_pages, shadow->tables[i].psz);
> > + }
> > + }
>
> You have duplicated the entire table decoding logic (calculating base,
> num_pages, checking INDIRECT...) down here in the rollback path.
> Consider abstracting "setup one table" and "teardown one table" into
> helper functions to make pkvm_setup_its_shadow_baser more readable and
> less prone to copy-pasta errors.
>
> Cheers,
> /fuad
>
Thanks,
Sebastian
>
> > +
> > + return ret;
> > +}
> > +
> > static int pkvm_setup_its_shadow_cmdq(struct its_shadow_tables *shadow)
> > {
> > int ret, i, num_pages;
> > @@ -205,6 +344,10 @@ int pkvm_init_gic_its_emulation(phys_addr_t dev_addr, void *host_priv_state,
> > if (ret)
> > goto err_with_shadow;
> >
> > + ret = pkvm_setup_its_shadow_baser(shadow);
> > + if (ret)
> > + goto err_with_shadow;
> > +
> > its_reg->priv = priv_state;
> >
> > hyp_spin_lock_init(&priv_state->its_lock);
> > --
> > 2.53.0.473.g4a7958ca14-goog
> >
^ permalink raw reply
* Re: [PATCH v3 0/4] mm: improve large folio readahead and alignment for exec memory
From: Lorenzo Stoakes @ 2026-04-10 13:50 UTC (permalink / raw)
To: Vlastimil Babka (SUSE)
Cc: Usama Arif, Andrew Morton, david, willy, ryan.roberts, linux-mm,
r, jack, ajd, apopple, baohua, baolin.wang, brauner,
catalin.marinas, dev.jain, kees, kevin.brodsky, lance.yang,
Liam.Howlett, linux-arm-kernel, linux-fsdevel, linux-kernel,
mhocko, npache, pasha.tatashin, rmclure, rppt, surenb, Al Viro,
ziy, hannes, kas, shakeel.butt, leitao, kernel-team
In-Reply-To: <40f31e5a-7161-4b17-af03-52b3a28a113e@kernel.org>
On Fri, Apr 10, 2026 at 03:29:12PM +0200, Vlastimil Babka (SUSE) wrote:
> On 4/10/26 14:24, Lorenzo Stoakes wrote:
> > On Fri, Apr 10, 2026 at 01:19:08PM +0100, Usama Arif wrote:
> >> >> Thanks, Lorenzo
> >> >
> >> > (Note that we're in a 'quiet period' from here until -rc1 of next cycle and
> >> > won't be taking anything new until then. We plan to do this from around rc5 or
> >> > rc6 of each cycle in future).
> >>
> >> Thanks! Just wanted to check, as I am always confused about this. Is it ok
> >> to send patches for review for next release at this time? So that they
> >> are in a good state when rc1 comes. I wanted to send PMD swap entries
> >> for review after I am finished testing, but I want them for review for
> >> next release.
> >
> > I think different people have different views on that :)
> >
> > I mean it's debateable whether having a glut of new material on day one of -rc1
> > is preferable to having a bunch come in that might or might not get lost along
> > the way :)
> >
> > I personally feel it'd be better to send during the cycle window rather than
> > before but I suspect others disagree with that!
> >
> > So from your point of view, feel free to do what you like, but maybe David +
> > others would want to chime in with their opinions?
>
> For me the more important part of the quiet period is that patches can't be
> merged, so there's less urgency to review them immediately. So I think it's
> fine to still send patches, but not having expectations about quick
> response, as people might be taking time off.
>
> On the other hand it would be better if new series could mature in this
> quiet period, so there would be less work after rc1. But the key to making
> that possible I think is to feel less urgency/being overwhelmed also in the
> non-quiet period (rc1-rc5/6). Then it's should be less necessary to take
> time off during the quiet period. So hopefully we'll get there through
> involving more reviewers, and by having more submaintainers agency.
Yeah I sympathise with that.
But until we for-sure have <you know what :))> signoff, I worry about the risk
of series 'just being taken' at -rc1 because it maybe seems easier to do that,
and then we have a series from 5 weeks ago you forgot about suddenly crop up.
So I guess the more nuanced take I have is:
Once we have a robust set up end-to-end _that can handle_ having series that are
deferred to next cycle without risk of things getting mixed up - then that makes
sense, yes.
But while there's still a bit of uncertainty around that, then I'd rather not.
But I think if people DO just resend their stuff in -rc1 then we're OK and it
addresses my concerns.
One thing we could do here is to tag series appropriately like:
[PATCH v7.2] 00/42
To make it clear where it's intended to head to.
P.S. Having the 'quiet period' REALLY REALLY helps. So thanks for that Andrew!
>
> Vlastimil
Thanks, Lorenzo
^ permalink raw reply
* Re: [patch 09/38] iommu/vt-d: Use sched_clock() instead of get_cycles()
From: Baolu Lu @ 2026-04-10 13:45 UTC (permalink / raw)
To: Thomas Gleixner, LKML
Cc: baolu.lu, x86, iommu, Arnd Bergmann, Michael Grzeschik, netdev,
linux-wireless, Herbert Xu, linux-crypto, Vlastimil Babka,
linux-mm, David Woodhouse, Bernie Thompson, linux-fbdev,
Theodore Tso, linux-ext4, Andrew Morton, Uladzislau Rezki,
Marco Elver, Dmitry Vyukov, kasan-dev, Andrey Ryabinin,
Thomas Sailer, linux-hams, Jason A. Donenfeld, Richard Henderson,
linux-alpha, Russell King, linux-arm-kernel, Catalin Marinas,
Huacai Chen, loongarch, Geert Uytterhoeven, linux-m68k,
Dinh Nguyen, Jonas Bonn, linux-openrisc, Helge Deller,
linux-parisc, Michael Ellerman, linuxppc-dev, Paul Walmsley,
linux-riscv, Heiko Carstens, linux-s390, David S. Miller,
sparclinux
In-Reply-To: <20260410120318.187521447@kernel.org>
On 4/10/2026 8:19 PM, Thomas Gleixner wrote:
> Calculating the timeout from get_cycles() is a historical leftover without
> any functional requirement.
>
> Use ktime_get() instead.
The subject line says "Use sched_clock() ...", but the implementation
actually uses ktime_get(). Is it a typo or anything I misunderstood?
Other parts look good to me,
Reviewed-by: Lu Baolu <baolu.lu@linux.intel.com>
>
> Signed-off-by: Thomas Gleixner<tglx@kernel.org>
> Cc:x86@kernel.org
> Cc: Lu Baolu<baolu.lu@linux.intel.com>
> Cc:iommu@lists.linux.dev
> ---
> arch/x86/include/asm/iommu.h | 3 ---
> drivers/iommu/intel/dmar.c | 4 ++--
> drivers/iommu/intel/iommu.h | 8 ++++++--
> 3 files changed, 8 insertions(+), 7 deletions(-)
Thanks,
baolu
^ permalink raw reply
* Re: [PATCH v3 4/7] arm64: dts: ti: k3-am62a7-sk: Split r5f memory region
From: Markus Schneider-Pargmann @ 2026-04-10 13:42 UTC (permalink / raw)
To: Vignesh Raghavendra, Markus Schneider-Pargmann (TI),
Bjorn Andersson, Mathieu Poirier, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Suman Anna, Nishanth Menon,
Tero Kristo
Cc: Vishal Mahaveer, Kevin Hilman, Dhruva Gole, Sebin Francis,
Kendall Willis, Akashdeep Kaur, linux-remoteproc, devicetree,
linux-kernel, linux-arm-kernel
In-Reply-To: <8673745d-aad2-49d3-b3af-556de7037b69@ti.com>
[-- Attachment #1: Type: text/plain, Size: 1864 bytes --]
Hi Vignesh,
On Fri Apr 10, 2026 at 6:30 AM CEST, Vignesh Raghavendra wrote:
> Hi Markus
>
> On 18/03/26 20:43, Markus Schneider-Pargmann (TI) wrote:
>> Split the firmware memory region in more specific parts so it is better
>> described where to find which information. Specifically the LPM metadata
>> region is important as bootloader software like U-Boot has to know where
>> that data is to be able to read that data.
>>
>> Signed-off-by: Markus Schneider-Pargmann (TI) <msp@baylibre.com>
>> ---
>> arch/arm64/boot/dts/ti/k3-am62a7-sk.dts | 40 +++++++++++++++++++++++++++++++--
>> 1 file changed, 38 insertions(+), 2 deletions(-)
>>
>> diff --git a/arch/arm64/boot/dts/ti/k3-am62a7-sk.dts b/arch/arm64/boot/dts/ti/k3-am62a7-sk.dts
>> index e99bdbc2e0cbdf858f1631096f9c2a086191bab3..c381cc33064ec427751a9ac5bcdff745a9559a89 100644
>> --- a/arch/arm64/boot/dts/ti/k3-am62a7-sk.dts
>> +++ b/arch/arm64/boot/dts/ti/k3-am62a7-sk.dts
>> @@ -59,9 +59,33 @@ wkup_r5fss0_core0_dma_memory_region: memory@9c800000 {
>> no-map;
>> };
>>
>> - wkup_r5fss0_core0_memory_region: memory@9c900000 {
>> + wkup_r5fss0_core0_ipc_region: memory@9c900000 {
>
> There are still references to wkup_r5fss0_core0_memory_region in
> k3-am62a-ti-ipc-firmware.dtsi (same comment applies to next 2 patches as
> well)
>
> Dont those need to be updated too?
I only updated the sk boards as these are the only ones that have IO+DDR
support that I know works and need the new memory region layout. But
thinking about this, updating the memory region structure shouldn't be a
problem for the other boards either, of course I can't tell if IO+DDR
would work on them, but the new memory region layout shouldn't break
anything.
I can respin the series or do a followup series with modifications for
all boards if you like.
Best
Markus
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 289 bytes --]
^ permalink raw reply
* Re: [patch 19/38] kcsan: Replace get_cycles() usage
From: Marco Elver @ 2026-04-10 13:39 UTC (permalink / raw)
To: Thomas Gleixner
Cc: LKML, Dmitry Vyukov, kasan-dev, Arnd Bergmann, x86, Lu Baolu,
iommu, Michael Grzeschik, netdev, linux-wireless, Herbert Xu,
linux-crypto, Vlastimil Babka, linux-mm, David Woodhouse,
Bernie Thompson, linux-fbdev, Theodore Tso, linux-ext4,
Andrew Morton, Uladzislau Rezki, Andrey Ryabinin, Thomas Sailer,
linux-hams, Jason A. Donenfeld, Richard Henderson, linux-alpha,
Russell King, linux-arm-kernel, Catalin Marinas, Huacai Chen,
loongarch, Geert Uytterhoeven, linux-m68k, Dinh Nguyen,
Jonas Bonn, linux-openrisc, Helge Deller, linux-parisc,
Michael Ellerman, linuxppc-dev, Paul Walmsley, linux-riscv,
Heiko Carstens, linux-s390, David S. Miller, sparclinux
In-Reply-To: <20260410120318.862164111@kernel.org>
On Fri, 10 Apr 2026 at 14:20, Thomas Gleixner <tglx@kernel.org> wrote:
>
> KCSAN uses get_cycles() for two purposes:
>
> 1) Seeding the random state with get_cycles() is a historical leftover.
>
> 2) The microbenchmark uses get_cycles(), which provides an unit less
> counter value and is not guaranteed to be functional on all
> systems/platforms.
>
> Use random_get_entropy() for seeding the random state and ktime_get() which
> is universaly functional and provides at least a comprehensible unit.
>
> This is part of a larger effort to remove get_cycles() usage from
> non-architecture code.
>
> Signed-off-by: Thomas Gleixner <tglx@kernel.org>
> Cc: Marco Elver <elver@google.com>
> Cc: Dmitry Vyukov <dvyukov@google.com>
> Cc: kasan-dev@googlegroups.com
Reviewed-by: Marco Elver <elver@google.com>
> ---
> kernel/kcsan/core.c | 2 +-
> kernel/kcsan/debugfs.c | 8 ++++----
> 2 files changed, 5 insertions(+), 5 deletions(-)
>
> --- a/kernel/kcsan/core.c
> +++ b/kernel/kcsan/core.c
> @@ -798,7 +798,7 @@ void __init kcsan_init(void)
> BUG_ON(!in_task());
>
> for_each_possible_cpu(cpu)
> - per_cpu(kcsan_rand_state, cpu) = (u32)get_cycles();
> + per_cpu(kcsan_rand_state, cpu) = (u32)random_get_entropy();
>
> /*
> * We are in the init task, and no other tasks should be running;
> --- a/kernel/kcsan/debugfs.c
> +++ b/kernel/kcsan/debugfs.c
> @@ -58,7 +58,7 @@ static noinline void microbenchmark(unsi
> {
> const struct kcsan_ctx ctx_save = current->kcsan_ctx;
> const bool was_enabled = READ_ONCE(kcsan_enabled);
> - u64 cycles;
> + ktime_t nsecs;
>
> /* We may have been called from an atomic region; reset context. */
> memset(¤t->kcsan_ctx, 0, sizeof(current->kcsan_ctx));
> @@ -70,16 +70,16 @@ static noinline void microbenchmark(unsi
>
> pr_info("%s begin | iters: %lu\n", __func__, iters);
>
> - cycles = get_cycles();
> + nsecs = ktime_get();
> while (iters--) {
> unsigned long addr = iters & ((PAGE_SIZE << 8) - 1);
> int type = !(iters & 0x7f) ? KCSAN_ACCESS_ATOMIC :
> (!(iters & 0xf) ? KCSAN_ACCESS_WRITE : 0);
> __kcsan_check_access((void *)addr, sizeof(long), type);
> }
> - cycles = get_cycles() - cycles;
> + nsecs = ktime_get() - nsecs;
>
> - pr_info("%s end | cycles: %llu\n", __func__, cycles);
> + pr_info("%s end | nsecs: %llu\n", __func__, nsecs);
>
> WRITE_ONCE(kcsan_enabled, was_enabled);
> /* restore context */
>
^ permalink raw reply
* Re: [PATCH v3 0/4] mm: improve large folio readahead and alignment for exec memory
From: Vlastimil Babka (SUSE) @ 2026-04-10 13:29 UTC (permalink / raw)
To: Lorenzo Stoakes, Usama Arif
Cc: Andrew Morton, david, willy, ryan.roberts, linux-mm, r, jack, ajd,
apopple, baohua, baolin.wang, brauner, catalin.marinas, dev.jain,
kees, kevin.brodsky, lance.yang, Liam.Howlett, linux-arm-kernel,
linux-fsdevel, linux-kernel, mhocko, npache, pasha.tatashin,
rmclure, rppt, surenb, Al Viro, ziy, hannes, kas, shakeel.butt,
leitao, kernel-team
In-Reply-To: <adjrKwgiZwXR9epk@lucifer>
On 4/10/26 14:24, Lorenzo Stoakes wrote:
> On Fri, Apr 10, 2026 at 01:19:08PM +0100, Usama Arif wrote:
>> >> Thanks, Lorenzo
>> >
>> > (Note that we're in a 'quiet period' from here until -rc1 of next cycle and
>> > won't be taking anything new until then. We plan to do this from around rc5 or
>> > rc6 of each cycle in future).
>>
>> Thanks! Just wanted to check, as I am always confused about this. Is it ok
>> to send patches for review for next release at this time? So that they
>> are in a good state when rc1 comes. I wanted to send PMD swap entries
>> for review after I am finished testing, but I want them for review for
>> next release.
>
> I think different people have different views on that :)
>
> I mean it's debateable whether having a glut of new material on day one of -rc1
> is preferable to having a bunch come in that might or might not get lost along
> the way :)
>
> I personally feel it'd be better to send during the cycle window rather than
> before but I suspect others disagree with that!
>
> So from your point of view, feel free to do what you like, but maybe David +
> others would want to chime in with their opinions?
For me the more important part of the quiet period is that patches can't be
merged, so there's less urgency to review them immediately. So I think it's
fine to still send patches, but not having expectations about quick
response, as people might be taking time off.
On the other hand it would be better if new series could mature in this
quiet period, so there would be less work after rc1. But the key to making
that possible I think is to feel less urgency/being overwhelmed also in the
non-quiet period (rc1-rc5/6). Then it's should be less necessary to take
time off during the quiet period. So hopefully we'll get there through
involving more reviewers, and by having more submaintainers agency.
Vlastimil
^ permalink raw reply
* Re: [PATCH v5 4/4] arm64: errata: Work around early CME DVMSync acknowledgement
From: Will Deacon @ 2026-04-10 13:26 UTC (permalink / raw)
To: Catalin Marinas; +Cc: linux-arm-kernel, James Morse, Mark Rutland, Mark Brown
In-Reply-To: <adjzVTjEOz7DGmW4@arm.com>
On Fri, Apr 10, 2026 at 01:55:49PM +0100, Catalin Marinas wrote:
> On Fri, Apr 10, 2026 at 01:09:41PM +0100, Will Deacon wrote:
> > On Tue, Apr 07, 2026 at 11:28:44AM +0100, Catalin Marinas wrote:
> > > diff --git a/arch/arm64/kernel/process.c b/arch/arm64/kernel/process.c
> > > index 489554931231..4c328b7c79ba 100644
> > > --- a/arch/arm64/kernel/process.c
> > > +++ b/arch/arm64/kernel/process.c
> > > @@ -26,6 +26,7 @@
> > > #include <linux/reboot.h>
> > > #include <linux/interrupt.h>
> > > #include <linux/init.h>
> > > +#include <linux/cpumask.h>
> > > #include <linux/cpu.h>
> > > #include <linux/elfcore.h>
> > > #include <linux/pm.h>
> > > @@ -339,8 +340,41 @@ void flush_thread(void)
> > > flush_gcs();
> > > }
> > >
> > > +#ifdef CONFIG_ARM64_ERRATUM_4193714
> > > +
> > > +static void arch_dup_tlbbatch_mask(struct task_struct *dst)
> > > +{
> > > + /*
> > > + * Clear the inherited cpumask with memset() to cover both cases where
> > > + * cpumask_var_t is a pointer or an array. It will be allocated lazily
> > > + * in sme_dvmsync_add_pending() if CPUMASK_OFFSTACK=y.
> > > + */
> > > + if (alternative_has_cap_unlikely(ARM64_WORKAROUND_4193714))
> > > + memset(&dst->tlb_ubc.arch.cpumask, 0,
> > > + sizeof(dst->tlb_ubc.arch.cpumask));
> >
> > nit: use cpumask_clear() instead?
>
> I tried to explain in the comment above. The memset() is on purpose to
> avoid #ifdef CPUMASK_OFFSTACK. When enabled, cpumask_var_t is a pointer
> and we want it set to NULL (for later lazy allocation) rather than
> clearing the parent's cpumask. I had the diff below initially but it
> looked uglier. Or we make the erratum dependent on !CPUMASK_OFFSTACK but
> it won't get compile coverage with defconfig.
Sorry, my mistake. I was focussing on the mm_cpumask() changes since v3
(which always seem to be embedded as part of the 'mm_struct' allocation)
and didn't realise that this memset() is operating on the TLB batch
cpumask.
So it looks like v5 is the charm :)
Will
^ permalink raw reply
* [GIT PULL] ARM: mvebu: dt64 for v7.1 (#1)
From: Gregory CLEMENT @ 2026-04-10 13:25 UTC (permalink / raw)
To: Arnd Bergmann, arm, soc
Cc: Andrew Lunn, Sebastian Hesselbarth, linux-arm-kernel
Hi,
Here is the first pull request for dt64 for mvebu for v7.1.
Gregory
The following changes since commit 6de23f81a5e08be8fbf5e8d7e9febc72a5b5f27f:
Linux 7.0-rc1 (2026-02-22 13:18:59 -0800)
are available in the Git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/gclement/mvebu.git tags/mvebu-dt64-7.1-1
for you to fetch changes up to 00e6d608fe80b0f68c325cb46862f78e9a8ec768:
arm64: dts: marvell: armada-37xx: swap PHYs' order in USB3 controller node (2026-04-09 10:14:40 +0200)
----------------------------------------------------------------
mvebu dt64 for 7.1 (part 1)
- Armada 37xx/3720 device tree fixes:
- Reorder USB PHYs, standardize names, drop undocumented
properties, fix schema alignment
- Add Marvell 7k COMe board bindings and uDPU ethernet aliases
- Cleanup: drop unused .dtsi files
----------------------------------------------------------------
Elad Nachman (2):
arm64: dts: a7k: use phy handle
dt-bindings: arm64: add Marvell 7k COMe boards
Gabor Juhos (6):
arm64: dts: marvell: armada-3720: drop 'marvell,xenon-emmc' properties
arm64: dts: marvell: armada-37xx: align 'phy-names' of EHCI node with DT schema
arm64: dts: marvell: armada-37xx: drop redundant status property
arm64: dts: marvell: armada-37xx: drop 'marvell,usb-misc-reg' from USB host nodes
arm64: dts: marvell: armada-37xx: use 'usb2-phy' in USB3 controller's phy-names
arm64: dts: marvell: armada-37xx: swap PHYs' order in USB3 controller node
Rob Herring (Arm) (1):
arm/arm64: dts: marvell: Drop unused .dtsi
Robert Marko (1):
arm64: dts: marvell: uDPU: add ethernet aliases
.../bindings/arm/marvell/armada-7k-8k.yaml | 11 ++
arch/arm/boot/dts/marvell/armada-380.dtsi | 148 ---------------------
.../boot/dts/marvell/armada-3720-atlas-v5.dts | 1 -
.../boot/dts/marvell/armada-3720-espressobin.dtsi | 1 -
arch/arm64/boot/dts/marvell/armada-3720-uDPU.dtsi | 7 +-
arch/arm64/boot/dts/marvell/armada-37xx.dtsi | 9 +-
.../boot/dts/marvell/armada-7020-comexpress.dtsi | 2 +-
arch/arm64/boot/dts/marvell/armada-8020.dtsi | 20 ---
.../boot/dts/marvell/cn9130-db-comexpress.dtsi | 96 -------------
9 files changed, 21 insertions(+), 274 deletions(-)
delete mode 100644 arch/arm/boot/dts/marvell/armada-380.dtsi
delete mode 100644 arch/arm64/boot/dts/marvell/armada-8020.dtsi
delete mode 100644 arch/arm64/boot/dts/marvell/cn9130-db-comexpress.dtsi
--
Grégory CLEMENT, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com
^ permalink raw reply
* Re: [PATCH net-next v3 01/12] dt-bindings: net: airoha: Add EN7581 ethernet-ports properties
From: Lorenzo Bianconi @ 2026-04-10 13:14 UTC (permalink / raw)
To: Jakub Kicinski
Cc: andrew+netdev, davem, edumazet, pabeni, robh, krzk+dt, conor+dt,
ansuelsmth, benjamin.larsson, linux-arm-kernel, linux-mediatek,
netdev, devicetree
In-Reply-To: <20260410025717.1809904-1-kuba@kernel.org>
[-- Attachment #1: Type: text/plain, Size: 2119 bytes --]
> This is an AI-generated review of your patch. The human sending this
> email says "For your consideration."
> ---
> dt-bindings: net: airoha: Add EN7581 ethernet-ports properties
>
> This commit introduces the ethernet-port property to model a net_device
> connected via an external arbiter to the GDM3 or GDM4 ports on EN7581
> and AN7583 SoCs.
>
> > diff --git a/Documentation/devicetree/bindings/net/airoha,en7581-eth.yaml b/Documentation/devicetree/bindings/net/airoha,en7581-eth.yaml
> > index fbe2ddcdd909c..ebbd433e9c9fb 100644
> > --- a/Documentation/devicetree/bindings/net/airoha,en7581-eth.yaml
> > +++ b/Documentation/devicetree/bindings/net/airoha,en7581-eth.yaml
> > @@ -130,6 +130,30 @@ patternProperties:
> > maximum: 4
> > description: GMAC port identifier
> >
> > + '#address-cells':
> > + const: 1
> > + '#size-cells':
> > + const: 0
> > +
> > + patternProperties:
> > + "^ethernet-port@[0-5]$":
>
> The commit message states that GDM1 and GDM2 do not support connection
> with the external arbiter. However, since this pattern property appears to
> be placed inside the generic ^ethernet@[1-4]$ block, does this allow a
> device tree to incorrectly configure ethernet-port subnodes on ethernet@1
> or ethernet@2 and still pass schema validation?
ack, I will fix it in v4
>
> Could this be restricted to GDM3 and GDM4, perhaps by splitting the
> patternProperties or using an if/then block based on the reg property?
>
> > + type: object
> > + unevaluatedProperties: false
> > + $ref: ethernet-controller.yaml#
>
> Does referencing ethernet-controller.yaml cause a validation conflict here?
>
> The ethernet-controller.yaml schema enforces a strict nodename pattern
> of ^ethernet(@.*)?$. Since these new nodes use the -port suffix and are
> named ethernet-port@X, will they unconditionally fail the node name
> validation enforced by the referenced schema during dt_binding_check?
ack, I will fix it in v4
Regards,
Lorenzo
>
> [ ... ]
> --
> pw-bot: cr
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
^ 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