Skip to content

Commit 7bb7977

Browse files
Ye Binwilldeacon
authored andcommitted
arm64/cpuinfo: only show one cpu's info in c_show()
Currently, when ARM64 displays CPU information, every call to c_show() assembles all CPU information. However, as the number of CPUs increases, this can lead to insufficient buffer space due to excessive assembly in a single call, causing repeated expansion and multiple calls to c_show(). To prevent this invalid c_show() call, only one CPU's information is assembled each time c_show() is called. Signed-off-by: Ye Bin <yebin10@huawei.com> Link: https://lore.kernel.org/r/20250421062947.4072855-1-yebin@huaweicloud.com Signed-off-by: Will Deacon <will@kernel.org>
1 parent 83a39ec commit 7bb7977

File tree

1 file changed

+53
-54
lines changed

1 file changed

+53
-54
lines changed

arch/arm64/kernel/cpuinfo.c

Lines changed: 53 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -209,80 +209,79 @@ static const char *const compat_hwcap2_str[] = {
209209

210210
static int c_show(struct seq_file *m, void *v)
211211
{
212-
int i, j;
212+
int j;
213+
int cpu = m->index;
213214
bool compat = personality(current->personality) == PER_LINUX32;
215+
struct cpuinfo_arm64 *cpuinfo = v;
216+
u32 midr = cpuinfo->reg_midr;
214217

215-
for_each_online_cpu(i) {
216-
struct cpuinfo_arm64 *cpuinfo = &per_cpu(cpu_data, i);
217-
u32 midr = cpuinfo->reg_midr;
218-
219-
/*
220-
* glibc reads /proc/cpuinfo to determine the number of
221-
* online processors, looking for lines beginning with
222-
* "processor". Give glibc what it expects.
223-
*/
224-
seq_printf(m, "processor\t: %d\n", i);
225-
if (compat)
226-
seq_printf(m, "model name\t: ARMv8 Processor rev %d (%s)\n",
227-
MIDR_REVISION(midr), COMPAT_ELF_PLATFORM);
218+
/*
219+
* glibc reads /proc/cpuinfo to determine the number of
220+
* online processors, looking for lines beginning with
221+
* "processor". Give glibc what it expects.
222+
*/
223+
seq_printf(m, "processor\t: %d\n", cpu);
224+
if (compat)
225+
seq_printf(m, "model name\t: ARMv8 Processor rev %d (%s)\n",
226+
MIDR_REVISION(midr), COMPAT_ELF_PLATFORM);
228227

229-
seq_printf(m, "BogoMIPS\t: %lu.%02lu\n",
230-
loops_per_jiffy / (500000UL/HZ),
231-
loops_per_jiffy / (5000UL/HZ) % 100);
228+
seq_printf(m, "BogoMIPS\t: %lu.%02lu\n",
229+
loops_per_jiffy / (500000UL/HZ),
230+
loops_per_jiffy / (5000UL/HZ) % 100);
232231

233-
/*
234-
* Dump out the common processor features in a single line.
235-
* Userspace should read the hwcaps with getauxval(AT_HWCAP)
236-
* rather than attempting to parse this, but there's a body of
237-
* software which does already (at least for 32-bit).
238-
*/
239-
seq_puts(m, "Features\t:");
240-
if (compat) {
232+
/*
233+
* Dump out the common processor features in a single line.
234+
* Userspace should read the hwcaps with getauxval(AT_HWCAP)
235+
* rather than attempting to parse this, but there's a body of
236+
* software which does already (at least for 32-bit).
237+
*/
238+
seq_puts(m, "Features\t:");
239+
if (compat) {
241240
#ifdef CONFIG_COMPAT
242-
for (j = 0; j < ARRAY_SIZE(compat_hwcap_str); j++) {
243-
if (compat_elf_hwcap & (1 << j)) {
244-
/*
245-
* Warn once if any feature should not
246-
* have been present on arm64 platform.
247-
*/
248-
if (WARN_ON_ONCE(!compat_hwcap_str[j]))
249-
continue;
250-
251-
seq_printf(m, " %s", compat_hwcap_str[j]);
252-
}
241+
for (j = 0; j < ARRAY_SIZE(compat_hwcap_str); j++) {
242+
if (compat_elf_hwcap & (1 << j)) {
243+
/*
244+
* Warn once if any feature should not
245+
* have been present on arm64 platform.
246+
*/
247+
if (WARN_ON_ONCE(!compat_hwcap_str[j]))
248+
continue;
249+
250+
seq_printf(m, " %s", compat_hwcap_str[j]);
253251
}
252+
}
254253

255-
for (j = 0; j < ARRAY_SIZE(compat_hwcap2_str); j++)
256-
if (compat_elf_hwcap2 & (1 << j))
257-
seq_printf(m, " %s", compat_hwcap2_str[j]);
254+
for (j = 0; j < ARRAY_SIZE(compat_hwcap2_str); j++)
255+
if (compat_elf_hwcap2 & (1 << j))
256+
seq_printf(m, " %s", compat_hwcap2_str[j]);
258257
#endif /* CONFIG_COMPAT */
259-
} else {
260-
for (j = 0; j < ARRAY_SIZE(hwcap_str); j++)
261-
if (cpu_have_feature(j))
262-
seq_printf(m, " %s", hwcap_str[j]);
263-
}
264-
seq_puts(m, "\n");
265-
266-
seq_printf(m, "CPU implementer\t: 0x%02x\n",
267-
MIDR_IMPLEMENTOR(midr));
268-
seq_printf(m, "CPU architecture: 8\n");
269-
seq_printf(m, "CPU variant\t: 0x%x\n", MIDR_VARIANT(midr));
270-
seq_printf(m, "CPU part\t: 0x%03x\n", MIDR_PARTNUM(midr));
271-
seq_printf(m, "CPU revision\t: %d\n\n", MIDR_REVISION(midr));
258+
} else {
259+
for (j = 0; j < ARRAY_SIZE(hwcap_str); j++)
260+
if (cpu_have_feature(j))
261+
seq_printf(m, " %s", hwcap_str[j]);
272262
}
263+
seq_puts(m, "\n");
264+
265+
seq_printf(m, "CPU implementer\t: 0x%02x\n",
266+
MIDR_IMPLEMENTOR(midr));
267+
seq_puts(m, "CPU architecture: 8\n");
268+
seq_printf(m, "CPU variant\t: 0x%x\n", MIDR_VARIANT(midr));
269+
seq_printf(m, "CPU part\t: 0x%03x\n", MIDR_PARTNUM(midr));
270+
seq_printf(m, "CPU revision\t: %d\n\n", MIDR_REVISION(midr));
273271

274272
return 0;
275273
}
276274

277275
static void *c_start(struct seq_file *m, loff_t *pos)
278276
{
279-
return *pos < 1 ? (void *)1 : NULL;
277+
*pos = cpumask_next(*pos - 1, cpu_online_mask);
278+
return *pos < nr_cpu_ids ? &per_cpu(cpu_data, *pos) : NULL;
280279
}
281280

282281
static void *c_next(struct seq_file *m, void *v, loff_t *pos)
283282
{
284283
++*pos;
285-
return NULL;
284+
return c_start(m, pos);
286285
}
287286

288287
static void c_stop(struct seq_file *m, void *v)

0 commit comments

Comments
 (0)