* Re: [PATCH RFC 3/9] net: stmmac: qcom-ethqos: fix RGMII_ID mode to use DLL bypass
From: Mohd Ayaan Anwar @ 2026-06-16 16:32 UTC (permalink / raw)
To: Andrew Lunn
Cc: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Richard Cochran, Bjorn Andersson, Konrad Dybcio, Maxime Coquelin,
Alexandre Torgue, Russell King, linux-arm-msm, netdev, devicetree,
linux-kernel, linux-stm32, linux-arm-kernel
In-Reply-To: <82705420-771d-41bf-a4d9-ed94dff86ff0@lunn.ch>
On Mon, Jun 15, 2026 at 06:48:55PM +0200, Andrew Lunn wrote:
> > > I'm curious how this works at the moment? Do no boards make use of
> > > RGMII ID? Are all current boards broken?
> >
> > Searching through the DTS, I found that we have two boards using "rgmii"
> > (qcs404-evb-4000.dts and sa8155-adp.dts) and another board using
> > "rgmii-txid" (sa8540p-ride.dts). No board which uses RGMII ID.
>
> So this causes problems. We cannot break existing boards, yet it would
> be good to fix the current broken behaviour.
I am trying to track down the sa8155-adp and sa8540p-ride boards. The
EMAC on QCS404 is extremely similar to QCS615 Ride [0], and I got that
board to work with this series (with RGMII ID mode). So I am fairly
confident that QCS404 would not break (if its even booting up with the
upstream kernel currently). Also, I think we could change the phy-mode
for QCS404 to "rgmii-id" from "rgmii" if these fixes go in.
> It could be the best way forward is that you issue a warning when
> "rgmii" is found and pass rgmii-id to the PHY. And you also change the
> two boards to use rgmii-id. Lets think about the rgmii-txid case once
> we better understand it.
>
As Konrad mentioned, it would be great to know if we can test out these
boards. Looking at the different versions of the ETHQOS programming
guide, stopping MAC side delay should be as simple as what we are doing
in this commit. But whether the two boards work directly with the
default PHY delays is unknown.
Ayaan
[0] The proposed RGMII fixes would help enable ethernet on QCS615 Ride
as well. I see that the original series had a lot of issues:
https://lore.kernel.org/all/20250121-dts_qcs615-v3-0-fa4496950d8a@quicinc.com/
^ permalink raw reply
* Re: [PATCH v2 1/5] arm64: Rename page table BSS section to .bss..pgtbl
From: Frank Li @ 2026-06-16 16:32 UTC (permalink / raw)
To: Ard Biesheuvel
Cc: Ard Biesheuvel, linux-arm-kernel, linux-kernel, Will Deacon,
Catalin Marinas, Kevin Brodsky, Mark Brown, Marc Zyngier
In-Reply-To: <fe467789-ae72-4a74-a9c0-6062b522fbd2@app.fastmail.com>
On Tue, Jun 16, 2026 at 11:38:48AM +0200, Ard Biesheuvel wrote:
>
>
> On Mon, 15 Jun 2026, at 22:09, Frank Li wrote:
> > On Thu, Jun 04, 2026 at 05:11:53PM +0200, Ard Biesheuvel wrote:
> >> From: Ard Biesheuvel <ardb@kernel.org>
> >>
> >> Rename the .pgdir.bss section to .bss..pgtbl so that the compiler will
> >> notice the leading ".bss" and mark it as NOBITS by default (rather than
> >> PROGBITS, which would take up space in Image binary, forcing all of the
> >> preceding BSS to be emitted into the image as well). This supersedes the
> >> NOLOAD linker directive, which achieves the same thing, and can be
> >> therefore be dropped.
> >>
> >> Also, rename .pgdir to .pgtbl to be more generic, as page tables of
> >> various levels will reside here.
> >>
> >> Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
> >> ---
> >
> > I met boot failure for i.MX8QXP by this patch
> >
> > [ 0.823515] Unable to handle kernel paging request at virtual
> > address ffff00000328f000
> > [ 0.831116] Mem abort info:
> > [ 0.833886] ESR = 0x0000000096000147
> > [ 0.837622] EC = 0x25: DABT (current EL), IL = 32 bits
> > [ 0.842923] SET = 0, FnV = 0
> > [ 0.845961] EA = 0, S1PTW = 0
> > [ 0.849088] FSC = 0x07: level 3 translation fault
> > [ 0.853952] Data abort info:
> > [ 0.856809] ISV = 0, ISS = 0x00000147, ISS2 = 0x00000000
> > [ 0.862296] CM = 1, WnR = 1, TnD = 0, TagAccess = 0
> > [ 0.867330] GCS = 0, Overlay = 0, DirtyBit = 0, Xs = 0
> > [ 0.872633] swapper pgtable: 4k pages, 48-bit VAs,
> > pgdp=000000008211f000
> > [ 0.879321] [ffff00000328f000] pgd=0000000000000000,
> > p4d=18000008bffff403, pud=18000008bfffe403, pmd=18000008bffea403,
> > pte=00e800008328ff06
> > [ 0.891834] Internal error: Oops: 0000000096000147 [#1] SMP
> > [ 0.897469] Modules linked in:
> > [ 0.900514] CPU: 0 UID: 0 PID: 1 Comm: swapper/0 Not tainted
> > 7.1.0-rc1-00016-g63e0b6a5b693 #834 PREEMPT
> > [ 0.909978] Hardware name: Freescale i.MX8QXP MEK (DT)
> > [ 0.915104] pstate: 80000005 (Nzcv daif -PAN -UAO -TCO -DIT -SSBS
> > BTYPE=--)
> > [ 0.922053] pc : dcache_clean_inval_poc+0x24/0x48
> > [ 0.926742] lr : kvm_arm_init+0xa78/0x1638
> > [ 0.930828] sp : ffff80008318bd10
> > [ 0.934127] x29: ffff80008318bd50 x28: 0000000000000000 x27:
> > ffff00000328f000
> > [ 0.941251] x26: 0000000000002000 x25: ffff80008219e000 x24:
> > 0000000001002222
> > [ 0.948374] x23: 0000000000000030 x22: ffff800081e850c0 x21:
> > ffff800082b790d0
> > [ 0.955498] x20: 0000000000000004 x19: ffff8000830a0000 x18:
> > 0000000000000000
> > [ 0.962622] x17: ffff800082f938b8 x16: ffff800082b8b4e0 x15:
> > ffff800082b8b4b8
> > [ 0.969746] x14: ffff80008308f0a0 x13: ffff800082b8b490 x12:
> > ffff800082b8b530
> > [ 0.976869] x11: ffff800082b8b508 x10: ffff80008308f140 x9 :
> > ffff80008308f118
> > [ 0.983993] x8 : ffff80008308f0f0 x7 : ffff80008308f0c8 x6 :
> > ffff80008308f078
> > [ 0.991117] x5 : ffff80008308f050 x4 : ffff800082b8b468 x3 :
> > 000000000000003f
> > [ 0.998240] x2 : 0000000000000040 x1 : ffff000003291000 x0 :
> > ffff00000328f000
> > [ 1.005367] Call trace:
> > [ 1.007800] dcache_clean_inval_poc+0x24/0x48 (P)
> > [ 1.012490] do_one_initcall+0x80/0x1c8
> > [ 1.016310] kernel_init_freeable+0x208/0x2f0
> > [ 1.020654] kernel_init+0x24/0x1e0
> > [ 1.024131] ret_from_fork+0x10/0x20
> > [ 1.027700] Code: 9ac32042 d1000443 8a230000 d503201f (d50b7e20)
> > [ 1.033779] ---[ end trace 0000000000000000 ]---
> > [ 1.038428] Kernel panic - not syncing: Attempted to kill init!
> > exitcode=0x0000000b
> > [ 1.046026] SMP: stopping secondary CPUs
> > [ 1.049943] Kernel Offset: disabled
> > [ 1.053408] CPU features: 0x00000000,00000008,00040021,0400421b
> > [ 1.059316] Memory Limit: none
> > [ 1.062359] ---[ end Kernel panic - not syncing: Attempted to kill
> > init! exitcode=0x0000000b ]---
> >
> >
> > Any idea?
> >
>
> Which tree is this based on?
Sorry, after rebase to 20260615 linux-next, problem disappear. Problem
appear at next-20260608. Suppose some patch fixed this problem recently.
Frank
^ permalink raw reply
* Re: [PATCH RFC 8/9] arm64: dts: qcom: shikra-cqs-evk: Enable ethernet0
From: Mohd Ayaan Anwar @ 2026-06-16 16:50 UTC (permalink / raw)
To: Konrad Dybcio
Cc: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Richard Cochran, Bjorn Andersson, Konrad Dybcio, Maxime Coquelin,
Alexandre Torgue, Russell King, linux-arm-msm, netdev, devicetree,
linux-kernel, linux-stm32, linux-arm-kernel
In-Reply-To: <2cb658f3-f564-4396-884d-d025eaa674a1@oss.qualcomm.com>
On Tue, Jun 16, 2026 at 11:50:26AM +0200, Konrad Dybcio wrote:
> On 6/11/26 8:37 PM, Mohd Ayaan Anwar wrote:
>
> > +&tlmm {
> > + ethernet0_defaults: ethernet0-defaults-state {
>
> s/defaults/default
>
> Please move this definition to shikra.dtsi
>
The CQM and CQS variants have identical GPIO mapping but the IQS is
different. So should I keep this in shikra.dtsi and overwrite for IQS in
shikra-iqs-evk.dts?
> > +
> > + emac0_phy_en_hog: emac0-phy-en-hog {
> > + gpio-hog;
> > + gpios = <149 GPIO_ACTIVE_HIGH>;
> > + output-high;
> > + line-name = "emac0-phy-en";
> > + };
>
> This looks like a hack - what does this pin actually do?
>
The power supply to both PHYs on Shikra is gated by a GPIO pin. I am
unsure whether they should be modelled as a fixed, enable-on-boot
regulator or just like this. They need to be powered on early so that
MDIO can detect them.
Thank you for the review. I will fix the stylistic issues in v2.
Ayaan
^ permalink raw reply
* Re: [PATCH v3] dmaengine: sun6i-dma: Fix use-after-free in error handling paths
From: Jernej Škrabec @ 2026-06-16 16:54 UTC (permalink / raw)
To: vkoul, Frank.Li, wens, samuel, mripard, arnd, Hongling Zeng
Cc: dmaengine, linux-arm-kernel, linux-sunxi, linux-kernel,
zhongling0719, Hongling Zeng
In-Reply-To: <20260616023138.15904-1-zenghongling@kylinos.cn>
Dne torek, 16. junij 2026 ob 04:31:38 Srednjeevropski poletni čas je Hongling Zeng napisal(a):
> In error handling paths, the for loop frees v_lli in the loop body,
> then accesses v_lli->v_lli_next and v_lli->p_lli_next in the
> increment expression, which is use-after-free.
>
> Fix by saving both the next virtual and physical pointers before
> freeing the current node.
>
> Fixes: 555859308723 ("dmaengine: Add driver for Allwinner sun6i DMA")
> Signed-off-by: Hongling Zeng <zenghongling@kylinos.cn>
> Suggested-by: Jernej Skrabec <jernej.skrabec@gmail.com>
>
> ---
This looks great! Thank you for your patience.
Reviewed-by: Jernej Skrabec <jernej.skrabec@gmail.com>
Best regards,
Jernej
> Changes in v2:
> -Refactored the fix to avoid code duplication by creating a helper function
> sun6i_dma_free_lli_list() that handles LLI list cleanup
> -Add Suggested-by: Jernej Skrabec <jernej.skrabec@gmail.com>
>
> ---
> Change in v3:
> -Further refactoring to move txd handling into the helper function
> as suggested by Jernej
> ---
> drivers/dma/sun6i-dma.c | 31 ++++++++++++++++---------------
> 1 file changed, 16 insertions(+), 15 deletions(-)
>
> diff --git a/drivers/dma/sun6i-dma.c b/drivers/dma/sun6i-dma.c
> index a9a254dbf8cb..7a79f346250a 100644
> --- a/drivers/dma/sun6i-dma.c
> +++ b/drivers/dma/sun6i-dma.c
> @@ -406,16 +406,12 @@ static inline void sun6i_dma_dump_lli(struct sun6i_vchan *vchan,
> v_lli->len, v_lli->para, v_lli->p_lli_next);
> }
>
> -static void sun6i_dma_free_desc(struct virt_dma_desc *vd)
> +static void sun6i_dma_free_desc(struct sun6i_dma_dev *sdev,
> + struct sun6i_desc *txd)
> {
> - struct sun6i_desc *txd = to_sun6i_desc(&vd->tx);
> - struct sun6i_dma_dev *sdev = to_sun6i_dma_dev(vd->tx.chan->device);
> struct sun6i_dma_lli *v_lli, *v_next;
> dma_addr_t p_lli, p_next;
>
> - if (unlikely(!txd))
> - return;
> -
> p_lli = txd->p_lli;
> v_lli = txd->v_lli;
>
> @@ -432,6 +428,17 @@ static void sun6i_dma_free_desc(struct virt_dma_desc *vd)
> kfree(txd);
> }
>
> +static void sun6i_dma_free_desc_virt(struct virt_dma_desc *vd)
> +{
> + struct sun6i_desc *txd = to_sun6i_desc(&vd->tx);
> + struct sun6i_dma_dev *sdev = to_sun6i_dma_dev(vd->tx.chan->device);
> +
> + if (unlikely(!txd))
> + return;
> +
> + sun6i_dma_free_desc(sdev, txd);
> +}
> +
> static int sun6i_dma_start_desc(struct sun6i_vchan *vchan)
> {
> struct sun6i_dma_dev *sdev = to_sun6i_dma_dev(vchan->vc.chan.device);
> @@ -788,10 +795,7 @@ static struct dma_async_tx_descriptor *sun6i_dma_prep_slave_sg(
> return vchan_tx_prep(&vchan->vc, &txd->vd, flags);
>
> err_lli_free:
> - for (p_lli = txd->p_lli, v_lli = txd->v_lli; v_lli;
> - p_lli = v_lli->p_lli_next, v_lli = v_lli->v_lli_next)
> - dma_pool_free(sdev->pool, v_lli, p_lli);
> - kfree(txd);
> + sun6i_dma_free_desc(sdev, txd);
> return NULL;
> }
>
> @@ -869,10 +873,7 @@ static struct dma_async_tx_descriptor *sun6i_dma_prep_dma_cyclic(
> return vchan_tx_prep(&vchan->vc, &txd->vd, flags);
>
> err_lli_free:
> - for (p_lli = txd->p_lli, v_lli = txd->v_lli; v_lli;
> - p_lli = v_lli->p_lli_next, v_lli = v_lli->v_lli_next)
> - dma_pool_free(sdev->pool, v_lli, p_lli);
> - kfree(txd);
> + sun6i_dma_free_desc(sdev, txd);
> return NULL;
> }
>
> @@ -1431,7 +1432,7 @@ static int sun6i_dma_probe(struct platform_device *pdev)
> struct sun6i_vchan *vchan = &sdc->vchans[i];
>
> INIT_LIST_HEAD(&vchan->node);
> - vchan->vc.desc_free = sun6i_dma_free_desc;
> + vchan->vc.desc_free = sun6i_dma_free_desc_virt;
> vchan_init(&vchan->vc, &sdc->slave);
> }
>
>
^ permalink raw reply
* Re: [PATCH v2] dmaengine: sun6i-dma: Fix memory leak in sun6i_dma_terminate_all
From: Jernej Škrabec @ 2026-06-16 16:59 UTC (permalink / raw)
To: vkoul, Frank.Li, wens, samuel, mripard, arnd, Hongling Zeng
Cc: dmaengine, linux-arm-kernel, linux-sunxi, linux-kernel,
zhongling0719, Hongling Zeng
In-Reply-To: <20260616060449.42225-1-zenghongling@kylinos.cn>
Dne torek, 16. junij 2026 ob 08:04:49 Srednjeevropski poletni čas je Hongling Zeng napisal(a):
> 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>
Acked-by: Jernej Skrabec <jernej.skrabec@gmail.com>
Best regards,
Jernej
>
> ---
> 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) {
>
^ permalink raw reply
* [arm-platforms:kvm-arm64/nv3 37/37] arch/arm64/kvm/sys_regs.c:222:32: warning: misleading indentation; statement is not part of the previous 'if'
From: kernel test robot @ 2026-06-16 17:35 UTC (permalink / raw)
To: Marc Zyngier; +Cc: llvm, oe-kbuild-all, linux-arm-kernel
tree: https://git.kernel.org/pub/scm/linux/kernel/git/maz/arm-platforms.git kvm-arm64/nv3
head: aa9a6e84f564417704258a20210b95d18ebf5601
commit: aa9a6e84f564417704258a20210b95d18ebf5601 [37/37] WIP
config: arm64-randconfig-003 (https://download.01.org/0day-ci/archive/20260617/202606170158.W9YgYBN4-lkp@intel.com/config)
compiler: clang version 20.1.8 (https://github.com/llvm/llvm-project 87f0227cb60147a26a1eeb4fb06e3b505e9c7261)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20260617/202606170158.W9YgYBN4-lkp@intel.com/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202606170158.W9YgYBN4-lkp@intel.com/
All warnings (new ones prefixed by >>):
arch/arm64/kvm/sys_regs.c:222:30: error: expected ';' after expression
222 | loc->loc = SR_LOC_SPECIAL : SR_LOC_MEMORY;
| ^
| ;
>> arch/arm64/kvm/sys_regs.c:222:32: warning: misleading indentation; statement is not part of the previous 'if' [-Wmisleading-indentation]
222 | loc->loc = SR_LOC_SPECIAL : SR_LOC_MEMORY;
| ^
arch/arm64/kvm/sys_regs.c:221:3: note: previous statement is here
221 | if (is_hyp_ctxt(vcpu))
| ^
>> arch/arm64/kvm/sys_regs.c:222:32: warning: expression result unused [-Wunused-value]
222 | loc->loc = SR_LOC_SPECIAL : SR_LOC_MEMORY;
| ^~~~~~~~~~~~~
2 warnings and 1 error generated.
vim +/if +222 arch/arm64/kvm/sys_regs.c
168
169 #define MAPPED_EL2_SYSREG(r, m, t) \
170 case r: { \
171 locate_mapped_el2_register(vcpu, r, m, t, loc); \
172 break; \
173 }
174
175 static void locate_register(const struct kvm_vcpu *vcpu, enum vcpu_sysreg reg,
176 struct sr_loc *loc)
177 {
178 if (!vcpu_get_flag(vcpu, SYSREGS_ON_CPU)) {
179 loc->loc = SR_LOC_MEMORY;
180 return;
181 }
182
183 switch (reg) {
184 MAPPED_EL2_SYSREG(SCTLR_EL2, SCTLR_EL1,
185 translate_sctlr_el2_to_sctlr_el1 );
186 MAPPED_EL2_SYSREG(TTBR0_EL2, TTBR0_EL1,
187 translate_ttbr0_el2_to_ttbr0_el1 );
188 MAPPED_EL2_SYSREG(TTBR1_EL2, TTBR1_EL1, NULL );
189 MAPPED_EL2_SYSREG(TCR_EL2, TCR_EL1,
190 translate_tcr_el2_to_tcr_el1 );
191 MAPPED_EL2_SYSREG(VBAR_EL2, VBAR_EL1, NULL );
192 MAPPED_EL2_SYSREG(AFSR0_EL2, AFSR0_EL1, NULL );
193 MAPPED_EL2_SYSREG(AFSR1_EL2, AFSR1_EL1, NULL );
194 MAPPED_EL2_SYSREG(ESR_EL2, ESR_EL1, NULL );
195 MAPPED_EL2_SYSREG(FAR_EL2, FAR_EL1, NULL );
196 MAPPED_EL2_SYSREG(MAIR_EL2, MAIR_EL1, NULL );
197 MAPPED_EL2_SYSREG(TCR2_EL2, TCR2_EL1, NULL );
198 MAPPED_EL2_SYSREG(PIR_EL2, PIR_EL1, NULL );
199 MAPPED_EL2_SYSREG(PIRE0_EL2, PIRE0_EL1, NULL );
200 MAPPED_EL2_SYSREG(POR_EL2, POR_EL1, NULL );
201 MAPPED_EL2_SYSREG(AMAIR_EL2, AMAIR_EL1, NULL );
202 MAPPED_EL2_SYSREG(ELR_EL2, ELR_EL1, NULL );
203 MAPPED_EL2_SYSREG(SPSR_EL2, SPSR_EL1, NULL );
204 MAPPED_EL2_SYSREG(CONTEXTIDR_EL2, CONTEXTIDR_EL1, NULL );
205 MAPPED_EL2_SYSREG(SCTLR2_EL2, SCTLR2_EL1, NULL );
206 case CNTHCTL_EL2:
207 /* CNTHCTL_EL2 is super special, unless we support NV2p1 */
208 loc->loc = (is_hyp_ctxt(vcpu) && vcpu_el2_e2h_is_set(vcpu) ?
209 SR_LOC_SPECIAL : SR_LOC_MEMORY);
210 break;
211 case CPTR_EL2:
212 /*
213 * CPTR_EL2 is just as special, and needs a certain amount
214 * of handholding. It always lives in memory, due to being
215 * heavily trapped thanks to CPACR_EL1.TCPAC being RES0.
216 * FEAT_NV2p1 fixes this.
217 */
218 locate_mapped_el2_register(vcpu, CPTR_EL2, CPACR_EL1,
219 translate_cptr_el2_to_cpacr_el1,
220 loc);
221 if (is_hyp_ctxt(vcpu))
> 222 loc->loc = SR_LOC_SPECIAL : SR_LOC_MEMORY;
223 break;
224 default:
225 loc->loc = locate_direct_register(vcpu, reg);
226 }
227 }
228
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
^ permalink raw reply
* [PATCH 6.1 337/522] arm64/mm: Enable batched TLB flush in unmap_hotplug_range()
From: Greg Kroah-Hartman @ 2026-06-16 14:58 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Will Deacon, linux-arm-kernel,
linux-kernel, David Hildenbrand (Arm), Ryan Roberts,
Anshuman Khandual, Catalin Marinas, Sasha Levin
In-Reply-To: <20260616145125.307082728@linuxfoundation.org>
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
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,
^ permalink raw reply
* [PATCH] ARM: omap2plus_defconfig: enable things required by iwd
From: Andreas Kemnade @ 2026-06-16 17:51 UTC (permalink / raw)
To: aaro.koskinen, andreas, khilman, rogerq, tony, linux, linux-omap,
linux-arm-kernel, linux-kernel
Several crypto related things are missing for opreation of iwd, turn
them on according to the list being printed out.
:~# /usr/libexec/iwd &
:~# No HMAC(SHA1) support found
No HMAC(MD5) support found
No CMAC(AES) support found
No HMAC(SHA256) support not found
No HMAC(SHA512) support found, certain TLS connections might fail
DES support not found
AES support not found
No CBC(DES3_EDE) support found, certain TLS connections might fail
No CBC(AES) support found, WPS will not be available
No Diffie-Hellman support found, WPS will not be available
The following options are missing in the kernel:
CONFIG_CRYPTO_USER_API_HASH
CONFIG_CRYPTO_USER_API_SKCIPHER
CONFIG_KEY_DH_OPERATIONS
CONFIG_CRYPTO_ECB
CONFIG_CRYPTO_MD5
CONFIG_CRYPTO_CBC
CONFIG_CRYPTO_SHA256
CONFIG_CRYPTO_AES
CONFIG_CRYPTO_DES
CONFIG_CRYPTO_CMAC
CONFIG_CRYPTO_HMAC
CONFIG_CRYPTO_SHA512
CONFIG_CRYPTO_SHA1
Apparently missing USER_API_SKCIPHER did also
hide some things for iwd.
Signed-off-by: Andreas Kemnade <andreas@kemnade.info>
---
arch/arm/configs/omap2plus_defconfig | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/arch/arm/configs/omap2plus_defconfig b/arch/arm/configs/omap2plus_defconfig
index ad5ae1636dee..fa6fb8b27f93 100644
--- a/arch/arm/configs/omap2plus_defconfig
+++ b/arch/arm/configs/omap2plus_defconfig
@@ -257,6 +257,9 @@ CONFIG_RXKAD=y
CONFIG_CFG80211=m
CONFIG_CFG80211_WEXT=y
CONFIG_MAC80211=m
+CONFIG_RFKILL=m
+CONFIG_RFKILL_INPUT=y
+CONFIG_RFKILL_GPIO=m
CONFIG_PCI=y
CONFIG_PCI_MSI=y
CONFIG_PCI_DRA7XX_EP=y
@@ -703,7 +706,15 @@ CONFIG_NFS_V4=y
CONFIG_ROOT_NFS=y
CONFIG_NLS_CODEPAGE_437=y
CONFIG_NLS_ISO8859_1=y
+CONFIG_KEY_DH_OPERATIONS=y
CONFIG_SECURITY=y
+CONFIG_CRYPTO_DH_RFC7919_GROUPS=y
+CONFIG_CRYPTO_DES=m
+CONFIG_CRYPTO_DEFLATE=y
+CONFIG_CRYPTO_LZO=y
+CONFIG_CRYPTO_ZSTD=y
+CONFIG_CRYPTO_USER_API_HASH=m
+CONFIG_CRYPTO_USER_API_SKCIPHER=m
CONFIG_CRYPTO_GHASH_ARM_CE=m
CONFIG_CRYPTO_AES=m
CONFIG_CRYPTO_AES_ARM_BS=m
--
2.47.3
^ permalink raw reply related
* Re: [PATCH 3/9] firmware: imx: ele: Add API functions for OCOTP fuse access
From: Frieder Schrempf @ 2026-06-16 17:59 UTC (permalink / raw)
To: Frank Li, Frieder Schrempf, Pankaj Gupta
Cc: Srinivas Kandagatla, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Frank Li, Sascha Hauer, Pengutronix Kernel Team,
Fabio Estevam, Shawn Guo, devicetree, imx, linux-arm-kernel,
linux-kernel
In-Reply-To: <ajFtkysqxuLV8GgF@SMW015318>
On 16.06.26 17:36, Frank Li wrote:
> On Tue, Jun 16, 2026 at 01:52:18PM +0200, Frieder Schrempf wrote:
>> From: Frieder Schrempf <frieder.schrempf@kontron.de>
>>
>> The ELE S400 API provides read and write access to the OCOTP fuse
>> registers. This adds the necessary API functions imx_se_read_fuse()
>> and imx_se_write_fuse() to be used by other drivers such as the
>> OCOTP S400 NVMEM driver.
>>
>> This is ported from the downstream vendor kernel.
>>
>> Signed-off-by: Frieder Schrempf <frieder.schrempf@kontron.de>
>> ---
>> drivers/firmware/imx/ele_base_msg.c | 122 ++++++++++++++++++++++++++++++++++++
>> drivers/firmware/imx/ele_base_msg.h | 6 ++
>> include/linux/firmware/imx/se_api.h | 3 +
>> 3 files changed, 131 insertions(+)
>>
> ...
>> +++ b/include/linux/firmware/imx/se_api.h
>> @@ -11,4 +11,7 @@
>> #define SOC_ID_OF_IMX8ULP 0x084d
>> #define SOC_ID_OF_IMX93 0x9300
>>
>> +int imx_se_read_fuse(void *se_if_data, uint16_t fuse_id, u32 *value);
>> +int imx_se_write_fuse(void *se_if_data, uint16_t fuse_id, u32 value);
>> +
>
> This API should implement in fuse drivers. Other consume should use standard
> fuse API to get value. If put here, it may bypass fuse driver.
The reason this is here, is the downstream implementation in linux-imx
and the current code organization. I thought there is some good reason
to have shared functions and it looks like Pankaj structured it like
this so all API functions live in ele_base_msg.c and the internal
structs and defines in ele_base_msg.h and se_ctrl.h are not exposed to
other drivers.
If I would move this into imx-ocotp-ele.c, then I would also need to
change how the code is organized and make the internal se_api functions
exposed to other drivers. I don't know if that is really a good idea.
I get your point but it looks like this contradicts the intention of
having a clean API in the firmware driver.
^ permalink raw reply
* [PATCH 1/2] module: add SCMI device table alias support
From: Bjorn Andersson @ 2026-06-16 18:09 UTC (permalink / raw)
To: Sudeep Holla, Cristian Marussi, Nathan Chancellor, Nicolas Schier
Cc: arm-scmi, linux-arm-kernel, linux-kernel, linux-kbuild,
Hans de Goede, Bjorn Andersson
In-Reply-To: <20260616-scmi-modalias-v1-0-662b8dd52ab2@oss.qualcomm.com>
SCMI client drivers already describe their bus match data with
MODULE_DEVICE_TABLE(scmi, ...), but modpost does not know how to consume
SCMI device tables. As a result, SCMI modules do not get generated module
aliases from their id tables.
Move struct scmi_device_id to mod_devicetable.h so it has a fixed layout
visible to modpost, add the corresponding generated offsets and teach
file2alias to emit scmi:<protocol>:<name> aliases.
Use the same stable alias format for SCMI device uevents and sysfs
modaliases. The previous string included the instance-specific device
name, which is not useful for matching modules.
Assisted-by: Codex:GPT-5.5
Signed-off-by: Bjorn Andersson <bjorn.andersson@oss.qualcomm.com>
---
drivers/firmware/arm_scmi/bus.c | 19 +++++++++----------
include/linux/mod_devicetable.h | 11 +++++++++++
include/linux/scmi_protocol.h | 6 +-----
scripts/mod/devicetable-offsets.c | 4 ++++
scripts/mod/file2alias.c | 11 +++++++++++
5 files changed, 36 insertions(+), 15 deletions(-)
diff --git a/drivers/firmware/arm_scmi/bus.c b/drivers/firmware/arm_scmi/bus.c
index 793be9eabaed..7e344f2ee18d 100644
--- a/drivers/firmware/arm_scmi/bus.c
+++ b/drivers/firmware/arm_scmi/bus.c
@@ -13,11 +13,12 @@
#include <linux/of.h>
#include <linux/kernel.h>
#include <linux/slab.h>
+#include <linux/string.h>
#include <linux/device.h>
#include "common.h"
-#define SCMI_UEVENT_MODALIAS_FMT "%s:%02x:%s"
+#define SCMI_UEVENT_MODALIAS_FMT SCMI_MODULE_PREFIX "%02x:%s"
BLOCKING_NOTIFIER_HEAD(scmi_requested_devices_nh);
EXPORT_SYMBOL_GPL(scmi_requested_devices_nh);
@@ -141,7 +142,7 @@ static int scmi_protocol_table_register(const struct scmi_device_id *id_table)
int ret = 0;
const struct scmi_device_id *entry;
- for (entry = id_table; entry->name && ret == 0; entry++)
+ for (entry = id_table; entry->name[0] && ret == 0; entry++)
ret = scmi_protocol_device_request(entry);
return ret;
@@ -197,18 +198,18 @@ scmi_protocol_table_unregister(const struct scmi_device_id *id_table)
{
const struct scmi_device_id *entry;
- for (entry = id_table; entry->name; entry++)
+ for (entry = id_table; entry->name[0]; entry++)
scmi_protocol_device_unrequest(entry);
}
static int scmi_dev_match_by_id_table(struct scmi_device *scmi_dev,
const struct scmi_device_id *id_table)
{
- if (!id_table || !id_table->name)
+ if (!id_table || !id_table->name[0])
return 0;
/* Always skip transport devices from matching */
- for (; id_table->protocol_id && id_table->name; id_table++)
+ for (; id_table->protocol_id && id_table->name[0]; id_table++)
if (id_table->protocol_id == scmi_dev->protocol_id &&
strncmp(scmi_dev->name, "__scmi_transport_device", 23) &&
!strcmp(id_table->name, scmi_dev->name))
@@ -245,7 +246,7 @@ static struct scmi_device *scmi_child_dev_find(struct device *parent,
struct device *dev;
id_table[0].protocol_id = prot_id;
- id_table[0].name = name;
+ strscpy(id_table[0].name, name, sizeof(id_table[0].name));
dev = device_find_child(parent, &id_table, scmi_match_by_id_table);
if (!dev)
@@ -282,8 +283,7 @@ static int scmi_device_uevent(const struct device *dev, struct kobj_uevent_env *
const struct scmi_device *scmi_dev = to_scmi_dev(dev);
return add_uevent_var(env, "MODALIAS=" SCMI_UEVENT_MODALIAS_FMT,
- dev_name(&scmi_dev->dev), scmi_dev->protocol_id,
- scmi_dev->name);
+ scmi_dev->protocol_id, scmi_dev->name);
}
static ssize_t modalias_show(struct device *dev,
@@ -292,8 +292,7 @@ static ssize_t modalias_show(struct device *dev,
struct scmi_device *scmi_dev = to_scmi_dev(dev);
return sysfs_emit(buf, SCMI_UEVENT_MODALIAS_FMT,
- dev_name(&scmi_dev->dev), scmi_dev->protocol_id,
- scmi_dev->name);
+ scmi_dev->protocol_id, scmi_dev->name);
}
static DEVICE_ATTR_RO(modalias);
diff --git a/include/linux/mod_devicetable.h b/include/linux/mod_devicetable.h
index 3b0c9a251a2e..769382f2eadd 100644
--- a/include/linux/mod_devicetable.h
+++ b/include/linux/mod_devicetable.h
@@ -473,6 +473,17 @@ struct rpmsg_device_id {
kernel_ulong_t driver_data;
};
+/* scmi */
+
+#define SCMI_NAME_SIZE 32
+#define SCMI_MODULE_PREFIX "scmi:"
+
+struct scmi_device_id {
+ __u8 protocol_id;
+ char name[SCMI_NAME_SIZE];
+ kernel_ulong_t driver_data;
+};
+
/* i2c */
#define I2C_NAME_SIZE 20
diff --git a/include/linux/scmi_protocol.h b/include/linux/scmi_protocol.h
index 5ab73b1ab9aa..48b346a26068 100644
--- a/include/linux/scmi_protocol.h
+++ b/include/linux/scmi_protocol.h
@@ -10,6 +10,7 @@
#include <linux/bitfield.h>
#include <linux/device.h>
+#include <linux/mod_devicetable.h>
#include <linux/notifier.h>
#include <linux/types.h>
@@ -951,11 +952,6 @@ struct scmi_device {
#define to_scmi_dev(d) container_of_const(d, struct scmi_device, dev)
-struct scmi_device_id {
- u8 protocol_id;
- const char *name;
-};
-
struct scmi_driver {
const char *name;
int (*probe)(struct scmi_device *sdev);
diff --git a/scripts/mod/devicetable-offsets.c b/scripts/mod/devicetable-offsets.c
index b4178c42d08f..da5bd712c8da 100644
--- a/scripts/mod/devicetable-offsets.c
+++ b/scripts/mod/devicetable-offsets.c
@@ -144,6 +144,10 @@ int main(void)
DEVID(rpmsg_device_id);
DEVID_FIELD(rpmsg_device_id, name);
+ DEVID(scmi_device_id);
+ DEVID_FIELD(scmi_device_id, protocol_id);
+ DEVID_FIELD(scmi_device_id, name);
+
DEVID(i2c_device_id);
DEVID_FIELD(i2c_device_id, name);
diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c
index 8d36c74dec2d..a5283f4c8e6f 100644
--- a/scripts/mod/file2alias.c
+++ b/scripts/mod/file2alias.c
@@ -852,6 +852,16 @@ static void do_rpmsg_entry(struct module *mod, void *symval)
module_alias_printf(mod, false, RPMSG_DEVICE_MODALIAS_FMT, *name);
}
+/* Looks like: scmi:NN:S */
+static void do_scmi_entry(struct module *mod, void *symval)
+{
+ DEF_FIELD(symval, scmi_device_id, protocol_id);
+ DEF_FIELD_ADDR(symval, scmi_device_id, name);
+
+ module_alias_printf(mod, false, SCMI_MODULE_PREFIX "%02x:%s",
+ protocol_id, *name);
+}
+
/* Looks like: i2c:S */
static void do_i2c_entry(struct module *mod, void *symval)
{
@@ -1491,6 +1501,7 @@ static const struct devtable devtable[] = {
{"virtio", SIZE_virtio_device_id, do_virtio_entry},
{"vmbus", SIZE_hv_vmbus_device_id, do_vmbus_entry},
{"rpmsg", SIZE_rpmsg_device_id, do_rpmsg_entry},
+ {"scmi", SIZE_scmi_device_id, do_scmi_entry},
{"i2c", SIZE_i2c_device_id, do_i2c_entry},
{"i3c", SIZE_i3c_device_id, do_i3c_entry},
{"slim", SIZE_slim_device_id, do_slim_entry},
--
2.53.0
^ permalink raw reply related
* [PATCH 2/2] firmware: arm_scmi: request modules for discovered protocols
From: Bjorn Andersson @ 2026-06-16 18:09 UTC (permalink / raw)
To: Sudeep Holla, Cristian Marussi, Nathan Chancellor, Nicolas Schier
Cc: arm-scmi, linux-arm-kernel, linux-kernel, linux-kbuild,
Hans de Goede, Bjorn Andersson
In-Reply-To: <20260616-scmi-modalias-v1-0-662b8dd52ab2@oss.qualcomm.com>
SCMI client devices are created from SCMI driver id tables. If such a
driver is modular, the core does not know the driver's client name until
the module has already loaded, so normal device uevent based autoloading
cannot break the dependency cycle.
Emit a protocol-level alias for each SCMI device id table entry and
request that alias when the SCMI core discovers an implemented protocol.
This loads modules that have registered interest in the protocol; their
normal SCMI driver registration then requests the concrete client device
and the SCMI bus matches it by protocol and name.
This allows e.g. ARM_SCMI_CPUFREQ=m to autoload on systems that expose
only the SCMI Performance protocol node, where the cpufreq client name
is Linux-internal and not available from firmware before loading the
module.
Assisted-by: Codex:GPT-5.5
Signed-off-by: Bjorn Andersson <bjorn.andersson@oss.qualcomm.com>
---
drivers/firmware/arm_scmi/driver.c | 2 ++
include/linux/mod_devicetable.h | 1 +
scripts/mod/file2alias.c | 4 +++-
3 files changed, 6 insertions(+), 1 deletion(-)
diff --git a/drivers/firmware/arm_scmi/driver.c b/drivers/firmware/arm_scmi/driver.c
index 3e0d975ec94c..8538eedc7c3a 100644
--- a/drivers/firmware/arm_scmi/driver.c
+++ b/drivers/firmware/arm_scmi/driver.c
@@ -47,6 +47,7 @@
#include <trace/events/scmi.h>
#define SCMI_VENDOR_MODULE_ALIAS_FMT "scmi-protocol-0x%02x-%s"
+#define SCMI_MODULE_ALIAS_FMT SCMI_PROTOCOL_MODULE_PREFIX "0x%02x"
static DEFINE_IDA(scmi_id);
@@ -3362,6 +3363,7 @@ static int scmi_probe(struct platform_device *pdev)
}
of_node_get(child);
+ request_module(SCMI_MODULE_ALIAS_FMT, prot_id);
scmi_create_protocol_devices(child, info, prot_id, NULL);
}
diff --git a/include/linux/mod_devicetable.h b/include/linux/mod_devicetable.h
index 769382f2eadd..2cc7e78e35a3 100644
--- a/include/linux/mod_devicetable.h
+++ b/include/linux/mod_devicetable.h
@@ -477,6 +477,7 @@ struct rpmsg_device_id {
#define SCMI_NAME_SIZE 32
#define SCMI_MODULE_PREFIX "scmi:"
+#define SCMI_PROTOCOL_MODULE_PREFIX "scmi-protocol-"
struct scmi_device_id {
__u8 protocol_id;
diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c
index a5283f4c8e6f..40a37b6bf1ad 100644
--- a/scripts/mod/file2alias.c
+++ b/scripts/mod/file2alias.c
@@ -852,7 +852,7 @@ static void do_rpmsg_entry(struct module *mod, void *symval)
module_alias_printf(mod, false, RPMSG_DEVICE_MODALIAS_FMT, *name);
}
-/* Looks like: scmi:NN:S */
+/* Looks like: scmi:NN:S and scmi-protocol-0xNN */
static void do_scmi_entry(struct module *mod, void *symval)
{
DEF_FIELD(symval, scmi_device_id, protocol_id);
@@ -860,6 +860,8 @@ static void do_scmi_entry(struct module *mod, void *symval)
module_alias_printf(mod, false, SCMI_MODULE_PREFIX "%02x:%s",
protocol_id, *name);
+ module_alias_printf(mod, false, SCMI_PROTOCOL_MODULE_PREFIX "0x%02x",
+ protocol_id);
}
/* Looks like: i2c:S */
--
2.53.0
^ permalink raw reply related
* [PATCH 0/2] firmware: arm_scmi: Ensure automatic module loading
From: Bjorn Andersson @ 2026-06-16 18:09 UTC (permalink / raw)
To: Sudeep Holla, Cristian Marussi, Nathan Chancellor, Nicolas Schier
Cc: arm-scmi, linux-arm-kernel, linux-kernel, linux-kbuild,
Hans de Goede, Bjorn Andersson
SCMI drivers such as the Arm SCMI CPUfreq driver are allowed to built as
modules, but they are then not automatically loaded. Rework the SCMI
device table alias support to make modpost consume the information from
MODULE_DEVICE_TABLE(scmi, ...) and allow drivers to be loaded based on
this information, if known. Also add a protocol-based alias to also
trigger driver loading when only the SCMI protocol id is known.
Signed-off-by: Bjorn Andersson <bjorn.andersson@oss.qualcomm.com>
---
Bjorn Andersson (2):
module: add SCMI device table alias support
firmware: arm_scmi: request modules for discovered protocols
drivers/firmware/arm_scmi/bus.c | 19 +++++++++----------
drivers/firmware/arm_scmi/driver.c | 2 ++
include/linux/mod_devicetable.h | 12 ++++++++++++
include/linux/scmi_protocol.h | 6 +-----
scripts/mod/devicetable-offsets.c | 4 ++++
scripts/mod/file2alias.c | 13 +++++++++++++
6 files changed, 41 insertions(+), 15 deletions(-)
---
base-commit: 8d6dbbbe3ba62de0a63e962ee004afb848c8e3ac
change-id: 20260616-scmi-modalias-0f32421bd452
Best regards,
--
Bjorn Andersson <bjorn.andersson@oss.qualcomm.com>
^ permalink raw reply
* [arm-platforms:kvm-arm64/nv3 37/37] arch/arm64/kvm/sys_regs.c:222:50: error: expected ';' before ':' token
From: kernel test robot @ 2026-06-16 18:10 UTC (permalink / raw)
To: Marc Zyngier; +Cc: oe-kbuild-all, linux-arm-kernel
tree: https://git.kernel.org/pub/scm/linux/kernel/git/maz/arm-platforms.git kvm-arm64/nv3
head: aa9a6e84f564417704258a20210b95d18ebf5601
commit: aa9a6e84f564417704258a20210b95d18ebf5601 [37/37] WIP
config: arm64-defconfig (https://download.01.org/0day-ci/archive/20260617/202606170206.EV8DFnS1-lkp@intel.com/config)
compiler: aarch64-linux-gcc (GCC) 16.1.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20260617/202606170206.EV8DFnS1-lkp@intel.com/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202606170206.EV8DFnS1-lkp@intel.com/
All errors (new ones prefixed by >>):
arch/arm64/kvm/sys_regs.c: In function 'locate_register':
>> arch/arm64/kvm/sys_regs.c:222:50: error: expected ';' before ':' token
222 | loc->loc = SR_LOC_SPECIAL : SR_LOC_MEMORY;
| ^~
| ;
vim +222 arch/arm64/kvm/sys_regs.c
168
169 #define MAPPED_EL2_SYSREG(r, m, t) \
170 case r: { \
171 locate_mapped_el2_register(vcpu, r, m, t, loc); \
172 break; \
173 }
174
175 static void locate_register(const struct kvm_vcpu *vcpu, enum vcpu_sysreg reg,
176 struct sr_loc *loc)
177 {
178 if (!vcpu_get_flag(vcpu, SYSREGS_ON_CPU)) {
179 loc->loc = SR_LOC_MEMORY;
180 return;
181 }
182
183 switch (reg) {
184 MAPPED_EL2_SYSREG(SCTLR_EL2, SCTLR_EL1,
185 translate_sctlr_el2_to_sctlr_el1 );
186 MAPPED_EL2_SYSREG(TTBR0_EL2, TTBR0_EL1,
187 translate_ttbr0_el2_to_ttbr0_el1 );
188 MAPPED_EL2_SYSREG(TTBR1_EL2, TTBR1_EL1, NULL );
189 MAPPED_EL2_SYSREG(TCR_EL2, TCR_EL1,
190 translate_tcr_el2_to_tcr_el1 );
191 MAPPED_EL2_SYSREG(VBAR_EL2, VBAR_EL1, NULL );
192 MAPPED_EL2_SYSREG(AFSR0_EL2, AFSR0_EL1, NULL );
193 MAPPED_EL2_SYSREG(AFSR1_EL2, AFSR1_EL1, NULL );
194 MAPPED_EL2_SYSREG(ESR_EL2, ESR_EL1, NULL );
195 MAPPED_EL2_SYSREG(FAR_EL2, FAR_EL1, NULL );
196 MAPPED_EL2_SYSREG(MAIR_EL2, MAIR_EL1, NULL );
197 MAPPED_EL2_SYSREG(TCR2_EL2, TCR2_EL1, NULL );
198 MAPPED_EL2_SYSREG(PIR_EL2, PIR_EL1, NULL );
199 MAPPED_EL2_SYSREG(PIRE0_EL2, PIRE0_EL1, NULL );
200 MAPPED_EL2_SYSREG(POR_EL2, POR_EL1, NULL );
201 MAPPED_EL2_SYSREG(AMAIR_EL2, AMAIR_EL1, NULL );
202 MAPPED_EL2_SYSREG(ELR_EL2, ELR_EL1, NULL );
203 MAPPED_EL2_SYSREG(SPSR_EL2, SPSR_EL1, NULL );
204 MAPPED_EL2_SYSREG(CONTEXTIDR_EL2, CONTEXTIDR_EL1, NULL );
205 MAPPED_EL2_SYSREG(SCTLR2_EL2, SCTLR2_EL1, NULL );
206 case CNTHCTL_EL2:
207 /* CNTHCTL_EL2 is super special, unless we support NV2p1 */
208 loc->loc = (is_hyp_ctxt(vcpu) && vcpu_el2_e2h_is_set(vcpu) ?
209 SR_LOC_SPECIAL : SR_LOC_MEMORY);
210 break;
211 case CPTR_EL2:
212 /*
213 * CPTR_EL2 is just as special, and needs a certain amount
214 * of handholding. It always lives in memory, due to being
215 * heavily trapped thanks to CPACR_EL1.TCPAC being RES0.
216 * FEAT_NV2p1 fixes this.
217 */
218 locate_mapped_el2_register(vcpu, CPTR_EL2, CPACR_EL1,
219 translate_cptr_el2_to_cpacr_el1,
220 loc);
221 if (is_hyp_ctxt(vcpu))
> 222 loc->loc = SR_LOC_SPECIAL : SR_LOC_MEMORY;
223 break;
224 default:
225 loc->loc = locate_direct_register(vcpu, reg);
226 }
227 }
228
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
^ permalink raw reply
* [PATCH 5.15 259/411] arm64/mm: Enable batched TLB flush in unmap_hotplug_range()
From: Greg Kroah-Hartman @ 2026-06-16 14:58 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Will Deacon, linux-arm-kernel,
linux-kernel, David Hildenbrand (Arm), Ryan Roberts,
Anshuman Khandual, Catalin Marinas, Sasha Levin
In-Reply-To: <20260616145100.376842714@linuxfoundation.org>
5.15-stable review patch. If anyone has any objections, please let me know.
------------------
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,
^ permalink raw reply
* Re: [PATCH] arm64: futex: Consolidate 'old == new' check in __lsui_cmpxchg32()
From: Catalin Marinas @ 2026-06-16 18:36 UTC (permalink / raw)
To: Yeoreum Yun; +Cc: Will Deacon, linux-arm-kernel
In-Reply-To: <ajEW41-ncVO_nDY7@e129823.arm.com>
On Tue, Jun 16, 2026 at 10:26:59AM +0100, Yeoreum Yun wrote:
> > On Tue, May 19, 2026 at 04:09:02PM +0100, Catalin Marinas wrote:
> > > On Tue, May 19, 2026 at 10:08:22AM +0100, Will Deacon wrote:
> > > > The LSUI futex implementation relies on a cmpxchg() loop to implement
> > > > FUTEX_OP_XOR, as the architecture doesn't provide unprivileged *EOR
> > > > atomics. Since the unprivileged 'CAST' instructions used to implement
> > > > the cmpxchg() can only operate on 64-bit memory locations, the
> > > > __lsui_cmpxchg32() helper function performs a song and dance to marshall
> > > > the 32-bit futex value into the correct part of a 64-bit register and
> > > > fill the remaining bytes with the neighbouring data.
> > >
> > > IIRC, the reason for the current __lsui_cmpxchg32() was not EOR but the
> > > expected futex_atomic_cmpxchg_inatomic() semantics. Looking at it again,
> > > we have wake_futex_pi() that does something else if the ret is 0 but the
> > > value differs. Looking at it again, the caller of wake_futex_pi()
> > > retries on -EAGAIN anyway, so I don't see a correctness issue, it will
> > > eventually hit the condition.
> >
> > Hmm, but I think that means my patch does change the behaviour of
> > wake_futex_pi() in an undesirable way. For example, futex_unlock_pi()
> > will go round the retry loop for any change in the futex value, whereas
> > before we would go back to userspace only if the TID changed.
> >
> > So I think we should swallow the -EAGAIN for the CAS-based cmpxchg() if
> > the futex word has changed, along the lines of the diff below.
> >
> > Will
> >
> > --->8
> >
> > diff --git a/arch/arm64/include/asm/futex.h b/arch/arm64/include/asm/futex.h
> > index db84a7b2de74..79c6d86c38a9 100644
> > --- a/arch/arm64/include/asm/futex.h
> > +++ b/arch/arm64/include/asm/futex.h
> > @@ -215,14 +215,14 @@ __lsui_futex_atomic_eor(int oparg, u32 __user *uaddr, int *oval)
> > static __always_inline int
> > __lsui_futex_cmpxchg(u32 __user *uaddr, u32 oldval, u32 newval, u32 *oval)
> > {
> > + u32 curval = oldval;
> > int ret;
> >
> > - /*
> > - * Callers of futex_atomic_cmpxchg_inatomic() already retry on
> > - * -EAGAIN, no need for another loop of max retries.
> > - */
> > - ret = __lsui_cmpxchg32(uaddr, &oldval, newval);
> > - *oval = oldval;
> > + ret = __lsui_cmpxchg32(uaddr, &curval, newval);
> > + if (ret == -EAGAIN && curval != oldval)
> > + ret = 0;
> > +
> > + *oval = curval;
> > return ret;
> > }
> > #endif /* CONFIG_ARM64_LSUI */
>
> Agree. It is good that this additional patch does not change
> the existing behavior.
>
> @Catalin, Could you check this please?
Ah, yes, looks good to me. I completely forgot about this.
--
Catalin
^ permalink raw reply
* Re: [PATCH v7 9/9] arm64: dts: mediatek: Add MediaTek MT6392 PMIC dtsi
From: Rob Herring @ 2026-06-16 18:57 UTC (permalink / raw)
To: Luca Leonardo Scorcia
Cc: linux-mediatek, Val Packett, Dmitry Torokhov, Krzysztof Kozlowski,
Conor Dooley, Sen Chu, Sean Wang, Macpaul Lin, Lee Jones,
Matthias Brugger, AngeloGioacchino Del Regno, Liam Girdwood,
Mark Brown, Linus Walleij, Louis-Alexis Eyraud, Julien Massot,
Fabien Parent, Akari Tsuyukusa, Chen Zhong, linux-input,
devicetree, linux-kernel, linux-pm, linux-arm-kernel, linux-gpio
In-Reply-To: <CAORyz2LiMHnaTK6QnsLxJDtw0fZ_N9LELw0iCorOZwHuWXus0g@mail.gmail.com>
On Tue, Jun 16, 2026 at 10:32 AM Luca Leonardo Scorcia
<l.scorcia@gmail.com> wrote:
>
> > > arch/arm64/boot/dts/mediatek/mt6392.dtsi | 75 ++++++++++++++++++++++++
> >
> > Nothing is using this so it is a dead file that doesn't get tested.
>
> Hi, it's not referenced as the dtsi inclusion was removed in the
> original patch from 2019 for an easier merging of support for mt8516
> pumpkin boards [1][2].
> If you prefer in the next revision I can add another patch to readd it
> to the existing pumpkin board.
That or move this patch to the series for the board(s). If the board
is already upstream, then add the include in *this* patch.
Rob
^ permalink raw reply
* [PATCH 5.10 223/342] arm64/mm: Enable batched TLB flush in unmap_hotplug_range()
From: Greg Kroah-Hartman @ 2026-06-16 14:58 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Will Deacon, linux-arm-kernel,
linux-kernel, David Hildenbrand (Arm), Ryan Roberts,
Anshuman Khandual, Catalin Marinas, Sasha Levin
In-Reply-To: <20260616145048.348037099@linuxfoundation.org>
5.10-stable review patch. If anyone has any objections, please let me know.
------------------
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,
^ permalink raw reply
* Re: [PATCH v7 2/3] PCI: rockchip-host: do not attempt 5.0 GT/s retraining
From: Dragan Simic @ 2026-06-16 19:08 UTC (permalink / raw)
To: Geraldo Nascimento
Cc: Shawn Lin, linux-rockchip, Lorenzo Pieralisi,
Krzysztof Wilczyński, Manivannan Sadhasivam, Rob Herring,
Bjorn Helgaas, linux-pci, linux-arm-kernel, linux-kernel
In-Reply-To: <68f6353e3a2ea4914de36c42b6906e41282adad3.1781622998.git.geraldogabriel@gmail.com>
Hello Geraldo,
Thanks for the v6 and v7 of this series.
On Tuesday, June 16, 2026 17:25 CEST, Geraldo Nascimento <geraldogabriel@gmail.com> wrote:
> Drop the 5.0 GT/s Link Speed retraining from Rockchip PCIe Root
> Complex Mode Operation, so called host driver.
>
> The reason is that Shawn Lin from Rockchip has reiterated that there
> may be danger of "catastrophic failure" in using their PCIe with
> 5.0GT/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
>
> 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-host.c | 20 --------------------
> 1 file changed, 20 deletions(-)
>
> diff --git a/drivers/pci/controller/pcie-rockchip-host.c b/drivers/pci/controller/pcie-rockchip-host.c
> index ee1822ca01db3..1374a2c92b563 100644
> --- a/drivers/pci/controller/pcie-rockchip-host.c
> +++ b/drivers/pci/controller/pcie-rockchip-host.c
> @@ -328,26 +328,6 @@ static int rockchip_pcie_host_init_port(struct rockchip_pcie *rockchip)
> goto err_power_off_phy;
> }
>
> - if (rockchip->link_gen == 2) {
> - /*
> - * Enable retrain for gen2. This should be configured only after
> - * gen1 finished.
> - */
> - status = rockchip_pcie_read(rockchip, PCIE_RC_CONFIG_CR + PCI_EXP_LNKCTL2);
> - status &= ~PCI_EXP_LNKCTL2_TLS;
> - status |= PCI_EXP_LNKCTL2_TLS_5_0GT;
> - rockchip_pcie_write(rockchip, status, PCIE_RC_CONFIG_CR + PCI_EXP_LNKCTL2);
> - status = rockchip_pcie_read(rockchip, PCIE_RC_CONFIG_CR + PCI_EXP_LNKCTL);
> - status |= PCI_EXP_LNKCTL_RL;
> - rockchip_pcie_write(rockchip, status, PCIE_RC_CONFIG_CR + PCI_EXP_LNKCTL);
> -
> - err = readl_poll_timeout(rockchip->apb_base + PCIE_CORE_CTRL,
> - status, PCIE_LINK_IS_GEN2(status), 20,
> - 500 * USEC_PER_MSEC);
> - if (err)
> - dev_dbg(dev, "PCIe link training gen2 timeout, fall back to gen1!\n");
> - }
> -
> /* Check the final link width from negotiated lane counter from MGMT */
> status = rockchip_pcie_read(rockchip, PCIE_CORE_CTRL);
> status = 0x1 << ((status & PCIE_CORE_PL_CONF_LANE_MASK) >>
Looking good to me, so please feel free to include
Reviewed-by: Dragan Simic <dsimic@manjaro.org>
^ permalink raw reply
* Re: [PATCH v7 3/3] PCI: rockchip: drive at 2.5 GT/s, error other speeds
From: Dragan Simic @ 2026-06-16 19:10 UTC (permalink / raw)
To: Geraldo Nascimento
Cc: Shawn Lin, linux-rockchip, Lorenzo Pieralisi,
Krzysztof Wilczyński, Manivannan Sadhasivam, Rob Herring,
Bjorn Helgaas, linux-pci, linux-arm-kernel, linux-kernel
In-Reply-To: <7421df7a7b7778ee99363cccfdfabbfa8aa6ab5e.1781622998.git.geraldogabriel@gmail.com>
Hello Geraldo,
Thanks for the v6 and v7 of this series.
On Tuesday, June 16, 2026 17:26 CEST, Geraldo Nascimento <geraldogabriel@gmail.com> 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 | 14 ++++++--------
> drivers/pci/controller/pcie-rockchip.h | 3 ---
> 2 files changed, 6 insertions(+), 11 deletions(-)
>
> diff --git a/drivers/pci/controller/pcie-rockchip.c b/drivers/pci/controller/pcie-rockchip.c
> index 0f88da3788054..456dcfd676ed7 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,8 @@ int rockchip_pcie_init_port(struct rockchip_pcie *rockchip)
> goto err_exit_phy;
> }
>
> - if (rockchip->link_gen == 2)
> - rockchip_pcie_write(rockchip, PCIE_CLIENT_GEN_SEL_2,
> - PCIE_CLIENT_CONFIG);
> - else
> - rockchip_pcie_write(rockchip, PCIE_CLIENT_GEN_SEL_1,
> - PCIE_CLIENT_CONFIG);
> + rockchip_pcie_write(rockchip, PCIE_CLIENT_GEN_SEL_1,
> + PCIE_CLIENT_CONFIG);
>
> regs = PCIE_CLIENT_ARI_ENABLE |
> PCIE_CLIENT_CONF_LANE_NUM(rockchip->lanes);
> diff --git a/drivers/pci/controller/pcie-rockchip.h b/drivers/pci/controller/pcie-rockchip.h
> index 3e82a69b9c006..b5da15601b585 100644
> --- a/drivers/pci/controller/pcie-rockchip.h
> +++ b/drivers/pci/controller/pcie-rockchip.h
> @@ -42,7 +42,6 @@
> #define PCIE_CLIENT_MODE_RC HWORD_SET_BIT(0x0040)
> #define PCIE_CLIENT_MODE_EP HWORD_CLR_BIT(0x0040)
> #define PCIE_CLIENT_GEN_SEL_1 HWORD_CLR_BIT(0x0080)
> -#define PCIE_CLIENT_GEN_SEL_2 HWORD_SET_BIT(0x0080)
> #define PCIE_CLIENT_LEGACY_INT_CTRL (PCIE_CLIENT_BASE + 0x0c)
> #define PCIE_CLIENT_INT_IN_ASSERT HWORD_SET_BIT(0x0002)
> #define PCIE_CLIENT_INT_IN_DEASSERT HWORD_CLR_BIT(0x0002)
> @@ -197,8 +196,6 @@
> (((x) & PCIE_CORE_PL_CONF_LS_MASK) == PCIE_CORE_PL_CONF_LS_READY)
> #define PCIE_LINK_UP(x) \
> (((x) & PCIE_CLIENT_LINK_STATUS_MASK) == PCIE_CLIENT_LINK_STATUS_UP)
> -#define PCIE_LINK_IS_GEN2(x) \
> - (((x) & PCIE_CORE_PL_CONF_SPEED_MASK) == PCIE_CORE_PL_CONF_SPEED_5G)
>
> #define RC_REGION_0_ADDR_TRANS_H 0x00000000
> #define RC_REGION_0_ADDR_TRANS_L 0x00000000
Looking good to me, so please feel free to include
Reviewed-by: Dragan Simic <dsimic@manjaro.org>
^ permalink raw reply
* Re: [PATCH v2] clk: mvebu: ap-cpu: fix missing clk_put() in ap_cpu_clock_probe()
From: Brian Masney @ 2026-06-16 19:22 UTC (permalink / raw)
To: Wentao Liang
Cc: andrew, gregory.clement, sebastian.hesselbarth, mturquette, sboyd,
linux-arm-kernel, linux-clk, linux-kernel
In-Reply-To: <20260616122936.1669366-1-vulab@iscas.ac.cn>
Hi Wentao,
On Tue, Jun 16, 2026 at 12:29:36PM +0000, Wentao Liang wrote:
> The function ap_cpu_clock_probe() calls of_clk_get() to obtain a
> reference to the parent clock for each CPU cluster, but it never
> releases it with clk_put(). The returned clk is used only to read
> the parent's name via __clk_get_name(), and the reference is leaked
> on every successful cluster initialization as well as on the error
> path when devm_clk_hw_register() fails.
>
> Rather than adding clk_put() calls, replace the of_clk_get() +
> __clk_get_name() pattern with of_clk_get_parent_name(), which is
> the intended API for this use case and handles the reference
> counting internally. This matches the pattern already used by the
> sibling drivers clk-cpu.c and clk-corediv.c.
>
> Fixes: af9617b419f7 ("clk: mvebu: ap-cpu-clk: Fix a memory leak in error handling paths")
> Signed-off-by: Wentao Liang <vulab@iscas.ac.cn>
The Fixes commit you listed missed this, and yes it should have been
fixed there as well, however the Fixes tag needs to point to the commit
where the leak was first introduced. In this case, it is:
Fixes: f756e362d9384 ("clk: mvebu: add CPU clock driver for Armada 7K/8K")
With that fixed:
Reviewed-by: Brian Masney <bmasney@redhat.com>
^ permalink raw reply
* Re: [PATCH 1/2] module: add SCMI device table alias support
From: Hans de Goede @ 2026-06-16 19:49 UTC (permalink / raw)
To: Bjorn Andersson, Sudeep Holla, Cristian Marussi,
Nathan Chancellor, Nicolas Schier
Cc: arm-scmi, linux-arm-kernel, linux-kernel, linux-kbuild
In-Reply-To: <20260616-scmi-modalias-v1-1-662b8dd52ab2@oss.qualcomm.com>
Hi,
On 16-Jun-26 20:09, Bjorn Andersson wrote:
> SCMI client drivers already describe their bus match data with
> MODULE_DEVICE_TABLE(scmi, ...), but modpost does not know how to consume
> SCMI device tables. As a result, SCMI modules do not get generated module
> aliases from their id tables.
>
> Move struct scmi_device_id to mod_devicetable.h so it has a fixed layout
> visible to modpost, add the corresponding generated offsets and teach
> file2alias to emit scmi:<protocol>:<name> aliases.
>
> Use the same stable alias format for SCMI device uevents and sysfs
> modaliases. The previous string included the instance-specific device
> name, which is not useful for matching modules.
>
> Assisted-by: Codex:GPT-5.5
> Signed-off-by: Bjorn Andersson <bjorn.andersson@oss.qualcomm.com>
Thank you for this. One small nit, you add:
#include <linux/mod_devicetable.h>
to include/linux/scmi_protocol.h
But that header only declares pointers to struct scmi_device_id.
so you can just forward declare the struct type there and
then only include linux/mod_devicetable.h in places which actually
need it, rather then dragging all of linux/mod_devicetable.h
into any file which includes linux/scmi_protocol.h .
Some people are working on untangling the kernel headers for
faster compile times. So IMHO it would be good to not introduce
new cases of headers unnecessary including other headers.
Either way the patch looks good to me:
Reviewed-by: Hans de Goede <johannes.goede@oss.qualcomm.com>
Regards,
Hans
> ---
> drivers/firmware/arm_scmi/bus.c | 19 +++++++++----------
> include/linux/mod_devicetable.h | 11 +++++++++++
> include/linux/scmi_protocol.h | 6 +-----
> scripts/mod/devicetable-offsets.c | 4 ++++
> scripts/mod/file2alias.c | 11 +++++++++++
> 5 files changed, 36 insertions(+), 15 deletions(-)
>
> diff --git a/drivers/firmware/arm_scmi/bus.c b/drivers/firmware/arm_scmi/bus.c
> index 793be9eabaed..7e344f2ee18d 100644
> --- a/drivers/firmware/arm_scmi/bus.c
> +++ b/drivers/firmware/arm_scmi/bus.c
> @@ -13,11 +13,12 @@
> #include <linux/of.h>
> #include <linux/kernel.h>
> #include <linux/slab.h>
> +#include <linux/string.h>
> #include <linux/device.h>
>
> #include "common.h"
>
> -#define SCMI_UEVENT_MODALIAS_FMT "%s:%02x:%s"
> +#define SCMI_UEVENT_MODALIAS_FMT SCMI_MODULE_PREFIX "%02x:%s"
>
> BLOCKING_NOTIFIER_HEAD(scmi_requested_devices_nh);
> EXPORT_SYMBOL_GPL(scmi_requested_devices_nh);
> @@ -141,7 +142,7 @@ static int scmi_protocol_table_register(const struct scmi_device_id *id_table)
> int ret = 0;
> const struct scmi_device_id *entry;
>
> - for (entry = id_table; entry->name && ret == 0; entry++)
> + for (entry = id_table; entry->name[0] && ret == 0; entry++)
> ret = scmi_protocol_device_request(entry);
>
> return ret;
> @@ -197,18 +198,18 @@ scmi_protocol_table_unregister(const struct scmi_device_id *id_table)
> {
> const struct scmi_device_id *entry;
>
> - for (entry = id_table; entry->name; entry++)
> + for (entry = id_table; entry->name[0]; entry++)
> scmi_protocol_device_unrequest(entry);
> }
>
> static int scmi_dev_match_by_id_table(struct scmi_device *scmi_dev,
> const struct scmi_device_id *id_table)
> {
> - if (!id_table || !id_table->name)
> + if (!id_table || !id_table->name[0])
> return 0;
>
> /* Always skip transport devices from matching */
> - for (; id_table->protocol_id && id_table->name; id_table++)
> + for (; id_table->protocol_id && id_table->name[0]; id_table++)
> if (id_table->protocol_id == scmi_dev->protocol_id &&
> strncmp(scmi_dev->name, "__scmi_transport_device", 23) &&
> !strcmp(id_table->name, scmi_dev->name))
> @@ -245,7 +246,7 @@ static struct scmi_device *scmi_child_dev_find(struct device *parent,
> struct device *dev;
>
> id_table[0].protocol_id = prot_id;
> - id_table[0].name = name;
> + strscpy(id_table[0].name, name, sizeof(id_table[0].name));
>
> dev = device_find_child(parent, &id_table, scmi_match_by_id_table);
> if (!dev)
> @@ -282,8 +283,7 @@ static int scmi_device_uevent(const struct device *dev, struct kobj_uevent_env *
> const struct scmi_device *scmi_dev = to_scmi_dev(dev);
>
> return add_uevent_var(env, "MODALIAS=" SCMI_UEVENT_MODALIAS_FMT,
> - dev_name(&scmi_dev->dev), scmi_dev->protocol_id,
> - scmi_dev->name);
> + scmi_dev->protocol_id, scmi_dev->name);
> }
>
> static ssize_t modalias_show(struct device *dev,
> @@ -292,8 +292,7 @@ static ssize_t modalias_show(struct device *dev,
> struct scmi_device *scmi_dev = to_scmi_dev(dev);
>
> return sysfs_emit(buf, SCMI_UEVENT_MODALIAS_FMT,
> - dev_name(&scmi_dev->dev), scmi_dev->protocol_id,
> - scmi_dev->name);
> + scmi_dev->protocol_id, scmi_dev->name);
> }
> static DEVICE_ATTR_RO(modalias);
>
> diff --git a/include/linux/mod_devicetable.h b/include/linux/mod_devicetable.h
> index 3b0c9a251a2e..769382f2eadd 100644
> --- a/include/linux/mod_devicetable.h
> +++ b/include/linux/mod_devicetable.h
> @@ -473,6 +473,17 @@ struct rpmsg_device_id {
> kernel_ulong_t driver_data;
> };
>
> +/* scmi */
> +
> +#define SCMI_NAME_SIZE 32
> +#define SCMI_MODULE_PREFIX "scmi:"
> +
> +struct scmi_device_id {
> + __u8 protocol_id;
> + char name[SCMI_NAME_SIZE];
> + kernel_ulong_t driver_data;
> +};
> +
> /* i2c */
>
> #define I2C_NAME_SIZE 20
> diff --git a/include/linux/scmi_protocol.h b/include/linux/scmi_protocol.h
> index 5ab73b1ab9aa..48b346a26068 100644
> --- a/include/linux/scmi_protocol.h
> +++ b/include/linux/scmi_protocol.h
> @@ -10,6 +10,7 @@
>
> #include <linux/bitfield.h>
> #include <linux/device.h>
> +#include <linux/mod_devicetable.h>
> #include <linux/notifier.h>
> #include <linux/types.h>
>
> @@ -951,11 +952,6 @@ struct scmi_device {
>
> #define to_scmi_dev(d) container_of_const(d, struct scmi_device, dev)
>
> -struct scmi_device_id {
> - u8 protocol_id;
> - const char *name;
> -};
> -
> struct scmi_driver {
> const char *name;
> int (*probe)(struct scmi_device *sdev);
> diff --git a/scripts/mod/devicetable-offsets.c b/scripts/mod/devicetable-offsets.c
> index b4178c42d08f..da5bd712c8da 100644
> --- a/scripts/mod/devicetable-offsets.c
> +++ b/scripts/mod/devicetable-offsets.c
> @@ -144,6 +144,10 @@ int main(void)
> DEVID(rpmsg_device_id);
> DEVID_FIELD(rpmsg_device_id, name);
>
> + DEVID(scmi_device_id);
> + DEVID_FIELD(scmi_device_id, protocol_id);
> + DEVID_FIELD(scmi_device_id, name);
> +
> DEVID(i2c_device_id);
> DEVID_FIELD(i2c_device_id, name);
>
> diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c
> index 8d36c74dec2d..a5283f4c8e6f 100644
> --- a/scripts/mod/file2alias.c
> +++ b/scripts/mod/file2alias.c
> @@ -852,6 +852,16 @@ static void do_rpmsg_entry(struct module *mod, void *symval)
> module_alias_printf(mod, false, RPMSG_DEVICE_MODALIAS_FMT, *name);
> }
>
> +/* Looks like: scmi:NN:S */
> +static void do_scmi_entry(struct module *mod, void *symval)
> +{
> + DEF_FIELD(symval, scmi_device_id, protocol_id);
> + DEF_FIELD_ADDR(symval, scmi_device_id, name);
> +
> + module_alias_printf(mod, false, SCMI_MODULE_PREFIX "%02x:%s",
> + protocol_id, *name);
> +}
> +
> /* Looks like: i2c:S */
> static void do_i2c_entry(struct module *mod, void *symval)
> {
> @@ -1491,6 +1501,7 @@ static const struct devtable devtable[] = {
> {"virtio", SIZE_virtio_device_id, do_virtio_entry},
> {"vmbus", SIZE_hv_vmbus_device_id, do_vmbus_entry},
> {"rpmsg", SIZE_rpmsg_device_id, do_rpmsg_entry},
> + {"scmi", SIZE_scmi_device_id, do_scmi_entry},
> {"i2c", SIZE_i2c_device_id, do_i2c_entry},
> {"i3c", SIZE_i3c_device_id, do_i3c_entry},
> {"slim", SIZE_slim_device_id, do_slim_entry},
>
^ permalink raw reply
* Re: [PATCH 2/2] firmware: arm_scmi: request modules for discovered protocols
From: Hans de Goede @ 2026-06-16 19:53 UTC (permalink / raw)
To: Bjorn Andersson, Sudeep Holla, Cristian Marussi,
Nathan Chancellor, Nicolas Schier
Cc: arm-scmi, linux-arm-kernel, linux-kernel, linux-kbuild
In-Reply-To: <20260616-scmi-modalias-v1-2-662b8dd52ab2@oss.qualcomm.com>
Hi,
On 16-Jun-26 20:09, Bjorn Andersson wrote:
> SCMI client devices are created from SCMI driver id tables. If such a
> driver is modular, the core does not know the driver's client name until
> the module has already loaded, so normal device uevent based autoloading
> cannot break the dependency cycle.
>
> Emit a protocol-level alias for each SCMI device id table entry and
> request that alias when the SCMI core discovers an implemented protocol.
> This loads modules that have registered interest in the protocol; their
> normal SCMI driver registration then requests the concrete client device
> and the SCMI bus matches it by protocol and name.
>
> This allows e.g. ARM_SCMI_CPUFREQ=m to autoload on systems that expose
> only the SCMI Performance protocol node, where the cpufreq client name
> is Linux-internal and not available from firmware before loading the
> module.
>
> Assisted-by: Codex:GPT-5.5
> Signed-off-by: Bjorn Andersson <bjorn.andersson@oss.qualcomm.com>
> ---
> drivers/firmware/arm_scmi/driver.c | 2 ++
> include/linux/mod_devicetable.h | 1 +
> scripts/mod/file2alias.c | 4 +++-
> 3 files changed, 6 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/firmware/arm_scmi/driver.c b/drivers/firmware/arm_scmi/driver.c
> index 3e0d975ec94c..8538eedc7c3a 100644
> --- a/drivers/firmware/arm_scmi/driver.c
> +++ b/drivers/firmware/arm_scmi/driver.c
> @@ -47,6 +47,7 @@
> #include <trace/events/scmi.h>
>
> #define SCMI_VENDOR_MODULE_ALIAS_FMT "scmi-protocol-0x%02x-%s"
> +#define SCMI_MODULE_ALIAS_FMT SCMI_PROTOCOL_MODULE_PREFIX "0x%02x"
>
> static DEFINE_IDA(scmi_id);
>
> @@ -3362,6 +3363,7 @@ static int scmi_probe(struct platform_device *pdev)
> }
>
> of_node_get(child);
> + request_module(SCMI_MODULE_ALIAS_FMT, prot_id);
I think it would be better to use request_module_nowait() here. AFAICT there
is no need to synchronously wait here for the module to actually get loaded.
Either way the patch looks good to me:
Reviewed-by: Hans de Goede <johannes.goede@oss.qualcomm.com>
Regards,
Hans
> scmi_create_protocol_devices(child, info, prot_id, NULL);
> }
>
> diff --git a/include/linux/mod_devicetable.h b/include/linux/mod_devicetable.h
> index 769382f2eadd..2cc7e78e35a3 100644
> --- a/include/linux/mod_devicetable.h
> +++ b/include/linux/mod_devicetable.h
> @@ -477,6 +477,7 @@ struct rpmsg_device_id {
>
> #define SCMI_NAME_SIZE 32
> #define SCMI_MODULE_PREFIX "scmi:"
> +#define SCMI_PROTOCOL_MODULE_PREFIX "scmi-protocol-"
>
> struct scmi_device_id {
> __u8 protocol_id;
> diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c
> index a5283f4c8e6f..40a37b6bf1ad 100644
> --- a/scripts/mod/file2alias.c
> +++ b/scripts/mod/file2alias.c
> @@ -852,7 +852,7 @@ static void do_rpmsg_entry(struct module *mod, void *symval)
> module_alias_printf(mod, false, RPMSG_DEVICE_MODALIAS_FMT, *name);
> }
>
> -/* Looks like: scmi:NN:S */
> +/* Looks like: scmi:NN:S and scmi-protocol-0xNN */
> static void do_scmi_entry(struct module *mod, void *symval)
> {
> DEF_FIELD(symval, scmi_device_id, protocol_id);
> @@ -860,6 +860,8 @@ static void do_scmi_entry(struct module *mod, void *symval)
>
> module_alias_printf(mod, false, SCMI_MODULE_PREFIX "%02x:%s",
> protocol_id, *name);
> + module_alias_printf(mod, false, SCMI_PROTOCOL_MODULE_PREFIX "0x%02x",
> + protocol_id);
> }
>
> /* Looks like: i2c:S */
>
^ permalink raw reply
* Re: [PATCH v7 1/3] PCI: rockchip-ep: do not attempt 5.0 GT/s retraining
From: Dragan Simic @ 2026-06-16 19:06 UTC (permalink / raw)
To: Geraldo Nascimento
Cc: Shawn Lin, linux-rockchip, Lorenzo Pieralisi,
Krzysztof Wilczyński, Manivannan Sadhasivam, Rob Herring,
Bjorn Helgaas, linux-pci, linux-arm-kernel, linux-kernel
In-Reply-To: <d994f8fb3481bbb8f3972f117334a6e8aea383fb.1781622998.git.geraldogabriel@gmail.com>
Hello Geraldo,
Thanks for the v6 and v7 of this series.
On Tuesday, June 16, 2026 17:25 CEST, Geraldo Nascimento <geraldogabriel@gmail.com> wrote:
> Drop the 5.0 GT/s Link Speed retraining code block from Rockchip PCIe
> EP driver. 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
>
> 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-ep.c | 13 -------------
> 1 file changed, 13 deletions(-)
>
> diff --git a/drivers/pci/controller/pcie-rockchip-ep.c b/drivers/pci/controller/pcie-rockchip-ep.c
> index 799461335762e..9ebc227a1ef84 100644
> --- a/drivers/pci/controller/pcie-rockchip-ep.c
> +++ b/drivers/pci/controller/pcie-rockchip-ep.c
> @@ -553,19 +553,6 @@ static void rockchip_pcie_ep_link_training(struct work_struct *work)
> if (ret)
> goto again;
>
> - /*
> - * Check the current speed: if gen2 speed was requested and we are not
> - * at gen2 speed yet, retrain again for gen2.
> - */
> - val = rockchip_pcie_read(rockchip, PCIE_CORE_CTRL);
> - if (!PCIE_LINK_IS_GEN2(val) && rockchip->link_gen == 2) {
> - /* Enable retrain for gen2 */
> - rockchip_pcie_ep_retrain_link(rockchip);
> - readl_poll_timeout(rockchip->apb_base + PCIE_CORE_CTRL,
> - val, PCIE_LINK_IS_GEN2(val), 50,
> - LINK_TRAIN_TIMEOUT);
> - }
> -
> /* Check again that the link is up */
> if (!rockchip_pcie_ep_link_up(rockchip))
> goto again;
Looking good to me, so please feel free to include
Reviewed-by: Dragan Simic <dsimic@manjaro.org>
^ permalink raw reply
* Re: [PATCH 3/9] firmware: imx: ele: Add API functions for OCOTP fuse access
From: Frank Li @ 2026-06-16 20:05 UTC (permalink / raw)
To: Frieder Schrempf
Cc: Frieder Schrempf, Pankaj Gupta, Srinivas Kandagatla, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Frank Li, Sascha Hauer,
Pengutronix Kernel Team, Fabio Estevam, Shawn Guo, devicetree,
imx, linux-arm-kernel, linux-kernel
In-Reply-To: <cea74ed4-1003-419e-8da3-1c62b1ace726@kontron.de>
On Tue, Jun 16, 2026 at 07:59:54PM +0200, Frieder Schrempf wrote:
> On 16.06.26 17:36, Frank Li wrote:
> > On Tue, Jun 16, 2026 at 01:52:18PM +0200, Frieder Schrempf wrote:
> >> From: Frieder Schrempf <frieder.schrempf@kontron.de>
> >>
> >> The ELE S400 API provides read and write access to the OCOTP fuse
> >> registers. This adds the necessary API functions imx_se_read_fuse()
> >> and imx_se_write_fuse() to be used by other drivers such as the
> >> OCOTP S400 NVMEM driver.
> >>
> >> This is ported from the downstream vendor kernel.
> >>
> >> Signed-off-by: Frieder Schrempf <frieder.schrempf@kontron.de>
> >> ---
> >> drivers/firmware/imx/ele_base_msg.c | 122 ++++++++++++++++++++++++++++++++++++
> >> drivers/firmware/imx/ele_base_msg.h | 6 ++
> >> include/linux/firmware/imx/se_api.h | 3 +
> >> 3 files changed, 131 insertions(+)
> >>
> > ...
> >> +++ b/include/linux/firmware/imx/se_api.h
> >> @@ -11,4 +11,7 @@
> >> #define SOC_ID_OF_IMX8ULP 0x084d
> >> #define SOC_ID_OF_IMX93 0x9300
> >>
> >> +int imx_se_read_fuse(void *se_if_data, uint16_t fuse_id, u32 *value);
> >> +int imx_se_write_fuse(void *se_if_data, uint16_t fuse_id, u32 value);
> >> +
> >
> > This API should implement in fuse drivers. Other consume should use standard
> > fuse API to get value. If put here, it may bypass fuse driver.
>
> The reason this is here, is the downstream implementation in linux-imx
> and the current code organization.
Downstream may not good enough, sometime, it is quick solution.
> I thought there is some good reason
> to have shared functions and it looks like Pankaj structured it like
> this so all API functions live in ele_base_msg.c and the internal
> structs and defines in ele_base_msg.h and se_ctrl.h are not exposed to
> other drivers.
>
> If I would move this into imx-ocotp-ele.c, then I would also need to
> change how the code is organized and make the internal se_api functions
> exposed to other drivers. I don't know if that is really a good idea.
>
> I get your point but it looks like this contradicts the intention of
> having a clean API in the firmware driver.
You can refer imx-ocotp-scu.c, structure should be similar, only difference
is that lower transfer APIs.
Frank
^ permalink raw reply
* Re: [PATCH] KVM: arm64: nv: Translate vEL2 PSTATE to EL1 in kvm_hyp_handle_mops()
From: Oliver Upton @ 2026-06-16 20:14 UTC (permalink / raw)
To: Weiming Shi
Cc: Marc Zyngier, Catalin Marinas, Will Deacon, Joey Gouly,
Steffen Eiden, Suzuki K Poulose, Zenghui Yu, Andrew Morton,
Jakub Kicinski, Bjorn Andersson, Mark Rutland, Kristina Martsenko,
linux-arm-kernel, kvmarm, Zhong Wang, Xuanqing Shi
In-Reply-To: <20260616114943.81188-2-bestswngs@gmail.com>
Hi Weiming,
Thanks for the fix.
On Tue, Jun 16, 2026 at 07:49:44PM +0800, Weiming Shi wrote:
> When a nested virtualisation guest is running its virtual EL2 (vEL2),
> fixup_guest_exit() rewrites vcpu_cpsr() to the guest's virtual exception
> level: a hardware PSTATE.M of EL1{t,h} is presented as EL2{t,h}. The
> hardware, however, executes vEL2 at EL1.
>
> kvm_hyp_handle_mops() runs on the fast guest re-entry path, where it
> clears the single-step bit and restores SPSR_EL2 directly from
> vcpu_cpsr():
>
> *vcpu_cpsr(vcpu) &= ~DBG_SPSR_SS;
> write_sysreg_el2(*vcpu_cpsr(vcpu), SYS_SPSR);
>
> For a guest hypervisor this writes the vEL2 view (PSTATE.M == EL2h) into
> the hardware SPSR_EL2 without translating it back. The fast path re-enters
> the guest via __guest_enter()/ERET without going through
> __sysreg_restore_el2_return_state(), so neither to_hw_pstate() nor the
> "return to a less privileged mode" safety check there (which would set
> PSR_IL_BIT) is applied. The ERET therefore restores PSTATE.M = EL2h and
> re-enters the guest at the real EL2 with a guest-controlled ELR, escaping
> stage-2 and the guest/host boundary.
>
> This is reachable on a kernel with FEAT_MOPS running a KVM nested guest
> (kvm-arm.mode=nested): KVM sets HCRX_EL2.MCE2, which the guest hypervisor
> cannot clear for its own context (is_nested_ctxt() is false), so a vEL2
> MOPS exception is taken to the host and dispatched to kvm_hyp_handle_mops()
> with VCPU_IN_HYP_CONTEXT set.
>
> Translate EL2{t,h} back to EL1{t,h} before writing SPSR_EL2, mirroring
> kvm_hyp_handle_eret(). For non-nested guests vcpu_cpsr() never holds an
> EL2 mode, so the translation is a no-op and behaviour is unchanged.
The changelog is unnecessarily verbose, instead:
kvm_hyp_handle_mops() resets the single-step state machine as part of
rewinding state for a MOPS exception by modifying vcpu_cpsr() and
writing the result directly into hardware.
In the case of nested virtualization, vcpu_cpsr() is a synthetic value
such that the rest of KVM can deal with vEL2 cleanly. That means the
value requires translation before being written into hardware, which is
unfortunately missing from the MOPS handler.
Fix it by directly modifying SPSR_EL2 and avoiding the synthetic state
altogether, which will be resynchronized on the next 'full' exit back
to KVM.
Also:
Cc: stable@vger.kernel.org
Definitely meets the bar :)
> Fixes: 2de451a329cf ("KVM: arm64: Add handler for MOPS exceptions")
> Assisted-by: Claude:claude-opus-4-8
> Reported-by: Zhong Wang <wangzhong.c0ss4ck@bytedance.com>
> Reported-by: Xuanqing Shi <shixuanqing.11@bytedance.com>
> Signed-off-by: Weiming Shi <bestswngs@gmail.com>
> ---
> arch/arm64/kvm/hyp/include/hyp/switch.h | 23 ++++++++++++++++++++++-
> 1 file changed, 22 insertions(+), 1 deletion(-)
>
> diff --git a/arch/arm64/kvm/hyp/include/hyp/switch.h b/arch/arm64/kvm/hyp/include/hyp/switch.h
> index e9b36a3b27bbc..a6b7963ddbf0b 100644
> --- a/arch/arm64/kvm/hyp/include/hyp/switch.h
> +++ b/arch/arm64/kvm/hyp/include/hyp/switch.h
> @@ -448,6 +448,8 @@ static inline bool __populate_fault_info(struct kvm_vcpu *vcpu)
>
> static inline bool kvm_hyp_handle_mops(struct kvm_vcpu *vcpu, u64 *exit_code)
> {
> + u64 spsr, mode;
> +
> *vcpu_pc(vcpu) = read_sysreg_el2(SYS_ELR);
> arm64_mops_reset_regs(vcpu_gp_regs(vcpu), vcpu->arch.fault.esr_el2);
> write_sysreg_el2(*vcpu_pc(vcpu), SYS_ELR);
> @@ -457,7 +459,26 @@ static inline bool kvm_hyp_handle_mops(struct kvm_vcpu *vcpu, u64 *exit_code)
> * instruction.
> */
> *vcpu_cpsr(vcpu) &= ~DBG_SPSR_SS;
> - write_sysreg_el2(*vcpu_cpsr(vcpu), SYS_SPSR);
> +
> + /*
> + * For a guest hypervisor, vcpu_cpsr() holds the vEL2 view
> + * (PSTATE.M == EL2h) installed by fixup_guest_exit(), but vEL2
> + * runs at EL1. Translate it back before restoring SPSR_EL2, as in
> + * kvm_hyp_handle_eret().
> + */
> + spsr = *vcpu_cpsr(vcpu);
> + mode = spsr & (PSR_MODE_MASK | PSR_MODE32_BIT);
> + switch (mode) {
> + case PSR_MODE_EL2t:
> + mode = PSR_MODE_EL1t;
> + break;
> + case PSR_MODE_EL2h:
> + mode = PSR_MODE_EL1h;
> + break;
> + }
> + spsr = (spsr & ~(PSR_MODE_MASK | PSR_MODE32_BIT)) | mode;
> +
> + write_sysreg_el2(spsr, SYS_SPSR);
As I allude to in the modified changelog, I'd rather we just manipulate
the hardware value of SPSR_EL2 directly. We already do this in
kvm_hyp_handle_eret()
spsr = read_sysreg_el2(SYS_SPSR);
write_sysreg_el2(spsr & ~DBG_SPSR_SS, SYS_SPSR);
Thanks,
Oliver
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox