Re: [PATCH] mm, kasan: don't poison boot memory

Subsystems: acpi, the rest, x86 architecture (32-bit and 64-bit), iscsi boot firmware table (ibft) driver

22 messages, 3 authors, 2021-03-02 · open the first message on its own page

Re: [PATCH] mm, kasan: don't poison boot memory

From: Mike Rapoport <hidden>
Date: 2021-02-23 21:34:44

On Tue, Feb 23, 2021 at 04:16:44PM -0500, George Kennedy wrote:

On 2/23/2021 3:09 PM, Mike Rapoport wrote:
quoted
On Tue, Feb 23, 2021 at 01:05:05PM -0500, George Kennedy wrote:
quoted
On 2/23/2021 10:47 AM, Mike Rapoport wrote:

It now crashes here:

[    0.051019] ACPI: Early table checksum verification disabled
[    0.056721] ACPI: RSDP 0x00000000BFBFA014 000024 (v02 BOCHS )
[    0.057874] ACPI: XSDT 0x00000000BFBF90E8 00004C (v01 BOCHS BXPCFACP
00000001      01000013)
[    0.059590] ACPI: FACP 0x00000000BFBF5000 000074 (v01 BOCHS BXPCFACP
00000001 BXPC 00000001)
[    0.061306] ACPI: DSDT 0x00000000BFBF6000 00238D (v01 BOCHS BXPCDSDT
00000001 BXPC 00000001)
[    0.063006] ACPI: FACS 0x00000000BFBFD000 000040
[    0.063938] ACPI: APIC 0x00000000BFBF4000 000090 (v01 BOCHS BXPCAPIC
00000001 BXPC 00000001)
[    0.065638] ACPI: HPET 0x00000000BFBF3000 000038 (v01 BOCHS BXPCHPET
00000001 BXPC 00000001)
[    0.067335] ACPI: BGRT 0x00000000BE49B000 000038 (v01 INTEL EDK2
00000002      01000013)
[    0.069030] ACPI: iBFT 0x00000000BE453000 000800 (v01 BOCHS BXPCFACP
00000000      00000000)
[    0.070734] XXX acpi_find_ibft_region:
[    0.071468] XXX iBFT, status=0
[    0.072073] XXX about to call acpi_put_table()...
ibft_addr=ffffffffff240000
[    0.073449] XXX acpi_find_ibft_region(EXIT):
PANIC: early exception 0x0e IP 10:ffffffff9259f439 error 0 cr2
0xffffffffff240004
Right, I've missed the dereference of the ibft_addr after
acpi_find_ibft_region().

With this change to iscsi_ibft_find.c instead of the previous one it should
be better:
diff --git a/drivers/firmware/iscsi_ibft_find.c b/drivers/firmware/iscsi_ibft_find.c
index 64bb94523281..1be7481d5c69 100644
--- a/drivers/firmware/iscsi_ibft_find.c
+++ b/drivers/firmware/iscsi_ibft_find.c
@@ -80,6 +80,27 @@ static int __init find_ibft_in_mem(void)
  done:
  	return len;
  }
+
+static void __init acpi_find_ibft_region(unsigned long *sizep)
+{
+	int i;
+	struct acpi_table_header *table = NULL;
+	acpi_status status;
+
+	if (acpi_disabled)
+		return;
+
+	for (i = 0; i < ARRAY_SIZE(ibft_signs) && !ibft_addr; i++) {
+		status = acpi_get_table(ibft_signs[i].sign, 0, &table);
+		if (ACPI_SUCCESS(status)) {
+			ibft_addr = (struct acpi_table_ibft *)table;
+			*sizep = PAGE_ALIGN(ibft_addr->header.length);
+			acpi_put_table(table);
+			break;
+		}
+	}
+}
+
  /*
   * Routine used to find the iSCSI Boot Format Table. The logical
   * kernel address is set in the ibft_addr global variable.
@@ -91,14 +112,16 @@ unsigned long __init find_ibft_region(unsigned long *sizep)
  	/* iBFT 1.03 section 1.4.3.1 mandates that UEFI machines will
  	 * only use ACPI for this */
-	if (!efi_enabled(EFI_BOOT))
+	if (!efi_enabled(EFI_BOOT)) {
  		find_ibft_in_mem();
-
-	if (ibft_addr) {
  		*sizep = PAGE_ALIGN(ibft_addr->header.length);
-		return (u64)virt_to_phys(ibft_addr);
+	} else {
+		acpi_find_ibft_region(sizep);
  	}
+	if (ibft_addr)
+		return (u64)virt_to_phys(ibft_addr);
+
  	*sizep = 0;
  	return 0;
  }
Mike,

No luck. Back to the original KASAN ibft_init crash.

I ran with only the above patch from you. Was that what you wanted? Your
previous patch had a section defined out by #if 0. Was that supposed to be
in there as well?
Sorry, I wasn't clear, but I meant to use the first patch and only replace
changes to iscsi_ibft_find.c with the new patch. 

Here's the full patch to be sure we're on the same page:
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..1be7481d5c69 100644
--- a/drivers/firmware/iscsi_ibft_find.c
+++ b/drivers/firmware/iscsi_ibft_find.c
@@ -80,6 +80,27 @@ static int __init find_ibft_in_mem(void)
 done:
 	return len;
 }
+
+static void __init acpi_find_ibft_region(unsigned long *sizep)
+{
+	int i;
+	struct acpi_table_header *table = NULL;
+	acpi_status status;
+
+	if (acpi_disabled)
+		return;
+
+	for (i = 0; i < ARRAY_SIZE(ibft_signs) && !ibft_addr; i++) {
+		status = acpi_get_table(ibft_signs[i].sign, 0, &table);
+		if (ACPI_SUCCESS(status)) {
+			ibft_addr = (struct acpi_table_ibft *)table;
+			*sizep = PAGE_ALIGN(ibft_addr->header.length);
+			acpi_put_table(table);
+			break;
+		}
+	}
+}
+
 /*
  * Routine used to find the iSCSI Boot Format Table. The logical
  * kernel address is set in the ibft_addr global variable.
@@ -91,14 +112,16 @@ unsigned long __init find_ibft_region(unsigned long *sizep)
 	/* iBFT 1.03 section 1.4.3.1 mandates that UEFI machines will
 	 * only use ACPI for this */
 
-	if (!efi_enabled(EFI_BOOT))
+	if (!efi_enabled(EFI_BOOT)) {
 		find_ibft_in_mem();
-
-	if (ibft_addr) {
 		*sizep = PAGE_ALIGN(ibft_addr->header.length);
-		return (u64)virt_to_phys(ibft_addr);
+	} else {
+		acpi_find_ibft_region(sizep);
 	}
 
+	if (ibft_addr)
+		return (u64)virt_to_phys(ibft_addr);
+
 	*sizep = 0;
 	return 0;
 }
 
-- 
Sincerely yours,
Mike.

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

Re: [PATCH] mm, kasan: don't poison boot memory

From: George Kennedy <hidden>
Date: 2021-02-23 21:48:50


On 2/23/2021 4:32 PM, Mike Rapoport wrote:
quoted hunk
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..1be7481d5c69 100644
--- a/drivers/firmware/iscsi_ibft_find.c
+++ b/drivers/firmware/iscsi_ibft_find.c
@@ -80,6 +80,27 @@ static int __init find_ibft_in_mem(void)
  done:
  	return len;
  }
+
+static void __init acpi_find_ibft_region(unsigned long *sizep)
+{
+	int i;
+	struct acpi_table_header *table = NULL;
+	acpi_status status;
+
+	if (acpi_disabled)
+		return;
+
+	for (i = 0; i < ARRAY_SIZE(ibft_signs) && !ibft_addr; i++) {
+		status = acpi_get_table(ibft_signs[i].sign, 0, &table);
+		if (ACPI_SUCCESS(status)) {
+			ibft_addr = (struct acpi_table_ibft *)table;
+			*sizep = PAGE_ALIGN(ibft_addr->header.length);
+			acpi_put_table(table);
+			break;
+		}
+	}
+}
+
  /*
   * Routine used to find the iSCSI Boot Format Table. The logical
   * kernel address is set in the ibft_addr global variable.
@@ -91,14 +112,16 @@ unsigned long __init find_ibft_region(unsigned long *sizep)
  	/* iBFT 1.03 section 1.4.3.1 mandates that UEFI machines will
  	 * only use ACPI for this */
  
-	if (!efi_enabled(EFI_BOOT))
+	if (!efi_enabled(EFI_BOOT)) {
  		find_ibft_in_mem();
-
-	if (ibft_addr) {
  		*sizep = PAGE_ALIGN(ibft_addr->header.length);
-		return (u64)virt_to_phys(ibft_addr);
+	} else {
+		acpi_find_ibft_region(sizep);
  	}
  
+	if (ibft_addr)
+		return (u64)virt_to_phys(ibft_addr);
+
  	*sizep = 0;
  	return 0;
  }
  
Mike,

Still no luck.

[   30.193723] iscsi: registered transport (iser)
[   30.195970] iBFT detected.
[   30.196571] BUG: unable to handle page fault for address: 
ffffffffff240004
[   30.196824] #PF: supervisor read access in kernel mode
[   30.196824] #PF: error_code(0x0000) - not-present page
[   30.196824] PGD 24e34067 P4D 24e34067 PUD 24e36067 PMD 27a0e067 PTE 0
[   30.196824] Oops: 0000 [#1] SMP KASAN PTI
[   30.196824] CPU: 3 PID: 1 Comm: swapper/0 Not tainted 5.11.0-f9593a0 #10
[   30.196824] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), 
BIOS 0.0.0 02/06/2015
[   30.196824] RIP: 0010:ibft_init+0x13d/0xc33
[   30.196824] Code: c1 40 84 ce 75 11 83 e0 07 38 c2 0f 9e c1 84 d2 0f 
95 c0 84 c1 74 0a be 04 00 00 00 e8 77 f2 5f ef 49 8d 7f 08 b8 ff ff 37 
00 <4d> 63 6f 04 48 89 fa 48 c1 e0 2a 48 c1 ea 03 8a 04 02 48 89 fa 83
[   30.196824] RSP: 0000:ffff888100fafc30 EFLAGS: 00010246
[   30.196824] RAX: 000000000037ffff RBX: ffffffff937c6fc0 RCX: 
ffffffff815fcf01
[   30.196824] RDX: dffffc0000000000 RSI: 0000000000000001 RDI: 
ffffffffff240008
[   30.196824] RBP: ffff888100fafcf8 R08: ffffed10201f5f12 R09: 
ffffed10201f5f12
[   30.196824] R10: ffff888100faf88f R11: ffffed10201f5f11 R12: 
dffffc0000000000
[   30.196824] R13: ffff888100fafdc0 R14: ffff888100fafcd0 R15: 
ffffffffff240000
[   30.196824] FS:  0000000000000000(0000) GS:ffff88810ad80000(0000) 
knlGS:0000000000000000
[   30.196824] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[   30.196824] CR2: ffffffffff240004 CR3: 0000000024e30000 CR4: 
00000000000006e0
[   30.196824] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 
0000000000000000
[   30.196824] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 
0000000000000400
[   30.196824] Call Trace:
[   30.196824]  ? write_comp_data+0x2f/0x90
[   30.196824]  ? __sanitizer_cov_trace_pc+0x21/0x50
[   30.196824]  ? ibft_check_initiator_for+0x159/0x159
[   30.196824]  ? dmi_setup+0x46c/0x46c
[   30.196824]  ? write_comp_data+0x2f/0x90
[   30.196824]  ? ibft_check_initiator_for+0x159/0x159
[   30.196824]  do_one_initcall+0xc4/0x3e0
[   30.196824]  ? perf_trace_initcall_level+0x3e0/0x3e0
[   30.196824]  ? asm_sysvec_error_interrupt+0x10/0x20
[   30.196824]  ? do_one_initcall+0x18c/0x3e0
[   30.196824]  kernel_init_freeable+0x596/0x652
[   30.196824]  ? console_on_rootfs+0x7d/0x7d
[   30.196824]  ? __sanitizer_cov_trace_pc+0x21/0x50
[   30.196824]  ? rest_init+0xf0/0xf0
[   30.196824]  kernel_init+0x16/0x1d0
[   30.196824]  ? rest_init+0xf0/0xf0
[   30.196824]  ret_from_fork+0x22/0x30
[   30.196824] Modules linked in:
[   30.196824] Dumping ftrace buffer:
[   30.196824]    (ftrace buffer empty)
[   30.196824] CR2: ffffffffff240004
[   30.196824] ---[ end trace 293eae51adac1398 ]---
[   30.196824] RIP: 0010:ibft_init+0x13d/0xc33
[   30.196824] Code: c1 40 84 ce 75 11 83 e0 07 38 c2 0f 9e c1 84 d2 0f 
95 c0 84 c1 74 0a be 04 00 00 00 e8 77 f2 5f ef 49 8d 7f 08 b8 ff ff 37 
00 <4d> 63 6f 04 48 89 fa 48 c1 e0 2a 48 c1 ea 03 8a 04 02 48 89 fa 83
[   30.196824] RSP: 0000:ffff888100fafc30 EFLAGS: 00010246
[   30.196824] RAX: 000000000037ffff RBX: ffffffff937c6fc0 RCX: 
ffffffff815fcf01
[   30.196824] RDX: dffffc0000000000 RSI: 0000000000000001 RDI: 
ffffffffff240008
[   30.196824] RBP: ffff888100fafcf8 R08: ffffed10201f5f12 R09: 
ffffed10201f5f12
[   30.196824] R10: ffff888100faf88f R11: ffffed10201f5f11 R12: 
dffffc0000000000
[   30.196824] R13: ffff888100fafdc0 R14: ffff888100fafcd0 R15: 
ffffffffff240000
[   30.196824] FS:  0000000000000000(0000) GS:ffff88810ad80000(0000) 
knlGS:0000000000000000
[   30.196824] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[   30.196824] CR2: ffffffffff240004 CR3: 0000000024e30000 CR4: 
00000000000006e0
[   30.196824] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 
0000000000000000
[   30.196824] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 
0000000000000400
[   30.196824] Kernel panic - not syncing: Fatal exception
[   30.196824] Dumping ftrace buffer:
[   30.196824]    (ftrace buffer empty)
[   30.196824] Kernel Offset: disabled
[   30.196824] Rebooting in 1 seconds..

George

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

Re: [PATCH] mm, kasan: don't poison boot memory

From: Mike Rapoport <hidden>
Date: 2021-02-24 10:39:16

On Tue, Feb 23, 2021 at 04:46:28PM -0500, George Kennedy wrote:
Mike,

Still no luck.

[   30.193723] iscsi: registered transport (iser)
[   30.195970] iBFT detected.
[   30.196571] BUG: unable to handle page fault for address: ffffffffff240004
Hmm, we cannot set ibft_addr to early pointer to the ACPI table.
Let's try something more disruptive and move the reservation back to
iscsi_ibft_find.c.
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..c615ce96c9a2 100644
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -570,16 +570,6 @@ void __init reserve_standard_io_resources(void)
 
 }
 
-static __init void reserve_ibft_region(void)
-{
-	unsigned long addr, size = 0;
-
-	addr = find_ibft_region(&size);
-
-	if (size)
-		memblock_reserve(addr, size);
-}
-
 static bool __init snb_gfx_workaround_needed(void)
 {
 #ifdef CONFIG_PCI
@@ -1032,6 +1022,12 @@ void __init setup_arch(char **cmdline_p)
 	 */
 	find_smp_config();
 
+	/*
+	 * Initialize the ACPI boot-time table parser.
+	 */
+	if (acpi_table_init())
+		disable_acpi();
+
 	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..01be513843d6 100644
--- a/drivers/firmware/iscsi_ibft_find.c
+++ b/drivers/firmware/iscsi_ibft_find.c
@@ -47,7 +47,25 @@ static const struct {
 #define VGA_MEM 0xA0000 /* VGA buffer */
 #define VGA_SIZE 0x20000 /* 128kB */
 
-static int __init find_ibft_in_mem(void)
+static void __init *acpi_find_ibft_region(void)
+{
+	int i;
+	struct acpi_table_header *table = NULL;
+	acpi_status status;
+
+	if (acpi_disabled)
+		return NULL;
+
+	for (i = 0; i < ARRAY_SIZE(ibft_signs) && !ibft_addr; i++) {
+		status = acpi_get_table(ibft_signs[i].sign, 0, &table);
+		if (ACPI_SUCCESS(status))
+			return table;
+	}
+
+	return NULL;
+}
+
+static void __init *find_ibft_in_mem(void)
 {
 	unsigned long pos;
 	unsigned int len = 0;
@@ -70,35 +88,44 @@ static int __init find_ibft_in_mem(void)
 				/* if the length of the table extends past 1M,
 				 * the table cannot be valid. */
 				if (pos + len <= (IBFT_END-1)) {
-					ibft_addr = (struct acpi_table_ibft *)virt;
 					pr_info("iBFT found at 0x%lx.\n", pos);
-					goto done;
+					return virt;
 				}
 			}
 		}
 	}
-done:
-	return len;
+
+	return NULL;
 }
+
+static void __init *find_ibft(void)
+{
+	/* iBFT 1.03 section 1.4.3.1 mandates that UEFI machines will
+	 * only use ACPI for this */
+	if (!efi_enabled(EFI_BOOT))
+		return find_ibft_in_mem();
+	else
+		return acpi_find_ibft_region();
+}
+
 /*
  * Routine used to find the iSCSI Boot Format Table. The logical
  * kernel address is set in the ibft_addr global variable.
  */
-unsigned long __init find_ibft_region(unsigned long *sizep)
+void __init reserve_ibft_region(void)
 {
-	ibft_addr = NULL;
+	struct acpi_table_ibft *table;
+	unsigned long size;
 
-	/* iBFT 1.03 section 1.4.3.1 mandates that UEFI machines will
-	 * only use ACPI for this */
+	table = find_ibft();
+	if (!table)
+		return;
 
-	if (!efi_enabled(EFI_BOOT))
-		find_ibft_in_mem();
-
-	if (ibft_addr) {
-		*sizep = PAGE_ALIGN(ibft_addr->header.length);
-		return (u64)virt_to_phys(ibft_addr);
-	}
+	size = PAGE_ALIGN(table->header.length);
+	memblock_reserve(virt_to_phys(table), size);
 
-	*sizep = 0;
-	return 0;
+	if (efi_enabled(EFI_BOOT))
+		acpi_put_table(&table->header);
+	else
+		ibft_addr = table;
 }
diff --git a/include/linux/iscsi_ibft.h b/include/linux/iscsi_ibft.h
index b7b45ca82bea..da813c891990 100644
--- a/include/linux/iscsi_ibft.h
+++ b/include/linux/iscsi_ibft.h
@@ -26,13 +26,9 @@ extern struct acpi_table_ibft *ibft_addr;
  * mapped address is set in the ibft_addr variable.
  */
 #ifdef CONFIG_ISCSI_IBFT_FIND
-unsigned long find_ibft_region(unsigned long *sizep);
+void reserve_ibft_region(void);
 #else
-static inline unsigned long find_ibft_region(unsigned long *sizep)
-{
-	*sizep = 0;
-	return 0;
-}
+static inline void reserve_ibft_region(void) {}
 #endif
 
 #endif /* ISCSI_IBFT_H */
-- 
Sincerely yours,
Mike.

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

Re: [PATCH] mm, kasan: don't poison boot memory

From: George Kennedy <hidden>
Date: 2021-02-24 15:15:15


On 2/24/2021 5:37 AM, Mike Rapoport wrote:
quoted hunk
On Tue, Feb 23, 2021 at 04:46:28PM -0500, George Kennedy wrote:
quoted
Mike,

Still no luck.

[   30.193723] iscsi: registered transport (iser)
[   30.195970] iBFT detected.
[   30.196571] BUG: unable to handle page fault for address: ffffffffff240004
Hmm, we cannot set ibft_addr to early pointer to the ACPI table.
Let's try something more disruptive and move the reservation back to
iscsi_ibft_find.c.
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..c615ce96c9a2 100644
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -570,16 +570,6 @@ void __init reserve_standard_io_resources(void)
  
  }
  
