mirror of
https://github.com/torvalds/linux.git
synced 2024-11-11 22:51:42 +00:00
ACPI / sysfs: Fix incorrect ACPI tables walk in acpi_tables_sysfs_init()
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>
This commit is contained in:
parent
083ca8c417
commit
de03beedb4
@ -354,8 +354,9 @@ static int acpi_tables_sysfs_init(void)
|
|||||||
{
|
{
|
||||||
struct acpi_table_attr *table_attr;
|
struct acpi_table_attr *table_attr;
|
||||||
struct acpi_table_header *table_header = NULL;
|
struct acpi_table_header *table_header = NULL;
|
||||||
int table_index = 0;
|
int table_index;
|
||||||
int result;
|
acpi_status status;
|
||||||
|
int ret;
|
||||||
|
|
||||||
tables_kobj = kobject_create_and_add("tables", acpi_kobj);
|
tables_kobj = kobject_create_and_add("tables", acpi_kobj);
|
||||||
if (!tables_kobj)
|
if (!tables_kobj)
|
||||||
@ -365,33 +366,34 @@ static int acpi_tables_sysfs_init(void)
|
|||||||
if (!dynamic_tables_kobj)
|
if (!dynamic_tables_kobj)
|
||||||
goto err_dynamic_tables;
|
goto err_dynamic_tables;
|
||||||
|
|
||||||
do {
|
for (table_index = 0;; table_index++) {
|
||||||
result = acpi_get_table_by_index(table_index, &table_header);
|
status = 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);
|
if (status == AE_BAD_PARAMETER)
|
||||||
result =
|
break;
|
||||||
sysfs_create_bin_file(tables_kobj,
|
|
||||||
&table_attr->attr);
|
if (ACPI_FAILURE(status))
|
||||||
if (result) {
|
continue;
|
||||||
kfree(table_attr);
|
|
||||||
return result;
|
table_attr = NULL;
|
||||||
} else
|
table_attr = kzalloc(sizeof(*table_attr), GFP_KERNEL);
|
||||||
list_add_tail(&table_attr->node,
|
if (!table_attr)
|
||||||
&acpi_table_attr_list);
|
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(tables_kobj, KOBJ_ADD);
|
||||||
kobject_uevent(dynamic_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:
|
err_dynamic_tables:
|
||||||
kobject_put(tables_kobj);
|
kobject_put(tables_kobj);
|
||||||
err:
|
err:
|
||||||
|
Loading…
Reference in New Issue
Block a user