* [PATCH 0/2] pinctrl: aspeed: Make AST2700 SoC1 JTAG master TRST optional
From: Billy Tsai @ 2026-06-16 3:30 UTC (permalink / raw)
To: Andrew Jeffery, Linus Walleij, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Joel Stanley
Cc: linux-aspeed, openbmc, linux-gpio, devicetree, linux-arm-kernel,
linux-kernel, Billy Tsai
The JTAGM1 pin group of the AST2700 SoC1 includes ball D12, which
carries the TRST signal. TRST is an optional signal for a JTAG master:
designs that do not wire it may need the D12 ball for other functions,
but with TRST embedded in the group they cannot use the JTAG master at
all.
Split D12 into a new JTAGM1TRST group under the existing JTAGM1
function, so TRST is only muxed when a board explicitly requests it.
Patch 1 adds the new group to the device tree binding and patch 2
splits the group in the driver.
Note that this changes the meaning of the existing JTAGM1 group: boards
that do use TRST now need to select both the JTAGM1 and JTAGM1TRST
groups.
Signed-off-by: Billy Tsai <billy_tsai@aspeedtech.com>
---
Billy Tsai (2):
dt-bindings: pinctrl: aspeed,ast2700-soc1: Add JTAGM1TRST group
pinctrl: aspeed: Split TRST out of the AST2700 SoC1 JTAGM1 group
.../devicetree/bindings/pinctrl/aspeed,ast2700-soc1-pinctrl.yaml | 1 +
drivers/pinctrl/aspeed/pinctrl-aspeed-g7-soc1.c | 6 ++++--
2 files changed, 5 insertions(+), 2 deletions(-)
---
base-commit: 761af93c9f1a100b8d9f71aa744b8f9abbbbbfb2
change-id: 20260612-pinctrl-fix-1c1e7c37261c
Best regards,
--
Billy Tsai <billy_tsai@aspeedtech.com>
^ permalink raw reply
* [PATCH 1/2] dt-bindings: pinctrl: aspeed,ast2700-soc1: Add JTAGM1TRST group
From: Billy Tsai @ 2026-06-16 3:30 UTC (permalink / raw)
To: Andrew Jeffery, Linus Walleij, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Joel Stanley
Cc: linux-aspeed, openbmc, linux-gpio, devicetree, linux-arm-kernel,
linux-kernel, Billy Tsai
In-Reply-To: <20260616-pinctrl-fix-v1-0-621036e45c7c@aspeedtech.com>
The TRST signal of the JTAG master is optional and may not be wired on
every design, but it is only selectable as part of the JTAGM1 group,
which forces the D12 ball to be muxed whenever the JTAG master is used.
Add a separate JTAGM1TRST group so boards can enable TRST independently
of the other JTAG master signals.
Signed-off-by: Billy Tsai <billy_tsai@aspeedtech.com>
---
.../devicetree/bindings/pinctrl/aspeed,ast2700-soc1-pinctrl.yaml | 1 +
1 file changed, 1 insertion(+)
diff --git a/Documentation/devicetree/bindings/pinctrl/aspeed,ast2700-soc1-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/aspeed,ast2700-soc1-pinctrl.yaml
index 76944fd14e2c..fe7cef4fef6a 100644
--- a/Documentation/devicetree/bindings/pinctrl/aspeed,ast2700-soc1-pinctrl.yaml
+++ b/Documentation/devicetree/bindings/pinctrl/aspeed,ast2700-soc1-pinctrl.yaml
@@ -356,6 +356,7 @@ patternProperties:
- I3C8
- I3C9
- JTAGM1
+ - JTAGM1TRST
- LPC0
- LPC1
- LTPI
--
2.34.1
^ permalink raw reply related
* [PATCH 2/2] pinctrl: aspeed: Split TRST out of the AST2700 SoC1 JTAGM1 group
From: Billy Tsai @ 2026-06-16 3:30 UTC (permalink / raw)
To: Andrew Jeffery, Linus Walleij, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Joel Stanley
Cc: linux-aspeed, openbmc, linux-gpio, devicetree, linux-arm-kernel,
linux-kernel, Billy Tsai
In-Reply-To: <20260616-pinctrl-fix-v1-0-621036e45c7c@aspeedtech.com>
The JTAGM1 group includes the D12 ball carrying the TRST signal, but
TRST is optional for a JTAG master and the ball may be needed for other
functions on designs that do not wire it. With TRST embedded in the
group, such designs cannot use the JTAG master at all.
Move D12 into a new JTAGM1TRST group under the same JTAGM1 function so
TRST is muxed only when a board requests it. Boards that do use TRST
now need to select both the JTAGM1 and JTAGM1TRST groups.
Signed-off-by: Billy Tsai <billy_tsai@aspeedtech.com>
---
drivers/pinctrl/aspeed/pinctrl-aspeed-g7-soc1.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/drivers/pinctrl/aspeed/pinctrl-aspeed-g7-soc1.c b/drivers/pinctrl/aspeed/pinctrl-aspeed-g7-soc1.c
index 50027d69c342..f8b4066699ce 100644
--- a/drivers/pinctrl/aspeed/pinctrl-aspeed-g7-soc1.c
+++ b/drivers/pinctrl/aspeed/pinctrl-aspeed-g7-soc1.c
@@ -1018,7 +1018,8 @@ PIN_GROUP(I3C6, AA22, AB20);
PIN_GROUP(I3C7, AF18, AE19);
PIN_GROUP(I3C8, AD20, AC20);
PIN_GROUP(I3C9, AA21, AB21);
-PIN_GROUP(JTAGM1, D12, F10, E11, F11, F13);
+PIN_GROUP(JTAGM1, F10, E11, F11, F13);
+PIN_GROUP(JTAGM1TRST, D12);
PIN_GROUP(LPC0, AF26, AF25, B16, D14, B15, B14, C17, B13, E14, C15);
PIN_GROUP(LPC1, C16, C14, C11, D9, F14, D10, C12, C13, AE16, AE17);
PIN_GROUP(LTPI, U25, U26, Y26, AA24);
@@ -1263,6 +1264,7 @@ static const struct pingroup aspeed_g7_soc1_groups[] = {
GROUP(I3C8),
GROUP(I3C9),
GROUP(JTAGM1),
+ GROUP(JTAGM1TRST),
GROUP(LPC0),
GROUP(LPC1),
GROUP(LTPI),
@@ -1528,7 +1530,7 @@ static const struct aspeed_g7_soc1_function aspeed_g7_soc1_functions[] = {
FUNC(I3C7, (1), "I3C7"),
FUNC(I3C8, (1), "I3C8"),
FUNC(I3C9, (1), "I3C9"),
- FUNC(JTAGM1, (1), "JTAGM1"),
+ FUNC(JTAGM1, (1, 1), "JTAGM1", "JTAGM1TRST"),
FUNC(LPC0, (2), "LPC0"),
FUNC(LPC1, (2), "LPC1"),
FUNC(LTPI, (2), "LTPI"),
--
2.34.1
^ permalink raw reply related
* [PATCH] dmaengine: sun6i-dma: Fix memory leak in sun6i_dma_terminate_all
From: Hongling Zeng @ 2026-06-16 3:31 UTC (permalink / raw)
To: vkoul, Frank.Li, wens, jernej.skrabec, samuel, mripard, arnd
Cc: dmaengine, linux-arm-kernel, linux-sunxi, linux-kernel,
zhongling0719, Hongling Zeng
When terminating a non-cyclic DMA transfer, the active descriptor
is not properly reclaimed. The descriptor is removed from the
desc_issued list in sun6i_dma_start_desc(), but in
sun6i_dma_terminate_all(), only cyclic transfer descriptors are
added to the desc_completed list before cleanup.
For non-cyclic transfers, pchan->desc is set to NULL without first
adding the descriptor back to a list that vchan_get_all_descriptors()
can collect. This causes the descriptor and its associated LLI chain
to be permanently leaked.
Fix by ensuring both cyclic and non-cyclic active descriptors are
added to the desc_completed list before setting pchan->desc to NULL.
Fixes: 555859308723 ("dmaengine: sun6i: Add driver for the Allwinner A31 DMA controller")
Signed-off-by: Hongling Zeng <zenghongling@kylinos.cn>
---
drivers/dma/sun6i-dma.c | 12 +++++-------
1 file changed, 5 insertions(+), 7 deletions(-)
diff --git a/drivers/dma/sun6i-dma.c b/drivers/dma/sun6i-dma.c
index 7a79f346250a..97730ba6c874 100644
--- a/drivers/dma/sun6i-dma.c
+++ b/drivers/dma/sun6i-dma.c
@@ -946,16 +946,14 @@ static int sun6i_dma_terminate_all(struct dma_chan *chan)
spin_lock_irqsave(&vchan->vc.lock, flags);
- if (vchan->cyclic) {
- vchan->cyclic = false;
- if (pchan && pchan->desc) {
- struct virt_dma_desc *vd = &pchan->desc->vd;
- struct virt_dma_chan *vc = &vchan->vc;
+ if (pchan && pchan->desc) {
+ struct virt_dma_desc *vd = &pchan->desc->vd;
+ struct virt_dma_chan *vc = &vchan->vc;
- list_add_tail(&vd->node, &vc->desc_completed);
- }
+ list_add_tail(&vd->node, &vc->desc_completed);
}
+ vchan->cyclic = false;
vchan_get_all_descriptors(&vchan->vc, &head);
if (pchan) {
--
2.25.1
^ permalink raw reply related
* Re: [PATCH v2 7/8] dt-bindings: display: allwinner: Split H616 DE33 layer reg space
From: Krzysztof Kozlowski @ 2026-06-16 3:51 UTC (permalink / raw)
To: Jernej Škrabec, wens
Cc: samuel, mripard, maarten.lankhorst, tzimmermann, airlied, simona,
robh, krzk+dt, conor+dt, mturquette, sboyd, dri-devel, devicetree,
linux-arm-kernel, linux-sunxi, linux-kernel, linux-clk
In-Reply-To: <0r4us4OeRRWtJhxvps-bZw@gmail.com>
On 15/06/2026 17:47, Jernej Škrabec wrote:
> Dne ponedeljek, 15. junij 2026 ob 06:28:54 Srednjeevropski poletni čas je Krzysztof Kozlowski napisal(a):
>> On 14/06/2026 16:08, Jernej Škrabec wrote:
>>> Dne ponedeljek, 25. maj 2026 ob 14:10:38 Srednjeevropski poletni čas je Krzysztof Kozlowski napisal(a):
>>>> On 24/05/2026 23:33, Chen-Yu Tsai wrote:
>>>>> Hi,
>>>>>
>>>>> (resent from new email)
>>>>>
>>>>> On Thu, May 14, 2026 at 2:04 PM Krzysztof Kozlowski <krzk@kernel.org> wrote:
>>>>>>
>>>>>> On Sat, May 09, 2026 at 09:00:14PM +0200, Jernej Skrabec wrote:
>>>>>>> From: Jernej Skrabec <jernej.skrabec@gmail.com>
>>>>>>>
>>>>>>> As it turns out, current H616 DE33 binding was written based on
>>>>>>> incomplete understanding of DE33 design. Namely, planes are shared
>>>>>>> resource and not tied to specific mixer, which was the case for previous
>>>>>>> generations of Display Engine (DE3 and earlier).
>>>>>>>
>>>>>>> This means that current DE33 binding doesn't properly reflect HW and
>>>>>>> using it would mean that second mixer (used for second display output)
>>>>>>> can't be supported.
>>>>>>>
>>>>>>> Remove layer register space, which will be represented with additional
>>>>>>> node, and replace it with phandle, which will point to that new, shared
>>>>>>> node. That way, all mixers can share same layers.
>>>>>>>
>>>>>>> There is no user of this binding yet, so changes can be made safely,
>>>>>>> without breaking any backward compatibility.
>>>>>>
>>>>>> There is user. git grep gives me:
>>>>>> drivers/gpu/drm/sun4i/sun8i_mixer.c
>>>>>>
>>>>>> which means this is a released ABI. As I understood, the old code was
>>>>>
>>>>> We held off on merging the DT changes so that we could rework this.
>>>>> I can't find the actual request though. It was probably over IRC.
>>>>>
>>>>>> working fine but just did not support all use cases. Why this cannot be
>>>>>> kept backwards compatible?
>>>>>
>>>>> AFAIK the "planes" block is shared between two display mixers. As the
>>>>> commit message explains, this prevents using the second mixer, since
>>>>> only one of them can claim and map the register space. And on the H700
>>>>> (which is the same die as the H616 discussed here but with more exposed
>>>>> interfaces), there could actually be a use case for the second mixer.
>>>>
>>>> It explains why you want to make the changes but not why you cannot keep
>>>> it backwards compatible.
>>>
>>> I guess it can be backward compatible, but I don't think it makes sense.
>>> Yes, original driver implemented original DT bindings, but there is no node
>>> which uses that binding. If there is no user of that, why would driver
>>
>> Did you check all out of tree users of the ABI? All vendor kernels,
>> forks and all of them for which the ABI was made for?
>
> Since when do we care about out of tree users? I understand that drivers
Since always? That is the meaning of ABI. Otherwise there is no point to
discuss ABI at all. Why would it exist if you had all DTS inside kernel
always matching the code?
> must support old device tree files. Once they work, compatibility must
> be carried forward. But that's not the case here.
>
> In any case, vendor kernels have completely different DT structure. This
> was developed independently from them. Take a look at [1] how BSP DT looks
> like, specifically Display Engine node.
>
> Of course there are some distros which grab WIP patches from mailing lists
> soon after they are available. For example, I know that Armbian carried old
> WIP patches which used old ABI. However, such distros generally don't care
> about exact solution and ditch patches as soon as proper solution is merged
> upstream or even when better WIP patches come around. DT files in such
> distros get updated alongside kernel, they are not hidden in firmware.
>
I am not talking about BSP. I am talking about out of tree users for
which we defined the ABI and called it that way.
Best regards,
Krzysztof
^ permalink raw reply
* Re: [GIT PULL] CRC updates for 7.2
From: pr-tracker-bot @ 2026-06-16 3:57 UTC (permalink / raw)
To: Eric Biggers
Cc: Linus Torvalds, linux-crypto, linux-arm-kernel, linux-kernel,
Ard Biesheuvel, Christoph Hellwig
In-Reply-To: <20260615174807.GA1831@quark>
The pull request you sent on Mon, 15 Jun 2026 10:48:07 -0700:
> https://git.kernel.org/pub/scm/linux/kernel/git/ebiggers/linux.git tags/crc-for-linus
has been merged into torvalds/linux.git:
https://git.kernel.org/torvalds/c/ef3b7426a63c930c51d60d6c2428663d52a84e2f
Thank you!
--
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/prtracker.html
^ permalink raw reply
* Re: [PATCH v2] arm64: tlbflush: Don't broadcast if mm was only active on local cpu
From: Linu Cherian @ 2026-06-16 4:54 UTC (permalink / raw)
To: Ryan Roberts
Cc: Will Deacon, Catalin Marinas, Kevin Brodsky, Anshuman Khandual,
Yang Shi, Mark Rutland, Huang Ying, linux-arm-kernel,
linux-kernel
In-Reply-To: <bfc8803d-b375-477e-bba7-806edaf86578@arm.com>
Hi,
On Mon, Jun 15, 2026 at 12:21:19PM +0100, Ryan Roberts wrote:
> On 14/06/2026 12:04, Will Deacon wrote:
> > On Sat, May 23, 2026 at 07:17:10PM +0530, Linu Cherian wrote:
> >> From: Ryan Roberts <ryan.roberts@arm.com>
> >>
> >> There are 3 variants of tlb flush that invalidate user mappings:
> >> flush_tlb_mm(), flush_tlb_page() and __flush_tlb_range(). All of these
> >> would previously unconditionally broadcast their tlbis to all cpus in
> >> the inner shareable domain.
> >>
> >> But this is a waste of effort if we can prove that the mm for which we
> >> are flushing the mappings has only ever been active on the local cpu. In
> >> that case, it is safe to avoid the broadcast and simply invalidate the
> >> current cpu.
> >>
> >> So let's track in mm_context_t::active_cpu either the mm has never been
> >> active on any cpu, has been active on more than 1 cpu, or has been
> >> active on precisely 1 cpu - and in that case, which one. We update this
> >> when switching context, being careful to ensure that it gets updated
> >> *before* installing the mm's pgtables. On the reader side, we ensure we
> >> read *after* the previous write(s) to the pgtable(s) that necessitated
> >> the tlb flush have completed. This guarrantees that if a cpu that is
> >> doing a tlb flush sees it's own id in active_cpu, then the old pgtable
> >> entry cannot have been seen by any other cpu and we can flush only the
> >> local cpu.
> >>
> >> Signed-off-by: Ryan Roberts <ryan.roberts@arm.com>
> >> Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>
> >> Tested-by: Huang Ying <ying.huang@linux.alibaba.com>
> >> [linu.cherian@arm.com: Adapted for v7.1 flush tlb API changes]
> >> Signed-off-by: Linu Cherian <linu.cherian@arm.com>
> >> ---
> >> Changelog from RFC v1:
> >> - Adapted for v7.1 flush tlb API changes
> >> No changes in core logic
> >> - Collected Rb and Tb tags
> >> - lat_mmap benchmark showed dsb(ishst) performs better than dsb(ish),
> >> hence retained dsb(ishst) in flush_tlb_user_pre
> >>
> >>
> >> Testing with 7.1-rc4 :
> >> +-----------------------+---------------------------------------------------+-------------+
> >> | Benchmark | Result Class | Improvement|
> >> +=======================+===================================================+=============+
> >> | perf/syscall | fork (ops/sec) | (I) 3.25% |
> >> +-----------------------+---------------------------------------------------+-------------+
> >> | pts/memtier-benchmark | Protocol: Redis Clients: 100 Ratio: 1:5 (Ops/sec) | (I) 2.70% |
> >> | | Protocol: Redis Clients: 100 Ratio: 5:1 (Ops/sec) | (I) 2.13% |
> >> +-----------------------+---------------------------------------------------+-------------+
> >
> > I think we need a much more comprehensive set of benchmarks before we can
> > begin to consider a change like this.
>
> I believe that Linu ran a wider set of benchmarks and didn't find any
> regressions. These are just the ones that show improvement (Linu, please correct
> me and/or provide details).
Yes, thats correct.
--
Thanks,
Linu Cherian.
^ permalink raw reply
* Re: [PATCH v2] arm64: tlbflush: Don't broadcast if mm was only active on local cpu
From: Linu Cherian @ 2026-06-16 5:00 UTC (permalink / raw)
To: Will Deacon
Cc: Ryan Roberts, Catalin Marinas, Kevin Brodsky, Anshuman Khandual,
Yang Shi, Mark Rutland, Huang Ying, linux-arm-kernel,
linux-kernel, shameerali.kolothum.thodi
In-Reply-To: <ajAPnahwTe1OHQDp@willie-the-truck>
Hi,
On Mon, Jun 15, 2026 at 03:43:41PM +0100, Will Deacon wrote:
> On Mon, Jun 15, 2026 at 12:21:19PM +0100, Ryan Roberts wrote:
> > On 14/06/2026 12:04, Will Deacon wrote:
> > > On Sat, May 23, 2026 at 07:17:10PM +0530, Linu Cherian wrote:
> > >> From: Ryan Roberts <ryan.roberts@arm.com>
> > >>
> > >> Testing with 7.1-rc4 :
> > >> +-----------------------+---------------------------------------------------+-------------+
> > >> | Benchmark | Result Class | Improvement|
> > >> +=======================+===================================================+=============+
> > >> | perf/syscall | fork (ops/sec) | (I) 3.25% |
> > >> +-----------------------+---------------------------------------------------+-------------+
> > >> | pts/memtier-benchmark | Protocol: Redis Clients: 100 Ratio: 1:5 (Ops/sec) | (I) 2.70% |
> > >> | | Protocol: Redis Clients: 100 Ratio: 5:1 (Ops/sec) | (I) 2.13% |
> > >> +-----------------------+---------------------------------------------------+-------------+
> > >
> > > I think we need a much more comprehensive set of benchmarks before we can
> > > begin to consider a change like this.
> >
> > I believe that Linu ran a wider set of benchmarks and didn't find any
> > regressions. These are just the ones that show improvement (Linu, please correct
> > me and/or provide details).
>
> I think it's important to show the ones that suffer as well... and also
> look at different configurations (e.g. preemptible settings) and different
> environments (e.g. native vs in a VM).
All our tests were ran on the host.
Yeah, agree that other suggested configurations/environments need to be anlayzed as well.
--
Thanks,
Linu Cherian.
^ permalink raw reply
* Re: [PATCH v2] arm64: tlbflush: Don't broadcast if mm was only active on local cpu
From: Linu Cherian @ 2026-06-16 5:05 UTC (permalink / raw)
To: Ryan Roberts
Cc: Will Deacon, Catalin Marinas, Kevin Brodsky, Anshuman Khandual,
Yang Shi, Mark Rutland, Huang Ying, linux-arm-kernel,
linux-kernel, shameerali.kolothum.thodi
In-Reply-To: <4aa78619-5a79-4fd0-aaac-a990b8c3fd05@arm.com>
Hi,
On Mon, Jun 15, 2026 at 04:41:04PM +0100, Ryan Roberts wrote:
> On 15/06/2026 15:43, Will Deacon wrote:
> > On Mon, Jun 15, 2026 at 12:21:19PM +0100, Ryan Roberts wrote:
> >> On 14/06/2026 12:04, Will Deacon wrote:
> >>> On Sat, May 23, 2026 at 07:17:10PM +0530, Linu Cherian wrote:
> >>>> From: Ryan Roberts <ryan.roberts@arm.com>
> >>>>
> >>>> Testing with 7.1-rc4 :
> >>>> +-----------------------+---------------------------------------------------+-------------+
> >>>> | Benchmark | Result Class | Improvement|
> >>>> +=======================+===================================================+=============+
> >>>> | perf/syscall | fork (ops/sec) | (I) 3.25% |
> >>>> +-----------------------+---------------------------------------------------+-------------+
> >>>> | pts/memtier-benchmark | Protocol: Redis Clients: 100 Ratio: 1:5 (Ops/sec) | (I) 2.70% |
> >>>> | | Protocol: Redis Clients: 100 Ratio: 5:1 (Ops/sec) | (I) 2.13% |
> >>>> +-----------------------+---------------------------------------------------+-------------+
> >>>
> >>> I think we need a much more comprehensive set of benchmarks before we can
> >>> begin to consider a change like this.
> >>
> >> I believe that Linu ran a wider set of benchmarks and didn't find any
> >> regressions. These are just the ones that show improvement (Linu, please correct
> >> me and/or provide details).
> >
> > I think it's important to show the ones that suffer as well... and also
> > look at different configurations (e.g. preemptible settings) and different
> > environments (e.g. native vs in a VM).
> >
> >> Additionally Huang Ying did some testing against the RFC and reported 4.5%
> >> improvement with Redis:
> >>
> >> https://lore.kernel.org/linux-arm-kernel/87segumv6w.fsf@DESKTOP-5N7EMDA
> >
> > To be clear: I'm not disputing that some benchmarks appear to show a small
> > boost from this series. I'm just worried that's not the whole story.
> >
> >>>> arch/arm64/include/asm/mmu.h | 12 +++
> >>>> arch/arm64/include/asm/mmu_context.h | 2 +
> >>>> arch/arm64/include/asm/tlbflush.h | 127 +++++++++++++++++++++------
> >>>> arch/arm64/mm/context.c | 30 ++++++-
> >>>> 4 files changed, 141 insertions(+), 30 deletions(-)
> >>>
> >>> Doesn't this break BTM/SVM with the SMMU? I think that's a non-starter
> >>> even if you can provide some more compelling numbers.
> >>
> >> AIUI, we don't support BTM upstream - the SMMU uses private ASIDs and implements
> >> MMU notifiers to forward the TLBIs via its command queue interface.
> >>
> >> I was also under the impression that supporting BTM upsteam was not desired;
> >> Please correct me if that's not accurate or if you're aware of plans to add
> >> support. I've been (coincidentlly) looking at some other stuff that could
> >> benefit from BTM but had concluded it wouldn't be an acceptable approach upstream.
> >>
> >> If we did ever want to add SMMU BTM support though, I think it would be simple
> >> enough to add an interface to allow the SMMU to disable the optimization (i.e.
> >> force active_cpu to ACTIVE_CPU_MULTIPLE)?
> >
> > We used to have some initial BTM support in the SMMUv3 driver but the
> > main problem was finding an upstream driver/soc that can use it properly
> > and so it was ultimately removed in d38c28dbefee ("iommu/arm-smmu-v3: Put
> > the SVA mmu notifier in the smmu_domain") because it was getting in the
> > way of wider driver rework and we couldn't test it.
> >
> > However, there *is* work to re-enable it on top of that rework (and other
> > changes):
> >
> > https://lore.kernel.org/linux-iommu/20250319173202.78988-6-shameerali.kolothum.thodi@huawei.com/
> >
> > although I don't know if Shameer intends to repost that...
>
> Thanks for the pointers; That's very interesting feedback. I'll take a closer
> look :)
>
> >
> >>>> +static inline bool flush_tlb_user_pre(struct mm_struct *mm, tlbf_t flags)
> >>>> +{
> >>>> + unsigned int self, active;
> >>>> + bool local;
> >>>> +
> >>>> + migrate_disable();
> >>>> +
> >>>> + if (flags & TLBF_NOBROADCAST) {
> >>>> + dsb(nshst);
> >>>> + return true;
> >>>> + }
> >>>
> >>> Why does the NOBROADCAST case need migration disabled? It didn't before...
> >>
> >> The existing semantic for TLBF_BOBROADCAST is that it emits a local TLBI on
> >> whatever CPU we happen to be executing on. It's used for lazily fixing up
> >> spurious faults (i.e. hitting RO TLB entries when the PTE has been relaxed to
> >> RW). So it's still functionally correct if the thread migrates CPU between
> >> taking the fault and issuing the local TLBI - in the worst case it just leads to
> >> another spurious fault.
> >>
> >> For this new case, we need to ensure we don't get migrated between reading
> >> active_cpu and issuing the local TLBI, otherwise we would only issue a local
> >> TLBI when a broadcast was required.
> >
> > Sounds like those two users probably need separating out, then?
>
> Ahh, I see; I'll admit I hadn't actually reviewed the new integration part. I
> agree - NOBROADCAST is different to to this. This is an optimization for the
> "not NOBROADCAST" case. We need to avoid disabling migration in the NOBROADCAST
> case.
>
Ack.
^ permalink raw reply
* Patch "arm64/mm: Enable batched TLB flush in unmap_hotplug_range()" has been added to the 6.1-stable tree
From: gregkh @ 2026-06-16 5:16 UTC (permalink / raw)
To: anshuman.khandual, catalin.marinas, david, gregkh,
linux-arm-kernel, ryan.roberts, sashal, will
Cc: stable-commits
In-Reply-To: <20260428181949.3127002-1-sashal@kernel.org>
This is a note to let you know that I've just added the patch titled
arm64/mm: Enable batched TLB flush in unmap_hotplug_range()
to the 6.1-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary
The filename of the patch is:
arm64-mm-enable-batched-tlb-flush-in-unmap_hotplug_range.patch
and it can be found in the queue-6.1 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree,
please let <stable@vger.kernel.org> know about it.
From stable+bounces-241756-greg=kroah.com@vger.kernel.org Tue Apr 28 23:49:57 2026
From: Sasha Levin <sashal@kernel.org>
Date: Tue, 28 Apr 2026 14:19:49 -0400
Subject: arm64/mm: Enable batched TLB flush in unmap_hotplug_range()
To: stable@vger.kernel.org
Cc: Anshuman Khandual <anshuman.khandual@arm.com>, Will Deacon <will@kernel.org>, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, "David Hildenbrand (Arm)" <david@kernel.org>, Ryan Roberts <ryan.roberts@arm.com>, Catalin Marinas <catalin.marinas@arm.com>, Sasha Levin <sashal@kernel.org>
Message-ID: <20260428181949.3127002-1-sashal@kernel.org>
From: Anshuman Khandual <anshuman.khandual@arm.com>
[ Upstream commit 48478b9f791376b4b89018d7afdfd06865498f65 ]
During a memory hot remove operation, both linear and vmemmap mappings for
the memory range being removed, get unmapped via unmap_hotplug_range() but
mapped pages get freed only for vmemmap mapping. This is just a sequential
operation where each table entry gets cleared, followed by a leaf specific
TLB flush, and then followed by memory free operation when applicable.
This approach was simple and uniform both for vmemmap and linear mappings.
But linear mapping might contain CONT marked block memory where it becomes
necessary to first clear out all entire in the range before a TLB flush.
This is as per the architecture requirement. Hence batch all TLB flushes
during the table tear down walk and finally do it in unmap_hotplug_range().
Prior to this fix, it was hypothetically possible for a speculative access
to a higher address in the contiguous block to fill the TLB with shattered
entries for the entire contiguous range after a lower address had already
been cleared and invalidated. Due to the table entries being shattered, the
subsequent TLB invalidation for the higher address would not then clear the
TLB entries for the lower address, meaning stale TLB entries could persist.
Besides it also helps in improving the performance via TLBI range operation
along with reduced synchronization instructions. The time spent executing
unmap_hotplug_range() improved 97% measured over a 2GB memory hot removal
in KVM guest.
This scheme is not applicable during vmemmap mapping tear down where memory
needs to be freed and hence a TLB flush is required after clearing out page
table entry.
Cc: Will Deacon <will@kernel.org>
Cc: linux-arm-kernel@lists.infradead.org
Cc: linux-kernel@vger.kernel.org
Closes: https://lore.kernel.org/all/aWZYXhrT6D2M-7-N@willie-the-truck/
Fixes: bbd6ec605c0f ("arm64/mm: Enable memory hot remove")
Cc: stable@vger.kernel.org
Reviewed-by: David Hildenbrand (Arm) <david@kernel.org>
Reviewed-by: Ryan Roberts <ryan.roberts@arm.com>
Signed-off-by: Ryan Roberts <ryan.roberts@arm.com>
Signed-off-by: Anshuman Khandual <anshuman.khandual@arm.com>
Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
[ replaced `__pte_clear()` with `pte_clear()` ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
arch/arm64/mm/mmu.c | 36 ++++++++++++++++++++----------------
1 file changed, 20 insertions(+), 16 deletions(-)
--- a/arch/arm64/mm/mmu.c
+++ b/arch/arm64/mm/mmu.c
@@ -925,10 +925,14 @@ static void unmap_hotplug_pte_range(pmd_
WARN_ON(!pte_present(pte));
pte_clear(&init_mm, addr, ptep);
- flush_tlb_kernel_range(addr, addr + PAGE_SIZE);
- if (free_mapped)
+ if (free_mapped) {
+ /* CONT blocks are not supported in the vmemmap */
+ WARN_ON(pte_cont(pte));
+ flush_tlb_kernel_range(addr, addr + PAGE_SIZE);
free_hotplug_page_range(pte_page(pte),
PAGE_SIZE, altmap);
+ }
+ /* unmap_hotplug_range() flushes TLB for !free_mapped */
} while (addr += PAGE_SIZE, addr < end);
}
@@ -949,15 +953,14 @@ static void unmap_hotplug_pmd_range(pud_
WARN_ON(!pmd_present(pmd));
if (pmd_sect(pmd)) {
pmd_clear(pmdp);
-
- /*
- * One TLBI should be sufficient here as the PMD_SIZE
- * range is mapped with a single block entry.
- */
- flush_tlb_kernel_range(addr, addr + PAGE_SIZE);
- if (free_mapped)
+ if (free_mapped) {
+ /* CONT blocks are not supported in the vmemmap */
+ WARN_ON(pmd_cont(pmd));
+ flush_tlb_kernel_range(addr, addr + PMD_SIZE);
free_hotplug_page_range(pmd_page(pmd),
PMD_SIZE, altmap);
+ }
+ /* unmap_hotplug_range() flushes TLB for !free_mapped */
continue;
}
WARN_ON(!pmd_table(pmd));
@@ -982,15 +985,12 @@ static void unmap_hotplug_pud_range(p4d_
WARN_ON(!pud_present(pud));
if (pud_sect(pud)) {
pud_clear(pudp);
-
- /*
- * One TLBI should be sufficient here as the PUD_SIZE
- * range is mapped with a single block entry.
- */
- flush_tlb_kernel_range(addr, addr + PAGE_SIZE);
- if (free_mapped)
+ if (free_mapped) {
+ flush_tlb_kernel_range(addr, addr + PUD_SIZE);
free_hotplug_page_range(pud_page(pud),
PUD_SIZE, altmap);
+ }
+ /* unmap_hotplug_range() flushes TLB for !free_mapped */
continue;
}
WARN_ON(!pud_table(pud));
@@ -1020,6 +1020,7 @@ static void unmap_hotplug_p4d_range(pgd_
static void unmap_hotplug_range(unsigned long addr, unsigned long end,
bool free_mapped, struct vmem_altmap *altmap)
{
+ unsigned long start = addr;
unsigned long next;
pgd_t *pgdp, pgd;
@@ -1041,6 +1042,9 @@ static void unmap_hotplug_range(unsigned
WARN_ON(!pgd_present(pgd));
unmap_hotplug_p4d_range(pgdp, addr, next, free_mapped, altmap);
} while (addr = next, addr < end);
+
+ if (!free_mapped)
+ flush_tlb_kernel_range(start, end);
}
static void free_empty_pte_table(pmd_t *pmdp, unsigned long addr,
Patches currently in stable-queue which might be from sashal@kernel.org are
queue-6.1/f2fs-use-kfree-instead-of-kvfree-to-free-some-memory.patch
queue-6.1/hwmon-pmbus-adm1266-serialize-gpio-pmbus-accesses-wi.patch
queue-6.1/bonding-refuse-to-enslave-can-devices.patch
queue-6.1/asoc-intel-bytcht_es8316-fix-mclk-leak-on-init-error.patch
queue-6.1/asoc-codecs-simple-mux-fix-enum-control-bounds-check.patch
queue-6.1/selftests-bpf-add-read_build_id-function.patch
queue-6.1/smb-client-validate-the-whole-dacl-before-rewriting-it-in-cifsacl.patch
queue-6.1/rdma-rxe-complete-the-rxe_cleanup_task-backport.patch
queue-6.1/bluetooth-l2cap-fix-possible-crash-on-l2cap_ecred_co.patch
queue-6.1/ipv6-sit-reload-inner-ipv6-header-after-gso-offloads.patch
queue-6.1/ethtool-eeprom-add-more-safeties-to-eeprom-netlink-f.patch
queue-6.1/vxlan-vnifilter-fix-spurious-notification-on-vni-upd.patch
queue-6.1/6lowpan-fix-off-by-one-in-multicast-context-address-.patch
queue-6.1/sctp-fix-race-between-sctp_wait_for_connect-and-peel.patch
queue-6.1/pcnet32-stop-holding-device-spin-lock-during-napi_co.patch
queue-6.1/drm-vc4-fix-krealloc-memory-leak.patch
queue-6.1/f2fs-fix-to-do-sanity-check-on-dcc-discard_cmd_cnt-conditionally.patch
queue-6.1/arm64-tlb-optimize-arm64_workaround_repeat_tlbi.patch
queue-6.1/nfc-llcp-fix-use-after-free-race-in-nfc_llcp_recv_cc.patch
queue-6.1/revert-selftests-bpf-workaround-strict-bpf_lsm-retur.patch
queue-6.1/net-netlink-fix-sending-unassigned-nsid-after-assign.patch
queue-6.1/bluetooth-bnep-reject-short-frames-before-parsing.patch
queue-6.1/net-packet-convert-po-has_vnet_hdr-to-an-atomic-flag.patch
queue-6.1/net-qrtr-ns-free-the-node-during-ctrl_cmd_bye.patch
queue-6.1/dm-cache-policy-smq-check-allocation-under-invalidat.patch
queue-6.1/ipmi-fix-rcu_read_unlock-to-srcu_read_unlock-in-hand.patch
queue-6.1/drm-i915-psr-read-intel-dpcd-workaround-register.patch
queue-6.1/net-fec-fix-pinctrl-default-state-restore-order-on-r.patch
queue-6.1/ipv6-rpl-fix-hdrlen-overflow-in-ipv6_rpl_srh_decompr.patch
queue-6.1/net-gro-don-t-merge-zcopy-skbs.patch
queue-6.1/ieee802154-6lowpan-only-accept-ipv6-packets-in-lowpa.patch
queue-6.1/tun-free-page-on-short-frame-rejection-in-tun_xdp_on.patch
queue-6.1/usb-serial-mct_u232-fix-memory-corruption-with-small.patch
queue-6.1/bluetooth-bnep-fix-incorrect-length-parsing-in-bnep_.patch
queue-6.1/signal-clear-jobctl_pending_mask-for-caller-in-zap_o.patch
queue-6.1/loongarch-add-spectre-boundry-for-syscall-dispatch-table.patch
queue-6.1/alsa-aoa-i2sbus-clear-stale-prepared-state.patch
queue-6.1/sched-use-u64-for-bandwidth-ratio-calculations.patch
queue-6.1/revert-rdma-rxe-fix-double-free-in-rxe_srq_from_init.patch
queue-6.1/net-qrtr-fix-refcount-saturation-and-potential-uaf-i.patch
queue-6.1/media-rc-igorplugusb-heed-coherency-rules.patch
queue-6.1/bpf-free-reuseport-cbpf-prog-after-rcu-grace-period.patch
queue-6.1/net-qrtr-ns-change-servers-radix-tree-to-xarray.patch
queue-6.1/net-mctp-ensure-our-nlmsg-responses-are-initialised.patch
queue-6.1/media-rc-ttusbir-respect-dma-coherency-rules.patch
queue-6.1/batman-adv-tt-fix-toctou-race-for-reported-vlans.patch
queue-6.1/ptp-vclock-switch-from-rcu-to-srcu.patch
queue-6.1/time-fix-off-by-one-in-settimeofday-usec-validation.patch
queue-6.1/usb-serial-cypress_m8-fix-memory-corruption-with-sma.patch
queue-6.1/xfrm-policy-fix-use-after-free-on-inexact-bin-in-xfr.patch
queue-6.1/tools-bootconfig-cleanup-bootconfig-footer-size-calc.patch
queue-6.1/netlabel-validate-unlabeled-address-and-mask-attribu.patch
queue-6.1/batman-adv-tt-avoid-empty-vlan-responses.patch
queue-6.1/net-hsr-fix-potential-oob-access-in-supervision-fram.patch
queue-6.1/drm-remove-plane-hsub-vsub-alignment-requirement-for.patch
queue-6.1/net-qrtr-ns-limit-the-total-number-of-nodes.patch
queue-6.1/selftests-bpf-convert-test_global_funcs-test-to-test.patch
queue-6.1/serial-dz-fix-bootconsole-handover-lockup.patch
queue-6.1/net-sched-revert-net-sched-restrict-conditions-for-a.patch
queue-6.1/net-packet-convert-po-tp_loss-to-an-atomic-flag.patch
queue-6.1/mm-hugetlb-avoid-false-positive-lockdep-assertion.patch
queue-6.1/drm-i915-psr-add-defininitions-for-intel_wa_register.patch
queue-6.1/revert-selftests-bpf-add-a-cgroup-prog-bpf_get_ns_cu.patch
queue-6.1/net-mvpp2-limit-xdp-frame-size-to-the-rx-buffer.patch
queue-6.1/bpf-fix-a-few-selftest-failures-due-to-llvm18-change.patch
queue-6.1/vxlan-do-not-reuse-cached-ip_hdr-value-after-skb_tun.patch
queue-6.1/net-guard-timestamp-cmsgs-to-real-error-queue-skbs.patch
queue-6.1/batman-adv-tvlv-reject-oversized-tvlv-packets.patch
queue-6.1/r8152-block-future-register-access-if-register-acces.patch
queue-6.1/net-mvpp2-add-metadata-support-for-xdp-mode.patch
queue-6.1/net-packet-convert-po-tp_tx_has_off-to-an-atomic-fla.patch
queue-6.1/net-mctp-fix-don-t-require-received-header-reserved-bits-to-be-zero.patch
queue-6.1/xfrm-check-for-underflow-in-xfrm_state_mtu.patch
queue-6.1/netfilter-nf_conntrack-destroy-stale-expectfn-expect.patch
queue-6.1/net-garp-fix-unsigned-integer-underflow-in-garp_pdu_.patch
queue-6.1/selftests-bpf-s-iptables-iptables-legacy-in-the-bpf_.patch
queue-6.1/revert-selftests-bpf-add-tests-for-_opts-variants-of.patch
queue-6.1/hid-core-fix-size_t-specifier-in-hid_report_raw_even.patch
queue-6.1/rds-mark-snapshot-pages-dirty-in-rds_info_getsockopt.patch
queue-6.1/net-sched-act_api-use-rcu-with-deferred-freeing-for-.patch
queue-6.1/bluetooth-6lowpan-check-skb_clone-return-value-in-se.patch
queue-6.1/batman-adv-v-stop-ogmv2-on-disabled-interface.patch
queue-6.1/net-openvswitch-fix-possible-kfree_skb-of-err_ptr.patch
queue-6.1/hwmon-pmbus-adm1266-serialize-sequencer_state-debugf.patch
queue-6.1/fbdev-defio-disconnect-deferred-i-o-from-the-lifetime-of-struct-fb_info.patch
queue-6.1/bluetooth-mgmt-fix-backward-compatibility-with-users.patch
queue-6.1/ip6_vti-fix-incorrect-tunnel-matching-in-vti6_tnl_lo.patch
queue-6.1/gpio-rockchip-convert-bank-clk-to-devm_clk_get_enabl.patch
queue-6.1/selftests-bpf-enhance-align-selftest-s-expected-log-.patch
queue-6.1/netfilter-ctnetlink-ensure-safe-access-to-master-con.patch
queue-6.1/rdma-rxe-fix-double-free-in-rxe_srq_from_init.patch-25226
queue-6.1/hid-pass-the-buffer-size-to-hid_report_raw_event.patch
queue-6.1/alsa-aoa-skip-devices-with-no-codecs-in-i2sbus_resume.patch
queue-6.1/batman-adv-bla-avoid-null-ptr-deref-for-claim-via-dr.patch
queue-6.1/usb-serial-digi_acceleport-fix-memory-corruption-wit.patch
queue-6.1/tools-bootconfig-fix-buf-leaks-in-apply_xbc.patch
queue-6.1/bluetooth-rfcomm-hold-listener-socket-in-rfcomm_conn.patch
queue-6.1/wifi-mwifiex-fix-use-after-free-in-mwifiex_adapter_cleanup.patch
queue-6.1/batman-adv-iv-recover-ogm-scheduling-after-forward-p.patch
queue-6.1/net-sched-cls_fw-fix-null-dereference-of-old-filters.patch
queue-6.1/net-netlink-don-t-set-nsid-on-local-notifications.patch
queue-6.1/tcp-restrict-so_attach_filter-to-priv-users.patch
queue-6.1/batman-adv-tp_meter-directly-shut-down-timer-on-clea.patch
queue-6.1/netfilter-nf_log-validate-mac-header-was-set-before-.patch
queue-6.1/mm-page_alloc-clear-page-private-in-free_pages_prepa.patch
queue-6.1/octeontx2-af-npc-fix-cpt-channel-mask-in-npc_install.patch
queue-6.1/net-smc-do-not-re-initialize-smc-hashtables.patch
queue-6.1/ipvs-clear-the-svc-scheduler-ptr-early-on-edit.patch
queue-6.1/bluetooth-l2cap-clear-chan-ident-on-ecred-reconfigur.patch
queue-6.1/bpf-bonding-reject-vlan-srcmac-xmit_hash_policy-chan.patch
queue-6.1/tunnels-do-not-assume-transport-header-in-iptunnel_p.patch
queue-6.1/iomap-don-t-revert-iov_iter-on-partially-completed-b.patch
queue-6.1/phy-mscc-use-phy_id_match_vendor-to-minimize-phy-id-.patch
queue-6.1/net-802-mrp-fix-vector-attribute-parsing-in-mrp_pdu_.patch
queue-6.1/batman-adv-bla-avoid-double-decrement-of-bla.num_req.patch
queue-6.1/batman-adv-tvlv-abort-ogm-send-on-tvlv-append-failur.patch
queue-6.1/lib-test_hmm-evict-device-pages-on-file-close-to-avoid-use-after-free.patch
queue-6.1/alsa-pcm-fix-wait-queue-list-corruption-in-snd_pcm_d.patch
queue-6.1/net-mvpp2-refill-rx-buffers-before-xdp-or-skb-use.patch
queue-6.1/tun-free-page-on-build_skb-failure-in-tun_xdp_one.patch
queue-6.1/selftests-bpf-fix-arg_ptr_to_long-half-uninitialized.patch
queue-6.1/net-mvpp2-build-skb-from-xdp-adjusted-data-on-xdp_pa.patch
queue-6.1/selftests-bpf-add-generic-bpf-program-tester-loader.patch
queue-6.1/bluetooth-fix-memory-leak-in-error-path-of-hci_alloc.patch
queue-6.1/hid-core-add-printk_ratelimited-variants-to-hid_warn.patch
queue-6.1/bluetooth-mgmt-validate-advertising-tlv-before-type-.patch
queue-6.1/mm-damon-ops-common-call-folio_test_lru-after-folio_.patch
queue-6.1/netfilter-synproxy-add-mutex-to-guard-hook-reference.patch
queue-6.1/asoc-wm_adsp-fix-null-dereference-when-removing-firm.patch
queue-6.1/net-skbuff-fix-missing-zerocopy-reference-in-pskb_ca.patch
queue-6.1/drm-dp-add-edp-1.5-bit-definition.patch
queue-6.1/dmaengine-idxd-fix-not-releasing-workqueue-on-.relea.patch
queue-6.1/ipv6-fix-possible-infinite-loop-in-rt6_fill_node.patch
queue-6.1/tee-optee-prevent-use-after-free-when-the-client-exi.patch
queue-6.1/disable-wattribute-alias-for-clang-23-and-newer.patch
queue-6.1/vxlan-vnifilter-send-notification-on-vni-add.patch
queue-6.1/usb-gadget-f_ncm-fix-net_device-lifecycle-with-devic.patch
queue-6.1/selftests-bpf-update-bpf_clone_redirect-expected-ret.patch
queue-6.1/net-skbuff-fix-pskb_carve-leaking-zcopy-pages.patch
queue-6.1/net-qrtr-ns-limit-the-maximum-number-of-lookups.patch
queue-6.1/net-sched-sch_sfb-replace-direct-dequeue-call-with-p.patch
queue-6.1/netfilter-x_tables-avoid-leaking-percpu-counter-poin.patch
queue-6.1/tunnels-load-network-headers-after-skb_cow-in-iptunn.patch
queue-6.1/spi-imx-fix-use-after-free-on-unbind.patch
queue-6.1/netfilter-synproxy-refresh-tcphdr-after-skb_ensure_w.patch
queue-6.1/arm64-mm-enable-batched-tlb-flush-in-unmap_hotplug_range.patch
queue-6.1/netfilter-nf_tables-restore-set-elements-when-delete.patch
queue-6.1/alsa-aoa-use-guard-for-mutex-locks.patch
queue-6.1/mm-huge_memory-update-file-pmd-counter-before-folio_.patch
queue-6.1/spi-fix-resource-leaks-on-device-setup-failure.patch
queue-6.1/kvm-arm64-remove-vpipt-i-cache-handling.patch
queue-6.1/xhci-tegra-fix-ghost-usb-device-on-dual-role-port-un.patch
queue-6.1/net-mana-add-null-guards-in-teardown-path-to-prevent.patch
queue-6.1/netfilter-nft_exthdr-fix-register-tracking-for-f_pre.patch
queue-6.1/net-packet-fix-toctou-race-on-mmap-d-vnet_hdr-in-tpa.patch
queue-6.1/net-cpsw_new-fix-potential-unregister-of-netdev-that.patch
queue-6.1/drm-i915-psr-apply-intel-dpcd-workaround-when-sdp-on.patch
queue-6.1/net-iucv-fix-locking-in-.getsockopt.patch
queue-6.1/sctp-purge-outqueue-on-stale-cookie-echo-handling.patch
queue-6.1/ipv4-restrict-ipopt_ssrr-and-ipopt_lsrr-options.patch
queue-6.1/netfilter-xt_cpu-prefer-raw_smp_processor_id.patch
queue-6.1/batman-adv-tt-reject-oversized-local-tvlv-buffers.patch
queue-6.1/net-annotate-sk-sk_write_space-for-udp-sockmap.patch
queue-6.1/r8152-handle-the-return-value-of-usb_reset_device.patch
queue-6.1/hwmon-pmbus-adm1266-serialize-nvmem-blackbox-read-wi.patch
queue-6.1/netfilter-ebtables-fix-oob-read-in-compat_mtw_from_u.patch
queue-6.1/r8152-reduce-the-control-transfer-of-rtl8152_get_ver.patch
queue-6.1/net-packet-convert-po-running-to-an-atomic-flag.patch
queue-6.1/tap-free-page-on-error-paths-in-tap_get_user_xdp.patch
queue-6.1/nfc-nxp-nci-i2c-use-rising-edge-irq-on-acpi-systems.patch
queue-6.1/bluetooth-rfcomm-validate-skb-length-in-mcc-handlers.patch
queue-6.1/net-bridge-use-a-stable-fdb-dst-snapshot-in-rcu-readers.patch
queue-6.1/fs-ntfs3-return-error-for-inconsistent-extended-attr.patch
queue-6.1/f2fs-fix-uaf-caused-by-decrementing-sbi-nr_pages-in-f2fs_write_end_io.patch
queue-6.1/thermal-core-fix-thermal-zone-governor-cleanup-issues.patch
queue-6.1/net-lan743x-permit-vlan-tagged-packets-up-to-configu.patch
queue-6.1/drm-imx-fix-three-kernel-doc-warnings-in-dcss-scaler.patch
queue-6.1/spi-imx-convert-to-platform-remove-callback-returning-void.patch
queue-6.1/net-mlx4-avoid-gcc-10-__bad_copy_from-false-positive.patch
queue-6.1/ipv6-fix-possible-infinite-loop-in-fib6_select_path.patch
queue-6.1/netfilter-bridge-make-ebt_snat-arp-rewrite-writable.patch
queue-6.1/nfc-llcp-fix-use-after-free-in-llcp_sock_release.patch
queue-6.1/selftests-forwarding-lib-add-helpers-for-checksum-ha.patch
queue-6.1/ksmbd-require-minimum-ace-size-in-smb_check_perm_dacl.patch
queue-6.1/netfilter-conntrack_irc-fix-possible-out-of-bounds-r.patch
queue-6.1/netfilter-xt_nfqueue-prefer-raw_smp_processor_id.patch
queue-6.1/phy-mscc-use-phy_id_match_exact-for-vsc8584-vsc8582-.patch
queue-6.1/usb-gadget-u_ether-fix-null-pointer-deref-in-eth_get.patch
queue-6.1/net-rds-fix-null-deref-in-rds_ib_send_cqe_handler-on.patch
queue-6.1/sctp-fix-uninit-value-in-__sctp_rcv_asconf_lookup.patch
queue-6.1/ipv4-free-net-ipv4.sysctl_local_reserved_ports-after.patch
queue-6.1/net-mvpp2-sync-rx-data-at-the-hardware-packet-offset.patch
queue-6.1/arm64-tlb-allow-xzr-argument-to-tlbi-ops.patch
^ permalink raw reply
* Patch "arm64/mm: Enable batched TLB flush in unmap_hotplug_range()" has been added to the 5.15-stable tree
From: gregkh @ 2026-06-16 5:32 UTC (permalink / raw)
To: anshuman.khandual, catalin.marinas, david, gregkh,
linux-arm-kernel, ryan.roberts, sashal, will
Cc: stable-commits
In-Reply-To: <20260428185311.3151505-1-sashal@kernel.org>
This is a note to let you know that I've just added the patch titled
arm64/mm: Enable batched TLB flush in unmap_hotplug_range()
to the 5.15-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary
The filename of the patch is:
arm64-mm-enable-batched-tlb-flush-in-unmap_hotplug_range.patch
and it can be found in the queue-5.15 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree,
please let <stable@vger.kernel.org> know about it.
From stable+bounces-241760-greg=kroah.com@vger.kernel.org Wed Apr 29 00:24:42 2026
From: Sasha Levin <sashal@kernel.org>
Date: Tue, 28 Apr 2026 14:53:11 -0400
Subject: arm64/mm: Enable batched TLB flush in unmap_hotplug_range()
To: stable@vger.kernel.org
Cc: Anshuman Khandual <anshuman.khandual@arm.com>, Will Deacon <will@kernel.org>, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, "David Hildenbrand (Arm)" <david@kernel.org>, Ryan Roberts <ryan.roberts@arm.com>, Catalin Marinas <catalin.marinas@arm.com>, Sasha Levin <sashal@kernel.org>
Message-ID: <20260428185311.3151505-1-sashal@kernel.org>
From: Anshuman Khandual <anshuman.khandual@arm.com>
[ Upstream commit 48478b9f791376b4b89018d7afdfd06865498f65 ]
During a memory hot remove operation, both linear and vmemmap mappings for
the memory range being removed, get unmapped via unmap_hotplug_range() but
mapped pages get freed only for vmemmap mapping. This is just a sequential
operation where each table entry gets cleared, followed by a leaf specific
TLB flush, and then followed by memory free operation when applicable.
This approach was simple and uniform both for vmemmap and linear mappings.
But linear mapping might contain CONT marked block memory where it becomes
necessary to first clear out all entire in the range before a TLB flush.
This is as per the architecture requirement. Hence batch all TLB flushes
during the table tear down walk and finally do it in unmap_hotplug_range().
Prior to this fix, it was hypothetically possible for a speculative access
to a higher address in the contiguous block to fill the TLB with shattered
entries for the entire contiguous range after a lower address had already
been cleared and invalidated. Due to the table entries being shattered, the
subsequent TLB invalidation for the higher address would not then clear the
TLB entries for the lower address, meaning stale TLB entries could persist.
Besides it also helps in improving the performance via TLBI range operation
along with reduced synchronization instructions. The time spent executing
unmap_hotplug_range() improved 97% measured over a 2GB memory hot removal
in KVM guest.
This scheme is not applicable during vmemmap mapping tear down where memory
needs to be freed and hence a TLB flush is required after clearing out page
table entry.
Cc: Will Deacon <will@kernel.org>
Cc: linux-arm-kernel@lists.infradead.org
Cc: linux-kernel@vger.kernel.org
Closes: https://lore.kernel.org/all/aWZYXhrT6D2M-7-N@willie-the-truck/
Fixes: bbd6ec605c0f ("arm64/mm: Enable memory hot remove")
Cc: stable@vger.kernel.org
Reviewed-by: David Hildenbrand (Arm) <david@kernel.org>
Reviewed-by: Ryan Roberts <ryan.roberts@arm.com>
Signed-off-by: Ryan Roberts <ryan.roberts@arm.com>
Signed-off-by: Anshuman Khandual <anshuman.khandual@arm.com>
Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
[ replaced `__pte_clear()` with `pte_clear()` ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
arch/arm64/mm/mmu.c | 36 ++++++++++++++++++++----------------
1 file changed, 20 insertions(+), 16 deletions(-)
--- a/arch/arm64/mm/mmu.c
+++ b/arch/arm64/mm/mmu.c
@@ -886,10 +886,14 @@ static void unmap_hotplug_pte_range(pmd_
WARN_ON(!pte_present(pte));
pte_clear(&init_mm, addr, ptep);
- flush_tlb_kernel_range(addr, addr + PAGE_SIZE);
- if (free_mapped)
+ if (free_mapped) {
+ /* CONT blocks are not supported in the vmemmap */
+ WARN_ON(pte_cont(pte));
+ flush_tlb_kernel_range(addr, addr + PAGE_SIZE);
free_hotplug_page_range(pte_page(pte),
PAGE_SIZE, altmap);
+ }
+ /* unmap_hotplug_range() flushes TLB for !free_mapped */
} while (addr += PAGE_SIZE, addr < end);
}
@@ -910,15 +914,14 @@ static void unmap_hotplug_pmd_range(pud_
WARN_ON(!pmd_present(pmd));
if (pmd_sect(pmd)) {
pmd_clear(pmdp);
-
- /*
- * One TLBI should be sufficient here as the PMD_SIZE
- * range is mapped with a single block entry.
- */
- flush_tlb_kernel_range(addr, addr + PAGE_SIZE);
- if (free_mapped)
+ if (free_mapped) {
+ /* CONT blocks are not supported in the vmemmap */
+ WARN_ON(pmd_cont(pmd));
+ flush_tlb_kernel_range(addr, addr + PMD_SIZE);
free_hotplug_page_range(pmd_page(pmd),
PMD_SIZE, altmap);
+ }
+ /* unmap_hotplug_range() flushes TLB for !free_mapped */
continue;
}
WARN_ON(!pmd_table(pmd));
@@ -943,15 +946,12 @@ static void unmap_hotplug_pud_range(p4d_
WARN_ON(!pud_present(pud));
if (pud_sect(pud)) {
pud_clear(pudp);
-
- /*
- * One TLBI should be sufficient here as the PUD_SIZE
- * range is mapped with a single block entry.
- */
- flush_tlb_kernel_range(addr, addr + PAGE_SIZE);
- if (free_mapped)
+ if (free_mapped) {
+ flush_tlb_kernel_range(addr, addr + PUD_SIZE);
free_hotplug_page_range(pud_page(pud),
PUD_SIZE, altmap);
+ }
+ /* unmap_hotplug_range() flushes TLB for !free_mapped */
continue;
}
WARN_ON(!pud_table(pud));
@@ -981,6 +981,7 @@ static void unmap_hotplug_p4d_range(pgd_
static void unmap_hotplug_range(unsigned long addr, unsigned long end,
bool free_mapped, struct vmem_altmap *altmap)
{
+ unsigned long start = addr;
unsigned long next;
pgd_t *pgdp, pgd;
@@ -1002,6 +1003,9 @@ static void unmap_hotplug_range(unsigned
WARN_ON(!pgd_present(pgd));
unmap_hotplug_p4d_range(pgdp, addr, next, free_mapped, altmap);
} while (addr = next, addr < end);
+
+ if (!free_mapped)
+ flush_tlb_kernel_range(start, end);
}
static void free_empty_pte_table(pmd_t *pmdp, unsigned long addr,
Patches currently in stable-queue which might be from sashal@kernel.org are
queue-5.15/bonding-refuse-to-enslave-can-devices.patch
queue-5.15/asoc-intel-bytcht_es8316-fix-mclk-leak-on-init-error.patch
queue-5.15/asoc-codecs-simple-mux-fix-enum-control-bounds-check.patch
queue-5.15/bluetooth-l2cap-fix-possible-crash-on-l2cap_ecred_co.patch
queue-5.15/ipv6-sit-reload-inner-ipv6-header-after-gso-offloads.patch
queue-5.15/ethtool-eeprom-add-more-safeties-to-eeprom-netlink-f.patch
queue-5.15/6lowpan-fix-off-by-one-in-multicast-context-address-.patch
queue-5.15/randomize_kstack-maintain-kstack_offset-per-task.patch
queue-5.15/sctp-fix-race-between-sctp_wait_for_connect-and-peel.patch
queue-5.15/pcnet32-stop-holding-device-spin-lock-during-napi_co.patch
queue-5.15/drm-vc4-fix-krealloc-memory-leak.patch
queue-5.15/f2fs-fix-to-do-sanity-check-on-dcc-discard_cmd_cnt-conditionally.patch
queue-5.15/arm64-tlb-optimize-arm64_workaround_repeat_tlbi.patch
queue-5.15/nfc-llcp-fix-use-after-free-race-in-nfc_llcp_recv_cc.patch
queue-5.15/net-netlink-fix-sending-unassigned-nsid-after-assign.patch
queue-5.15/bluetooth-bnep-reject-short-frames-before-parsing.patch
queue-5.15/nvme-respect-nvme_quirk_disable_write_zeroes-when-wzsl-is-set.patch
queue-5.15/rtw88-8821ce-disable-pcie-aspm-l1-for-8821ce-using-chip-id.patch
queue-5.15/net-qrtr-ns-free-the-node-during-ctrl_cmd_bye.patch
queue-5.15/dm-cache-policy-smq-check-allocation-under-invalidat.patch
queue-5.15/crypto-nx-avoid-wflex-array-member-not-at-end-warning.patch
queue-5.15/drm-i915-psr-read-intel-dpcd-workaround-register.patch
queue-5.15/ipv6-rpl-fix-hdrlen-overflow-in-ipv6_rpl_srh_decompr.patch
queue-5.15/ieee802154-6lowpan-only-accept-ipv6-packets-in-lowpa.patch
queue-5.15/tun-free-page-on-short-frame-rejection-in-tun_xdp_on.patch
queue-5.15/usb-serial-mct_u232-fix-memory-corruption-with-small.patch
queue-5.15/ext4-validate-p_idx-bounds-in-ext4_ext_correct_index.patch
queue-5.15/wifi-rtw88-check-for-pci-upstream-bridge-existence.patch
queue-5.15/bluetooth-bnep-fix-incorrect-length-parsing-in-bnep_.patch
queue-5.15/mtd-spi-nor-sst-fix-write-enable-before-aai-sequence.patch
queue-5.15/signal-clear-jobctl_pending_mask-for-caller-in-zap_o.patch
queue-5.15/alsa-aoa-i2sbus-clear-stale-prepared-state.patch
queue-5.15/sched-use-u64-for-bandwidth-ratio-calculations.patch
queue-5.15/revert-rdma-rxe-fix-double-free-in-rxe_srq_from_init.patch
queue-5.15/can-ucan-fix-devres-lifetime.patch
queue-5.15/net-qrtr-fix-refcount-saturation-and-potential-uaf-i.patch
queue-5.15/media-rc-igorplugusb-heed-coherency-rules.patch
queue-5.15/bpf-free-reuseport-cbpf-prog-after-rcu-grace-period.patch
queue-5.15/net-qrtr-ns-change-servers-radix-tree-to-xarray.patch
queue-5.15/net-mctp-ensure-our-nlmsg-responses-are-initialised.patch
queue-5.15/media-rc-ttusbir-respect-dma-coherency-rules.patch
queue-5.15/batman-adv-tt-fix-toctou-race-for-reported-vlans.patch
queue-5.15/nvme-fix-interpretation-of-dmrsl.patch
queue-5.15/time-fix-off-by-one-in-settimeofday-usec-validation.patch
queue-5.15/usb-serial-cypress_m8-fix-memory-corruption-with-sma.patch
queue-5.15/crypto-nx-fix-bounce-buffer-leaks-in-nx842_crypto_-alloc-free-_ctx.patch
queue-5.15/xfrm-policy-fix-use-after-free-on-inexact-bin-in-xfr.patch
queue-5.15/netlabel-validate-unlabeled-address-and-mask-attribu.patch
queue-5.15/can-ucan-fix-typos-in-comments.patch
queue-5.15/batman-adv-tt-avoid-empty-vlan-responses.patch
queue-5.15/drm-remove-plane-hsub-vsub-alignment-requirement-for.patch
queue-5.15/net-qrtr-ns-limit-the-total-number-of-nodes.patch
queue-5.15/scsi-sd-fix-missing-put_disk-when-device_add-disk_dev-fails.patch
queue-5.15/serial-dz-fix-bootconsole-handover-lockup.patch
queue-5.15/net-sched-revert-net-sched-restrict-conditions-for-a.patch
queue-5.15/drm-i915-psr-add-defininitions-for-intel_wa_register.patch
queue-5.15/net-mvpp2-limit-xdp-frame-size-to-the-rx-buffer.patch
queue-5.15/vxlan-do-not-reuse-cached-ip_hdr-value-after-skb_tun.patch
queue-5.15/udf-fix-partition-descriptor-append-bookkeeping.patch
queue-5.15/scsi-sd-add-error-handling-support-for-add_disk.patch
queue-5.15/net-guard-timestamp-cmsgs-to-real-error-queue-skbs.patch
queue-5.15/batman-adv-tvlv-reject-oversized-tvlv-packets.patch
queue-5.15/net-mvpp2-add-metadata-support-for-xdp-mode.patch
queue-5.15/net-mctp-fix-don-t-require-received-header-reserved-bits-to-be-zero.patch
queue-5.15/xfrm-check-for-underflow-in-xfrm_state_mtu.patch
queue-5.15/net-garp-fix-unsigned-integer-underflow-in-garp_pdu_.patch
queue-5.15/alsa-aloop-fix-peer-runtime-uaf-during-format-change-stop.patch
queue-5.15/hid-core-fix-size_t-specifier-in-hid_report_raw_even.patch
queue-5.15/rds-mark-snapshot-pages-dirty-in-rds_info_getsockopt.patch
queue-5.15/net-sched-act_api-use-rcu-with-deferred-freeing-for-.patch
queue-5.15/wifi-brcmfmac-fix-use-after-free-when-rescheduling-b.patch
queue-5.15/bluetooth-6lowpan-check-skb_clone-return-value-in-se.patch
queue-5.15/mtd-docg3-fix-use-after-free-in-docg3_release.patch
queue-5.15/batman-adv-v-stop-ogmv2-on-disabled-interface.patch
queue-5.15/net-openvswitch-fix-possible-kfree_skb-of-err_ptr.patch
queue-5.15/smb-client-fix-smbdirect_recv_io-leak-in-smbd_negoti.patch
queue-5.15/fbdev-defio-disconnect-deferred-i-o-from-the-lifetime-of-struct-fb_info.patch
queue-5.15/net-packet-fix-toctou-race-on-mmap-d-vnet_hdr-in-tpacket_snd.patch
queue-5.15/ip6_vti-fix-incorrect-tunnel-matching-in-vti6_tnl_lo.patch
queue-5.15/gpio-rockchip-convert-bank-clk-to-devm_clk_get_enabl.patch
queue-5.15/hid-pass-the-buffer-size-to-hid_report_raw_event.patch
queue-5.15/smb-server-fix-active_num_conn-leak-on-transport-allocation-failure.patch
queue-5.15/alsa-aoa-skip-devices-with-no-codecs-in-i2sbus_resume.patch
queue-5.15/printk-add-print_hex_dump_devel.patch
queue-5.15/batman-adv-bla-avoid-null-ptr-deref-for-claim-via-dr.patch
queue-5.15/usb-serial-digi_acceleport-fix-memory-corruption-wit.patch
queue-5.15/bluetooth-rfcomm-hold-listener-socket-in-rfcomm_conn.patch
queue-5.15/wifi-mwifiex-fix-use-after-free-in-mwifiex_adapter_cleanup.patch
queue-5.15/tracepoint-balance-regfunc-on-func_add-failure-in-tracepoint_add_func.patch
queue-5.15/batman-adv-iv-recover-ogm-scheduling-after-forward-p.patch
queue-5.15/net-sched-cls_fw-fix-null-dereference-of-old-filters.patch
queue-5.15/compiler-clang.h-add-__diag-infrastructure-for-clang.patch
queue-5.15/net-netlink-don-t-set-nsid-on-local-notifications.patch
queue-5.15/smb-client-fix-oob-read-in-smb2_ioctl_query_info-query_info-path.patch
queue-5.15/batman-adv-tp_meter-directly-shut-down-timer-on-clea.patch
queue-5.15/netfilter-nf_log-validate-mac-header-was-set-before-.patch
queue-5.15/alsa-core-fix-potential-data-race-at-fasync-handling.patch
queue-5.15/net-smc-do-not-re-initialize-smc-hashtables.patch
queue-5.15/ipvs-clear-the-svc-scheduler-ptr-early-on-edit.patch
queue-5.15/bluetooth-l2cap-clear-chan-ident-on-ecred-reconfigur.patch
queue-5.15/tunnels-do-not-assume-transport-header-in-iptunnel_p.patch
queue-5.15/phy-mscc-use-phy_id_match_vendor-to-minimize-phy-id-.patch
queue-5.15/net-802-mrp-fix-vector-attribute-parsing-in-mrp_pdu_.patch
queue-5.15/batman-adv-bla-avoid-double-decrement-of-bla.num_req.patch
queue-5.15/hfsplus-fix-uninit-value-by-validating-catalog-record-size.patch
queue-5.15/batman-adv-tvlv-abort-ogm-send-on-tvlv-append-failur.patch
queue-5.15/net-mvpp2-refill-rx-buffers-before-xdp-or-skb-use.patch
queue-5.15/mtd-docg3-convert-to-platform-remove-callback-returning-void.patch
queue-5.15/scsi-core-pm-rely-on-the-device-driver-core-for-async-power-management.patch
queue-5.15/tun-free-page-on-build_skb-failure-in-tun_xdp_one.patch
queue-5.15/net-mvpp2-build-skb-from-xdp-adjusted-data-on-xdp_pa.patch
queue-5.15/bluetooth-fix-memory-leak-in-error-path-of-hci_alloc.patch
queue-5.15/hid-core-add-printk_ratelimited-variants-to-hid_warn.patch
queue-5.15/bluetooth-mgmt-validate-advertising-tlv-before-type-.patch
queue-5.15/mm-damon-ops-common-call-folio_test_lru-after-folio_.patch
queue-5.15/mmc-sdhci-of-dwcmshc-disable-clock-before-dll-configuration.patch
queue-5.15/netfilter-synproxy-add-mutex-to-guard-hook-reference.patch
queue-5.15/drm-dp-add-edp-1.5-bit-definition.patch
queue-5.15/dmaengine-idxd-fix-not-releasing-workqueue-on-.relea.patch
queue-5.15/tee-optee-prevent-use-after-free-when-the-client-exi.patch
queue-5.15/disable-wattribute-alias-for-clang-23-and-newer.patch
queue-5.15/net-qrtr-ns-limit-the-maximum-number-of-lookups.patch
queue-5.15/net-sched-sch_sfb-replace-direct-dequeue-call-with-p.patch
queue-5.15/netfilter-x_tables-avoid-leaking-percpu-counter-poin.patch
queue-5.15/tunnels-load-network-headers-after-skb_cow-in-iptunn.patch
queue-5.15/netfilter-synproxy-refresh-tcphdr-after-skb_ensure_w.patch
queue-5.15/arm64-mm-enable-batched-tlb-flush-in-unmap_hotplug_range.patch
queue-5.15/alsa-aoa-use-guard-for-mutex-locks.patch
queue-5.15/bluetooth-hci_event-fix-potential-uaf-in-ssp-passkey-handlers.patch
queue-5.15/kvm-arm64-remove-vpipt-i-cache-handling.patch
queue-5.15/xhci-tegra-fix-ghost-usb-device-on-dual-role-port-un.patch
queue-5.15/netfilter-nft_exthdr-fix-register-tracking-for-f_pre.patch
queue-5.15/net-cpsw_new-fix-potential-unregister-of-netdev-that.patch
queue-5.15/smb-server-fix-max_connections-off-by-one-in-tcp-accept-path.patch
queue-5.15/drm-i915-psr-apply-intel-dpcd-workaround-when-sdp-on.patch
queue-5.15/net-iucv-fix-locking-in-.getsockopt.patch
queue-5.15/rdma-rxe-fix-double-free-in-rxe_srq_from_init.patch-82
queue-5.15/sctp-purge-outqueue-on-stale-cookie-echo-handling.patch
queue-5.15/ipv4-restrict-ipopt_ssrr-and-ipopt_lsrr-options.patch
queue-5.15/netfilter-xt_cpu-prefer-raw_smp_processor_id.patch
queue-5.15/erofs-fix-the-out-of-bounds-nameoff-handling-for-trailing-dirents.patch
queue-5.15/smb-client-require-a-full-nfs-mode-sid-before-reading-mode-bits.patch
queue-5.15/netfilter-ebtables-fix-oob-read-in-compat_mtw_from_u.patch
queue-5.15/ceph-only-d_add-negative-dentries-when-they-are-unhashed.patch
queue-5.15/tap-free-page-on-error-paths-in-tap_get_user_xdp.patch
queue-5.15/nfc-nxp-nci-i2c-use-rising-edge-irq-on-acpi-systems.patch
queue-5.15/bluetooth-rfcomm-validate-skb-length-in-mcc-handlers.patch
queue-5.15/net-bridge-use-a-stable-fdb-dst-snapshot-in-rcu-readers.patch
queue-5.15/fs-ntfs3-return-error-for-inconsistent-extended-attr.patch
queue-5.15/f2fs-fix-uaf-caused-by-decrementing-sbi-nr_pages-in-f2fs_write_end_io.patch
queue-5.15/thermal-core-fix-thermal-zone-governor-cleanup-issues.patch
queue-5.15/net-lan743x-permit-vlan-tagged-packets-up-to-configu.patch
queue-5.15/crypto-nx-migrate-to-scomp-api.patch
queue-5.15/drm-imx-fix-three-kernel-doc-warnings-in-dcss-scaler.patch
queue-5.15/sd-rename-the-scsi_disk.dev-field.patch
queue-5.15/crypto-caam-guard-hmac-key-hex-dumps-in-hash_digest_key.patch
queue-5.15/netfilter-bridge-make-ebt_snat-arp-rewrite-writable.patch
queue-5.15/nfc-llcp-fix-use-after-free-in-llcp_sock_release.patch
queue-5.15/selftests-forwarding-lib-add-helpers-for-checksum-ha.patch
queue-5.15/hfsplus-fix-held-lock-freed-on-hfsplus_fill_super.patch
queue-5.15/ksmbd-require-minimum-ace-size-in-smb_check_perm_dacl.patch
queue-5.15/netfilter-conntrack_irc-fix-possible-out-of-bounds-r.patch
queue-5.15/netfilter-xt_nfqueue-prefer-raw_smp_processor_id.patch
queue-5.15/phy-mscc-use-phy_id_match_exact-for-vsc8584-vsc8582-.patch
queue-5.15/net-rds-fix-null-deref-in-rds_ib_send_cqe_handler-on.patch
queue-5.15/erofs-fix-unsigned-underflow-in-z_erofs_lz4_handle_overlap.patch
queue-5.15/sctp-fix-uninit-value-in-__sctp_rcv_asconf_lookup.patch
queue-5.15/ipv4-free-net-ipv4.sysctl_local_reserved_ports-after.patch
queue-5.15/net-mvpp2-sync-rx-data-at-the-hardware-packet-offset.patch
queue-5.15/arm64-tlb-allow-xzr-argument-to-tlbi-ops.patch
queue-5.15/rxrpc-fix-conn-level-packet-handling-to-unshare-response-packets.patch
queue-5.15/nfsd-don-t-ignore-the-return-code-of-svc_proc_regist.patch
^ permalink raw reply
* Re: [PATCH v6 3/3] PCI: rockchip: drive at 2.5 GT/s, error other speeds
From: Manivannan Sadhasivam @ 2026-06-16 5:39 UTC (permalink / raw)
To: Geraldo Nascimento
Cc: Shawn Lin, Dragan Simic, linux-rockchip, Lorenzo Pieralisi,
Krzysztof Wilczyński, Rob Herring, Bjorn Helgaas, linux-pci,
linux-arm-kernel, linux-kernel
In-Reply-To: <ajBS3tGp0wqLyVq7@geday>
On Mon, Jun 15, 2026 at 04:30:38PM -0300, Geraldo Nascimento wrote:
> Hi,
>
> On Thu, Jun 11, 2026 at 05:04:22PM -0300, Geraldo Nascimento wrote:
> > Configure the core to be driven at 2.5 GT/s Link Speed and ignore
> > any other speed with a warning. Also drop the 5.0 GT/s Link Speed
> > defines from Rockchip PCIe header.
> >
> > The reason is that Shawn Lin from Rockchip has reiterated that there
> > may be danger of "catastrophic failure" in using their PCIe with
> > 5.0 GT/s speeds.
> >
> > While Rockchip has done so informally without issuing a proper errata,
> > and the particulars are thus unknown, this may cause data loss or
> > worse.
> >
> > This change is corroborated by RK3399 official datasheet [1], which
> > states maximum link speed for this platform is 2.5 GT/s.
> >
> > [1] https://opensource.rock-chips.com/images/d/d7/Rockchip_RK3399_Datasheet_V2.1-20200323.pdf
> >
> > Fixes: 956cd99b35a8 ("PCI: rockchip: Separate common code from RC driver")
> > Link: https://lore.kernel.org/all/ffd05070-9879-4468-94e3-b88968b4c21b@rock-chips.com/
> > Cc: stable@vger.kernel.org
> > Reported-by: Dragan Simic <dsimic@manjaro.org>
> > Reported-by: Shawn Lin <shawn.lin@rock-chips.com>
> > Signed-off-by: Geraldo Nascimento <geraldogabriel@gmail.com>
> > ---
> > drivers/pci/controller/pcie-rockchip.c | 16 +++++++++-------
> > drivers/pci/controller/pcie-rockchip.h | 3 ---
> > 2 files changed, 9 insertions(+), 10 deletions(-)
> >
> > diff --git a/drivers/pci/controller/pcie-rockchip.c b/drivers/pci/controller/pcie-rockchip.c
> > index 0f88da3788054..5a2876d7c8547 100644
> > --- a/drivers/pci/controller/pcie-rockchip.c
> > +++ b/drivers/pci/controller/pcie-rockchip.c
> > @@ -66,8 +66,10 @@ int rockchip_pcie_parse_dt(struct rockchip_pcie *rockchip)
> > }
> >
> > rockchip->link_gen = of_pci_get_max_link_speed(node);
> > - if (rockchip->link_gen < 0 || rockchip->link_gen > 2)
> > - rockchip->link_gen = 2;
> > + if (rockchip->link_gen < 0 || rockchip->link_gen >= 2) {
> > + rockchip->link_gen = 1;
> > + dev_warn(dev, "invalid max-link-speed, limited to 2.5 GT/s\n");
> > + }
> >
> > for (i = 0; i < ROCKCHIP_NUM_PM_RSTS; i++)
> > rockchip->pm_rsts[i].id = rockchip_pci_pm_rsts[i];
> > @@ -147,12 +149,12 @@ int rockchip_pcie_init_port(struct rockchip_pcie *rockchip)
> > goto err_exit_phy;
> > }
> >
> > + /* 5.0 GT/s may cause catastrophic failure for this core */
> > if (rockchip->link_gen == 2)
> > - rockchip_pcie_write(rockchip, PCIE_CLIENT_GEN_SEL_2,
>
> Sashiko caught unreachable dead code rightfully here. It looks like I
> had got it right in v4 and then the fix regressed.
>
> Will address this for v7 after I get more comments.
>
I don't have any comments other than this.
- Mani
--
மணிவண்ணன் சதாசிவம்
^ permalink raw reply
* [PATCH v2] dmaengine: sun6i-dma: Fix memory leak in sun6i_dma_terminate_all
From: Hongling Zeng @ 2026-06-16 6:04 UTC (permalink / raw)
To: vkoul, Frank.Li, wens, jernej.skrabec, samuel, mripard, arnd
Cc: dmaengine, linux-arm-kernel, linux-sunxi, linux-kernel,
zhongling0719, Hongling Zeng
When terminating a non-cyclic DMA transfer, the active descriptor
is not properly reclaimed. The descriptor is removed from the
desc_issued list in sun6i_dma_start_desc(), but in
sun6i_dma_terminate_all(), only cyclic transfer descriptors are
added to the desc_completed list before cleanup.
For non-cyclic transfers, pchan->desc is set to NULL without first
adding the descriptor back to a list that vchan_get_all_descriptors()
can collect. This causes the descriptor and its associated LLI chain
to be permanently leaked.
Fix by ensuring both cyclic and non-cyclic active descriptors are
added to the desc_completed list before setting pchan->desc to NULL.
Fixes: 555859308723 ("dmaengine: sun6i: Add driver for the Allwinner A31 DMA controller")
Signed-off-by: Hongling Zeng <zenghongling@kylinos.cn>
---
Change in v2;
-Add pchan->desc != pchan->done check to prevent race condition
where completed descriptors could be double-added to desc_completed
list, causing list corruption
---
drivers/dma/sun6i-dma.c | 12 +++++-------
1 file changed, 5 insertions(+), 7 deletions(-)
diff --git a/drivers/dma/sun6i-dma.c b/drivers/dma/sun6i-dma.c
index 7a79f346250a..12d038ef5f2e 100644
--- a/drivers/dma/sun6i-dma.c
+++ b/drivers/dma/sun6i-dma.c
@@ -946,16 +946,14 @@ static int sun6i_dma_terminate_all(struct dma_chan *chan)
spin_lock_irqsave(&vchan->vc.lock, flags);
- if (vchan->cyclic) {
- vchan->cyclic = false;
- if (pchan && pchan->desc) {
- struct virt_dma_desc *vd = &pchan->desc->vd;
- struct virt_dma_chan *vc = &vchan->vc;
+ if (pchan && pchan->desc && pchan->desc != pchan->done) {
+ struct virt_dma_desc *vd = &pchan->desc->vd;
+ struct virt_dma_chan *vc = &vchan->vc;
- list_add_tail(&vd->node, &vc->desc_completed);
- }
+ list_add_tail(&vd->node, &vc->desc_completed);
}
+ vchan->cyclic = false;
vchan_get_all_descriptors(&vchan->vc, &head);
if (pchan) {
--
2.25.1
^ permalink raw reply related
* Re: [PATCH] PCI: meson: Fix PERST# timing by asserting reset before LTSSM enable
From: neil.armstrong @ 2026-06-16 6:06 UTC (permalink / raw)
To: Ronald Claveau, Gowtham Kudupudi
Cc: robh, bhelgaas, khilman, jbrunet, martin.blumenstingl, linux-pci,
linux-amlogic, linux-arm-kernel, linux-kernel, yue.wang,
lpieralisi, kwilczynski, mani
In-Reply-To: <84cc8b0c-da06-4d01-a076-9743c29c91f6@aliel.fr>
On 6/15/26 12:34, Ronald Claveau wrote:
> On 6/14/26 3:56 AM, Gowtham Kudupudi wrote:
>> On warm reboot, the PCIe controller's LTSSM starts link training
>> immediately if PERST# is already deasserted from the previous boot.
>> The driver then pulses PERST# for only 500us, which is too short to
>> properly reset the endpoint device that has already started training.
>>
>> Fix by moving the PERST# assert/deassert pulse BEFORE enabling LTSSM,
>> so the endpoint gets a clean reset cycle before link training begins.
>>
>> This was found on Amlogic G12B (A311D) with NVMe on an M.2 slot.
>> Cold boot worked because POR held PERST# low; warm reboot did not.
>> The fix was confirmed on a Banana Pi CM4 with Waveshare IO base board.
>>
>> Signed-off-by: Gowtham Kudupudi <gowtham@ferryfair.com>
>> ---
>> drivers/pci/controller/dwc/pci-meson.c | 2 +-
>> 1 file changed, 1 insertion(+), 1 deletion(-)
>>
>> diff --git a/drivers/pci/controller/dwc/pci-meson.c b/drivers/pci/controller/dwc/pci-meson.c
>> index 5f8e2f4b3c12..3a7e9f1d5b8c 100644
>> --- a/drivers/pci/controller/dwc/pci-meson.c
>> +++ b/drivers/pci/controller/dwc/pci-meson.c
>> @@ -310,8 +310,8 @@ static int meson_pcie_start_link(struct dw_pcie *pci)
>> {
>> struct meson_pcie *mp = to_meson_pcie(pci);
>>
>> + meson_pcie_assert_reset(mp);
>> meson_pcie_ltssm_enable(mp);
>> - meson_pcie_assert_reset(mp);
I think this change is valid, other controllers resets PERST
in the host init callback, so either this or move to the
init callback.
Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org>
>>
>> return 0;
>> }
>
> Hi Gowtham,
>
> I have a patch [1] that I haven't submitted yet.
> This might be related to your issue, what do you think ?
Ronald, This fix is valid, it's definitely better to probe the
driver with PERST asserted, please send it.
Neil
>
> [1] https://github.com/rclaveau-tech/linux-khadas/commit/bee0a02d9756
>
^ permalink raw reply
* Re: [PATCH] soc: amlogic: meson-clk-measure: remove debugfs tree
From: Neil Armstrong @ 2026-06-16 6:07 UTC (permalink / raw)
To: Pengpeng Hou, Kevin Hilman, Jerome Brunet, Martin Blumenstingl,
linux-arm-kernel, linux-amlogic, linux-kernel
In-Reply-To: <20260615091531.21964-1-pengpeng@iscas.ac.cn>
On 6/15/26 11:15, Pengpeng Hou wrote:
> meson_msr_probe() creates a debugfs tree with entries that reference
> devm-managed measurement table entries and the driver's private regmap
> state. The driver has no remove callback, so unbinding the device can
> leave those debugfs entries behind after the private data is released.
>
> Store the debugfs root and remove the subtree from a new remove callback.
>
> Signed-off-by: Pengpeng Hou <pengpeng@iscas.ac.cn>
> ---
> drivers/soc/amlogic/meson-clk-measure.c | 14 ++++++++++++++
> 1 file changed, 14 insertions(+)
>
> diff --git a/drivers/soc/amlogic/meson-clk-measure.c b/drivers/soc/amlogic/meson-clk-measure.c
> index d862e30a244e..7ca43bcb622a 100644
> --- a/drivers/soc/amlogic/meson-clk-measure.c
> +++ b/drivers/soc/amlogic/meson-clk-measure.c
> @@ -7,6 +7,7 @@
> #include <linux/of_address.h>
> #include <linux/platform_device.h>
> #include <linux/bitfield.h>
> +#include <linux/err.h>
> #include <linux/seq_file.h>
> #include <linux/debugfs.h>
> #include <linux/regmap.h>
> @@ -50,6 +51,7 @@ struct meson_msr_data {
> struct meson_msr {
> struct regmap *regmap;
> struct meson_msr_data data;
> + struct dentry *debugfs_root;
> };
>
> #define CLK_MSR_ID(__id, __name) \
> @@ -952,6 +954,7 @@ static int meson_msr_probe(struct platform_device *pdev)
> sizeof(struct msr_reg_offset));
>
> root = debugfs_create_dir("meson-clk-msr", NULL);
> + priv->debugfs_root = root;
> clks = debugfs_create_dir("clks", root);
>
> debugfs_create_file("measure_summary", 0444, root,
> @@ -967,9 +970,19 @@ static int meson_msr_probe(struct platform_device *pdev)
> &priv->data.msr_table[i], &clk_msr_fops);
> }
>
> + platform_set_drvdata(pdev, priv);
> +
> return 0;
> }
>
> +static void meson_msr_remove(struct platform_device *pdev)
> +{
> + struct meson_msr *priv = platform_get_drvdata(pdev);
> +
> + if (!IS_ERR_OR_NULL(priv->debugfs_root))
> + debugfs_remove_recursive(priv->debugfs_root);
> +}
> +
> static const struct msr_reg_offset msr_reg_offset = {
> .duty_val = 0x0,
> .freq_ctrl = 0x4,
> @@ -1065,6 +1078,7 @@ MODULE_DEVICE_TABLE(of, meson_msr_match_table);
>
> static struct platform_driver meson_msr_driver = {
> .probe = meson_msr_probe,
> + .remove = meson_msr_remove,
> .driver = {
> .name = "meson_msr",
> .of_match_table = meson_msr_match_table,
Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org>
Thanks,
Neil
^ permalink raw reply
* Re: [PATCH v3 2/2] clk: amlogic: Add A9 peripherals clock controller driver
From: Jian Hu @ 2026-06-16 6:12 UTC (permalink / raw)
To: Jerome Brunet
Cc: Jian Hu via B4 Relay, Neil Armstrong, Michael Turquette,
Stephen Boyd, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Xianwei Zhao, Kevin Hilman, Martin Blumenstingl, linux-amlogic,
linux-clk, devicetree, linux-kernel, linux-arm-kernel
In-Reply-To: <1j7bo0dm0z.fsf@starbuckisacylon.baylibre.com>
On 6/15/2026 8:29 PM, Jerome Brunet wrote:
> [ EXTERNAL EMAIL ]
>
> On lun. 15 juin 2026 at 19:25, Jian Hu <jian.hu@amlogic.com> wrote:
>
>> On 6/10/2026 8:49 PM, Jerome Brunet wrote:
>>> [ EXTERNAL EMAIL ]
>>>
>>> On mer. 10 juin 2026 at 16:14, Jian Hu via B4 Relay <devnull+jian.hu.amlogic.com@kernel.org> wrote:
>>>
>>>> From: Jian Hu <jian.hu@amlogic.com>
>>>>
>>>> Add the peripherals clock controller driver for the Amlogic A9 SoC family.
>>>>
>>>> Signed-off-by: Jian Hu <jian.hu@amlogic.com>
>>>> ---
>>>> drivers/clk/meson/Kconfig | 15 +
>>>> drivers/clk/meson/Makefile | 1 +
>>>> drivers/clk/meson/a9-peripherals.c | 1925 ++++++++++++++++++++++++++++++++++++
>>>> 3 files changed, 1941 insertions(+)
>>>>
>> [ ... ]
>>
>>>> +
>>>> +/* Channel 6 is unconnected. */
>>>> +static u32 a9_glb_parents_val_table[] = { 0, 1, 2, 3, 4, 5, 7 };
>>>> +static struct clk_regmap a9_dspa;
>>> What is this ?
>>
>> The peripheral clock definitions are ordered by register offset.
>>
>> dspa is one of the parents of the glb clock, while the dsp clock registers
>> are located after the GLB clock registers.
>>
>> Since glb references a9_dspa before its full definition appears, the
>> declaration
>>
>> static struct clk_regmap a9_dspa;
>>
>> is added as a forward declaration to satisfy the compiler.
>>
>>
>> Would it make sense to relax the register-offset ordering in this case?
>>
> I don't think we ever enforced such ordering (or any other ordering) in
> the clock driver, so yes please.
>
Understood. I'll reorder the clock definitions accordingly and remove
the forward declaration
in the next version.
>> By defining the DSP clock before the GLB clock, we could remove the forward
>> declaration of a9_dspa.
> Unless it is absolutely necessary, please avoid forward declaration.
>
> Declare what is needed first, keep related things together and use your.
> best judgement ... IOW, make it easy for me to review ;)
Ok.
>>>> +
>>>> +static const struct clk_parent_data a9_glb_parents[] = {
>>>> +};
> [...]
>
>>>> +
>>>> +static struct clk_regmap a9_vclk_div2_en = {
>>>> + .data = &(struct clk_regmap_gate_data){
>>>> + .offset = VID_CLK_CTRL,
>>>> + .bit_idx = 1,
>>>> + },
>>>> + .hw.init = CLK_HW_INIT_HW("vclk_div2_en", &a9_vclk.hw,
>>>> + &clk_regmap_gate_ops, CLK_SET_RATE_PARENT),
>>>> +};
>>> Looks to me all this div_en / div repeating pattern would be easier to review
>>> with tiny macro .
>>
>> Good point.
>>
>> I tried to reduce the repeated div_en/div pattern using a helper macro.
>>
>> It keeps the relationship between gate and fixed-factor clock more compact
>> and easier to review.
>>
>> After using the helper macro, the div_en/div code can be simplified to the
>> following:
>>
>> #define A9_VCLK(_name, _reg, _bit, _div, _parent) \
>> struct clk_regmap a9_##_name##_en = { \
> ^- not strictly necessary, a touch too agressive
>
>
>> .data = &(struct clk_regmap_gate_data){ \
>> .offset = _reg, \
>> .bit_idx = _bit, \
>> }, \
>> .hw.init = &(struct clk_init_data) { \
>> .name = #_name "_en", \
>> .ops = &clk_regmap_gate_ops, \
>> .parent_hws = (const struct clk_hw *[]) { _parent }, \
>> .num_parents = 1, \
>> .flags = CLK_SET_RATE_PARENT, \
>> }, \
>> }; \
>> \
>> struct clk_fixed_factor a9_##_name = { \
>> .mult = 1, \
>> .div = _div, \
>> .hw.init = &(struct clk_init_data){ \
>> .name = #_name, \
>> .ops = &clk_fixed_factor_ops, \
>> .parent_hws = (const struct clk_hw *[]) { \
>> &a9_##_name##_en.hw \
>> }, \
>> .num_parents = 1, \
>> .flags = CLK_SET_RATE_PARENT, \
>> }, \
>> }; \
>>
>> static A9_VCLK(vclk_div2, VID_CLK_CTRL, 1, 2, &a9_vclk.hw);
>> static A9_VCLK(vclk_div4, VID_CLK_CTRL, 2, 4, &a9_vclk.hw);
>> static A9_VCLK(vclk_div6, VID_CLK_CTRL, 3, 6, &a9_vclk.hw);
>> static A9_VCLK(vclk_div6, VID_CLK_CTRL, 4, 12, &a9_vclk.hw);
>> static A9_VCLK(vclk2_div2, VIID_CLK_CTRL, 1, 2, &a9_vclk2.hw);
>> static A9_VCLK(vclk2_div4, VIID_CLK_CTRL, 2, 4, &a9_vclk2.hw);
>> static A9_VCLK(vclk2_div6, VIID_CLK_CTRL, 3, 6, &a9_vclk2.hw);
>> static A9_VCLK(vclk2_div6, VIID_CLK_CTRL, 4, 12, &a9_vclk2.hw);
>>
>>
>> If you think splitting it further into separate helper macros would improve
>> readability.
> One clock per macro please. Hidding 2 declaration is recipe for
> disaster. For ex, here the first one is static, the 2nd is not
I'll split it into separate helper macros so that each macro expands to
a single clock definition.
They are defined as follows: (Excluding struct clk_regmap)
#define A9_VCLK_GATE(_name, _reg, _bit, _parent) \
.data = &(struct clk_regmap_gate_data){ \
.offset = _reg, \
.bit_idx = _bit, \
}, \
.hw.init = &(struct clk_init_data) { \
.name = #_name "_en", \
.ops = &clk_regmap_gate_ops, \
.parent_hws = (const struct clk_hw *[]) { _parent }, \
.num_parents = 1, \
.flags = CLK_SET_RATE_PARENT, \
},
#define A9_VCLK_DIV(_name, _reg, _div) \
....
static struct clk_regmap a9_vclk_div2_en = {
A9_VCLK_GATE(vclk_div2, VID_CLK_CTRL, 1, &a9_vclk.hw),
};
static struct clk_regmap a9_vclk_div2 = {
A9_VCLK_DIV(vclk_div2, VID_CLK_CTRL, 2),
};
My understanding is that you would prefer helper macros to cover only
the repeated initializer fields,
while keeping the actual clock declarations explicit.
If that's not what you had in mind, please let me know.
>> I can do that as well.
>>
--
Jian
^ permalink raw reply
* Re: [PATCH] mmc: sdhci-of-aspeed: depopulate slots before disabling clock
From: Adrian Hunter @ 2026-06-16 6:13 UTC (permalink / raw)
To: Pengpeng Hou, Andrew Jeffery, Ulf Hansson, Joel Stanley,
linux-mmc, linux-aspeed, openbmc, linux-arm-kernel, linux-kernel,
Ryan Chen
In-Reply-To: <20260616004953.3469-1-pengpeng@iscas.ac.cn>
On 16/06/2026 03:49, Pengpeng Hou wrote:
> aspeed_sdc_probe() creates child slot devices one by one after enabling
> the controller clock. If a later slot creation fails, the already-created
> slot devices remain registered while the parent probe returns an error.
>
> Depopulate any created slot devices on probe failure and during remove,
> before disabling the shared controller clock used by the slots.
>
> Signed-off-by: Pengpeng Hou <pengpeng@iscas.ac.cn>
> ---
> drivers/mmc/host/sdhci-of-aspeed.c | 5 ++++-
> 1 file changed, 4 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/mmc/host/sdhci-of-aspeed.c b/drivers/mmc/host/sdhci-of-aspeed.c
> index f5d973783cbe..3e941b176687 100644
> --- a/drivers/mmc/host/sdhci-of-aspeed.c
> +++ b/drivers/mmc/host/sdhci-of-aspeed.c
> @@ -560,12 +560,14 @@ static int aspeed_sdc_probe(struct platform_device *pdev)
> cpdev = of_platform_device_create(child, NULL, &pdev->dev);
> if (!cpdev) {
> ret = -ENODEV;
> - goto err_clk;
> + goto err_depopulate;
> }
> }
>
> return 0;
>
> +err_depopulate:
> + of_platform_depopulate(&pdev->dev);
of_platform_depopulate() does not appear to work with
of_platform_device_create() due to the OF_POPULATED_BUS flag
> err_clk:
> clk_disable_unprepare(sdc->clk);
> return ret;
> @@ -575,6 +577,7 @@ static void aspeed_sdc_remove(struct platform_device *pdev)
> {
> struct aspeed_sdc *sdc = dev_get_drvdata(&pdev->dev);
>
> + of_platform_depopulate(&pdev->dev);
> clk_disable_unprepare(sdc->clk);
> }
>
There is another existing issue that Sashiko noticed:
struct platform_driver aspeed_sdc_driver has:
.pm = &sdhci_pltfm_pmops,
where it won't work correctly. It looks like it
should have instead been in:
struct platform_driver aspeed_sdhci_driver
Refer:
https://sashiko.dev/#/patchset/20260616004953.3469-1-pengpeng%40iscas.ac.cn
^ permalink raw reply
* Re: [PATCH v2] arm64: tlbflush: Don't broadcast if mm was only active on local cpu
From: Mark Rutland @ 2026-06-16 6:13 UTC (permalink / raw)
To: Will Deacon
Cc: Linu Cherian, Catalin Marinas, Ryan Roberts, Kevin Brodsky,
Anshuman Khandual, Yang Shi, Huang Ying, linux-arm-kernel,
linux-kernel
In-Reply-To: <ajAPxKUTp66IRMMF@willie-the-truck>
On Mon, Jun 15, 2026 at 03:44:20PM +0100, Will Deacon wrote:
> On Mon, Jun 15, 2026 at 01:39:43PM +0100, Mark Rutland wrote:
> > On Sun, Jun 14, 2026 at 12:04:44PM +0100, Will Deacon wrote:
> > > On Sat, May 23, 2026 at 07:17:10PM +0530, Linu Cherian wrote:
> >
> > > > static inline void flush_tlb_mm(struct mm_struct *mm)
> > > > {
> > > > unsigned long asid;
> > > > + bool local;
> > > >
> > > > - dsb(ishst);
> > > > + local = flush_tlb_user_pre(mm, TLBF_NONE);
> > > > asid = __TLBI_VADDR(0, ASID(mm));
> > > > - __tlbi(aside1is, asid);
> > > > - __tlbi_user(aside1is, asid);
> > > > - __tlbi_sync_s1ish(mm);
> > > > + if (local) {
> > > > + __tlbi(aside1, asid);
> > > > + __tlbi_user(aside1, asid);
> > > > + dsb(nsh);
> > > > + } else {
> > > > + __tlbi(aside1is, asid);
> > > > + __tlbi_user(aside1is, asid);
> > > > + __tlbi_sync_s1ish(mm);
> > > > + }
> > > > + flush_tlb_user_post(local);
> > >
> > > I think you've changed this since Ryan's original patch, but why are you
> > > only calling __tlbi_sync_s1ish() for the !local case? Doesn't that break
> > > the erratum workaround when running as a VM if the vCPU is migrated?
> >
> > The errata mitigated by __tlbi_sync_s1ish() only affect broadcast
> > maintenance (the 'ish' in the name was intended to convey that). No
> > workaround is necessary for local TLB maintenance; aside from anything
> > else, when some PE executes the DSB to complete the maintenance, that
> > DSB alone is sufficient to complete memory accesses made by that PE.
> >
> > If it would make things clearer, we could add a __tlbi_sync_s1nsh()
> > helper for the local case, which would boil down to a DSB NSH.
>
> No, I don't think that's what I'm concerned about.
I *think* you're missing the shape of the errata; more on that below.
> > Regardless of the erratum, to correctly handle a vCPU being migrated
> > from pCPU-x to pCPU-y, we rely on:
> >
> > * The host to set HCR_EL2.FB to ensure that TLB maintenance is
> > broadcast to the ISH domain.
> >
> > * The host to set HCR_EL2.BSU to ensure the DSB is upgrade to ISH such
> > that any guest-issued DSB NSH will it can complete any TLB maintenance
> > that was upgraded to ISH.
> >
> > * The host to issue a DSB ISH on pCPU-x before the vCPU can run on
> > pCPU-y, to complete any outstanding maintenance that was issued on
> > pCPU-x. IIUC a DSB ISH on pCPU-y is not architecturally sufficient; it
> > must be executed on the same CPU which issued the TLB maintenance.
> >
> > ... but as above, all of that should be independent of any of the errata
> > that require the workaround.
>
> Yes, I understand all of the above but the case I'm struggling with is
> where a vCPU runs on a system that needs the TLB invalidation to be
> performed twice. For non-broadcast invalidation (from the guest
> perspective), this patch will mean that it only performs the
> invalidation once. So if the vCPU migrates to another physical CPU, can
> that effectively undo the HCR_EL2.FB upgrade unless KVM issues TLB
> invalidation as well as a DSB on migration?
>
> Maybe I'm missing something, as it looks like upstream already elides
> the call to __tlbi_sync_s1ish() for the NOBROADCAST case.
The key thing is that these errata only affect the completion of memory
accesses, and only those accesses made by other (physical) PEs.
A single TLBI will correctly remove the actual TLB entries, and
HCR_EL2.{FB,BSU} will still ensure that TLB entries are removed from the
TLBs of other PEs.
The errata only prevent completion of memory accesses made on other
(physical) PEs, and:
* For accesses made by the vCPU which is issuing the TLBI(s):
- Regardless of the errata, the hypervisor has to ensure that when a
vCPU is migrated from pCPU-x to pCPU-y, any prior CMOs or TLBIs are
completed, which requires the host to execute a DSB ISH on pCPU-x
before the vCPU can be run on pCPU-y.
Maybe we have a latent bug here?
- Within the context of the vCPU thread, a DSB {NSH,ISH,OSH} will
complete all prior accesses made by the vCPU *regardless* of any TLB
invalidation.
* For accesses made by *other* vCPUs, either:
- Software in the VM intended to complete concurrency accesses made by
other vCPUs. In which case, regardless of the errata, using a local
TLBI alone is a software bug since that's not guaranteed to affect
other PEs.
- Software did not intend to complete accesses made by other vCPUs.
In which case, it's fine that they may have uncompleted accesses.
... but maybe I'm still missing your concern?
Mark.
^ permalink raw reply
* Re: [PATCH v5 3/4] PCI: endpoint: Add support for DOE initialization and setup in EPC core
From: Manivannan Sadhasivam @ 2026-06-16 6:22 UTC (permalink / raw)
To: Aksh Garg
Cc: Bjorn Helgaas, linux-pci, linux-doc, kwilczynski, bhelgaas,
corbet, kishon, skhan, lukas, cassel, alistair, linux-arm-kernel,
linux-kernel, s-vadapalli, danishanwar, srk
In-Reply-To: <0216a528-3737-4714-b9d1-5d28008e0ec8@ti.com>
On Fri, Jun 12, 2026 at 01:54:13PM +0530, Aksh Garg wrote:
>
>
> On 12/06/26 00:42, Bjorn Helgaas wrote:
> > On Wed, Jun 10, 2026 at 03:32:55PM +0530, Aksh Garg wrote:
> > > Add pci_epc_init_capabilities() in EPC core driver to initialize and
> > > setup the capabilities supported by the EPC driver. This calls
> > > pci_epc_doe_setup() to setup the DOE framework for an endpoint controller,
> > > which discovers the DOE capabilities (extended capability ID 0x2E), and
> > > registers each discovered DOE mailbox for all the functions in the
> > > endpoint controller.
> > >
> > > Add pci_epc_deinit_capabilities() in EPC core driver for cleanup of the
> > > resources used by the capabilities of the EPC driver. This calls
> > > pci_ep_doe_destroy() to destroy all DOE mailboxes and free associated
> > > resources.
> > >
> > > Co-developed-by: Siddharth Vadapalli <s-vadapalli@ti.com>
> > > Signed-off-by: Siddharth Vadapalli <s-vadapalli@ti.com>
> > > Signed-off-by: Aksh Garg <a-garg7@ti.com>
> > > ---
> > > +/**
> > > + * pci_epc_doe_setup() - Discover and setup DOE mailboxes for all functions
> > > + * @epc: the EPC device on which DOE mailboxes has to be setup
> > > + *
> > > + * Discover DOE (Data Object Exchange) capabilities for all physical functions
> > > + * in the endpoint controller and register DOE mailboxes.
> > > + *
> > > + * Returns: 0 on success, -errno on failure
> > > + */
> > > +static int pci_epc_doe_setup(struct pci_epc *epc)
> > > +{
> > > + u8 func_no, vfunc_no = 0;
> > > + u16 cap_offset;
> > > + int ret;
> > > +
> > > + if (!epc->ops || !epc->ops->find_ext_capability)
> > > + return -EINVAL;
> >
>
> Hi Bjorn,
>
> Thank you for your feedback comments. I will work on them and post v6
> series incorporating the changes.
>
> > I don't see anything that sets pci_epc_ops.find_ext_capability in this
> > series, so this looks currently unused and untestable, so likely not
> > mergeable as-is. What's the plan for users of this?
> >
>
> Currently there is no EPC driver upstream which supports DOE yet. However, I
> am working on a platform which supports DOE (support for
> which would be added soon). Mani pointed out that if EPC driver support
> for the same is guaranteed to be added soon, the APIs can be merged
> first.
>
> For the demonstration purpose, he asked to show how an EPC driver is
> expected to use the API as a snippet in the cover letter itself.
>
I retract my previous comment here. Let's not introduce dead code in the kernel.
We can review the series now, but cannot merge it until the EPC driver gets
submitted.
- Mani
--
மணிவண்ணன் சதாசிவம்
^ permalink raw reply
* [PATCH] PCI: dwc: meson: Fix reset GPIO initial state
From: Ronald Claveau via B4 Relay @ 2026-06-16 7:07 UTC (permalink / raw)
To: Yue Wang, Lorenzo Pieralisi, Krzysztof Wilczyński,
Manivannan Sadhasivam, Rob Herring, Bjorn Helgaas, Neil Armstrong,
Kevin Hilman, Jerome Brunet, Martin Blumenstingl, Remi Pommarel
Cc: linux-pci, linux-amlogic, linux-arm-kernel, linux-kernel,
Ronald Claveau
From: Ronald Claveau <linux-kernel-dev@aliel.fr>
Commit 4d3186a525b3 ("PCI: amlogic: Fix reset assertion via gpio
descriptor") inverted the reset assertion logic to use proper gpio
descriptor semantics, and moved the polarity configuration to the
device tree as GPIO_ACTIVE_LOW. However, the initial GPIO state
"GPIOD_OUT_LOW" was not updated accordingly.
Change GPIOD_OUT_LOW to GPIOD_OUT_HIGH to get the right behaviour.
With GPIOD_OUT_LOW:
ahci 0000:01:00.0: enabling device (0000 -> 0002)
ahci 0000:01:00.0: SSS flag set, parallel bus scan disabled
ahci 0000:01:00.0: Controller reset failed (0xffffffff)
ahci 0000:01:00.0: probe with driver ahci failed with error -5
With this fix:
ahci 0000:01:00.0: enabling device (0000 -> 0002)
ahci 0000:01:00.0: AHCI vers 0001.0300, 32 command slots, 6 Gbps,
SATA mode
ahci 0000:01:00.0: 1/1 ports implemented (port mask 0x1)
ahci 0000:01:00.0: flags: 64bit ncq led clo only pio ccc
Fixes: 4d3186a525b3 ("PCI: amlogic: Fix reset assertion via gpio descriptor")
Signed-off-by: Ronald Claveau <linux-kernel-dev@aliel.fr>
---
drivers/pci/controller/dwc/pci-meson.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/pci/controller/dwc/pci-meson.c b/drivers/pci/controller/dwc/pci-meson.c
index 0694084f612b7..15ed59b8764fb 100644
--- a/drivers/pci/controller/dwc/pci-meson.c
+++ b/drivers/pci/controller/dwc/pci-meson.c
@@ -400,7 +400,7 @@ static int meson_pcie_probe(struct platform_device *pdev)
return PTR_ERR(mp->phy);
}
- mp->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW);
+ mp->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_HIGH);
if (IS_ERR(mp->reset_gpio)) {
dev_err(dev, "get reset gpio failed\n");
return PTR_ERR(mp->reset_gpio);
---
base-commit: abe651837cb394f76d738a7a747322fca3bf17ba
change-id: 20260616-fix-meson-pcie-reset-gpio-2b9e188668c5
Best regards,
--
Ronald Claveau <linux-kernel-dev@aliel.fr>
^ permalink raw reply related
* Re: [PATCH] PCI: dwc: meson: Fix reset GPIO initial state
From: Neil Armstrong @ 2026-06-16 7:10 UTC (permalink / raw)
To: linux-kernel-dev, Yue Wang, Lorenzo Pieralisi,
Krzysztof Wilczyński, Manivannan Sadhasivam, Rob Herring,
Bjorn Helgaas, Kevin Hilman, Jerome Brunet, Martin Blumenstingl,
Remi Pommarel
Cc: linux-pci, linux-amlogic, linux-arm-kernel, linux-kernel
In-Reply-To: <20260616-fix-meson-pcie-reset-gpio-v1-1-fca404b4c8be@aliel.fr>
On 6/16/26 09:07, Ronald Claveau via B4 Relay wrote:
> From: Ronald Claveau <linux-kernel-dev@aliel.fr>
>
> Commit 4d3186a525b3 ("PCI: amlogic: Fix reset assertion via gpio
> descriptor") inverted the reset assertion logic to use proper gpio
> descriptor semantics, and moved the polarity configuration to the
> device tree as GPIO_ACTIVE_LOW. However, the initial GPIO state
> "GPIOD_OUT_LOW" was not updated accordingly.
>
> Change GPIOD_OUT_LOW to GPIOD_OUT_HIGH to get the right behaviour.
>
> With GPIOD_OUT_LOW:
>
> ahci 0000:01:00.0: enabling device (0000 -> 0002)
> ahci 0000:01:00.0: SSS flag set, parallel bus scan disabled
> ahci 0000:01:00.0: Controller reset failed (0xffffffff)
> ahci 0000:01:00.0: probe with driver ahci failed with error -5
>
> With this fix:
>
> ahci 0000:01:00.0: enabling device (0000 -> 0002)
> ahci 0000:01:00.0: AHCI vers 0001.0300, 32 command slots, 6 Gbps,
> SATA mode
> ahci 0000:01:00.0: 1/1 ports implemented (port mask 0x1)
> ahci 0000:01:00.0: flags: 64bit ncq led clo only pio ccc
>
> Fixes: 4d3186a525b3 ("PCI: amlogic: Fix reset assertion via gpio descriptor")
> Signed-off-by: Ronald Claveau <linux-kernel-dev@aliel.fr>
> ---
> drivers/pci/controller/dwc/pci-meson.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/pci/controller/dwc/pci-meson.c b/drivers/pci/controller/dwc/pci-meson.c
> index 0694084f612b7..15ed59b8764fb 100644
> --- a/drivers/pci/controller/dwc/pci-meson.c
> +++ b/drivers/pci/controller/dwc/pci-meson.c
> @@ -400,7 +400,7 @@ static int meson_pcie_probe(struct platform_device *pdev)
> return PTR_ERR(mp->phy);
> }
>
> - mp->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW);
> + mp->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_HIGH);
> if (IS_ERR(mp->reset_gpio)) {
> dev_err(dev, "get reset gpio failed\n");
> return PTR_ERR(mp->reset_gpio);
>
> ---
> base-commit: abe651837cb394f76d738a7a747322fca3bf17ba
> change-id: 20260616-fix-meson-pcie-reset-gpio-2b9e188668c5
>
> Best regards,
Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org>
Thanks,
Neil
^ permalink raw reply
* [PATCH v3 0/3] perf: marvell: LLC-TAD PMU MPAM filtering support
From: Geetha sowjanya @ 2026-06-16 7:11 UTC (permalink / raw)
To: linux-perf-users, linux-kernel, linux-arm-kernel, devicetree
Cc: mark.rutland, will, krzk+dt, gakula
This series extends the Marvell LLC-TAD performance driver used on CN10K
and CN20K systems.
Patch 1 adds optional MPAM partition-id filtering for the subset of TAD
events that support it, exposes partid / partid_en in the PMU format string,
and keeps the reduced Odyssey event surface without advertising partid where
it does not apply. It also fixes probe resource handling (no in-place
mutation of platform_get_resource() bounds, validate MMIO window vs
tad-cnt), orders perf registration vs hotplug with unwind, and aligns the
filter-enable bit in config1 with the sysfs format (bit 9).
Patch 2 introduces CN20K LLC-TAD support: non-standard PFC/PRF offsets,
additional programmable events with visibility checks so CN10K does not
advertise V3-only events, CN20K-specific MPAM encoding for the V3 profile,
local64_set(prev_count) on counter start, and device discovery via OF and
ACPI.
Patch 3 extends the DeviceTree binding for marvell,cn20k-tad-pmu.
Changes since v2
----------------
- Validate the eventId using an appropriate mask to ensure it is restricted to 8 bits.
Changes since v1
----------------
- config1: use bit 9 for MPAM filter enable consistently with partid_en in
the PMU format; allow only bits 0..9 in event_init on CN10K/CN20K paths.
- Reject reserved bits in attr.config and use the same 8-bit event index in
start_counter as in event_init so MPAM validation cannot be bypassed.
- Hide V3-only sysfs events on V1.
- Reset prev_count when starting counters after clearing hardware.
- DT binding: explain non-fallback compatibles for CN10K vs CN20K.
Tanmay Jagdale (1):
perf: marvell: Add MPAM partid filtering to CN10K TAD PMU
Geetha sowjanya (2):
perf: marvell: Add CN20K LLC-TAD PMU support
dt-bindings: perf: marvell: Extend CN10K TAD PMU binding for CN20K
Signed-off-by: Geetha sowjanya <gakula@marvell.com>
--
2.25.1
^ permalink raw reply
* [PATCH v3 1/3] perf: marvell: Add MPAM partid filtering to CN10K TAD PMU
From: Geetha sowjanya @ 2026-06-16 7:11 UTC (permalink / raw)
To: linux-perf-users, linux-kernel, linux-arm-kernel, devicetree
Cc: mark.rutland, will, krzk+dt, gakula
In-Reply-To: <20260616071149.12523-1-gakula@marvell.com>
From: Tanmay Jagdale <tanmay@marvell.com>
The TAD PMU exposes counters that can be filtered by MPAM partition id
for a subset of allocation and hit events.
Add a 9-bit partid format attribute (config1) and route counter programming
through variant-specific ops so CN10K keeps MPAM-capable programming while
Odyssey keeps the reduced event set without advertising partid in sysfs.
Probe no longer mutates the platform_device MMIO resource (walk a local
map_start), rejects tad-cnt / page sizes of zero, validates the memory
window against tad-cnt, and registers the perf PMU before hotplug with
correct unwind.
Example:
perf stat -e tad/tad_alloc_any,partid=0x12,partid_en=1/ -- <program>
Signed-off-by: Tanmay Jagdale <tanmay@marvell.com>
---
Changelog (since v2)
--------------------
- Validate the eventId using an appropriate mask to ensure
it is restricted to 8 bits
Changelog (since v1)
--------------------
- Fix config1 filter enable to use bit 9 consistently with the PMU format
string (partid_en) and reject reserved bits with GENMASK(9, 0).
- Register perf_pmu_register before cpuhp_state_add_instance_nocalls and
unregister on hotplug failure.
drivers/perf/marvell_cn10k_tad_pmu.c | 216 ++++++++++++++++++++-------
1 file changed, 164 insertions(+), 52 deletions(-)
diff --git a/drivers/perf/marvell_cn10k_tad_pmu.c b/drivers/perf/marvell_cn10k_tad_pmu.c
index 51ccb0befa05..69a6648fa664 100644
--- a/drivers/perf/marvell_cn10k_tad_pmu.c
+++ b/drivers/perf/marvell_cn10k_tad_pmu.c
@@ -7,6 +7,7 @@
#define pr_fmt(fmt) "tad_pmu: " fmt
#include <linux/io.h>
+#include <linux/bits.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/cpuhotplug.h>
@@ -14,12 +15,20 @@
#include <linux/platform_device.h>
#include <linux/acpi.h>
-#define TAD_PFC_OFFSET 0x800
-#define TAD_PFC(counter) (TAD_PFC_OFFSET | (counter << 3))
#define TAD_PRF_OFFSET 0x900
-#define TAD_PRF(counter) (TAD_PRF_OFFSET | (counter << 3))
+#define TAD_PFC_OFFSET 0x800
+#define TAD_PFC(base, counter) ((base) | ((u64)(counter) << 3))
+#define TAD_PRF(base, counter) ((base) | ((u64)(counter) << 3))
#define TAD_PRF_CNTSEL_MASK 0xFF
+#define TAD_PRF_MATCH_PARTID BIT(8)
+#define TAD_PRF_PARTID_NS BIT(10)
+/*
+ * config1: bits 0..8 MPAM partition id (including 0); bit 9 requests
+ * filtering for MPAM-capable events. All-zero config1 means no filter.
+ */
+#define TAD_PARTID_FILTER_EN BIT(9)
#define TAD_MAX_COUNTERS 8
+#define TAD_EVENT_SEL_MASK GENMASK(7, 0)
#define to_tad_pmu(p) (container_of(p, struct tad_pmu, pmu))
@@ -27,30 +36,92 @@ struct tad_region {
void __iomem *base;
};
+enum mrvl_tad_pmu_version {
+ TAD_PMU_V1 = 1,
+ TAD_PMU_V2,
+};
+
+struct tad_pmu_data {
+ int id;
+ u64 tad_prf_offset;
+ u64 tad_pfc_offset;
+};
+
struct tad_pmu {
struct pmu pmu;
struct tad_region *regions;
u32 region_cnt;
unsigned int cpu;
+ const struct tad_pmu_ops *ops;
+ const struct tad_pmu_data *pdata;
struct hlist_node node;
struct perf_event *events[TAD_MAX_COUNTERS];
DECLARE_BITMAP(counters_map, TAD_MAX_COUNTERS);
};
-enum mrvl_tad_pmu_version {
- TAD_PMU_V1 = 1,
- TAD_PMU_V2,
-};
-
-struct tad_pmu_data {
- int id;
+struct tad_pmu_ops {
+ void (*start_counter)(struct tad_pmu *pmu, struct perf_event *event);
};
static int tad_pmu_cpuhp_state;
+static void tad_pmu_start_counter(struct tad_pmu *pmu,
+ struct perf_event *event)
+{
+ const struct tad_pmu_data *pdata = pmu->pdata;
+ struct hw_perf_event *hwc = &event->hw;
+ u32 event_idx = (u32)(event->attr.config & TAD_EVENT_SEL_MASK);
+ u32 counter_idx = hwc->idx;
+ u64 partid_filter = 0;
+ u64 reg_val;
+ u64 cfg1 = event->attr.config1;
+ bool use_mpam = cfg1 & TAD_PARTID_FILTER_EN;
+ u32 partid = (u32)(cfg1 & GENMASK(8, 0));
+ int i;
+
+ for (i = 0; i < pmu->region_cnt; i++)
+ writeq_relaxed(0, pmu->regions[i].base +
+ TAD_PFC(pdata->tad_pfc_offset, counter_idx));
+
+ if (use_mpam && event_idx > 0x19 && event_idx < 0x21) {
+ partid_filter = TAD_PRF_MATCH_PARTID | TAD_PRF_PARTID_NS |
+ ((u64)partid << 11);
+ }
+
+
+ for (i = 0; i < pmu->region_cnt; i++) {
+ reg_val = event_idx & 0xFF;
+ reg_val |= partid_filter;
+ writeq_relaxed(reg_val, pmu->regions[i].base +
+ TAD_PRF(pdata->tad_prf_offset, counter_idx));
+ }
+}
+
+static void tad_pmu_v2_start_counter(struct tad_pmu *pmu,
+ struct perf_event *event)
+{
+ const struct tad_pmu_data *pdata = pmu->pdata;
+ struct hw_perf_event *hwc = &event->hw;
+ u32 event_idx = (u32)(event->attr.config & TAD_EVENT_SEL_MASK);
+ u32 counter_idx = hwc->idx;
+ u64 reg_val;
+ int i;
+
+ for (i = 0; i < pmu->region_cnt; i++)
+ writeq_relaxed(0, pmu->regions[i].base +
+ TAD_PFC(pdata->tad_pfc_offset, counter_idx));
+
+ for (i = 0; i < pmu->region_cnt; i++) {
+ reg_val = event_idx & 0xFF;
+ writeq_relaxed(reg_val, pmu->regions[i].base +
+ TAD_PRF(pdata->tad_prf_offset, counter_idx));
+ }
+}
+
static void tad_pmu_event_counter_read(struct perf_event *event)
{
struct tad_pmu *tad_pmu = to_tad_pmu(event->pmu);
+ const struct tad_pmu_data *pdata = tad_pmu->pdata;
struct hw_perf_event *hwc = &event->hw;
u32 counter_idx = hwc->idx;
u64 prev, new;
@@ -60,7 +131,7 @@ static void tad_pmu_event_counter_read(struct perf_event *event)
prev = local64_read(&hwc->prev_count);
for (i = 0, new = 0; i < tad_pmu->region_cnt; i++)
new += readq(tad_pmu->regions[i].base +
- TAD_PFC(counter_idx));
+ TAD_PFC(pdata->tad_pfc_offset, counter_idx));
} while (local64_cmpxchg(&hwc->prev_count, prev, new) != prev);
local64_add(new - prev, &event->count);
@@ -69,16 +140,14 @@ static void tad_pmu_event_counter_read(struct perf_event *event)
static void tad_pmu_event_counter_stop(struct perf_event *event, int flags)
{
struct tad_pmu *tad_pmu = to_tad_pmu(event->pmu);
+ const struct tad_pmu_data *pdata = tad_pmu->pdata;
struct hw_perf_event *hwc = &event->hw;
u32 counter_idx = hwc->idx;
int i;
- /* TAD()_PFC() stop counting on the write
- * which sets TAD()_PRF()[CNTSEL] == 0
- */
for (i = 0; i < tad_pmu->region_cnt; i++) {
writeq_relaxed(0, tad_pmu->regions[i].base +
- TAD_PRF(counter_idx));
+ TAD_PRF(pdata->tad_prf_offset, counter_idx));
}
tad_pmu_event_counter_read(event);
@@ -89,26 +158,10 @@ static void tad_pmu_event_counter_start(struct perf_event *event, int flags)
{
struct tad_pmu *tad_pmu = to_tad_pmu(event->pmu);
struct hw_perf_event *hwc = &event->hw;
- u32 event_idx = event->attr.config;
- u32 counter_idx = hwc->idx;
- u64 reg_val;
- int i;
hwc->state = 0;
- /* Typically TAD_PFC() are zeroed to start counting */
- for (i = 0; i < tad_pmu->region_cnt; i++)
- writeq_relaxed(0, tad_pmu->regions[i].base +
- TAD_PFC(counter_idx));
-
- /* TAD()_PFC() start counting on the write
- * which sets TAD()_PRF()[CNTSEL] != 0
- */
- for (i = 0; i < tad_pmu->region_cnt; i++) {
- reg_val = event_idx & 0xFF;
- writeq_relaxed(reg_val, tad_pmu->regions[i].base +
- TAD_PRF(counter_idx));
- }
+ tad_pmu->ops->start_counter(tad_pmu, event);
}
static void tad_pmu_event_counter_del(struct perf_event *event, int flags)
@@ -128,7 +181,6 @@ static int tad_pmu_event_counter_add(struct perf_event *event, int flags)
struct hw_perf_event *hwc = &event->hw;
int idx;
- /* Get a free counter for this event */
idx = find_first_zero_bit(tad_pmu->counters_map, TAD_MAX_COUNTERS);
if (idx == TAD_MAX_COUNTERS)
return -EAGAIN;
@@ -148,6 +200,9 @@ static int tad_pmu_event_counter_add(struct perf_event *event, int flags)
static int tad_pmu_event_init(struct perf_event *event)
{
struct tad_pmu *tad_pmu = to_tad_pmu(event->pmu);
+ const struct tad_pmu_data *pdata = tad_pmu->pdata;
+ u32 event_idx = (u32)(event->attr.config & TAD_EVENT_SEL_MASK);
+ u64 cfg1 = event->attr.config1;
if (event->attr.type != event->pmu->type)
return -ENOENT;
@@ -158,6 +213,23 @@ static int tad_pmu_event_init(struct perf_event *event)
if (event->state != PERF_EVENT_STATE_OFF)
return -EINVAL;
+ if (event->attr.config & ~TAD_EVENT_SEL_MASK)
+ return -EINVAL;
+
+ if (pdata->id == TAD_PMU_V2) {
+ if (cfg1)
+ return -EINVAL;
+ } else {
+ if ((cfg1 & GENMASK(8, 0)) && !(cfg1 & TAD_PARTID_FILTER_EN))
+ return -EINVAL;
+ if (cfg1 & TAD_PARTID_FILTER_EN) {
+ if (event_idx <= 0x19 || event_idx >= 0x21)
+ return -EINVAL;
+ }
+ if (cfg1 & ~GENMASK(9, 0))
+ return -EINVAL;
+ }
+
event->cpu = tad_pmu->cpu;
event->hw.idx = -1;
event->hw.config_base = event->attr.config;
@@ -232,7 +304,7 @@ static struct attribute *ody_tad_pmu_event_attrs[] = {
TAD_PMU_EVENT_ATTR(tad_hit_ltg, 0x1e),
TAD_PMU_EVENT_ATTR(tad_hit_any, 0x1f),
TAD_PMU_EVENT_ATTR(tad_tag_rd, 0x20),
- TAD_PMU_EVENT_ATTR(tad_tot_cycle, 0xFF),
+ TAD_PMU_EVENT_ATTR(tad_tot_cycle, 0xff),
NULL
};
@@ -242,9 +314,13 @@ static const struct attribute_group ody_tad_pmu_events_attr_group = {
};
PMU_FORMAT_ATTR(event, "config:0-7");
+PMU_FORMAT_ATTR(partid, "config1:0-8");
+PMU_FORMAT_ATTR(partid_en, "config1:9-9");
static struct attribute *tad_pmu_format_attrs[] = {
&format_attr_event.attr,
+ &format_attr_partid.attr,
+ &format_attr_partid_en.attr,
NULL
};
@@ -253,6 +329,16 @@ static struct attribute_group tad_pmu_format_attr_group = {
.attrs = tad_pmu_format_attrs,
};
+static struct attribute *ody_tad_pmu_format_attrs[] = {
+ &format_attr_event.attr,
+ NULL
+};
+
+static struct attribute_group ody_tad_pmu_format_attr_group = {
+ .name = "format",
+ .attrs = ody_tad_pmu_format_attrs,
+};
+
static ssize_t tad_pmu_cpumask_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
@@ -281,16 +367,25 @@ static const struct attribute_group *tad_pmu_attr_groups[] = {
static const struct attribute_group *ody_tad_pmu_attr_groups[] = {
&ody_tad_pmu_events_attr_group,
- &tad_pmu_format_attr_group,
+ &ody_tad_pmu_format_attr_group,
&tad_pmu_cpumask_attr_group,
NULL
};
+static const struct tad_pmu_ops tad_pmu_ops = {
+ .start_counter = tad_pmu_start_counter,
+};
+
+static const struct tad_pmu_ops tad_pmu_v2_ops = {
+ .start_counter = tad_pmu_v2_start_counter,
+};
+
static int tad_pmu_probe(struct platform_device *pdev)
{
const struct tad_pmu_data *dev_data;
struct device *dev = &pdev->dev;
struct tad_region *regions;
+ resource_size_t map_start;
struct tad_pmu *tad_pmu;
struct resource *res;
u32 tad_pmu_page_size;
@@ -298,7 +393,6 @@ static int tad_pmu_probe(struct platform_device *pdev)
u32 tad_cnt;
int version;
int i, ret;
- char *name;
tad_pmu = devm_kzalloc(&pdev->dev, sizeof(*tad_pmu), GFP_KERNEL);
if (!tad_pmu)
@@ -312,6 +406,7 @@ static int tad_pmu_probe(struct platform_device *pdev)
return -ENODEV;
}
version = dev_data->id;
+ tad_pmu->pdata = dev_data;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!res) {
@@ -338,22 +433,31 @@ static int tad_pmu_probe(struct platform_device *pdev)
dev_err(&pdev->dev, "Can't find tad-cnt property\n");
return ret;
}
+ if (!tad_cnt || !tad_page_size || !tad_pmu_page_size) {
+ dev_err(&pdev->dev, "Invalid tad-cnt or page size\n");
+ return -EINVAL;
+ }
regions = devm_kcalloc(&pdev->dev, tad_cnt,
sizeof(*regions), GFP_KERNEL);
if (!regions)
return -ENOMEM;
- /* ioremap the distributed TAD pmu regions */
- for (i = 0; i < tad_cnt && res->start < res->end; i++) {
- regions[i].base = devm_ioremap(&pdev->dev,
- res->start,
+ map_start = res->start;
+ for (i = 0; i < tad_cnt; i++) {
+ if (map_start > res->end ||
+ tad_pmu_page_size > (resource_size_t)(res->end - map_start + 1)) {
+ dev_err(&pdev->dev, "TAD PMU mem window too small for tad-cnt=%u\n",
+ tad_cnt);
+ return -EINVAL;
+ }
+ regions[i].base = devm_ioremap(&pdev->dev, map_start,
tad_pmu_page_size);
if (!regions[i].base) {
dev_err(&pdev->dev, "TAD%d ioremap fail\n", i);
return -ENOMEM;
}
- res->start += tad_page_size;
+ map_start += tad_page_size;
}
tad_pmu->regions = regions;
@@ -374,28 +478,31 @@ static int tad_pmu_probe(struct platform_device *pdev)
.read = tad_pmu_event_counter_read,
};
- if (version == TAD_PMU_V1)
+ if (version == TAD_PMU_V1) {
tad_pmu->pmu.attr_groups = tad_pmu_attr_groups;
- else
+ tad_pmu->ops = &tad_pmu_ops;
+ } else {
tad_pmu->pmu.attr_groups = ody_tad_pmu_attr_groups;
+ tad_pmu->ops = &tad_pmu_v2_ops;
+ }
tad_pmu->cpu = raw_smp_processor_id();
- /* Register pmu instance for cpu hotplug */
+ ret = perf_pmu_register(&tad_pmu->pmu, "tad", -1);
+ if (ret) {
+ dev_err(&pdev->dev, "Error %d registering perf PMU\n", ret);
+ return ret;
+ }
+
ret = cpuhp_state_add_instance_nocalls(tad_pmu_cpuhp_state,
&tad_pmu->node);
if (ret) {
dev_err(&pdev->dev, "Error %d registering hotplug\n", ret);
+ perf_pmu_unregister(&tad_pmu->pmu);
return ret;
}
- name = "tad";
- ret = perf_pmu_register(&tad_pmu->pmu, name, -1);
- if (ret)
- cpuhp_state_remove_instance_nocalls(tad_pmu_cpuhp_state,
- &tad_pmu->node);
-
- return ret;
+ return 0;
}
static void tad_pmu_remove(struct platform_device *pdev)
@@ -410,12 +517,17 @@ static void tad_pmu_remove(struct platform_device *pdev)
#if defined(CONFIG_OF) || defined(CONFIG_ACPI)
static const struct tad_pmu_data tad_pmu_data = {
.id = TAD_PMU_V1,
+ .tad_prf_offset = TAD_PRF_OFFSET,
+ .tad_pfc_offset = TAD_PFC_OFFSET,
};
+
#endif
#ifdef CONFIG_ACPI
static const struct tad_pmu_data tad_pmu_v2_data = {
.id = TAD_PMU_V2,
+ .tad_prf_offset = TAD_PRF_OFFSET,
+ .tad_pfc_offset = TAD_PFC_OFFSET,
};
#endif
@@ -491,6 +603,6 @@ static void __exit tad_pmu_exit(void)
module_init(tad_pmu_init);
module_exit(tad_pmu_exit);
-MODULE_DESCRIPTION("Marvell CN10K LLC-TAD Perf driver");
+MODULE_DESCRIPTION("Marvell CN10K LLC-TAD perf driver");
MODULE_AUTHOR("Bhaskara Budiredla <bbudiredla@marvell.com>");
MODULE_LICENSE("GPL v2");
--
2.25.1
^ permalink raw reply related
* Patch "arm64/mm: Enable batched TLB flush in unmap_hotplug_range()" has been added to the 5.10-stable tree
From: gregkh @ 2026-06-16 7:10 UTC (permalink / raw)
To: anshuman.khandual, catalin.marinas, david, gregkh,
linux-arm-kernel, ryan.roberts, sashal, will
Cc: stable-commits
In-Reply-To: <20260428200548.3191346-1-sashal@kernel.org>
This is a note to let you know that I've just added the patch titled
arm64/mm: Enable batched TLB flush in unmap_hotplug_range()
to the 5.10-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary
The filename of the patch is:
arm64-mm-enable-batched-tlb-flush-in-unmap_hotplug_range.patch
and it can be found in the queue-5.10 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree,
please let <stable@vger.kernel.org> know about it.
From stable+bounces-241768-greg=kroah.com@vger.kernel.org Wed Apr 29 01:35:55 2026
From: Sasha Levin <sashal@kernel.org>
Date: Tue, 28 Apr 2026 16:05:48 -0400
Subject: arm64/mm: Enable batched TLB flush in unmap_hotplug_range()
To: stable@vger.kernel.org
Cc: Anshuman Khandual <anshuman.khandual@arm.com>, Will Deacon <will@kernel.org>, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, "David Hildenbrand (Arm)" <david@kernel.org>, Ryan Roberts <ryan.roberts@arm.com>, Catalin Marinas <catalin.marinas@arm.com>, Sasha Levin <sashal@kernel.org>
Message-ID: <20260428200548.3191346-1-sashal@kernel.org>
From: Anshuman Khandual <anshuman.khandual@arm.com>
[ Upstream commit 48478b9f791376b4b89018d7afdfd06865498f65 ]
During a memory hot remove operation, both linear and vmemmap mappings for
the memory range being removed, get unmapped via unmap_hotplug_range() but
mapped pages get freed only for vmemmap mapping. This is just a sequential
operation where each table entry gets cleared, followed by a leaf specific
TLB flush, and then followed by memory free operation when applicable.
This approach was simple and uniform both for vmemmap and linear mappings.
But linear mapping might contain CONT marked block memory where it becomes
necessary to first clear out all entire in the range before a TLB flush.
This is as per the architecture requirement. Hence batch all TLB flushes
during the table tear down walk and finally do it in unmap_hotplug_range().
Prior to this fix, it was hypothetically possible for a speculative access
to a higher address in the contiguous block to fill the TLB with shattered
entries for the entire contiguous range after a lower address had already
been cleared and invalidated. Due to the table entries being shattered, the
subsequent TLB invalidation for the higher address would not then clear the
TLB entries for the lower address, meaning stale TLB entries could persist.
Besides it also helps in improving the performance via TLBI range operation
along with reduced synchronization instructions. The time spent executing
unmap_hotplug_range() improved 97% measured over a 2GB memory hot removal
in KVM guest.
This scheme is not applicable during vmemmap mapping tear down where memory
needs to be freed and hence a TLB flush is required after clearing out page
table entry.
Cc: Will Deacon <will@kernel.org>
Cc: linux-arm-kernel@lists.infradead.org
Cc: linux-kernel@vger.kernel.org
Closes: https://lore.kernel.org/all/aWZYXhrT6D2M-7-N@willie-the-truck/
Fixes: bbd6ec605c0f ("arm64/mm: Enable memory hot remove")
Cc: stable@vger.kernel.org
Reviewed-by: David Hildenbrand (Arm) <david@kernel.org>
Reviewed-by: Ryan Roberts <ryan.roberts@arm.com>
Signed-off-by: Ryan Roberts <ryan.roberts@arm.com>
Signed-off-by: Anshuman Khandual <anshuman.khandual@arm.com>
Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
[ renamed `__pte_clear()` to `pte_clear()` and inlined `pmd_cont(pmd)` as `pmd_val(pmd) & PMD_SECT_CONT` ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
arch/arm64/mm/mmu.c | 36 ++++++++++++++++++++----------------
1 file changed, 20 insertions(+), 16 deletions(-)
--- a/arch/arm64/mm/mmu.c
+++ b/arch/arm64/mm/mmu.c
@@ -862,10 +862,14 @@ static void unmap_hotplug_pte_range(pmd_
WARN_ON(!pte_present(pte));
pte_clear(&init_mm, addr, ptep);
- flush_tlb_kernel_range(addr, addr + PAGE_SIZE);
- if (free_mapped)
+ if (free_mapped) {
+ /* CONT blocks are not supported in the vmemmap */
+ WARN_ON(pte_cont(pte));
+ flush_tlb_kernel_range(addr, addr + PAGE_SIZE);
free_hotplug_page_range(pte_page(pte),
PAGE_SIZE, altmap);
+ }
+ /* unmap_hotplug_range() flushes TLB for !free_mapped */
} while (addr += PAGE_SIZE, addr < end);
}
@@ -886,15 +890,14 @@ static void unmap_hotplug_pmd_range(pud_
WARN_ON(!pmd_present(pmd));
if (pmd_sect(pmd)) {
pmd_clear(pmdp);
-
- /*
- * One TLBI should be sufficient here as the PMD_SIZE
- * range is mapped with a single block entry.
- */
- flush_tlb_kernel_range(addr, addr + PAGE_SIZE);
- if (free_mapped)
+ if (free_mapped) {
+ /* CONT blocks are not supported in the vmemmap */
+ WARN_ON(pmd_val(pmd) & PMD_SECT_CONT);
+ flush_tlb_kernel_range(addr, addr + PMD_SIZE);
free_hotplug_page_range(pmd_page(pmd),
PMD_SIZE, altmap);
+ }
+ /* unmap_hotplug_range() flushes TLB for !free_mapped */
continue;
}
WARN_ON(!pmd_table(pmd));
@@ -919,15 +922,12 @@ static void unmap_hotplug_pud_range(p4d_
WARN_ON(!pud_present(pud));
if (pud_sect(pud)) {
pud_clear(pudp);
-
- /*
- * One TLBI should be sufficient here as the PUD_SIZE
- * range is mapped with a single block entry.
- */
- flush_tlb_kernel_range(addr, addr + PAGE_SIZE);
- if (free_mapped)
+ if (free_mapped) {
+ flush_tlb_kernel_range(addr, addr + PUD_SIZE);
free_hotplug_page_range(pud_page(pud),
PUD_SIZE, altmap);
+ }
+ /* unmap_hotplug_range() flushes TLB for !free_mapped */
continue;
}
WARN_ON(!pud_table(pud));
@@ -957,6 +957,7 @@ static void unmap_hotplug_p4d_range(pgd_
static void unmap_hotplug_range(unsigned long addr, unsigned long end,
bool free_mapped, struct vmem_altmap *altmap)
{
+ unsigned long start = addr;
unsigned long next;
pgd_t *pgdp, pgd;
@@ -978,6 +979,9 @@ static void unmap_hotplug_range(unsigned
WARN_ON(!pgd_present(pgd));
unmap_hotplug_p4d_range(pgdp, addr, next, free_mapped, altmap);
} while (addr = next, addr < end);
+
+ if (!free_mapped)
+ flush_tlb_kernel_range(start, end);
}
static void free_empty_pte_table(pmd_t *pmdp, unsigned long addr,
Patches currently in stable-queue which might be from sashal@kernel.org are
queue-5.10/team-move-team-device-type-change-at-the-end-of-team.patch
queue-5.10/netfilter-nft_fib-fix-stale-stack-leak-via-the-oifname-register.patch
queue-5.10/asoc-intel-bytcht_es8316-fix-mclk-leak-on-init-error.patch
queue-5.10/spi-sun4i-fix-controller-deregistration.patch
queue-5.10/bluetooth-l2cap-fix-possible-crash-on-l2cap_ecred_co.patch
queue-5.10/ice-fix-vf-queue-configuration-with-low-mtu-values.patch
queue-5.10/ipv6-sit-reload-inner-ipv6-header-after-gso-offloads.patch
queue-5.10/ktest-fixing-indentation-to-match-expected-pattern.patch
queue-5.10/6lowpan-fix-off-by-one-in-multicast-context-address-.patch
queue-5.10/spi-meson-spicc-fix-double-put-in-remove-path.patch
queue-5.10/sctp-fix-race-between-sctp_wait_for_connect-and-peel.patch
queue-5.10/pcnet32-stop-holding-device-spin-lock-during-napi_co.patch
queue-5.10/mptcp-do-not-drop-partial-packets.patch
queue-5.10/bluetooth-hci_core-fix-use-after-free-in-vhci_flush.patch
queue-5.10/serial-qcom-geni-fix-uart_rx_par_en-bit-position.patch
queue-5.10/arm64-tlb-optimize-arm64_workaround_repeat_tlbi.patch
queue-5.10/nfc-llcp-fix-use-after-free-race-in-nfc_llcp_recv_cc.patch
queue-5.10/octeontx2-pf-avoid-double-free-of-pool-stack-on-aq-init-failure.patch
queue-5.10/net-hsr-defer-node-table-free-until-after-rcu-readers.patch
queue-5.10/f2fs-fix-incorrect-file-address-mapping-when-inline-inode-is-unwritten.patch
queue-5.10/phy-tegra-xusb-fix-per-pad-high-speed-termination-calibration.patch
queue-5.10/net-netlink-fix-sending-unassigned-nsid-after-assign.patch
queue-5.10/net-qrtr-ns-free-the-node-during-ctrl_cmd_bye.patch
queue-5.10/dm-cache-policy-smq-check-allocation-under-invalidat.patch
queue-5.10/rdma-rxe-fix-double-free-in-rxe_srq_from_init.patch-26331
queue-5.10/spi-ti-qspi-fix-controller-deregistration.patch
queue-5.10/ipv6-rpl-fix-hdrlen-overflow-in-ipv6_rpl_srh_decompr.patch
queue-5.10/smb-client-use-fullsessionkey-for-aes-256-encryption-key-derivation.patch
queue-5.10/ieee802154-6lowpan-only-accept-ipv6-packets-in-lowpa.patch
queue-5.10/tun-free-page-on-short-frame-rejection-in-tun_xdp_on.patch
queue-5.10/usb-serial-mct_u232-fix-memory-corruption-with-small.patch
queue-5.10/ext4-validate-p_idx-bounds-in-ext4_ext_correct_index.patch
queue-5.10/spi-topcliff-pch-fix-controller-deregistration.patch
queue-5.10/spi-uniphier-fix-controller-deregistration.patch
queue-5.10/mtd-spi-nor-sst-fix-write-enable-before-aai-sequence.patch
queue-5.10/signal-clear-jobctl_pending_mask-for-caller-in-zap_o.patch
queue-5.10/spi-syncuacer-fix-controller-deregistration.patch
queue-5.10/alsa-aoa-i2sbus-clear-stale-prepared-state.patch
queue-5.10/sched-use-u64-for-bandwidth-ratio-calculations.patch
queue-5.10/spi-tegra20-sflash-fix-controller-deregistration.patch
queue-5.10/usb-typec-ucsi-check-if-power-role-change-actually-happened-before-handling.patch
queue-5.10/rdma-umem-fix-kernel-doc-warnings.patch
queue-5.10/revert-rdma-rxe-fix-double-free-in-rxe_srq_from_init.patch
queue-5.10/octeontx2-af-add-validation-for-lmac-type.patch
queue-5.10/can-ucan-fix-devres-lifetime.patch
queue-5.10/net-qrtr-fix-refcount-saturation-and-potential-uaf-i.patch
queue-5.10/spi-qup-switch-to-use-modern-name.patch
queue-5.10/media-rc-igorplugusb-heed-coherency-rules.patch
queue-5.10/bpf-free-reuseport-cbpf-prog-after-rcu-grace-period.patch
queue-5.10/net-qrtr-ns-change-servers-radix-tree-to-xarray.patch
queue-5.10/qed-fix-double-free-in-qed_cxt_tables_alloc.patch
queue-5.10/usb-typec-ucsi-don-t-update-power_supply-on-power-role-change-if-not-connected.patch
queue-5.10/media-rc-ttusbir-respect-dma-coherency-rules.patch
queue-5.10/wifi-mac80211-check-tdls-flag-in-ieee80211_tdls_oper.patch
queue-5.10/batman-adv-tt-fix-toctou-race-for-reported-vlans.patch
queue-5.10/tty-serial-qcom-geni-serial-remove-unused-symbols.patch
queue-5.10/tty-serial-qcom-geni-serial-align-define-values.patch
queue-5.10/bluetooth-fix-uaf-in-l2cap_sock_cleanup_listen-vs-l2cap_conn_del.patch
queue-5.10/time-fix-off-by-one-in-settimeofday-usec-validation.patch
queue-5.10/usb-serial-cypress_m8-fix-memory-corruption-with-sma.patch
queue-5.10/xfrm-policy-fix-use-after-free-on-inexact-bin-in-xfr.patch
queue-5.10/netlabel-validate-unlabeled-address-and-mask-attribu.patch
queue-5.10/can-ucan-fix-typos-in-comments.patch
queue-5.10/batman-adv-tp_meter-fix-race-condition-in-send-error.patch
queue-5.10/batman-adv-tt-avoid-empty-vlan-responses.patch
queue-5.10/net-qrtr-ns-limit-the-total-number-of-nodes.patch
queue-5.10/spi-zynq-qspi-fix-controller-deregistration.patch
queue-5.10/serial-altera_jtaguart-handle-uart_add_one_port-failures.patch
queue-5.10/thunderbolt-property-cap-recursion-depth-in-__tb_property_parse_dir.patch
queue-5.10/serial-dz-fix-bootconsole-handover-lockup.patch
queue-5.10/net-sched-revert-net-sched-restrict-conditions-for-a.patch
queue-5.10/octeontx2-af-cgx-add-bounds-check-to-cgx_speed_mbps-index.patch
queue-5.10/btrfs-fix-missing-last_unlink_trans-update-when-removing-a-directory.patch
queue-5.10/vxlan-do-not-reuse-cached-ip_hdr-value-after-skb_tun.patch
queue-5.10/udf-fix-partition-descriptor-append-bookkeeping.patch
queue-5.10/net-guard-timestamp-cmsgs-to-real-error-queue-skbs.patch
queue-5.10/batman-adv-tvlv-reject-oversized-tvlv-packets.patch
queue-5.10/xfrm-check-for-underflow-in-xfrm_state_mtu.patch
queue-5.10/rdma-umem-fix-truncation-for-block-sizes-4g.patch
queue-5.10/net-garp-fix-unsigned-integer-underflow-in-garp_pdu_.patch
queue-5.10/alsa-aloop-fix-peer-runtime-uaf-during-format-change-stop.patch
queue-5.10/hid-core-fix-size_t-specifier-in-hid_report_raw_even.patch
queue-5.10/rds-mark-snapshot-pages-dirty-in-rds_info_getsockopt.patch
queue-5.10/bluetooth-init-sk_peer_-on-bt_sock_alloc.patch
queue-5.10/serial-altera_jtaguart-use-platform_get_irq_optional-to-get-the-interrupt.patch
queue-5.10/net-sched-act_api-use-rcu-with-deferred-freeing-for-.patch
queue-5.10/bluetooth-6lowpan-check-skb_clone-return-value-in-se.patch
queue-5.10/batman-adv-v-stop-ogmv2-on-disabled-interface.patch
queue-5.10/nfc-llcp-protect-nfc_llcp_sock_unlink-calls.patch
queue-5.10/net-openvswitch-fix-possible-kfree_skb-of-err_ptr.patch
queue-5.10/smb-client-fix-smbdirect_recv_io-leak-in-smbd_negoti.patch
queue-5.10/arm64-tlb-flush-walk-cache-when-unsharing-pmd-tables.patch
queue-5.10/mptcp-pm-add_addr-rtx-fix-potential-data-race.patch
queue-5.10/spi-st-ssc4-fix-controller-deregistration.patch
queue-5.10/net-packet-fix-toctou-race-on-mmap-d-vnet_hdr-in-tpacket_snd.patch
queue-5.10/netfilter-nf_queue-hold-bridge-skb-dev-while-queued.patch
queue-5.10/drm-nouveau-fix-u32-overflow-in-pushbuf-reloc-bounds-check.patch
queue-5.10/ip6_vti-fix-incorrect-tunnel-matching-in-vti6_tnl_lo.patch
queue-5.10/btrfs-fix-btrfs_ioctl_space_info-slot_count-toctou-which-can-lead-to-info-leak.patch
queue-5.10/io_uring-prevent-opcode-speculation.patch
queue-5.10/wifi-brcmfmac-fix-potential-use-after-free-issue-when-stopping-watchdog-task.patch
queue-5.10/hid-pass-the-buffer-size-to-hid_report_raw_event.patch
queue-5.10/alsa-aoa-skip-devices-with-no-codecs-in-i2sbus_resume.patch
queue-5.10/printk-add-print_hex_dump_devel.patch
queue-5.10/dm-thin-fix-metadata-refcount-underflow.patch
queue-5.10/batman-adv-bla-avoid-null-ptr-deref-for-claim-via-dr.patch
queue-5.10/tracing-probes-limit-size-of-event-probe-to-3k.patch
queue-5.10/usb-serial-digi_acceleport-fix-memory-corruption-wit.patch
queue-5.10/mm-hugetlb_cma-round-up-per_node-before-logging-it.patch
queue-5.10/bluetooth-rfcomm-hold-listener-socket-in-rfcomm_conn.patch
queue-5.10/wifi-mwifiex-fix-use-after-free-in-mwifiex_adapter_cleanup.patch
queue-5.10/tracepoint-balance-regfunc-on-func_add-failure-in-tracepoint_add_func.patch
queue-5.10/batman-adv-iv-recover-ogm-scheduling-after-forward-p.patch
queue-5.10/net-sched-cls_fw-fix-null-dereference-of-old-filters.patch
queue-5.10/compiler-clang.h-add-__diag-infrastructure-for-clang.patch
queue-5.10/spi-qup-fix-error-pointer-deref-after-dma-setup-failure.patch
queue-5.10/net-netlink-don-t-set-nsid-on-local-notifications.patch
queue-5.10/smb-client-fix-oob-read-in-smb2_ioctl_query_info-query_info-path.patch
queue-5.10/alsa-core-fix-potential-data-race-at-fasync-handling.patch
queue-5.10/net-smc-do-not-re-initialize-smc-hashtables.patch
queue-5.10/batman-adv-tp_meter-avoid-role-confusion-in-tp_list.patch
queue-5.10/ipvs-clear-the-svc-scheduler-ptr-early-on-edit.patch
queue-5.10/bluetooth-l2cap-clear-chan-ident-on-ecred-reconfigur.patch
queue-5.10/tunnels-do-not-assume-transport-header-in-iptunnel_p.patch
queue-5.10/selftests-mptcp-drop-nanoseconds-width-specifier.patch
queue-5.10/net-802-mrp-fix-vector-attribute-parsing-in-mrp_pdu_.patch
queue-5.10/batman-adv-bla-avoid-double-decrement-of-bla.num_req.patch
queue-5.10/hfsplus-fix-uninit-value-by-validating-catalog-record-size.patch
queue-5.10/batman-adv-tvlv-abort-ogm-send-on-tvlv-append-failur.patch
queue-5.10/alsa-pcm-fix-wait-queue-list-corruption-in-snd_pcm_d.patch
queue-5.10/rdma-move-dma-block-iterator-logic-into-dedicated-files.patch
queue-5.10/dm-btree-improve-btree-residency.patch
queue-5.10/page_pool-fix-use-after-free-in-page_pool_recycle_in.patch
queue-5.10/fbcon-avoid-oob-font-access-if-console-rotation-fails.patch
queue-5.10/tun-free-page-on-build_skb-failure-in-tun_xdp_one.patch
queue-5.10/qed-use-the-bitmap-api-to-simplify-some-functions.patch
queue-5.10/hid-core-add-printk_ratelimited-variants-to-hid_warn.patch
queue-5.10/bluetooth-mgmt-validate-advertising-tlv-before-type-.patch
queue-5.10/usb-dwc3-move-guid-programming-after-phy-initialization.patch
queue-5.10/netfilter-synproxy-add-mutex-to-guard-hook-reference.patch
queue-5.10/net-remove-redundant-if-statements.patch
queue-5.10/tee-optee-prevent-use-after-free-when-the-client-exi.patch
queue-5.10/hv_netvsc-use-kmap_local_page-in-netvsc_copy_to_send_buf.patch
queue-5.10/disable-wattribute-alias-for-clang-23-and-newer.patch
queue-5.10/net-qrtr-ns-limit-the-maximum-number-of-lookups.patch
queue-5.10/net-sched-sch_sfb-replace-direct-dequeue-call-with-p.patch
queue-5.10/netfilter-x_tables-avoid-leaking-percpu-counter-poin.patch
queue-5.10/tunnels-load-network-headers-after-skb_cow-in-iptunn.patch
queue-5.10/netfilter-synproxy-refresh-tcphdr-after-skb_ensure_w.patch
queue-5.10/arm64-mm-enable-batched-tlb-flush-in-unmap_hotplug_range.patch
queue-5.10/alsa-aoa-use-guard-for-mutex-locks.patch
queue-5.10/bluetooth-hci_event-fix-potential-uaf-in-ssp-passkey-handlers.patch
queue-5.10/bluetooth-consolidate-code-around-sk_alloc-into-a-helper-function.patch
queue-5.10/kvm-arm64-remove-vpipt-i-cache-handling.patch
queue-5.10/xhci-tegra-fix-ghost-usb-device-on-dual-role-port-un.patch
queue-5.10/netfilter-nft_exthdr-fix-register-tracking-for-f_pre.patch
queue-5.10/net-iucv-fix-locking-in-.getsockopt.patch
queue-5.10/sctp-purge-outqueue-on-stale-cookie-echo-handling.patch
queue-5.10/ipv4-restrict-ipopt_ssrr-and-ipopt_lsrr-options.patch
queue-5.10/netfilter-xt_cpu-prefer-raw_smp_processor_id.patch
queue-5.10/bluetooth-hci_qca-convert-timeout-from-jiffies-to-ms.patch
queue-5.10/spi-lantiq-ssc-fix-controller-deregistration.patch
queue-5.10/erofs-fix-the-out-of-bounds-nameoff-handling-for-trailing-dirents.patch
queue-5.10/smb-client-require-a-full-nfs-mode-sid-before-reading-mode-bits.patch
queue-5.10/phy-renesas-rcar-gen3-usb2-fix-the-use-of-msleep-dur.patch
queue-5.10/bonding-limit-bond_mode_8023ad-to-ethernet-devices.patch
queue-5.10/scsi-target-iscsi-bound-iscsi_encode_text_output-appends-to-rsp_buf.patch
queue-5.10/spi-sun6i-fix-controller-deregistration.patch
queue-5.10/netfilter-ebtables-fix-oob-read-in-compat_mtw_from_u.patch
queue-5.10/phy-tegra-xusb-disable-trk-clk-when-not-in-use.patch
queue-5.10/ceph-only-d_add-negative-dentries-when-they-are-unhashed.patch
queue-5.10/octeontx2-af-replace-deprecated-strncpy-with-strscpy.patch
queue-5.10/tap-free-page-on-error-paths-in-tap_get_user_xdp.patch
queue-5.10/nfc-nxp-nci-i2c-use-rising-edge-irq-on-acpi-systems.patch
queue-5.10/ktest-fix-the-month-in-the-name-of-the-failure-directory.patch
queue-5.10/pmdomain-core-fix-detach-procedure-for-virtual-devices-in-genpd.patch
queue-5.10/scsi-target-iscsi-fix-crc-overread-and-double-free-in-iscsit_handle_text_cmd.patch
queue-5.10/mm-huge_memory-update-file-pmd-counter-before-folio_put.patch
queue-5.10/net-bridge-use-a-stable-fdb-dst-snapshot-in-rcu-readers.patch
queue-5.10/f2fs-fix-uaf-caused-by-decrementing-sbi-nr_pages-in-f2fs_write_end_io.patch
queue-5.10/thermal-core-fix-thermal-zone-governor-cleanup-issues.patch
queue-5.10/net-lan743x-permit-vlan-tagged-packets-up-to-configu.patch
queue-5.10/drm-imx-fix-three-kernel-doc-warnings-in-dcss-scaler.patch
queue-5.10/usbnet-fix-using-smp_processor_id-in-preemptible-cod.patch
queue-5.10/spi-tegra114-fix-controller-deregistration.patch
queue-5.10/bluetooth-serialize-accept_q-access.patch
queue-5.10/crypto-caam-guard-hmac-key-hex-dumps-in-hash_digest_key.patch
queue-5.10/netfilter-bridge-make-ebt_snat-arp-rewrite-writable.patch
queue-5.10/acpi-scan-use-acpi_dev_put-in-object-add-error-paths.patch
queue-5.10/nfc-llcp-fix-use-after-free-in-llcp_sock_release.patch
queue-5.10/selftests-forwarding-lib-add-helpers-for-checksum-ha.patch
queue-5.10/alsa-usb-audio-fix-null-pointer-dereference-on-point.patch
queue-5.10/hfsplus-fix-held-lock-freed-on-hfsplus_fill_super.patch
queue-5.10/netfilter-conntrack_irc-fix-possible-out-of-bounds-r.patch
queue-5.10/netfilter-xt_nfqueue-prefer-raw_smp_processor_id.patch
queue-5.10/use-less-confusing-names-for-iov_iter-direction-initializers.patch
queue-5.10/net-rds-fix-null-deref-in-rds_ib_send_cqe_handler-on.patch
queue-5.10/sctp-fix-uninit-value-in-__sctp_rcv_asconf_lookup.patch
queue-5.10/ipv4-free-net-ipv4.sysctl_local_reserved_ports-after.patch
queue-5.10/net-mvpp2-sync-rx-data-at-the-hardware-packet-offset.patch
queue-5.10/arm64-tlb-allow-xzr-argument-to-tlbi-ops.patch
queue-5.10/nfsd-don-t-ignore-the-return-code-of-svc_proc_regist.patch
^ permalink raw reply
* [PATCH v3 2/3] perf: marvell: Add CN20K LLC-TAD PMU support
From: Geetha sowjanya @ 2026-06-16 7:11 UTC (permalink / raw)
To: linux-perf-users, linux-kernel, linux-arm-kernel, devicetree
Cc: mark.rutland, will, krzk+dt, gakula
In-Reply-To: <20260616071149.12523-1-gakula@marvell.com>
Add support for the LLC Tag-and-Data (TAD) PMU present in
Marvell CN20K SoCs.
The CN20K TAD PMU is based on the CN10K design but differs in the
layout of PFC/PRF register offsets relative to each TAD base, and
introduces additional events. These offsets are selected by the driver
based on the compatible string and are not described via DT properties.
Because of this, "marvell,cn10k-tad-pmu" cannot be used as a fallback
for CN20K, as it would result in incorrect register programming.
Add support for "marvell,cn20k-tad-pmu" by:
- Introducing a TAD_PMU_V3 profile with CN20K-specific register bases
- Extending the event map for new CN20K events
- Matching the PMU via OF and ACPI (MRVL000F)
Signed-off-by: Geetha sowjanya <gakula@marvell.com>
---
Changelog (since v2)
--------------------
- Validate the eventId using an appropriate mask to ensure
it is restricted to 8 bits.
Changelog (since v1)
--------------------
- Hide V3-only events on CN10K via sysfs is_visible and reject them in
event_init.
- Use CN20K-specific MPAM PRF bits (MATCH_MPAMNS, partid << 10) for V3;
software partid is limited to nine bits so this does not collide with
the fixed bit at 25.
- Reset hwc->prev_count when starting counters so reads match cleared HW.
drivers/perf/marvell_cn10k_tad_pmu.c | 54 ++++++++++++++++++++++++++--
1 file changed, 52 insertions(+), 2 deletions(-)
diff --git a/drivers/perf/marvell_cn10k_tad_pmu.c b/drivers/perf/marvell_cn10k_tad_pmu.c
index 69a6648fa664..cd81bf8ff569 100644
--- a/drivers/perf/marvell_cn10k_tad_pmu.c
+++ b/drivers/perf/marvell_cn10k_tad_pmu.c
@@ -17,11 +17,14 @@
#define TAD_PRF_OFFSET 0x900
#define TAD_PFC_OFFSET 0x800
+#define TAD_PRF_NS_OFFSET 0x30900
+#define TAD_PFC_NS_OFFSET 0x30800
#define TAD_PFC(base, counter) ((base) | ((u64)(counter) << 3))
#define TAD_PRF(base, counter) ((base) | ((u64)(counter) << 3))
#define TAD_PRF_CNTSEL_MASK 0xFF
#define TAD_PRF_MATCH_PARTID BIT(8)
#define TAD_PRF_PARTID_NS BIT(10)
+#define TAD_PRF_MATCH_MPAMNS BIT(25)
/*
* config1: bits 0..8 MPAM partition id (including 0); bit 9 requests
* filtering for MPAM-capable events. All-zero config1 means no filter.
@@ -39,6 +42,7 @@ struct tad_region {
enum mrvl_tad_pmu_version {
TAD_PMU_V1 = 1,
TAD_PMU_V2,
+ TAD_PMU_V3,
};
struct tad_pmu_data {
@@ -86,8 +90,15 @@ static void tad_pmu_start_counter(struct tad_pmu *pmu,
if (use_mpam && event_idx > 0x19 && event_idx < 0x21) {
partid_filter = TAD_PRF_MATCH_PARTID | TAD_PRF_PARTID_NS |
((u64)partid << 11);
+
+ if (pdata->id == TAD_PMU_V3)
+ partid_filter = TAD_PRF_MATCH_PARTID | TAD_PRF_MATCH_MPAMNS |
+ ((u64)partid << 10);
}
+ /* CN10K support events 0:24*/
+ if (pdata->id == TAD_PMU_V1 && event_idx >= 0x25)
+ return;
for (i = 0; i < pmu->region_cnt; i++) {
reg_val = event_idx & 0xFF;
@@ -160,6 +171,7 @@ static void tad_pmu_event_counter_start(struct perf_event *event, int flags)
struct hw_perf_event *hwc = &event->hw;
hwc->state = 0;
+ local64_set(&hwc->prev_count, 0);
tad_pmu->ops->start_counter(tad_pmu, event);
}
@@ -220,6 +232,8 @@ static int tad_pmu_event_init(struct perf_event *event)
if (cfg1)
return -EINVAL;
} else {
+ if (pdata->id == TAD_PMU_V1 && event_idx >= 0x25)
+ return -EINVAL;
if ((cfg1 & GENMASK(8, 0)) && !(cfg1 & TAD_PARTID_FILTER_EN))
return -EINVAL;
if (cfg1 & TAD_PARTID_FILTER_EN) {
@@ -246,6 +260,22 @@ static ssize_t tad_pmu_event_show(struct device *dev,
return sysfs_emit(page, "event=0x%02llx\n", pmu_attr->id);
}
+static umode_t tad_pmu_event_attr_is_visible(struct kobject *kobj,
+ struct attribute *attr, int unused)
+{
+ struct pmu *pmu = dev_get_drvdata(kobj_to_dev(kobj));
+ struct tad_pmu *t = to_tad_pmu(pmu);
+ struct device_attribute *da = container_of(attr, struct device_attribute,
+ attr);
+ struct perf_pmu_events_attr *e = container_of(da, struct perf_pmu_events_attr,
+ attr);
+ u64 id = e->id;
+
+ if (t->pdata->id != TAD_PMU_V3 && id >= 0x25)
+ return 0;
+ return attr->mode;
+}
+
#define TAD_PMU_EVENT_ATTR(name, config) \
PMU_EVENT_ATTR_ID(name, tad_pmu_event_show, config)
@@ -287,12 +317,25 @@ static struct attribute *tad_pmu_event_attrs[] = {
TAD_PMU_EVENT_ATTR(tad_dat_rd_byp, 0x22),
TAD_PMU_EVENT_ATTR(tad_ifb_occ, 0x23),
TAD_PMU_EVENT_ATTR(tad_req_occ, 0x24),
+ TAD_PMU_EVENT_ATTR(tad_req_msh_out_dtg_evict, 0x25),
+ TAD_PMU_EVENT_ATTR(tad_req_msh_out_ltg_evict, 0x26),
+ TAD_PMU_EVENT_ATTR(tad_rsp_msh_out_mpam, 0x28),
+ TAD_PMU_EVENT_ATTR(tad_replays, 0x29),
+ TAD_PMU_EVENT_ATTR(tad_req_byp0, 0x2a),
+ TAD_PMU_EVENT_ATTR(tad_req_byp1, 0x2b),
+ TAD_PMU_EVENT_ATTR(tad_txreq_byp, 0x2c),
+ TAD_PMU_EVENT_ATTR(tad_time_in_dslp, 0x2d),
+ TAD_PMU_EVENT_ATTR(tad_time_elapsed, 0x2e),
+ TAD_PMU_EVENT_ATTR(tad_req_msh_out_dss_rd_128mrg, 0x2f),
+ TAD_PMU_EVENT_ATTR(tad_req_msh_out_dss_wr_128mrg, 0x30),
+ TAD_PMU_EVENT_ATTR(tad_tot_cycle, 0xff),
NULL
};
static const struct attribute_group tad_pmu_events_attr_group = {
.name = "events",
.attrs = tad_pmu_event_attrs,
+ .is_visible = tad_pmu_event_attr_is_visible,
};
static struct attribute *ody_tad_pmu_event_attrs[] = {
@@ -478,7 +521,7 @@ static int tad_pmu_probe(struct platform_device *pdev)
.read = tad_pmu_event_counter_read,
};
- if (version == TAD_PMU_V1) {
+ if (version == TAD_PMU_V1 || version == TAD_PMU_V3) {
tad_pmu->pmu.attr_groups = tad_pmu_attr_groups;
tad_pmu->ops = &tad_pmu_ops;
} else {
@@ -521,6 +564,11 @@ static const struct tad_pmu_data tad_pmu_data = {
.tad_pfc_offset = TAD_PFC_OFFSET,
};
+static const struct tad_pmu_data tad_pmu_cn20k_data = {
+ .id = TAD_PMU_V3,
+ .tad_prf_offset = TAD_PRF_NS_OFFSET,
+ .tad_pfc_offset = TAD_PFC_NS_OFFSET,
+};
#endif
#ifdef CONFIG_ACPI
@@ -534,6 +582,7 @@ static const struct tad_pmu_data tad_pmu_v2_data = {
#ifdef CONFIG_OF
static const struct of_device_id tad_pmu_of_match[] = {
{ .compatible = "marvell,cn10k-tad-pmu", .data = &tad_pmu_data },
+ { .compatible = "marvell,cn20k-tad-pmu", .data = &tad_pmu_cn20k_data },
{},
};
#endif
@@ -542,6 +591,7 @@ static const struct of_device_id tad_pmu_of_match[] = {
static const struct acpi_device_id tad_pmu_acpi_match[] = {
{"MRVL000B", (kernel_ulong_t)&tad_pmu_data},
{"MRVL000D", (kernel_ulong_t)&tad_pmu_v2_data},
+ {"MRVL000F", (kernel_ulong_t)&tad_pmu_cn20k_data},
{},
};
MODULE_DEVICE_TABLE(acpi, tad_pmu_acpi_match);
@@ -603,6 +653,6 @@ static void __exit tad_pmu_exit(void)
module_init(tad_pmu_init);
module_exit(tad_pmu_exit);
-MODULE_DESCRIPTION("Marvell CN10K LLC-TAD perf driver");
+MODULE_DESCRIPTION("Marvell CN10K/CN20K LLC-TAD perf driver");
MODULE_AUTHOR("Bhaskara Budiredla <bbudiredla@marvell.com>");
MODULE_LICENSE("GPL v2");
--
2.25.1
^ 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