-static __init void reserve_ibft_region(void)
-{
-	unsigned long addr, size = 0;
-
-	addr = find_ibft_region(&size);
-
-	if (size)
-		memblock_reserve(addr, size);
-}
-
  static bool __init snb_gfx_workaround_needed(void)
  {
  #ifdef CONFIG_PCI
@@ -1032,6 +1022,12 @@ void __init setup_arch(char **cmdline_p)
  	 */
  	find_smp_config();
  
+	/*
+	 * Initialize the ACPI boot-time table parser.
+	 */
+	if (acpi_table_init())
+		disable_acpi();
+
  	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..01be513843d6 100644
--- a/drivers/firmware/iscsi_ibft_find.c
+++ b/drivers/firmware/iscsi_ibft_find.c
@@ -47,7 +47,25 @@ static const struct {
  #define VGA_MEM 0xA0000 /* VGA buffer */
  #define VGA_SIZE 0x20000 /* 128kB */
  
-static int __init find_ibft_in_mem(void)
+static void __init *acpi_find_ibft_region(void)
+{
+	int i;
+	struct acpi_table_header *table = NULL;
+	acpi_status status;
+
+	if (acpi_disabled)
+		return NULL;
+
+	for (i = 0; i < ARRAY_SIZE(ibft_signs) && !ibft_addr; i++) {
+		status = acpi_get_table(ibft_signs[i].sign, 0, &table);
+		if (ACPI_SUCCESS(status))
+			return table;
+	}
+
+	return NULL;
+}
+
+static void __init *find_ibft_in_mem(void)
  {
  	unsigned long pos;
  	unsigned int len = 0;
@@ -70,35 +88,44 @@ static int __init find_ibft_in_mem(void)
  				/* if the length of the table extends past 1M,
  				 * the table cannot be valid. */
  				if (pos + len <= (IBFT_END-1)) {
-					ibft_addr = (struct acpi_table_ibft *)virt;
  					pr_info("iBFT found at 0x%lx.\n", pos);
-					goto done;
+					return virt;
  				}
  			}
  		}
  	}
-done:
-	return len;
+
+	return NULL;
  }
+
+static void __init *find_ibft(void)
+{
+	/* iBFT 1.03 section 1.4.3.1 mandates that UEFI machines will
+	 * only use ACPI for this */
+	if (!efi_enabled(EFI_BOOT))
+		return find_ibft_in_mem();
+	else
+		return acpi_find_ibft_region();
+}
+
  /*
   * Routine used to find the iSCSI Boot Format Table. The logical
   * kernel address is set in the ibft_addr global variable.
   */
-unsigned long __init find_ibft_region(unsigned long *sizep)
+void __init reserve_ibft_region(void)
  {
-	ibft_addr = NULL;
+	struct acpi_table_ibft *table;
+	unsigned long size;
  
-	/* iBFT 1.03 section 1.4.3.1 mandates that UEFI machines will
-	 * only use ACPI for this */
+	table = find_ibft();
+	if (!table)
+		return;
  
-	if (!efi_enabled(EFI_BOOT))
-		find_ibft_in_mem();
-
-	if (ibft_addr) {
-		*sizep = PAGE_ALIGN(ibft_addr->header.length);
-		return (u64)virt_to_phys(ibft_addr);
-	}
+	size = PAGE_ALIGN(table->header.length);
+	memblock_reserve(virt_to_phys(table), size);
  
-	*sizep = 0;
-	return 0;
+	if (efi_enabled(EFI_BOOT))
+		acpi_put_table(&table->header);
+	else
+		ibft_addr = table;
  }
diff --git a/include/linux/iscsi_ibft.h b/include/linux/iscsi_ibft.h
index b7b45ca82bea..da813c891990 100644
--- a/include/linux/iscsi_ibft.h
+++ b/include/linux/iscsi_ibft.h
@@ -26,13 +26,9 @@ extern struct acpi_table_ibft *ibft_addr;
   * mapped address is set in the ibft_addr variable.
   */
  #ifdef CONFIG_ISCSI_IBFT_FIND
-unsigned long find_ibft_region(unsigned long *sizep);
+void reserve_ibft_region(void);
  #else
-static inline unsigned long find_ibft_region(unsigned long *sizep)
-{
-	*sizep = 0;
-	return 0;
-}
+static inline void reserve_ibft_region(void) {}
  #endif
  
  #endif /* ISCSI_IBFT_H */
Still no luck Mike,

We're back to the original problem where the only thing that worked was 
to run "SetPageReserved(page)" before calling "kmap(page)". The page is 
being "freed" before ibft_init() is called as a result of the recent 
buddy page freeing changes.

[   30.385207] iscsi: registered transport (iser)
[   30.387462] iBFT detected.
[   30.388042] 
==================================================================
[   30.388119] BUG: KASAN: use-after-free in ibft_init+0x134/0xc33
[   30.388119] Read of size 4 at addr ffff8880be453004 by task swapper/0/1
[   30.388119]
[   30.388119] CPU: 0 PID: 1 Comm: swapper/0 Not tainted 5.11.0-f9593a0 #11
[   30.388119] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), 
BIOS 0.0.0 02/06/2015
[   30.388119] Call Trace:
[   30.388119]  dump_stack+0xdb/0x120
[   30.388119]  ? ibft_init+0x134/0xc33
[   30.388119]  print_address_description.constprop.7+0x41/0x60
[   30.388119]  ? ibft_init+0x134/0xc33
[   30.388119]  ? ibft_init+0x134/0xc33
[   30.388119]  kasan_report.cold.10+0x78/0xd1
[   30.388119]  ? ibft_init+0x134/0xc33
[   30.388119]  __asan_report_load_n_noabort+0xf/0x20
[   30.388119]  ibft_init+0x134/0xc33
[   30.388119]  ? write_comp_data+0x2f/0x90
[   30.388119]  ? ibft_check_initiator_for+0x159/0x159
[   30.388119]  ? write_comp_data+0x2f/0x90
[   30.388119]  ? ibft_check_initiator_for+0x159/0x159
[   30.388119]  do_one_initcall+0xc4/0x3e0
[   30.388119]  ? perf_trace_initcall_level+0x3e0/0x3e0
[   30.388119]  ? unpoison_range+0x14/0x40
[   30.388119]  ? ____kasan_kmalloc.constprop.5+0x8f/0xc0
[   30.388119]  ? kernel_init_freeable+0x420/0x652

George

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

Re: [PATCH] mm, kasan: don't poison boot memory

From: Mike Rapoport <hidden>
Date: 2021-02-25 08:54:34

Hi George,
On 2/24/2021 5:37 AM, Mike Rapoport wrote:
quoted
On Tue, Feb 23, 2021 at 04:46:28PM -0500, George Kennedy wrote:
quoted
Mike,

Still no luck.

[   30.193723] iscsi: registered transport (iser)
[   30.195970] iBFT detected.
[   30.196571] BUG: unable to handle page fault for address: ffffffffff240004
Hmm, we cannot set ibft_addr to early pointer to the ACPI table.
Let's try something more disruptive and move the reservation back to
iscsi_ibft_find.c.
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..c615ce96c9a2 100644
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -570,16 +570,6 @@ void __init reserve_standard_io_resources(void)
  }
-static __init void reserve_ibft_region(void)
-{
-	unsigned long addr, size = 0;
-
-	addr = find_ibft_region(&size);
-
-	if (size)
-		memblock_reserve(addr, size);
-}
-
  static bool __init snb_gfx_workaround_needed(void)
  {
  #ifdef CONFIG_PCI
@@ -1032,6 +1022,12 @@ void __init setup_arch(char **cmdline_p)
  	 */
  	find_smp_config();
+	/*
+	 * Initialize the ACPI boot-time table parser.
+	 */
+	if (acpi_table_init())
+		disable_acpi();
+
  	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..01be513843d6 100644
--- a/drivers/firmware/iscsi_ibft_find.c
+++ b/drivers/firmware/iscsi_ibft_find.c
@@ -47,7 +47,25 @@ static const struct {
  #define VGA_MEM 0xA0000 /* VGA buffer */
  #define VGA_SIZE 0x20000 /* 128kB */
-static int __init find_ibft_in_mem(void)
+static void __init *acpi_find_ibft_region(void)
+{
+	int i;
+	struct acpi_table_header *table = NULL;
+	acpi_status status;
+
+	if (acpi_disabled)
+		return NULL;
+
+	for (i = 0; i < ARRAY_SIZE(ibft_signs) && !ibft_addr; i++) {
+		status = acpi_get_table(ibft_signs[i].sign, 0, &table);
+		if (ACPI_SUCCESS(status))
+			return table;
+	}
+
+	return NULL;
+}
+
+static void __init *find_ibft_in_mem(void)
  {
  	unsigned long pos;
  	unsigned int len = 0;
@@ -70,35 +88,44 @@ static int __init find_ibft_in_mem(void)
  				/* if the length of the table extends past 1M,
  				 * the table cannot be valid. */
  				if (pos + len <= (IBFT_END-1)) {
-					ibft_addr = (struct acpi_table_ibft *)virt;
  					pr_info("iBFT found at 0x%lx.\n", pos);
-					goto done;
+					return virt;
  				}
  			}
  		}
  	}
-done:
-	return len;
+
+	return NULL;
  }
+
+static void __init *find_ibft(void)
+{
+	/* iBFT 1.03 section 1.4.3.1 mandates that UEFI machines will
+	 * only use ACPI for this */
+	if (!efi_enabled(EFI_BOOT))
+		return find_ibft_in_mem();
+	else
+		return acpi_find_ibft_region();
+}
+
  /*
   * Routine used to find the iSCSI Boot Format Table. The logical
   * kernel address is set in the ibft_addr global variable.
   */
-unsigned long __init find_ibft_region(unsigned long *sizep)
+void __init reserve_ibft_region(void)
  {
-	ibft_addr = NULL;
+	struct acpi_table_ibft *table;
+	unsigned long size;
-	/* iBFT 1.03 section 1.4.3.1 mandates that UEFI machines will
-	 * only use ACPI for this */
+	table = find_ibft();
+	if (!table)
+		return;
-	if (!efi_enabled(EFI_BOOT))
-		find_ibft_in_mem();
-
-	if (ibft_addr) {
-		*sizep = PAGE_ALIGN(ibft_addr->header.length);
-		return (u64)virt_to_phys(ibft_addr);
-	}
+	size = PAGE_ALIGN(table->header.length);
+	memblock_reserve(virt_to_phys(table), size);
-	*sizep = 0;
-	return 0;
+	if (efi_enabled(EFI_BOOT))
+		acpi_put_table(&table->header);
+	else
+		ibft_addr = table;
  }
diff --git a/include/linux/iscsi_ibft.h b/include/linux/iscsi_ibft.h
index b7b45ca82bea..da813c891990 100644
--- a/include/linux/iscsi_ibft.h
+++ b/include/linux/iscsi_ibft.h
@@ -26,13 +26,9 @@ extern struct acpi_table_ibft *ibft_addr;
   * mapped address is set in the ibft_addr variable.
   */
  #ifdef CONFIG_ISCSI_IBFT_FIND
-unsigned long find_ibft_region(unsigned long *sizep);
+void reserve_ibft_region(void);
  #else
-static inline unsigned long find_ibft_region(unsigned long *sizep)
-{
-	*sizep = 0;
-	return 0;
-}
+static inline void reserve_ibft_region(void) {}
  #endif
  #endif /* ISCSI_IBFT_H */
Still no luck Mike,

We're back to the original problem where the only thing that worked was to
run "SetPageReserved(page)" before calling "kmap(page)". The page is being
"freed" before ibft_init() is called as a result of the recent buddy page
freeing changes.
I keep missing some little details each time :(
Ok, let's try from the different angle.
diff --git a/drivers/acpi/acpica/tbutils.c b/drivers/acpi/acpica/tbutils.c
index 4b9b329a5a92..ec43e1447336 100644
--- a/drivers/acpi/acpica/tbutils.c
+++ b/drivers/acpi/acpica/tbutils.c
@@ -7,6 +7,8 @@
  *
  *****************************************************************************/
 
+#include <linux/memblock.h>
+
 #include <acpi/acpi.h>
 #include "accommon.h"
 #include "actables.h"
@@ -339,6 +341,21 @@ acpi_tb_parse_root_table(acpi_physical_address rsdp_address)
 			acpi_tb_parse_fadt();
 		}
 
+		if (ACPI_SUCCESS(status) &&
+		    ACPI_COMPARE_NAMESEG(&acpi_gbl_root_table_list.
+					 tables[table_index].signature,
+					 ACPI_SIG_IBFT)) {
+			struct acpi_table_header *ibft;
+			struct acpi_table_desc *desc;
+
+			desc = &acpi_gbl_root_table_list.tables[table_index];
+			status = acpi_tb_get_table(desc, &ibft);
+			if (ACPI_SUCCESS(status)) {
+				memblock_reserve(address, ibft->length);
+				acpi_tb_put_table(desc);
+			}
+		}
+
 next_table:
 
 		table_entry += table_entry_size;
 

-- 
Sincerely yours,
Mike.

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

Re: [PATCH] mm, kasan: don't poison boot memory

From: George Kennedy <hidden>
Date: 2021-02-25 12:40:24


On 2/25/2021 3:53 AM, Mike Rapoport wrote:
Hi George,
quoted
On 2/24/2021 5:37 AM, Mike Rapoport wrote:
quoted
On Tue, Feb 23, 2021 at 04:46:28PM -0500, George Kennedy wrote:
quoted
Mike,

Still no luck.

[   30.193723] iscsi: registered transport (iser)
[   30.195970] iBFT detected.
[   30.196571] BUG: unable to handle page fault for address: ffffffffff240004
Hmm, we cannot set ibft_addr to early pointer to the ACPI table.
Let's try something more disruptive and move the reservation back to
iscsi_ibft_find.c.
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..c615ce96c9a2 100644
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -570,16 +570,6 @@ void __init reserve_standard_io_resources(void)
   }
-static __init void reserve_ibft_region(void)
-{
-	unsigned long addr, size = 0;
-
-	addr = find_ibft_region(&size);
-
-	if (size)
-		memblock_reserve(addr, size);
-}
-
   static bool __init snb_gfx_workaround_needed(void)
   {
   #ifdef CONFIG_PCI
@@ -1032,6 +1022,12 @@ void __init setup_arch(char **cmdline_p)
   	 */
   	find_smp_config();
+	/*
+	 * Initialize the ACPI boot-time table parser.
+	 */
+	if (acpi_table_init())
+		disable_acpi();
+
   	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..01be513843d6 100644
--- a/drivers/firmware/iscsi_ibft_find.c
+++ b/drivers/firmware/iscsi_ibft_find.c
@@ -47,7 +47,25 @@ static const struct {
   #define VGA_MEM 0xA0000 /* VGA buffer */
   #define VGA_SIZE 0x20000 /* 128kB */
-static int __init find_ibft_in_mem(void)
+static void __init *acpi_find_ibft_region(void)
+{
+	int i;
+	struct acpi_table_header *table = NULL;
+	acpi_status status;
+
+	if (acpi_disabled)
+		return NULL;
+
+	for (i = 0; i < ARRAY_SIZE(ibft_signs) && !ibft_addr; i++) {
+		status = acpi_get_table(ibft_signs[i].sign, 0, &table);
+		if (ACPI_SUCCESS(status))
+			return table;
+	}
+
+	return NULL;
+}
+
+static void __init *find_ibft_in_mem(void)
   {
   	unsigned long pos;
   	unsigned int len = 0;
@@ -70,35 +88,44 @@ static int __init find_ibft_in_mem(void)
   				/* if the length of the table extends past 1M,
   				 * the table cannot be valid. */
   				if (pos + len <= (IBFT_END-1)) {
-					ibft_addr = (struct acpi_table_ibft *)virt;
   					pr_info("iBFT found at 0x%lx.\n", pos);
-					goto done;
+					return virt;
   				}
   			}
   		}
   	}
-done:
-	return len;
+
+	return NULL;
   }
+
+static void __init *find_ibft(void)
+{
+	/* iBFT 1.03 section 1.4.3.1 mandates that UEFI machines will
+	 * only use ACPI for this */
+	if (!efi_enabled(EFI_BOOT))
+		return find_ibft_in_mem();
+	else
+		return acpi_find_ibft_region();
+}
+
   /*
    * Routine used to find the iSCSI Boot Format Table. The logical
    * kernel address is set in the ibft_addr global variable.
    */
-unsigned long __init find_ibft_region(unsigned long *sizep)
+void __init reserve_ibft_region(void)
   {
-	ibft_addr = NULL;
+	struct acpi_table_ibft *table;
+	unsigned long size;
-	/* iBFT 1.03 section 1.4.3.1 mandates that UEFI machines will
-	 * only use ACPI for this */
+	table = find_ibft();
+	if (!table)
+		return;
-	if (!efi_enabled(EFI_BOOT))
-		find_ibft_in_mem();
-
-	if (ibft_addr) {
-		*sizep = PAGE_ALIGN(ibft_addr->header.length);
-		return (u64)virt_to_phys(ibft_addr);
-	}
+	size = PAGE_ALIGN(table->header.length);
+	memblock_reserve(virt_to_phys(table), size);
-	*sizep = 0;
-	return 0;
+	if (efi_enabled(EFI_BOOT))
+		acpi_put_table(&table->header);
+	else
+		ibft_addr = table;
   }
diff --git a/include/linux/iscsi_ibft.h b/include/linux/iscsi_ibft.h
index b7b45ca82bea..da813c891990 100644
--- a/include/linux/iscsi_ibft.h
+++ b/include/linux/iscsi_ibft.h
@@ -26,13 +26,9 @@ extern struct acpi_table_ibft *ibft_addr;
    * mapped address is set in the ibft_addr variable.
    */
   #ifdef CONFIG_ISCSI_IBFT_FIND
-unsigned long find_ibft_region(unsigned long *sizep);
+void reserve_ibft_region(void);
   #else
-static inline unsigned long find_ibft_region(unsigned long *sizep)
-{
-	*sizep = 0;
-	return 0;
-}
+static inline void reserve_ibft_region(void) {}
   #endif
   #endif /* ISCSI_IBFT_H */
Still no luck Mike,

We're back to the original problem where the only thing that worked was to
run "SetPageReserved(page)" before calling "kmap(page)". The page is being
"freed" before ibft_init() is called as a result of the recent buddy page
freeing changes.
I keep missing some little details each time :(
No worries. Thanks for all your help. Does this patch go on top of your 
previous patch or is it standalone?

George
quoted hunk
Ok, let's try from the different angle.
diff --git a/drivers/acpi/acpica/tbutils.c b/drivers/acpi/acpica/tbutils.c
index 4b9b329a5a92..ec43e1447336 100644
--- a/drivers/acpi/acpica/tbutils.c
+++ b/drivers/acpi/acpica/tbutils.c
@@ -7,6 +7,8 @@
   *
   *****************************************************************************/
  
+#include <linux/memblock.h>
+
  #include <acpi/acpi.h>
  #include "accommon.h"
  #include "actables.h"
@@ -339,6 +341,21 @@ acpi_tb_parse_root_table(acpi_physical_address rsdp_address)
  			acpi_tb_parse_fadt();
  		}
  
+		if (ACPI_SUCCESS(status) &&
+		    ACPI_COMPARE_NAMESEG(&acpi_gbl_root_table_list.
+					 tables[table_index].signature,
+					 ACPI_SIG_IBFT)) {
+			struct acpi_table_header *ibft;
+			struct acpi_table_desc *desc;
+
+			desc = &acpi_gbl_root_table_list.tables[table_index];
+			status = acpi_tb_get_table(desc, &ibft);
+			if (ACPI_SUCCESS(status)) {
+				memblock_reserve(address, ibft->length);
+				acpi_tb_put_table(desc);
+			}
+		}
+
  next_table:
  
  		table_entry += table_entry_size;
  

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

Re: [PATCH] mm, kasan: don't poison boot memory

From: Mike Rapoport <hidden>
Date: 2021-02-25 14:58:48

On Thu, Feb 25, 2021 at 07:38:19AM -0500, George Kennedy wrote:
On 2/25/2021 3:53 AM, Mike Rapoport wrote:
quoted
Hi George,
quoted
On 2/24/2021 5:37 AM, Mike Rapoport wrote:
quoted
On Tue, Feb 23, 2021 at 04:46:28PM -0500, George Kennedy wrote:
quoted
Mike,

Still no luck.

[   30.193723] iscsi: registered transport (iser)
[   30.195970] iBFT detected.
[   30.196571] BUG: unable to handle page fault for address: ffffffffff240004
Hmm, we cannot set ibft_addr to early pointer to the ACPI table.
Let's try something more disruptive and move the reservation back to
iscsi_ibft_find.c.
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..c615ce96c9a2 100644
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -570,16 +570,6 @@ void __init reserve_standard_io_resources(void)
   }
