* [RFC] arm64: early_ioremap fails to map ACPI MADT on 64K pages
@ 2026-06-17 6:01 Yu Peng
2026-06-19 14:43 ` Will Deacon
0 siblings, 1 reply; 7+ messages in thread
From: Yu Peng @ 2026-06-17 6:01 UTC (permalink / raw)
To: Catalin Marinas, Will Deacon, linux-arm-kernel
Cc: Rafael J. Wysocki, Len Brown, linux-acpi, Andrew Morton,
linux-mm, linux-kernel
Hi all,
I hit an early boot failure on an arm64 system built with 64K pages while
parsing the ACPI MADT.
The failing system reports:
PAGE_SIZE: 64K
MADT physical address: 0x5a7ae018
MADT length: 0x32094
The failure happens when acpi_table_parse_madt() calls into early_memremap()
via __acpi_map_table(). The MADT itself is smaller than 256K, but its
placement causes the early mapping to require 5 64K pages:
offset within 64K page = 0x5a7ae018 & 0xffff = 0xe018
mapped range = PAGE_ALIGN(0xe018 + 0x32094)
= PAGE_ALIGN(0x400ac)
= 0x50000
nrpages = 0x50000 / 0x10000 = 5
On arm64, NR_FIX_BTMAPS is currently derived from a 256K per-slot budget:
#define NR_FIX_BTMAPS (SZ_256K / PAGE_SIZE)
So for 64K pages, NR_FIX_BTMAPS is 4. The mapping therefore fails the
early_ioremap() check:
if (WARN_ON(nrpages > NR_FIX_BTMAPS))
return NULL;
After that, MADT parsing fails and the boot continues with symptoms such as:
ACPI: APIC not present
missing boot CPU MPIDR, not enabling secondaries
Kernel panic - not syncing: No interrupt controller found.
A firmware change can avoid this by placing MADT so that:
(madt_phys & 0xffff) + madt_length <= SZ_256K
However, I do not think ACPI requires such placement, so this looks like a
kernel-side robustness issue as well, especially on large arm64 systems where
MADT can grow with CPU topology.
One possible kernel-side change is to increase the boot-time mapping budget for
CONFIG_ARM64_64K_PAGES, for example using a 512K per-slot budget only in that
configuration. I do not think this should be applied unconditionally to all
page sizes, since the arm64 early fixmap code expects the boot-ioremap range
to stay within one PMD.
Has anyone seen similar failures on arm64 64K systems?
Would maintainers prefer treating this as a firmware layout issue, or would
increasing the early_ioremap budget for 64K pages be acceptable?
Thanks,
Yu Peng
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [RFC] arm64: early_ioremap fails to map ACPI MADT on 64K pages
2026-06-17 6:01 [RFC] arm64: early_ioremap fails to map ACPI MADT on 64K pages Yu Peng
@ 2026-06-19 14:43 ` Will Deacon
2026-06-22 8:55 ` Hanjun Guo
0 siblings, 1 reply; 7+ messages in thread
From: Will Deacon @ 2026-06-19 14:43 UTC (permalink / raw)
To: Yu Peng
Cc: Catalin Marinas, linux-arm-kernel, Rafael J. Wysocki, Len Brown,
linux-acpi, Andrew Morton, linux-mm, linux-kernel, lpieralisi,
guohanjun, sudeep.holla
+arm64 ACPI maintainers
On Wed, Jun 17, 2026 at 02:01:10PM +0800, Yu Peng wrote:
> I hit an early boot failure on an arm64 system built with 64K pages while
> parsing the ACPI MADT.
>
> The failing system reports:
>
> PAGE_SIZE: 64K
> MADT physical address: 0x5a7ae018
> MADT length: 0x32094
The MADT isn't even 4k aligned, so why does the page size matter in this
case?
> The failure happens when acpi_table_parse_madt() calls into early_memremap()
> via __acpi_map_table(). The MADT itself is smaller than 256K, but its
> placement causes the early mapping to require 5 64K pages:
>
> offset within 64K page = 0x5a7ae018 & 0xffff = 0xe018
> mapped range = PAGE_ALIGN(0xe018 + 0x32094)
> = PAGE_ALIGN(0x400ac)
> = 0x50000
> nrpages = 0x50000 / 0x10000 = 5
>
> On arm64, NR_FIX_BTMAPS is currently derived from a 256K per-slot budget:
>
> #define NR_FIX_BTMAPS (SZ_256K / PAGE_SIZE)
>
> So for 64K pages, NR_FIX_BTMAPS is 4. The mapping therefore fails the
> early_ioremap() check:
>
> if (WARN_ON(nrpages > NR_FIX_BTMAPS))
> return NULL;
>
> After that, MADT parsing fails and the boot continues with symptoms such as:
>
> ACPI: APIC not present
> missing boot CPU MPIDR, not enabling secondaries
> Kernel panic - not syncing: No interrupt controller found.
>
> A firmware change can avoid this by placing MADT so that:
>
> (madt_phys & 0xffff) + madt_length <= SZ_256K
>
> However, I do not think ACPI requires such placement, so this looks like a
> kernel-side robustness issue as well, especially on large arm64 systems where
> MADT can grow with CPU topology.
>
> One possible kernel-side change is to increase the boot-time mapping budget for
> CONFIG_ARM64_64K_PAGES, for example using a 512K per-slot budget only in that
> configuration. I do not think this should be applied unconditionally to all
> page sizes, since the arm64 early fixmap code expects the boot-ioremap range
> to stay within one PMD.
>
> Has anyone seen similar failures on arm64 64K systems?
>
> Would maintainers prefer treating this as a firmware layout issue, or would
> increasing the early_ioremap budget for 64K pages be acceptable?
It think it boils down to what ACPI says about the alignment of the MADT.
Lorenzo?
Will
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [RFC] arm64: early_ioremap fails to map ACPI MADT on 64K pages
2026-06-19 14:43 ` Will Deacon
@ 2026-06-22 8:55 ` Hanjun Guo
2026-06-22 9:49 ` Lorenzo Pieralisi
0 siblings, 1 reply; 7+ messages in thread
From: Hanjun Guo @ 2026-06-22 8:55 UTC (permalink / raw)
To: Will Deacon, Yu Peng
Cc: Catalin Marinas, linux-arm-kernel, Rafael J. Wysocki, Len Brown,
linux-acpi, Andrew Morton, linux-mm, linux-kernel, lpieralisi,
sudeep.holla
On 2026/6/19 22:43, Will Deacon wrote:
> +arm64 ACPI maintainers
>
> On Wed, Jun 17, 2026 at 02:01:10PM +0800, Yu Peng wrote:
>> I hit an early boot failure on an arm64 system built with 64K pages while
>> parsing the ACPI MADT.
>>
>> The failing system reports:
>>
>> PAGE_SIZE: 64K
>> MADT physical address: 0x5a7ae018
>> MADT length: 0x32094
>
> The MADT isn't even 4k aligned, so why does the page size matter in this
> case?
>
>> The failure happens when acpi_table_parse_madt() calls into early_memremap()
>> via __acpi_map_table(). The MADT itself is smaller than 256K, but its
>> placement causes the early mapping to require 5 64K pages:
>>
>> offset within 64K page = 0x5a7ae018 & 0xffff = 0xe018
>> mapped range = PAGE_ALIGN(0xe018 + 0x32094)
>> = PAGE_ALIGN(0x400ac)
>> = 0x50000
>> nrpages = 0x50000 / 0x10000 = 5
>>
>> On arm64, NR_FIX_BTMAPS is currently derived from a 256K per-slot budget:
>>
>> #define NR_FIX_BTMAPS (SZ_256K / PAGE_SIZE)
>>
>> So for 64K pages, NR_FIX_BTMAPS is 4. The mapping therefore fails the
>> early_ioremap() check:
>>
>> if (WARN_ON(nrpages > NR_FIX_BTMAPS))
>> return NULL;
>>
>> After that, MADT parsing fails and the boot continues with symptoms such as:
>>
>> ACPI: APIC not present
>> missing boot CPU MPIDR, not enabling secondaries
>> Kernel panic - not syncing: No interrupt controller found.
>>
>> A firmware change can avoid this by placing MADT so that:
>>
>> (madt_phys & 0xffff) + madt_length <= SZ_256K
>>
>> However, I do not think ACPI requires such placement, so this looks like a
>> kernel-side robustness issue as well, especially on large arm64 systems where
>> MADT can grow with CPU topology.
>>
>> One possible kernel-side change is to increase the boot-time mapping budget for
>> CONFIG_ARM64_64K_PAGES, for example using a 512K per-slot budget only in that
>> configuration. I do not think this should be applied unconditionally to all
>> page sizes, since the arm64 early fixmap code expects the boot-ioremap range
>> to stay within one PMD.
>>
>> Has anyone seen similar failures on arm64 64K systems?
>>
>> Would maintainers prefer treating this as a firmware layout issue, or would
>> increasing the early_ioremap budget for 64K pages be acceptable?
>
> It think it boils down to what ACPI says about the alignment of the MADT.
I checked the ACPI spec and it didn't require the alignment for ACPI
tables, but in UEFI spec, it says (for aarch64):
ACPI Tables loaded at boot time can be contained in memory of type
EfiACPIReclaimMemory (recommended) or EfiACPIMemoryNVS.
EFI memory descriptors of type EfiACPIReclaimMemory and EfiACPIMemoryNVS
must be aligned on a 4 KiB boundary and must be a multiple of 4 KiB in
size.
It only requires EfiACPIReclaimMemory type to be 4K aligned, not
for each ACPI table, because ACPI tables can be packed into the
allocated EfiACPIReclaimMemory type, correct me if I'm wrong!
Thanks
Hanjun
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [RFC] arm64: early_ioremap fails to map ACPI MADT on 64K pages
2026-06-22 8:55 ` Hanjun Guo
@ 2026-06-22 9:49 ` Lorenzo Pieralisi
2026-06-23 2:47 ` Yu Peng
0 siblings, 1 reply; 7+ messages in thread
From: Lorenzo Pieralisi @ 2026-06-22 9:49 UTC (permalink / raw)
To: Hanjun Guo
Cc: Will Deacon, Yu Peng, Catalin Marinas, linux-arm-kernel,
Rafael J. Wysocki, Len Brown, linux-acpi, Andrew Morton,
linux-mm, linux-kernel, sudeep.holla
On Mon, Jun 22, 2026 at 04:55:29PM +0800, Hanjun Guo wrote:
> On 2026/6/19 22:43, Will Deacon wrote:
> > +arm64 ACPI maintainers
> >
> > On Wed, Jun 17, 2026 at 02:01:10PM +0800, Yu Peng wrote:
> > > I hit an early boot failure on an arm64 system built with 64K pages while
> > > parsing the ACPI MADT.
> > >
> > > The failing system reports:
> > >
> > > PAGE_SIZE: 64K
> > > MADT physical address: 0x5a7ae018
> > > MADT length: 0x32094
> >
> > The MADT isn't even 4k aligned, so why does the page size matter in this
> > case?
> >
> > > The failure happens when acpi_table_parse_madt() calls into early_memremap()
> > > via __acpi_map_table(). The MADT itself is smaller than 256K, but its
> > > placement causes the early mapping to require 5 64K pages:
> > >
> > > offset within 64K page = 0x5a7ae018 & 0xffff = 0xe018
> > > mapped range = PAGE_ALIGN(0xe018 + 0x32094)
> > > = PAGE_ALIGN(0x400ac)
> > > = 0x50000
> > > nrpages = 0x50000 / 0x10000 = 5
> > >
> > > On arm64, NR_FIX_BTMAPS is currently derived from a 256K per-slot budget:
> > >
> > > #define NR_FIX_BTMAPS (SZ_256K / PAGE_SIZE)
> > >
> > > So for 64K pages, NR_FIX_BTMAPS is 4. The mapping therefore fails the
> > > early_ioremap() check:
> > >
> > > if (WARN_ON(nrpages > NR_FIX_BTMAPS))
> > > return NULL;
> > >
> > > After that, MADT parsing fails and the boot continues with symptoms such as:
> > >
> > > ACPI: APIC not present
> > > missing boot CPU MPIDR, not enabling secondaries
> > > Kernel panic - not syncing: No interrupt controller found.
> > >
> > > A firmware change can avoid this by placing MADT so that:
> > >
> > > (madt_phys & 0xffff) + madt_length <= SZ_256K
> > >
> > > However, I do not think ACPI requires such placement, so this looks like a
> > > kernel-side robustness issue as well, especially on large arm64 systems where
> > > MADT can grow with CPU topology.
> > >
> > > One possible kernel-side change is to increase the boot-time mapping budget for
> > > CONFIG_ARM64_64K_PAGES, for example using a 512K per-slot budget only in that
> > > configuration. I do not think this should be applied unconditionally to all
> > > page sizes, since the arm64 early fixmap code expects the boot-ioremap range
> > > to stay within one PMD.
> > >
> > > Has anyone seen similar failures on arm64 64K systems?
First bug report I am aware of, perhaps this was papered over in FW,
MADT parsing failure is the first thing you would notice in bootstrapping
an ACPI system (FADT is not that big).
> > >
> > > Would maintainers prefer treating this as a firmware layout issue, or would
> > > increasing the early_ioremap budget for 64K pages be acceptable?
> >
> > It think it boils down to what ACPI says about the alignment of the MADT.
>
> I checked the ACPI spec and it didn't require the alignment for ACPI
> tables, but in UEFI spec, it says (for aarch64):
>
> ACPI Tables loaded at boot time can be contained in memory of type
> EfiACPIReclaimMemory (recommended) or EfiACPIMemoryNVS.
>
> EFI memory descriptors of type EfiACPIReclaimMemory and EfiACPIMemoryNVS
> must be aligned on a 4 KiB boundary and must be a multiple of 4 KiB in
> size.
>
> It only requires EfiACPIReclaimMemory type to be 4K aligned, not
> for each ACPI table, because ACPI tables can be packed into the
> allocated EfiACPIReclaimMemory type, correct me if I'm wrong!
I am afraid you are not wrong - we can't blame firmware (yet), this
has to be addressed.
Lorenzo
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [RFC] arm64: early_ioremap fails to map ACPI MADT on 64K pages
2026-06-22 9:49 ` Lorenzo Pieralisi
@ 2026-06-23 2:47 ` Yu Peng
2026-06-23 12:07 ` Will Deacon
0 siblings, 1 reply; 7+ messages in thread
From: Yu Peng @ 2026-06-23 2:47 UTC (permalink / raw)
To: lpieralisi
Cc: akpm, catalin.marinas, guohanjun, lenb, linux-acpi,
linux-arm-kernel, linux-kernel, linux-mm, pengyu, rafael,
sudeep.holla, will
Hi Lorenzo, Hanjun, Will,
Thanks for confirming.
I will send a proper patch for this. The change I plan to post is along
these lines:
diff --git a/arch/arm64/include/asm/fixmap.h b/arch/arm64/include/asm/fixmap.h
index ... .. ...
--- a/arch/arm64/include/asm/fixmap.h
+++ b/arch/arm64/include/asm/fixmap.h
@@ -79,7 +79,11 @@ enum fixed_addresses {
* Temporary boot-time mappings, used by early_ioremap(),
* before ioremap() is functional.
*/
+#ifdef CONFIG_ARM64_64K_PAGES
+#define NR_FIX_BTMAPS (SZ_512K / PAGE_SIZE)
+#else
#define NR_FIX_BTMAPS (SZ_256K / PAGE_SIZE)
+#endif
#define FIX_BTMAPS_SLOTS 7
#define TOTAL_FIX_BTMAPS (NR_FIX_BTMAPS * FIX_BTMAPS_SLOTS)
Thanks,
Yu Peng
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [RFC] arm64: early_ioremap fails to map ACPI MADT on 64K pages
2026-06-23 2:47 ` Yu Peng
@ 2026-06-23 12:07 ` Will Deacon
2026-06-26 1:55 ` Yu Peng
0 siblings, 1 reply; 7+ messages in thread
From: Will Deacon @ 2026-06-23 12:07 UTC (permalink / raw)
To: Yu Peng
Cc: lpieralisi, akpm, catalin.marinas, guohanjun, lenb, linux-acpi,
linux-arm-kernel, linux-kernel, linux-mm, rafael, sudeep.holla
On Tue, Jun 23, 2026 at 10:47:12AM +0800, Yu Peng wrote:
> Hi Lorenzo, Hanjun, Will,
>
> Thanks for confirming.
>
> I will send a proper patch for this. The change I plan to post is along
> these lines:
>
> diff --git a/arch/arm64/include/asm/fixmap.h b/arch/arm64/include/asm/fixmap.h
> index ... .. ...
> --- a/arch/arm64/include/asm/fixmap.h
> +++ b/arch/arm64/include/asm/fixmap.h
> @@ -79,7 +79,11 @@ enum fixed_addresses {
> * Temporary boot-time mappings, used by early_ioremap(),
> * before ioremap() is functional.
> */
> +#ifdef CONFIG_ARM64_64K_PAGES
> +#define NR_FIX_BTMAPS (SZ_512K / PAGE_SIZE)
> +#else
> #define NR_FIX_BTMAPS (SZ_256K / PAGE_SIZE)
> +#endif
> #define FIX_BTMAPS_SLOTS 7
> #define TOTAL_FIX_BTMAPS (NR_FIX_BTMAPS * FIX_BTMAPS_SLOTS)
I still don't understand why this issue is specific to 64k pages, though.
In the example you gave, the thing wasn't even 4k aligned.
Will
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [RFC] arm64: early_ioremap fails to map ACPI MADT on 64K pages
2026-06-23 12:07 ` Will Deacon
@ 2026-06-26 1:55 ` Yu Peng
0 siblings, 0 replies; 7+ messages in thread
From: Yu Peng @ 2026-06-26 1:55 UTC (permalink / raw)
To: Will Deacon
Cc: lpieralisi, akpm, catalin.marinas, guohanjun, lenb, linux-acpi,
linux-arm-kernel, linux-kernel, linux-mm, rafael, sudeep.holla
On 6/23/2026 8:07 PM, Will Deacon wrote:
> On Tue, Jun 23, 2026 at 10:47:12AM +0800, Yu Peng wrote:
>> Hi Lorenzo, Hanjun, Will,
>>
>> Thanks for confirming.
>>
>> I will send a proper patch for this. The change I plan to post is along
>> these lines:
>>
>> diff --git a/arch/arm64/include/asm/fixmap.h b/arch/arm64/include/asm/fixmap.h
>> index ... .. ...
>> --- a/arch/arm64/include/asm/fixmap.h
>> +++ b/arch/arm64/include/asm/fixmap.h
>> @@ -79,7 +79,11 @@ enum fixed_addresses {
>> * Temporary boot-time mappings, used by early_ioremap(),
>> * before ioremap() is functional.
>> */
>> +#ifdef CONFIG_ARM64_64K_PAGES
>> +#define NR_FIX_BTMAPS (SZ_512K / PAGE_SIZE)
>> +#else
>> #define NR_FIX_BTMAPS (SZ_256K / PAGE_SIZE)
>> +#endif
>> #define FIX_BTMAPS_SLOTS 7
>> #define TOTAL_FIX_BTMAPS (NR_FIX_BTMAPS * FIX_BTMAPS_SLOTS)
>
> I still don't understand why this issue is specific to 64k pages, though.
>
> In the example you gave, the thing wasn't even 4k aligned.
>
> Will
You're right, this is not specific to 64K pages.
I looked at 64K first because the current slot is only 4 pages there,
compared with 64 pages on 4K. Any initial offset therefore leaves much
less room in the page-aligned span.
A blanket SZ_512K slot does not look right either. On 4K pages it would
make the boot-ioremap area 512K * 7 = 3.5M, while arm64 requires it to
stay within one PMD:
/*
* The boot-ioremap range spans multiple pmds, for which
* we are not prepared:
*/
BUILD_BUG_ON((__fix_to_virt(FIX_BTMAP_BEGIN) >> PMD_SHIFT)
!= (__fix_to_virt(FIX_BTMAP_END) >> PMD_SHIFT));
So I think the better fix is to preserve the 256K payload budget and add
one page for the possible initial offset:
#define NR_FIX_BTMAPS ((SZ_256K / PAGE_SIZE) + 1)
That should allow any table up to 256K to be mapped regardless of its
initial offset, without exceeding the single-PMD constraint.
Does this direction sound reasonable?
Thanks,
Yu Peng
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2026-06-26 1:55 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-06-17 6:01 [RFC] arm64: early_ioremap fails to map ACPI MADT on 64K pages Yu Peng
2026-06-19 14:43 ` Will Deacon
2026-06-22 8:55 ` Hanjun Guo
2026-06-22 9:49 ` Lorenzo Pieralisi
2026-06-23 2:47 ` Yu Peng
2026-06-23 12:07 ` Will Deacon
2026-06-26 1:55 ` Yu Peng
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox