ACPI / sysfs: Fix an issue for LoadTable opcode
authorLv Zheng <lv.zheng@intel.com>
Tue, 13 Sep 2016 09:48:27 +0000 (17:48 +0800)
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>
Fri, 16 Sep 2016 23:10:43 +0000 (01:10 +0200)
OEM tables can be installed via RSDT/XSDT, in this case, they have already
been created under /sys/firmware/acpi/tables.

For this kind of tables, normally LoadTable opcode will be executed to load
them. If LoadTable opcode is executed after acpi_sysfs_init(),
acpi_sysfs_table_handler() will be invoked, thus a redundant table file
will be created under /sys/firmware/acpi/tables/dynamic. Then running
"acpidump" on such platform results in an error, complaining blank empty
table (see Link 1 below).

The bug can be reproduced by customizing an OEM1 table, allowing it to be
overridden via 'table_sigs' (drivers/acpi/tables.c), adding the following
code to the customized DSDT to load it:

  Name (OEMH, Zero)
  Name (OEMF, One)
  If (LEqual (OEMF, One)) {
      Store (LoadTable ("OEM1", "Intel", "Test"), OEMH)
      Store (Zero, OEMF)
  }

In order to make sure that the OEM1 table is installed after
acpi_sysfs_init(), acpi_sysfs_init() can be moved before invoking
acpi_load_tables(). Then the following command execution result can be
seen:
 # acpidump > acpidump.txt
 Could not read table header: /sysfs/firmware/acpi/tables/dynamic/OEM12
 Could not get ACPI table at index 17, AE_BAD_HEADER

Link: https://bugzilla.kernel.org/show_bug.cgi?id=150841
Link: https://github.com/acpica/acpica/commit/ed6a5fbc
Reported-by: Jason Voelz <jason.voelz@intel.com>
Reported-by: Francisco Leoner <francisco.j.lenoer.soto@intel.com>
Signed-off-by: Lv Zheng <lv.zheng@intel.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
drivers/acpi/sysfs.c

index 703c993..c88d4bd 100644 (file)
@@ -383,7 +383,7 @@ acpi_status acpi_sysfs_table_handler(u32 event, void *table, void *context)
        struct acpi_table_attr *table_attr;
 
        switch (event) {
-       case ACPI_TABLE_EVENT_LOAD:
+       case ACPI_TABLE_EVENT_INSTALL:
                table_attr =
                    kzalloc(sizeof(struct acpi_table_attr), GFP_KERNEL);
                if (!table_attr)
@@ -397,7 +397,9 @@ acpi_status acpi_sysfs_table_handler(u32 event, void *table, void *context)
                } else
                        list_add_tail(&table_attr->node, &acpi_table_attr_list);
                break;
+       case ACPI_TABLE_EVENT_LOAD:
        case ACPI_TABLE_EVENT_UNLOAD:
+       case ACPI_TABLE_EVENT_UNINSTALL:
                /*
                 * we do not need to do anything right now
                 * because the table is not deleted from the