-static __init void reserve_ibft_region(void)
-{
-	unsigned long addr, size = 0;
-
-	addr = find_ibft_region(&size);
-
-	if (size)
-		memblock_reserve(addr, size);
-}
-
   static bool __init snb_gfx_workaround_needed(void)
   {
   #ifdef CONFIG_PCI
@@ -1032,6 +1022,12 @@ void __init setup_arch(char **cmdline_p)
   	 */
   	find_smp_config();
+	/*
+	 * Initialize the ACPI boot-time table parser.
+	 */
+	if (acpi_table_init())
+		disable_acpi();
+
   	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..01be513843d6 100644
--- a/drivers/firmware/iscsi_ibft_find.c
+++ b/drivers/firmware/iscsi_ibft_find.c
@@ -47,7 +47,25 @@ static const struct {
   #define VGA_MEM 0xA0000 /* VGA buffer */
   #define VGA_SIZE 0x20000 /* 128kB */
-static int __init find_ibft_in_mem(void)
+static void __init *acpi_find_ibft_region(void)
+{
+	int i;
+	struct acpi_table_header *table = NULL;
+	acpi_status status;
+
+	if (acpi_disabled)
+		return NULL;
+
+	for (i = 0; i < ARRAY_SIZE(ibft_signs) && !ibft_addr; i++) {
+		status = acpi_get_table(ibft_signs[i].sign, 0, &table);
+		if (ACPI_SUCCESS(status))
+			return table;
+	}
+
+	return NULL;
+}
+
+static void __init *find_ibft_in_mem(void)
   {
   	unsigned long pos;
   	unsigned int len = 0;
@@ -70,35 +88,44 @@ static int __init find_ibft_in_mem(void)
   				/* if the length of the table extends past 1M,
   				 * the table cannot be valid. */
   				if (pos + len <= (IBFT_END-1)) {
-					ibft_addr = (struct acpi_table_ibft *)virt;
   					pr_info("iBFT found at 0x%lx.\n", pos);
-					goto done;
+					return virt;
   				}
   			}
   		}
   	}
-done:
-	return len;
+
+	return NULL;
   }
+
+static void __init *find_ibft(void)
+{
+	/* iBFT 1.03 section 1.4.3.1 mandates that UEFI machines will
+	 * only use ACPI for this */
+	if (!efi_enabled(EFI_BOOT))
+		return find_ibft_in_mem();
+	else
+		return acpi_find_ibft_region();
+}
+
   /*
    * Routine used to find the iSCSI Boot Format Table. The logical
    * kernel address is set in the ibft_addr global variable.
    */
-unsigned long __init find_ibft_region(unsigned long *sizep)
+void __init reserve_ibft_region(void)
   {
-	ibft_addr = NULL;
+	struct acpi_table_ibft *table;
+	unsigned long size;
-	/* iBFT 1.03 section 1.4.3.1 mandates that UEFI machines will
-	 * only use ACPI for this */
+	table = find_ibft();
+	if (!table)
+		return;
-	if (!efi_enabled(EFI_BOOT))
-		find_ibft_in_mem();
-
-	if (ibft_addr) {
-		*sizep = PAGE_ALIGN(ibft_addr->header.length);
-		return (u64)virt_to_phys(ibft_addr);
-	}
+	size = PAGE_ALIGN(table->header.length);
+	memblock_reserve(virt_to_phys(table), size);
-	*sizep = 0;
-	return 0;
+	if (efi_enabled(EFI_BOOT))
+		acpi_put_table(&table->header);
+	else
+		ibft_addr = table;
   }
diff --git a/include/linux/iscsi_ibft.h b/include/linux/iscsi_ibft.h
index b7b45ca82bea..da813c891990 100644
--- a/include/linux/iscsi_ibft.h
+++ b/include/linux/iscsi_ibft.h
@@ -26,13 +26,9 @@ extern struct acpi_table_ibft *ibft_addr;
    * mapped address is set in the ibft_addr variable.
    */
   #ifdef CONFIG_ISCSI_IBFT_FIND
-unsigned long find_ibft_region(unsigned long *sizep);
+void reserve_ibft_region(void);
   #else
-static inline unsigned long find_ibft_region(unsigned long *sizep)
-{
-	*sizep = 0;
-	return 0;
-}
+static inline void reserve_ibft_region(void) {}
   #endif
   #endif /* ISCSI_IBFT_H */
Still no luck Mike,

We're back to the original problem where the only thing that worked was to
run "SetPageReserved(page)" before calling "kmap(page)". The page is being
"freed" before ibft_init() is called as a result of the recent buddy page
freeing changes.
I keep missing some little details each time :(
No worries. Thanks for all your help. Does this patch go on top of your
previous patch or is it standalone?
This is standalone.
 
George
quoted
Ok, let's try from the different angle.
diff --git a/drivers/acpi/acpica/tbutils.c b/drivers/acpi/acpica/tbutils.c
index 4b9b329a5a92..ec43e1447336 100644
--- a/drivers/acpi/acpica/tbutils.c
+++ b/drivers/acpi/acpica/tbutils.c
@@ -7,6 +7,8 @@
   *
   *****************************************************************************/
+#include <linux/memblock.h>
+
  #include <acpi/acpi.h>
  #include "accommon.h"
  #include "actables.h"
@@ -339,6 +341,21 @@ acpi_tb_parse_root_table(acpi_physical_address rsdp_address)
  			acpi_tb_parse_fadt();
  		}
+		if (ACPI_SUCCESS(status) &&
+		    ACPI_COMPARE_NAMESEG(&acpi_gbl_root_table_list.
+					 tables[table_index].signature,
+					 ACPI_SIG_IBFT)) {
+			struct acpi_table_header *ibft;
+			struct acpi_table_desc *desc;
+
+			desc = &acpi_gbl_root_table_list.tables[table_index];
+			status = acpi_tb_get_table(desc, &ibft);
+			if (ACPI_SUCCESS(status)) {
+				memblock_reserve(address, ibft->length);
+				acpi_tb_put_table(desc);
+			}
+		}
+
  next_table:
  		table_entry += table_entry_size;
-- 
Sincerely yours,
Mike.

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

Re: [PATCH] mm, kasan: don't poison boot memory

From: George Kennedy <hidden>
Date: 2021-02-25 15:27:47


On 2/25/2021 9:57 AM, Mike Rapoport wrote:
On Thu, Feb 25, 2021 at 07:38:19AM -0500, George Kennedy wrote:
quoted
On 2/25/2021 3:53 AM, Mike Rapoport wrote:
quoted
Hi George,
quoted
On 2/24/2021 5:37 AM, Mike Rapoport wrote:
quoted
On Tue, Feb 23, 2021 at 04:46:28PM -0500, George Kennedy wrote:
quoted
Mike,

Still no luck.

[   30.193723] iscsi: registered transport (iser)
[   30.195970] iBFT detected.
[   30.196571] BUG: unable to handle page fault for address: ffffffffff240004
Hmm, we cannot set ibft_addr to early pointer to the ACPI table.
Let's try something more disruptive and move the reservation back to
iscsi_ibft_find.c.
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..c615ce96c9a2 100644
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -570,16 +570,6 @@ void __init reserve_standard_io_resources(void)
    }
-static __init void reserve_ibft_region(void)
-{
-	unsigned long addr, size = 0;
-
-	addr = find_ibft_region(&size);
-
-	if (size)
-		memblock_reserve(addr, size);
-}
-
    static bool __init snb_gfx_workaround_needed(void)
    {
    #ifdef CONFIG_PCI
@@ -1032,6 +1022,12 @@ void __init setup_arch(char **cmdline_p)
    	 */
    	find_smp_config();
+	/*
+	 * Initialize the ACPI boot-time table parser.
+	 */
+	if (acpi_table_init())
+		disable_acpi();
+
    	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..01be513843d6 100644
--- a/drivers/firmware/iscsi_ibft_find.c
+++ b/drivers/firmware/iscsi_ibft_find.c
@@ -47,7 +47,25 @@ static const struct {
    #define VGA_MEM 0xA0000 /* VGA buffer */
    #define VGA_SIZE 0x20000 /* 128kB */
-static int __init find_ibft_in_mem(void)
+static void __init *acpi_find_ibft_region(void)
+{
+	int i;
+	struct acpi_table_header *table = NULL;
+	acpi_status status;
+
+	if (acpi_disabled)
+		return NULL;
+
+	for (i = 0; i < ARRAY_SIZE(ibft_signs) && !ibft_addr; i++) {
+		status = acpi_get_table(ibft_signs[i].sign, 0, &table);
+		if (ACPI_SUCCESS(status))
+			return table;
+	}
+
+	return NULL;
+}
+
+static void __init *find_ibft_in_mem(void)
    {
    	unsigned long pos;
    	unsigned int len = 0;
@@ -70,35 +88,44 @@ static int __init find_ibft_in_mem(void)
    				/* if the length of the table extends past 1M,
    				 * the table cannot be valid. */
    				if (pos + len <= (IBFT_END-1)) {
-					ibft_addr = (struct acpi_table_ibft *)virt;
    					pr_info("iBFT found at 0x%lx.\n", pos);
-					goto done;
+					return virt;
    				}
    			}
    		}
    	}
-done:
-	return len;
+
+	return NULL;
    }
+
+static void __init *find_ibft(void)
+{
+	/* iBFT 1.03 section 1.4.3.1 mandates that UEFI machines will
+	 * only use ACPI for this */
+	if (!efi_enabled(EFI_BOOT))
+		return find_ibft_in_mem();
+	else
+		return acpi_find_ibft_region();
+}
+
    /*
     * Routine used to find the iSCSI Boot Format Table. The logical
     * kernel address is set in the ibft_addr global variable.
     */
-unsigned long __init find_ibft_region(unsigned long *sizep)
+void __init reserve_ibft_region(void)
    {
-	ibft_addr = NULL;
+	struct acpi_table_ibft *table;
+	unsigned long size;
-	/* iBFT 1.03 section 1.4.3.1 mandates that UEFI machines will
-	 * only use ACPI for this */
+	table = find_ibft();
+	if (!table)
+		return;
-	if (!efi_enabled(EFI_BOOT))
-		find_ibft_in_mem();
-
-	if (ibft_addr) {
-		*sizep = PAGE_ALIGN(ibft_addr->header.length);
-		return (u64)virt_to_phys(ibft_addr);
-	}
+	size = PAGE_ALIGN(table->header.length);
+	memblock_reserve(virt_to_phys(table), size);
-	*sizep = 0;
-	return 0;
+	if (efi_enabled(EFI_BOOT))
+		acpi_put_table(&table->header);
+	else
+		ibft_addr = table;
    }
diff --git a/include/linux/iscsi_ibft.h b/include/linux/iscsi_ibft.h
index b7b45ca82bea..da813c891990 100644
--- a/include/linux/iscsi_ibft.h
+++ b/include/linux/iscsi_ibft.h
@@ -26,13 +26,9 @@ extern struct acpi_table_ibft *ibft_addr;
     * mapped address is set in the ibft_addr variable.
     */
    #ifdef CONFIG_ISCSI_IBFT_FIND
-unsigned long find_ibft_region(unsigned long *sizep);
+void reserve_ibft_region(void);
    #else
-static inline unsigned long find_ibft_region(unsigned long *sizep)
-{
-	*sizep = 0;
-	return 0;
-}
+static inline void reserve_ibft_region(void) {}
    #endif
    #endif /* ISCSI_IBFT_H */
Still no luck Mike,

We're back to the original problem where the only thing that worked was to
run "SetPageReserved(page)" before calling "kmap(page)". The page is being
"freed" before ibft_init() is called as a result of the recent buddy page
freeing changes.
I keep missing some little details each time :(
No worries. Thanks for all your help. Does this patch go on top of your
previous patch or is it standalone?
This is standalone.
  
quoted
George
quoted
Ok, let's try from the different angle.
diff --git a/drivers/acpi/acpica/tbutils.c b/drivers/acpi/acpica/tbutils.c
index 4b9b329a5a92..ec43e1447336 100644
--- a/drivers/acpi/acpica/tbutils.c
+++ b/drivers/acpi/acpica/tbutils.c
@@ -7,6 +7,8 @@
    *
    *****************************************************************************/
+#include <linux/memblock.h>
+
   #include <acpi/acpi.h>
   #include "accommon.h"
   #include "actables.h"
@@ -339,6 +341,21 @@ acpi_tb_parse_root_table(acpi_physical_address rsdp_address)
   			acpi_tb_parse_fadt();
   		}
+		if (ACPI_SUCCESS(status) &&
+		    ACPI_COMPARE_NAMESEG(&acpi_gbl_root_table_list.
+					 tables[table_index].signature,
+					 ACPI_SIG_IBFT)) {
+			struct acpi_table_header *ibft;
+			struct acpi_table_desc *desc;
+
+			desc = &acpi_gbl_root_table_list.tables[table_index];
+			status = acpi_tb_get_table(desc, &ibft);
+			if (ACPI_SUCCESS(status)) {
+				memblock_reserve(address, ibft->length);
+				acpi_tb_put_table(desc);
+		
+		}
+
   next_table:
   		table_entry += table_entry_size;
Applied just your latest patch, but same failure.

I thought there was an earlier comment (which I can't find now) that 
stated that memblock_reserve() wouldn't reserve the page, which is 
what's needed here.

[   30.308229] iBFT detected..
[   30.308796] 
==================================================================
[   30.308890] BUG: KASAN: use-after-free in ibft_init+0x134/0xc33
[   30.308890] Read of size 4 at addr ffff8880be453004 by task swapper/0/1
[   30.308890]
[   30.308890] CPU: 1 PID: 1 Comm: swapper/0 Not tainted 5.11.0-f9593a0 #12
[   30.308890] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), 
BIOS 0.0.0 02/06/2015
[   30.308890] Call Trace:
[   30.308890]  dump_stack+0xdb/0x120
[   30.308890]  ? ibft_init+0x134/0xc33
[   30.308890]  print_address_description.constprop.7+0x41/0x60
[   30.308890]  ? ibft_init+0x134/0xc33
[   30.308890]  ? ibft_init+0x134/0xc33
[   30.308890]  kasan_report.cold.10+0x78/0xd1
[   30.308890]  ? ibft_init+0x134/0xc33
[   30.308890]  __asan_report_load_n_noabort+0xf/0x20
[   30.308890]  ibft_init+0x134/0xc33
[   30.308890]  ? write_comp_data+0x2f/0x90
[   30.308890]  ? ibft_check_initiator_for+0x159/0x159
[   30.308890]  ? write_comp_data+0x2f/0x90
[   30.308890]  ? ibft_check_initiator_for+0x159/0x159
[   30.308890]  do_one_initcall+0xc4/0x3e0
[   30.308890]  ? perf_trace_initcall_level+0x3e0/0x3e0
[   30.308890]  ? unpoison_range+0x14/0x40
[   30.308890]  ? ____kasan_kmalloc.constprop.5+0x8f/0xc0
[   30.308890]  ? kernel_init_freeable+0x420/0x652
[   30.308890]  ? __kasan_kmalloc+0x9/0x10
[   30.308890]  ? __sanitizer_cov_trace_pc+0x21/0x50
[   30.308890]  kernel_init_freeable+0x596/0x652
[   30.308890]  ? console_on_rootfs+0x7d/0x7d
[   30.308890]  ? __sanitizer_cov_trace_pc+0x21/0x50
[   30.308890]  ? rest_init+0xf0/0xf0
[   30.308890]  kernel_init+0x16/0x1d0
[   30.308890]  ? rest_init+0xf0/0xf0
[   30.308890]  ret_from_fork+0x22/0x30
[   30.308890]
[   30.308890] The buggy address belongs to the page:
[   30.308890] page:0000000001b7b17c refcount:0 mapcount:0 
mapping:0000000000000000 index:0x1 pfn:0xbe453
[   30.308890] flags: 0xfffffc0000000()
[   30.308890] raw: 000fffffc0000000 ffffea0002ef9788 ffffea0002f91488 
0000000000000000
[   30.308890] raw: 0000000000000001 0000000000000000 00000000ffffffff 
0000000000000000
[   30.308890] page dumped because: kasan: bad access detected
[   30.308890] page_owner tracks the page as freed
[   30.308890] page last allocated via order 0, migratetype Movable, 
gfp_mask 0x100dca(GFP_HIGHUSER_MOVABLE|__GFP_ZERO), pid 204, ts 28121288605
[   30.308890]  prep_new_page+0xfb/0x140
[   30.308890]  get_page_from_freelist+0x3503/0x5730
[   30.308890]  __alloc_pages_nodemask+0x2d8/0x650
[   30.308890]  alloc_pages_vma+0xe2/0x560
[   30.308890]  __handle_mm_fault+0x930/0x26c0
[   30.308890]  handle_mm_fault+0x1f9/0x810
[   30.308890]  do_user_addr_fault+0x6f7/0xca0
[   30.308890]  exc_page_fault+0xaf/0x1a0
[   30.308890]  asm_exc_page_fault+0x1e/0x30
[   30.308890] page last free stack trace:
[   30.308890]  free_pcp_prepare+0x122/0x290
[   30.308890]  free_unref_page_list+0xe6/0x490
[   30.308890]  release_pages+0x2ed/0x1270
[   30.308890]  free_pages_and_swap_cache+0x245/0x2e0
[   30.308890]  tlb_flush_mmu+0x11e/0x680
[   30.308890]  tlb_finish_mmu+0xa6/0x3e0
[   30.308890]  exit_mmap+0x2b3/0x540
[   30.308890]  mmput+0x11d/0x450
[   30.308890]  do_exit+0xaa6/0x2d40
[   30.308890]  do_group_exit+0x128/0x340
[   30.308890]  __x64_sys_exit_group+0x43/0x50
[   30.308890]  do_syscall_64+0x37/0x50
[   30.308890]  entry_SYSCALL_64_after_hwframe+0x44/0xa9
[   30.308890]
[   30.308890] Memory state around the buggy address:
[   30.308890]  ffff8880be452f00: ff ff ff ff ff ff ff ff ff ff ff ff ff 
ff ff ff
[   30.308890]  ffff8880be452f80: ff ff ff ff ff ff ff ff ff ff ff ff ff 
ff ff ff
[   30.308890] >ffff8880be453000: ff ff ff ff ff ff ff ff ff ff ff ff ff 
ff ff ff
[   30.308890]                    ^
[   30.308890]  ffff8880be453080: ff ff ff ff ff ff ff ff ff ff ff ff ff 
ff ff ff
[   30.308890]  ffff8880be453100: ff ff ff ff ff ff ff ff ff ff ff ff ff 
ff ff ff
[   30.308890] 
==================================================================

George


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

Re: [PATCH] mm, kasan: don't poison boot memory

From: George Kennedy <hidden>
Date: 2021-02-25 16:08:21


On 2/25/2021 10:22 AM, George Kennedy wrote:

On 2/25/2021 9:57 AM, Mike Rapoport wrote:
quoted
On Thu, Feb 25, 2021 at 07:38:19AM -0500, George Kennedy wrote:
quoted
On 2/25/2021 3:53 AM, Mike Rapoport wrote:
quoted
Hi George,
quoted
On 2/24/2021 5:37 AM, Mike Rapoport wrote:
quoted
On Tue, Feb 23, 2021 at 04:46:28PM -0500, George Kennedy wrote:
quoted
Mike,

Still no luck.

[   30.193723] iscsi: registered transport (iser)
[   30.195970] iBFT detected.
[   30.196571] BUG: unable to handle page fault for address: 
ffffffffff240004
Hmm, we cannot set ibft_addr to early pointer to the ACPI table.
Let's try something more disruptive and move the reservation back to
iscsi_ibft_find.c.
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..c615ce96c9a2 100644
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -570,16 +570,6 @@ void __init reserve_standard_io_resources(void)
    }
-static __init void reserve_ibft_region(void)
-{
-    unsigned long addr, size = 0;
-
-    addr = find_ibft_region(&size);
-
-    if (size)
-        memblock_reserve(addr, size);
-}
-
    static bool __init snb_gfx_workaround_needed(void)
    {
    #ifdef CONFIG_PCI
@@ -1032,6 +1022,12 @@ void __init setup_arch(char **cmdline_p)
         */
        find_smp_config();
+    /*
+     * Initialize the ACPI boot-time table parser.
+     */
+    if (acpi_table_init())
+        disable_acpi();
+
        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..01be513843d6 100644
--- a/drivers/firmware/iscsi_ibft_find.c
+++ b/drivers/firmware/iscsi_ibft_find.c
@@ -47,7 +47,25 @@ static const struct {
    #define VGA_MEM 0xA0000 /* VGA buffer */
    #define VGA_SIZE 0x20000 /* 128kB */
-static int __init find_ibft_in_mem(void)
+static void __init *acpi_find_ibft_region(void)
+{
+    int i;
+    struct acpi_table_header *table = NULL;
+    acpi_status status;
+
+    if (acpi_disabled)
+        return NULL;
+
+    for (i = 0; i < ARRAY_SIZE(ibft_signs) && !ibft_addr; i++) {
+        status = acpi_get_table(ibft_signs[i].sign, 0, &table);
+        if (ACPI_SUCCESS(status))
+            return table;
+    }
+
+    return NULL;
+}
+
+static void __init *find_ibft_in_mem(void)
    {
        unsigned long pos;
        unsigned int len = 0;
@@ -70,35 +88,44 @@ static int __init find_ibft_in_mem(void)
                    /* if the length of the table extends past 1M,
                     * the table cannot be valid. */
                    if (pos + len <= (IBFT_END-1)) {
-                    ibft_addr = (struct acpi_table_ibft *)virt;
                        pr_info("iBFT found at 0x%lx.\n", pos);
-                    goto done;
+                    return virt;
                    }
                }
            }
        }
