* Re: [PATCH v3 02/11] iommu: Pass in reset result to pci_dev_reset_iommu_done()
From: Nicolin Chen @ 2026-04-24 2:46 UTC (permalink / raw)
To: Baolu Lu
Cc: Will Deacon, Robin Murphy, Joerg Roedel, Bjorn Helgaas,
Jason Gunthorpe, Rafael J . Wysocki, Len Brown,
Pranjal Shrivastava, Mostafa Saleh, Kevin Tian, linux-arm-kernel,
iommu, linux-kernel, linux-acpi, linux-pci, vsethi, Shuai Xue
In-Reply-To: <c8c8b482-3781-4d33-9aea-866467d15b69@linux.intel.com>
On Fri, Apr 24, 2026 at 10:38:09AM +0800, Baolu Lu wrote:
> On 4/17/26 07:28, Nicolin Chen wrote:
> > @@ -4083,6 +4093,18 @@ void pci_dev_reset_iommu_done(struct pci_dev *pdev)
> > if (WARN_ON(!group->blocking_domain))
> > return;
> > + /*
> > + * A reset failure implies that the device might be unreliable. E.g. its
> > + * device cache might retain stale entries, which potentially results in
> > + * memory corruption. Thus, do not unblock the device until a successful
> > + * reset.
> > + */
> > + if (!reset_succeeds) {
> > + pci_err(pdev,
> > + "Reset failed. Keep it blocked to protect memory\n");
> > + return;
> > + }
>
> Nit: pci_dev_reset_iommu_done() does nothing if reset_succeeds is false.
> Would it be better to handle this in the caller instead? Something like:
>
> if (reset_succeeds)
> pci_dev_reset_iommu_done(dev);
>
> ?
It would also need a print and some duplicated comments. Actually,
that would be my v2, which Kevin suggested this against:
https://lore.kernel.org/all/BN9PR11MB5276706AE4E0BBE86F0F6E158C4EA@BN9PR11MB5276.namprd11.prod.outlook.com/
Though I don't have a strong personal reference here, I do see this
version slightly cleaner than doing in the callers.
Thanks
Nicolin
^ permalink raw reply
* Re: [PATCH v3 04/11] iommu: Add __iommu_group_block_device helper
From: Baolu Lu @ 2026-04-24 2:40 UTC (permalink / raw)
To: Nicolin Chen, Will Deacon, Robin Murphy, Joerg Roedel,
Bjorn Helgaas, Jason Gunthorpe
Cc: Rafael J . Wysocki, Len Brown, Pranjal Shrivastava, Mostafa Saleh,
Kevin Tian, linux-arm-kernel, iommu, linux-kernel, linux-acpi,
linux-pci, vsethi, Shuai Xue
In-Reply-To: <5bf2e259f80696c498cb15f40452862e4b43a295.1776381841.git.nicolinc@nvidia.com>
On 4/17/26 07:28, Nicolin Chen wrote:
> Move the RID/PASID blocking routine into a separate helper, which will be
> reused by a new function to quarantine the device but does not bother the
> gdev->reset_depth counter.
>
> No functional changes.
>
> Suggested-by: Kevin Tian<kevin.tian@intel.com>
> Signed-off-by: Nicolin Chen<nicolinc@nvidia.com>
> ---
> drivers/iommu/iommu.c | 99 ++++++++++++++++++++++++-------------------
> 1 file changed, 56 insertions(+), 43 deletions(-)
Reviewed-by: Lu Baolu <baolu.lu@linux.intel.com>
^ permalink raw reply
* Re: [PATCH v3 03/11] iommu: Add reset_device_done callback for hardware fault recovery
From: Baolu Lu @ 2026-04-24 2:40 UTC (permalink / raw)
To: Nicolin Chen, Will Deacon, Robin Murphy, Joerg Roedel,
Bjorn Helgaas, Jason Gunthorpe
Cc: Rafael J . Wysocki, Len Brown, Pranjal Shrivastava, Mostafa Saleh,
Kevin Tian, linux-arm-kernel, iommu, linux-kernel, linux-acpi,
linux-pci, vsethi, Shuai Xue
In-Reply-To: <c90693e75c0610da38103a683b558d5596bd843b.1776381841.git.nicolinc@nvidia.com>
On 4/17/26 07:28, Nicolin Chen wrote:
> When an IOMMU hardware detects an error due to a faulty device (e.g. an ATS
> invalidation timeout), IOMMU drivers may quarantine the device by disabling
> specific hardware features or dropping translation capabilities.
>
> To recover from these states, the IOMMU driver needs a reliable signal that
> the underlying physical hardware has been cleanly reset (e.g., via PCIe AER
> or a sysfs Function Level Reset) so as to lift the quarantine.
>
> Introduce a reset_device_done callback in struct iommu_ops. Trigger it from
> the existing pci_dev_reset_iommu_done() path to notify the underlying IOMMU
> driver that the device's internal state has been sanitized.
>
> Signed-off-by: Nicolin Chen<nicolinc@nvidia.com>
> ---
> include/linux/iommu.h | 4 ++++
> drivers/iommu/iommu.c | 12 ++++++++++++
> 2 files changed, 16 insertions(+)
Reviewed-by: Lu Baolu <baolu.lu@linux.intel.com>
^ permalink raw reply
* Re: [PATCH v3 02/11] iommu: Pass in reset result to pci_dev_reset_iommu_done()
From: Baolu Lu @ 2026-04-24 2:38 UTC (permalink / raw)
To: Nicolin Chen, Will Deacon, Robin Murphy, Joerg Roedel,
Bjorn Helgaas, Jason Gunthorpe
Cc: Rafael J . Wysocki, Len Brown, Pranjal Shrivastava, Mostafa Saleh,
Kevin Tian, linux-arm-kernel, iommu, linux-kernel, linux-acpi,
linux-pci, vsethi, Shuai Xue
In-Reply-To: <bf99f11ac9a42b5552ec3367d02840366459ae7b.1776381841.git.nicolinc@nvidia.com>
On 4/17/26 07:28, Nicolin Chen wrote:
> IOMMU drivers handle ATC cache maintenance. They may encounter ATC-related
> errors (e.g., ATC invalidation request timeout), indicating that ATC cache
> might have stale entries that can corrupt the memory. In this case, IOMMU
> driver has no choice but to block the device's ATS function and wait for a
> device recovery.
>
> The pci_dev_reset_iommu_done() called at the end of a reset function could
> serve as a reliable signal to the IOMMU subsystem that the physical device
> cache is completely clean. However, the function is called unconditionally
> even if the reset operation had actually failed, which would re-attach the
> faulty device back to a normal translation domain. And this will leave the
> system highly exposed, creating vulnerabilities for data corruption:
> IOMMU blocks RID/ATS
> pci_reset_function():
> pci_dev_reset_iommu_prepare(); // Block RID/ATS
> __reset(); // Failed (ATC is still stale)
> pci_dev_reset_iommu_done(); // Unblock RID/ATS (ah-ha)
>
> Instead, add a @reset_succeeds parameter to pci_dev_reset_iommu_done() and
> pass the reset result from each caller:
> IOMMU blocks RID/ATS
> pci_reset_function():
> pci_dev_reset_iommu_prepare(); // Block RID/ATS
> rc = __reset();
> pci_dev_reset_iommu_done(!rc); // Unblock or quarantine
>
> On a successful reset, done() restores the device to its RID/PASID domains
> and decrements group->recovery_cnt. On failure, the device remains blocked,
> and concurrent domain attachment will be rejected until a successful reset.
>
> Suggested-by: Kevin Tian<kevin.tian@intel.com>
> Signed-off-by: Nicolin Chen<nicolinc@nvidia.com>
> ---
> include/linux/iommu.h | 5 +++--
> drivers/iommu/iommu.c | 28 +++++++++++++++++++++++++---
> drivers/pci/pci-acpi.c | 2 +-
> drivers/pci/pci.c | 10 +++++-----
> drivers/pci/quirks.c | 2 +-
> 5 files changed, 35 insertions(+), 12 deletions(-)
>
> diff --git a/include/linux/iommu.h b/include/linux/iommu.h
> index 54b8b48c762e8..d3685967e960a 100644
> --- a/include/linux/iommu.h
> +++ b/include/linux/iommu.h
> @@ -1191,7 +1191,7 @@ void iommu_free_global_pasid(ioasid_t pasid);
>
> /* PCI device reset functions */
> int pci_dev_reset_iommu_prepare(struct pci_dev *pdev);
> -void pci_dev_reset_iommu_done(struct pci_dev *pdev);
> +void pci_dev_reset_iommu_done(struct pci_dev *pdev, bool reset_succeeds);
> #else /* CONFIG_IOMMU_API */
>
> struct iommu_ops {};
> @@ -1521,7 +1521,8 @@ static inline int pci_dev_reset_iommu_prepare(struct pci_dev *pdev)
> return 0;
> }
>
> -static inline void pci_dev_reset_iommu_done(struct pci_dev *pdev)
> +static inline void pci_dev_reset_iommu_done(struct pci_dev *pdev,
> + bool reset_succeeds)
> {
> }
> #endif /* CONFIG_IOMMU_API */
> diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
> index ff181db687bbf..28d4c1f143a08 100644
> --- a/drivers/iommu/iommu.c
> +++ b/drivers/iommu/iommu.c
> @@ -80,6 +80,7 @@ struct group_device {
> * Device is blocked for a pending recovery while its group->domain is
> * retained. This can happen when:
> * - Device is undergoing a reset
> + * - Device failed the last reset
> */
> bool blocked;
> unsigned int reset_depth;
> @@ -3971,7 +3972,9 @@ EXPORT_SYMBOL_NS_GPL(iommu_replace_group_handle, "IOMMUFD_INTERNAL");
> * reset is finished, pci_dev_reset_iommu_done() can restore everything.
> *
> * Caller must use pci_dev_reset_iommu_prepare() with pci_dev_reset_iommu_done()
> - * before/after the core-level reset routine, to decrement the recovery_cnt.
> + * before/after the core-level reset routine. On a successful reset, done() will
> + * decrement group->recovery_cnt and restore domains. On a failure, recovery_cnt
> + * is left intact and the device stays blocked.
> *
> * Return: 0 on success or negative error code if the preparation failed.
> *
> @@ -4000,6 +4003,9 @@ int pci_dev_reset_iommu_prepare(struct pci_dev *pdev)
>
> if (gdev->reset_depth++)
> return 0;
> + /* Device might be already blocked for a quarantine */
> + if (gdev->blocked)
> + return 0;
>
> ret = __iommu_group_alloc_blocking_domain(group);
> if (ret)
> @@ -4047,18 +4053,22 @@ EXPORT_SYMBOL_GPL(pci_dev_reset_iommu_prepare);
> /**
> * pci_dev_reset_iommu_done() - Restore IOMMU after a PCI device reset is done
> * @pdev: PCI device that has finished a reset routine
> + * @reset_succeeds: Whether the PCI device reset is successful or not
> *
> * After a PCIe device finishes a reset routine, it wants to restore its IOMMU
> * activity, including new translation and cache invalidation, by re-attaching
> * all RID/PASID of the device back to the domains retained in the core-level
> * structure.
> *
> - * Caller must pair it with a successful pci_dev_reset_iommu_prepare().
> + * This is a pairing function for pci_dev_reset_iommu_prepare(). Caller should
> + * pass in the reset state via @reset_succeeds. On a failed reset, the device
> + * remains blocked for a quarantine with the group->recovery_cnt intact, so as
> + * to protect system memory until a subsequent successful reset.
> *
> * Note that, although unlikely, there is a risk that re-attaching domains might
> * fail due to some unexpected happening like OOM.
> */
> -void pci_dev_reset_iommu_done(struct pci_dev *pdev)
> +void pci_dev_reset_iommu_done(struct pci_dev *pdev, bool reset_succeeds)
> {
> struct iommu_group *group = pdev->dev.iommu_group;
> struct group_device *gdev;
> @@ -4083,6 +4093,18 @@ void pci_dev_reset_iommu_done(struct pci_dev *pdev)
> if (WARN_ON(!group->blocking_domain))
> return;
>
> + /*
> + * A reset failure implies that the device might be unreliable. E.g. its
> + * device cache might retain stale entries, which potentially results in
> + * memory corruption. Thus, do not unblock the device until a successful
> + * reset.
> + */
> + if (!reset_succeeds) {
> + pci_err(pdev,
> + "Reset failed. Keep it blocked to protect memory\n");
> + return;
> + }
Nit: pci_dev_reset_iommu_done() does nothing if reset_succeeds is false.
Would it be better to handle this in the caller instead? Something like:
if (reset_succeeds)
pci_dev_reset_iommu_done(dev);
?
> +
> /* Re-attach RID domain back to group->domain */
> if (group->domain != group->blocking_domain) {
> WARN_ON(__iommu_attach_device(group->domain, &pdev->dev,
Thanks,
baolu
^ permalink raw reply
* Re: [PATCH v3 06/11] iommu: Defer __iommu_group_free_device() to be outside group->mutex
From: Baolu Lu @ 2026-04-24 2:29 UTC (permalink / raw)
To: Nicolin Chen
Cc: Will Deacon, Robin Murphy, Joerg Roedel, Bjorn Helgaas,
Jason Gunthorpe, Rafael J . Wysocki, Len Brown,
Pranjal Shrivastava, Mostafa Saleh, Kevin Tian, linux-arm-kernel,
iommu, linux-kernel, linux-acpi, linux-pci, vsethi, Shuai Xue
In-Reply-To: <aeo/BDwYM9yYHctI@Asurada-Nvidia>
On 4/23/26 23:47, Nicolin Chen wrote:
> On Thu, Apr 23, 2026 at 03:55:02PM +0800, Baolu Lu wrote:
>> On 4/17/26 07:28, Nicolin Chen wrote:
>>> +static void __iommu_group_empty_assert_owner_cnt(struct iommu_group *group)
>>> +{
>>> + lockdep_assert_held(&group->mutex);
>>> + /*
>>> + * If the group has become empty then ownership must have been
>>> + * released, and the current domain must be set back to NULL or
>>> + * the default domain.
>>> + */
>>
>> Nit: this comment doesn't quite match the following code. The code
>> doesn't check "group->domain != NULL". Or perhaps in that case,
>> group->default_domain must be NULL?
>
> This is the original patch from Jason:
> https://lore.kernel.org/r/4-v3-328044aa278c+45e49-iommu_probe_jgg@nvidia.com
>
> I kept the comments as-is, though It might be slightly confusing?
>
> I think it means:
> If group->default_domain == NULL, it does check "set back to NULL".
> If group->default_domain != NULL, it then checks "default domain".
>
> Maybe it could be "must be set back to the default domain (which
> itself can be NULL"?
This is clearer. As I understand it, when the last device leaves the
iommu_group, the group->domain should be one of the static system
domains, either the default domain or the blocking domain.
>
>> Furthermore, if a device is currently quarantined, group->domain will be
>> the blocking_domain. If that quarantined device is then hot-removed and
>> happens to be the last device in the group, will this WARN_ON trigger
>> unnecessarily?
>
> If a device is quarantined, its group->domain is retained to the
> previously attached domain. Its blocking state is logged in the
> gdev->blocked flag. So, I think it can pass the test.
Oh, my mistake. I thought group->domain would point to the blocking
domain when a device is quarantined. It's fine if group->domain remains
set to the previous domain.
> Thanks
> Nicolin
Thanks,
baolu
^ permalink raw reply
* Re: [PATCH] cpu/hotplug: Fix NULL kobject warning in cpuhp_smt_enable()
From: Jinjie Ruan @ 2026-04-24 1:56 UTC (permalink / raw)
To: Catalin Marinas
Cc: Thomas Gleixner, peterz, sudeep.holla, yangyicong,
dietmar.eggemann, Jonathan.Cameron, linux-kernel, James Morse,
linux-arm-kernel
In-Reply-To: <aep85G05D3TM9uj2@arm.com>
On 4/24/2026 4:11 AM, Catalin Marinas wrote:
> On Thu, Apr 23, 2026 at 08:32:34PM +0800, Jinjie Ruan wrote:
>> On 4/23/2026 6:08 PM, Thomas Gleixner wrote:
>>> On Sat, Apr 18 2026 at 12:55, Catalin Marinas wrote:
>>>> Another option would have been to avoid marking such CPUs present but I
>>>> think this will break other things. Yet another option is to register
>>>> all CPU devices even if they never come up (like maxcpus greater than
>>>> actual CPUs).
>>>>
>>>> Opinions? It might be an arm64+ACPI-only thing.
>>>
>>> I think so. The proper thing to do is to apply sane limits:
>>>
>>> 1) The possible CPUs enumerated by firmware N_POSSIBLE_FW
>>>
>>> 2) The maxcpus limit on the command line N_MAXCPUS_CL
>>>
>>> So the actual possible CPUs evaluates to:
>>>
>>> num_possible = min(N_POSSIBLE_FW, N_MAXCPUS_CL, CONFIG_NR_CPUS);
>>>
>>> The evaluation of the firmware should not mark CPUs present which are
>>> actually not. ACPI gives you that information. See:
>>>
>>> 5.2.12.14 GIC CPU Interface (GICC) Structure
>>>
>>> in the ACPI spec. That has two related bits:
>>>
>>> Enabled:
>>>
>>> If this bit is set, the processor is ready for use. If this bit is
>>> clear and the Online Capable bit is set, the system supports enabling
>>> this processor during OS runtime. If this bit is clear and the Online
>>> Capable bit is also clear, this processor is un- usable, and the
>>> operating system support will not attempt to use it.
>>>
>>> Online Capable:
>>>
>>> The information conveyed by this bit depends on the value of the
>>> Enabled bit. If the Enabled bit is set, this bit is reserved and must
>>> be zero. Otherwise, if this bit is set, the system supports enabling
>>> this processor later during OS runtime
>>>
>>> So the combination of those gives you the right answer:
>>>
>>> Enabled Online
>>> Capable
>>> 0 0 Not present, not possible
>>> 0 1 Not present, but possible to "hotplug" layter
>>> 1 0 Present
>>> 1 1 Invalid
>>
>> On x86, it seems that all CPUs with the ACPI_MADT_ENABLED bit set will
>> be marked as present.
>>
>> acpi_parse_x2apic()
>> -> enabled = processor->lapic_flags & ACPI_MADT_ENABLED
>> -> topology_register_apic(enabled)
>> -> topo_register_apic(enabled)
>> -> set_cpu_present(cpu, true)
>
> Yes but arm64 marks all CPUs present even if !ACPI_MADT_ENABLED as we
> don't have the notion of hardware CPU hotplug.
>
> I need to dig some more into the original vCPU hotplug support and why
> we ended up with all CPUs marked as present even if not calling
> register_cpu():
>
> https://lore.kernel.org/linux-arm-kernel/20240529133446.28446-1-Jonathan.Cameron@huawei.com/
>
> What's the MADT GICC provided by qemu with "-smp cpus=4,maxcpus=8"? If
> it says Enabled for the first 4 and Online Capable for the rest, maybe
> we can try something like below:
Yes, you are absolutely right,Enabled for the first 4(with GIC Flags:
0x1, bit0 set) and Online Capable for the rest(with GIC Flags: 0x8, bit3
set). The ACPI MADT disassembly result is as follows:
Link:
https://uefi.org/specs/ACPI/6.5/05_ACPI_Software_Programming_Model.html#gic-cpu-interface-gicc-structure
# cat /sys/firmware/acpi/tables/APIC > madt.bin
# iasl -d madt.bin
[048h 0072 4] CPU Interface Number : 00000000
[030h 0048 4] Local GIC Hardware ID : 00000000
...
[04Ch 0076 4] Processor UID : 00000000
[050h 0080 4] Flags (decoded below) : 00000001
Processor Enabled : 1
Performance Interrupt Trigger Mode : 0
Virtual GIC Interrupt Trigger Mode : 0
...
[098h 0152 4] CPU Interface Number : 00000001
[09Ch 0156 4] Processor UID : 00000001
[0A0h 0160 4] Flags (decoded below) : 00000001
Processor Enabled : 1
Performance Interrupt Trigger Mode : 0
Virtual GIC Interrupt Trigger Mode : 0
...
[0E8h 0232 4] CPU Interface Number : 00000002
[0ECh 0236 4] Processor UID : 00000002
[0F0h 0240 4] Flags (decoded below) : 00000001
Processor Enabled : 1
Performance Interrupt Trigger Mode : 0
Virtual GIC Interrupt Trigger Mode : 0
...
[138h 0312 4] CPU Interface Number : 00000003
[13Ch 0316 4] Processor UID : 00000003
[140h 0320 4] Flags (decoded below) : 00000001
Processor Enabled : 1
Performance Interrupt Trigger Mode : 0
Virtual GIC Interrupt Trigger Mode : 0
...
[188h 0392 4] CPU Interface Number : 00000004
[18Ch 0396 4] Processor UID : 00000004
[190h 0400 4] Flags (decoded below) : 00000008
Processor Enabled : 0
Performance Interrupt Trigger Mode : 0
Virtual GIC Interrupt Trigger Mode : 0
...
[1D8h 0472 4] CPU Interface Number : 00000005
[1DCh 0476 4] Processor UID : 00000005
[1E0h 0480 4] Flags (decoded below) : 00000008
Processor Enabled : 0
Performance Interrupt Trigger Mode : 0
Virtual GIC Interrupt Trigger Mode : 0
...
[228h 0552 4] CPU Interface Number : 00000006
[22Ch 0556 4] Processor UID : 00000006
[230h 0560 4] Flags (decoded below) : 00000008
Processor Enabled : 0
Performance Interrupt Trigger Mode : 0
Virtual GIC Interrupt Trigger Mode : 0
...
[278h 0632 4] CPU Interface Number : 00000007
[27Ch 0636 4] Processor UID : 00000007
[280h 0640 4] Flags (decoded below) : 00000008
Processor Enabled : 0
Performance Interrupt Trigger Mode : 0
Virtual GIC Interrupt Trigger Mode : 0
...
>
> ----------------------8<-----------------
> diff --git a/arch/arm64/kernel/acpi.c b/arch/arm64/kernel/acpi.c
> index 5891f92c2035..681aa2bbc399 100644
> --- a/arch/arm64/kernel/acpi.c
> +++ b/arch/arm64/kernel/acpi.c
> @@ -448,12 +448,14 @@ int acpi_map_cpu(acpi_handle handle, phys_cpuid_t physid, u32 apci_id,
> return *pcpu;
> }
>
> + set_cpu_present(*pcpu, true);
> return 0;
> }
> EXPORT_SYMBOL(acpi_map_cpu);
>
> int acpi_unmap_cpu(int cpu)
> {
> + set_cpu_present(cpu, false);
> return 0;
> }
> EXPORT_SYMBOL(acpi_unmap_cpu);
> diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c
> index 1aa324104afb..6421027669fc 100644
> --- a/arch/arm64/kernel/smp.c
> +++ b/arch/arm64/kernel/smp.c
> @@ -566,6 +566,11 @@ struct acpi_madt_generic_interrupt *acpi_cpu_get_madt_gicc(int cpu)
> }
> EXPORT_SYMBOL_GPL(acpi_cpu_get_madt_gicc);
>
> +static bool acpi_cpu_is_present(int cpu)
> +{
> + return acpi_cpu_get_madt_gicc(cpu)->flags & ACPI_MADT_ENABLED;
> +}
> +
> /*
> * acpi_map_gic_cpu_interface - parse processor MADT entry
> *
> @@ -670,6 +675,11 @@ static void __init acpi_parse_and_init_cpus(void)
> early_map_cpu_to_node(i, acpi_numa_get_nid(i));
> }
> #else
> +static bool acpi_cpu_is_present(int cpu)
> +{
> + return false;
> +}
> +
> #define acpi_parse_and_init_cpus(...) do { } while (0)
> #endif
>
> @@ -808,7 +818,8 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
> if (err)
> continue;
>
> - set_cpu_present(cpu, true);
> + if (acpi_disabled || acpi_cpu_is_present(cpu))
> + set_cpu_present(cpu, true);
> numa_store_cpu_info(cpu);
> }
> }
>
^ permalink raw reply
* Re: [RFC PATCH v2 1/4] security: ima: call ima_init() again at late_initcall_sync for defered TPM
From: Paul Moore @ 2026-04-24 1:27 UTC (permalink / raw)
To: Mimi Zohar, roberto.sassu
Cc: Yeoreum Yun, Jonathan McDowell, linux-security-module,
linux-kernel, linux-integrity, linux-arm-kernel, kvmarm, jmorris,
serge, dmitry.kasatkin, eric.snowberg, jarkko, jgg, sudeep.holla,
maz, oupton, joey.gouly, suzuki.poulose, yuzenghui,
catalin.marinas, will, noodles, sebastianene
In-Reply-To: <aephL3MzYoqFGaT5@e129823.arm.com>
On Thu, Apr 23, 2026 at 2:13 PM Yeoreum Yun <yeoreum.yun@arm.com> wrote:
>
> Sounds good. Once the patch is posted, I’ll review it as well.
> Sorry again for the noise, and thanks for your patience ;)
My apologies for not getting a chance to look at this patchset sooner.
This seems like an obvious, perhaps even stupid, question, but I have
to ask: if IMA can be properly initialized via late_initcall_sync(),
why not simply do the initialization in late_initcall_sync() and drop
the late_initcall() initialization?
Does any IMA functionality suffer if initialization waits until
late_initcall_sync()? If so, it seems non-critical if waiting until
_sync() is acceptable, as it appears in these patches/comments.
--
paul-moore.com
^ permalink raw reply
* Re: [PATCH v4 35/49] KVM: arm64: GICv3: nv: Plug L1 LR sync into deactivation primitive
From: Darren Hart @ 2026-04-24 0:02 UTC (permalink / raw)
To: Marc Zyngier
Cc: Vishnu Pajjuri, Fuad Tabba, Joey Gouly, Suzuki K Poulose,
Oliver Upton, Zenghui Yu, Christoffer Dall, Mark Brown, kvm,
linux-arm-kernel, kvmarm
In-Reply-To: <86eck71o1v.wl-maz@kernel.org>
On Wed, Apr 22, 2026 at 07:55:56AM +0100, Marc Zyngier wrote:
> [+ Darren]
>
Thanks for the head's up Marc.
> On Tue, 31 Mar 2026 10:42:57 +0100,
> Marc Zyngier <maz@kernel.org> wrote:
> > >
...
> > > Although this behavior is puzzling, it matches the trace I typically
> > > observe on L0. After reverting the patch, I was able to boot L2 guests
> > > successfully.
> >
> > Well, this patch fixes real bugs, so it isn't going anywhere.
Understood.
>
> Have you made progress on this? I can't reproduce it at all despite my
> best effort. I'm perfectly happy to help, but you need to give me
> *something* to go on.
>
I didn't give this the attention it deserved. I've now got Vishnu the
resources he needs to help move this forward. We owe you something
concrete/actionable/reproducible and we'll report back once we have it.
--
Darren Hart
Ampere Computing / Linux Enabling
^ permalink raw reply
* Re: [REGRESSION] rseq: refactoring in v6.19 broke everyone on arm64 and tcmalloc everywhere
From: Linus Torvalds @ 2026-04-23 23:08 UTC (permalink / raw)
To: Thomas Gleixner
Cc: Mathias Stearn, Peter Zijlstra, Mathieu Desnoyers,
Catalin Marinas, Will Deacon, Boqun Feng, Paul E. McKenney,
Chris Kennelly, Dmitry Vyukov, regressions, linux-kernel,
linux-arm-kernel, Ingo Molnar, Mark Rutland, Jinjie Ruan,
Blake Oler
In-Reply-To: <CAHk-=wh=B3fqU9AaBsyViZR=eVTG5qa2CGyN=qxPROVxu9Gctg@mail.gmail.com>
On Thu, 23 Apr 2026 at 14:28, Linus Torvalds
<torvalds@linux-foundation.org> wrote:
>
> This is all 100% on the RSEQ kernel code, not on users who took advantage of it.
Side note: when RSEQ was merged, the *primary* documented use case was
literally user space allocators with percpu caches. That's what I was
told at the time.
Now I think it was jemalloc(), not tcmalloc, but it's not like
tcmalloc is some odd minor use-case.
We are pretty much talking about the raison d'être of the whole rseq
feature, not some odd small corner case.
Linus
^ permalink raw reply
* Re: [PATCH V1 3/3] iommu/arm-smmu-v3: Honor IORT Root Complex PASID descriptors
From: Jason Gunthorpe @ 2026-04-23 22:45 UTC (permalink / raw)
To: Vidya Sagar
Cc: rafael, lenb, saket.dumbre, lpieralisi, guohanjun, sudeep.holla,
will, catalin.marinas, joro, robin.murphy, nicolinc, praan,
vsethi, sdonthineni, kthota, sagar.tv, linux-acpi,
linux-arm-kernel, acpica-devel, iommu, linux-kernel
In-Reply-To: <20260423191417.2031652-4-vidyas@nvidia.com>
On Fri, Apr 24, 2026 at 12:44:17AM +0530, Vidya Sagar wrote:
> The SMMUv3 driver currently calls pci_enable_pasid() for any PCI
> master that exposes a PASID capability, regardless of whether the
> upstream Root Complex actually supports PASID and regardless of the
> RC's declared Max PASID Width. With IORT spec E.c (RC node revision
> >= 4) firmware reports both, so we can do better:
>
> - If the IORT Root Complex node says PASID is not supported
> (Flags bit 0 == 0 at byte offset 36), enabling PASID on the
> endpoint is futile - the RC will not forward the PASID prefix to
> the SMMU - so skip pci_enable_pasid() silently.
>
> - If the IORT Root Complex node reports a Max PASID Width (bits[4:0]
> of PASID Capabilities at offset 33), clamp the endpoint's
> pci_max_pasids() result by 1 << width before computing the SMMU
> SSID width. This prevents master->ssid_bits from exceeding what
> the RC can actually carry.
>
> Both behaviours are gated on iort_pci_rc_pasid_max_width_known(), i.e.
> RC node revision >= 4, so platforms with older IORT firmware see no
> behavioural change and continue to enable PASID purely on the basis
> of the endpoint capability.
>
> Use the new IOMMU_FWSPEC_PCI_RC_PASID fwspec flag (set by IORT) for
> the support check, and call iort_pci_rc_pasid_max_width_for_dev() for
> the width clamp; both pieces are wired up in
> iort_iommu_configure_id() by the previous patch.
>
> Signed-off-by: Vidya Sagar <vidyas@nvidia.com>
> ---
> drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 26 ++++++++++++++++++---
> 1 file changed, 23 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
> index e8d7dbe495f0..2b269307fd33 100644
> --- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
> +++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
> @@ -3071,16 +3071,28 @@ static void arm_smmu_enable_ats(struct arm_smmu_master *master)
>
> static int arm_smmu_enable_pasid(struct arm_smmu_master *master)
> {
> - int ret;
> - int features;
> - int num_pasids;
> + struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(master->dev);
> struct pci_dev *pdev;
> + int features, num_pasids, ret, rc_width;
Don't reformat the code like this.
Otherwise the series broadly makes sense to me
Jason
^ permalink raw reply
* Re: [PATCH V1 1/3] ACPICA: IORT: Add Root Complex PASID Flags field
From: Jason Gunthorpe @ 2026-04-23 22:43 UTC (permalink / raw)
To: Vidya Sagar
Cc: rafael, lenb, saket.dumbre, lpieralisi, guohanjun, sudeep.holla,
will, catalin.marinas, joro, robin.murphy, nicolinc, praan,
vsethi, sdonthineni, kthota, sagar.tv, linux-acpi,
linux-arm-kernel, acpica-devel, iommu, linux-kernel
In-Reply-To: <20260423191417.2031652-2-vidyas@nvidia.com>
On Fri, Apr 24, 2026 at 12:44:15AM +0530, Vidya Sagar wrote:
> The IORT spec, Issue E.c (ARM DEN 0049E.c, January 2022), bumps the
> Root Complex Node to revision 4 and adds two PASID descriptors:
>
> - PASID Capabilities at byte offset 33 (2 bytes), bits[4:0] of which
> report the Max PASID Width supported by the Root Complex.
> - Flags at byte offset 36 (4 bytes), bit 0 of which reports whether
> the Root Complex itself supports PASID. This is distinct from the
> existing ATS Attribute bit 2 (at offset 24) that only reports
> whether the RC forwards PASID information on translated
> transactions.
>
> The ACPICA struct in include/acpi/actbl2.h was updated for the E.c
> PASID Capabilities descriptor (offset 33) but stops short with a
> trailing 'u8 reserved[]' flexible array, so the new Flags field at
> offset 36 is unreachable and the existing ACPI_IORT_PASID_*
> definitions have no consumer.
>
> Replace the trailing flexible array with a fixed 'u8 reserved[1]'
> followed by 'u32 flags' so the struct fully covers RC node revision 4,
> and add the ACPI_IORT_RC_PASID_SUPPORTED mask for bit 0 of the new
> field. With #pragma pack(1) in effect for actbl2.h, this lands the new
> field at the spec-mandated absolute offset 36.
>
> Signed-off-by: Vidya Sagar <vidyas@nvidia.com>
> ---
> include/acpi/actbl2.h | 6 +++++-
> 1 file changed, 5 insertions(+), 1 deletion(-)
There is a whole process to change this file, I went through it once
for canwbs..
https://lore.kernel.org/acpica-devel/2-v3-e2e16cd7467f+2a6a1-smmuv3_nesting_jgg@nvidia.com/
You have to make a pull request here:
https://github.com/acpica/acpica/pulls
And then use the
generate/linux/make-patches.sh -u <commit-id>
Script to make this patch for linux in the perscribed format.
I think, something like that
Jason
^ permalink raw reply
* Re: [PATCH] iommu/arm-smmu-v3: Allow disabling Stage 1 translation
From: Jason Gunthorpe @ 2026-04-23 22:37 UTC (permalink / raw)
To: Will Deacon
Cc: Evangelos Petrongonas, Robin Murphy, Joerg Roedel, Nicolin Chen,
Pranjal Shrivastava, Lu Baolu, linux-arm-kernel, iommu,
linux-kernel, nh-open-source, Zeev Zilberman
In-Reply-To: <aepRy7Gp7Ng85Zr7@willie-the-truck>
On Thu, Apr 23, 2026 at 06:07:23PM +0100, Will Deacon wrote:
> I don't think it's that odd given that the STE/CD entries are bigger
> than PTEs and the SMMU permits a lot more relaxations about how they are
> accessed and cached compared to the PTW.
Well I'm not sure bigger really matters, but I wasn't aware there was
a spec relaxation here that would make the cachable path not viable
for STE but not PTW...
> Having said that, the page-table code looks broken to me even in the
> coherent case:
>
> ptep[i] = pte | paddr_to_iopte(paddr + i * sz, data);
>
> as the compiler can theoretically make a right mess of that.
Heh, great. The iommupt stuff does better.. It does a 64 bit cmpxchg
to store a table pointer and a 64 bit WRITE_ONCE to store the pte,
then a CMO through the DMA API.
DMA API has to guarentee the right ordering, so we only have the
question below:
> > STE/CD is pretty simple now, there is only one place to put the CMO
> > and the ordering is all handled with that shared code. We no longer
> > care about ordering beyond all the writes must be visible to HW before
> > issuing the CMDQ invalidation command - which is the same environment
> > as the pagetable.
>
> You presumably rely on 64-bit single-copy atomicity for hitless updates,
> no?
Yes, just like the page table does..
I hope that's not a problem or we have a issue with the PTW :)
> > I also don't like this "lot of systems thing". I don't want these
> > powerful capabilities locked up in some giant CSP's proprietary
> > kernel. I want all the companies in the cloud market to have access
> > to the same feature set. That's what open source is supposed to be
> > driving toward. I have several interesting use cases for this
> > functionality already.
>
> Sorry, the point here was definitely _not_ about keeping this out of
> tree, nor was I trying to say that this stuff isn't important. But the
> mobile world doesn't give a hoot about KHO and _does_ tend to care about
> the impact of CMO, so we have to find a way to balance the two worlds.
Yes, that make sense.
My argument is that the CMO on STE/CD shouldn't bother mobile, you
could even view it as an micro-optimization because we do occasionally
read-back the STE/CD fields.
But if you say the SMM STE/CD fetch doesn't have to follow the single
copy rules and PTW does, then ok..
And if Samiullah can tackle dma_alloc_coherent then maybe the whole
question is moot.
Jason
^ permalink raw reply
* Re: [PATCH 2/5] drm/panel-edp: Add support for Samsung LTL101DL02-002 panel
From: Doug Anderson @ 2026-04-23 21:49 UTC (permalink / raw)
To: Lukas Timmermann
Cc: Neil Armstrong, Jessica Zhang, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, David Airlie, Simona Vetter, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Thierry Reding, Sam Ravnborg,
Krzysztof Kozlowski, Sylwester Nawrocki, Chanwoo Choi,
Alim Akhtar, Michael Turquette, Stephen Boyd, dri-devel,
devicetree, linux-kernel, linux-samsung-soc, linux-clk,
linux-arm-kernel, Alexandre Marquet
In-Reply-To: <20260423-manta-display-v1-2-196f80c5673a@timmermann.space>
Hi,
On Thu, Apr 23, 2026 at 2:15 PM Lukas Timmermann <linux@timmermann.space> wrote:
>
> From: Alexandre Marquet <tb@a-marquet.fr>
>
> Add a panel entry for the Samsung LTL101DL02-002 panel, as found in
> Samsung Manta (Google Nexus 10).
>
> Signed-off-by: Alexandre Marquet <tb@a-marquet.fr>
> Signed-off-by: Lukas Timmermann <linux@timmermann.space>
> ---
> drivers/gpu/drm/panel/panel-edp.c | 31 +++++++++++++++++++++++++++++++
> 1 file changed, 31 insertions(+)
Adding new panels like this is discouraged these days. Is there a
reason you can't use the generic "edp-panel" compatible? I know that
the exynos5 driver is pretty old, but a quick glance shows that it's
based on the same analogix-dp core that "rockchip,analogix-dp" is, and
that seems to have support for aux-bus...
-Doug
^ permalink raw reply
* Re: [REGRESSION] rseq: refactoring in v6.19 broke everyone on arm64 and tcmalloc everywhere
From: Linus Torvalds @ 2026-04-23 21:28 UTC (permalink / raw)
To: Thomas Gleixner
Cc: Mathias Stearn, Peter Zijlstra, Mathieu Desnoyers,
Catalin Marinas, Will Deacon, Boqun Feng, Paul E. McKenney,
Chris Kennelly, Dmitry Vyukov, regressions, linux-kernel,
linux-arm-kernel, Ingo Molnar, Mark Rutland, Jinjie Ruan,
Blake Oler
In-Reply-To: <874il11jac.ffs@tglx>
On Thu, 23 Apr 2026 at 14:03, Thomas Gleixner <tglx@kernel.org> wrote:
>
> Feel free to enforce it, but be aware that you thereby set a
> precedence that a single abuser can then rightfully own a general
> shared interface of the kernel forever and force everybody else to
> give up.
That's not a new precedent. That is *literally* the rule we have always had.
This is why system calls and ABI's need to have hard rules that they
actually check, because if they don't, they are stuck with the
semantics that people assume.
And no, "documented behavior" is BS. It has absolutely no relevance.
All that matters is hard harsh reality.
Yes, this has led to issues before.
Most new system calls have learnt their lesson, and they check for
unused bits in flags etc, and error out on bits that the lernel
doesn't really care about being randomly set - so that one day we
*can* extend on things and start caring about them.
But they do it because we've been burnt so many times before because
we haven't checked those bits, and then we were forced to just live
with the fact that people passed in random values.
> // Note: this makes __rseq_abi.cpu_id_start unusable for its original purpose.
>
> Do you seriously want to proliferate that?
Absolutely.
That's how clever hacks work - they take advantage of things past
their design parameters. "If it works, it's not stupid".
We don't then turn around and say "you were clever, and we did
something stupid, so now we'll hurt you".
This is all 100% on the RSEQ kernel code, not on users who took advantage of it.
Linus
^ permalink raw reply
* [PATCH 5/5] ARM: dts: exynos: Add display support for exynos5250-manta
From: Lukas Timmermann @ 2026-04-23 21:14 UTC (permalink / raw)
To: Neil Armstrong, Jessica Zhang, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, David Airlie, Simona Vetter, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Thierry Reding, Sam Ravnborg,
Douglas Anderson, Krzysztof Kozlowski, Sylwester Nawrocki,
Chanwoo Choi, Alim Akhtar, Michael Turquette, Stephen Boyd
Cc: dri-devel, devicetree, linux-kernel, linux-samsung-soc, linux-clk,
linux-arm-kernel, Lukas Timmermann, Alexandre Marquet
In-Reply-To: <20260423-manta-display-v1-0-196f80c5673a@timmermann.space>
Adds the necessary entries for panel and backlight as
well as the fimd controller.
Signed-off-by: Alexandre Marquet <tb@a-marquet.fr>
Signed-off-by: Lukas Timmermann <linux@timmermann.space>
---
arch/arm/boot/dts/samsung/exynos5250-manta.dts | 99 ++++++++++++++++++++++++++
1 file changed, 99 insertions(+)
diff --git a/arch/arm/boot/dts/samsung/exynos5250-manta.dts b/arch/arm/boot/dts/samsung/exynos5250-manta.dts
index 76d3657eb22f..eb97a28ff4e3 100644
--- a/arch/arm/boot/dts/samsung/exynos5250-manta.dts
+++ b/arch/arm/boot/dts/samsung/exynos5250-manta.dts
@@ -25,6 +25,29 @@ aliases {
mmc1 = &mmc_1; /* WiFi */
};
+ backlight: backlight {
+ compatible = "pwm-backlight";
+ pwms = <&pwm 0 1000000 0>;
+
+ brightness-levels = <2 255>; /* TODO */
+ num-interpolated-steps = <254>; /* TODO */
+ default-brightness-level = <102>; /* TODO */
+ post-pwm-on-delay-ms = <97>; /* TODO */
+
+ power-supply = <&backlight_reg>;
+ enable-gpios = <&gpg0 5 GPIO_ACTIVE_HIGH>;
+
+ pinctrl-0 = <&led_bl_reset &pwm0_out>;
+ pinctrl-names = "default";
+ };
+
+ backlight_reg: regulator-backlight {
+ compatible = "regulator-fixed";
+ regulator-name = "APS_EN_18V";
+ pinctrl-0 = <&aps_en_18v>;
+ pinctrl-names = "default";
+ };
+
/* Voltage source unknown */
bmp180_vdda_reg: regulator-bmp180-vdda {
compatible = "regulator-fixed";
@@ -105,6 +128,28 @@ multi-led {
leds = <&status_red>, <&status_green>, <&status_blue>, <&status_white>;
};
+ panel {
+ compatible = "samsung,ltl101dl02-002";
+
+ backlight = <&backlight>;
+ power-supply = <&panel_reg>;
+ enable-gpios = <&gph1 7 GPIO_ACTIVE_HIGH>;
+ pinctrl-0 = <&lcd_en>;
+ pinctrl-names = "default";
+ no-hpd;
+
+ port {
+ panel: endpoint {
+ remote-endpoint = <&dp_out>;
+ };
+ };
+ };
+
+ panel_reg: regulator-panel {
+ compatible = "regulator-fixed";
+ regulator-name = "LCD_EN";
+ };
+
pwrseq: mmc1-pwrseq {
compatible = "mmc-pwrseq-simple";
@@ -146,10 +191,36 @@ &cpu1 {
cpu-supply = <&buck2_reg>;
};
+&dp {
+ status = "okay";
+
+ samsung,color-space = <0>;
+ samsung,color-depth = <1>;
+ samsung,link-rate = <0x0a>;
+ samsung,lane-count = <4>;
+ samsung,dynamic-range = <0>;
+ samsung,ycbcr-coeff = <0>;
+
+ ports {
+ port {
+ dp_out: endpoint {
+ remote-endpoint = <&panel>;
+ };
+ };
+ };
+};
+
&ehci {
status = "disabled";
};
+&fimd {
+ status = "okay";
+
+ assigned-clocks = <&clock CLK_MOUT_FIMD1>, <&clock CLK_MOUT_VPLL>;
+ assigned-clock-parents = <&clock CLK_MOUT_VPLL>;
+};
+
&i2c_1 {
status = "okay";
@@ -396,6 +467,12 @@ ldo25_reg: LDO25 {
};
};
+&mali {
+ status = "okay";
+
+ mali-supply = <&buck4_reg>;
+};
+
&mixer {
status = "okay";
};
@@ -489,6 +566,14 @@ wlan_irq: wlan-irq-pins {
};
&pinctrl_1 {
+ aps_en_18v: aps-en-18v-pins {
+ samsung,pins = "gph1-6";
+ samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>; /* TODO */
+ samsung,pin-con-pdn = <EXYNOS_PIN_PDN_INPUT>; /* TODO */
+ samsung,pin-pud-pdn = <EXYNOS_PIN_PULL_UP>; /* TODO */
+ samsung,pin-val = <0>; /* TODO */
+ };
+
bh1721fvc_reset: bh1721fvc-reset-pins {
samsung,pins = "gph1-2";
samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>;
@@ -509,6 +594,20 @@ bt_wake: bt-wake-pins {
samsung,pin-pud-pdn = <EXYNOS_PIN_PULL_NONE>;
};
+ lcd_en: lcd-en-pins {
+ samsung,pins = "gph1-7";
+ samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>; /* TODO */
+ samsung,pin-val = <0>;
+ };
+
+ led_bl_reset: led-bl-rst-pins {
+ samsung,pins = "gpg0-5";
+ samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>; /* TODO */
+ samsung,pin-con-pdn = <EXYNOS_PIN_PDN_PREV>; /* TODO */
+ samsung,pin-pud-pdn = <EXYNOS_PIN_PULL_NONE>; /* TODO */
+ samsung,pin-val = <0>; /* TODO */
+ };
+
msense_reset: msense-reset-pins {
samsung,pins = "gpg2-0";
samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>;
--
2.53.0
^ permalink raw reply related
* [PATCH 4/5] clk: samsung: exynos5250: Define more clocks
From: Lukas Timmermann @ 2026-04-23 21:14 UTC (permalink / raw)
To: Neil Armstrong, Jessica Zhang, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, David Airlie, Simona Vetter, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Thierry Reding, Sam Ravnborg,
Douglas Anderson, Krzysztof Kozlowski, Sylwester Nawrocki,
Chanwoo Choi, Alim Akhtar, Michael Turquette, Stephen Boyd
Cc: dri-devel, devicetree, linux-kernel, linux-samsung-soc, linux-clk,
linux-arm-kernel, Lukas Timmermann, Alexandre Marquet
In-Reply-To: <20260423-manta-display-v1-0-196f80c5673a@timmermann.space>
Add defines for mout_fimd1 and mout_vpll to enable display support for
exynos5250-manta boards.
Signed-off-by: Alexandre Marquet <tb@a-marquet.fr>
Signed-off-by: Lukas Timmermann <linux@timmermann.space>
---
drivers/clk/samsung/clk-exynos5250.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/clk/samsung/clk-exynos5250.c b/drivers/clk/samsung/clk-exynos5250.c
index e90d3a0848cb..a43d05d3014f 100644
--- a/drivers/clk/samsung/clk-exynos5250.c
+++ b/drivers/clk/samsung/clk-exynos5250.c
@@ -102,7 +102,7 @@
#define PWR_CTRL2_CORE1_UP_RATIO (1 << 0)
/* NOTE: Must be equal to the last clock ID increased by one */
-#define CLKS_NR (CLK_MOUT_VPLLSRC + 1)
+#define CLKS_NR (CLK_MOUT_VPLL + 1)
/* list of PLLs to be registered */
enum exynos5250_plls {
@@ -283,7 +283,7 @@ static const struct samsung_mux_clock exynos5250_mux_clks[] __initconst = {
MUX(0, "mout_cpll", mout_cpll_p, SRC_TOP2, 8, 1),
MUX(0, "mout_epll", mout_epll_p, SRC_TOP2, 12, 1),
- MUX(0, "mout_vpll", mout_vpll_p, SRC_TOP2, 16, 1),
+ MUX(CLK_MOUT_VPLL, "mout_vpll", mout_vpll_p, SRC_TOP2, 16, 1),
MUX(0, "mout_mpll_user", mout_mpll_user_p, SRC_TOP2, 20, 1),
MUX(0, "mout_bpll_user", mout_bpll_user_p, SRC_TOP2, 24, 1),
MUX(CLK_MOUT_GPLL, "mout_gpll", mout_gpll_p, SRC_TOP2, 28, 1),
@@ -304,7 +304,7 @@ static const struct samsung_mux_clock exynos5250_mux_clks[] __initconst = {
MUX(0, "mout_gscl_wa", mout_group1_p, SRC_GSCL, 24, 4),
MUX(0, "mout_gscl_wb", mout_group1_p, SRC_GSCL, 28, 4),
- MUX(0, "mout_fimd1", mout_group1_p, SRC_DISP1_0, 0, 4),
+ MUX(CLK_MOUT_FIMD1, "mout_fimd1", mout_group1_p, SRC_DISP1_0, 0, 4),
MUX(0, "mout_mipi1", mout_group1_p, SRC_DISP1_0, 12, 4),
MUX(0, "mout_dp", mout_group1_p, SRC_DISP1_0, 16, 4),
MUX(CLK_MOUT_HDMI, "mout_hdmi", mout_hdmi_p, SRC_DISP1_0, 20, 1),
--
2.53.0
^ permalink raw reply related
* [PATCH 3/5] dt-bindings: clock: samsung: Add fimd1 and vpll muxes
From: Lukas Timmermann @ 2026-04-23 21:14 UTC (permalink / raw)
To: Neil Armstrong, Jessica Zhang, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, David Airlie, Simona Vetter, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Thierry Reding, Sam Ravnborg,
Douglas Anderson, Krzysztof Kozlowski, Sylwester Nawrocki,
Chanwoo Choi, Alim Akhtar, Michael Turquette, Stephen Boyd
Cc: dri-devel, devicetree, linux-kernel, linux-samsung-soc, linux-clk,
linux-arm-kernel, Lukas Timmermann
In-Reply-To: <20260423-manta-display-v1-0-196f80c5673a@timmermann.space>
Add two clocks necessary for the google-manta board
display.
Signed-off-by: Lukas Timmermann <linux@timmermann.space>
---
include/dt-bindings/clock/exynos5250.h | 2 ++
1 file changed, 2 insertions(+)
diff --git a/include/dt-bindings/clock/exynos5250.h b/include/dt-bindings/clock/exynos5250.h
index 2337c028bbe1..93122823c04d 100644
--- a/include/dt-bindings/clock/exynos5250.h
+++ b/include/dt-bindings/clock/exynos5250.h
@@ -176,5 +176,7 @@
#define CLK_MOUT_APLL 1028
#define CLK_MOUT_MPLL 1029
#define CLK_MOUT_VPLLSRC 1030
+#define CLK_MOUT_FIMD1 1031
+#define CLK_MOUT_VPLL 1032
#endif /* _DT_BINDINGS_CLOCK_EXYNOS_5250_H */
--
2.53.0
^ permalink raw reply related
* [PATCH 2/5] drm/panel-edp: Add support for Samsung LTL101DL02-002 panel
From: Lukas Timmermann @ 2026-04-23 21:14 UTC (permalink / raw)
To: Neil Armstrong, Jessica Zhang, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, David Airlie, Simona Vetter, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Thierry Reding, Sam Ravnborg,
Douglas Anderson, Krzysztof Kozlowski, Sylwester Nawrocki,
Chanwoo Choi, Alim Akhtar, Michael Turquette, Stephen Boyd
Cc: dri-devel, devicetree, linux-kernel, linux-samsung-soc, linux-clk,
linux-arm-kernel, Lukas Timmermann, Alexandre Marquet
In-Reply-To: <20260423-manta-display-v1-0-196f80c5673a@timmermann.space>
From: Alexandre Marquet <tb@a-marquet.fr>
Add a panel entry for the Samsung LTL101DL02-002 panel, as found in
Samsung Manta (Google Nexus 10).
Signed-off-by: Alexandre Marquet <tb@a-marquet.fr>
Signed-off-by: Lukas Timmermann <linux@timmermann.space>
---
drivers/gpu/drm/panel/panel-edp.c | 31 +++++++++++++++++++++++++++++++
1 file changed, 31 insertions(+)
diff --git a/drivers/gpu/drm/panel/panel-edp.c b/drivers/gpu/drm/panel/panel-edp.c
index 415b894890ad..2004699db41b 100644
--- a/drivers/gpu/drm/panel/panel-edp.c
+++ b/drivers/gpu/drm/panel/panel-edp.c
@@ -1542,6 +1542,34 @@ static const struct panel_desc samsung_lsn122dl01_c01 = {
},
};
+static const struct drm_display_mode samsung_ltl101dl02_002_mode = {
+ .clock = 268627,
+ .hdisplay = 2560,
+ .hsync_start = 2560 + 48,
+ .hsync_end = 2560 + 48 + 32,
+ .htotal = 2560 + 48 + 32 + 80,
+ .vdisplay = 1600,
+ .vsync_start = 1600 + 3,
+ .vsync_end = 1600 + 3 + 6,
+ .vtotal = 1600 + 3 + 6 + 37,
+ .flags = DRM_MODE_FLAG_NVSYNC | DRM_MODE_FLAG_NHSYNC,
+};
+
+static const struct panel_desc samsung_ltl101dl02_002 = {
+ .modes = &samsung_ltl101dl02_002_mode,
+ .num_modes = 1,
+ .bpc = 6,
+ .size = {
+ .width = 218,
+ .height = 136,
+ },
+ .delay = {
+ .hpd_absent = 200,
+ .unprepare = 500,
+ },
+
+};
+
static const struct drm_display_mode samsung_ltn140at29_301_mode = {
.clock = 76300,
.hdisplay = 1366,
@@ -1696,6 +1724,9 @@ static const struct of_device_id platform_of_match[] = {
}, {
.compatible = "samsung,lsn122dl01-c01",
.data = &samsung_lsn122dl01_c01,
+ }, {
+ .compatible = "samsung,ltl101dl02-002",
+ .data = &samsung_ltl101dl02_002,
}, {
.compatible = "samsung,ltn140at29-301",
.data = &samsung_ltn140at29_301,
--
2.53.0
^ permalink raw reply related
* [PATCH 1/5] dt-bindings: display: panel: Document Samsung LTL101DL02-002 panel
From: Lukas Timmermann @ 2026-04-23 21:14 UTC (permalink / raw)
To: Neil Armstrong, Jessica Zhang, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, David Airlie, Simona Vetter, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Thierry Reding, Sam Ravnborg,
Douglas Anderson, Krzysztof Kozlowski, Sylwester Nawrocki,
Chanwoo Choi, Alim Akhtar, Michael Turquette, Stephen Boyd
Cc: dri-devel, devicetree, linux-kernel, linux-samsung-soc, linux-clk,
linux-arm-kernel, Lukas Timmermann, Alexandre Marquet
In-Reply-To: <20260423-manta-display-v1-0-196f80c5673a@timmermann.space>
From: Alexandre Marquet <tb@a-marquet.fr>
Add the dt-bindings for the LTL101DL02-002 panel.
Signed-off-by: Alexandre Marquet <tb@a-marquet.fr>
Signed-off-by: Lukas Timmermann <linux@timmermann.space>
---
Documentation/devicetree/bindings/display/panel/panel-simple.yaml | 2 ++
1 file changed, 2 insertions(+)
diff --git a/Documentation/devicetree/bindings/display/panel/panel-simple.yaml b/Documentation/devicetree/bindings/display/panel/panel-simple.yaml
index 24e277b19094..2de0a3a6d1fe 100644
--- a/Documentation/devicetree/bindings/display/panel/panel-simple.yaml
+++ b/Documentation/devicetree/bindings/display/panel/panel-simple.yaml
@@ -283,6 +283,8 @@ properties:
# Samsung Electronics 10.6" FWXGA (1366x768) TFT LCD panel
- samsung,ltl106al01
# Samsung Electronics 10.1" WSVGA TFT LCD panel
+ - samsung,ltl101dl02-002
+ # Samsung Electronics 10.1" WQXGA (2560x1600) TFT LCD panel
- samsung,ltn101nt05
# Satoz SAT050AT40H12R2 5.0" WVGA TFT LCD panel
- satoz,sat050at40h12r2
--
2.53.0
^ permalink raw reply related
* [PATCH 0/5] Google Nexus 10 display support
From: Lukas Timmermann @ 2026-04-23 21:14 UTC (permalink / raw)
To: Neil Armstrong, Jessica Zhang, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, David Airlie, Simona Vetter, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Thierry Reding, Sam Ravnborg,
Douglas Anderson, Krzysztof Kozlowski, Sylwester Nawrocki,
Chanwoo Choi, Alim Akhtar, Michael Turquette, Stephen Boyd
Cc: dri-devel, devicetree, linux-kernel, linux-samsung-soc, linux-clk,
linux-arm-kernel, Lukas Timmermann, Alexandre Marquet
This patch series adds display support to the
Nexus 10 (google-manta) tablet.
The panel can be used with the panel-edp
driver and just had to be added.
Also needed for display output were two clocks which had to be defined.
This patch series depends on previous patches which are
currently only found in linux-next.
See: https://lore.kernel.org/all/177214038655.341086.4114348823043257597.b4-ty@kernel.org/
Signed-off-by: Lukas Timmermann <linux@timmermann.space>
---
Alexandre Marquet (2):
dt-bindings: display: panel: Document Samsung LTL101DL02-002 panel
drm/panel-edp: Add support for Samsung LTL101DL02-002 panel
Lukas Timmermann (3):
dt-bindings: clock: samsung: Add fimd1 and vpll muxes
clk: samsung: exynos5250: Define more clocks
ARM: dts: exynos: Add display support for exynos5250-manta
.../bindings/display/panel/panel-simple.yaml | 2 +
arch/arm/boot/dts/samsung/exynos5250-manta.dts | 99 ++++++++++++++++++++++
drivers/clk/samsung/clk-exynos5250.c | 6 +-
drivers/gpu/drm/panel/panel-edp.c | 31 +++++++
include/dt-bindings/clock/exynos5250.h | 2 +
5 files changed, 137 insertions(+), 3 deletions(-)
---
base-commit: 6d130a71abb393ce99b081e78783581bd3b5985b
change-id: 20260423-manta-display-55781039fb0d
Best regards,
--
Lukas Timmermann <linux@timmermann.space>
^ permalink raw reply
* Re: [REGRESSION] rseq: refactoring in v6.19 broke everyone on arm64 and tcmalloc everywhere
From: Thomas Gleixner @ 2026-04-23 21:03 UTC (permalink / raw)
To: Linus Torvalds
Cc: Mathias Stearn, Peter Zijlstra, Mathieu Desnoyers,
Catalin Marinas, Will Deacon, Boqun Feng, Paul E. McKenney,
Chris Kennelly, Dmitry Vyukov, regressions, linux-kernel,
linux-arm-kernel, Ingo Molnar, Mark Rutland, Jinjie Ruan,
Blake Oler
In-Reply-To: <CAHk-=wjsEqWJxXArS-P5+ksSY2Apaox8u6FtUrtyWSBEOL4Q2Q@mail.gmail.com>
On Thu, Apr 23 2026 at 10:41, Linus Torvalds wrote:
> If that rule was actually an important part of the ABI, it shouldn't
> have been a debug thing.
It's a debug thing because it's too expensive to be enabled by
default. And it's actually valuable for validating RSEQ critical section
ABI correctness as they can't be single stepped with a debugger as the
break point interruption would immediately canceled.
> So:
>
> (a) the debug code in question needs to just be removed, since it's
> now actively detrimental, and means that any kernel developer who
> *does* enable it can't actually test this case any more. It's checking
> for something that has been shown to not be true.
>
> (b) we need to fix this (revert if it can't be fixed otherwise)
>
> I see some patches flying around, but am not clear on whether there
> was an actual patch that make this work again?
There are two issues:
1) ARM64
On ARM64 RSEQ got broken completely with the partial move to the
generic entry code. There are patches flying around which "fix" it
and Mark is working on a more complete solution as there are other
subtle issues with that aside of the obvious RSEQ wreckage. The
latter could have been detected with the existing RSEQ selftests if
any CI would actually run them on -next.
That's uninteresting and unrelated to the tcmalloc issue. It's just
a boring bug which will be fixed in the next couple of days.
2) The tcmalloc problem
That's a known problem for at least 6 years. tcmalloc assumes that
it "owns" rseq and can do whatever it wants with it.
In 2022 the glibc people requested that tcmalloc becomes
interoperable with the reasonable expection of glibc to utilize
rseq as well:
https://github.com/google/tcmalloc/issues/144
Status unresolved.
That means that using tcmalloc requires to tell glibc to _NOT_ use
rseq and at the same time precludes any other library which wants
to use it for the documented purposes. So this code sequence blows
up in your face:
x = tcmalloc();
dostuff(x)
evaluate(rseq::cpu_id_start, rseq::cpu_id)
because tcmalloc overwrites rseq::cpu_id_start and thereby breaks
the ABI which evaluate() is rightfully depending on.
That has absolutely nothing to do with the kernel as there is no
kernel interaction between tcmalloc's abuse and the subsequent
evaluation of rseq::cpu_id_start. The kernel has no way to fix that
problem at all.
Now back to your generally correct and agreed on "observed
behaviour" rule.
Feel free to enforce it, but be aware that you thereby set a
precedence that a single abuser can then rightfully own a general
shared interface of the kernel forever and force everybody else to
give up.
The tcmalloc developers actually documented that they own the
world:
// Note: this makes __rseq_abi.cpu_id_start unusable for its original purpose.
Do you seriously want to proliferate that?
Thanks,
tglx
^ permalink raw reply
* Re: [PATCH] cpu/hotplug: Fix NULL kobject warning in cpuhp_smt_enable()
From: Catalin Marinas @ 2026-04-23 20:11 UTC (permalink / raw)
To: Jinjie Ruan
Cc: Thomas Gleixner, peterz, sudeep.holla, yangyicong,
dietmar.eggemann, Jonathan.Cameron, linux-kernel, James Morse,
linux-arm-kernel
In-Reply-To: <78515da3-03a1-4fdb-a606-3fea9f4cd20b@huawei.com>
On Thu, Apr 23, 2026 at 08:32:34PM +0800, Jinjie Ruan wrote:
> On 4/23/2026 6:08 PM, Thomas Gleixner wrote:
> > On Sat, Apr 18 2026 at 12:55, Catalin Marinas wrote:
> >> Another option would have been to avoid marking such CPUs present but I
> >> think this will break other things. Yet another option is to register
> >> all CPU devices even if they never come up (like maxcpus greater than
> >> actual CPUs).
> >>
> >> Opinions? It might be an arm64+ACPI-only thing.
> >
> > I think so. The proper thing to do is to apply sane limits:
> >
> > 1) The possible CPUs enumerated by firmware N_POSSIBLE_FW
> >
> > 2) The maxcpus limit on the command line N_MAXCPUS_CL
> >
> > So the actual possible CPUs evaluates to:
> >
> > num_possible = min(N_POSSIBLE_FW, N_MAXCPUS_CL, CONFIG_NR_CPUS);
> >
> > The evaluation of the firmware should not mark CPUs present which are
> > actually not. ACPI gives you that information. See:
> >
> > 5.2.12.14 GIC CPU Interface (GICC) Structure
> >
> > in the ACPI spec. That has two related bits:
> >
> > Enabled:
> >
> > If this bit is set, the processor is ready for use. If this bit is
> > clear and the Online Capable bit is set, the system supports enabling
> > this processor during OS runtime. If this bit is clear and the Online
> > Capable bit is also clear, this processor is un- usable, and the
> > operating system support will not attempt to use it.
> >
> > Online Capable:
> >
> > The information conveyed by this bit depends on the value of the
> > Enabled bit. If the Enabled bit is set, this bit is reserved and must
> > be zero. Otherwise, if this bit is set, the system supports enabling
> > this processor later during OS runtime
> >
> > So the combination of those gives you the right answer:
> >
> > Enabled Online
> > Capable
> > 0 0 Not present, not possible
> > 0 1 Not present, but possible to "hotplug" layter
> > 1 0 Present
> > 1 1 Invalid
>
> On x86, it seems that all CPUs with the ACPI_MADT_ENABLED bit set will
> be marked as present.
>
> acpi_parse_x2apic()
> -> enabled = processor->lapic_flags & ACPI_MADT_ENABLED
> -> topology_register_apic(enabled)
> -> topo_register_apic(enabled)
> -> set_cpu_present(cpu, true)
Yes but arm64 marks all CPUs present even if !ACPI_MADT_ENABLED as we
don't have the notion of hardware CPU hotplug.
I need to dig some more into the original vCPU hotplug support and why
we ended up with all CPUs marked as present even if not calling
register_cpu():
https://lore.kernel.org/linux-arm-kernel/20240529133446.28446-1-Jonathan.Cameron@huawei.com/
What's the MADT GICC provided by qemu with "-smp cpus=4,maxcpus=8"? If
it says Enabled for the first 4 and Online Capable for the rest, maybe
we can try something like below:
----------------------8<-----------------
diff --git a/arch/arm64/kernel/acpi.c b/arch/arm64/kernel/acpi.c
index 5891f92c2035..681aa2bbc399 100644
--- a/arch/arm64/kernel/acpi.c
+++ b/arch/arm64/kernel/acpi.c
@@ -448,12 +448,14 @@ int acpi_map_cpu(acpi_handle handle, phys_cpuid_t physid, u32 apci_id,
return *pcpu;
}
+ set_cpu_present(*pcpu, true);
return 0;
}
EXPORT_SYMBOL(acpi_map_cpu);
int acpi_unmap_cpu(int cpu)
{
+ set_cpu_present(cpu, false);
return 0;
}
EXPORT_SYMBOL(acpi_unmap_cpu);
diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c
index 1aa324104afb..6421027669fc 100644
--- a/arch/arm64/kernel/smp.c
+++ b/arch/arm64/kernel/smp.c
@@ -566,6 +566,11 @@ struct acpi_madt_generic_interrupt *acpi_cpu_get_madt_gicc(int cpu)
}
EXPORT_SYMBOL_GPL(acpi_cpu_get_madt_gicc);
+static bool acpi_cpu_is_present(int cpu)
+{
+ return acpi_cpu_get_madt_gicc(cpu)->flags & ACPI_MADT_ENABLED;
+}
+
/*
* acpi_map_gic_cpu_interface - parse processor MADT entry
*
@@ -670,6 +675,11 @@ static void __init acpi_parse_and_init_cpus(void)
early_map_cpu_to_node(i, acpi_numa_get_nid(i));
}
#else
+static bool acpi_cpu_is_present(int cpu)
+{
+ return false;
+}
+
#define acpi_parse_and_init_cpus(...) do { } while (0)
#endif
@@ -808,7 +818,8 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
if (err)
continue;
- set_cpu_present(cpu, true);
+ if (acpi_disabled || acpi_cpu_is_present(cpu))
+ set_cpu_present(cpu, true);
numa_store_cpu_info(cpu);
}
}
^ permalink raw reply related
* [PATCH v3 2/3] drm/exynos: remove bridge when component_add fails
From: Osama Abdelkader @ 2026-04-23 20:06 UTC (permalink / raw)
To: luca.ceresoli, Inki Dae, Seung-Woo Kim, Kyungmin Park,
David Airlie, Simona Vetter, Krzysztof Kozlowski, Alim Akhtar,
Andrzej Hajda, Hoegeun Kwon, dri-devel, linux-arm-kernel,
linux-samsung-soc, linux-kernel
Cc: Osama Abdelkader, stable
In-Reply-To: <20260423200622.325076-1-osama.abdelkader@gmail.com>
Use devm_drm_bridge_add() so the bridge is released if probe fails after
registration, and drop the manual drm_bridge_remove() in remove().
Check the return value of devm_drm_bridge_add().
Signed-off-by: Osama Abdelkader <osama.abdelkader@gmail.com>
Fixes: 576d72fbfb45 ("drm/exynos: mic: add a bridge at probe")
Cc: stable@vger.kernel.org
---
v3: add Fixes and Cc tags
v2: devm_drm_bridge_add instead of drm_bridge_add + goto remove_bridge
---
drivers/gpu/drm/exynos/exynos_drm_mic.c | 8 +++-----
1 file changed, 3 insertions(+), 5 deletions(-)
diff --git a/drivers/gpu/drm/exynos/exynos_drm_mic.c b/drivers/gpu/drm/exynos/exynos_drm_mic.c
index 29a8366513fa..e68c954ec3e6 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_mic.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_mic.c
@@ -423,7 +423,9 @@ static int exynos_mic_probe(struct platform_device *pdev)
mic->bridge.of_node = dev->of_node;
- drm_bridge_add(&mic->bridge);
+ ret = devm_drm_bridge_add(dev, &mic->bridge);
+ if (ret)
+ goto err;
pm_runtime_enable(dev);
@@ -443,12 +445,8 @@ static int exynos_mic_probe(struct platform_device *pdev)
static void exynos_mic_remove(struct platform_device *pdev)
{
- struct exynos_mic *mic = platform_get_drvdata(pdev);
-
component_del(&pdev->dev, &exynos_mic_component_ops);
pm_runtime_disable(&pdev->dev);
-
- drm_bridge_remove(&mic->bridge);
}
static const struct of_device_id exynos_mic_of_match[] = {
--
2.43.0
^ permalink raw reply related
* Re: [PATCH rc v2 0/5] iommu/arm-smmu-v3: Fix device crash on kdump kernel
From: Nicolin Chen @ 2026-04-23 20:02 UTC (permalink / raw)
To: will, robin.murphy, jgg, kevin.tian
Cc: joro, praan, baolu.lu, miko.lenczewski, smostafa,
linux-arm-kernel, iommu, linux-kernel, stable, jamien
In-Reply-To: <cover.1776286352.git.nicolinc@nvidia.com>
On Wed, Apr 15, 2026 at 02:17:35PM -0700, Nicolin Chen wrote:
> This is on Github:
> https://github.com/nicolinc/iommufd/commits/smmuv3_kdump-v2
>
> Changelog
> v2
> * Add warning in non-coherent SMMU cases
> * Keep eventq/priq disabled v.s. enabling-and-disabling-later
> * Check KDUMP option in the beginning of arm_smmu_device_reset()
> * Validate STRTAB format matches HW capability instead of forcing flags
https://sashiko.dev/#/patchset/cover.1776286352.git.nicolinc%40nvidia.com
Sashiko posted a few comments, mostly valid.
I am fixing them with a v3.
Thanks
Nicolin
^ permalink raw reply
* [PATCH v4 30/58] perf flamegraph: Port flamegraph to use python module
From: Ian Rogers @ 2026-04-23 19:43 UTC (permalink / raw)
To: acme, adrian.hunter, james.clark, leo.yan, namhyung, tmricht
Cc: alice.mei.rogers, dapeng1.mi, linux-arm-kernel, linux-kernel,
linux-perf-users, mingo, peterz, Ian Rogers
In-Reply-To: <20260423194428.1846255-1-irogers@google.com>
Add a port of the flamegraph script that uses the perf python module
directly. This approach is significantly faster than using perf script
callbacks as it avoids creating intermediate dictionaries for all
event fields.
Assisted-by: Gemini:gemini-3.1-pro-preview
Signed-off-by: Ian Rogers <irogers@google.com>
---
v2:
1. Performance Optimization: Changed Node.children from a list to a
dictionary, reducing the lookup time in find_or_create_node from
O(N) to O(1) and avoiding performance bottlenecks on wide call
graphs.
2. Callchain Fallback: Added a fallback to use the sample's top-level
symbol or instruction pointer if no callchain is present, ensuring
the script still generates meaningful output rather than just
process names.
3. Template Downloading Fix: Corrected the logic handling the
--allow-download flag and custom HTTP URLs. It no longer warns
about missing local files when a URL is provided, and won't
silently overwrite custom URLs with the default one.
4. Output Stream Separation: Moved informational warnings to
sys.stderr to prevent them from corrupting the resulting HTML/JSON
file when the user streams the output to stdout (e.g., using -o -
).
5. XSS Protection: Added basic HTML entity escaping for < , > , and &
within the embedded JSON data blocks. This mitigates the risk of
cross-site scripting if trace data contains maliciously formed
process or symbol names.
---
tools/perf/python/flamegraph.py | 250 ++++++++++++++++++++++++++++++++
1 file changed, 250 insertions(+)
create mode 100755 tools/perf/python/flamegraph.py
diff --git a/tools/perf/python/flamegraph.py b/tools/perf/python/flamegraph.py
new file mode 100755
index 000000000000..f3f69e5a88c2
--- /dev/null
+++ b/tools/perf/python/flamegraph.py
@@ -0,0 +1,250 @@
+#!/usr/bin/env python3
+# SPDX-License-Identifier: GPL-2.0
+"""
+flamegraph.py - create flame graphs from perf samples using perf python module
+"""
+
+import argparse
+import hashlib
+import json
+import os
+import subprocess
+import sys
+import urllib.request
+from typing import Dict, Optional, Union
+import perf
+
+MINIMAL_HTML = """<head>
+ <link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/d3-flame-graph@4.1.3/dist/d3-flamegraph.css">
+</head>
+<body>
+ <div id="chart"></div>
+ <script type="text/javascript" src="https://d3js.org/d3.v7.js"></script>
+ <script type="text/javascript" src="https://cdn.jsdelivr.net/npm/d3-flame-graph@4.1.3/dist/d3-flamegraph.min.js"></script>
+ <script type="text/javascript">
+ const stacks = [/** @flamegraph_json **/];
+ // Note, options is unused.
+ const options = [/** @options_json **/];
+
+ var chart = flamegraph();
+ d3.select("#chart")
+ .datum(stacks[0])
+ .call(chart);
+ </script>
+</body>
+"""
+
+class Node:
+ """A node in the flame graph tree."""
+ def __init__(self, name: str, libtype: str):
+ self.name = name
+ self.libtype = libtype
+ self.value: int = 0
+ self.children: dict[str, Node] = {}
+
+ def to_json(self) -> Dict[str, Union[str, int, list[Dict]]]:
+ """Convert the node to a JSON-serializable dictionary."""
+ return {
+ "n": self.name,
+ "l": self.libtype,
+ "v": self.value,
+ "c": [x.to_json() for x in self.children.values()]
+ }
+
+
+class FlameGraphCLI:
+ """Command-line interface for generating flame graphs."""
+ def __init__(self, args):
+ self.args = args
+ self.stack = Node("all", "root")
+ self.session = None
+
+ @staticmethod
+ def get_libtype_from_dso(dso: Optional[str]) -> str:
+ """Determine the library type from the DSO name."""
+ if dso and (dso == "[kernel.kallsyms]" or dso.endswith("/vmlinux") or dso == "[kernel]"):
+ return "kernel"
+ return ""
+
+ @staticmethod
+ def find_or_create_node(node: Node, name: str, libtype: str) -> Node:
+ """Find a child node with the given name or create a new one."""
+ if name in node.children:
+ return node.children[name]
+ child = Node(name, libtype)
+ node.children[name] = child
+ return child
+
+ def process_event(self, sample) -> None:
+ """Process a single perf sample event."""
+ if self.args.event_name and str(sample.evsel) != self.args.event_name:
+ return
+
+ pid = sample.sample_pid
+ dso_type = ""
+ try:
+ thread = self.session.process(sample.sample_tid)
+ comm = thread.comm()
+ except Exception:
+ comm = "[unknown]"
+
+ if pid == 0:
+ comm = "swapper"
+ dso_type = "kernel"
+ else:
+ comm = f"{comm} ({pid})"
+
+ node = self.find_or_create_node(self.stack, comm, dso_type)
+
+ callchain = sample.callchain
+ if callchain:
+ # We want to traverse from root to leaf.
+ # perf callchain iterator gives leaf to root.
+ # We collect them and reverse.
+ frames = list(callchain)
+ for entry in reversed(frames):
+ name = entry.symbol or "[unknown]"
+ libtype = self.get_libtype_from_dso(entry.dso)
+ node = self.find_or_create_node(node, name, libtype)
+ else:
+ # Fallback if no callchain
+ name = getattr(sample, "symbol", "[unknown]")
+ libtype = self.get_libtype_from_dso(getattr(sample, "dso", "[unknown]"))
+ node = self.find_or_create_node(node, name, libtype)
+
+ node.value += 1
+
+ def get_report_header(self) -> str:
+ """Get the header from the perf report."""
+ try:
+ input_file = self.args.input or "perf.data"
+ output = subprocess.check_output(["perf", "report", "--header-only", "-i", input_file])
+ result = output.decode("utf-8")
+ if self.args.event_name:
+ result += "\nFocused event: " + self.args.event_name
+ return result
+ except Exception:
+ return ""
+
+ def run(self) -> None:
+ """Run the flame graph generation."""
+ input_file = self.args.input or "perf.data"
+ if not os.path.exists(input_file):
+ print(f"Error: {input_file} not found. (try 'perf record' first)", file=sys.stderr)
+ sys.exit(1)
+
+ try:
+ self.session = perf.session(perf.data(input_file),
+ sample=self.process_event)
+ except Exception as e:
+ print(f"Error opening session: {e}", file=sys.stderr)
+ sys.exit(1)
+
+ self.session.process_events()
+
+ stacks_json = json.dumps(self.stack, default=lambda x: x.to_json())
+ # Escape HTML special characters to prevent XSS
+ stacks_json = stacks_json.replace("<", "\\u003c") \
+ .replace(">", "\\u003e").replace("&", "\\u0026")
+
+ if self.args.format == "html":
+ report_header = self.get_report_header()
+ options = {
+ "colorscheme": self.args.colorscheme,
+ "context": report_header
+ }
+ options_json = json.dumps(options)
+ options_json = options_json.replace("<", "\\u003c") \
+ .replace(">", "\\u003e").replace("&", "\\u0026")
+
+ template = self.args.template
+ template_md5sum = None
+ output_str = None
+
+ if not os.path.isfile(template):
+ if template.startswith("http://") or template.startswith("https://"):
+ if not self.args.allow_download:
+ print("Warning: Downloading templates is disabled. "
+ "Use --allow-download.", file=sys.stderr)
+ template = None
+ else:
+ print(f"Warning: Template file '{template}' not found.", file=sys.stderr)
+ if self.args.allow_download:
+ print("Using default CDN template.", file=sys.stderr)
+ template = (
+ "https://cdn.jsdelivr.net/npm/d3-flame-graph@4.1.3/dist/templates/"
+ "d3-flamegraph-base.html"
+ )
+ template_md5sum = "143e0d06ba69b8370b9848dcd6ae3f36"
+ else:
+ template = None
+
+ use_minimal = False
+ try:
+ if not template:
+ use_minimal = True
+ elif template.startswith("http"):
+ with urllib.request.urlopen(template) as url_template:
+ output_str = "".join([l.decode("utf-8") for l in url_template.readlines()])
+ else:
+ with open(template, "r", encoding="utf-8") as f:
+ output_str = f.read()
+ except Exception as err:
+ print(f"Error reading template {template}: {err}\n", file=sys.stderr)
+ use_minimal = True
+
+ if use_minimal:
+ print("Using internal minimal HTML that refers to d3's web site. JavaScript " +
+ "loaded this way from a local file may be blocked unless your " +
+ "browser has relaxed permissions. Run with '--allow-download' to fetch" +
+ "the full D3 HTML template.", file=sys.stderr)
+ output_str = MINIMAL_HTML
+
+ elif template_md5sum:
+ assert output_str is not None
+ download_md5sum = hashlib.md5(output_str.encode("utf-8")).hexdigest()
+ if download_md5sum != template_md5sum:
+ s = None
+ while s not in ["y", "n"]:
+ s = input(f"""Unexpected template md5sum.
+{download_md5sum} != {template_md5sum}, for:
+{output_str}
+continue?[yn] """).lower()
+ if s == "n":
+ sys.exit(1)
+
+ assert output_str is not None
+ output_str = output_str.replace("/** @options_json **/", options_json)
+ output_str = output_str.replace("/** @flamegraph_json **/", stacks_json)
+ output_fn = self.args.output or "flamegraph.html"
+ else:
+ output_str = stacks_json
+ output_fn = self.args.output or "stacks.json"
+
+ if output_fn == "-":
+ sys.stdout.write(output_str)
+ else:
+ print(f"dumping data to {output_fn}")
+ with open(output_fn, "w", encoding="utf-8") as out:
+ out.write(output_str)
+
+
+if __name__ == "__main__":
+ parser = argparse.ArgumentParser(description="Create flame graphs using perf python module.")
+ parser.add_argument("-f", "--format", default="html", choices=["json", "html"],
+ help="output file format")
+ parser.add_argument("-o", "--output", help="output file name")
+ parser.add_argument("--template",
+ default="/usr/share/d3-flame-graph/d3-flamegraph-base.html",
+ help="path to flame graph HTML template")
+ parser.add_argument("--colorscheme", default="blue-green",
+ help="flame graph color scheme", choices=["blue-green", "orange"])
+ parser.add_argument("-i", "--input", help="input perf.data file")
+ parser.add_argument("--allow-download", default=False, action="store_true",
+ help="allow unprompted downloading of HTML template")
+ parser.add_argument("-e", "--event", default="", dest="event_name", type=str,
+ help="specify the event to generate flamegraph for")
+
+ cli_args = parser.parse_args()
+ cli = FlameGraphCLI(cli_args)
+ cli.run()
--
2.54.0.rc2.533.g4f5dca5207-goog
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox