drivers/acpi/pptt.c | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+)
There was a bug that kernel printed error message:
" ACPI PPTT: PPTT table found, but unable to locate core 1 (1)"
and later on the kernel met issues when building up scheduler domain.
Debug showed the kernel actually brought up all 8 CPUs successfully
(MADT and other table worked fine), while the PPTT table was broken
as it only had 4 CPUs in total.
Add check for number of CPU of PPTT table against system CPU number,
and warn if they are not equal, to help debugging similar issues.
Suggested-by: Sudeep Holla <sudeep.holla@arm.com>
Signed-off-by: Feng Tang <feng.tang@linux.alibaba.com>
---
Changelog:
v3
* Only check the number of CPUs in PPTT table againt system
CPU count when error happens, instead of dump all the CPU/cache
entries (Sudeep/Rafael)
v2
* rebase againt 6.19 and refine the commit log
drivers/acpi/pptt.c | 40 ++++++++++++++++++++++++++++++++++++++++
1 file changed, 40 insertions(+)
diff --git a/drivers/acpi/pptt.c b/drivers/acpi/pptt.c
index de5f8c018333..9958c3961001 100644
--- a/drivers/acpi/pptt.c
+++ b/drivers/acpi/pptt.c
@@ -529,6 +529,43 @@ static void acpi_pptt_warn_missing(void)
pr_warn_once("No PPTT table found, CPU and cache topology may be inaccurate\n");
}
+static void pptt_verify_cpu_count(struct acpi_table_header *table_hdr)
+{
+ struct acpi_subtable_header *entry;
+ unsigned long end;
+ struct acpi_pptt_processor *cpu;
+ u8 len;
+ int nr_pptt_cpus = 0;
+ static bool checked;
+
+ if (checked)
+ return;
+
+ end = (unsigned long)table_hdr + table_hdr->length;
+ entry = ACPI_ADD_PTR(struct acpi_subtable_header, table_hdr,
+ sizeof(struct acpi_table_pptt));
+
+ while ((unsigned long)entry + sizeof(struct acpi_pptt_processor) <= end) {
+ len = entry->length;
+ if (!len) {
+ pr_warn("Invalid zero length subtable\n");
+ return;
+ }
+
+ cpu = (struct acpi_pptt_processor *)entry;
+ entry = ACPI_ADD_PTR(struct acpi_subtable_header, entry, len);
+ if (cpu->header.type == ACPI_PPTT_TYPE_PROCESSOR &&
+ (cpu->flags & ACPI_PPTT_ACPI_LEAF_NODE))
+ nr_pptt_cpus++;
+ }
+
+ if (nr_pptt_cpus != num_possible_cpus())
+ pr_warn("The number of CPUs (%d) in PPTT table doesn't match system's CPU count (%d)!\n",
+ nr_pptt_cpus, num_possible_cpus());
+
+ checked = true;
+}
+
/**
* topology_get_acpi_cpu_tag() - Find a unique topology value for a feature
* @table: Pointer to the head of the PPTT table
@@ -565,6 +602,9 @@ static int topology_get_acpi_cpu_tag(struct acpi_table_header *table,
}
pr_warn_once("PPTT table found, but unable to locate core %d (%d)\n",
cpu, acpi_cpu_id);
+
+ /* Check whether PPTT table's CPU count match with system count */
+ pptt_verify_cpu_count(table);
return -ENOENT;
}
--
2.39.5 (Apple Git-154)
On Fri, Jan 16, 2026 at 03:29:43PM +0800, Feng Tang wrote:
> There was a bug that kernel printed error message:
> " ACPI PPTT: PPTT table found, but unable to locate core 1 (1)"
> and later on the kernel met issues when building up scheduler domain.
>
> Debug showed the kernel actually brought up all 8 CPUs successfully
> (MADT and other table worked fine), while the PPTT table was broken
> as it only had 4 CPUs in total.
>
> Add check for number of CPU of PPTT table against system CPU number,
> and warn if they are not equal, to help debugging similar issues.
>
> Suggested-by: Sudeep Holla <sudeep.holla@arm.com>
> Signed-off-by: Feng Tang <feng.tang@linux.alibaba.com>
> ---
> Changelog:
>
> v3
> * Only check the number of CPUs in PPTT table againt system
> CPU count when error happens, instead of dump all the CPU/cache
> entries (Sudeep/Rafael)
>
> v2
> * rebase againt 6.19 and refine the commit log
>
> drivers/acpi/pptt.c | 40 ++++++++++++++++++++++++++++++++++++++++
> 1 file changed, 40 insertions(+)
>
> diff --git a/drivers/acpi/pptt.c b/drivers/acpi/pptt.c
> index de5f8c018333..9958c3961001 100644
> --- a/drivers/acpi/pptt.c
> +++ b/drivers/acpi/pptt.c
> @@ -529,6 +529,43 @@ static void acpi_pptt_warn_missing(void)
> pr_warn_once("No PPTT table found, CPU and cache topology may be inaccurate\n");
> }
>
> +static void pptt_verify_cpu_count(struct acpi_table_header *table_hdr)
> +{
> + struct acpi_subtable_header *entry;
> + unsigned long end;
> + struct acpi_pptt_processor *cpu;
> + u8 len;
> + int nr_pptt_cpus = 0;
> + static bool checked;
> +
> + if (checked)
> + return;
> +
> + end = (unsigned long)table_hdr + table_hdr->length;
> + entry = ACPI_ADD_PTR(struct acpi_subtable_header, table_hdr,
> + sizeof(struct acpi_table_pptt));
> +
> + while ((unsigned long)entry + sizeof(struct acpi_pptt_processor) <= end) {
> + len = entry->length;
> + if (!len) {
> + pr_warn("Invalid zero length subtable\n");
> + return;
> + }
> +
> + cpu = (struct acpi_pptt_processor *)entry;
> + entry = ACPI_ADD_PTR(struct acpi_subtable_header, entry, len);
> + if (cpu->header.type == ACPI_PPTT_TYPE_PROCESSOR &&
> + (cpu->flags & ACPI_PPTT_ACPI_LEAF_NODE))
> + nr_pptt_cpus++;
> + }
> +
> + if (nr_pptt_cpus != num_possible_cpus())
This is going to be tricky. I recall some config option that sets all
`NR_CPUS` as possible. In short it will break if that is enabled.
> + pr_warn("The number of CPUs (%d) in PPTT table doesn't match system's CPU count (%d)!\n",
> + nr_pptt_cpus, num_possible_cpus());
> +
> + checked = true;
> +}
> +
> /**
> * topology_get_acpi_cpu_tag() - Find a unique topology value for a feature
> * @table: Pointer to the head of the PPTT table
> @@ -565,6 +602,9 @@ static int topology_get_acpi_cpu_tag(struct acpi_table_header *table,
> }
> pr_warn_once("PPTT table found, but unable to locate core %d (%d)\n",
> cpu, acpi_cpu_id);
I was expecting the above log will be improved to just say possible mismatch
with cpu count.
> +
> + /* Check whether PPTT table's CPU count match with system count */
> + pptt_verify_cpu_count(table);
Today it is a request to check the CPU count; tomorrow it will be something
else in the PPTT. Where do we draw the line on PPTT validation in the kernel?
These issues ultimately need to be fixed in firmware, and the firmware
should not depend on the kernel to precisely identify what is wrong in
the PPTT tables.
--
Regards,
Sudeep
On Fri, Jan 16, 2026 at 01:52:37PM +0000, Sudeep Holla wrote:
> On Fri, Jan 16, 2026 at 03:29:43PM +0800, Feng Tang wrote:
> > There was a bug that kernel printed error message:
> > " ACPI PPTT: PPTT table found, but unable to locate core 1 (1)"
> > and later on the kernel met issues when building up scheduler domain.
> >
> > Debug showed the kernel actually brought up all 8 CPUs successfully
> > (MADT and other table worked fine), while the PPTT table was broken
> > as it only had 4 CPUs in total.
> >
> > Add check for number of CPU of PPTT table against system CPU number,
> > and warn if they are not equal, to help debugging similar issues.
> >
> > Suggested-by: Sudeep Holla <sudeep.holla@arm.com>
> > Signed-off-by: Feng Tang <feng.tang@linux.alibaba.com>
[...]
> > + cpu = (struct acpi_pptt_processor *)entry;
> > + entry = ACPI_ADD_PTR(struct acpi_subtable_header, entry, len);
> > + if (cpu->header.type == ACPI_PPTT_TYPE_PROCESSOR &&
> > + (cpu->flags & ACPI_PPTT_ACPI_LEAF_NODE))
> > + nr_pptt_cpus++;
> > + }
> > +
> > + if (nr_pptt_cpus != num_possible_cpus())
>
> This is going to be tricky. I recall some config option that sets all
> `NR_CPUS` as possible. In short it will break if that is enabled.
Thanks for the info.
> > + pr_warn("The number of CPUs (%d) in PPTT table doesn't match system's CPU count (%d)!\n",
> > + nr_pptt_cpus, num_possible_cpus());
> > +
> > + checked = true;
> > +}
> > +
> > /**
> > * topology_get_acpi_cpu_tag() - Find a unique topology value for a feature
> > * @table: Pointer to the head of the PPTT table
> > @@ -565,6 +602,9 @@ static int topology_get_acpi_cpu_tag(struct acpi_table_header *table,
> > }
> > pr_warn_once("PPTT table found, but unable to locate core %d (%d)\n",
> > cpu, acpi_cpu_id);
>
> I was expecting the above log will be improved to just say possible mismatch
> with cpu count.
Yep. it should be more explicite about the source.
> > +
> > + /* Check whether PPTT table's CPU count match with system count */
> > + pptt_verify_cpu_count(table);
>
> Today it is a request to check the CPU count; tomorrow it will be something
> else in the PPTT. Where do we draw the line on PPTT validation in the kernel?
I had similar concern, so I listed all items in orignal patch for check.
> These issues ultimately need to be fixed in firmware, and the firmware
> should not depend on the kernel to precisely identify what is wrong in
> the PPTT tables.
Ideally yes. But upon the sad experience of raising issue to BIOS vendor or
engineers, the more precise info, the sooner it gets solved and not refused.
Thanks,
Feng
© 2016 - 2026 Red Hat, Inc.