-done:
-    return len;
+
+    return NULL;
    }
+
+static void __init *find_ibft(void)
+{
+    /* iBFT 1.03 section 1.4.3.1 mandates that UEFI machines will
+     * only use ACPI for this */
+    if (!efi_enabled(EFI_BOOT))
+        return find_ibft_in_mem();
+    else
+        return acpi_find_ibft_region();
+}
+
    /*
     * Routine used to find the iSCSI Boot Format Table. The logical
     * kernel address is set in the ibft_addr global variable.
     */
-unsigned long __init find_ibft_region(unsigned long *sizep)
+void __init reserve_ibft_region(void)
    {
-    ibft_addr = NULL;
+    struct acpi_table_ibft *table;
+    unsigned long size;
-    /* iBFT 1.03 section 1.4.3.1 mandates that UEFI machines will
-     * only use ACPI for this */
+    table = find_ibft();
+    if (!table)
+        return;
-    if (!efi_enabled(EFI_BOOT))
-        find_ibft_in_mem();
-
-    if (ibft_addr) {
-        *sizep = PAGE_ALIGN(ibft_addr->header.length);
-        return (u64)virt_to_phys(ibft_addr);
-    }
+    size = PAGE_ALIGN(table->header.length);
+    memblock_reserve(virt_to_phys(table), size);
-    *sizep = 0;
-    return 0;
+    if (efi_enabled(EFI_BOOT))
+        acpi_put_table(&table->header);
+    else
+        ibft_addr = table;
    }
diff --git a/include/linux/iscsi_ibft.h b/include/linux/iscsi_ibft.h
index b7b45ca82bea..da813c891990 100644
--- a/include/linux/iscsi_ibft.h
+++ b/include/linux/iscsi_ibft.h
@@ -26,13 +26,9 @@ extern struct acpi_table_ibft *ibft_addr;
     * mapped address is set in the ibft_addr variable.
     */
    #ifdef CONFIG_ISCSI_IBFT_FIND
-unsigned long find_ibft_region(unsigned long *sizep);
+void reserve_ibft_region(void);
    #else
-static inline unsigned long find_ibft_region(unsigned long *sizep)
-{
-    *sizep = 0;
-    return 0;
-}
+static inline void reserve_ibft_region(void) {}
    #endif
    #endif /* ISCSI_IBFT_H */
Still no luck Mike,

We're back to the original problem where the only thing that 
worked was to
run "SetPageReserved(page)" before calling "kmap(page)". The page 
is being
"freed" before ibft_init() is called as a result of the recent 
buddy page
freeing changes.
I keep missing some little details each time :(
No worries. Thanks for all your help. Does this patch go on top of your
previous patch or is it standalone?
This is standalone.
quoted
George
quoted
Ok, let's try from the different angle.
diff --git a/drivers/acpi/acpica/tbutils.c 
b/drivers/acpi/acpica/tbutils.c
index 4b9b329a5a92..ec43e1447336 100644
--- a/drivers/acpi/acpica/tbutils.c
+++ b/drivers/acpi/acpica/tbutils.c
@@ -7,6 +7,8 @@
    *
*****************************************************************************/
+#include <linux/memblock.h>
+
   #include <acpi/acpi.h>
   #include "accommon.h"
   #include "actables.h"
@@ -339,6 +341,21 @@ acpi_tb_parse_root_table(acpi_physical_address 
rsdp_address)
               acpi_tb_parse_fadt();
           }
+        if (ACPI_SUCCESS(status) &&
+ ACPI_COMPARE_NAMESEG(&acpi_gbl_root_table_list.
+                     tables[table_index].signature,
+                     ACPI_SIG_IBFT)) {
+            struct acpi_table_header *ibft;
+            struct acpi_table_desc *desc;
+
+            desc = &acpi_gbl_root_table_list.tables[table_index];
+            status = acpi_tb_get_table(desc, &ibft);
+            if (ACPI_SUCCESS(status)) {
+                memblock_reserve(address, ibft->length);
+                acpi_tb_put_table(desc);
+
+        }
+
   next_table:
           table_entry += table_entry_size;
Applied just your latest patch, but same failure.

I thought there was an earlier comment (which I can't find now) that 
stated that memblock_reserve() wouldn't reserve the page, which is 
what's needed here.
Mike,

Here was David's explanation of what he thinks is going on (or should be 
going on) from a few days ago:

QUOTE...
I assume that acpi_map()/acpi_unmap() map some firmware blob that is 
provided via firmware/bios/... to us.

should_use_kmap() tells us whether
a) we have a "struct page" and should kmap() that one
b) we don't have a "struct page" and should ioremap.

As it is a blob, the firmware should always reserve that memory region 
via memblock (e.g., memblock_reserve()), such that we either
1) don't create a memmap ("struct page") at all (-> case b) )
2) if we have to create e memmap, we mark the page PG_reserved and
*never* expose it to the buddy (-> case a) )


Are you telling me that in this case we might have a memmap for the HW 
blob that is *not* PG_reserved? In that case it most probably got 
exposed to the buddy where it can happily get allocated/freed.

The latent BUG would be that that blob gets exposed to the system like 
ordinary RAM, and not reserved via memblock early during boot. Assuming 
that blob has a low physical address, with my patch it will get 
allocated/used a lot earlier - which would mean we trigger this latent 
BUG now more easily.
...END_QUOTE

Your most recent patch has added the memblock_reserve(), but it's still 
missing the PG_reserved setting.

Thanks,
George
[   30.308229] iBFT detected..
[   30.308796] 
==================================================================
[   30.308890] BUG: KASAN: use-after-free in ibft_init+0x134/0xc33
[   30.308890] Read of size 4 at addr ffff8880be453004 by task 
swapper/0/1
[   30.308890]
[   30.308890] CPU: 1 PID: 1 Comm: swapper/0 Not tainted 
5.11.0-f9593a0 #12
[   30.308890] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), 
BIOS 0.0.0 02/06/2015
[   30.308890] Call Trace:
[   30.308890]  dump_stack+0xdb/0x120
[   30.308890]  ? ibft_init+0x134/0xc33
[   30.308890]  print_address_description.constprop.7+0x41/0x60
[   30.308890]  ? ibft_init+0x134/0xc33
[   30.308890]  ? ibft_init+0x134/0xc33
[   30.308890]  kasan_report.cold.10+0x78/0xd1
[   30.308890]  ? ibft_init+0x134/0xc33
[   30.308890]  __asan_report_load_n_noabort+0xf/0x20
[   30.308890]  ibft_init+0x134/0xc33
[   30.308890]  ? write_comp_data+0x2f/0x90
[   30.308890]  ? ibft_check_initiator_for+0x159/0x159
[   30.308890]  ? write_comp_data+0x2f/0x90
[   30.308890]  ? ibft_check_initiator_for+0x159/0x159
[   30.308890]  do_one_initcall+0xc4/0x3e0
[   30.308890]  ? perf_trace_initcall_level+0x3e0/0x3e0
[   30.308890]  ? unpoison_range+0x14/0x40
[   30.308890]  ? ____kasan_kmalloc.constprop.5+0x8f/0xc0
[   30.308890]  ? kernel_init_freeable+0x420/0x652
[   30.308890]  ? __kasan_kmalloc+0x9/0x10
[   30.308890]  ? __sanitizer_cov_trace_pc+0x21/0x50
[   30.308890]  kernel_init_freeable+0x596/0x652
[   30.308890]  ? console_on_rootfs+0x7d/0x7d
[   30.308890]  ? __sanitizer_cov_trace_pc+0x21/0x50
[   30.308890]  ? rest_init+0xf0/0xf0
[   30.308890]  kernel_init+0x16/0x1d0
[   30.308890]  ? rest_init+0xf0/0xf0
[   30.308890]  ret_from_fork+0x22/0x30
[   30.308890]
[   30.308890] The buggy address belongs to the page:
[   30.308890] page:0000000001b7b17c refcount:0 mapcount:0 
mapping:0000000000000000 index:0x1 pfn:0xbe453
[   30.308890] flags: 0xfffffc0000000()
[   30.308890] raw: 000fffffc0000000 ffffea0002ef9788 ffffea0002f91488 
0000000000000000
[   30.308890] raw: 0000000000000001 0000000000000000 00000000ffffffff 
0000000000000000
[   30.308890] page dumped because: kasan: bad access detected
[   30.308890] page_owner tracks the page as freed
[   30.308890] page last allocated via order 0, migratetype Movable, 
gfp_mask 0x100dca(GFP_HIGHUSER_MOVABLE|__GFP_ZERO), pid 204, ts 
28121288605
[   30.308890]  prep_new_page+0xfb/0x140
[   30.308890]  get_page_from_freelist+0x3503/0x5730
[   30.308890]  __alloc_pages_nodemask+0x2d8/0x650
[   30.308890]  alloc_pages_vma+0xe2/0x560
[   30.308890]  __handle_mm_fault+0x930/0x26c0
[   30.308890]  handle_mm_fault+0x1f9/0x810
[   30.308890]  do_user_addr_fault+0x6f7/0xca0
[   30.308890]  exc_page_fault+0xaf/0x1a0
[   30.308890]  asm_exc_page_fault+0x1e/0x30
[   30.308890] page last free stack trace:
[   30.308890]  free_pcp_prepare+0x122/0x290
[   30.308890]  free_unref_page_list+0xe6/0x490
[   30.308890]  release_pages+0x2ed/0x1270
[   30.308890]  free_pages_and_swap_cache+0x245/0x2e0
[   30.308890]  tlb_flush_mmu+0x11e/0x680
[   30.308890]  tlb_finish_mmu+0xa6/0x3e0
[   30.308890]  exit_mmap+0x2b3/0x540
[   30.308890]  mmput+0x11d/0x450
[   30.308890]  do_exit+0xaa6/0x2d40
[   30.308890]  do_group_exit+0x128/0x340
[   30.308890]  __x64_sys_exit_group+0x43/0x50
[   30.308890]  do_syscall_64+0x37/0x50
[   30.308890]  entry_SYSCALL_64_after_hwframe+0x44/0xa9
[   30.308890]
[   30.308890] Memory state around the buggy address:
[   30.308890]  ffff8880be452f00: ff ff ff ff ff ff ff ff ff ff ff ff 
ff ff ff ff
[   30.308890]  ffff8880be452f80: ff ff ff ff ff ff ff ff ff ff ff ff 
ff ff ff ff
[   30.308890] >ffff8880be453000: ff ff ff ff ff ff ff ff ff ff ff ff 
ff ff ff ff
[   30.308890]                    ^
[   30.308890]  ffff8880be453080: ff ff ff ff ff ff ff ff ff ff ff ff 
ff ff ff ff
[   30.308890]  ffff8880be453100: ff ff ff ff ff ff ff ff ff ff ff ff 
ff ff ff ff
[   30.308890] 
==================================================================

George

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

Re: [PATCH] mm, kasan: don't poison boot memory

From: Mike Rapoport <hidden>
Date: 2021-02-25 16:10:16

On Thu, Feb 25, 2021 at 10:22:44AM -0500, George Kennedy wrote:
quoted
quoted
quoted
quoted
On 2/24/2021 5:37 AM, Mike Rapoport wrote:
Applied just your latest patch, but same failure.

I thought there was an earlier comment (which I can't find now) that stated
that memblock_reserve() wouldn't reserve the page, which is what's needed
here.
Actually, I think that memblock_reserve() should be just fine, but it seems
I'm missing something in address calculation each time.

What would happen if you stuck

	memblock_reserve(0xbe453000, PAGE_SIZE);

say, at the beginning of find_ibft_region()?
 
[   30.308229] iBFT detected..
[   30.308796]
==================================================================
[   30.308890] BUG: KASAN: use-after-free in ibft_init+0x134/0xc33
[   30.308890] Read of size 4 at addr ffff8880be453004 by task swapper/0/1
[   30.308890]
[   30.308890] CPU: 1 PID: 1 Comm: swapper/0 Not tainted 5.11.0-f9593a0 #12
[   30.308890] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS
0.0.0 02/06/2015
[   30.308890] Call Trace:
[   30.308890]  dump_stack+0xdb/0x120
[   30.308890]  ? ibft_init+0x134/0xc33
[   30.308890]  print_address_description.constprop.7+0x41/0x60
[   30.308890]  ? ibft_init+0x134/0xc33
[   30.308890]  ? ibft_init+0x134/0xc33
[   30.308890]  kasan_report.cold.10+0x78/0xd1
[   30.308890]  ? ibft_init+0x134/0xc33
[   30.308890]  __asan_report_load_n_noabort+0xf/0x20
[   30.308890]  ibft_init+0x134/0xc33
[   30.308890]  ? write_comp_data+0x2f/0x90
[   30.308890]  ? ibft_check_initiator_for+0x159/0x159
[   30.308890]  ? write_comp_data+0x2f/0x90
[   30.308890]  ? ibft_check_initiator_for+0x159/0x159
[   30.308890]  do_one_initcall+0xc4/0x3e0
[   30.308890]  ? perf_trace_initcall_level+0x3e0/0x3e0
[   30.308890]  ? unpoison_range+0x14/0x40
[   30.308890]  ? ____kasan_kmalloc.constprop.5+0x8f/0xc0
[   30.308890]  ? kernel_init_freeable+0x420/0x652
[   30.308890]  ? __kasan_kmalloc+0x9/0x10
[   30.308890]  ? __sanitizer_cov_trace_pc+0x21/0x50
[   30.308890]  kernel_init_freeable+0x596/0x652
[   30.308890]  ? console_on_rootfs+0x7d/0x7d
[   30.308890]  ? __sanitizer_cov_trace_pc+0x21/0x50
[   30.308890]  ? rest_init+0xf0/0xf0
[   30.308890]  kernel_init+0x16/0x1d0
[   30.308890]  ? rest_init+0xf0/0xf0
[   30.308890]  ret_from_fork+0x22/0x30
[   30.308890]
[   30.308890] The buggy address belongs to the page:
[   30.308890] page:0000000001b7b17c refcount:0 mapcount:0
mapping:0000000000000000 index:0x1 pfn:0xbe453
[   30.308890] flags: 0xfffffc0000000()
[   30.308890] raw: 000fffffc0000000 ffffea0002ef9788 ffffea0002f91488
0000000000000000
[   30.308890] raw: 0000000000000001 0000000000000000 00000000ffffffff
0000000000000000
[   30.308890] page dumped because: kasan: bad access detected
[   30.308890] page_owner tracks the page as freed
[   30.308890] page last allocated via order 0, migratetype Movable,
gfp_mask 0x100dca(GFP_HIGHUSER_MOVABLE|__GFP_ZERO), pid 204, ts 28121288605
[   30.308890]  prep_new_page+0xfb/0x140
[   30.308890]  get_page_from_freelist+0x3503/0x5730
[   30.308890]  __alloc_pages_nodemask+0x2d8/0x650
[   30.308890]  alloc_pages_vma+0xe2/0x560
[   30.308890]  __handle_mm_fault+0x930/0x26c0
[   30.308890]  handle_mm_fault+0x1f9/0x810
[   30.308890]  do_user_addr_fault+0x6f7/0xca0
[   30.308890]  exc_page_fault+0xaf/0x1a0
[   30.308890]  asm_exc_page_fault+0x1e/0x30
[   30.308890] page last free stack trace:
[   30.308890]  free_pcp_prepare+0x122/0x290
[   30.308890]  free_unref_page_list+0xe6/0x490
[   30.308890]  release_pages+0x2ed/0x1270
[   30.308890]  free_pages_and_swap_cache+0x245/0x2e0
[   30.308890]  tlb_flush_mmu+0x11e/0x680
[   30.308890]  tlb_finish_mmu+0xa6/0x3e0
[   30.308890]  exit_mmap+0x2b3/0x540
[   30.308890]  mmput+0x11d/0x450
[   30.308890]  do_exit+0xaa6/0x2d40
[   30.308890]  do_group_exit+0x128/0x340
[   30.308890]  __x64_sys_exit_group+0x43/0x50
[   30.308890]  do_syscall_64+0x37/0x50
[   30.308890]  entry_SYSCALL_64_after_hwframe+0x44/0xa9
[   30.308890]
[   30.308890] Memory state around the buggy address:
[   30.308890]  ffff8880be452f00: ff ff ff ff ff ff ff ff ff ff ff ff ff ff
ff ff
[   30.308890]  ffff8880be452f80: ff ff ff ff ff ff ff ff ff ff ff ff ff ff
ff ff
[   30.308890] >ffff8880be453000: ff ff ff ff ff ff ff ff ff ff ff ff ff ff
ff ff
[   30.308890]                    ^
[   30.308890]  ffff8880be453080: ff ff ff ff ff ff ff ff ff ff ff ff ff ff
ff ff
[   30.308890]  ffff8880be453100: ff ff ff ff ff ff ff ff ff ff ff ff ff ff
ff ff
[   30.308890]
==================================================================

George
-- 
Sincerely yours,
Mike.

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

Re: [PATCH] mm, kasan: don't poison boot memory

From: George Kennedy <hidden>
Date: 2021-02-25 16:32:39


On 2/25/2021 11:07 AM, Mike Rapoport wrote:
On Thu, Feb 25, 2021 at 10:22:44AM -0500, George Kennedy wrote:
quoted
quoted
quoted
quoted
quoted
On 2/24/2021 5:37 AM, Mike Rapoport wrote:
Applied just your latest patch, but same failure.

I thought there was an earlier comment (which I can't find now) that stated
that memblock_reserve() wouldn't reserve the page, which is what's needed
here.
Actually, I think that memblock_reserve() should be just fine, but it seems
I'm missing something in address calculation each time.

What would happen if you stuck

	memblock_reserve(0xbe453000, PAGE_SIZE);

say, at the beginning of find_ibft_region()?
Added debug to your patch and this is all that shows up. Looks like the 
patch is in the wrong place as acpi_tb_parse_root_table() is only called 
for the RSDP address.

[    0.064317] ACPI: Early table checksum verification disabled
[    0.065437] XXX acpi_tb_parse_root_table: rsdp_address=bfbfa014
[    0.066612] ACPI: RSDP 0x00000000BFBFA014 000024 (v02 BOCHS )
[    0.067759] ACPI: XSDT 0x00000000BFBF90E8 00004C (v01 BOCHS BXPCFACP 
00000001      01000013)
[    0.069470] ACPI: FACP 0x00000000BFBF5000 000074 (v01 BOCHS BXPCFACP 
00000001 BXPC 00000001)
[    0.071183] ACPI: DSDT 0x00000000BFBF6000 00238D (v01 BOCHS BXPCDSDT 
00000001 BXPC 00000001)
[    0.072876] ACPI: FACS 0x00000000BFBFD000 000040
[    0.073806] ACPI: APIC 0x00000000BFBF4000 000090 (v01 BOCHS BXPCAPIC 
00000001 BXPC 00000001)
[    0.075501] ACPI: HPET 0x00000000BFBF3000 000038 (v01 BOCHS BXPCHPET 
00000001 BXPC 00000001)
[    0.077194] ACPI: BGRT 0x00000000BE49B000 000038 (v01 INTEL EDK2     
00000002      01000013)
[    0.078880] ACPI: iBFT 0x00000000BE453000 000800 (v01 BOCHS BXPCFACP 
00000000      00000000)
[    0.080588] ACPI: Local APIC address 0xfee00000
diff --git a/drivers/acpi/acpica/tbutils.c b/drivers/acpi/acpica/tbutils.c
index dfe1ac3..603b3a8 100644
--- a/drivers/acpi/acpica/tbutils.c
+++ b/drivers/acpi/acpica/tbutils.c
@@ -7,6 +7,8 @@
   *
*****************************************************************************/

+#include <linux/memblock.h>
+
  #include <acpi/acpi.h>
  #include "accommon.h"
  #include "actables.h"
@@ -232,6 +234,8 @@ struct acpi_table_header *acpi_tb_copy_dsdt(u32 
table_index)
      acpi_status status;
      u32 table_index;

+printk(KERN_ERR "XXX acpi_tb_parse_root_table: rsdp_address=%llx\n", 
rsdp_address);
+
      ACPI_FUNCTION_TRACE(tb_parse_root_table);

      /* Map the entire RSDP and extract the address of the RSDT or XSDT */
@@ -339,6 +343,22 @@ struct acpi_table_header *acpi_tb_copy_dsdt(u32 
table_index)
              acpi_tb_parse_fadt();
          }

+        if (ACPI_SUCCESS(status) &&
+            ACPI_COMPARE_NAMESEG(&acpi_gbl_root_table_list.
+                     tables[table_index].signature,
+                     ACPI_SIG_IBFT)) {
+            struct acpi_table_header *ibft;
+            struct acpi_table_desc *desc;
+
+            desc = &acpi_gbl_root_table_list.tables[table_index];
+            status = acpi_tb_get_table(desc, &ibft);
+            if (ACPI_SUCCESS(status)) {
+printk(KERN_ERR "XXX acpi_tb_parse_root_table(calling 
memblock_reserve()): addres=%llx, ibft->length=%x\n", address, 
ibft->length);
+                memblock_reserve(address, ibft->length);
+                acpi_tb_put_table(desc);
+            }
+        }
+
  next_table:

          table_entry += table_entry_size;

  
