* [PATCH] ASoC: fsl_sai: Fix 32 slots TDM broken by integer shift UB in xMR write
From: Chancel Liu @ 2026-05-29 8:50 UTC (permalink / raw)
To: shengjiu.wang, Xiubo.Lee, festevam, nicoleotsuka, lgirdwood,
broonie, perex, tiwai
Cc: linux-kernel, linuxppc-dev, linux-sound, stable
When configuring 32 slots TDM (channels == slots == 32), the xMR
(Mask Register) write used:
~0UL - ((1 << min(channels, slots)) - 1)
The literal '1' is a signed 32-bit int. Shifting it by 32 positions is
undefined behaviour which may set this register to 0xFFFFFFFF, masking
all 32 slots.
Use 1ULL so the shift is carried out in 64 bits. For 32 slots this
produces a zero mask after truncation to the 32-bit register:
~0ULL - ((1ULL << 32) - 1)
= 0xFFFFFFFFFFFFFFFF - (0x100000000 - 1)
= 0xFFFFFFFFFFFFFFFF - 0xFFFFFFFF
= 0xFFFFFFFF00000000
-> Truncates to 0x00000000
Behaviour for fewer than 32 slots is unchanged.
Fixes: 770f58d7d2c5 ("ASoC: fsl_sai: Support multiple data channel enable bits")
Cc: stable@vger.kernel.org
Signed-off-by: Chancel Liu <chancel.liu@nxp.com>
---
sound/soc/fsl/fsl_sai.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/sound/soc/fsl/fsl_sai.c b/sound/soc/fsl/fsl_sai.c
index d6dd95680892..821e3bd51b6e 100644
--- a/sound/soc/fsl/fsl_sai.c
+++ b/sound/soc/fsl/fsl_sai.c
@@ -797,7 +797,7 @@ static int fsl_sai_hw_params(struct snd_pcm_substream *substream,
FSL_SAI_CR4_FSD_MSTR, FSL_SAI_CR4_FSD_MSTR);
regmap_write(sai->regmap, FSL_SAI_xMR(tx),
- ~0UL - ((1 << min(channels, slots)) - 1));
+ ~0ULL - ((1ULL << min(channels, slots)) - 1));
return 0;
}
--
2.50.1
^ permalink raw reply related
* Re: [PATCH] powerpc/boot: remove unused min_t/max_t macros
From: Christophe Leroy (CS GROUP) @ 2026-05-29 9:10 UTC (permalink / raw)
To: Thorsten Blum, Madhavan Srinivasan, Michael Ellerman,
Nicholas Piggin
Cc: linuxppc-dev, linux-kernel
In-Reply-To: <20260525091839.817778-3-thorsten.blum@linux.dev>
Le 25/05/2026 à 11:18, Thorsten Blum a écrit :
> The min_t() and max_t() macros are no longer used by the boot wrapper,
> remove them.
Did you test your change ?
BOOTCC arch/powerpc/boot/decompress.o
In file included from arch/powerpc/boot/../../../lib/decompress_unxz.c:241,
from arch/powerpc/boot/decompress.c:37:
arch/powerpc/boot/../../../lib/xz/xz_dec_stream.c: In function 'fill_temp':
arch/powerpc/boot/../../../lib/xz/xz_dec_stream.c:158:28: error:
implicit declaration of function 'min_t'; did you mean 'min'?
[-Wimplicit-function-declaration]
158 | size_t copy_size = min_t(size_t,
| ^~~~~
| min
arch/powerpc/boot/../../../lib/xz/xz_dec_stream.c:158:34: error:
expected expression before 'size_t'
158 | size_t copy_size = min_t(size_t,
| ^~~~~~
In file included from arch/powerpc/boot/../../../lib/decompress_unxz.c:242:
arch/powerpc/boot/../../../lib/xz/xz_dec_lzma2.c: In function 'dict_repeat':
arch/powerpc/boot/../../../lib/xz/xz_dec_lzma2.c:357:22: error: expected
expression before 'size_t'
357 | left = min_t(size_t, dict->limit - dict->pos, *len);
| ^~~~~~
arch/powerpc/boot/../../../lib/xz/xz_dec_lzma2.c: In function
'xz_dec_lzma2_run':
arch/powerpc/boot/../../../lib/xz/xz_dec_lzma2.c:1101:52: error:
expected expression before 'size_t'
1101 | dict_limit(&s->dict, min_t(size_t,
| ^~~~~~
In file included from arch/powerpc/boot/../../../lib/decompress_unxz.c:243:
arch/powerpc/boot/../../../lib/xz/xz_dec_bcj.c: In function 'bcj_flush':
arch/powerpc/boot/../../../lib/xz/xz_dec_bcj.c:469:27: error: expected
expression before 'size_t'
469 | copy_size = min_t(size_t, s->temp.filtered, b->out_size
- b->out_pos);
| ^~~~~~
make[2]: *** [arch/powerpc/boot/Makefile:235:
arch/powerpc/boot/decompress.o] Error 1
make[1]: *** [arch/powerpc/Makefile:236: zImage] Error 2
make: *** [Makefile:248: __sub-make] Error 2
>
> Signed-off-by: Thorsten Blum <thorsten.blum@linux.dev>
> ---
> arch/powerpc/boot/types.h | 3 ---
> 1 file changed, 3 deletions(-)
>
> diff --git a/arch/powerpc/boot/types.h b/arch/powerpc/boot/types.h
> index 8a4c418b7260..c5085c2632bf 100644
> --- a/arch/powerpc/boot/types.h
> +++ b/arch/powerpc/boot/types.h
> @@ -37,9 +37,6 @@ typedef s64 int64_t;
> (void) (&_x == &_y); \
> _x > _y ? _x : _y; })
>
> -#define min_t(type, a, b) min(((type) a), ((type) b))
> -#define max_t(type, a, b) max(((type) a), ((type) b))
> -
> typedef int bool;
>
> #ifndef true
^ permalink raw reply
* Re: [PATCH] sched/topology: Provide arch_llc_mask for cache aware scheduling
From: Peter Zijlstra @ 2026-05-29 9:17 UTC (permalink / raw)
To: Shrikanth Hegde
Cc: maddy, linuxppc-dev, mingo, christophe.leroy, linux-kernel,
venkat88, yu.c.chen, tim.c.chen, kprateek.nayak, srikar, riteshh,
stable, Ritesh Harjani (IBM)
In-Reply-To: <20260529075712.1181039-1-sshegde@linux.ibm.com>
On Fri, May 29, 2026 at 01:27:12PM +0530, Shrikanth Hegde wrote:
> Venkat Reported a boot kernel panic next-20260522. Git bisect pointed to
> b5ea300a17e3 ("sched/cache: Make LLC id continuous")
>
> Stacktrace points to llc_mask being null.
>
> NIP [c000000000e58504] _find_first_bit+0x44/0x130
> LR [c000000000e58500] _find_first_bit+0x40/0x130
> Call Trace:
> build_sched_domains+0xad8/0xe50
> sched_init_smp+0xa8/0x164
> kernel_init_freeable+0x250/0x370
> ret_from_kernel_user_thread+0x14/0x1c
>
> On powerpc, cpu_coregroup_mask is available only when the underlying
> hardware support coregroup. In shared LPAR, QEMU guest or power9 etc
> coregroup isn't supported. In such cases llc_mask was being referenced
> when it was null leading to panic.
>
> On powerpc, LLC is at SMT core level. So assumption that coregroup(MC)
> domain point to LLC is wrong. Provide a way for archs to say where its
> LLC is if it not at MC domain.
>
> Based on tip/master at 5c89783224e9 ("Merge branch into tip/master: 'x86/tdx'")
> Cc: stable@vger.kernel.org
This seems unwarranted, the patch breaking stuff is in tip:sched/core.
> Fixes: b5ea300a17e3 ("sched/cache: Make LLC id continuous")
> Reported-by: Venkat Rao Bagalkote <venkat88@linux.ibm.com>
> Closes: https://lore.kernel.org/all/51154de7-3700-4cb4-82f2-1b3a8fa427f7@linux.ibm.com/
> Reviewed-by: Chen Yu <yu.c.chen@intel.com>
> Tested-by: Venkat Rao Bagalkote <venkat88@linux.ibm.com>
> Tested-by: Ritesh Harjani (IBM) <ritesh.list@gmail.com>
> Co-developed-by: Chen, Yu C <yu.c.chen@intel.com>
> Signed-off-by: Shrikanth Hegde <sshegde@linux.ibm.com>
Thanks all! I'll stick this in tip:sched/core to go along with the
patches that broke stuff.
^ permalink raw reply
* Re: [PATCH] ASoC: fsl_sai: Fix 32 slots TDM broken by integer shift UB in xMR write
From: Christophe Leroy (CS GROUP) @ 2026-05-29 9:21 UTC (permalink / raw)
To: Chancel Liu, shengjiu.wang, Xiubo.Lee, festevam, nicoleotsuka,
lgirdwood, broonie, perex, tiwai
Cc: linux-kernel, linuxppc-dev, linux-sound, stable
In-Reply-To: <20260529085020.3727790-1-chancel.liu@nxp.com>
Le 29/05/2026 à 10:50, Chancel Liu a écrit :
> When configuring 32 slots TDM (channels == slots == 32), the xMR
> (Mask Register) write used:
> ~0UL - ((1 << min(channels, slots)) - 1)
>
> The literal '1' is a signed 32-bit int. Shifting it by 32 positions is
> undefined behaviour which may set this register to 0xFFFFFFFF, masking
> all 32 slots.
>
> Use 1ULL so the shift is carried out in 64 bits. For 32 slots this
> produces a zero mask after truncation to the 32-bit register:
> ~0ULL - ((1ULL << 32) - 1)
> = 0xFFFFFFFFFFFFFFFF - (0x100000000 - 1)
> = 0xFFFFFFFFFFFFFFFF - 0xFFFFFFFF
> = 0xFFFFFFFF00000000
> -> Truncates to 0x00000000
> Behaviour for fewer than 32 slots is unchanged.
Why not use macro GENMASK_U32() instead ?
>
> Fixes: 770f58d7d2c5 ("ASoC: fsl_sai: Support multiple data channel enable bits")
> Cc: stable@vger.kernel.org
> Signed-off-by: Chancel Liu <chancel.liu@nxp.com>
> ---
> sound/soc/fsl/fsl_sai.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/sound/soc/fsl/fsl_sai.c b/sound/soc/fsl/fsl_sai.c
> index d6dd95680892..821e3bd51b6e 100644
> --- a/sound/soc/fsl/fsl_sai.c
> +++ b/sound/soc/fsl/fsl_sai.c
> @@ -797,7 +797,7 @@ static int fsl_sai_hw_params(struct snd_pcm_substream *substream,
> FSL_SAI_CR4_FSD_MSTR, FSL_SAI_CR4_FSD_MSTR);
>
> regmap_write(sai->regmap, FSL_SAI_xMR(tx),
> - ~0UL - ((1 << min(channels, slots)) - 1));
> + ~0ULL - ((1ULL << min(channels, slots)) - 1));
>
> return 0;
> }
^ permalink raw reply
* Re: [PATCH] powerpc/boot: remove unused min_t/max_t macros
From: Thorsten Blum @ 2026-05-29 9:45 UTC (permalink / raw)
To: Christophe Leroy (CS GROUP)
Cc: Madhavan Srinivasan, Michael Ellerman, Nicholas Piggin,
linuxppc-dev, linux-kernel
In-Reply-To: <7c1a04f3-caa8-4200-a4ee-55cd2cc28461@kernel.org>
Hi Christophe,
On Fri, May 29, 2026 at 11:10:20AM +0200, Christophe Leroy (CS GROUP) wrote:
>
>
> Le 25/05/2026 à 11:18, Thorsten Blum a écrit :
> > The min_t() and max_t() macros are no longer used by the boot wrapper,
> > remove them.
>
> Did you test your change ?
Yes, but with Gzip and not with XZ, and by grepping for min_t/max_t in
arch/powerpc/boot/. I (wrongly) assumed that arch/powerpc/boot/ is
self-contained.
Thanks for catching this, and please drop this patch for now as I wasn't
aware of the dependency to lib/xz/.
Thorsten
^ permalink raw reply
* Re: [PATCH] powerpc/boot: remove unused min_t/max_t macros
From: Christophe Leroy (CS GROUP) @ 2026-05-29 9:52 UTC (permalink / raw)
To: Thorsten Blum
Cc: Madhavan Srinivasan, Michael Ellerman, Nicholas Piggin,
linuxppc-dev, linux-kernel
In-Reply-To: <ahlgQZW7z7Ht4qpS@linux.dev>
Le 29/05/2026 à 11:45, Thorsten Blum a écrit :
> Hi Christophe,
>
> On Fri, May 29, 2026 at 11:10:20AM +0200, Christophe Leroy (CS GROUP) wrote:
>>
>>
>> Le 25/05/2026 à 11:18, Thorsten Blum a écrit :
>>> The min_t() and max_t() macros are no longer used by the boot wrapper,
>>> remove them.
>>
>> Did you test your change ?
>
> Yes, but with Gzip and not with XZ, and by grepping for min_t/max_t in
> arch/powerpc/boot/. I (wrongly) assumed that arch/powerpc/boot/ is
> self-contained.
You could have figured out with 'git blame arch/powerpc/boot/types.h'
that those lines were added by commit c762c69e106f ("powerpc/boot: Add
support for XZ compression")
>
> Thanks for catching this, and please drop this patch for now as I wasn't
> aware of the dependency to lib/xz/.
^ permalink raw reply
* Re: [PATCH] sched/topology: Provide arch_llc_mask for cache aware scheduling
From: Srikar Dronamraju @ 2026-05-29 10:15 UTC (permalink / raw)
To: Shrikanth Hegde
Cc: maddy, linuxppc-dev, peterz, mingo, christophe.leroy,
linux-kernel, venkat88, yu.c.chen, tim.c.chen, kprateek.nayak,
riteshh, stable, Ritesh Harjani (IBM)
In-Reply-To: <20260529075712.1181039-1-sshegde@linux.ibm.com>
* Shrikanth Hegde <sshegde@linux.ibm.com> [2026-05-29 13:27:12]:
> Venkat Reported a boot kernel panic next-20260522. Git bisect pointed to
> b5ea300a17e3 ("sched/cache: Make LLC id continuous")
>
> Stacktrace points to llc_mask being null.
>
> NIP [c000000000e58504] _find_first_bit+0x44/0x130
> LR [c000000000e58500] _find_first_bit+0x40/0x130
> Call Trace:
> build_sched_domains+0xad8/0xe50
> sched_init_smp+0xa8/0x164
> kernel_init_freeable+0x250/0x370
> ret_from_kernel_user_thread+0x14/0x1c
>
> On powerpc, cpu_coregroup_mask is available only when the underlying
> hardware support coregroup. In shared LPAR, QEMU guest or power9 etc
> coregroup isn't supported. In such cases llc_mask was being referenced
> when it was null leading to panic.
>
> On powerpc, LLC is at SMT core level. So assumption that coregroup(MC)
> domain point to LLC is wrong. Provide a way for archs to say where its
> LLC is if it not at MC domain.
>
> Based on tip/master at 5c89783224e9 ("Merge branch into tip/master: 'x86/tdx'")
> Cc: stable@vger.kernel.org
>
> Fixes: b5ea300a17e3 ("sched/cache: Make LLC id continuous")
> Reported-by: Venkat Rao Bagalkote <venkat88@linux.ibm.com>
> Closes: https://lore.kernel.org/all/51154de7-3700-4cb4-82f2-1b3a8fa427f7@linux.ibm.com/
> Reviewed-by: Chen Yu <yu.c.chen@intel.com>
> Tested-by: Venkat Rao Bagalkote <venkat88@linux.ibm.com>
> Tested-by: Ritesh Harjani (IBM) <ritesh.list@gmail.com>
> Co-developed-by: Chen, Yu C <yu.c.chen@intel.com>
> Signed-off-by: Shrikanth Hegde <sshegde@linux.ibm.com>
> ---
> arch/powerpc/include/asm/topology.h | 6 ++++++
> kernel/sched/topology.c | 13 +++++++++++--
> 2 files changed, 17 insertions(+), 2 deletions(-)
>
> diff --git a/arch/powerpc/include/asm/topology.h b/arch/powerpc/include/asm/topology.h
> index 66ed5fe1b718..e3de0f3d8b86 100644
> --- a/arch/powerpc/include/asm/topology.h
> +++ b/arch/powerpc/include/asm/topology.h
> @@ -135,6 +135,12 @@ struct cpumask *cpu_coregroup_mask(int cpu);
> const struct cpumask *cpu_die_mask(int cpu);
> int cpu_die_id(int cpu);
>
> +/* Points to where the LLC is. On power9 this will point at CACHE
> + * domain, On others it will point to SMT domain. In all cases
> + * cpu_l2_cache_mask points to where LLC is
> + */
Nit: Regular comment style could have been better.
> +#define arch_llc_mask(cpu) cpu_l2_cache_mask(cpu)
> +
> #ifdef CONFIG_PPC64
> #include <asm/smp.h>
>
> diff --git a/kernel/sched/topology.c b/kernel/sched/topology.c
> index df2ceb54c970..622e2e01974c 100644
> --- a/kernel/sched/topology.c
> +++ b/kernel/sched/topology.c
> @@ -2063,12 +2063,21 @@ const struct cpumask *tl_mc_mask(struct sched_domain_topology_level *tl, int cpu
> return cpu_coregroup_mask(cpu);
> }
>
> -#define llc_mask(cpu) cpu_coregroup_mask(cpu)
> +/*
> + * Majority of architectures have LLC at MC domain level with exception
> + * such as powerpc. Provide a way for arch to specify where its LLC is
> + * if it falls in exception category
> + */
> +# ifndef arch_llc_mask
> +#define arch_llc_mask(cpu) cpu_coregroup_mask(cpu)
> +# endif
>
> #else
> -#define llc_mask(cpu) cpumask_of(cpu)
> +#define arch_llc_mask(cpu) cpumask_of(cpu)
> #endif
>
> +#define llc_mask(cpu) arch_llc_mask(cpu)
> +
Instead of having another define, could we have modified current users of
llc_mask() to arch_llc_mask()? Again its not a problem, but why have 2
defines since both point to the same thing.
> const struct cpumask *tl_pkg_mask(struct sched_domain_topology_level *tl, int cpu)
> {
> return cpu_node_mask(cpu);
> --
> 2.47.3
>
Otherwise, looks good to me.
Reviewed-by: Srikar Dronamraju <srikar@linux.ibm.com>
--
Thanks and Regards
Srikar Dronamraju
^ permalink raw reply
* Re: [PATCH v3 1/5] KVM: PPC: Book3S HV: Validate arch_compat against host compatibility mode
From: Amit Machhiwal @ 2026-05-29 10:28 UTC (permalink / raw)
To: Ritesh Harjani
Cc: Amit Machhiwal, linuxppc-dev, Madhavan Srinivasan, Vaibhav Jain,
Anushree Mathur, Paolo Bonzini, Nicholas Piggin, Michael Ellerman,
Christophe Leroy (CS GROUP), Jonathan Corbet, Shuah Khan, kvm,
linux-kernel, linux-doc, lkp
In-Reply-To: <pl2g6xbz.ritesh.list@gmail.com>
Hi Ritesh,
Thanks for taking a look at this patch. Please find my response inline
below:
On 2026/05/28 08:43 AM, Ritesh Harjani wrote:
> Amit Machhiwal <amachhiw@linux.ibm.com> writes:
>
> > On IBM POWER systems, newer processor generations can operate in
> > compatibility modes corresponding to earlier generations. This becomes
> > relevant for nested virtualization, where nested KVM guests may need to
> > run with a specific processor compatibility level.
> >
> > Currently, when running a nested KVM guest (L2) inside a Power11 pSeries
> > logical partition (L1) booted in Power10 compatibility mode, the guest
> > fails to boot while setting 'arch_compat'. This happens because the CPU
> > class is derived from the hardware PVR (via mfspr()), which reflects the
> > physical processor generation (Power11), rather than the effective
> > compatibility mode (Power10).
> >
> > As a result, userspace may request a Power11 arch_compat for the L2
> > guest. However, the L1 partition, running in Power10 compatibility, has
> > only negotiated support up to Power10 with the Power Hypervisor (L0).
> > When H_SET_STATE is invoked with a Power11 Logical PVR, the hypervisor
>
> s/H_SET_STATE/H_GUEST_SET_STATE
Good catch! I'll fix this in the next version.
>
> > rejects the request, leading to a late guest boot failure:
> >
> > KVM-NESTEDv2: couldn't set guest wide elements
> > [..KVM reg dump..]
> >
>
> I think irrespective of the other UAPI changes, we should still get this
> fixed - so that we don't see a late KVM guest boot failure msgs.
>
> So, in this review, I would like to mainly look at fixing this issue
> first and would request if we can defer the UAPI changes as a separate
> patch series please.
This patch only enables the guest boot to bail out early instead of going upto
making an H_GUEST_SET_STATE hcall with a non supported compatibility mode. In
addition to that, it does not fix the real problem where guest fails to boot on
Power11 LPAR booted in a Power10 compatibility mode.
I understand your point and to make the segregation explicitly clear, I shall
update the cover letter to mention that patch 1 only takes care of failing
earlier as soon as an invalid compatibility mode is detected and Patch 2-5
introduce a new uAPI for evaluating the right compatibility mode.
The actual L2 guest boot fix with L1 booted in a compatibility mode is done via
the next 4 patches which enables correct compatibility mode detection using the
newly introduced uAPI. So, we would still want to prioritize the whole series
instead of just this one patch.
>
>
> > This situation should be detected earlier. Rejecting unsupported
> > 'arch_compat' values in 'kvmppc_set_arch_compat()' avoids issuing an
> > invalid H_SET_STATE hcall and provides a clearer failure mode.
>
> s/H_SET_STATE/H_GUEST_SET_STATE
Will rectify in the next version.
>
> >
> > Add a check to reject Power11 'arch_compat' requests when the host is
> > running in Power10 compatibility mode, returning -EINVAL early instead
> > of deferring the failure to the hypervisor.
> >
> > Suggested-by: Vaibhav Jain <vaibhav@linux.ibm.com>
> > Tested-by: Anushree Mathur <anushree.mathur@linux.ibm.com>
> > Signed-off-by: Amit Machhiwal <amachhiw@linux.ibm.com>
> > ---
> > arch/powerpc/kvm/book3s_hv.c | 12 ++++++++++++
> > 1 file changed, 12 insertions(+)
> >
> > diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c
> > index 61dbeea317f3..249d1f2e4e2c 100644
> > --- a/arch/powerpc/kvm/book3s_hv.c
> > +++ b/arch/powerpc/kvm/book3s_hv.c
> > @@ -446,7 +446,19 @@ static int kvmppc_set_arch_compat(struct kvm_vcpu *vcpu, u32 arch_compat)
> > guest_pcr_bit = PCR_ARCH_300;
> > break;
> > case PVR_ARCH_31:
> > + guest_pcr_bit = PCR_ARCH_31;
> > + break;
> > case PVR_ARCH_31_P11:
> > + /*
> > + * Need to check this for ISA 3.1, as Power10 and
> > + * Power11 share the same PCR. For any subsequent ISA
> > + * versions, this will be taken care of by the guest vs
> > + * host PCR comparison below.
> > + */
> > + if ((PVR_ARCH_31 & cur_cpu_spec->pvr_mask) ==
> > + cur_cpu_spec->pvr_value) {
> > + return -EINVAL;
> > + }
>
> Instead of the complicated check can we simply do this?
> if (!cpu_has_feature(CPU_FTR_P11_PVR))
> return -EINVAL;
Sure, I can base this check on CPU features.
Thanks,
Amit
>
> which means that if the Qemu is trying to set the arch_compat with P11
> PVR (arch_compat) and if the host cpu FTR doesn't support P11 PVR, then
> simply return -EINVAL
>
> -ritesh
>
^ permalink raw reply
* Re: [PATCH] powerpc/topology: Support coregroup in PowerNV
From: Srikar Dronamraju @ 2026-05-29 10:31 UTC (permalink / raw)
To: Christophe Leroy (CS GROUP)
Cc: linuxppc-dev, Madhavan Srinivasan, Michael Ellerman,
Nicholas Piggin, Naveen N Rao, skiboot, arbab, mahesh,
linux-kernel
In-Reply-To: <6387fb12-76f1-4503-8ac2-3ca777c0186e@kernel.org>
* Christophe Leroy (CS GROUP) <chleroy@kernel.org> [2026-05-29 09:58:25]:
> Le 24/05/2026 à 03:00, Srikar Dronamraju a écrit :
> > Coregroup support was only available on PowerPC on PowerVM LPARs.
> > However if firmware were to expose coregroup-id to the kernel, then
> > coregroup can even be supported on PowerNV too.
> >
Thanks Christophe for taking a look.
> > +extern int cpu_to_coregroup_id(int cpu);
> No new 'extern' for function prototypes (allthough it is only a move),
> that's pointless. checkpatch.pl --strict will likely complain about it.
>
Ok, will do..
> > #else
> > static inline int early_cpu_to_node(int cpu) { return 0; }
> > @@ -107,14 +108,6 @@ static inline void map_cpu_to_node(int cpu, int node) {}
> > static inline void unmap_cpu_from_node(unsigned long cpu) {}
> > #endif /* CONFIG_HOTPLUG_CPU */
> > #endif /* CONFIG_SMP */
> > -
> > -#endif /* CONFIG_NUMA */
> > -
> > -#if defined(CONFIG_NUMA) && defined(CONFIG_PPC_SPLPAR)
> > -void find_and_update_cpu_nid(int cpu);
> > -extern int cpu_to_coregroup_id(int cpu);
> > -#else
> > -static inline void find_and_update_cpu_nid(int cpu) {}
> > static inline int cpu_to_coregroup_id(int cpu)
> > {
> > #ifdef CONFIG_SMP
> > @@ -124,6 +117,12 @@ static inline int cpu_to_coregroup_id(int cpu)
> > #endif
> > }
> > +#endif /* CONFIG_NUMA */
> > +
> > +#if defined(CONFIG_NUMA) && defined(CONFIG_PPC_SPLPAR)
> > +void find_and_update_cpu_nid(int cpu);
> > +#else
> > +static inline void find_and_update_cpu_nid(int cpu) {}
> > #endif /* CONFIG_NUMA && CONFIG_PPC_SPLPAR */
> > #include <asm-generic/topology.h>
> > diff --git a/arch/powerpc/mm/numa.c b/arch/powerpc/mm/numa.c
> > index f4cf3ae036de..9b45cc9e1f27 100644
> > --- a/arch/powerpc/mm/numa.c
> > +++ b/arch/powerpc/mm/numa.c
> > @@ -432,7 +432,7 @@ static void __init initialize_form2_numa_distance_lookup_table(void)
> > static int __init find_primary_domain_index(void)
> > {
> > - int index;
> > + int index = -1;
> > struct device_node *root;
> > /*
> > @@ -502,12 +502,9 @@ static int __init find_primary_domain_index(void)
> > distance_ref_points_depth = MAX_DISTANCE_REF_POINTS;
> > }
> > - of_node_put(root);
> > - return index;
> > -
> > err:
> > of_node_put(root);
> > - return -1;
> > + return index;
> > }
> > static void __init get_n_mem_cells(int *n_addr_cells, int *n_size_cells)
> > @@ -892,12 +889,32 @@ static int __init numa_setup_drmem_lmb(struct drmem_lmb *lmb,
> > return 0;
> > }
> > +/*
> > + * If hierarchy extends beyond primary_domain_index + 1, then next
> > + * level corresponds to coregroup.
> > + */
> > +static int detect_and_enable_coregroup(const __be32 *associativity, int index)
> > +{
> > + if (!associativity)
> > + return -1;
>
> Even if 'index' is not 0 ?
In the hypothetical case, where we don't have the associativity for a CPU,
then which coregroup should we place this CPU. Placing it in arbitrary group
can confuse the scheduler and cause more issues.
Hence I guess, its better to return -1.
>
> > +
> > + if (!index) {
> > + index = of_read_number(associativity, 1);
> > +
> > + if (index > primary_domain_index + 1)
> > + coregroup_enabled = 1;
> > + else
> > + index = -1;
> > + }
> > + return index;
> > +}
>
> I'd prefer something more flat:
>
> if (index)
> return index;
>
> index = of_read_number(associativity, 1);
>
> if (index <= primary_domain_index + 1)
> return -1;
>
> coregroup_enabled = 1;
> return index;
>
Again, if a particular associativity doesn't have coregroup info, we are
probably better of disabling coregroup for all. Since we can't enable
coregroup for some CPUs and disable for other CPUs. And we can't add default
coregroup too since that would confuse the scheduler. For example 2 CPUs
from 2 nodes may end up being part of the same coregroup because of default
numbering. This will lead to topology_span_sane() cribbing.
May be we should also reset coregroup_enabled, whenever index is set to -1.
> > +
--
Thanks and Regards
Srikar Dronamraju
^ permalink raw reply
* Re: [PATCH 13/16] perf: Use sysfs_emit() for cpumask show callbacks
From: Robin Murphy @ 2026-05-29 11:05 UTC (permalink / raw)
To: Yury Norov, Andrew Morton, Rasmus Villemoes
Cc: Russell King, Frank Li, Sascha Hauer, Pengutronix Kernel Team,
Fabio Estevam, Madhavan Srinivasan, Michael Ellerman,
Nicholas Piggin, Christophe Leroy (CS GROUP), Peter Zijlstra,
Ingo Molnar, Arnaldo Carvalho de Melo, Namhyung Kim, Mark Rutland,
Alexander Shishkin, Jiri Olsa, Ian Rogers, Adrian Hunter,
James Clark, Thomas Gleixner, Borislav Petkov, Dave Hansen,
H. Peter Anvin, Rafael J. Wysocki, Len Brown, Greg Kroah-Hartman,
Danilo Krummrich, Chanwoo Choi, MyungJoo Ham, Kyungmin Park,
Heiko Stuebner, Lorenzo Pieralisi, Xu Yilun, Tom Rix,
Moritz Fischer, Yicong Yang, Jonathan Cameron, Dennis Dalessandro,
Jason Gunthorpe, Leon Romanovsky, Dan Williams, Vishal Verma,
Dave Jiang, Ira Weiny, Bjorn Helgaas, Shuai Xue, Will Deacon,
Jiucheng Xu, Neil Armstrong, Kevin Hilman, Jerome Brunet,
Martin Blumenstingl, Jing Zhang, Xu Yang, Linu Cherian,
Gowthami Thiagarajan, Ji Sheng Teoh, Khuong Dinh, Daniel Lezcano,
Zhang Rui, Lukasz Luba, Yury Norov, Kees Cook,
Thomas Weißschuh, Aboorva Devarajan, Ritesh Harjani (IBM),
Ilkka Koskinen, Besar Wicaksono, Ma Ke, Chengwen Feng,
linux-arm-kernel, imx, linux-kernel, linuxppc-dev,
linux-perf-users, linux-acpi, driver-core, linux-pm,
linux-rockchip, linux-fpga, linux-rdma, nvdimm, linux-pci,
linux-amlogic, linux-cxl, linux-arm-msm
In-Reply-To: <20260528183625.870813-14-ynorov@nvidia.com>
On 2026-05-28 7:36 pm, Yury Norov wrote:
> These callbacks are sysfs show paths.
>
> Use sysfs_emit() and cpumask_pr_args() to emit the masks.
>
> This prepares for removing cpumap_print_to_pagebuf().
TBH, looking at this diff I think it only shows the value of having a
helper to abstract the boilerplate...
I'm not sure I agree with the argument of removing something entirely
just because it may occasionally be misused, but could we at least have
something like:
#define sysfs_emit_cpumask(buf, mask) \
sysfs_emit((buf), "%*pbl\n", cpumask_pr_args(mask))
to save the mess in all the many places where the current
cpumap_print_to_pagebuf() usage _is_ entirely appropriate?
Thansk,
Robin.
> Signed-off-by: Yury Norov <ynorov@nvidia.com>
> ---
> drivers/perf/alibaba_uncore_drw_pmu.c | 2 +-
> drivers/perf/amlogic/meson_ddr_pmu_core.c | 2 +-
> drivers/perf/arm-cci.c | 2 +-
> drivers/perf/arm-ccn.c | 2 +-
> drivers/perf/arm-cmn.c | 2 +-
> drivers/perf/arm-ni.c | 2 +-
> drivers/perf/arm_cspmu/arm_cspmu.c | 2 +-
> drivers/perf/arm_dmc620_pmu.c | 4 ++--
> drivers/perf/arm_dsu_pmu.c | 2 +-
> drivers/perf/arm_pmu.c | 2 +-
> drivers/perf/arm_smmuv3_pmu.c | 2 +-
> drivers/perf/arm_spe_pmu.c | 2 +-
> drivers/perf/cxl_pmu.c | 2 +-
> drivers/perf/dwc_pcie_pmu.c | 2 +-
> drivers/perf/fsl_imx8_ddr_perf.c | 2 +-
> drivers/perf/fsl_imx9_ddr_perf.c | 2 +-
> drivers/perf/fujitsu_uncore_pmu.c | 2 +-
> drivers/perf/hisilicon/hisi_pcie_pmu.c | 2 +-
> drivers/perf/hisilicon/hisi_uncore_pmu.c | 2 +-
> drivers/perf/marvell_cn10k_ddr_pmu.c | 2 +-
> drivers/perf/marvell_cn10k_tad_pmu.c | 2 +-
> drivers/perf/marvell_pem_pmu.c | 2 +-
> drivers/perf/nvidia_t410_c2c_pmu.c | 2 +-
> drivers/perf/nvidia_t410_cmem_latency_pmu.c | 2 +-
> drivers/perf/qcom_l2_pmu.c | 2 +-
> drivers/perf/qcom_l3_pmu.c | 2 +-
> drivers/perf/starfive_starlink_pmu.c | 2 +-
> drivers/perf/thunderx2_pmu.c | 2 +-
> drivers/perf/xgene_pmu.c | 2 +-
> kernel/events/core.c | 2 +-
> 30 files changed, 31 insertions(+), 31 deletions(-)
>
> diff --git a/drivers/perf/alibaba_uncore_drw_pmu.c b/drivers/perf/alibaba_uncore_drw_pmu.c
> index ac49d3b2dad6..74786a5dd6a2 100644
> --- a/drivers/perf/alibaba_uncore_drw_pmu.c
> +++ b/drivers/perf/alibaba_uncore_drw_pmu.c
> @@ -221,7 +221,7 @@ static ssize_t ali_drw_pmu_cpumask_show(struct device *dev,
> {
> struct ali_drw_pmu *drw_pmu = to_ali_drw_pmu(dev_get_drvdata(dev));
>
> - return cpumap_print_to_pagebuf(true, buf, cpumask_of(drw_pmu->cpu));
> + return sysfs_emit(buf, "%*pbl\n", cpumask_pr_args(cpumask_of(drw_pmu->cpu)));
> }
>
> static struct device_attribute ali_drw_pmu_cpumask_attr =
> diff --git a/drivers/perf/amlogic/meson_ddr_pmu_core.c b/drivers/perf/amlogic/meson_ddr_pmu_core.c
> index c1e755c356a3..f614aa3434a5 100644
> --- a/drivers/perf/amlogic/meson_ddr_pmu_core.c
> +++ b/drivers/perf/amlogic/meson_ddr_pmu_core.c
> @@ -191,7 +191,7 @@ static ssize_t meson_ddr_perf_cpumask_show(struct device *dev,
> {
> struct ddr_pmu *pmu = dev_get_drvdata(dev);
>
> - return cpumap_print_to_pagebuf(true, buf, cpumask_of(pmu->cpu));
> + return sysfs_emit(buf, "%*pbl\n", cpumask_pr_args(cpumask_of(pmu->cpu)));
> }
>
> static struct device_attribute meson_ddr_perf_cpumask_attr =
> diff --git a/drivers/perf/arm-cci.c b/drivers/perf/arm-cci.c
> index 1cc3214d6b6d..f0ef0a679e74 100644
> --- a/drivers/perf/arm-cci.c
> +++ b/drivers/perf/arm-cci.c
> @@ -1351,7 +1351,7 @@ static ssize_t pmu_cpumask_attr_show(struct device *dev,
> struct pmu *pmu = dev_get_drvdata(dev);
> struct cci_pmu *cci_pmu = to_cci_pmu(pmu);
>
> - return cpumap_print_to_pagebuf(true, buf, cpumask_of(cci_pmu->cpu));
> + return sysfs_emit(buf, "%*pbl\n", cpumask_pr_args(cpumask_of(cci_pmu->cpu)));
> }
>
> static struct device_attribute pmu_cpumask_attr =
> diff --git a/drivers/perf/arm-ccn.c b/drivers/perf/arm-ccn.c
> index 8af3563fdf60..d5dcb4280434 100644
> --- a/drivers/perf/arm-ccn.c
> +++ b/drivers/perf/arm-ccn.c
> @@ -538,7 +538,7 @@ static ssize_t arm_ccn_pmu_cpumask_show(struct device *dev,
> {
> struct arm_ccn *ccn = pmu_to_arm_ccn(dev_get_drvdata(dev));
>
> - return cpumap_print_to_pagebuf(true, buf, cpumask_of(ccn->dt.cpu));
> + return sysfs_emit(buf, "%*pbl\n", cpumask_pr_args(cpumask_of(ccn->dt.cpu)));
> }
>
> static struct device_attribute arm_ccn_pmu_cpumask_attr =
> diff --git a/drivers/perf/arm-cmn.c b/drivers/perf/arm-cmn.c
> index f5305c8fdca4..2187ba763b72 100644
> --- a/drivers/perf/arm-cmn.c
> +++ b/drivers/perf/arm-cmn.c
> @@ -1326,7 +1326,7 @@ static ssize_t arm_cmn_cpumask_show(struct device *dev,
> {
> struct arm_cmn *cmn = to_cmn(dev_get_drvdata(dev));
>
> - return cpumap_print_to_pagebuf(true, buf, cpumask_of(cmn->cpu));
> + return sysfs_emit(buf, "%*pbl\n", cpumask_pr_args(cpumask_of(cmn->cpu)));
> }
>
> static struct device_attribute arm_cmn_cpumask_attr =
> diff --git a/drivers/perf/arm-ni.c b/drivers/perf/arm-ni.c
> index 66858c65215d..03a1c6bf9223 100644
> --- a/drivers/perf/arm-ni.c
> +++ b/drivers/perf/arm-ni.c
> @@ -239,7 +239,7 @@ static ssize_t arm_ni_cpumask_show(struct device *dev,
> {
> struct arm_ni *ni = cd_to_ni(pmu_to_cd(dev_get_drvdata(dev)));
>
> - return cpumap_print_to_pagebuf(true, buf, cpumask_of(ni->cpu));
> + return sysfs_emit(buf, "%*pbl\n", cpumask_pr_args(cpumask_of(ni->cpu)));
> }
>
> static struct device_attribute arm_ni_cpumask_attr =
> diff --git a/drivers/perf/arm_cspmu/arm_cspmu.c b/drivers/perf/arm_cspmu/arm_cspmu.c
> index 80fb314d5135..e6292021f653 100644
> --- a/drivers/perf/arm_cspmu/arm_cspmu.c
> +++ b/drivers/perf/arm_cspmu/arm_cspmu.c
> @@ -305,7 +305,7 @@ static ssize_t arm_cspmu_cpumask_show(struct device *dev,
> default:
> return 0;
> }
> - return cpumap_print_to_pagebuf(true, buf, cpumask);
> + return sysfs_emit(buf, "%*pbl\n", cpumask_pr_args(cpumask));
> }
>
> static struct attribute *arm_cspmu_cpumask_attrs[] = {
> diff --git a/drivers/perf/arm_dmc620_pmu.c b/drivers/perf/arm_dmc620_pmu.c
> index 4f6b196160f8..467147a05eec 100644
> --- a/drivers/perf/arm_dmc620_pmu.c
> +++ b/drivers/perf/arm_dmc620_pmu.c
> @@ -237,8 +237,8 @@ static ssize_t dmc620_pmu_cpumask_show(struct device *dev,
> {
> struct dmc620_pmu *dmc620_pmu = to_dmc620_pmu(dev_get_drvdata(dev));
>
> - return cpumap_print_to_pagebuf(true, buf,
> - cpumask_of(dmc620_pmu->irq->cpu));
> + return sysfs_emit(buf, "%*pbl\n",
> + cpumask_pr_args(cpumask_of(dmc620_pmu->irq->cpu)));
> }
>
> static struct device_attribute dmc620_pmu_cpumask_attr =
> diff --git a/drivers/perf/arm_dsu_pmu.c b/drivers/perf/arm_dsu_pmu.c
> index 32b0dd7c693b..bcbd19e075a5 100644
> --- a/drivers/perf/arm_dsu_pmu.c
> +++ b/drivers/perf/arm_dsu_pmu.c
> @@ -157,7 +157,7 @@ static ssize_t dsu_pmu_cpumask_show(struct device *dev,
> default:
> return 0;
> }
> - return cpumap_print_to_pagebuf(true, buf, cpumask);
> + return sysfs_emit(buf, "%*pbl\n", cpumask_pr_args(cpumask));
> }
>
> static struct attribute *dsu_pmu_format_attrs[] = {
> diff --git a/drivers/perf/arm_pmu.c b/drivers/perf/arm_pmu.c
> index 939bcbd433aa..51ab6cc52ca0 100644
> --- a/drivers/perf/arm_pmu.c
> +++ b/drivers/perf/arm_pmu.c
> @@ -570,7 +570,7 @@ static ssize_t cpus_show(struct device *dev,
> struct device_attribute *attr, char *buf)
> {
> struct arm_pmu *armpmu = to_arm_pmu(dev_get_drvdata(dev));
> - return cpumap_print_to_pagebuf(true, buf, &armpmu->supported_cpus);
> + return sysfs_emit(buf, "%*pbl\n", cpumask_pr_args(&armpmu->supported_cpus));
> }
>
> static DEVICE_ATTR_RO(cpus);
> diff --git a/drivers/perf/arm_smmuv3_pmu.c b/drivers/perf/arm_smmuv3_pmu.c
> index 621f02a7f43b..8ce34e6bb82b 100644
> --- a/drivers/perf/arm_smmuv3_pmu.c
> +++ b/drivers/perf/arm_smmuv3_pmu.c
> @@ -537,7 +537,7 @@ static ssize_t smmu_pmu_cpumask_show(struct device *dev,
> {
> struct smmu_pmu *smmu_pmu = to_smmu_pmu(dev_get_drvdata(dev));
>
> - return cpumap_print_to_pagebuf(true, buf, cpumask_of(smmu_pmu->on_cpu));
> + return sysfs_emit(buf, "%*pbl\n", cpumask_pr_args(cpumask_of(smmu_pmu->on_cpu)));
> }
>
> static struct device_attribute smmu_pmu_cpumask_attr =
> diff --git a/drivers/perf/arm_spe_pmu.c b/drivers/perf/arm_spe_pmu.c
> index dbd0da111639..9f786fd48cdd 100644
> --- a/drivers/perf/arm_spe_pmu.c
> +++ b/drivers/perf/arm_spe_pmu.c
> @@ -343,7 +343,7 @@ static ssize_t cpumask_show(struct device *dev,
> {
> struct arm_spe_pmu *spe_pmu = dev_get_drvdata(dev);
>
> - return cpumap_print_to_pagebuf(true, buf, &spe_pmu->supported_cpus);
> + return sysfs_emit(buf, "%*pbl\n", cpumask_pr_args(&spe_pmu->supported_cpus));
> }
> static DEVICE_ATTR_RO(cpumask);
>
> diff --git a/drivers/perf/cxl_pmu.c b/drivers/perf/cxl_pmu.c
> index 68a54d97d2a8..0735eb33f5f3 100644
> --- a/drivers/perf/cxl_pmu.c
> +++ b/drivers/perf/cxl_pmu.c
> @@ -493,7 +493,7 @@ static ssize_t cpumask_show(struct device *dev, struct device_attribute *attr,
> {
> struct cxl_pmu_info *info = dev_get_drvdata(dev);
>
> - return cpumap_print_to_pagebuf(true, buf, cpumask_of(info->on_cpu));
> + return sysfs_emit(buf, "%*pbl\n", cpumask_pr_args(cpumask_of(info->on_cpu)));
> }
> static DEVICE_ATTR_RO(cpumask);
>
> diff --git a/drivers/perf/dwc_pcie_pmu.c b/drivers/perf/dwc_pcie_pmu.c
> index 5385401fa9cf..291e776d6f6a 100644
> --- a/drivers/perf/dwc_pcie_pmu.c
> +++ b/drivers/perf/dwc_pcie_pmu.c
> @@ -117,7 +117,7 @@ static ssize_t cpumask_show(struct device *dev,
> {
> struct dwc_pcie_pmu *pcie_pmu = to_dwc_pcie_pmu(dev_get_drvdata(dev));
>
> - return cpumap_print_to_pagebuf(true, buf, cpumask_of(pcie_pmu->on_cpu));
> + return sysfs_emit(buf, "%*pbl\n", cpumask_pr_args(cpumask_of(pcie_pmu->on_cpu)));
> }
> static DEVICE_ATTR_RO(cpumask);
>
> diff --git a/drivers/perf/fsl_imx8_ddr_perf.c b/drivers/perf/fsl_imx8_ddr_perf.c
> index bcdf5575d71c..3760ebe02674 100644
> --- a/drivers/perf/fsl_imx8_ddr_perf.c
> +++ b/drivers/perf/fsl_imx8_ddr_perf.c
> @@ -237,7 +237,7 @@ static ssize_t ddr_perf_cpumask_show(struct device *dev,
> {
> struct ddr_pmu *pmu = dev_get_drvdata(dev);
>
> - return cpumap_print_to_pagebuf(true, buf, cpumask_of(pmu->cpu));
> + return sysfs_emit(buf, "%*pbl\n", cpumask_pr_args(cpumask_of(pmu->cpu)));
> }
>
> static struct device_attribute ddr_perf_cpumask_attr =
> diff --git a/drivers/perf/fsl_imx9_ddr_perf.c b/drivers/perf/fsl_imx9_ddr_perf.c
> index 7050b48c0467..6fee5eb5087a 100644
> --- a/drivers/perf/fsl_imx9_ddr_perf.c
> +++ b/drivers/perf/fsl_imx9_ddr_perf.c
> @@ -159,7 +159,7 @@ static ssize_t ddr_perf_cpumask_show(struct device *dev,
> {
> struct ddr_pmu *pmu = dev_get_drvdata(dev);
>
> - return cpumap_print_to_pagebuf(true, buf, cpumask_of(pmu->cpu));
> + return sysfs_emit(buf, "%*pbl\n", cpumask_pr_args(cpumask_of(pmu->cpu)));
> }
>
> static struct device_attribute ddr_perf_cpumask_attr =
> diff --git a/drivers/perf/fujitsu_uncore_pmu.c b/drivers/perf/fujitsu_uncore_pmu.c
> index c3c6f56474ad..a07877632d53 100644
> --- a/drivers/perf/fujitsu_uncore_pmu.c
> +++ b/drivers/perf/fujitsu_uncore_pmu.c
> @@ -374,7 +374,7 @@ static ssize_t cpumask_show(struct device *dev,
> {
> struct uncore_pmu *uncorepmu = to_uncore_pmu(dev_get_drvdata(dev));
>
> - return cpumap_print_to_pagebuf(true, buf, cpumask_of(uncorepmu->cpu));
> + return sysfs_emit(buf, "%*pbl\n", cpumask_pr_args(cpumask_of(uncorepmu->cpu)));
> }
> static DEVICE_ATTR_RO(cpumask);
>
> diff --git a/drivers/perf/hisilicon/hisi_pcie_pmu.c b/drivers/perf/hisilicon/hisi_pcie_pmu.c
> index c5394d007b61..0f55d871c67e 100644
> --- a/drivers/perf/hisilicon/hisi_pcie_pmu.c
> +++ b/drivers/perf/hisilicon/hisi_pcie_pmu.c
> @@ -121,7 +121,7 @@ static ssize_t cpumask_show(struct device *dev, struct device_attribute *attr, c
> {
> struct hisi_pcie_pmu *pcie_pmu = to_pcie_pmu(dev_get_drvdata(dev));
>
> - return cpumap_print_to_pagebuf(true, buf, cpumask_of(pcie_pmu->on_cpu));
> + return sysfs_emit(buf, "%*pbl\n", cpumask_pr_args(cpumask_of(pcie_pmu->on_cpu)));
> }
> static DEVICE_ATTR_RO(cpumask);
>
> diff --git a/drivers/perf/hisilicon/hisi_uncore_pmu.c b/drivers/perf/hisilicon/hisi_uncore_pmu.c
> index de71dcf11653..0ff2fdf4b3e2 100644
> --- a/drivers/perf/hisilicon/hisi_uncore_pmu.c
> +++ b/drivers/perf/hisilicon/hisi_uncore_pmu.c
> @@ -56,7 +56,7 @@ static ssize_t hisi_associated_cpus_sysfs_show(struct device *dev,
> {
> struct hisi_pmu *hisi_pmu = to_hisi_pmu(dev_get_drvdata(dev));
>
> - return cpumap_print_to_pagebuf(true, buf, &hisi_pmu->associated_cpus);
> + return sysfs_emit(buf, "%*pbl\n", cpumask_pr_args(&hisi_pmu->associated_cpus));
> }
> static DEVICE_ATTR(associated_cpus, 0444, hisi_associated_cpus_sysfs_show, NULL);
>
> diff --git a/drivers/perf/marvell_cn10k_ddr_pmu.c b/drivers/perf/marvell_cn10k_ddr_pmu.c
> index 72ac17efd846..8681e8715cb3 100644
> --- a/drivers/perf/marvell_cn10k_ddr_pmu.c
> +++ b/drivers/perf/marvell_cn10k_ddr_pmu.c
> @@ -364,7 +364,7 @@ static ssize_t cn10k_ddr_perf_cpumask_show(struct device *dev,
> {
> struct cn10k_ddr_pmu *pmu = dev_get_drvdata(dev);
>
> - return cpumap_print_to_pagebuf(true, buf, cpumask_of(pmu->cpu));
> + return sysfs_emit(buf, "%*pbl\n", cpumask_pr_args(cpumask_of(pmu->cpu)));
> }
>
> static struct device_attribute cn10k_ddr_perf_cpumask_attr =
> diff --git a/drivers/perf/marvell_cn10k_tad_pmu.c b/drivers/perf/marvell_cn10k_tad_pmu.c
> index 51ccb0befa05..54909d0031b7 100644
> --- a/drivers/perf/marvell_cn10k_tad_pmu.c
> +++ b/drivers/perf/marvell_cn10k_tad_pmu.c
> @@ -258,7 +258,7 @@ static ssize_t tad_pmu_cpumask_show(struct device *dev,
> {
> struct tad_pmu *tad_pmu = to_tad_pmu(dev_get_drvdata(dev));
>
> - return cpumap_print_to_pagebuf(true, buf, cpumask_of(tad_pmu->cpu));
> + return sysfs_emit(buf, "%*pbl\n", cpumask_pr_args(cpumask_of(tad_pmu->cpu)));
> }
>
> static DEVICE_ATTR(cpumask, 0444, tad_pmu_cpumask_show, NULL);
> diff --git a/drivers/perf/marvell_pem_pmu.c b/drivers/perf/marvell_pem_pmu.c
> index 29fbcd1848e4..cf1d8cdb1318 100644
> --- a/drivers/perf/marvell_pem_pmu.c
> +++ b/drivers/perf/marvell_pem_pmu.c
> @@ -164,7 +164,7 @@ static ssize_t pem_perf_cpumask_show(struct device *dev,
> {
> struct pem_pmu *pmu = dev_get_drvdata(dev);
>
> - return cpumap_print_to_pagebuf(true, buf, cpumask_of(pmu->cpu));
> + return sysfs_emit(buf, "%*pbl\n", cpumask_pr_args(cpumask_of(pmu->cpu)));
> }
>
> static struct device_attribute pem_perf_cpumask_attr =
> diff --git a/drivers/perf/nvidia_t410_c2c_pmu.c b/drivers/perf/nvidia_t410_c2c_pmu.c
> index 411987153ff3..bff875f4f625 100644
> --- a/drivers/perf/nvidia_t410_c2c_pmu.c
> +++ b/drivers/perf/nvidia_t410_c2c_pmu.c
> @@ -658,7 +658,7 @@ static ssize_t nv_c2c_pmu_cpumask_show(struct device *dev,
> default:
> return 0;
> }
> - return cpumap_print_to_pagebuf(true, buf, cpumask);
> + return sysfs_emit(buf, "%*pbl\n", cpumask_pr_args(cpumask));
> }
>
> #define NV_C2C_PMU_CPUMASK_ATTR(_name, _config) \
> diff --git a/drivers/perf/nvidia_t410_cmem_latency_pmu.c b/drivers/perf/nvidia_t410_cmem_latency_pmu.c
> index acb8f5571522..6c8e41598ec1 100644
> --- a/drivers/perf/nvidia_t410_cmem_latency_pmu.c
> +++ b/drivers/perf/nvidia_t410_cmem_latency_pmu.c
> @@ -501,7 +501,7 @@ static ssize_t cmem_lat_pmu_cpumask_show(struct device *dev,
> default:
> return 0;
> }
> - return cpumap_print_to_pagebuf(true, buf, cpumask);
> + return sysfs_emit(buf, "%*pbl\n", cpumask_pr_args(cpumask));
> }
>
> #define NV_PMU_CPUMASK_ATTR(_name, _config) \
> diff --git a/drivers/perf/qcom_l2_pmu.c b/drivers/perf/qcom_l2_pmu.c
> index ea8c85729937..c0c522b10b72 100644
> --- a/drivers/perf/qcom_l2_pmu.c
> +++ b/drivers/perf/qcom_l2_pmu.c
> @@ -638,7 +638,7 @@ static ssize_t l2_cache_pmu_cpumask_show(struct device *dev,
> {
> struct l2cache_pmu *l2cache_pmu = to_l2cache_pmu(dev_get_drvdata(dev));
>
> - return cpumap_print_to_pagebuf(true, buf, &l2cache_pmu->cpumask);
> + return sysfs_emit(buf, "%*pbl\n", cpumask_pr_args(&l2cache_pmu->cpumask));
> }
>
> static struct device_attribute l2_cache_pmu_cpumask_attr =
> diff --git a/drivers/perf/qcom_l3_pmu.c b/drivers/perf/qcom_l3_pmu.c
> index 66e6cabd6fff..c8d259dd1f80 100644
> --- a/drivers/perf/qcom_l3_pmu.c
> +++ b/drivers/perf/qcom_l3_pmu.c
> @@ -663,7 +663,7 @@ static ssize_t cpumask_show(struct device *dev,
> {
> struct l3cache_pmu *l3pmu = to_l3cache_pmu(dev_get_drvdata(dev));
>
> - return cpumap_print_to_pagebuf(true, buf, &l3pmu->cpumask);
> + return sysfs_emit(buf, "%*pbl\n", cpumask_pr_args(&l3pmu->cpumask));
> }
>
> static DEVICE_ATTR_RO(cpumask);
> diff --git a/drivers/perf/starfive_starlink_pmu.c b/drivers/perf/starfive_starlink_pmu.c
> index 964897c2baa9..222a0a34e211 100644
> --- a/drivers/perf/starfive_starlink_pmu.c
> +++ b/drivers/perf/starfive_starlink_pmu.c
> @@ -131,7 +131,7 @@ cpumask_show(struct device *dev, struct device_attribute *attr, char *buf)
> {
> struct starlink_pmu *starlink_pmu = to_starlink_pmu(dev_get_drvdata(dev));
>
> - return cpumap_print_to_pagebuf(true, buf, &starlink_pmu->cpumask);
> + return sysfs_emit(buf, "%*pbl\n", cpumask_pr_args(&starlink_pmu->cpumask));
> }
>
> static DEVICE_ATTR_RO(cpumask);
> diff --git a/drivers/perf/thunderx2_pmu.c b/drivers/perf/thunderx2_pmu.c
> index 6ed4707bd6bb..a69c02d2d874 100644
> --- a/drivers/perf/thunderx2_pmu.c
> +++ b/drivers/perf/thunderx2_pmu.c
> @@ -254,7 +254,7 @@ static ssize_t cpumask_show(struct device *dev, struct device_attribute *attr,
> struct tx2_uncore_pmu *tx2_pmu;
>
> tx2_pmu = pmu_to_tx2_pmu(dev_get_drvdata(dev));
> - return cpumap_print_to_pagebuf(true, buf, cpumask_of(tx2_pmu->cpu));
> + return sysfs_emit(buf, "%*pbl\n", cpumask_pr_args(cpumask_of(tx2_pmu->cpu)));
> }
> static DEVICE_ATTR_RO(cpumask);
>
> diff --git a/drivers/perf/xgene_pmu.c b/drivers/perf/xgene_pmu.c
> index 33b5497bdc06..e9e4871db08d 100644
> --- a/drivers/perf/xgene_pmu.c
> +++ b/drivers/perf/xgene_pmu.c
> @@ -595,7 +595,7 @@ static ssize_t cpumask_show(struct device *dev,
> {
> struct xgene_pmu_dev *pmu_dev = to_pmu_dev(dev_get_drvdata(dev));
>
> - return cpumap_print_to_pagebuf(true, buf, &pmu_dev->parent->cpu);
> + return sysfs_emit(buf, "%*pbl\n", cpumask_pr_args(&pmu_dev->parent->cpu));
> }
>
> static DEVICE_ATTR_RO(cpumask);
> diff --git a/kernel/events/core.c b/kernel/events/core.c
> index 7935d5663944..61689d348abd 100644
> --- a/kernel/events/core.c
> +++ b/kernel/events/core.c
> @@ -12657,7 +12657,7 @@ static ssize_t cpumask_show(struct device *dev, struct device_attribute *attr,
> struct cpumask *mask = perf_scope_cpumask(pmu->scope);
>
> if (mask)
> - return cpumap_print_to_pagebuf(true, buf, mask);
> + return sysfs_emit(buf, "%*pbl\n", cpumask_pr_args(mask));
> return 0;
> }
>
^ permalink raw reply
* Re: [PATCH v6 09/15] arm64: Move fixmap and kasan page tables to end of kernel image
From: Ard Biesheuvel @ 2026-05-29 11:19 UTC (permalink / raw)
To: Kevin Brodsky, Ard Biesheuvel, linux-arm-kernel
Cc: linux-kernel, Will Deacon, Catalin Marinas, Mark Rutland,
Ryan Roberts, Anshuman Khandual, Liz Prucka, Seth Jenkins,
Kees Cook, Mike Rapoport, David Hildenbrand, Andrew Morton,
Jann Horn, linux-mm, linux-hardening, linuxppc-dev, linux-sh
In-Reply-To: <2a6f9f05-ac57-4ef8-9328-74cc8ccfea16@arm.com>
On Fri, 29 May 2026, at 10:27, Kevin Brodsky wrote:
> On 26/05/2026 19:58, Ard Biesheuvel wrote:
>> From: Ard Biesheuvel <ardb@kernel.org>
>>
>> Move the fixmap and kasan page tables out of the BSS section, and place
>> them at the end of the image, right before the init_pg_dir section where
>> some of the other statically allocated page tables live.
>>
>> These page tables are currently the only data objects in vmlinux that
>> are meant to be accessed via the kernel image's linear alias, and so
>> placing them together allows the remainder of the data/bss section to be
>> remapped read-only or unmapped entirely.
>>
>> Reviewed-by: Kevin Brodsky <kevin.brodsky@arm.com>
>> Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
>> ---
>> arch/arm64/include/asm/mmu.h | 2 ++
>> arch/arm64/kernel/vmlinux.lds.S | 8 +++++++-
>> arch/arm64/mm/fixmap.c | 6 +++---
>> arch/arm64/mm/kasan_init.c | 2 +-
>> 4 files changed, 13 insertions(+), 5 deletions(-)
>>
>> diff --git a/arch/arm64/include/asm/mmu.h b/arch/arm64/include/asm/mmu.h
>> index 5e1211c540ab..fb95754f2876 100644
>> --- a/arch/arm64/include/asm/mmu.h
>> +++ b/arch/arm64/include/asm/mmu.h
>> @@ -13,6 +13,8 @@
>>
>> #ifndef __ASSEMBLER__
>>
>> +#define __pgtbl_bss __section(".pgdir.bss") __aligned(PAGE_SIZE)
>> +
>> #include <linux/refcount.h>
>> #include <asm/cpufeature.h>
>>
>> diff --git a/arch/arm64/kernel/vmlinux.lds.S b/arch/arm64/kernel/vmlinux.lds.S
>> index e1ac876200a3..2b0ebfb30c63 100644
>> --- a/arch/arm64/kernel/vmlinux.lds.S
>> +++ b/arch/arm64/kernel/vmlinux.lds.S
>> @@ -349,9 +349,15 @@ SECTIONS
>> _edata = .;
>>
>> /* start of zero-init region */
>> - BSS_SECTION(SBSS_ALIGN, 0, 0)
>> + BSS_SECTION(SBSS_ALIGN, 0, PAGE_SIZE)
>> __pi___bss_start = __bss_start;
>>
>> + /* fixmap BSS starts here - preceding data/BSS is omitted from the linear map */
>> + .pgdir.bss (NOLOAD) : ALIGN(PAGE_SIZE) {
>
> Do we actually need the NOLOAD type here?
Yes, otherwise it is emitted as PROGBITS, resulting in all of BSS to be
emitted into Image.
^ permalink raw reply
* RE: Re: [PATCH] ASoC: fsl_sai: Fix 32 slots TDM broken by integer shift UB in xMR write
From: Chancel Liu @ 2026-05-29 11:41 UTC (permalink / raw)
To: Christophe Leroy (CS GROUP), shengjiu.wang@gmail.com,
Xiubo.Lee@gmail.com, festevam@gmail.com, nicoleotsuka@gmail.com,
lgirdwood@gmail.com, broonie@kernel.org, perex@perex.cz,
tiwai@suse.com
Cc: linux-kernel@vger.kernel.org, linuxppc-dev@lists.ozlabs.org,
linux-sound@vger.kernel.org, stable@vger.kernel.org,
Chancel Liu (OSS)
In-Reply-To: <c5591024-0d8e-4c41-9e35-56689fa94731@kernel.org>
> > When configuring 32 slots TDM (channels == slots == 32), the xMR (Mask
> > Register) write used:
> > ~0UL - ((1 << min(channels, slots)) - 1)
> >
> > The literal '1' is a signed 32-bit int. Shifting it by 32 positions is
> > undefined behaviour which may set this register to 0xFFFFFFFF, masking
> > all 32 slots.
> >
> > Use 1ULL so the shift is carried out in 64 bits. For 32 slots this
> > produces a zero mask after truncation to the 32-bit register:
> > ~0ULL - ((1ULL << 32) - 1)
> > = 0xFFFFFFFFFFFFFFFF - (0x100000000 - 1)
> > = 0xFFFFFFFFFFFFFFFF - 0xFFFFFFFF
> > = 0xFFFFFFFF00000000
> > -> Truncates to 0x00000000
> > Behaviour for fewer than 32 slots is unchanged.
>
> Why not use macro GENMASK_U32() instead ?
>
Thanks for this reminder. OK, I will switch to the clearer and safer
GENMASK_U32() macro:
regmap_write(sai->regmap, FSL_SAI_xMR(tx),
~GENMASK_U32(min(channels, slots) - 1, 0));
Regards,
Chancel Liu
> >
> > Fixes: 770f58d7d2c5 ("ASoC: fsl_sai: Support multiple data channel
> > enable bits")
> > Cc: stable@vger.kernel.org
> > Signed-off-by: Chancel Liu <chancel.liu@nxp.com>
> > ---
> > sound/soc/fsl/fsl_sai.c | 2 +-
> > 1 file changed, 1 insertion(+), 1 deletion(-)
> >
> > diff --git a/sound/soc/fsl/fsl_sai.c b/sound/soc/fsl/fsl_sai.c index
> > d6dd95680892..821e3bd51b6e 100644
> > --- a/sound/soc/fsl/fsl_sai.c
> > +++ b/sound/soc/fsl/fsl_sai.c
> > @@ -797,7 +797,7 @@ static int fsl_sai_hw_params(struct
> snd_pcm_substream *substream,
> > FSL_SAI_CR4_FSD_MSTR,
> > FSL_SAI_CR4_FSD_MSTR);
> >
> > regmap_write(sai->regmap, FSL_SAI_xMR(tx),
> > - ~0UL - ((1 << min(channels, slots)) - 1));
> > + ~0ULL - ((1ULL << min(channels, slots)) - 1));
> >
> > return 0;
> > }
^ permalink raw reply
* Re: [PATCH v6 15/15] arm64: mm: Unmap kernel data/bss entirely from the linear map
From: Ard Biesheuvel @ 2026-05-29 11:48 UTC (permalink / raw)
To: Kevin Brodsky, Ard Biesheuvel, linux-arm-kernel
Cc: linux-kernel, Will Deacon, Catalin Marinas, Mark Rutland,
Ryan Roberts, Anshuman Khandual, Liz Prucka, Seth Jenkins,
Kees Cook, Mike Rapoport, David Hildenbrand, Andrew Morton,
Jann Horn, linux-mm, linux-hardening, linuxppc-dev, linux-sh
In-Reply-To: <32458c49-0e3c-4d27-b1cf-0e2d7ee0273d@arm.com>
On Fri, 29 May 2026, at 10:49, Kevin Brodsky wrote:
> On 29/05/2026 10:34, Ard Biesheuvel wrote:
>> On Fri, 29 May 2026, at 10:29, Kevin Brodsky wrote:
>>> On 26/05/2026 19:59, Ard Biesheuvel wrote:
>>>> From: Ard Biesheuvel <ardb@kernel.org>
>>>>
>>>> The linear aliases of the kernel text and rodata are mapped read-only in
>>>> the linear map as well. Given that the contents of these regions are
>>>> mostly identical to the version in the loadable image, mapping them
>>>> read-only and leaving their contents visible is a reasonable hardening
>>>> measure.
>>>>
>>>> Data and bss, however, are now also mapped read-only but the contents of
>>>> these regions are more likely to contain data that we'd rather not leak.
>>>> So let's unmap these entirely in the linear map when the kernel is
>>>> running normally.
>>>>
>>>> When going into hibernation or waking up from it, these regions need to
>>>> be mapped, so map the region initially, and toggle the valid bit so
>>>> map/unmap the region as needed. (While the hibernation snapshot logic
>>>> seems able to map inaccessible pages as needed, it currently disregards
>>>> non-present pages entirely.)
>>> I'm not sure I understand this, is there something wrong with the
>>> kernel_page_present() check in safe_copy_page()?
>>>
>> No. If the hibernate code decides to snapshot a page and it is not mapped,
>> safe_copy_page() will do the right thing and map it on demand.
>>
>> The problem is that pages belonging to the kernel image are marked as
>> PageReserved, and so the hibernation logic will not even consider the
>> pages for snapshotting if they are not mapped.
>
> Right I see the check in saveable_page() now. Maybe it would be worth
> spelling it out in the commit message (hibernation logic ignores
> non-present Reserved pages).
>
Yeah it's there but clearly not spelled out sufficiently :-)
^ permalink raw reply
* Re: [PATCH 13/16] perf: Use sysfs_emit() for cpumask show callbacks
From: David Laight @ 2026-05-29 12:06 UTC (permalink / raw)
To: Robin Murphy
Cc: Yury Norov, Andrew Morton, Rasmus Villemoes, Russell King,
Frank Li, Sascha Hauer, Pengutronix Kernel Team, Fabio Estevam,
Madhavan Srinivasan, Michael Ellerman, Nicholas Piggin,
Christophe Leroy (CS GROUP), Peter Zijlstra, Ingo Molnar,
Arnaldo Carvalho de Melo, Namhyung Kim, Mark Rutland,
Alexander Shishkin, Jiri Olsa, Ian Rogers, Adrian Hunter,
James Clark, Thomas Gleixner, Borislav Petkov, Dave Hansen,
H. Peter Anvin, Rafael J. Wysocki, Len Brown, Greg Kroah-Hartman,
Danilo Krummrich, Chanwoo Choi, MyungJoo Ham, Kyungmin Park,
Heiko Stuebner, Lorenzo Pieralisi, Xu Yilun, Tom Rix,
Moritz Fischer, Yicong Yang, Jonathan Cameron, Dennis Dalessandro,
Jason Gunthorpe, Leon Romanovsky, Dan Williams, Vishal Verma,
Dave Jiang, Ira Weiny, Bjorn Helgaas, Shuai Xue, Will Deacon,
Jiucheng Xu, Neil Armstrong, Kevin Hilman, Jerome Brunet,
Martin Blumenstingl, Jing Zhang, Xu Yang, Linu Cherian,
Gowthami Thiagarajan, Ji Sheng Teoh, Khuong Dinh, Daniel Lezcano,
Zhang Rui, Lukasz Luba, Yury Norov, Kees Cook,
Thomas Weißschuh, Aboorva Devarajan, Ritesh Harjani (IBM),
Ilkka Koskinen, Besar Wicaksono, Ma Ke, Chengwen Feng,
linux-arm-kernel, imx, linux-kernel, linuxppc-dev,
linux-perf-users, linux-acpi, driver-core, linux-pm,
linux-rockchip, linux-fpga, linux-rdma, nvdimm, linux-pci,
linux-amlogic, linux-cxl, linux-arm-msm
In-Reply-To: <7e980b99-1e4e-408b-8ebd-4d28116e7ad5@arm.com>
On Fri, 29 May 2026 12:05:08 +0100
Robin Murphy <robin.murphy@arm.com> wrote:
> On 2026-05-28 7:36 pm, Yury Norov wrote:
> > These callbacks are sysfs show paths.
> >
> > Use sysfs_emit() and cpumask_pr_args() to emit the masks.
> >
> > This prepares for removing cpumap_print_to_pagebuf().
>
> TBH, looking at this diff I think it only shows the value of having a
> helper to abstract the boilerplate...
>
> I'm not sure I agree with the argument of removing something entirely
> just because it may occasionally be misused, but could we at least have
> something like:
>
> #define sysfs_emit_cpumask(buf, mask) \
> sysfs_emit((buf), "%*pbl\n", cpumask_pr_args(mask))
>
> to save the mess in all the many places where the current
> cpumap_print_to_pagebuf() usage _is_ entirely appropriate?
That has the advantage of letting you change how it is done (again)
without having to find all the callers.
-- David
>
> Thansk,
> Robin.
>
> > Signed-off-by: Yury Norov <ynorov@nvidia.com>
> > ---
> > drivers/perf/alibaba_uncore_drw_pmu.c | 2 +-
> > drivers/perf/amlogic/meson_ddr_pmu_core.c | 2 +-
> > drivers/perf/arm-cci.c | 2 +-
> > drivers/perf/arm-ccn.c | 2 +-
> > drivers/perf/arm-cmn.c | 2 +-
> > drivers/perf/arm-ni.c | 2 +-
> > drivers/perf/arm_cspmu/arm_cspmu.c | 2 +-
> > drivers/perf/arm_dmc620_pmu.c | 4 ++--
> > drivers/perf/arm_dsu_pmu.c | 2 +-
> > drivers/perf/arm_pmu.c | 2 +-
> > drivers/perf/arm_smmuv3_pmu.c | 2 +-
> > drivers/perf/arm_spe_pmu.c | 2 +-
> > drivers/perf/cxl_pmu.c | 2 +-
> > drivers/perf/dwc_pcie_pmu.c | 2 +-
> > drivers/perf/fsl_imx8_ddr_perf.c | 2 +-
> > drivers/perf/fsl_imx9_ddr_perf.c | 2 +-
> > drivers/perf/fujitsu_uncore_pmu.c | 2 +-
> > drivers/perf/hisilicon/hisi_pcie_pmu.c | 2 +-
> > drivers/perf/hisilicon/hisi_uncore_pmu.c | 2 +-
> > drivers/perf/marvell_cn10k_ddr_pmu.c | 2 +-
> > drivers/perf/marvell_cn10k_tad_pmu.c | 2 +-
> > drivers/perf/marvell_pem_pmu.c | 2 +-
> > drivers/perf/nvidia_t410_c2c_pmu.c | 2 +-
> > drivers/perf/nvidia_t410_cmem_latency_pmu.c | 2 +-
> > drivers/perf/qcom_l2_pmu.c | 2 +-
> > drivers/perf/qcom_l3_pmu.c | 2 +-
> > drivers/perf/starfive_starlink_pmu.c | 2 +-
> > drivers/perf/thunderx2_pmu.c | 2 +-
> > drivers/perf/xgene_pmu.c | 2 +-
> > kernel/events/core.c | 2 +-
> > 30 files changed, 31 insertions(+), 31 deletions(-)
> >
> > diff --git a/drivers/perf/alibaba_uncore_drw_pmu.c b/drivers/perf/alibaba_uncore_drw_pmu.c
> > index ac49d3b2dad6..74786a5dd6a2 100644
> > --- a/drivers/perf/alibaba_uncore_drw_pmu.c
> > +++ b/drivers/perf/alibaba_uncore_drw_pmu.c
> > @@ -221,7 +221,7 @@ static ssize_t ali_drw_pmu_cpumask_show(struct device *dev,
> > {
> > struct ali_drw_pmu *drw_pmu = to_ali_drw_pmu(dev_get_drvdata(dev));
> >
> > - return cpumap_print_to_pagebuf(true, buf, cpumask_of(drw_pmu->cpu));
> > + return sysfs_emit(buf, "%*pbl\n", cpumask_pr_args(cpumask_of(drw_pmu->cpu)));
> > }
> >
> > static struct device_attribute ali_drw_pmu_cpumask_attr =
> > diff --git a/drivers/perf/amlogic/meson_ddr_pmu_core.c b/drivers/perf/amlogic/meson_ddr_pmu_core.c
> > index c1e755c356a3..f614aa3434a5 100644
> > --- a/drivers/perf/amlogic/meson_ddr_pmu_core.c
> > +++ b/drivers/perf/amlogic/meson_ddr_pmu_core.c
> > @@ -191,7 +191,7 @@ static ssize_t meson_ddr_perf_cpumask_show(struct device *dev,
> > {
> > struct ddr_pmu *pmu = dev_get_drvdata(dev);
> >
> > - return cpumap_print_to_pagebuf(true, buf, cpumask_of(pmu->cpu));
> > + return sysfs_emit(buf, "%*pbl\n", cpumask_pr_args(cpumask_of(pmu->cpu)));
> > }
> >
> > static struct device_attribute meson_ddr_perf_cpumask_attr =
> > diff --git a/drivers/perf/arm-cci.c b/drivers/perf/arm-cci.c
> > index 1cc3214d6b6d..f0ef0a679e74 100644
> > --- a/drivers/perf/arm-cci.c
> > +++ b/drivers/perf/arm-cci.c
> > @@ -1351,7 +1351,7 @@ static ssize_t pmu_cpumask_attr_show(struct device *dev,
> > struct pmu *pmu = dev_get_drvdata(dev);
> > struct cci_pmu *cci_pmu = to_cci_pmu(pmu);
> >
> > - return cpumap_print_to_pagebuf(true, buf, cpumask_of(cci_pmu->cpu));
> > + return sysfs_emit(buf, "%*pbl\n", cpumask_pr_args(cpumask_of(cci_pmu->cpu)));
> > }
> >
> > static struct device_attribute pmu_cpumask_attr =
> > diff --git a/drivers/perf/arm-ccn.c b/drivers/perf/arm-ccn.c
> > index 8af3563fdf60..d5dcb4280434 100644
> > --- a/drivers/perf/arm-ccn.c
> > +++ b/drivers/perf/arm-ccn.c
> > @@ -538,7 +538,7 @@ static ssize_t arm_ccn_pmu_cpumask_show(struct device *dev,
> > {
> > struct arm_ccn *ccn = pmu_to_arm_ccn(dev_get_drvdata(dev));
> >
> > - return cpumap_print_to_pagebuf(true, buf, cpumask_of(ccn->dt.cpu));
> > + return sysfs_emit(buf, "%*pbl\n", cpumask_pr_args(cpumask_of(ccn->dt.cpu)));
> > }
> >
> > static struct device_attribute arm_ccn_pmu_cpumask_attr =
> > diff --git a/drivers/perf/arm-cmn.c b/drivers/perf/arm-cmn.c
> > index f5305c8fdca4..2187ba763b72 100644
> > --- a/drivers/perf/arm-cmn.c
> > +++ b/drivers/perf/arm-cmn.c
> > @@ -1326,7 +1326,7 @@ static ssize_t arm_cmn_cpumask_show(struct device *dev,
> > {
> > struct arm_cmn *cmn = to_cmn(dev_get_drvdata(dev));
> >
> > - return cpumap_print_to_pagebuf(true, buf, cpumask_of(cmn->cpu));
> > + return sysfs_emit(buf, "%*pbl\n", cpumask_pr_args(cpumask_of(cmn->cpu)));
> > }
> >
> > static struct device_attribute arm_cmn_cpumask_attr =
> > diff --git a/drivers/perf/arm-ni.c b/drivers/perf/arm-ni.c
> > index 66858c65215d..03a1c6bf9223 100644
> > --- a/drivers/perf/arm-ni.c
> > +++ b/drivers/perf/arm-ni.c
> > @@ -239,7 +239,7 @@ static ssize_t arm_ni_cpumask_show(struct device *dev,
> > {
> > struct arm_ni *ni = cd_to_ni(pmu_to_cd(dev_get_drvdata(dev)));
> >
> > - return cpumap_print_to_pagebuf(true, buf, cpumask_of(ni->cpu));
> > + return sysfs_emit(buf, "%*pbl\n", cpumask_pr_args(cpumask_of(ni->cpu)));
> > }
> >
> > static struct device_attribute arm_ni_cpumask_attr =
> > diff --git a/drivers/perf/arm_cspmu/arm_cspmu.c b/drivers/perf/arm_cspmu/arm_cspmu.c
> > index 80fb314d5135..e6292021f653 100644
> > --- a/drivers/perf/arm_cspmu/arm_cspmu.c
> > +++ b/drivers/perf/arm_cspmu/arm_cspmu.c
> > @@ -305,7 +305,7 @@ static ssize_t arm_cspmu_cpumask_show(struct device *dev,
> > default:
> > return 0;
> > }
> > - return cpumap_print_to_pagebuf(true, buf, cpumask);
> > + return sysfs_emit(buf, "%*pbl\n", cpumask_pr_args(cpumask));
> > }
> >
> > static struct attribute *arm_cspmu_cpumask_attrs[] = {
> > diff --git a/drivers/perf/arm_dmc620_pmu.c b/drivers/perf/arm_dmc620_pmu.c
> > index 4f6b196160f8..467147a05eec 100644
> > --- a/drivers/perf/arm_dmc620_pmu.c
> > +++ b/drivers/perf/arm_dmc620_pmu.c
> > @@ -237,8 +237,8 @@ static ssize_t dmc620_pmu_cpumask_show(struct device *dev,
> > {
> > struct dmc620_pmu *dmc620_pmu = to_dmc620_pmu(dev_get_drvdata(dev));
> >
> > - return cpumap_print_to_pagebuf(true, buf,
> > - cpumask_of(dmc620_pmu->irq->cpu));
> > + return sysfs_emit(buf, "%*pbl\n",
> > + cpumask_pr_args(cpumask_of(dmc620_pmu->irq->cpu)));
> > }
> >
> > static struct device_attribute dmc620_pmu_cpumask_attr =
> > diff --git a/drivers/perf/arm_dsu_pmu.c b/drivers/perf/arm_dsu_pmu.c
> > index 32b0dd7c693b..bcbd19e075a5 100644
> > --- a/drivers/perf/arm_dsu_pmu.c
> > +++ b/drivers/perf/arm_dsu_pmu.c
> > @@ -157,7 +157,7 @@ static ssize_t dsu_pmu_cpumask_show(struct device *dev,
> > default:
> > return 0;
> > }
> > - return cpumap_print_to_pagebuf(true, buf, cpumask);
> > + return sysfs_emit(buf, "%*pbl\n", cpumask_pr_args(cpumask));
> > }
> >
> > static struct attribute *dsu_pmu_format_attrs[] = {
> > diff --git a/drivers/perf/arm_pmu.c b/drivers/perf/arm_pmu.c
> > index 939bcbd433aa..51ab6cc52ca0 100644
> > --- a/drivers/perf/arm_pmu.c
> > +++ b/drivers/perf/arm_pmu.c
> > @@ -570,7 +570,7 @@ static ssize_t cpus_show(struct device *dev,
> > struct device_attribute *attr, char *buf)
> > {
> > struct arm_pmu *armpmu = to_arm_pmu(dev_get_drvdata(dev));
> > - return cpumap_print_to_pagebuf(true, buf, &armpmu->supported_cpus);
> > + return sysfs_emit(buf, "%*pbl\n", cpumask_pr_args(&armpmu->supported_cpus));
> > }
> >
> > static DEVICE_ATTR_RO(cpus);
> > diff --git a/drivers/perf/arm_smmuv3_pmu.c b/drivers/perf/arm_smmuv3_pmu.c
> > index 621f02a7f43b..8ce34e6bb82b 100644
> > --- a/drivers/perf/arm_smmuv3_pmu.c
> > +++ b/drivers/perf/arm_smmuv3_pmu.c
> > @@ -537,7 +537,7 @@ static ssize_t smmu_pmu_cpumask_show(struct device *dev,
> > {
> > struct smmu_pmu *smmu_pmu = to_smmu_pmu(dev_get_drvdata(dev));
> >
> > - return cpumap_print_to_pagebuf(true, buf, cpumask_of(smmu_pmu->on_cpu));
> > + return sysfs_emit(buf, "%*pbl\n", cpumask_pr_args(cpumask_of(smmu_pmu->on_cpu)));
> > }
> >
> > static struct device_attribute smmu_pmu_cpumask_attr =
> > diff --git a/drivers/perf/arm_spe_pmu.c b/drivers/perf/arm_spe_pmu.c
> > index dbd0da111639..9f786fd48cdd 100644
> > --- a/drivers/perf/arm_spe_pmu.c
> > +++ b/drivers/perf/arm_spe_pmu.c
> > @@ -343,7 +343,7 @@ static ssize_t cpumask_show(struct device *dev,
> > {
> > struct arm_spe_pmu *spe_pmu = dev_get_drvdata(dev);
> >
> > - return cpumap_print_to_pagebuf(true, buf, &spe_pmu->supported_cpus);
> > + return sysfs_emit(buf, "%*pbl\n", cpumask_pr_args(&spe_pmu->supported_cpus));
> > }
> > static DEVICE_ATTR_RO(cpumask);
> >
> > diff --git a/drivers/perf/cxl_pmu.c b/drivers/perf/cxl_pmu.c
> > index 68a54d97d2a8..0735eb33f5f3 100644
> > --- a/drivers/perf/cxl_pmu.c
> > +++ b/drivers/perf/cxl_pmu.c
> > @@ -493,7 +493,7 @@ static ssize_t cpumask_show(struct device *dev, struct device_attribute *attr,
> > {
> > struct cxl_pmu_info *info = dev_get_drvdata(dev);
> >
> > - return cpumap_print_to_pagebuf(true, buf, cpumask_of(info->on_cpu));
> > + return sysfs_emit(buf, "%*pbl\n", cpumask_pr_args(cpumask_of(info->on_cpu)));
> > }
> > static DEVICE_ATTR_RO(cpumask);
> >
> > diff --git a/drivers/perf/dwc_pcie_pmu.c b/drivers/perf/dwc_pcie_pmu.c
> > index 5385401fa9cf..291e776d6f6a 100644
> > --- a/drivers/perf/dwc_pcie_pmu.c
> > +++ b/drivers/perf/dwc_pcie_pmu.c
> > @@ -117,7 +117,7 @@ static ssize_t cpumask_show(struct device *dev,
> > {
> > struct dwc_pcie_pmu *pcie_pmu = to_dwc_pcie_pmu(dev_get_drvdata(dev));
> >
> > - return cpumap_print_to_pagebuf(true, buf, cpumask_of(pcie_pmu->on_cpu));
> > + return sysfs_emit(buf, "%*pbl\n", cpumask_pr_args(cpumask_of(pcie_pmu->on_cpu)));
> > }
> > static DEVICE_ATTR_RO(cpumask);
> >
> > diff --git a/drivers/perf/fsl_imx8_ddr_perf.c b/drivers/perf/fsl_imx8_ddr_perf.c
> > index bcdf5575d71c..3760ebe02674 100644
> > --- a/drivers/perf/fsl_imx8_ddr_perf.c
> > +++ b/drivers/perf/fsl_imx8_ddr_perf.c
> > @@ -237,7 +237,7 @@ static ssize_t ddr_perf_cpumask_show(struct device *dev,
> > {
> > struct ddr_pmu *pmu = dev_get_drvdata(dev);
> >
> > - return cpumap_print_to_pagebuf(true, buf, cpumask_of(pmu->cpu));
> > + return sysfs_emit(buf, "%*pbl\n", cpumask_pr_args(cpumask_of(pmu->cpu)));
> > }
> >
> > static struct device_attribute ddr_perf_cpumask_attr =
> > diff --git a/drivers/perf/fsl_imx9_ddr_perf.c b/drivers/perf/fsl_imx9_ddr_perf.c
> > index 7050b48c0467..6fee5eb5087a 100644
> > --- a/drivers/perf/fsl_imx9_ddr_perf.c
> > +++ b/drivers/perf/fsl_imx9_ddr_perf.c
> > @@ -159,7 +159,7 @@ static ssize_t ddr_perf_cpumask_show(struct device *dev,
> > {
> > struct ddr_pmu *pmu = dev_get_drvdata(dev);
> >
> > - return cpumap_print_to_pagebuf(true, buf, cpumask_of(pmu->cpu));
> > + return sysfs_emit(buf, "%*pbl\n", cpumask_pr_args(cpumask_of(pmu->cpu)));
> > }
> >
> > static struct device_attribute ddr_perf_cpumask_attr =
> > diff --git a/drivers/perf/fujitsu_uncore_pmu.c b/drivers/perf/fujitsu_uncore_pmu.c
> > index c3c6f56474ad..a07877632d53 100644
> > --- a/drivers/perf/fujitsu_uncore_pmu.c
> > +++ b/drivers/perf/fujitsu_uncore_pmu.c
> > @@ -374,7 +374,7 @@ static ssize_t cpumask_show(struct device *dev,
> > {
> > struct uncore_pmu *uncorepmu = to_uncore_pmu(dev_get_drvdata(dev));
> >
> > - return cpumap_print_to_pagebuf(true, buf, cpumask_of(uncorepmu->cpu));
> > + return sysfs_emit(buf, "%*pbl\n", cpumask_pr_args(cpumask_of(uncorepmu->cpu)));
> > }
> > static DEVICE_ATTR_RO(cpumask);
> >
> > diff --git a/drivers/perf/hisilicon/hisi_pcie_pmu.c b/drivers/perf/hisilicon/hisi_pcie_pmu.c
> > index c5394d007b61..0f55d871c67e 100644
> > --- a/drivers/perf/hisilicon/hisi_pcie_pmu.c
> > +++ b/drivers/perf/hisilicon/hisi_pcie_pmu.c
> > @@ -121,7 +121,7 @@ static ssize_t cpumask_show(struct device *dev, struct device_attribute *attr, c
> > {
> > struct hisi_pcie_pmu *pcie_pmu = to_pcie_pmu(dev_get_drvdata(dev));
> >
> > - return cpumap_print_to_pagebuf(true, buf, cpumask_of(pcie_pmu->on_cpu));
> > + return sysfs_emit(buf, "%*pbl\n", cpumask_pr_args(cpumask_of(pcie_pmu->on_cpu)));
> > }
> > static DEVICE_ATTR_RO(cpumask);
> >
> > diff --git a/drivers/perf/hisilicon/hisi_uncore_pmu.c b/drivers/perf/hisilicon/hisi_uncore_pmu.c
> > index de71dcf11653..0ff2fdf4b3e2 100644
> > --- a/drivers/perf/hisilicon/hisi_uncore_pmu.c
> > +++ b/drivers/perf/hisilicon/hisi_uncore_pmu.c
> > @@ -56,7 +56,7 @@ static ssize_t hisi_associated_cpus_sysfs_show(struct device *dev,
> > {
> > struct hisi_pmu *hisi_pmu = to_hisi_pmu(dev_get_drvdata(dev));
> >
> > - return cpumap_print_to_pagebuf(true, buf, &hisi_pmu->associated_cpus);
> > + return sysfs_emit(buf, "%*pbl\n", cpumask_pr_args(&hisi_pmu->associated_cpus));
> > }
> > static DEVICE_ATTR(associated_cpus, 0444, hisi_associated_cpus_sysfs_show, NULL);
> >
> > diff --git a/drivers/perf/marvell_cn10k_ddr_pmu.c b/drivers/perf/marvell_cn10k_ddr_pmu.c
> > index 72ac17efd846..8681e8715cb3 100644
> > --- a/drivers/perf/marvell_cn10k_ddr_pmu.c
> > +++ b/drivers/perf/marvell_cn10k_ddr_pmu.c
> > @@ -364,7 +364,7 @@ static ssize_t cn10k_ddr_perf_cpumask_show(struct device *dev,
> > {
> > struct cn10k_ddr_pmu *pmu = dev_get_drvdata(dev);
> >
> > - return cpumap_print_to_pagebuf(true, buf, cpumask_of(pmu->cpu));
> > + return sysfs_emit(buf, "%*pbl\n", cpumask_pr_args(cpumask_of(pmu->cpu)));
> > }
> >
> > static struct device_attribute cn10k_ddr_perf_cpumask_attr =
> > diff --git a/drivers/perf/marvell_cn10k_tad_pmu.c b/drivers/perf/marvell_cn10k_tad_pmu.c
> > index 51ccb0befa05..54909d0031b7 100644
> > --- a/drivers/perf/marvell_cn10k_tad_pmu.c
> > +++ b/drivers/perf/marvell_cn10k_tad_pmu.c
> > @@ -258,7 +258,7 @@ static ssize_t tad_pmu_cpumask_show(struct device *dev,
> > {
> > struct tad_pmu *tad_pmu = to_tad_pmu(dev_get_drvdata(dev));
> >
> > - return cpumap_print_to_pagebuf(true, buf, cpumask_of(tad_pmu->cpu));
> > + return sysfs_emit(buf, "%*pbl\n", cpumask_pr_args(cpumask_of(tad_pmu->cpu)));
> > }
> >
> > static DEVICE_ATTR(cpumask, 0444, tad_pmu_cpumask_show, NULL);
> > diff --git a/drivers/perf/marvell_pem_pmu.c b/drivers/perf/marvell_pem_pmu.c
> > index 29fbcd1848e4..cf1d8cdb1318 100644
> > --- a/drivers/perf/marvell_pem_pmu.c
> > +++ b/drivers/perf/marvell_pem_pmu.c
> > @@ -164,7 +164,7 @@ static ssize_t pem_perf_cpumask_show(struct device *dev,
> > {
> > struct pem_pmu *pmu = dev_get_drvdata(dev);
> >
> > - return cpumap_print_to_pagebuf(true, buf, cpumask_of(pmu->cpu));
> > + return sysfs_emit(buf, "%*pbl\n", cpumask_pr_args(cpumask_of(pmu->cpu)));
> > }
> >
> > static struct device_attribute pem_perf_cpumask_attr =
> > diff --git a/drivers/perf/nvidia_t410_c2c_pmu.c b/drivers/perf/nvidia_t410_c2c_pmu.c
> > index 411987153ff3..bff875f4f625 100644
> > --- a/drivers/perf/nvidia_t410_c2c_pmu.c
> > +++ b/drivers/perf/nvidia_t410_c2c_pmu.c
> > @@ -658,7 +658,7 @@ static ssize_t nv_c2c_pmu_cpumask_show(struct device *dev,
> > default:
> > return 0;
> > }
> > - return cpumap_print_to_pagebuf(true, buf, cpumask);
> > + return sysfs_emit(buf, "%*pbl\n", cpumask_pr_args(cpumask));
> > }
> >
> > #define NV_C2C_PMU_CPUMASK_ATTR(_name, _config) \
> > diff --git a/drivers/perf/nvidia_t410_cmem_latency_pmu.c b/drivers/perf/nvidia_t410_cmem_latency_pmu.c
> > index acb8f5571522..6c8e41598ec1 100644
> > --- a/drivers/perf/nvidia_t410_cmem_latency_pmu.c
> > +++ b/drivers/perf/nvidia_t410_cmem_latency_pmu.c
> > @@ -501,7 +501,7 @@ static ssize_t cmem_lat_pmu_cpumask_show(struct device *dev,
> > default:
> > return 0;
> > }
> > - return cpumap_print_to_pagebuf(true, buf, cpumask);
> > + return sysfs_emit(buf, "%*pbl\n", cpumask_pr_args(cpumask));
> > }
> >
> > #define NV_PMU_CPUMASK_ATTR(_name, _config) \
> > diff --git a/drivers/perf/qcom_l2_pmu.c b/drivers/perf/qcom_l2_pmu.c
> > index ea8c85729937..c0c522b10b72 100644
> > --- a/drivers/perf/qcom_l2_pmu.c
> > +++ b/drivers/perf/qcom_l2_pmu.c
> > @@ -638,7 +638,7 @@ static ssize_t l2_cache_pmu_cpumask_show(struct device *dev,
> > {
> > struct l2cache_pmu *l2cache_pmu = to_l2cache_pmu(dev_get_drvdata(dev));
> >
> > - return cpumap_print_to_pagebuf(true, buf, &l2cache_pmu->cpumask);
> > + return sysfs_emit(buf, "%*pbl\n", cpumask_pr_args(&l2cache_pmu->cpumask));
> > }
> >
> > static struct device_attribute l2_cache_pmu_cpumask_attr =
> > diff --git a/drivers/perf/qcom_l3_pmu.c b/drivers/perf/qcom_l3_pmu.c
> > index 66e6cabd6fff..c8d259dd1f80 100644
> > --- a/drivers/perf/qcom_l3_pmu.c
> > +++ b/drivers/perf/qcom_l3_pmu.c
> > @@ -663,7 +663,7 @@ static ssize_t cpumask_show(struct device *dev,
> > {
> > struct l3cache_pmu *l3pmu = to_l3cache_pmu(dev_get_drvdata(dev));
> >
> > - return cpumap_print_to_pagebuf(true, buf, &l3pmu->cpumask);
> > + return sysfs_emit(buf, "%*pbl\n", cpumask_pr_args(&l3pmu->cpumask));
> > }
> >
> > static DEVICE_ATTR_RO(cpumask);
> > diff --git a/drivers/perf/starfive_starlink_pmu.c b/drivers/perf/starfive_starlink_pmu.c
> > index 964897c2baa9..222a0a34e211 100644
> > --- a/drivers/perf/starfive_starlink_pmu.c
> > +++ b/drivers/perf/starfive_starlink_pmu.c
> > @@ -131,7 +131,7 @@ cpumask_show(struct device *dev, struct device_attribute *attr, char *buf)
> > {
> > struct starlink_pmu *starlink_pmu = to_starlink_pmu(dev_get_drvdata(dev));
> >
> > - return cpumap_print_to_pagebuf(true, buf, &starlink_pmu->cpumask);
> > + return sysfs_emit(buf, "%*pbl\n", cpumask_pr_args(&starlink_pmu->cpumask));
> > }
> >
> > static DEVICE_ATTR_RO(cpumask);
> > diff --git a/drivers/perf/thunderx2_pmu.c b/drivers/perf/thunderx2_pmu.c
> > index 6ed4707bd6bb..a69c02d2d874 100644
> > --- a/drivers/perf/thunderx2_pmu.c
> > +++ b/drivers/perf/thunderx2_pmu.c
> > @@ -254,7 +254,7 @@ static ssize_t cpumask_show(struct device *dev, struct device_attribute *attr,
> > struct tx2_uncore_pmu *tx2_pmu;
> >
> > tx2_pmu = pmu_to_tx2_pmu(dev_get_drvdata(dev));
> > - return cpumap_print_to_pagebuf(true, buf, cpumask_of(tx2_pmu->cpu));
> > + return sysfs_emit(buf, "%*pbl\n", cpumask_pr_args(cpumask_of(tx2_pmu->cpu)));
> > }
> > static DEVICE_ATTR_RO(cpumask);
> >
> > diff --git a/drivers/perf/xgene_pmu.c b/drivers/perf/xgene_pmu.c
> > index 33b5497bdc06..e9e4871db08d 100644
> > --- a/drivers/perf/xgene_pmu.c
> > +++ b/drivers/perf/xgene_pmu.c
> > @@ -595,7 +595,7 @@ static ssize_t cpumask_show(struct device *dev,
> > {
> > struct xgene_pmu_dev *pmu_dev = to_pmu_dev(dev_get_drvdata(dev));
> >
> > - return cpumap_print_to_pagebuf(true, buf, &pmu_dev->parent->cpu);
> > + return sysfs_emit(buf, "%*pbl\n", cpumask_pr_args(&pmu_dev->parent->cpu));
> > }
> >
> > static DEVICE_ATTR_RO(cpumask);
> > diff --git a/kernel/events/core.c b/kernel/events/core.c
> > index 7935d5663944..61689d348abd 100644
> > --- a/kernel/events/core.c
> > +++ b/kernel/events/core.c
> > @@ -12657,7 +12657,7 @@ static ssize_t cpumask_show(struct device *dev, struct device_attribute *attr,
> > struct cpumask *mask = perf_scope_cpumask(pmu->scope);
> >
> > if (mask)
> > - return cpumap_print_to_pagebuf(true, buf, mask);
> > + return sysfs_emit(buf, "%*pbl\n", cpumask_pr_args(mask));
> > return 0;
> > }
> >
>
>
^ permalink raw reply
* Re: [PATCH v3 1/5] KVM: PPC: Book3S HV: Validate arch_compat against host compatibility mode
From: Ritesh Harjani @ 2026-05-29 11:53 UTC (permalink / raw)
To: Amit Machhiwal
Cc: Amit Machhiwal, linuxppc-dev, Madhavan Srinivasan, Vaibhav Jain,
Anushree Mathur, Paolo Bonzini, Nicholas Piggin, Michael Ellerman,
Christophe Leroy (CS GROUP), Jonathan Corbet, Shuah Khan, kvm,
linux-kernel, linux-doc, lkp
In-Reply-To: <20260529141530.fc225a67-e9-amachhiw@linux.ibm.com>
Amit Machhiwal <amachhiw@linux.ibm.com> writes:
> So, we would still want to prioritize the whole series
> instead of just this one patch.
>
Patch-1 could go as a bug fix even in 7.1-rc6 (or maybe with 7.2
bug fixes). - Maddy?
So, you may want to add a fixes tag and maybe even cc stable if you are
seeing this issue from older kernels maybe when nestedv2 got introduced?
However the new UAPI discussion might still require more discussion with
the community and I don't think it is ready for 7.2 yet ;)
-ritesh
^ permalink raw reply
* Re: [PATCH 01/16] psci: simplify hotplug_tests()
From: Robin Murphy @ 2026-05-29 12:24 UTC (permalink / raw)
To: Yury Norov, Andrew Morton, Rasmus Villemoes
Cc: Russell King, Frank Li, Sascha Hauer, Pengutronix Kernel Team,
Fabio Estevam, Madhavan Srinivasan, Michael Ellerman,
Nicholas Piggin, Christophe Leroy (CS GROUP), Peter Zijlstra,
Ingo Molnar, Arnaldo Carvalho de Melo, Namhyung Kim, Mark Rutland,
Alexander Shishkin, Jiri Olsa, Ian Rogers, Adrian Hunter,
James Clark, Thomas Gleixner, Borislav Petkov, Dave Hansen,
H. Peter Anvin, Rafael J. Wysocki, Len Brown, Greg Kroah-Hartman,
Danilo Krummrich, Chanwoo Choi, MyungJoo Ham, Kyungmin Park,
Heiko Stuebner, Lorenzo Pieralisi, Xu Yilun, Tom Rix,
Moritz Fischer, Yicong Yang, Jonathan Cameron, Dennis Dalessandro,
Jason Gunthorpe, Leon Romanovsky, Dan Williams, Vishal Verma,
Dave Jiang, Ira Weiny, Bjorn Helgaas, Shuai Xue, Will Deacon,
Jiucheng Xu, Neil Armstrong, Kevin Hilman, Jerome Brunet,
Martin Blumenstingl, Jing Zhang, Xu Yang, Linu Cherian,
Gowthami Thiagarajan, Ji Sheng Teoh, Khuong Dinh, Daniel Lezcano,
Zhang Rui, Lukasz Luba, Yury Norov, Kees Cook,
Thomas Weißschuh, Aboorva Devarajan, Ritesh Harjani (IBM),
Ilkka Koskinen, Besar Wicaksono, Ma Ke, Chengwen Feng,
linux-arm-kernel, imx, linux-kernel, linuxppc-dev,
linux-perf-users, linux-acpi, driver-core, linux-pm,
linux-rockchip, linux-fpga, linux-rdma, nvdimm, linux-pci,
linux-amlogic, linux-cxl, linux-arm-msm
In-Reply-To: <20260528183625.870813-2-ynorov@nvidia.com>
On 2026-05-28 7:36 pm, Yury Norov wrote:
> Switch to pr_info("... %pbl"), and drop the temporary buffer allocation.
I would say this is simply an improvement in its own right, regardless
of whether cpumap_print_to_pagebuf() deserves to be removed or not. For
the change itself, FWIW,
Reviewed-by: Robin Murphy <robin.murphy@arm.com>
> This prepares for removing cpumap_print_to_pagebuf().
>
> Signed-off-by: Yury Norov <ynorov@nvidia.com>
> ---
> drivers/firmware/psci/psci_checker.c | 14 ++------------
> 1 file changed, 2 insertions(+), 12 deletions(-)
>
> diff --git a/drivers/firmware/psci/psci_checker.c b/drivers/firmware/psci/psci_checker.c
> index e67ba9891082..ecd745bb90bf 100644
> --- a/drivers/firmware/psci/psci_checker.c
> +++ b/drivers/firmware/psci/psci_checker.c
> @@ -186,7 +186,6 @@ static int hotplug_tests(void)
> {
> int i, nb_cpu_group, err = -ENOMEM;
> cpumask_var_t offlined_cpus, *cpu_groups;
> - char *page_buf;
>
> if (!alloc_cpumask_var(&offlined_cpus, GFP_KERNEL))
> return err;
> @@ -194,10 +193,6 @@ static int hotplug_tests(void)
> nb_cpu_group = alloc_init_cpu_groups(&cpu_groups);
> if (nb_cpu_group < 0)
> goto out_free_cpus;
> - page_buf = (char *)__get_free_page(GFP_KERNEL);
> - if (!page_buf)
> - goto out_free_cpu_groups;
> -
> /*
> * Of course the last CPU cannot be powered down and cpu_down() should
> * refuse doing that.
> @@ -210,16 +205,11 @@ static int hotplug_tests(void)
> * off, the cpu group itself should shut down.
> */
> for (i = 0; i < nb_cpu_group; ++i) {
> - ssize_t len = cpumap_print_to_pagebuf(true, page_buf,
> - cpu_groups[i]);
> - /* Remove trailing newline. */
> - page_buf[len - 1] = '\0';
> - pr_info("Trying to turn off and on again group %d (CPUs %s)\n",
> - i, page_buf);
> + pr_info("Trying to turn off and on again group %d (CPUs %*pbl)\n",
> + i, cpumask_pr_args(cpu_groups[i]));
> err += down_and_up_cpus(cpu_groups[i], offlined_cpus);
> }
>
> - free_page((unsigned long)page_buf);
> out_free_cpu_groups:
> free_cpu_groups(nb_cpu_group, &cpu_groups);
> out_free_cpus:
^ permalink raw reply
* [PATCH v2 0/3] powerpc/irq: Use optimizations for /proc/interrupts
From: Shrikanth Hegde @ 2026-05-29 12:40 UTC (permalink / raw)
To: christophe.leroy, maddy, linuxppc-dev, tglx; +Cc: sshegde, linux-kernel
v1-> v2:
- Collected the tags (Thanks to Christophe Leroy)
- Rename skip to optional and check optional while printing
(Christophe Leroy)
- Decided not to add cpu_has_feature(CPU_FTR_DBELL) while printing.
This feature is mostly true for majority of platforms and adding check
means more ifdefs in that path. Prinitng "Doorbell interrupts" shouldn't
cause any issue when feature if off since all entries would be zero.
(sashiko)
This series is based on work by Thomas Gleixner[1].
Further details can be found in cover-letter of v1.
======== Performance Data ==================
Time taken to read /proc/interrupts 1000 times[2]
Base : 103us
v6[1] : 63us
v6+patch 1+2 : 57us
v6+patch 1+2+3 : 54us
Base: tip/master at 'ddfd3966d0d4 ("Merge branch into tip/master: 'x86/tdx'")'
[1]: https://lore.kernel.org/all/20260517194421.705253664@kernel.org/
[2]: https://lore.kernel.org/all/87jysxw65f.ffs@tglx/
v1: https://lore.kernel.org/all/20260523174016.999456-1-sshegde@linux.ibm.com/
Shrikanth Hegde (3):
powerpc/irq: Move __softirq_pending out of irq_stat
powerpc/irq: Make irqstats array based
powerpc/irq: Suppress unlikely interrupt stats by default
arch/powerpc/include/asm/hardirq.h | 31 ++++---
arch/powerpc/kernel/dbell.c | 2 +-
arch/powerpc/kernel/irq.c | 131 +++++++++++++++--------------
arch/powerpc/kernel/time.c | 6 +-
arch/powerpc/kernel/traps.c | 11 +--
arch/powerpc/kernel/watchdog.c | 2 +-
6 files changed, 95 insertions(+), 88 deletions(-)
--
2.47.3
^ permalink raw reply
* [PATCH v2 1/3] powerpc/irq: Move __softirq_pending out of irq_stat
From: Shrikanth Hegde @ 2026-05-29 12:40 UTC (permalink / raw)
To: christophe.leroy, maddy, linuxppc-dev, tglx
Cc: sshegde, linux-kernel, Christophe Leroy (CS GROUP)
In-Reply-To: <20260529124045.1208539-1-sshegde@linux.ibm.com>
__softirq_pending isn't part of arch specific irq_stats. It is used
by softirq core for various decision making such as whether to kick off
ksoftirqd.
Move it out of irq_cpustat_t. This makes it simple to make irq_cpustat_t
array based approach.
Reviewed-by: Christophe Leroy (CS GROUP) <chleroy@kernel.org>
Signed-off-by: Shrikanth Hegde <sshegde@linux.ibm.com>
---
arch/powerpc/include/asm/hardirq.h | 3 ++-
arch/powerpc/kernel/irq.c | 1 +
2 files changed, 3 insertions(+), 1 deletion(-)
diff --git a/arch/powerpc/include/asm/hardirq.h b/arch/powerpc/include/asm/hardirq.h
index f133b5930ae1..bf3926a0c69c 100644
--- a/arch/powerpc/include/asm/hardirq.h
+++ b/arch/powerpc/include/asm/hardirq.h
@@ -6,7 +6,6 @@
#include <linux/irq.h>
typedef struct {
- unsigned int __softirq_pending;
unsigned int timer_irqs_event;
unsigned int broadcast_irqs_event;
unsigned int timer_irqs_others;
@@ -23,6 +22,8 @@ typedef struct {
} ____cacheline_aligned irq_cpustat_t;
DECLARE_PER_CPU_SHARED_ALIGNED(irq_cpustat_t, irq_stat);
+DECLARE_PER_CPU(unsigned int, __softirq_pending);
+#define local_softirq_pending_ref __softirq_pending
#define __ARCH_IRQ_STAT
#define __ARCH_IRQ_EXIT_IRQS_DISABLED
diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c
index a0e8b998c9b5..f33df5e5c23f 100644
--- a/arch/powerpc/kernel/irq.c
+++ b/arch/powerpc/kernel/irq.c
@@ -73,6 +73,7 @@
DEFINE_PER_CPU_SHARED_ALIGNED(irq_cpustat_t, irq_stat);
EXPORT_PER_CPU_SYMBOL(irq_stat);
+DEFINE_PER_CPU(unsigned int, __softirq_pending);
#ifdef CONFIG_PPC32
atomic_t ppc_n_lost_interrupts;
--
2.47.3
^ permalink raw reply related
* [PATCH v2 3/3] powerpc/irq: Suppress unlikely interrupt stats by default
From: Shrikanth Hegde @ 2026-05-29 12:40 UTC (permalink / raw)
To: christophe.leroy, maddy, linuxppc-dev, tglx; +Cc: sshegde, linux-kernel
In-Reply-To: <20260529124045.1208539-1-sshegde@linux.ibm.com>
Some interrupts are always zero and that is expected since they occur
very rarely and are mostly error indications. Don't print them by
default.
"MCE" - "Machine check exceptions"
"NMI" - "System Reset interrupts"
Print them if they occur once. Maintain a bitmap to know which
interrupts are to be printed.
Time taken to read /proc/interrupts 1000 times.
Base and v6 details can be found in cover-letter.
Base : 103us
v6 : 63us
v6+patch 1+2 : 57us
v6+patch 1+2+3 : 54us
Patch 3 shows an additional 5% gain compared to patch 1+2. So it does
make sense to print them only if they are ever set.
Note: Since /proc/interrupts depend on kconfig and arch dependent,
userspace tools don't make explicit assumptions.
Signed-off-by: Shrikanth Hegde <sshegde@linux.ibm.com>
---
arch/powerpc/include/asm/hardirq.h | 1 +
arch/powerpc/kernel/irq.c | 37 +++++++++++++++++++++++++++---
arch/powerpc/kernel/traps.c | 4 ++--
3 files changed, 37 insertions(+), 5 deletions(-)
diff --git a/arch/powerpc/include/asm/hardirq.h b/arch/powerpc/include/asm/hardirq.h
index 38098e35b241..be6cd5aab016 100644
--- a/arch/powerpc/include/asm/hardirq.h
+++ b/arch/powerpc/include/asm/hardirq.h
@@ -31,6 +31,7 @@ DECLARE_PER_CPU(unsigned int, __softirq_pending);
#define local_softirq_pending_ref __softirq_pending
#define inc_irq_stat(index) __this_cpu_inc(irq_stat.counts[IRQ_COUNT_##index])
+void inc_irq_stat_and_enable(enum irq_stat_counts which);
#define __ARCH_IRQ_STAT
#define __ARCH_IRQ_EXIT_IRQS_DISABLED
diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c
index e67a18f62142..0a6a0e707fe8 100644
--- a/arch/powerpc/kernel/irq.c
+++ b/arch/powerpc/kernel/irq.c
@@ -87,9 +87,13 @@ u32 tau_interrupts(unsigned long cpu);
struct irq_stat_info {
const char *symbol;
const char *text;
+ int optional;
};
-#define ISE(idx, sym, txt)[IRQ_COUNT_##idx] = { .symbol = sym, .text = txt}
+/* ISE - IRQ STAT ENABLED, ISC - IRQ STAT CONDITIONAL */
+#define ISE(idx, sym, txt)[IRQ_COUNT_##idx] = { .symbol = sym, .text = txt, .optional = 0}
+#define ISC(idx, sym, txt)[IRQ_COUNT_##idx] = { .symbol = sym, .text = txt, .optional = 1}
+
static struct irq_stat_info irq_stat_info[IRQ_COUNT_MAX] __ro_after_init = {
ISE(LOC_TIMER, "LOC", " Local timer interrupts for timer event device\n"),
@@ -97,8 +101,8 @@ static struct irq_stat_info irq_stat_info[IRQ_COUNT_MAX] __ro_after_init = {
ISE(OTHER_TIMER, "LOC", " Local timer interrupts for others\n"),
ISE(SPURIOUS, "SPU", " Spurious interrupts\n"),
ISE(PMI, "PMI", " Performance monitoring interrupts\n"),
- ISE(MCE, "MCE", " Machine check exceptions\n"),
- ISE(NMI_SRESET, "NMI", " System Reset interrupts\n"),
+ ISC(MCE, "MCE", " Machine check exceptions\n"),
+ ISC(NMI_SRESET, "NMI", " System Reset interrupts\n"),
#ifdef CONFIG_PPC_WATCHDOG
ISE(WATCHDOG, "WDG", " Watchdog soft-NMI interrupts\n"),
#endif
@@ -107,11 +111,25 @@ static struct irq_stat_info irq_stat_info[IRQ_COUNT_MAX] __ro_after_init = {
#endif
};
+/*
+ * Used for default disabled counters to increment the stats and to enable the
+ * entry for /proc/interrupts output.
+ */
+static DECLARE_BITMAP(irq_stat_count_show, IRQ_COUNT_MAX) __read_mostly;
+void inc_irq_stat_and_enable(enum irq_stat_counts which)
+{
+ __this_cpu_inc(irq_stat.counts[which]);
+ set_bit(which, irq_stat_count_show);
+}
+
int arch_show_interrupts(struct seq_file *p, int prec)
{
const struct irq_stat_info *info = irq_stat_info;
for (unsigned int i = 0; i < ARRAY_SIZE(irq_stat_info); i++, info++) {
+ if (info->optional && !test_bit(i, irq_stat_count_show))
+ continue;
+
seq_printf(p, "%*s:", prec, info->symbol);
irq_proc_emit_counts(p, &irq_stat.counts[i]);
seq_puts(p, info->text);
@@ -138,6 +156,19 @@ int arch_show_interrupts(struct seq_file *p, int prec)
return 0;
}
+static int __init irq_init_stats(void)
+{
+ struct irq_stat_info *info = irq_stat_info;
+
+ for (unsigned int i = 0; i < ARRAY_SIZE(irq_stat_info); i++, info++) {
+ if (info->optional == 0)
+ set_bit(i, irq_stat_count_show);
+ }
+
+ return 0;
+}
+late_initcall(irq_init_stats);
+
/*
* /proc/stat helpers
*/
diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c
index a8f15154bd9a..3eacbd20fc80 100644
--- a/arch/powerpc/kernel/traps.c
+++ b/arch/powerpc/kernel/traps.c
@@ -459,7 +459,7 @@ DEFINE_INTERRUPT_HANDLER_NMI(system_reset_exception)
}
hv_nmi_check_nonrecoverable(regs);
- inc_irq_stat(NMI_SRESET);
+ inc_irq_stat_and_enable(IRQ_COUNT_NMI_SRESET);
/* See if any machine dependent calls */
if (ppc_md.system_reset_exception) {
@@ -816,7 +816,7 @@ static void __machine_check_exception(struct pt_regs *regs)
{
int recover = 0;
- inc_irq_stat(MCE);
+ inc_irq_stat_and_enable(IRQ_COUNT_MCE);
add_taint(TAINT_MACHINE_CHECK, LOCKDEP_NOW_UNRELIABLE);
--
2.47.3
^ permalink raw reply related
* [PATCH v2 2/3] powerpc/irq: Make irqstats array based
From: Shrikanth Hegde @ 2026-05-29 12:40 UTC (permalink / raw)
To: christophe.leroy, maddy, linuxppc-dev, tglx
Cc: sshegde, linux-kernel, Christophe Leroy (CS GROUP)
In-Reply-To: <20260529124045.1208539-1-sshegde@linux.ibm.com>
Current irq_cpustat_t has separate member for handling each arch
specific interrupt type. The same can be achieved with array instead
indexed by corresponding irq counter type.
This helps to,
- Make it easy to integrate into genirq improvements by calling
genirq provided irq_proc_emit_counts. That speeds up quite a bit
by printing all 0's once as much as possible.
- Adding a new vector or software counter only requires to update the table
and everything just works
- Remove ifdef usage a bit.
- Instead of going through each member, it simply becomes an array
traversal.
Time taken to read /proc/interrupts 1000 times.
Base and v6 details can be found in cover-letter.
Base : 103us
v6 : 63us
v6+this_patch : 57us
A Decent 10% reduction can be seen in a system 240 CPUs. As the system
size increases the gain would be more as emitting 0 would reduce more
and more.
Reviewed-by: Christophe Leroy (CS GROUP) <chleroy@kernel.org>
Signed-off-by: Shrikanth Hegde <sshegde@linux.ibm.com>
---
arch/powerpc/include/asm/hardirq.h | 27 +++++---
arch/powerpc/kernel/dbell.c | 2 +-
arch/powerpc/kernel/irq.c | 107 ++++++++++-------------------
arch/powerpc/kernel/time.c | 6 +-
arch/powerpc/kernel/traps.c | 11 ++-
arch/powerpc/kernel/watchdog.c | 2 +-
6 files changed, 64 insertions(+), 91 deletions(-)
diff --git a/arch/powerpc/include/asm/hardirq.h b/arch/powerpc/include/asm/hardirq.h
index bf3926a0c69c..38098e35b241 100644
--- a/arch/powerpc/include/asm/hardirq.h
+++ b/arch/powerpc/include/asm/hardirq.h
@@ -5,26 +5,33 @@
#include <linux/threads.h>
#include <linux/irq.h>
-typedef struct {
- unsigned int timer_irqs_event;
- unsigned int broadcast_irqs_event;
- unsigned int timer_irqs_others;
- unsigned int pmu_irqs;
- unsigned int mce_exceptions;
- unsigned int spurious_irqs;
- unsigned int sreset_irqs;
+enum irq_stat_counts {
+ IRQ_COUNT_LOC_TIMER,
+ IRQ_COUNT_BCT_TIMER,
+ IRQ_COUNT_OTHER_TIMER,
+ IRQ_COUNT_SPURIOUS,
+ IRQ_COUNT_PMI,
+ IRQ_COUNT_MCE,
+ IRQ_COUNT_NMI_SRESET,
#ifdef CONFIG_PPC_WATCHDOG
- unsigned int soft_nmi_irqs;
+ IRQ_COUNT_WATCHDOG,
#endif
#ifdef CONFIG_PPC_DOORBELL
- unsigned int doorbell_irqs;
+ IRQ_COUNT_DOORBELL,
#endif
+ IRQ_COUNT_MAX,
+};
+
+typedef struct {
+ unsigned int counts[IRQ_COUNT_MAX];
} ____cacheline_aligned irq_cpustat_t;
DECLARE_PER_CPU_SHARED_ALIGNED(irq_cpustat_t, irq_stat);
DECLARE_PER_CPU(unsigned int, __softirq_pending);
#define local_softirq_pending_ref __softirq_pending
+#define inc_irq_stat(index) __this_cpu_inc(irq_stat.counts[IRQ_COUNT_##index])
+
#define __ARCH_IRQ_STAT
#define __ARCH_IRQ_EXIT_IRQS_DISABLED
diff --git a/arch/powerpc/kernel/dbell.c b/arch/powerpc/kernel/dbell.c
index 5712dd846263..f5e298a4c4c0 100644
--- a/arch/powerpc/kernel/dbell.c
+++ b/arch/powerpc/kernel/dbell.c
@@ -31,7 +31,7 @@ DEFINE_INTERRUPT_HANDLER_ASYNC(doorbell_exception)
do_hard_irq_enable();
kvmppc_clear_host_ipi(smp_processor_id());
- __this_cpu_inc(irq_stat.doorbell_irqs);
+ inc_irq_stat(DOORBELL);
smp_ipi_demux_relaxed(); /* already performed the barrier */
diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c
index f33df5e5c23f..e67a18f62142 100644
--- a/arch/powerpc/kernel/irq.c
+++ b/arch/powerpc/kernel/irq.c
@@ -84,79 +84,57 @@ u32 tau_interrupts(unsigned long cpu);
#endif
#endif /* CONFIG_PPC32 */
+struct irq_stat_info {
+ const char *symbol;
+ const char *text;
+};
+
+#define ISE(idx, sym, txt)[IRQ_COUNT_##idx] = { .symbol = sym, .text = txt}
+
+static struct irq_stat_info irq_stat_info[IRQ_COUNT_MAX] __ro_after_init = {
+ ISE(LOC_TIMER, "LOC", " Local timer interrupts for timer event device\n"),
+ ISE(BCT_TIMER, "BCT", " Broadcast timer interrupts for timer event device\n"),
+ ISE(OTHER_TIMER, "LOC", " Local timer interrupts for others\n"),
+ ISE(SPURIOUS, "SPU", " Spurious interrupts\n"),
+ ISE(PMI, "PMI", " Performance monitoring interrupts\n"),
+ ISE(MCE, "MCE", " Machine check exceptions\n"),
+ ISE(NMI_SRESET, "NMI", " System Reset interrupts\n"),
+#ifdef CONFIG_PPC_WATCHDOG
+ ISE(WATCHDOG, "WDG", " Watchdog soft-NMI interrupts\n"),
+#endif
+#ifdef CONFIG_PPC_DOORBELL
+ ISE(DOORBELL, "DBL", " Doorbell interrupts\n"),
+#endif
+};
+
int arch_show_interrupts(struct seq_file *p, int prec)
{
- int j;
+ const struct irq_stat_info *info = irq_stat_info;
+
+ for (unsigned int i = 0; i < ARRAY_SIZE(irq_stat_info); i++, info++) {
+ seq_printf(p, "%*s:", prec, info->symbol);
+ irq_proc_emit_counts(p, &irq_stat.counts[i]);
+ seq_puts(p, info->text);
+ }
#if defined(CONFIG_PPC32) && defined(CONFIG_TAU_INT)
if (tau_initialized) {
+ int j;
seq_printf(p, "%*s:", prec, "TAU");
for_each_online_cpu(j)
seq_put_decimal_ull_width(p, " ", tau_interrupts(j), 10);
seq_puts(p, " PowerPC Thermal Assist (cpu temp)\n");
}
#endif /* CONFIG_PPC32 && CONFIG_TAU_INT */
-
- seq_printf(p, "%*s:", prec, "LOC");
- for_each_online_cpu(j)
- seq_put_decimal_ull_width(p, " ", per_cpu(irq_stat, j).timer_irqs_event, 10);
- seq_printf(p, " Local timer interrupts for timer event device\n");
-
- seq_printf(p, "%*s:", prec, "BCT");
- for_each_online_cpu(j)
- seq_put_decimal_ull_width(p, " ", per_cpu(irq_stat, j).broadcast_irqs_event, 10);
- seq_printf(p, " Broadcast timer interrupts for timer event device\n");
-
- seq_printf(p, "%*s:", prec, "LOC");
- for_each_online_cpu(j)
- seq_put_decimal_ull_width(p, " ", per_cpu(irq_stat, j).timer_irqs_others, 10);
- seq_printf(p, " Local timer interrupts for others\n");
-
- seq_printf(p, "%*s:", prec, "SPU");
- for_each_online_cpu(j)
- seq_put_decimal_ull_width(p, " ", per_cpu(irq_stat, j).spurious_irqs, 10);
- seq_printf(p, " Spurious interrupts\n");
-
- seq_printf(p, "%*s:", prec, "PMI");
- for_each_online_cpu(j)
- seq_put_decimal_ull_width(p, " ", per_cpu(irq_stat, j).pmu_irqs, 10);
- seq_printf(p, " Performance monitoring interrupts\n");
-
- seq_printf(p, "%*s:", prec, "MCE");
- for_each_online_cpu(j)
- seq_put_decimal_ull_width(p, " ", per_cpu(irq_stat, j).mce_exceptions, 10);
- seq_printf(p, " Machine check exceptions\n");
-
#ifdef CONFIG_PPC_BOOK3S_64
if (cpu_has_feature(CPU_FTR_HVMODE)) {
+ int j;
seq_printf(p, "%*s:", prec, "HMI");
for_each_online_cpu(j)
seq_put_decimal_ull_width(p, " ", paca_ptrs[j]->hmi_irqs, 10);
seq_printf(p, " Hypervisor Maintenance Interrupts\n");
}
#endif
-
- seq_printf(p, "%*s:", prec, "NMI");
- for_each_online_cpu(j)
- seq_put_decimal_ull_width(p, " ", per_cpu(irq_stat, j).sreset_irqs, 10);
- seq_printf(p, " System Reset interrupts\n");
-
-#ifdef CONFIG_PPC_WATCHDOG
- seq_printf(p, "%*s:", prec, "WDG");
- for_each_online_cpu(j)
- seq_put_decimal_ull_width(p, " ", per_cpu(irq_stat, j).soft_nmi_irqs, 10);
- seq_printf(p, " Watchdog soft-NMI interrupts\n");
-#endif
-
-#ifdef CONFIG_PPC_DOORBELL
- if (cpu_has_feature(CPU_FTR_DBELL)) {
- seq_printf(p, "%*s:", prec, "DBL");
- for_each_online_cpu(j)
- seq_put_decimal_ull_width(p, " ", per_cpu(irq_stat, j).doorbell_irqs, 10);
- seq_printf(p, " Doorbell interrupts\n");
- }
-#endif
-
return 0;
}
@@ -165,24 +143,15 @@ int arch_show_interrupts(struct seq_file *p, int prec)
*/
u64 arch_irq_stat_cpu(unsigned int cpu)
{
- u64 sum = per_cpu(irq_stat, cpu).timer_irqs_event;
+ irq_cpustat_t *p = per_cpu_ptr(&irq_stat, cpu);
+ u64 sum = 0;
+
+ for (unsigned int i = 0; i < ARRAY_SIZE(irq_stat_info); i++)
+ sum += p->counts[i];
- sum += per_cpu(irq_stat, cpu).broadcast_irqs_event;
- sum += per_cpu(irq_stat, cpu).pmu_irqs;
- sum += per_cpu(irq_stat, cpu).mce_exceptions;
- sum += per_cpu(irq_stat, cpu).spurious_irqs;
- sum += per_cpu(irq_stat, cpu).timer_irqs_others;
#ifdef CONFIG_PPC_BOOK3S_64
sum += paca_ptrs[cpu]->hmi_irqs;
#endif
- sum += per_cpu(irq_stat, cpu).sreset_irqs;
-#ifdef CONFIG_PPC_WATCHDOG
- sum += per_cpu(irq_stat, cpu).soft_nmi_irqs;
-#endif
-#ifdef CONFIG_PPC_DOORBELL
- sum += per_cpu(irq_stat, cpu).doorbell_irqs;
-#endif
-
return sum;
}
@@ -248,7 +217,7 @@ static void __do_irq(struct pt_regs *regs, unsigned long oldsp)
/* And finally process it */
if (unlikely(!irq))
- __this_cpu_inc(irq_stat.spurious_irqs);
+ inc_irq_stat(SPURIOUS);
else
generic_handle_irq(irq);
diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c
index b4472288e0d4..5794adc2e8df 100644
--- a/arch/powerpc/kernel/time.c
+++ b/arch/powerpc/kernel/time.c
@@ -574,13 +574,13 @@ DEFINE_INTERRUPT_HANDLER_ASYNC(timer_interrupt)
now = get_tb();
if (now >= *next_tb) {
evt->event_handler(evt);
- __this_cpu_inc(irq_stat.timer_irqs_event);
+ inc_irq_stat(LOC_TIMER);
} else {
now = *next_tb - now;
if (now > decrementer_max)
now = decrementer_max;
set_dec_or_work(now);
- __this_cpu_inc(irq_stat.timer_irqs_others);
+ inc_irq_stat(OTHER_TIMER);
}
trace_timer_interrupt_exit(regs);
@@ -593,7 +593,7 @@ EXPORT_SYMBOL(timer_interrupt);
void timer_broadcast_interrupt(void)
{
tick_receive_broadcast();
- __this_cpu_inc(irq_stat.broadcast_irqs_event);
+ inc_irq_stat(BCT_TIMER);
}
#endif
diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c
index cb8e9357383e..a8f15154bd9a 100644
--- a/arch/powerpc/kernel/traps.c
+++ b/arch/powerpc/kernel/traps.c
@@ -459,8 +459,7 @@ DEFINE_INTERRUPT_HANDLER_NMI(system_reset_exception)
}
hv_nmi_check_nonrecoverable(regs);
-
- __this_cpu_inc(irq_stat.sreset_irqs);
+ inc_irq_stat(NMI_SRESET);
/* See if any machine dependent calls */
if (ppc_md.system_reset_exception) {
@@ -817,7 +816,7 @@ static void __machine_check_exception(struct pt_regs *regs)
{
int recover = 0;
- __this_cpu_inc(irq_stat.mce_exceptions);
+ inc_irq_stat(MCE);
add_taint(TAINT_MACHINE_CHECK, LOCKDEP_NOW_UNRELIABLE);
@@ -1932,8 +1931,7 @@ DEFINE_INTERRUPT_HANDLER(vsx_unavailable_tm)
DECLARE_INTERRUPT_HANDLER_NMI(performance_monitor_exception_nmi);
DEFINE_INTERRUPT_HANDLER_NMI(performance_monitor_exception_nmi)
{
- __this_cpu_inc(irq_stat.pmu_irqs);
-
+ inc_irq_stat(PMI);
perf_irq(regs);
return 0;
@@ -1943,8 +1941,7 @@ DEFINE_INTERRUPT_HANDLER_NMI(performance_monitor_exception_nmi)
DECLARE_INTERRUPT_HANDLER_ASYNC(performance_monitor_exception_async);
DEFINE_INTERRUPT_HANDLER_ASYNC(performance_monitor_exception_async)
{
- __this_cpu_inc(irq_stat.pmu_irqs);
-
+ inc_irq_stat(PMI);
perf_irq(regs);
}
diff --git a/arch/powerpc/kernel/watchdog.c b/arch/powerpc/kernel/watchdog.c
index 764001deb060..f516eeccc9f6 100644
--- a/arch/powerpc/kernel/watchdog.c
+++ b/arch/powerpc/kernel/watchdog.c
@@ -381,7 +381,7 @@ DEFINE_INTERRUPT_HANDLER_NMI(soft_nmi_interrupt)
if (!cpumask_test_cpu(cpu, &wd_cpus_enabled))
return 0;
- __this_cpu_inc(irq_stat.soft_nmi_irqs);
+ inc_irq_stat(WATCHDOG);
tb = get_tb();
if (tb - per_cpu(wd_timer_tb, cpu) >= wd_panic_timeout_tb) {
--
2.47.3
^ permalink raw reply related
* Re: PowerPC: Random memory corruption causing kernel oops on Power11
From: Venkat Rao Bagalkote @ 2026-05-29 13:37 UTC (permalink / raw)
To: linuxppc-dev, Madhavan Srinivasan, selinux, rppt, paul
Cc: LKML, Ritesh Harjani, Christophe Leroy (CS GROUP)
In-Reply-To: <03e5151a-f420-46f9-ad5e-109420132021@linux.ibm.com>
On 29/05/26 12:20 pm, Venkat Rao Bagalkote wrote:
> Greetings!!!
>
> Kernel 7.1.0-rc5-next-20260528 crashes randomly on IBM Power11
> hardware. Attached is the config file.
>
> **System:**
> - Hardware: IBM 9080-HEX Power11, pSeries
> - Broken: 7.1.0-rc5-next-20260528
> - Config: 64K pages, Radix MMU
>
>
> **Problem:**
> Different crash at each reboot.
>
>
> **Example Crash 1:**
>
> [ 4.678016] BUG: Unable to handle kernel data access at
> 0xbffffffefec10628
> [ 4.678112] NIP [c008000004e3c74c]
> xfs_dir2_block_lookup_int+0xd4/0x300 [xfs]
> [ 4.678281] [c000000005eaf7d0] [c008000004e3c6d4]
> xfs_dir2_block_lookup_int+0x5c/0x300 [xfs]
> [ 4.678363] [c000000005eaf850] [c008000004e3d56c]
> xfs_dir2_block_lookup+0x44/0x1e0 [xfs]
>
>
> **Example Crash 2:**
>
> [ 6.327116] BUG: Unable to handle kernel data access at
> 0x762f736563697695
> [ 6.327242] NIP [c00000000073cf34] __refill_obj_stock+0x74/0x2c0
> [ 6.327261] [c0000013ffdbfd10] [c0000000007418b8]
> obj_cgroup_uncharge+0x48/0x70
> [ 6.327271] [c0000013ffdbfd50] [c00000000062fffc]
> free_percpu.part.0+0x12c/0x630
>
>
Git bisect is pointing to 54067bacb49c selinux: hooks: use __getname()
to allocate path buffer as the first bad commit.
# git bisect good
54067bacb49caeada82b20b6bd706dca0cb99ffc is the first bad commit
commit 54067bacb49caeada82b20b6bd706dca0cb99ffc
Author: Mike Rapoport (Microsoft) <rppt@kernel.org>
Date: Wed May 20 11:18:56 2026 +0300
selinux: hooks: use __getname() to allocate path buffer
selinux_genfs_get_sid() allocates memory for a path with
__get_free_page()
although there is a dedicated helper for allocation of file paths:
__getname().
Replace __get_free_page() for allocation of a path buffer with
__getname().
Signed-off-by: Mike Rapoport (Microsoft) <rppt@kernel.org>
Signed-off-by: Paul Moore <paul@paul-moore.com>
security/selinux/hooks.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
# git bisect log
git bisect start
# status: waiting for both good and bad commits
# good: [e7ae89a0c97ce2b68b0983cd01eda67cf373517d] Linux 7.1-rc5
git bisect good e7ae89a0c97ce2b68b0983cd01eda67cf373517d
# status: waiting for bad commit, 1 good commit known
# bad: [f7af91adc230aa99e23330ecf85bc9badd9780ad] Add linux-next
specific files for 20260528
git bisect bad f7af91adc230aa99e23330ecf85bc9badd9780ad
# good: [7189ebc81d5e4cb4e03dc4040b07c582b95b09d5] Merge branch
'nand/next' of https://git.kernel.org/pub/scm/linux/kernel/git/mtd/linux.git
git bisect good 7189ebc81d5e4cb4e03dc4040b07c582b95b09d5
# skip: [d22aa6f023f3fc275e1f994045a6b347288b2e5a] Merge branch
'watchdog-next' of
https://git.kernel.org/pub/scm/linux/kernel/git/groeck/linux-staging.git
git bisect skip d22aa6f023f3fc275e1f994045a6b347288b2e5a
# good: [40d5349aaaae55ec62451bfacc6189cf44ce02cb] iio: adc: ti-ads1298:
Add parentheses around macro parameter
git bisect good 40d5349aaaae55ec62451bfacc6189cf44ce02cb
# good: [6665ab5cf8e74edba571d3d2f31e575f89373dfd] Merge branch
'next-integrity' of
https://git.kernel.org/pub/scm/linux/kernel/git/zohar/linux-integrity
git bisect good 6665ab5cf8e74edba571d3d2f31e575f89373dfd
# bad: [4cc60db652df7ae5d659ec23325c341a52d065e0] Merge branch
'driver-core-next' of
https://git.kernel.org/pub/scm/linux/kernel/git/driver-core/driver-core.git
git bisect bad 4cc60db652df7ae5d659ec23325c341a52d065e0
# bad: [e1d469c38defe7fcb8c6f62a2b7dbf4a103da300] Merge branch 'master'
of https://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git
git bisect bad e1d469c38defe7fcb8c6f62a2b7dbf4a103da300
# good: [4678d11f294de0fd295a265e02955b5d1a4a2684] Merge branch into
tip/master: 'x86/tdx'
git bisect good 4678d11f294de0fd295a265e02955b5d1a4a2684
# bad: [9397e02d718fc52703d753f489042293cd807dd3] Merge branch 'next' of
https://git.kernel.org/pub/scm/linux/kernel/git/pcmoore/audit.git
git bisect bad 9397e02d718fc52703d753f489042293cd807dd3
# good: [c574bdb524095d24169e229b2e3b9318c72e733a] watchdog:
ziirave_wdt: Use named initializers for struct i2c_device_id
git bisect good c574bdb524095d24169e229b2e3b9318c72e733a
# bad: [5568ff6b5e30c7736c24e2096e968c8785c2c245] Merge branch
'for-next-tpm' of
https://git.kernel.org/pub/scm/linux/kernel/git/jarkko/linux-tpmdd.git
git bisect bad 5568ff6b5e30c7736c24e2096e968c8785c2c245
# bad: [23f6b2756d28e76464c7e87850d3d4f6d8c8b365] Merge branch 'next' of
https://git.kernel.org/pub/scm/linux/kernel/git/pcmoore/selinux.git
git bisect bad 23f6b2756d28e76464c7e87850d3d4f6d8c8b365
# good: [ecf41f6218b58c72f1511e395e480f70a9f44889] selinux: reorder
policydb_index()
git bisect good ecf41f6218b58c72f1511e395e480f70a9f44889
# bad: [54067bacb49caeada82b20b6bd706dca0cb99ffc] selinux: hooks: use
__getname() to allocate path buffer
git bisect bad 54067bacb49caeada82b20b6bd706dca0cb99ffc
# good: [2f0af91353cb64b54cfee5423820d2149039338d] selinux: check for
simple types
git bisect good 2f0af91353cb64b54cfee5423820d2149039338d
# good: [bc3f08d1ef15ebbd32faf0b10cd9699b90b9d30c] selinux: use
k[mz]alloc() to allocate temporary buffers
git bisect good bc3f08d1ef15ebbd32faf0b10cd9699b90b9d30c
# first bad commit: [54067bacb49caeada82b20b6bd706dca0cb99ffc] selinux:
hooks: use __getname() to allocate path buffer
> If you happen to fix this, please add below tag.
>
> Reported-by: Venkat Rao Bagalkote <venkat88@linux.ibm.com>
>
>
> Regards,
>
> Venkat.
>
^ permalink raw reply
* [mainline]selftests/bpf: task_local_data_race test crashes on PowerPC
From: Venkat Rao Bagalkote @ 2026-05-29 13:45 UTC (permalink / raw)
To: bpf, Saket Kumar Bhaskar, Hari Bathini, Alexei Starovoitov
Cc: Madhavan Srinivasan, linuxppc-dev, LKML
Greetings!!!
The task_local_data_race selftest crashes with segfault on PowerPC 64-bit.
**Test Failure:**
#466/2 task_local_data/task_local_data_race:FAIL
Caught signal #11!
Segmentation fault (core dumped)
**Architecture:** PowerPC 64-bit (ppc64le)
**Kernel:** 7.1.0-rc5-00149-g8fde5d1d47f6
libbpf: map 'test_tas.bss': created successfully, fd=7
test_task_local_data_race:PASS:skel_open_and_load 0 nsec
test_task_local_data_race:PASS:calloc tld_keys 0 nsec
test_task_local_data_race:PASS:TLD_DEFINE_KEY 0 nsec
test_task_local_data_race:FAIL:273
Caught signal #11!
Stack trace:
./test_progs(crash_handler+0x34) [0x106b5874]
linux-vdso64.so.1(__kernel_sigtramp_rt64+0x0) [0x7fffa4660474]
./test_progs() [0x105bed50]
./test_progs(test_task_local_data+0x64) [0x105c0094]
./test_progs() [0x106b6064]
./test_progs(main+0x7ac) [0x106b82ac]
/lib64/libc.so.6(+0x2b224) [0x7fffa3cfb224]
/lib64/libc.so.6(__libc_start_main+0x1bc) [0x7fffa3cfb47c]
Segmentation fault (core dumped)
If you happen to fix this, please add below tag.
Reported-by: Venkat Rao Bagalkote <venkat88@linux.ibm.com>
Regards,
Venkat.
^ permalink raw reply
* [mainline] selftests/bpf: struct_ops_assoc test hangs indefinitely on PowerPC
From: Venkat Rao Bagalkote @ 2026-05-29 13:52 UTC (permalink / raw)
To: bpf
Cc: netdev@vger.kernel.org, linuxppc-dev, Alexei Starovoitov,
Daniel Borkmann, Andrii Nakryiko, Martin KaFai Lau, LKML,
Madhavan Srinivasan, Hari Bathini, Saket Kumar Bhaskar
Greetings!!!
The struct_ops_assoc/st_ops_assoc_in_timer selftest hangs indefinitely on
PowerPC, spinning in sched_yield() until watchdog timeout.
**Test Failure:**
./test_progs -t struct_ops_assoc
WATCHDOG: test case struct_ops_assoc/st_ops_assoc_in_timer executes for
10 seconds...
WATCHDOG: test case struct_ops_assoc/st_ops_assoc_in_timer executes for
120 seconds, terminating with SIGSEGV
#445 struct_ops_assoc:FAIL
**Architecture:** PowerPC 64-bit (ppc64le)
**Kernel:** 7.1.0-rc5-00149-g8fde5d1d47f6
**Symptoms:**
Test hangs indefinitely in infinite loop, repeatedly calling sched_yield():
Stack trace:
./test_progs(crash_handler+0x34)
linux-vdso64.so.1(__kernel_sigtramp_rt64+0x0)
/lib64/libc.so.6(__sched_yield+0x2c) ← stuck here
./test_progs() [0x105ae220]
./test_progs(test_struct_ops_assoc+0x88)
./test_progs(main+0x7ac)
If you happen to fix this, please add below tag.
Reported-by: Venkat Rao Bagalkote <venkat88@linux.ibm.com>
Regards,
Venkat.
^ permalink raw reply
* [PATCH v3] powerpc/pseries/Kconfig: Enable CONFIG_VPA_PMU to be used with KVM
From: Gautam Menghani @ 2026-05-29 14:10 UTC (permalink / raw)
To: maddy, mpe, npiggin, chleroy
Cc: Gautam Menghani, linuxppc-dev, linux-kernel, atrajeev, harshpb,
stable, Sean Christopherson
Currently, CONFIG_VPA_PMU is not enabled any of the configs, and
consequently cannot be used for KVM guests at all.
Mark CONFIG_VPA_PMU as "default m" to ensure it is available when KVM is
being used.
Fixes: 176cda0619b6c ("powerpc/perf: Add perf interface to expose vpa counters")
Cc: stable@vger.kernel.org # v6.13+
Suggested-by: Sean Christopherson <seanjc@google.com>
Signed-off-by: Gautam Menghani <gautam@linux.ibm.com>
---
v2 -> v3:
1. Make CONFIG_VPA_PMU as default m so that it can separately disabled
(Sean)
v1 -> v2:
1. Rebased on latest master
arch/powerpc/platforms/pseries/Kconfig | 1 +
1 file changed, 1 insertion(+)
diff --git a/arch/powerpc/platforms/pseries/Kconfig b/arch/powerpc/platforms/pseries/Kconfig
index f7052b131a4c..74910ce3a541 100644
--- a/arch/powerpc/platforms/pseries/Kconfig
+++ b/arch/powerpc/platforms/pseries/Kconfig
@@ -154,6 +154,7 @@ config HV_PERF_CTRS
config VPA_PMU
tristate "VPA PMU events"
depends on KVM_BOOK3S_64_HV && HV_PERF_CTRS
+ default m
help
Enable access to the VPA PMU counters via perf. This enables
code that support measurement for KVM on PowerVM(KoP) feature.
--
2.53.0
^ permalink raw reply related
* Re: [PATCH v6 09/15] arm64: Move fixmap and kasan page tables to end of kernel image
From: Kevin Brodsky @ 2026-05-29 14:42 UTC (permalink / raw)
To: Ard Biesheuvel, Ard Biesheuvel, linux-arm-kernel
Cc: linux-kernel, Will Deacon, Catalin Marinas, Mark Rutland,
Ryan Roberts, Anshuman Khandual, Liz Prucka, Seth Jenkins,
Kees Cook, Mike Rapoport, David Hildenbrand, Andrew Morton,
Jann Horn, linux-mm, linux-hardening, linuxppc-dev, linux-sh
In-Reply-To: <96a8b6b9-71f2-4550-bbbb-fbfa146f4e6a@app.fastmail.com>
On 29/05/2026 13:19, Ard Biesheuvel wrote:
> On Fri, 29 May 2026, at 10:27, Kevin Brodsky wrote:
>> On 26/05/2026 19:58, Ard Biesheuvel wrote:
>>> From: Ard Biesheuvel <ardb@kernel.org>
>>>
>>> Move the fixmap and kasan page tables out of the BSS section, and place
>>> them at the end of the image, right before the init_pg_dir section where
>>> some of the other statically allocated page tables live.
>>>
>>> These page tables are currently the only data objects in vmlinux that
>>> are meant to be accessed via the kernel image's linear alias, and so
>>> placing them together allows the remainder of the data/bss section to be
>>> remapped read-only or unmapped entirely.
>>>
>>> Reviewed-by: Kevin Brodsky <kevin.brodsky@arm.com>
>>> Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
>>> ---
>>> arch/arm64/include/asm/mmu.h | 2 ++
>>> arch/arm64/kernel/vmlinux.lds.S | 8 +++++++-
>>> arch/arm64/mm/fixmap.c | 6 +++---
>>> arch/arm64/mm/kasan_init.c | 2 +-
>>> 4 files changed, 13 insertions(+), 5 deletions(-)
>>>
>>> diff --git a/arch/arm64/include/asm/mmu.h b/arch/arm64/include/asm/mmu.h
>>> index 5e1211c540ab..fb95754f2876 100644
>>> --- a/arch/arm64/include/asm/mmu.h
>>> +++ b/arch/arm64/include/asm/mmu.h
>>> @@ -13,6 +13,8 @@
>>>
>>> #ifndef __ASSEMBLER__
>>>
>>> +#define __pgtbl_bss __section(".pgdir.bss") __aligned(PAGE_SIZE)
>>> +
>>> #include <linux/refcount.h>
>>> #include <asm/cpufeature.h>
>>>
>>> diff --git a/arch/arm64/kernel/vmlinux.lds.S b/arch/arm64/kernel/vmlinux.lds.S
>>> index e1ac876200a3..2b0ebfb30c63 100644
>>> --- a/arch/arm64/kernel/vmlinux.lds.S
>>> +++ b/arch/arm64/kernel/vmlinux.lds.S
>>> @@ -349,9 +349,15 @@ SECTIONS
>>> _edata = .;
>>>
>>> /* start of zero-init region */
>>> - BSS_SECTION(SBSS_ALIGN, 0, 0)
>>> + BSS_SECTION(SBSS_ALIGN, 0, PAGE_SIZE)
>>> __pi___bss_start = __bss_start;
>>>
>>> + /* fixmap BSS starts here - preceding data/BSS is omitted from the linear map */
>>> + .pgdir.bss (NOLOAD) : ALIGN(PAGE_SIZE) {
>> Do we actually need the NOLOAD type here?
> Yes, otherwise it is emitted as PROGBITS, resulting in all of BSS to be
> emitted into Image.
That's rather strange, aren't the .pgdir.bss input sections already
NOBITS since __pgtbl_bss is only used on default-initialised globals?
Also AFAIU NOLOAD does not prevent the output section from being emitted
into the ELF file.
- Kevin
^ 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