Re: [PATCH] mm, kasan: don't poison boot memory
From: Mike Rapoport
Date: Tue Feb 23 2021 - 05:35:51 EST
(re-added CC)
On Mon, Feb 22, 2021 at 08:24:59PM -0500, George Kennedy wrote:
>
> On 2/22/2021 4:55 PM, Mike Rapoport wrote:
> > On Mon, Feb 22, 2021 at 01:42:56PM -0500, George Kennedy wrote:
> > > On 2/22/2021 11:13 AM, David Hildenbrand wrote:
> > > > On 22.02.21 16:13, George Kennedy wrote:
> > > >
> > > > The PFN 0xbe453 looks a little strange, though. Do we expect ACPI tables
> > > > close to 3 GiB ? No idea. Could it be that you are trying to map a wrong
> > > > table? Just a guess.
> > > >
> > > > > What would be the correct way to reserve the page so that the above
> > > > > would not be hit?
> > > > I would have assumed that if this is a binary blob, that someone (which
> > > > I think would be acpi code) reserved via memblock_reserve() early during
> > > > boot.
> > > >
> > > > E.g., see drivers/acpi/tables.c:acpi_table_upgrade()->memblock_reserve().
> > > acpi_table_upgrade() gets called, but bails out before memblock_reserve() is
> > > called. Thus, it appears no pages are getting reserved.
> > acpi_table_upgrade() does not actually reserve memory but rather open
> > codes memblock allocation with memblock_find_in_range() +
> > memblock_reserve(), so it does not seem related anyway.
> >
> > Do you have by chance a full boot log handy?
>
> Hello Mike,
>
> Are you after the console output? See attached.
>
> It includes my patch to set PG_Reserved along with the dump_page() debug
> that David asked for - see: "page:"
So, iBFT is indeed at pfn 0xbe453:
[ 0.077698] ACPI: iBFT 0x00000000BE453000 000800 (v01 BOCHS BXPCFACP 00000000 00000000)
and it's in E820_TYPE_RAM region rather than in ACPI data:
[ 0.000000] BIOS-e820: [mem 0x0000000000810000-0x00000000008fffff] ACPI NVS
[ 0.000000] BIOS-e820: [mem 0x0000000000900000-0x00000000be49afff] usable
[ 0.000000] BIOS-e820: [mem 0x00000000be49b000-0x00000000be49bfff] ACPI data
I could not find anywhere in x86 setup or in ACPI tables parsing the code
that reserves this memory or any other ACPI data for that matter. It could
be that I've missed some copying of the data to statically allocated
initial_tables, but AFAICS any ACPI data that was not marked as such in
e820 tables by BIOS resides in memory that is considered as free.
Can you please check if this hack (entirely untested) changes anything:
diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c
index 7bdc0239a943..c118dd54a747 100644
--- a/arch/x86/kernel/acpi/boot.c
+++ b/arch/x86/kernel/acpi/boot.c
@@ -1551,6 +1551,7 @@ void __init acpi_boot_table_init(void)
if (acpi_disabled)
return;
+#if 0
/*
* Initialize the ACPI boot-time table parser.
*/
@@ -1558,6 +1559,7 @@ void __init acpi_boot_table_init(void)
disable_acpi();
return;
}
+#endif
acpi_table_parse(ACPI_SIG_BOOT, acpi_parse_sbf);
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
index d883176ef2ce..c8a07a7b9577 100644
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -1032,6 +1032,14 @@ void __init setup_arch(char **cmdline_p)
*/
find_smp_config();
+ /*
+ * Initialize the ACPI boot-time table parser.
+ */
+ if (acpi_table_init()) {
+ disable_acpi();
+ return;
+ }
+
reserve_ibft_region();
early_alloc_pgt_buf();
diff --git a/drivers/firmware/iscsi_ibft_find.c b/drivers/firmware/iscsi_ibft_find.c
index 64bb94523281..2e5e04090fe2 100644
--- a/drivers/firmware/iscsi_ibft_find.c
+++ b/drivers/firmware/iscsi_ibft_find.c
@@ -80,6 +80,21 @@ static int __init find_ibft_in_mem(void)
done:
return len;
}
+
+static void __init acpi_find_ibft_region(void)
+{
+ int i;
+ struct acpi_table_header *table = NULL;
+
+ if (acpi_disabled)
+ return;
+
+ for (i = 0; i < ARRAY_SIZE(ibft_signs) && !ibft_addr; i++) {
+ acpi_get_table(ibft_signs[i].sign, 0, &table);
+ ibft_addr = (struct acpi_table_ibft *)table;
+ }
+}
+
/*
* Routine used to find the iSCSI Boot Format Table. The logical
* kernel address is set in the ibft_addr global variable.
@@ -93,6 +108,8 @@ unsigned long __init find_ibft_region(unsigned long *sizep)
if (!efi_enabled(EFI_BOOT))
find_ibft_in_mem();
+ else
+ acpi_find_ibft_region();
if (ibft_addr) {
*sizep = PAGE_ALIGN(ibft_addr->header.length);
> Thank you,
> George
--
Sincerely yours,
Mike.