quoted
[   30.308229] iBFT detected..
[   30.308796]
==================================================================
[   30.308890] BUG: KASAN: use-after-free in ibft_init+0x134/0xc33
[   30.308890] Read of size 4 at addr ffff8880be453004 by task swapper/0/1
[   30.308890]
[   30.308890] CPU: 1 PID: 1 Comm: swapper/0 Not tainted 5.11.0-f9593a0 #12
[   30.308890] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS
0.0.0 02/06/2015
[   30.308890] Call Trace:
[   30.308890]  dump_stack+0xdb/0x120
[   30.308890]  ? ibft_init+0x134/0xc33
[   30.308890]  print_address_description.constprop.7+0x41/0x60
[   30.308890]  ? ibft_init+0x134/0xc33
[   30.308890]  ? ibft_init+0x134/0xc33
[   30.308890]  kasan_report.cold.10+0x78/0xd1
[   30.308890]  ? ibft_init+0x134/0xc33
[   30.308890]  __asan_report_load_n_noabort+0xf/0x20
[   30.308890]  ibft_init+0x134/0xc33
[   30.308890]  ? write_comp_data+0x2f/0x90
[   30.308890]  ? ibft_check_initiator_for+0x159/0x159
[   30.308890]  ? write_comp_data+0x2f/0x90
[   30.308890]  ? ibft_check_initiator_for+0x159/0x159
[   30.308890]  do_one_initcall+0xc4/0x3e0
[   30.308890]  ? perf_trace_initcall_level+0x3e0/0x3e0
[   30.308890]  ? unpoison_range+0x14/0x40
[   30.308890]  ? ____kasan_kmalloc.constprop.5+0x8f/0xc0
[   30.308890]  ? kernel_init_freeable+0x420/0x652
[   30.308890]  ? __kasan_kmalloc+0x9/0x10
[   30.308890]  ? __sanitizer_cov_trace_pc+0x21/0x50
[   30.308890]  kernel_init_freeable+0x596/0x652
[   30.308890]  ? console_on_rootfs+0x7d/0x7d
[   30.308890]  ? __sanitizer_cov_trace_pc+0x21/0x50
[   30.308890]  ? rest_init+0xf0/0xf0
[   30.308890]  kernel_init+0x16/0x1d0
[   30.308890]  ? rest_init+0xf0/0xf0
[   30.308890]  ret_from_fork+0x22/0x30
[   30.308890]
[   30.308890] The buggy address belongs to the page:
[   30.308890] page:0000000001b7b17c refcount:0 mapcount:0
mapping:0000000000000000 index:0x1 pfn:0xbe453
[   30.308890] flags: 0xfffffc0000000()
[   30.308890] raw: 000fffffc0000000 ffffea0002ef9788 ffffea0002f91488
0000000000000000
[   30.308890] raw: 0000000000000001 0000000000000000 00000000ffffffff
0000000000000000
[   30.308890] page dumped because: kasan: bad access detected
[   30.308890] page_owner tracks the page as freed
[   30.308890] page last allocated via order 0, migratetype Movable,
gfp_mask 0x100dca(GFP_HIGHUSER_MOVABLE|__GFP_ZERO), pid 204, ts 28121288605
[   30.308890]  prep_new_page+0xfb/0x140
[   30.308890]  get_page_from_freelist+0x3503/0x5730
[   30.308890]  __alloc_pages_nodemask+0x2d8/0x650
[   30.308890]  alloc_pages_vma+0xe2/0x560
[   30.308890]  __handle_mm_fault+0x930/0x26c0
[   30.308890]  handle_mm_fault+0x1f9/0x810
[   30.308890]  do_user_addr_fault+0x6f7/0xca0
[   30.308890]  exc_page_fault+0xaf/0x1a0
[   30.308890]  asm_exc_page_fault+0x1e/0x30
[   30.308890] page last free stack trace:
[   30.308890]  free_pcp_prepare+0x122/0x290
[   30.308890]  free_unref_page_list+0xe6/0x490
[   30.308890]  release_pages+0x2ed/0x1270
[   30.308890]  free_pages_and_swap_cache+0x245/0x2e0
[   30.308890]  tlb_flush_mmu+0x11e/0x680
[   30.308890]  tlb_finish_mmu+0xa6/0x3e0
[   30.308890]  exit_mmap+0x2b3/0x540
[   30.308890]  mmput+0x11d/0x450
[   30.308890]  do_exit+0xaa6/0x2d40
[   30.308890]  do_group_exit+0x128/0x340
[   30.308890]  __x64_sys_exit_group+0x43/0x50
[   30.308890]  do_syscall_64+0x37/0x50
[   30.308890]  entry_SYSCALL_64_after_hwframe+0x44/0xa9
[   30.308890]
[   30.308890] Memory state around the buggy address:
[   30.308890]  ffff8880be452f00: ff ff ff ff ff ff ff ff ff ff ff ff ff ff
ff ff
[   30.308890]  ffff8880be452f80: ff ff ff ff ff ff ff ff ff ff ff ff ff ff
ff ff
[   30.308890] >ffff8880be453000: ff ff ff ff ff ff ff ff ff ff ff ff ff ff
ff ff
[   30.308890]                    ^
[   30.308890]  ffff8880be453080: ff ff ff ff ff ff ff ff ff ff ff ff ff ff
ff ff
[   30.308890]  ffff8880be453100: ff ff ff ff ff ff ff ff ff ff ff ff ff ff
ff ff
[   30.308890]
==================================================================

George

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

Re: [PATCH] mm, kasan: don't poison boot memory

From: David Hildenbrand <hidden>
Date: 2021-02-25 17:25:15

On 25.02.21 17:31, George Kennedy wrote:
: rsdp_address=bfbfa014
[    0.066612] ACPI: RSDP 0x00000000BFBFA014 000024 (v02 BOCHS )
[    0.067759] ACPI: XSDT 0x00000000BFBF90E8 00004C (v01 BOCHS BXPCFACP
00000001      01000013)
[    0.069470] ACPI: FACP 0x00000000BFBF5000 000074 (v01 BOCHS BXPCFACP
00000001 BXPC 00000001)
[    0.071183] ACPI: DSDT 0x00000000BFBF6000 00238D (v01 BOCHS BXPCDSDT
00000001 BXPC 00000001)
[    0.072876] ACPI: FACS 0x00000000BFBFD000 000040
[    0.073806] ACPI: APIC 0x00000000BFBF4000 000090 (v01 BOCHS BXPCAPIC
00000001 BXPC 00000001)
[    0.075501] ACPI: HPET 0x00000000BFBF3000 000038 (v01 BOCHS BXPCHPET
00000001 BXPC 00000001)
[    0.077194] ACPI: BGRT 0x00000000BE49B000 000038 (v01 INTEL EDK2
00000002      01000013)
[    0.078880] ACPI: iBFT 0x00000000BE453000 000800 (v01 BOCHS BXPCFACP
00000000      00000000)

Can you explore the relevant area using the page-flags tools (located in 
Linux src code located in tools/vm/page-flags.c)


./page-types -L -r -a 0xbe490,0xbe4a0

-- 
Thanks,

David / dhildenb


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

Re: [PATCH] mm, kasan: don't poison boot memory

From: George Kennedy <hidden>
Date: 2021-02-25 17:35:43


On 2/25/2021 11:07 AM, Mike Rapoport wrote:
On Thu, Feb 25, 2021 at 10:22:44AM -0500, George Kennedy wrote:
quoted
quoted
quoted
quoted
quoted
On 2/24/2021 5:37 AM, Mike Rapoport wrote:
Applied just your latest patch, but same failure.

I thought there was an earlier comment (which I can't find now) that stated
that memblock_reserve() wouldn't reserve the page, which is what's needed
here.
Actually, I think that memblock_reserve() should be just fine, but it seems
I'm missing something in address calculation each time.

What would happen if you stuck

	memblock_reserve(0xbe453000, PAGE_SIZE);

say, at the beginning of find_ibft_region()?
Good news Mike!

The above hack in yesterday's last patch works - 10 successful reboots. 
See: "BE453" below for the hack.

I'll modify the patch to use "table_desc->address" instead, which is the 
physical address of the table.
diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c
index 7bdc023..c118dd5 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 740f3bdb..b045ab2 100644
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -571,16 +571,6 @@ void __init reserve_standard_io_resources(void)

  }

-static __init void reserve_ibft_region(void)
-{
-    unsigned long addr, size = 0;
-
-    addr = find_ibft_region(&size);
-
-    if (size)
-        memblock_reserve(addr, size);
-}
-
  static bool __init snb_gfx_workaround_needed(void)
  {
  #ifdef CONFIG_PCI
@@ -1033,6 +1023,12 @@ void __init setup_arch(char **cmdline_p)
       */
      find_smp_config();

+    /*
+     * Initialize the ACPI boot-time table parser.
+     */
+    if (acpi_table_init())
+        disable_acpi();
+
      reserve_ibft_region();

      early_alloc_pgt_buf();
diff --git a/drivers/firmware/iscsi_ibft_find.c 
b/drivers/firmware/iscsi_ibft_find.c
index 64bb945..95fc1a6 100644
--- a/drivers/firmware/iscsi_ibft_find.c
+++ b/drivers/firmware/iscsi_ibft_find.c
@@ -47,7 +47,25 @@
  #define VGA_MEM 0xA0000 /* VGA buffer */
  #define VGA_SIZE 0x20000 /* 128kB */

-static int __init find_ibft_in_mem(void)
+static void __init *acpi_find_ibft_region(void)
+{
+    int i;
+    struct acpi_table_header *table = NULL;
+    acpi_status status;
+
+    if (acpi_disabled)
+        return NULL;
+
+    for (i = 0; i < ARRAY_SIZE(ibft_signs) && !ibft_addr; i++) {
+        status = acpi_get_table(ibft_signs[i].sign, 0, &table);
+        if (ACPI_SUCCESS(status))
+            return table;
+    }
+
+    return NULL;
+}
+
+static void __init *find_ibft_in_mem(void)
  {
      unsigned long pos;
      unsigned int len = 0;
@@ -70,35 +88,52 @@ static int __init find_ibft_in_mem(void)
                  /* if the length of the table extends past 1M,
                   * the table cannot be valid. */
                  if (pos + len <= (IBFT_END-1)) {
-                    ibft_addr = (struct acpi_table_ibft *)virt;
                      pr_info("iBFT found at 0x%lx.\n", pos);
-                    goto done;
+                    return virt;
                  }
              }
          }
      }
-done:
-    return len;
+
+    return NULL;
  }
+
+static void __init *find_ibft(void)
+{
+    /* iBFT 1.03 section 1.4.3.1 mandates that UEFI machines will
+     * only use ACPI for this */
+    if (!efi_enabled(EFI_BOOT))
+        return find_ibft_in_mem();
+    else
+        return acpi_find_ibft_region();
+}
+
  /*
   * Routine used to find the iSCSI Boot Format Table. The logical
   * kernel address is set in the ibft_addr global variable.
   */
-unsigned long __init find_ibft_region(unsigned long *sizep)
+void __init reserve_ibft_region(void)
  {
-    ibft_addr = NULL;
+    struct acpi_table_ibft *table;
+    unsigned long size;

-    /* iBFT 1.03 section 1.4.3.1 mandates that UEFI machines will
-     * only use ACPI for this */
+    table = find_ibft();
+    if (!table)
+        return;

-    if (!efi_enabled(EFI_BOOT))
-        find_ibft_in_mem();
-
-    if (ibft_addr) {
-        *sizep = PAGE_ALIGN(ibft_addr->header.length);
-        return (u64)virt_to_phys(ibft_addr);
-    }
+    size = PAGE_ALIGN(table->header.length);
+#if 0
+printk(KERN_ERR "XXX reserve_ibft_region: table=%llx, 
virt_to_phys(table)=%llx, size=%lx\n",
+    (u64)table, virt_to_phys(table), size);
+    memblock_reserve(virt_to_phys(table), size);
+#else
+printk(KERN_ERR "XXX reserve_ibft_region: table=%llx, 
0x00000000BE453000, size=%lx\n",
+    (u64)table, size);
+    memblock_reserve(0x00000000BE453000, size);
+#endif

-    *sizep = 0;
-    return 0;
+    if (efi_enabled(EFI_BOOT))
+        acpi_put_table(&table->header);
+    else
+        ibft_addr = table;
  }
diff --git a/include/linux/iscsi_ibft.h b/include/linux/iscsi_ibft.h
index b7b45ca..da813c8 100644
--- a/include/linux/iscsi_ibft.h
+++ b/include/linux/iscsi_ibft.h
@@ -26,13 +26,9 @@
   * mapped address is set in the ibft_addr variable.
   */
  #ifdef CONFIG_ISCSI_IBFT_FIND
-unsigned long find_ibft_region(unsigned long *sizep);
+void reserve_ibft_region(void);
  #else
-static inline unsigned long find_ibft_region(unsigned long *sizep)
-{
-    *sizep = 0;
-    return 0;
-}
+static inline void reserve_ibft_region(void) {}
  #endif

  #endif /* ISCSI_IBFT_H */

Debug from the above:

[    0.020293] last_pfn = 0xbfedc max_arch_pfn = 0x400000000
[    0.050778] ACPI: Early table checksum verification disabled
[    0.056475] ACPI: RSDP 0x00000000BFBFA014 000024 (v02 BOCHS )
[    0.057628] ACPI: XSDT 0x00000000BFBF90E8 00004C (v01 BOCHS BXPCFACP 
00000001      01000013)
[    0.059341] ACPI: FACP 0x00000000BFBF5000 000074 (v01 BOCHS BXPCFACP 
00000001 BXPC 00000001)
[    0.061043] ACPI: DSDT 0x00000000BFBF6000 00238D (v01 BOCHS BXPCDSDT 
00000001 BXPC 00000001)
[    0.062740] ACPI: FACS 0x00000000BFBFD000 000040
[    0.063673] ACPI: APIC 0x00000000BFBF4000 000090 (v01 BOCHS BXPCAPIC 
00000001 BXPC 00000001)
[    0.065369] ACPI: HPET 0x00000000BFBF3000 000038 (v01 BOCHS BXPCHPET 
00000001 BXPC 00000001)
[    0.067061] ACPI: BGRT 0x00000000BE49B000 000038 (v01 INTEL EDK2     
00000002      01000013)
[    0.068761] ACPI: iBFT 0x00000000BE453000 000800 (v01 BOCHS BXPCFACP 
00000000      00000000)
[    0.070461] XXX reserve_ibft_region: table=ffffffffff240000, 
0x00000000BE453000, size=1000
[    0.072231] check: Scanning 1 areas for low memory corruption

George
  
quoted
[   30.308229] iBFT detected..
[   30.308796]
==================================================================
[   30.308890] BUG: KASAN: use-after-free in ibft_init+0x134/0xc33
[   30.308890] Read of size 4 at addr ffff8880be453004 by task swapper/0/1
[   30.308890]
[   30.308890] CPU: 1 PID: 1 Comm: swapper/0 Not tainted 5.11.0-f9593a0 #12
[   30.308890] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS
0.0.0 02/06/2015
[   30.308890] Call Trace:
[   30.308890]  dump_stack+0xdb/0x120
[   30.308890]  ? ibft_init+0x134/0xc33
[   30.308890]  print_address_description.constprop.7+0x41/0x60
[   30.308890]  ? ibft_init+0x134/0xc33
[   30.308890]  ? ibft_init+0x134/0xc33
[   30.308890]  kasan_report.cold.10+0x78/0xd1
[   30.308890]  ? ibft_init+0x134/0xc33
[   30.308890]  __asan_report_load_n_noabort+0xf/0x20
[   30.308890]  ibft_init+0x134/0xc33
[   30.308890]  ? write_comp_data+0x2f/0x90
[   30.308890]  ? ibft_check_initiator_for+0x159/0x159
[   30.308890]  ? write_comp_data+0x2f/0x90
[   30.308890]  ? ibft_check_initiator_for+0x159/0x159
[   30.308890]  do_one_initcall+0xc4/0x3e0
[   30.308890]  ? perf_trace_initcall_level+0x3e0/0x3e0
[   30.308890]  ? unpoison_range+0x14/0x40
[   30.308890]  ? ____kasan_kmalloc.constprop.5+0x8f/0xc0
[   30.308890]  ? kernel_init_freeable+0x420/0x652
[   30.308890]  ? __kasan_kmalloc+0x9/0x10
[   30.308890]  ? __sanitizer_cov_trace_pc+0x21/0x50
[   30.308890]  kernel_init_freeable+0x596/0x652
[   30.308890]  ? console_on_rootfs+0x7d/0x7d
[   30.308890]  ? __sanitizer_cov_trace_pc+0x21/0x50
[   30.308890]  ? rest_init+0xf0/0xf0
[   30.308890]  kernel_init+0x16/0x1d0
[   30.308890]  ? rest_init+0xf0/0xf0
[   30.308890]  ret_from_fork+0x22/0x30
[   30.308890]
[   30.308890] The buggy address belongs to the page:
[   30.308890] page:0000000001b7b17c refcount:0 mapcount:0
mapping:0000000000000000 index:0x1 pfn:0xbe453
[   30.308890] flags: 0xfffffc0000000()
[   30.308890] raw: 000fffffc0000000 ffffea0002ef9788 ffffea0002f91488
0000000000000000
[   30.308890] raw: 0000000000000001 0000000000000000 00000000ffffffff
0000000000000000
[   30.308890] page dumped because: kasan: bad access detected
[   30.308890] page_owner tracks the page as freed
[   30.308890] page last allocated via order 0, migratetype Movable,
gfp_mask 0x100dca(GFP_HIGHUSER_MOVABLE|__GFP_ZERO), pid 204, ts 28121288605
[   30.308890]  prep_new_page+0xfb/0x140
[   30.308890]  get_page_from_freelist+0x3503/0x5730
[   30.308890]  __alloc_pages_nodemask+0x2d8/0x650
[   30.308890]  alloc_pages_vma+0xe2/0x560
[   30.308890]  __handle_mm_fault+0x930/0x26c0
[   30.308890]  handle_mm_fault+0x1f9/0x810
[   30.308890]  do_user_addr_fault+0x6f7/0xca0
[   30.308890]  exc_page_fault+0xaf/0x1a0
[   30.308890]  asm_exc_page_fault+0x1e/0x30
[   30.308890] page last free stack trace:
[   30.308890]  free_pcp_prepare+0x122/0x290
[   30.308890]  free_unref_page_list+0xe6/0x490
[   30.308890]  release_pages+0x2ed/0x1270
[   30.308890]  free_pages_and_swap_cache+0x245/0x2e0
[   30.308890]  tlb_flush_mmu+0x11e/0x680
[   30.308890]  tlb_finish_mmu+0xa6/0x3e0
[   30.308890]  exit_mmap+0x2b3/0x540
[   30.308890]  mmput+0x11d/0x450
[   30.308890]  do_exit+0xaa6/0x2d40
[   30.308890]  do_group_exit+0x128/0x340
[   30.308890]  __x64_sys_exit_group+0x43/0x50
[   30.308890]  do_syscall_64+0x37/0x50
[   30.308890]  entry_SYSCALL_64_after_hwframe+0x44/0xa9
[   30.308890]
[   30.308890] Memory state around the buggy address:
[   30.308890]  ffff8880be452f00: ff ff ff ff ff ff ff ff ff ff ff ff ff ff
ff ff
[   30.308890]  ffff8880be452f80: ff ff ff ff ff ff ff ff ff ff ff ff ff ff
ff ff
[   30.308890] >ffff8880be453000: ff ff ff ff ff ff ff ff ff ff ff ff ff ff
ff ff
[   30.308890]                    ^
[   30.308890]  ffff8880be453080: ff ff ff ff ff ff ff ff ff ff ff ff ff ff
ff ff
[   30.308890]  ffff8880be453100: ff ff ff ff ff ff ff ff ff ff ff ff ff ff
ff ff
[   30.308890]
==================================================================

George

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

Re: [PATCH] mm, kasan: don't poison boot memory

From: Mike Rapoport <hidden>
Date: 2021-02-25 17:43:48

