Skip to content

Commit

Permalink
ACPI / sysfs: Fix incorrect ACPI tables walk in acpi_tables_sysfs_init()
Browse files Browse the repository at this point in the history
When executing on an ACPI Hardware Reduced hardware, all the ACPI
tables are not exposed in sysfs due to the fact that FACS is
silently ignored by the kernel in the ACPI hardware reduced mode
and, moreover, the acpi_tables_sysfs_init() ACPI table walk
is buggy and stops too soon.

The acpi_tables_sysfs_init() function should rely on the acpi_status
return value from acpi_get_table_by_index() to decide whether or not
to stop the iteration (the walk should only be terminated when that
value is AE_BAD_PARAMETER).  This way, when running in an ACPI Harware
Reduced environment (where the FACS table is silently ignored by the
kernel) or if some ACPI tables are not correctly memory mapped or
have bad checksums, it will still walk through the remaining tables
that may be correct.

[rjw: Changelog]
Signed-off-by: Jeremy Compostella <jeremy.compostella@intel.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
  • Loading branch information
Jeremy Compostella authored and Rafael J. Wysocki committed Nov 21, 2013
1 parent 083ca8c commit de03bee
Showing 1 changed file with 27 additions and 25 deletions.
52 changes: 27 additions & 25 deletions drivers/acpi/sysfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -354,8 +354,9 @@ static int acpi_tables_sysfs_init(void)
{
struct acpi_table_attr *table_attr;
struct acpi_table_header *table_header = NULL;
int table_index = 0;
int result;
int table_index;
acpi_status status;
int ret;

tables_kobj = kobject_create_and_add("tables", acpi_kobj);
if (!tables_kobj)
Expand All @@ -365,33 +366,34 @@ static int acpi_tables_sysfs_init(void)
if (!dynamic_tables_kobj)
goto err_dynamic_tables;

do {
result = acpi_get_table_by_index(table_index, &table_header);
if (!result) {
table_index++;
table_attr = NULL;
table_attr =
kzalloc(sizeof(struct acpi_table_attr), GFP_KERNEL);
if (!table_attr)
return -ENOMEM;

acpi_table_attr_init(table_attr, table_header);
result =
sysfs_create_bin_file(tables_kobj,
&table_attr->attr);
if (result) {
kfree(table_attr);
return result;
} else
list_add_tail(&table_attr->node,
&acpi_table_attr_list);
for (table_index = 0;; table_index++) {
status = acpi_get_table_by_index(table_index, &table_header);

if (status == AE_BAD_PARAMETER)
break;

if (ACPI_FAILURE(status))
continue;

table_attr = NULL;
table_attr = kzalloc(sizeof(*table_attr), GFP_KERNEL);
if (!table_attr)
return -ENOMEM;

acpi_table_attr_init(table_attr, table_header);
ret = sysfs_create_bin_file(tables_kobj, &table_attr->attr);
if (ret) {
kfree(table_attr);
return ret;
}
} while (!result);
list_add_tail(&table_attr->node, &acpi_table_attr_list);
}

kobject_uevent(tables_kobj, KOBJ_ADD);
kobject_uevent(dynamic_tables_kobj, KOBJ_ADD);
result = acpi_install_table_handler(acpi_sysfs_table_handler, NULL);
status = acpi_install_table_handler(acpi_sysfs_table_handler, NULL);

return result == AE_OK ? 0 : -EINVAL;
return ACPI_FAILURE(status) ? -EINVAL : 0;
err_dynamic_tables:
kobject_put(tables_kobj);
err:
Expand Down

0 comments on commit de03bee

Please sign in to comment.