aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLv Zheng <lv.zheng@intel.com>2014-05-30 20:15:02 -0400
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2014-05-31 18:20:52 -0400
commit4fc0a7e889e5540305926e41931cf3bc0a60abb2 (patch)
tree0aef3c0eb39701166efdff443032d1c579c12985
parent47d68c7f688c01557cb67dd80eb540e88d7913b6 (diff)
ACPI: Fix x86 regression related to early mapping size limitation
The following warning message is triggered: WARNING: CPU: 0 PID: 0 at mm/early_ioremap.c:136 __early_ioremap+0x11f/0x1f2() Modules linked in: CPU: 0 PID: 0 Comm: swapper Not tainted 3.15.0-rc1-00017-g86dfc6f3-dirty #298 Hardware name: Intel Corporation S2600CP/S2600CP, BIOS SE5C600.86B.99.99.x036.091920111209 09/19/2011 0000000000000009 ffffffff81b75c40 ffffffff817c627b 0000000000000000 ffffffff81b75c78 ffffffff81067b5d 000000000000007b 8000000000000563 00000000b96b20dc 0000000000000001 ffffffffff300e0c ffffffff81b75c88 Call Trace: [<ffffffff817c627b>] dump_stack+0x45/0x56 [<ffffffff81067b5d>] warn_slowpath_common+0x7d/0xa0 [<ffffffff81067c3a>] warn_slowpath_null+0x1a/0x20 [<ffffffff81d4b9d5>] __early_ioremap+0x11f/0x1f2 [<ffffffff81d4bc5b>] early_ioremap+0x13/0x15 [<ffffffff81d2b8f3>] __acpi_map_table+0x13/0x18 [<ffffffff817b8d1a>] acpi_os_map_memory+0x26/0x14e [<ffffffff813ff018>] acpi_tb_acquire_table+0x42/0x70 [<ffffffff813ff086>] acpi_tb_validate_table+0x27/0x37 [<ffffffff813ff0e5>] acpi_tb_verify_table+0x22/0xd8 [<ffffffff813ff6a8>] acpi_tb_install_non_fixed_table+0x60/0x1c9 [<ffffffff81d61024>] acpi_tb_parse_root_table+0x218/0x26a [<ffffffff81d1b120>] ? early_idt_handlers+0x120/0x120 [<ffffffff81d610cd>] acpi_initialize_tables+0x57/0x59 [<ffffffff81d5f25d>] acpi_table_init+0x1b/0x99 [<ffffffff81d2bca0>] acpi_boot_table_init+0x1e/0x85 [<ffffffff81d23043>] setup_arch+0x99d/0xcc6 [<ffffffff81d1b120>] ? early_idt_handlers+0x120/0x120 [<ffffffff81d1bbbe>] start_kernel+0x8b/0x415 [<ffffffff81d1b120>] ? early_idt_handlers+0x120/0x120 [<ffffffff81d1b5ee>] x86_64_start_reservations+0x2a/0x2c [<ffffffff81d1b72e>] x86_64_start_kernel+0x13e/0x14d ---[ end trace 11ae599a1898f4e7 ]--- when installing the following table during early stage: ACPI: SSDT 0x00000000B9638018 07A0C4 (v02 INTEL S2600CP 00004000 INTL 20100331) The regression is caused by the size limitation of the x86 early IO mapping. The root cause is: 1. ACPICA doesn't split IO memory mapping and table mapping; 2. Linux x86 OSL implements acpi_os_map_memory() using a size limited fix-map mechanism during early boot stage, which is more suitable for only IO mappings. This patch fixes this issue by utilizing acpi_gbl_verify_table_checksum to disable the table mapping during early stage and enabling it again for the late stage. In this way, the normal code path is not affected. Then after the code related to the root cause is cleaned up, the early checksum verification can be easily re-enabled. A new boot parameter - acpi_force_table_verification is introduced for the platforms that require the checksum verification to stop loading bad tables. This fix also covers the checksum verification for the table overrides. Now large tables can also be overridden using the initrd override mechanism. Signed-off-by: Lv Zheng <lv.zheng@intel.com> Reported-and-tested-by: Yuanhan Liu <yuanhan.liu@linux.intel.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
-rw-r--r--Documentation/kernel-parameters.txt5
-rw-r--r--drivers/acpi/bus.c3
-rw-r--r--drivers/acpi/tables.c23
3 files changed, 31 insertions, 0 deletions
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index 60a278948652..4b7cc1481436 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -214,6 +214,11 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
214 unusable. The "log_buf_len" parameter may be useful 214 unusable. The "log_buf_len" parameter may be useful
215 if you need to capture more output. 215 if you need to capture more output.
216 216
217 acpi_force_table_verification [HW,ACPI]
218 Enable table checksum verification during early stage.
219 By default, this is disabled due to x86 early mapping
220 size limitation.
221
217 acpi_irq_balance [HW,ACPI] 222 acpi_irq_balance [HW,ACPI]
218 ACPI will balance active IRQs 223 ACPI will balance active IRQs
219 default in APIC mode 224 default in APIC mode
diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c
index cf925c4f36b7..cf0b5ecf55b6 100644
--- a/drivers/acpi/bus.c
+++ b/drivers/acpi/bus.c
@@ -466,6 +466,9 @@ void __init acpi_early_init(void)
466 466
467 printk(KERN_INFO PREFIX "Core revision %08x\n", ACPI_CA_VERSION); 467 printk(KERN_INFO PREFIX "Core revision %08x\n", ACPI_CA_VERSION);
468 468
469 /* It's safe to verify table checksums during late stage */
470 acpi_gbl_verify_table_checksum = TRUE;
471
469 /* enable workarounds, unless strict ACPI spec. compliance */ 472 /* enable workarounds, unless strict ACPI spec. compliance */
470 if (!acpi_strict) 473 if (!acpi_strict)
471 acpi_gbl_enable_interpreter_slack = TRUE; 474 acpi_gbl_enable_interpreter_slack = TRUE;
diff --git a/drivers/acpi/tables.c b/drivers/acpi/tables.c
index 21782290df41..05550ba44d32 100644
--- a/drivers/acpi/tables.c
+++ b/drivers/acpi/tables.c
@@ -44,6 +44,12 @@ static struct acpi_table_desc initial_tables[ACPI_MAX_TABLES] __initdata;
44 44
45static int acpi_apic_instance __initdata; 45static int acpi_apic_instance __initdata;
46 46
47/*
48 * Disable table checksum verification for the early stage due to the size
49 * limitation of the current x86 early mapping implementation.
50 */
51static bool acpi_verify_table_checksum __initdata = false;
52
47void acpi_table_print_madt_entry(struct acpi_subtable_header *header) 53void acpi_table_print_madt_entry(struct acpi_subtable_header *header)
48{ 54{
49 if (!header) 55 if (!header)
@@ -333,6 +339,14 @@ int __init acpi_table_init(void)
333{ 339{
334 acpi_status status; 340 acpi_status status;
335 341
342 if (acpi_verify_table_checksum) {
343 pr_info("Early table checksum verification enabled\n");
344 acpi_gbl_verify_table_checksum = TRUE;
345 } else {
346 pr_info("Early table checksum verification disabled\n");
347 acpi_gbl_verify_table_checksum = FALSE;
348 }
349
336 status = acpi_initialize_tables(initial_tables, ACPI_MAX_TABLES, 0); 350 status = acpi_initialize_tables(initial_tables, ACPI_MAX_TABLES, 0);
337 if (ACPI_FAILURE(status)) 351 if (ACPI_FAILURE(status))
338 return -EINVAL; 352 return -EINVAL;
@@ -354,3 +368,12 @@ static int __init acpi_parse_apic_instance(char *str)
354} 368}
355 369
356early_param("acpi_apic_instance", acpi_parse_apic_instance); 370early_param("acpi_apic_instance", acpi_parse_apic_instance);
371
372static int __init acpi_force_table_verification_setup(char *s)
373{
374 acpi_verify_table_checksum = true;
375
376 return 0;
377}
378
379early_param("acpi_force_table_verification", acpi_force_table_verification_setup);