On Thu, Feb 25, 2021 at 06:23:24PM +0100, David Hildenbrand wrote:
On 25.02.21 17:31, George Kennedy wrote:
quoted
: rsdp_address=bfbfa014
[    0.066612] ACPI: RSDP 0x00000000BFBFA014 000024 (v02 BOCHS )
[    0.067759] ACPI: XSDT 0x00000000BFBF90E8 00004C (v01 BOCHS BXPCFACP
00000001      01000013)
[    0.069470] ACPI: FACP 0x00000000BFBF5000 000074 (v01 BOCHS BXPCFACP
00000001 BXPC 00000001)
[    0.071183] ACPI: DSDT 0x00000000BFBF6000 00238D (v01 BOCHS BXPCDSDT
00000001 BXPC 00000001)
[    0.072876] ACPI: FACS 0x00000000BFBFD000 000040
[    0.073806] ACPI: APIC 0x00000000BFBF4000 000090 (v01 BOCHS BXPCAPIC
00000001 BXPC 00000001)
[    0.075501] ACPI: HPET 0x00000000BFBF3000 000038 (v01 BOCHS BXPCHPET
00000001 BXPC 00000001)
[    0.077194] ACPI: BGRT 0x00000000BE49B000 000038 (v01 INTEL EDK2
00000002      01000013)
[    0.078880] ACPI: iBFT 0x00000000BE453000 000800 (v01 BOCHS BXPCFACP
00000000      00000000)

Can you explore the relevant area using the page-flags tools (located in
Linux src code located in tools/vm/page-flags.c)


./page-types -L -r -a 0xbe490,0xbe4a0
These are not iBFT and they are "ACPI data", so we should have them as
PG_Reserved set at init_unavailable_mem().


[    0.000000] BIOS-e820: [mem 0x0000000000808000-0x000000000080ffff] usable
[    0.000000] BIOS-e820: [mem 0x0000000000810000-0x00000000008fffff] ACPI NVS
[    0.000000] BIOS-e820: [mem 0x0000000000900000-0x00000000be49afff] usable

                               ^ iBFT@0xbe453 lives here ^ 

And it should be a normal page, as it's in "usable" memory and nothing
reserves it at boot, so no reason it won't be freed to buddy.

If iBFT was in the low memory (<1M) it would have been reserved by
reserve_ibft_region(), but with ACPI any block not marked by BIOS as "ACPI
something" is treated like a normal memory and there is nothing that
reserves it.

So we do need to memblock_reserve() iBFT region, but I still couldn't find
the right place to properly get its address without duplicating ACPI tables
parsing :(

[    0.000000] BIOS-e820: [mem 0x00000000be49b000-0x00000000be49bfff] ACPI data




-- 
Sincerely yours,
Mike.

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

Re: [PATCH] mm, kasan: don't poison boot memory

From: Mike Rapoport <hidden>
Date: 2021-02-25 17:55:19

On Thu, Feb 25, 2021 at 11:31:04AM -0500, George Kennedy wrote:

On 2/25/2021 11:07 AM, Mike Rapoport wrote:
quoted
On Thu, Feb 25, 2021 at 10:22:44AM -0500, George Kennedy wrote:
quoted
quoted
quoted
quoted
quoted
On 2/24/2021 5:37 AM, Mike Rapoport wrote:
Applied just your latest patch, but same failure.

I thought there was an earlier comment (which I can't find now) that stated
that memblock_reserve() wouldn't reserve the page, which is what's needed
here.
Actually, I think that memblock_reserve() should be just fine, but it seems
I'm missing something in address calculation each time.

What would happen if you stuck

	memblock_reserve(0xbe453000, PAGE_SIZE);

say, at the beginning of find_ibft_region()?
Added debug to your patch and this is all that shows up. Looks like the
patch is in the wrong place as acpi_tb_parse_root_table() is only called for
the RSDP address.
Right, but I think it parses table description of the other tables and
populates local tables with them.
I think the problem is with how I compare the signatures, please see below
quoted hunk
[    0.064317] ACPI: Early table checksum verification disabled
[    0.065437] XXX acpi_tb_parse_root_table: rsdp_address=bfbfa014
[    0.066612] ACPI: RSDP 0x00000000BFBFA014 000024 (v02 BOCHS )
[    0.067759] ACPI: XSDT 0x00000000BFBF90E8 00004C (v01 BOCHS BXPCFACP
00000001      01000013)
[    0.069470] ACPI: FACP 0x00000000BFBF5000 000074 (v01 BOCHS BXPCFACP
00000001 BXPC 00000001)
[    0.071183] ACPI: DSDT 0x00000000BFBF6000 00238D (v01 BOCHS BXPCDSDT
00000001 BXPC 00000001)
[    0.072876] ACPI: FACS 0x00000000BFBFD000 000040
[    0.073806] ACPI: APIC 0x00000000BFBF4000 000090 (v01 BOCHS BXPCAPIC
00000001 BXPC 00000001)
[    0.075501] ACPI: HPET 0x00000000BFBF3000 000038 (v01 BOCHS BXPCHPET
00000001 BXPC 00000001)
[    0.077194] ACPI: BGRT 0x00000000BE49B000 000038 (v01 INTEL EDK2    
00000002      01000013)
[    0.078880] ACPI: iBFT 0x00000000BE453000 000800 (v01 BOCHS BXPCFACP
00000000      00000000)
[    0.080588] ACPI: Local APIC address 0xfee00000
diff --git a/drivers/acpi/acpica/tbutils.c b/drivers/acpi/acpica/tbutils.c
index dfe1ac3..603b3a8 100644
--- a/drivers/acpi/acpica/tbutils.c
+++ b/drivers/acpi/acpica/tbutils.c
@@ -7,6 +7,8 @@
  *
*****************************************************************************/

+#include <linux/memblock.h>
+
 #include <acpi/acpi.h>
 #include "accommon.h"
 #include "actables.h"
@@ -232,6 +234,8 @@ struct acpi_table_header *acpi_tb_copy_dsdt(u32
table_index)
     acpi_status status;
     u32 table_index;

+printk(KERN_ERR "XXX acpi_tb_parse_root_table: rsdp_address=%llx\n",
rsdp_address);
+
     ACPI_FUNCTION_TRACE(tb_parse_root_table);

     /* Map the entire RSDP and extract the address of the RSDT or XSDT */
@@ -339,6 +343,22 @@ struct acpi_table_header *acpi_tb_copy_dsdt(u32
table_index)
             acpi_tb_parse_fadt();
         }

+        if (ACPI_SUCCESS(status) &&
+            ACPI_COMPARE_NAMESEG(&acpi_gbl_root_table_list.
+                     tables[table_index].signature,
+                     ACPI_SIG_IBFT)) {
We have:

include/acpi/actbl1.h:#define ACPI_SIG_IBFT           "IBFT"    /* iSCSI Boot Firmware Table */

and the BIOS uses "iBFT", so we need to loop over possible signature
variants like iscsi_ibft_find does.

Do you mind replacing ACPI_SIG_IBFT with "iBFT" and try again?
+            struct acpi_table_header *ibft;
+            struct acpi_table_desc *desc;
+
+            desc = &acpi_gbl_root_table_list.tables[table_index];
+            status = acpi_tb_get_table(desc, &ibft);
+            if (ACPI_SUCCESS(status)) {
+printk(KERN_ERR "XXX acpi_tb_parse_root_table(calling memblock_reserve()):
addres=%llx, ibft->length=%x\n", address, ibft->length);
+                memblock_reserve(address, ibft->length);
+                acpi_tb_put_table(desc);
+            }
+        }
+
 next_table:

         table_entry += table_entry_size;

quoted
quoted
[   30.308229] iBFT detected..
[   30.308796]
==================================================================
[   30.308890] BUG: KASAN: use-after-free in ibft_init+0x134/0xc33
[   30.308890] Read of size 4 at addr ffff8880be453004 by task swapper/0/1
[   30.308890]
[   30.308890] CPU: 1 PID: 1 Comm: swapper/0 Not tainted 5.11.0-f9593a0 #12
[   30.308890] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS
0.0.0 02/06/2015
[   30.308890] Call Trace:
[   30.308890]  dump_stack+0xdb/0x120
[   30.308890]  ? ibft_init+0x134/0xc33
[   30.308890]  print_address_description.constprop.7+0x41/0x60
[   30.308890]  ? ibft_init+0x134/0xc33
[   30.308890]  ? ibft_init+0x134/0xc33
[   30.308890]  kasan_report.cold.10+0x78/0xd1
[   30.308890]  ? ibft_init+0x134/0xc33
[   30.308890]  __asan_report_load_n_noabort+0xf/0x20
[   30.308890]  ibft_init+0x134/0xc33
[   30.308890]  ? write_comp_data+0x2f/0x90
[   30.308890]  ? ibft_check_initiator_for+0x159/0x159
[   30.308890]  ? write_comp_data+0x2f/0x90
[   30.308890]  ? ibft_check_initiator_for+0x159/0x159
[   30.308890]  do_one_initcall+0xc4/0x3e0
[   30.308890]  ? perf_trace_initcall_level+0x3e0/0x3e0
[   30.308890]  ? unpoison_range+0x14/0x40
[   30.308890]  ? ____kasan_kmalloc.constprop.5+0x8f/0xc0
[   30.308890]  ? kernel_init_freeable+0x420/0x652
[   30.308890]  ? __kasan_kmalloc+0x9/0x10
[   30.308890]  ? __sanitizer_cov_trace_pc+0x21/0x50
[   30.308890]  kernel_init_freeable+0x596/0x652
[   30.308890]  ? console_on_rootfs+0x7d/0x7d
[   30.308890]  ? __sanitizer_cov_trace_pc+0x21/0x50
[   30.308890]  ? rest_init+0xf0/0xf0
[   30.308890]  kernel_init+0x16/0x1d0
[   30.308890]  ? rest_init+0xf0/0xf0
[   30.308890]  ret_from_fork+0x22/0x30
[   30.308890]
[   30.308890] The buggy address belongs to the page:
[   30.308890] page:0000000001b7b17c refcount:0 mapcount:0
mapping:0000000000000000 index:0x1 pfn:0xbe453
[   30.308890] flags: 0xfffffc0000000()
[   30.308890] raw: 000fffffc0000000 ffffea0002ef9788 ffffea0002f91488
0000000000000000
[   30.308890] raw: 0000000000000001 0000000000000000 00000000ffffffff
0000000000000000
[   30.308890] page dumped because: kasan: bad access detected
[   30.308890] page_owner tracks the page as freed
[   30.308890] page last allocated via order 0, migratetype Movable,
gfp_mask 0x100dca(GFP_HIGHUSER_MOVABLE|__GFP_ZERO), pid 204, ts 28121288605
[   30.308890]  prep_new_page+0xfb/0x140
[   30.308890]  get_page_from_freelist+0x3503/0x5730
[   30.308890]  __alloc_pages_nodemask+0x2d8/0x650
[   30.308890]  alloc_pages_vma+0xe2/0x560
[   30.308890]  __handle_mm_fault+0x930/0x26c0
[   30.308890]  handle_mm_fault+0x1f9/0x810
[   30.308890]  do_user_addr_fault+0x6f7/0xca0
[   30.308890]  exc_page_fault+0xaf/0x1a0
[   30.308890]  asm_exc_page_fault+0x1e/0x30
[   30.308890] page last free stack trace:
[   30.308890]  free_pcp_prepare+0x122/0x290
[   30.308890]  free_unref_page_list+0xe6/0x490
[   30.308890]  release_pages+0x2ed/0x1270
[   30.308890]  free_pages_and_swap_cache+0x245/0x2e0
[   30.308890]  tlb_flush_mmu+0x11e/0x680
[   30.308890]  tlb_finish_mmu+0xa6/0x3e0
[   30.308890]  exit_mmap+0x2b3/0x540
[   30.308890]  mmput+0x11d/0x450
[   30.308890]  do_exit+0xaa6/0x2d40
[   30.308890]  do_group_exit+0x128/0x340
[   30.308890]  __x64_sys_exit_group+0x43/0x50
[   30.308890]  do_syscall_64+0x37/0x50
[   30.308890]  entry_SYSCALL_64_after_hwframe+0x44/0xa9
[   30.308890]
[   30.308890] Memory state around the buggy address:
[   30.308890]  ffff8880be452f00: ff ff ff ff ff ff ff ff ff ff ff ff ff ff
ff ff
[   30.308890]  ffff8880be452f80: ff ff ff ff ff ff ff ff ff ff ff ff ff ff
ff ff
[   30.308890] >ffff8880be453000: ff ff ff ff ff ff ff ff ff ff ff ff ff ff
ff ff
[   30.308890]                    ^
[   30.308890]  ffff8880be453080: ff ff ff ff ff ff ff ff ff ff ff ff ff ff
ff ff
[   30.308890]  ffff8880be453100: ff ff ff ff ff ff ff ff ff ff ff ff ff ff
ff ff
[   30.308890]
==================================================================

George
-- 
Sincerely yours,
Mike.

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

Re: [PATCH] mm, kasan: don't poison boot memory

From: George Kennedy <hidden>
Date: 2021-02-26 01:22:34


On 2/25/2021 12:33 PM, George Kennedy wrote:
quoted hunk

On 2/25/2021 11:07 AM, Mike Rapoport wrote:
quoted
On Thu, Feb 25, 2021 at 10:22:44AM -0500, George Kennedy wrote:
quoted
quoted
quoted
quoted
quoted
On 2/24/2021 5:37 AM, Mike Rapoport wrote:
Applied just your latest patch, but same failure.

I thought there was an earlier comment (which I can't find now) that 
stated
that memblock_reserve() wouldn't reserve the page, which is what's 
needed
here.
Actually, I think that memblock_reserve() should be just fine, but it 
seems
I'm missing something in address calculation each time.

What would happen if you stuck

    memblock_reserve(0xbe453000, PAGE_SIZE);

say, at the beginning of find_ibft_region()?
Good news Mike!

The above hack in yesterday's last patch works - 10 successful 
reboots. See: "BE453" below for the hack.

I'll modify the patch to use "table_desc->address" instead, which is 
the physical address of the table.
diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c
index 7bdc023..c118dd5 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 740f3bdb..b045ab2 100644
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -571,16 +571,6 @@ void __init reserve_standard_io_resources(void)
 }

-static __init void reserve_ibft_region(void)
-{
-    unsigned long addr, size = 0;
-
-    addr = find_ibft_region(&size);
-
-    if (size)
-        memblock_reserve(addr, size);
-}
-
 static bool __init snb_gfx_workaround_needed(void)
 {
 #ifdef CONFIG_PCI
@@ -1033,6 +1023,12 @@ void __init setup_arch(char **cmdline_p)
      */
     find_smp_config();

+    /*
+     * Initialize the ACPI boot-time table parser.
+     */
+    if (acpi_table_init())
+        disable_acpi();
+
     reserve_ibft_region();

     early_alloc_pgt_buf();
diff --git a/drivers/firmware/iscsi_ibft_find.c 
b/drivers/firmware/iscsi_ibft_find.c
index 64bb945..95fc1a6 100644
--- a/drivers/firmware/iscsi_ibft_find.c
+++ b/drivers/firmware/iscsi_ibft_find.c
@@ -47,7 +47,25 @@
 #define VGA_MEM 0xA0000 /* VGA buffer */
 #define VGA_SIZE 0x20000 /* 128kB */

-static int __init find_ibft_in_mem(void)
+static void __init *acpi_find_ibft_region(void)
+{
+    int i;
+    struct acpi_table_header *table = NULL;
+    acpi_status status;
+
+    if (acpi_disabled)
+        return NULL;
+
+    for (i = 0; i < ARRAY_SIZE(ibft_signs) && !ibft_addr; i++) {
+        status = acpi_get_table(ibft_signs[i].sign, 0, &table);
+        if (ACPI_SUCCESS(status))
+            return table;
+    }
+
+    return NULL;
+}
+
+static void __init *find_ibft_in_mem(void)
 {
     unsigned long pos;
     unsigned int len = 0;
@@ -70,35 +88,52 @@ static int __init find_ibft_in_mem(void)
                 /* if the length of the table extends past 1M,
                  * the table cannot be valid. */
                 if (pos + len <= (IBFT_END-1)) {
-                    ibft_addr = (struct acpi_table_ibft *)virt;
                     pr_info("iBFT found at 0x%lx.\n", pos);
-                    goto done;
+                    return virt;
                 }
             }
         }
     }
-done:
-    return len;
+
+    return NULL;
 }
+
+static void __init *find_ibft(void)
+{
+    /* iBFT 1.03 section 1.4.3.1 mandates that UEFI machines will
+     * only use ACPI for this */
+    if (!efi_enabled(EFI_BOOT))
+        return find_ibft_in_mem();
+    else
+        return acpi_find_ibft_region();
+}
+
 /*
  * Routine used to find the iSCSI Boot Format Table. The logical
  * kernel address is set in the ibft_addr global variable.
  */
-unsigned long __init find_ibft_region(unsigned long *sizep)
+void __init reserve_ibft_region(void)
 {
-    ibft_addr = NULL;
+    struct acpi_table_ibft *table;
+    unsigned long size;

-    /* iBFT 1.03 section 1.4.3.1 mandates that UEFI machines will
-     * only use ACPI for this */
+    table = find_ibft();
+    if (!table)
+        return;

-    if (!efi_enabled(EFI_BOOT))
-        find_ibft_in_mem();
-
-    if (ibft_addr) {
-        *sizep = PAGE_ALIGN(ibft_addr->header.length);
-        return (u64)virt_to_phys(ibft_addr);
-    }
+    size = PAGE_ALIGN(table->header.length);
+#if 0
+printk(KERN_ERR "XXX reserve_ibft_region: table=%llx, 
virt_to_phys(table)=%llx, size=%lx\n",
+    (u64)table, virt_to_phys(table), size);
+    memblock_reserve(virt_to_phys(table), size);
+#else
+printk(KERN_ERR "XXX reserve_ibft_region: table=%llx, 
0x00000000BE453000, size=%lx\n",
+    (u64)table, size);
+    memblock_reserve(0x00000000BE453000, size);
+#endif

-    *sizep = 0;
-    return 0;
+    if (efi_enabled(EFI_BOOT))
+        acpi_put_table(&table->header);
+    else
+        ibft_addr = table;
 }
diff --git a/include/linux/iscsi_ibft.h b/include/linux/iscsi_ibft.h
index b7b45ca..da813c8 100644
--- a/include/linux/iscsi_ibft.h
+++ b/include/linux/iscsi_ibft.h
@@ -26,13 +26,9 @@
  * mapped address is set in the ibft_addr variable.
  */
 #ifdef CONFIG_ISCSI_IBFT_FIND
-unsigned long find_ibft_region(unsigned long *sizep);
+void reserve_ibft_region(void);
 #else
-static inline unsigned long find_ibft_region(unsigned long *sizep)
-{
-    *sizep = 0;
-    return 0;
-}
+static inline void reserve_ibft_region(void) {}
 #endif

 #endif /* ISCSI_IBFT_H */
Mike,

To get rid of the 0x00000000BE453000 hardcoding, I added the following 
patch to your above patch to get the iBFT table "address" to use with 
memblock_reserve():
diff --git a/drivers/acpi/acpica/tbfind.c b/drivers/acpi/acpica/tbfind.c
index 56d81e4..4bc7bf3 100644
--- a/drivers/acpi/acpica/tbfind.c
+++ b/drivers/acpi/acpica/tbfind.c
@@ -120,3 +120,34 @@
      (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
      return_ACPI_STATUS(status);
  }
+
+acpi_physical_address
+acpi_tb_find_table_address(char *signature)
+{
+    acpi_physical_address address = 0;
+    struct acpi_table_desc *table_desc;
+    int i;
+
+    ACPI_FUNCTION_TRACE(tb_find_table_address);
+
+printk(KERN_ERR "XXX acpi_tb_find_table_address: signature=%s\n", 
signature);
+
+    (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
+    for (i = 0; i < acpi_gbl_root_table_list.current_table_count; ++i) {
+        if (memcmp(&(acpi_gbl_root_table_list.tables[i].signature),
+               signature, ACPI_NAMESEG_SIZE)) {
+
+            /* Not the requested table */
+
+            continue;
+        }
+
+        /* Table with matching signature has been found */
+        table_desc = &acpi_gbl_root_table_list.tables[i];
+        address = table_desc->address;
+    }
+
+    (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
+printk(KERN_ERR "XXX acpi_tb_find_table_address(EXIT): address=%llx\n", 
address);
+    return address;
+}
diff --git a/drivers/firmware/iscsi_ibft_find.c 
b/drivers/firmware/iscsi_ibft_find.c
index 95fc1a6..0de70b4 100644
--- a/drivers/firmware/iscsi_ibft_find.c
+++ b/drivers/firmware/iscsi_ibft_find.c
@@ -28,6 +28,8 @@

  #include <asm/mmzone.h>

+extern acpi_physical_address acpi_tb_find_table_address(char *signature);
+
  /*
   * Physical location of iSCSI Boot Format Table.
   */
@@ -116,24 +118,32 @@ void __init reserve_ibft_region(void)
  {
      struct acpi_table_ibft *table;
      unsigned long size;
+    acpi_physical_address address;

      table = find_ibft();
      if (!table)
          return;

      size = PAGE_ALIGN(table->header.length);
+    address = acpi_tb_find_table_address(table->header.signature);
  #if 0
  printk(KERN_ERR "XXX reserve_ibft_region: table=%llx, 
virt_to_phys(table)=%llx, size=%lx\n",
      (u64)table, virt_to_phys(table), size);
      memblock_reserve(virt_to_phys(table), size);
  #else
-printk(KERN_ERR "XXX reserve_ibft_region: table=%llx, 
0x00000000BE453000, size=%lx\n",
-    (u64)table, size);
-    memblock_reserve(0x00000000BE453000, size);
+printk(KERN_ERR "XXX reserve_ibft_region: table=%llx, address=%llx, 
size=%lx\n",
+    (u64)table, address, size);
+    if (address)
+        memblock_reserve(address, size);
+    else
+        printk(KERN_ERR "%s: Can't find table address\n", __func__);
  #endif

-    if (efi_enabled(EFI_BOOT))
+    if (efi_enabled(EFI_BOOT)) {
+printk(KERN_ERR "XXX reserve_ibft_region: calling 
acpi_put_table(%llx)\n", (u64)&table->header);
          acpi_put_table(&table->header);
-    else
+    } else {
          ibft_addr = table;
+printk(KERN_ERR "XXX reserve_ibft_region: ibft_addr=%llx\n", 
(u64)ibft_addr);
+    }
  }

Debug from the above:
[    0.050646] ACPI: Early table checksum verification disabled
[    0.051778] ACPI: RSDP 0x00000000BFBFA014 000024 (v02 BOCHS )
[    0.052922] ACPI: XSDT 0x00000000BFBF90E8 00004C (v01 BOCHS BXPCFACP 
00000001      01000013)
[    0.054623] ACPI: FACP 0x00000000BFBF5000 000074 (v01 BOCHS BXPCFACP 
00000001 BXPC 00000001)
[    0.056326] ACPI: DSDT 0x00000000BFBF6000 00238D (v01 BOCHS BXPCDSDT 
00000001 BXPC 00000001)
[    0.058016] ACPI: FACS 0x00000000BFBFD000 000040
[    0.058940] ACPI: APIC 0x00000000BFBF4000 000090 (v01 BOCHS BXPCAPIC 
00000001 BXPC 00000001)
[    0.060627] ACPI: HPET 0x00000000BFBF3000 000038 (v01 BOCHS BXPCHPET 
00000001 BXPC 00000001)
[    0.062304] ACPI: BGRT 0x00000000BE49B000 000038 (v01 INTEL EDK2     
00000002      01000013)
[    0.063987] ACPI: iBFT 0x00000000BE453000 000800 (v01 BOCHS BXPCFACP 
00000000      00000000)
[    0.065683] XXX acpi_tb_find_table_address: signature=iBFT
[    0.066754] XXX acpi_tb_find_table_address(EXIT): address=be453000
[    0.067959] XXX reserve_ibft_region: table=ffffffffff240000, 
address=be453000, size=1000
[    0.069534] XXX reserve_ibft_region: calling 
acpi_put_table(ffffffffff240000)

Not sure if it's the right thing to do, but added 
"acpi_tb_find_table_address()" to return the physical address of a table 
to use with memblock_reserve().

virt_to_phys(table) does not seem to return the physical address for the 
iBFT table (it would be nice if struct acpi_table_header also had a 
"address" element for the physical address of the table).

Ran 10 successful boots with the above without failure.

George

Debug from the above:

[    0.020293] last_pfn = 0xbfedc max_arch_pfn = 0x400000000
[    0.050778] ACPI: Early table checksum verification disabled
[    0.056475] ACPI: RSDP 0x00000000BFBFA014 000024 (v02 BOCHS )
[    0.057628] ACPI: XSDT 0x00000000BFBF90E8 00004C (v01 BOCHS 
BXPCFACP 00000001      01000013)
[    0.059341] ACPI: FACP 0x00000000BFBF5000 000074 (v01 BOCHS 
BXPCFACP 00000001 BXPC 00000001)
[    0.061043] ACPI: DSDT 0x00000000BFBF6000 00238D (v01 BOCHS 
BXPCDSDT 00000001 BXPC 00000001)
[    0.062740] ACPI: FACS 0x00000000BFBFD000 000040
[    0.063673] ACPI: APIC 0x00000000BFBF4000 000090 (v01 BOCHS 
BXPCAPIC 00000001 BXPC 00000001)
[    0.065369] ACPI: HPET 0x00000000BFBF3000 000038 (v01 BOCHS 
BXPCHPET 00000001 BXPC 00000001)
[    0.067061] ACPI: BGRT 0x00000000BE49B000 000038 (v01 INTEL 
EDK2     00000002      01000013)
[    0.068761] ACPI: iBFT 0x00000000BE453000 000800 (v01 BOCHS 
BXPCFACP 00000000      00000000)
[    0.070461] XXX reserve_ibft_region: table=ffffffffff240000, 
0x00000000BE453000, size=1000
[    0.072231] check: Scanning 1 areas for low memory corruption

George
quoted
quoted
[   30.308229] iBFT detected..
[   30.308796]
==================================================================
[   30.308890] BUG: KASAN: use-after-free in ibft_init+0x134/0xc33
[   30.308890] Read of size 4 at addr ffff8880be453004 by task 
swapper/0/1
[   30.308890]
[   30.308890] CPU: 1 PID: 1 Comm: swapper/0 Not tainted 
5.11.0-f9593a0 #12
[   30.308890] Hardware name: QEMU Standard PC (i440FX + PIIX, 
1996), BIOS
0.0.0 02/06/2015
[   30.308890] Call Trace:
[   30.308890]  dump_stack+0xdb/0x120
[   30.308890]  ? ibft_init+0x134/0xc33
[   30.308890] print_address_description.constprop.7+0x41/0x60
[   30.308890]  ? ibft_init+0x134/0xc33
[   30.308890]  ? ibft_init+0x134/0xc33
[   30.308890]  kasan_report.cold.10+0x78/0xd1
[   30.308890]  ? ibft_init+0x134/0xc33
[   30.308890]  __asan_report_load_n_noabort+0xf/0x20
[   30.308890]  ibft_init+0x134/0xc33
[   30.308890]  ? write_comp_data+0x2f/0x90
[   30.308890]  ? ibft_check_initiator_for+0x159/0x159
[   30.308890]  ? write_comp_data+0x2f/0x90
[   30.308890]  ? ibft_check_initiator_for+0x159/0x159
[   30.308890]  do_one_initcall+0xc4/0x3e0
[   30.308890]  ? perf_trace_initcall_level+0x3e0/0x3e0
[   30.308890]  ? unpoison_range+0x14/0x40
[   30.308890]  ? ____kasan_kmalloc.constprop.5+0x8f/0xc0
[   30.308890]  ? kernel_init_freeable+0x420/0x652
[   30.308890]  ? __kasan_kmalloc+0x9/0x10
[   30.308890]  ? __sanitizer_cov_trace_pc+0x21/0x50
[   30.308890]  kernel_init_freeable+0x596/0x652
[   30.308890]  ? console_on_rootfs+0x7d/0x7d
[   30.308890]  ? __sanitizer_cov_trace_pc+0x21/0x50
[   30.308890]  ? rest_init+0xf0/0xf0
[   30.308890]  kernel_init+0x16/0x1d0
[   30.308890]  ? rest_init+0xf0/0xf0
[   30.308890]  ret_from_fork+0x22/0x30
[   30.308890]
[   30.308890] The buggy address belongs to the page:
[   30.308890] page:0000000001b7b17c refcount:0 mapcount:0
mapping:0000000000000000 index:0x1 pfn:0xbe453
[   30.308890] flags: 0xfffffc0000000()
[   30.308890] raw: 000fffffc0000000 ffffea0002ef9788 ffffea0002f91488
0000000000000000
[   30.308890] raw: 0000000000000001 0000000000000000 00000000ffffffff
0000000000000000
[   30.308890] page dumped because: kasan: bad access detected
[   30.308890] page_owner tracks the page as freed
[   30.308890] page last allocated via order 0, migratetype Movable,
gfp_mask 0x100dca(GFP_HIGHUSER_MOVABLE|__GFP_ZERO), pid 204, ts 
28121288605
[   30.308890]  prep_new_page+0xfb/0x140
[   30.308890]  get_page_from_freelist+0x3503/0x5730
[   30.308890]  __alloc_pages_nodemask+0x2d8/0x650
[   30.308890]  alloc_pages_vma+0xe2/0x560
[   30.308890]  __handle_mm_fault+0x930/0x26c0
[   30.308890]  handle_mm_fault+0x1f9/0x810
[   30.308890]  do_user_addr_fault+0x6f7/0xca0
[   30.308890]  exc_page_fault+0xaf/0x1a0
[   30.308890]  asm_exc_page_fault+0x1e/0x30
[   30.308890] page last free stack trace:
[   30.308890]  free_pcp_prepare+0x122/0x290
[   30.308890]  free_unref_page_list+0xe6/0x490
[   30.308890]  release_pages+0x2ed/0x1270
[   30.308890]  free_pages_and_swap_cache+0x245/0x2e0
[   30.308890]  tlb_flush_mmu+0x11e/0x680
[   30.308890]  tlb_finish_mmu+0xa6/0x3e0
[   30.308890]  exit_mmap+0x2b3/0x540
[   30.308890]  mmput+0x11d/0x450
[   30.308890]  do_exit+0xaa6/0x2d40
[   30.308890]  do_group_exit+0x128/0x340
[   30.308890]  __x64_sys_exit_group+0x43/0x50
[   30.308890]  do_syscall_64+0x37/0x50
[   30.308890]  entry_SYSCALL_64_after_hwframe+0x44/0xa9
[   30.308890]
[   30.308890] Memory state around the buggy address:
[   30.308890]  ffff8880be452f00: ff ff ff ff ff ff ff ff ff ff ff 
ff ff ff
ff ff
[   30.308890]  ffff8880be452f80: ff ff ff ff ff ff ff ff ff ff ff 
ff ff ff
ff ff
[   30.308890] >ffff8880be453000: ff ff ff ff ff ff ff ff ff ff ff 
ff ff ff
ff ff
[   30.308890]                    ^
[   30.308890]  ffff8880be453080: ff ff ff ff ff ff ff ff ff ff ff 
ff ff ff
ff ff
[   30.308890]  ffff8880be453100: ff ff ff ff ff ff ff ff ff ff ff 
ff ff ff
ff ff
[   30.308890]
==================================================================

George

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

Re: [PATCH] mm, kasan: don't poison boot memory

From: Mike Rapoport <hidden>
Date: 2021-02-26 11:18:55

Hi George,

On Thu, Feb 25, 2021 at 08:19:18PM -0500, George Kennedy wrote:
quoted hunk
Mike,

To get rid of the 0x00000000BE453000 hardcoding, I added the following patch
to your above patch to get the iBFT table "address" to use with
memblock_reserve():
diff --git a/drivers/acpi/acpica/tbfind.c b/drivers/acpi/acpica/tbfind.c
index 56d81e4..4bc7bf3 100644
--- a/drivers/acpi/acpica/tbfind.c
+++ b/drivers/acpi/acpica/tbfind.c
@@ -120,3 +120,34 @@
     (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
     return_ACPI_STATUS(status);
 }
+
+acpi_physical_address
+acpi_tb_find_table_address(char *signature)
+{
+    acpi_physical_address address = 0;
+    struct acpi_table_desc *table_desc;
+    int i;
+
+    ACPI_FUNCTION_TRACE(tb_find_table_address);
+
+printk(KERN_ERR "XXX acpi_tb_find_table_address: signature=%s\n",
signature);
+
+    (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
+    for (i = 0; i < acpi_gbl_root_table_list.current_table_count; ++i) {
+        if (memcmp(&(acpi_gbl_root_table_list.tables[i].signature),
+               signature, ACPI_NAMESEG_SIZE)) {
+
+            /* Not the requested table */
+
+            continue;
+        }
+
+        /* Table with matching signature has been found */
+        table_desc = &acpi_gbl_root_table_list.tables[i];
+        address = table_desc->address;
+    }
+
+    (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
+printk(KERN_ERR "XXX acpi_tb_find_table_address(EXIT): address=%llx\n",
address);
+    return address;
+}
diff --git a/drivers/firmware/iscsi_ibft_find.c
b/drivers/firmware/iscsi_ibft_find.c
index 95fc1a6..0de70b4 100644
--- a/drivers/firmware/iscsi_ibft_find.c
+++ b/drivers/firmware/iscsi_ibft_find.c
@@ -28,6 +28,8 @@
 #include <asm/mmzone.h>

+extern acpi_physical_address acpi_tb_find_table_address(char *signature);
+
 /*
  * Physical location of iSCSI Boot Format Table.
  */
@@ -116,24 +118,32 @@ void __init reserve_ibft_region(void)
 {
     struct acpi_table_ibft *table;
     unsigned long size;
+    acpi_physical_address address;

     table = find_ibft();
     if (!table)
         return;

     size = PAGE_ALIGN(table->header.length);
+    address = acpi_tb_find_table_address(table->header.signature);
 #if 0
 printk(KERN_ERR "XXX reserve_ibft_region: table=%llx,
virt_to_phys(table)=%llx, size=%lx\n",
     (u64)table, virt_to_phys(table), size);
     memblock_reserve(virt_to_phys(table), size);
 #else
-printk(KERN_ERR "XXX reserve_ibft_region: table=%llx, 0x00000000BE453000,
size=%lx\n",
-    (u64)table, size);
-    memblock_reserve(0x00000000BE453000, size);
+printk(KERN_ERR "XXX reserve_ibft_region: table=%llx, address=%llx,
size=%lx\n",
+    (u64)table, address, size);
+    if (address)
+        memblock_reserve(address, size);
+    else
+        printk(KERN_ERR "%s: Can't find table address\n", __func__);
 #endif

-    if (efi_enabled(EFI_BOOT))
+    if (efi_enabled(EFI_BOOT)) {
+printk(KERN_ERR "XXX reserve_ibft_region: calling acpi_put_table(%llx)\n",
(u64)&table->header);
         acpi_put_table(&table->header);
-    else
+    } else {
         ibft_addr = table;
+printk(KERN_ERR "XXX reserve_ibft_region: ibft_addr=%llx\n",
(u64)ibft_addr);
+    }
 }

Debug from the above:
[    0.050646] ACPI: Early table checksum verification disabled
[    0.051778] ACPI: RSDP 0x00000000BFBFA014 000024 (v02 BOCHS )
[    0.052922] ACPI: XSDT 0x00000000BFBF90E8 00004C (v01 BOCHS BXPCFACP
00000001      01000013)
[    0.054623] ACPI: FACP 0x00000000BFBF5000 000074 (v01 BOCHS BXPCFACP
00000001 BXPC 00000001)
[    0.056326] ACPI: DSDT 0x00000000BFBF6000 00238D (v01 BOCHS BXPCDSDT
00000001 BXPC 00000001)
[    0.058016] ACPI: FACS 0x00000000BFBFD000 000040
[    0.058940] ACPI: APIC 0x00000000BFBF4000 000090 (v01 BOCHS BXPCAPIC
00000001 BXPC 00000001)
[    0.060627] ACPI: HPET 0x00000000BFBF3000 000038 (v01 BOCHS BXPCHPET
00000001 BXPC 00000001)
[    0.062304] ACPI: BGRT 0x00000000BE49B000 000038 (v01 INTEL EDK2    
00000002      01000013)
[    0.063987] ACPI: iBFT 0x00000000BE453000 000800 (v01 BOCHS BXPCFACP
00000000      00000000)
[    0.065683] XXX acpi_tb_find_table_address: signature=iBFT
[    0.066754] XXX acpi_tb_find_table_address(EXIT): address=be453000
[    0.067959] XXX reserve_ibft_region: table=ffffffffff240000,
address=be453000, size=1000
[    0.069534] XXX reserve_ibft_region: calling
acpi_put_table(ffffffffff240000)

Not sure if it's the right thing to do, but added
"acpi_tb_find_table_address()" to return the physical address of a table to
use with memblock_reserve().

virt_to_phys(table) does not seem to return the physical address for the
iBFT table (it would be nice if struct acpi_table_header also had a
"address" element for the physical address of the table).
virt_to_phys() does not work that early because then it is mapped with
early_memremap()  which uses different virtual to physical scheme.

I'd say that acpi_tb_find_table_address() makes sense if we'd like to
reserve ACPI tables outside of drivers/acpi. 

But probably we should simply reserve all the tables during
acpi_table_init() so that any table that firmware put in the normal memory
will be surely reserved.
 
Ran 10 successful boots with the above without failure.
That's good news indeed :)
George
quoted
-- 
Sincerely yours,
Mike.

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

Re: [PATCH] mm, kasan: don't poison boot memory

From: George Kennedy <hidden>
Date: 2021-02-26 16:18:25

Hi Mike,

On 2/26/2021 6:17 AM, Mike Rapoport wrote:
Hi George,

On Thu, Feb 25, 2021 at 08:19:18PM -0500, George Kennedy wrote:
quoted
Mike,

To get rid of the 0x00000000BE453000 hardcoding, I added the following patch
to your above patch to get the iBFT table "address" to use with
memblock_reserve():
diff --git a/drivers/acpi/acpica/tbfind.c b/drivers/acpi/acpica/tbfind.c
index 56d81e4..4bc7bf3 100644
--- a/drivers/acpi/acpica/tbfind.c
+++ b/drivers/acpi/acpica/tbfind.c
@@ -120,3 +120,34 @@
      (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
      return_ACPI_STATUS(status);
  }
+
+acpi_physical_address
+acpi_tb_find_table_address(char *signature)
+{
+    acpi_physical_address address = 0;
+    struct acpi_table_desc *table_desc;
+    int i;
+
+    ACPI_FUNCTION_TRACE(tb_find_table_address);
+
+printk(KERN_ERR "XXX acpi_tb_find_table_address: signature=%s\n",
signature);
+
+    (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
+    for (i = 0; i < acpi_gbl_root_table_list.current_table_count; ++i) {
+        if (memcmp(&(acpi_gbl_root_table_list.tables[i].signature),
+               signature, ACPI_NAMESEG_SIZE)) {
+
+            /* Not the requested table */
+
+            continue;
+        }
+
+        /* Table with matching signature has been found */
+        table_desc = &acpi_gbl_root_table_list.tables[i];
+        address = table_desc->address;
+    }
+
+    (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
+printk(KERN_ERR "XXX acpi_tb_find_table_address(EXIT): address=%llx\n",
address);
+    return address;
+}
diff --git a/drivers/firmware/iscsi_ibft_find.c
b/drivers/firmware/iscsi_ibft_find.c
index 95fc1a6..0de70b4 100644
--- a/drivers/firmware/iscsi_ibft_find.c
+++ b/drivers/firmware/iscsi_ibft_find.c
@@ -28,6 +28,8 @@

  #include <asm/mmzone.h>

+extern acpi_physical_address acpi_tb_find_table_address(char *signature);
+
  /*
   * Physical location of iSCSI Boot Format Table.
   */
@@ -116,24 +118,32 @@ void __init reserve_ibft_region(void)
  {
      struct acpi_table_ibft *table;
      unsigned long size;
+    acpi_physical_address address;

      table = find_ibft();
      if (!table)
          return;

      size = PAGE_ALIGN(table->header.length);
+    address = acpi_tb_find_table_address(table->header.signature);
  #if 0
  printk(KERN_ERR "XXX reserve_ibft_region: table=%llx,
virt_to_phys(table)=%llx, size=%lx\n",
      (u64)table, virt_to_phys(table), size);
      memblock_reserve(virt_to_phys(table), size);
  #else
-printk(KERN_ERR "XXX reserve_ibft_region: table=%llx, 0x00000000BE453000,
size=%lx\n",
-    (u64)table, size);
-    memblock_reserve(0x00000000BE453000, size);
+printk(KERN_ERR "XXX reserve_ibft_region: table=%llx, address=%llx,
size=%lx\n",
+    (u64)table, address, size);
+    if (address)
+        memblock_reserve(address, size);
+    else
+        printk(KERN_ERR "%s: Can't find table address\n", __func__);
  #endif

-    if (efi_enabled(EFI_BOOT))
+    if (efi_enabled(EFI_BOOT)) {
+printk(KERN_ERR "XXX reserve_ibft_region: calling acpi_put_table(%llx)\n",
(u64)&table->header);
          acpi_put_table(&table->header);
-    else
+    } else {
          ibft_addr = table;
+printk(KERN_ERR "XXX reserve_ibft_region: ibft_addr=%llx\n",
(u64)ibft_addr);
+    }
  }

Debug from the above:
[    0.050646] ACPI: Early table checksum verification disabled
[    0.051778] ACPI: RSDP 0x00000000BFBFA014 000024 (v02 BOCHS )
[    0.052922] ACPI: XSDT 0x00000000BFBF90E8 00004C (v01 BOCHS BXPCFACP
00000001      01000013)
[    0.054623] ACPI: FACP 0x00000000BFBF5000 000074 (v01 BOCHS BXPCFACP
00000001 BXPC 00000001)
[    0.056326] ACPI: DSDT 0x00000000BFBF6000 00238D (v01 BOCHS BXPCDSDT
00000001 BXPC 00000001)
[    0.058016] ACPI: FACS 0x00000000BFBFD000 000040
[    0.058940] ACPI: APIC 0x00000000BFBF4000 000090 (v01 BOCHS BXPCAPIC
00000001 BXPC 00000001)
[    0.060627] ACPI: HPET 0x00000000BFBF3000 000038 (v01 BOCHS BXPCHPET
00000001 BXPC 00000001)
[    0.062304] ACPI: BGRT 0x00000000BE49B000 000038 (v01 INTEL EDK2
00000002      01000013)
[    0.063987] ACPI: iBFT 0x00000000BE453000 000800 (v01 BOCHS BXPCFACP
00000000      00000000)
[    0.065683] XXX acpi_tb_find_table_address: signature=iBFT
[    0.066754] XXX acpi_tb_find_table_address(EXIT): address=be453000
[    0.067959] XXX reserve_ibft_region: table=ffffffffff240000,
address=be453000, size=1000
[    0.069534] XXX reserve_ibft_region: calling
acpi_put_table(ffffffffff240000)

Not sure if it's the right thing to do, but added
"acpi_tb_find_table_address()" to return the physical address of a table to
use with memblock_reserve().

virt_to_phys(table) does not seem to return the physical address for the
iBFT table (it would be nice if struct acpi_table_header also had a
"address" element for the physical address of the table).
virt_to_phys() does not work that early because then it is mapped with
early_memremap()  which uses different virtual to physical scheme.

I'd say that acpi_tb_find_table_address() makes sense if we'd like to
reserve ACPI tables outside of drivers/acpi.

But probably we should simply reserve all the tables during
acpi_table_init() so that any table that firmware put in the normal memory
will be surely reserved.
  
quoted
Ran 10 successful boots with the above without failure.
That's good news indeed :)
Wondering if we could do something like this instead (trying to keep 
changes minimal). Just do the memblock_reserve() for all the standard 
tables.
diff --git a/drivers/acpi/acpica/tbinstal.c b/drivers/acpi/acpica/tbinstal.c
index 0bb15ad..830f82c 100644
--- a/drivers/acpi/acpica/tbinstal.c
+++ b/drivers/acpi/acpica/tbinstal.c
@@ -7,6 +7,7 @@
   *
*****************************************************************************/

+#include <linux/memblock.h>
  #include <acpi/acpi.h>
  #include "accommon.h"
  #include "actables.h"
@@ -14,6 +15,23 @@
  #define _COMPONENT          ACPI_TABLES
  ACPI_MODULE_NAME("tbinstal")

+void
+acpi_tb_reserve_standard_table(acpi_physical_address address,
+               struct acpi_table_header *header)
+{
+    struct acpi_table_header local_header;
+
+    if ((ACPI_COMPARE_NAMESEG(header->signature, ACPI_SIG_FACS)) ||
+        (ACPI_VALIDATE_RSDP_SIG(header->signature))) {
+        return;
+    }
+    /* Standard ACPI table with full common header */
+
+    memcpy(&local_header, header, sizeof(struct acpi_table_header));
+
+    memblock_reserve(address, PAGE_ALIGN(local_header.length));
+}
+
  /*******************************************************************************
   *
   * FUNCTION:    acpi_tb_install_table_with_override
@@ -58,6 +76,9 @@
                        new_table_desc->flags,
                        new_table_desc->pointer);

+    acpi_tb_reserve_standard_table(new_table_desc->address,
+                   new_table_desc->pointer);
+
      acpi_tb_print_table_header(new_table_desc->address,
                     new_table_desc->pointer);
There should be no harm in doing the memblock_reserve() for all the 
standard tables, right?

Ran 10 boots with the above without failure.

George
quoted
George
quoted

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

Re: [PATCH] mm, kasan: don't poison boot memory

From: Mike Rapoport <hidden>
Date: 2021-02-28 18:10:18

On Fri, Feb 26, 2021 at 11:16:06AM -0500, George Kennedy wrote:
On 2/26/2021 6:17 AM, Mike Rapoport wrote:
quoted
Hi George,

On Thu, Feb 25, 2021 at 08:19:18PM -0500, George Kennedy wrote:
quoted
Not sure if it's the right thing to do, but added
"acpi_tb_find_table_address()" to return the physical address of a table to
use with memblock_reserve().

virt_to_phys(table) does not seem to return the physical address for the
iBFT table (it would be nice if struct acpi_table_header also had a
"address" element for the physical address of the table).
virt_to_phys() does not work that early because then it is mapped with
early_memremap()  which uses different virtual to physical scheme.

I'd say that acpi_tb_find_table_address() makes sense if we'd like to
reserve ACPI tables outside of drivers/acpi.

But probably we should simply reserve all the tables during
acpi_table_init() so that any table that firmware put in the normal memory
will be surely reserved.
quoted
Ran 10 successful boots with the above without failure.
That's good news indeed :)
Wondering if we could do something like this instead (trying to keep changes
minimal). Just do the memblock_reserve() for all the standard tables.
I think something like this should work, but I'm not an ACPI expert to say
if this the best way to reserve the tables.
 
quoted hunk
diff --git a/drivers/acpi/acpica/tbinstal.c b/drivers/acpi/acpica/tbinstal.c
index 0bb15ad..830f82c 100644
--- a/drivers/acpi/acpica/tbinstal.c
+++ b/drivers/acpi/acpica/tbinstal.c
@@ -7,6 +7,7 @@
  *
*****************************************************************************/

+#include <linux/memblock.h>
 #include <acpi/acpi.h>
 #include "accommon.h"
 #include "actables.h"
@@ -14,6 +15,23 @@
 #define _COMPONENT          ACPI_TABLES
 ACPI_MODULE_NAME("tbinstal")

+void
+acpi_tb_reserve_standard_table(acpi_physical_address address,
+               struct acpi_table_header *header)
+{
+    struct acpi_table_header local_header;
+
+    if ((ACPI_COMPARE_NAMESEG(header->signature, ACPI_SIG_FACS)) ||
+        (ACPI_VALIDATE_RSDP_SIG(header->signature))) {
+        return;
+    }
+    /* Standard ACPI table with full common header */
+
+    memcpy(&local_header, header, sizeof(struct acpi_table_header));
+
+    memblock_reserve(address, PAGE_ALIGN(local_header.length));
+}
+
 /*******************************************************************************
  *
  * FUNCTION:    acpi_tb_install_table_with_override
@@ -58,6 +76,9 @@
                       new_table_desc->flags,
                       new_table_desc->pointer);

+    acpi_tb_reserve_standard_table(new_table_desc->address,
+                   new_table_desc->pointer);
+
     acpi_tb_print_table_header(new_table_desc->address,
                    new_table_desc->pointer);

There should be no harm in doing the memblock_reserve() for all the standard
tables, right?
It should be ok to memblock_reserve() all the tables very early as long as
we don't run out of static entries in memblock.reserved.

We just need to make sure the tables are reserved before memblock
allocations are possible, so we'd still need to move acpi_table_init() in
x86::setup_arch() before e820__memblock_setup().
Not sure how early ACPI is initialized on arm64.
 
Ran 10 boots with the above without failure.

George
-- 
Sincerely yours,
Mike.

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

Re: [PATCH] mm, kasan: don't poison boot memory

From: George Kennedy <hidden>
Date: 2021-03-01 14:33:03


On 2/28/2021 1:08 PM, Mike Rapoport wrote:
On Fri, Feb 26, 2021 at 11:16:06AM -0500, George Kennedy wrote:
quoted
On 2/26/2021 6:17 AM, Mike Rapoport wrote:
quoted
Hi George,

On Thu, Feb 25, 2021 at 08:19:18PM -0500, George Kennedy wrote:
quoted
Not sure if it's the right thing to do, but added
"acpi_tb_find_table_address()" to return the physical address of a table to
use with memblock_reserve().

virt_to_phys(table) does not seem to return the physical address for the
iBFT table (it would be nice if struct acpi_table_header also had a
"address" element for the physical address of the table).
virt_to_phys() does not work that early because then it is mapped with
early_memremap()  which uses different virtual to physical scheme.

I'd say that acpi_tb_find_table_address() makes sense if we'd like to
reserve ACPI tables outside of drivers/acpi.

But probably we should simply reserve all the tables during
acpi_table_init() so that any table that firmware put in the normal memory
will be surely reserved.
quoted
Ran 10 successful boots with the above without failure.
That's good news indeed :)
Wondering if we could do something like this instead (trying to keep changes
minimal). Just do the memblock_reserve() for all the standard tables.
I think something like this should work, but I'm not an ACPI expert to say
if this the best way to reserve the tables.
Adding ACPI maintainers to the CC list.
  
quoted
diff --git a/drivers/acpi/acpica/tbinstal.c b/drivers/acpi/acpica/tbinstal.c
index 0bb15ad..830f82c 100644
--- a/drivers/acpi/acpica/tbinstal.c
+++ b/drivers/acpi/acpica/tbinstal.c
@@ -7,6 +7,7 @@
   *
*****************************************************************************/

+#include <linux/memblock.h>
  #include <acpi/acpi.h>
  #include "accommon.h"
  #include "actables.h"
@@ -14,6 +15,23 @@
  #define _COMPONENT          ACPI_TABLES
  ACPI_MODULE_NAME("tbinstal")

+void
+acpi_tb_reserve_standard_table(acpi_physical_address address,
+               struct acpi_table_header *header)
+{
+    struct acpi_table_header local_header;
+
+    if ((ACPI_COMPARE_NAMESEG(header->signature, ACPI_SIG_FACS)) ||
+        (ACPI_VALIDATE_RSDP_SIG(header->signature))) {
+        return;
+    }
+    /* Standard ACPI table with full common header */
+
+    memcpy(&local_header, header, sizeof(struct acpi_table_header));
+
+    memblock_reserve(address, PAGE_ALIGN(local_header.length));
+}
+
  /*******************************************************************************
   *
   * FUNCTION:    acpi_tb_install_table_with_override
@@ -58,6 +76,9 @@
                        new_table_desc->flags,
                        new_table_desc->pointer);

+    acpi_tb_reserve_standard_table(new_table_desc->address,
+                   new_table_desc->pointer);
+
      acpi_tb_print_table_header(new_table_desc->address,
                     new_table_desc->pointer);
There should be no harm in doing the memblock_reserve() for all the standard
tables, right?
It should be ok to memblock_reserve() all the tables very early as long as
we don't run out of static entries in memblock.reserved.

We just need to make sure the tables are reserved before memblock
allocations are possible, so we'd still need to move acpi_table_init() in
x86::setup_arch() before e820__memblock_setup().
Not sure how early ACPI is initialized on arm64.
Thanks Mike. Will try to move the memblock_reserves() before 
e820__memblock_setup().

George
  
quoted
Ran 10 boots with the above without failure.

George

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

Re: [PATCH] mm, kasan: don't poison boot memory

From: George Kennedy <hidden>
Date: 2021-03-02 07:47:23


On 3/1/2021 9:29 AM, George Kennedy wrote:

On 2/28/2021 1:08 PM, Mike Rapoport wrote:
quoted
On Fri, Feb 26, 2021 at 11:16:06AM -0500, George Kennedy wrote:
quoted
On 2/26/2021 6:17 AM, Mike Rapoport wrote:
quoted
Hi George,

On Thu, Feb 25, 2021 at 08:19:18PM -0500, George Kennedy wrote:
quoted
Not sure if it's the right thing to do, but added
"acpi_tb_find_table_address()" to return the physical address of a 
table to
use with memblock_reserve().

virt_to_phys(table) does not seem to return the physical address 
for the
iBFT table (it would be nice if struct acpi_table_header also had a
"address" element for the physical address of the table).
virt_to_phys() does not work that early because then it is mapped with
early_memremap()  which uses different virtual to physical scheme.

I'd say that acpi_tb_find_table_address() makes sense if we'd like to
reserve ACPI tables outside of drivers/acpi.

But probably we should simply reserve all the tables during
acpi_table_init() so that any table that firmware put in the normal 
memory
will be surely reserved.
quoted
Ran 10 successful boots with the above without failure.
That's good news indeed :)
Wondering if we could do something like this instead (trying to keep 
changes
minimal). Just do the memblock_reserve() for all the standard tables.
I think something like this should work, but I'm not an ACPI expert 
to say
if this the best way to reserve the tables.
Adding ACPI maintainers to the CC list.
quoted
quoted
diff --git a/drivers/acpi/acpica/tbinstal.c 
b/drivers/acpi/acpica/tbinstal.c
index 0bb15ad..830f82c 100644
--- a/drivers/acpi/acpica/tbinstal.c
+++ b/drivers/acpi/acpica/tbinstal.c
@@ -7,6 +7,7 @@
   *
*****************************************************************************/ 


+#include <linux/memblock.h>
  #include <acpi/acpi.h>
  #include "accommon.h"
  #include "actables.h"
@@ -14,6 +15,23 @@
  #define _COMPONENT          ACPI_TABLES
  ACPI_MODULE_NAME("tbinstal")

+void
+acpi_tb_reserve_standard_table(acpi_physical_address address,
+               struct acpi_table_header *header)
+{
+    struct acpi_table_header local_header;
+
+    if ((ACPI_COMPARE_NAMESEG(header->signature, ACPI_SIG_FACS)) ||
+        (ACPI_VALIDATE_RSDP_SIG(header->signature))) {
+        return;
+    }
+    /* Standard ACPI table with full common header */
+
+    memcpy(&local_header, header, sizeof(struct acpi_table_header));
+
+    memblock_reserve(address, PAGE_ALIGN(local_header.length));
+}
+
  /******************************************************************************* 

   *
   * FUNCTION:    acpi_tb_install_table_with_override
@@ -58,6 +76,9 @@
                        new_table_desc->flags,
                        new_table_desc->pointer);

+ acpi_tb_reserve_standard_table(new_table_desc->address,
+                   new_table_desc->pointer);
+
      acpi_tb_print_table_header(new_table_desc->address,
                     new_table_desc->pointer);

There should be no harm in doing the memblock_reserve() for all the 
standard
tables, right?
It should be ok to memblock_reserve() all the tables very early as 
long as
we don't run out of static entries in memblock.reserved.

We just need to make sure the tables are reserved before memblock
allocations are possible, so we'd still need to move 
acpi_table_init() in
x86::setup_arch() before e820__memblock_setup().
Not sure how early ACPI is initialized on arm64.
Thanks Mike. Will try to move the memblock_reserves() before 
e820__memblock_setup().
Hi Mike,

Moved acpi_table_init() in x86::setup_arch() before 
e820__memblock_setup() as you suggested.

Ran 10 boots with the following without error.
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
index 740f3bdb..3b1dd24 100644
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -1047,6 +1047,7 @@ void __init setup_arch(char **cmdline_p)
      cleanup_highmap();

      memblock_set_current_limit(ISA_END_ADDRESS);
+    acpi_boot_table_init();
      e820__memblock_setup();

      /*
@@ -1140,8 +1141,6 @@ void __init setup_arch(char **cmdline_p)
      /*
       * Parse the ACPI tables for possible boot-time SMP configuration.
       */
-    acpi_boot_table_init();
-
      early_acpi_boot_init();

      initmem_init();
diff --git a/drivers/acpi/acpica/tbinstal.c b/drivers/acpi/acpica/tbinstal.c
index 0bb15ad..7830109 100644
--- a/drivers/acpi/acpica/tbinstal.c
+++ b/drivers/acpi/acpica/tbinstal.c
@@ -7,6 +7,7 @@
   *
*****************************************************************************/

+#include <linux/memblock.h>
  #include <acpi/acpi.h>
  #include "accommon.h"
  #include "actables.h"
@@ -16,6 +17,33 @@

  /*******************************************************************************
   *
+ * FUNCTION:    acpi_tb_reserve_standard_table
+ *
+ * PARAMETERS:  address             - Table physical address
+ *              header              - Table header
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: To avoid an acpi table page from being "stolen" by the 
buddy
+ *              allocator run memblock_reserve() on all the standard 
acpi tables.
+ *
+ 
******************************************************************************/
+void
+acpi_tb_reserve_standard_table(acpi_physical_address address,
+               struct acpi_table_header *header)
+{
+    if ((ACPI_COMPARE_NAMESEG(header->signature, ACPI_SIG_FACS)) ||
+        (ACPI_VALIDATE_RSDP_SIG(header->signature)))
+        return;
+
+    if (header->length > PAGE_SIZE) /* same check as in acpi_map() */
+        return;
+
+    memblock_reserve(address, PAGE_ALIGN(header->length));
+}
+
+/*******************************************************************************
+ *
   * FUNCTION:    acpi_tb_install_table_with_override
   *
   * PARAMETERS:  new_table_desc          - New table descriptor to install
@@ -58,6 +86,9 @@
                        new_table_desc->flags,
                        new_table_desc->pointer);

+    acpi_tb_reserve_standard_table(new_table_desc->address,
+                   new_table_desc->pointer);
+
      acpi_tb_print_table_header(new_table_desc->address,
                     new_table_desc->pointer);
George
George
quoted
quoted
Ran 10 boots with the above without failure.

George

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

Re: [PATCH] mm, kasan: don't poison boot memory

From: Mike Rapoport <hidden>
Date: 2021-03-02 10:11:15

Hi George,

On Mon, Mar 01, 2021 at 08:20:45PM -0500, George Kennedy wrote:
quoted
quoted
quoted
quoted
There should be no harm in doing the memblock_reserve() for all
the standard
tables, right?
It should be ok to memblock_reserve() all the tables very early as
long as
we don't run out of static entries in memblock.reserved.

We just need to make sure the tables are reserved before memblock
allocations are possible, so we'd still need to move
acpi_table_init() in
x86::setup_arch() before e820__memblock_setup().
Not sure how early ACPI is initialized on arm64.
Thanks Mike. Will try to move the memblock_reserves() before
e820__memblock_setup().
Hi Mike,

Moved acpi_table_init() in x86::setup_arch() before e820__memblock_setup()
as you suggested.

Ran 10 boots with the following without error.
I'd suggest to send it as a formal patch to see what x86 and ACPI folks
have to say about this.
 
quoted hunk
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
index 740f3bdb..3b1dd24 100644
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -1047,6 +1047,7 @@ void __init setup_arch(char **cmdline_p)
     cleanup_highmap();

     memblock_set_current_limit(ISA_END_ADDRESS);
+    acpi_boot_table_init();
     e820__memblock_setup();

     /*
@@ -1140,8 +1141,6 @@ void __init setup_arch(char **cmdline_p)
     /*
      * Parse the ACPI tables for possible boot-time SMP configuration.
      */
-    acpi_boot_table_init();
-
     early_acpi_boot_init();

     initmem_init();
diff --git a/drivers/acpi/acpica/tbinstal.c b/drivers/acpi/acpica/tbinstal.c
index 0bb15ad..7830109 100644
--- a/drivers/acpi/acpica/tbinstal.c
+++ b/drivers/acpi/acpica/tbinstal.c
@@ -7,6 +7,7 @@
  *
*****************************************************************************/

+#include <linux/memblock.h>
 #include <acpi/acpi.h>
 #include "accommon.h"
 #include "actables.h"
@@ -16,6 +17,33 @@
 /*******************************************************************************
  *
+ * FUNCTION:    acpi_tb_reserve_standard_table
+ *
+ * PARAMETERS:  address             - Table physical address
+ *              header              - Table header
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: To avoid an acpi table page from being "stolen" by the
buddy
+ *              allocator run memblock_reserve() on all the standard acpi
tables.
+ *
+ ******************************************************************************/
+void
+acpi_tb_reserve_standard_table(acpi_physical_address address,
+               struct acpi_table_header *header)
+{
+    if ((ACPI_COMPARE_NAMESEG(header->signature, ACPI_SIG_FACS)) ||
+        (ACPI_VALIDATE_RSDP_SIG(header->signature)))
+        return;
+
Why these should be excluded?
+    if (header->length > PAGE_SIZE) /* same check as in acpi_map() */
+        return;
I don't think this is required, I believe acpi_map() has this check because
kmap() cannot handle multiple pages.
quoted hunk
+
+    memblock_reserve(address, PAGE_ALIGN(header->length));
+}
+
+/*******************************************************************************
+ *
  * FUNCTION:    acpi_tb_install_table_with_override
  *
  * PARAMETERS:  new_table_desc          - New table descriptor to install
@@ -58,6 +86,9 @@
                       new_table_desc->flags,
                       new_table_desc->pointer);

+    acpi_tb_reserve_standard_table(new_table_desc->address,
+                   new_table_desc->pointer);
+
     acpi_tb_print_table_header(new_table_desc->address,
                    new_table_desc->pointer);

George
-- 
Sincerely yours,
Mike.

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help