summaryrefslogtreecommitdiff
path: root/drivers/acpi/acpica/tbdata.c
diff options
context:
space:
mode:
authorLv Zheng <lv.zheng@intel.com>2017-07-10 10:23:56 +0300
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2017-07-20 17:38:25 +0300
commit19df56bdf0833a8ad9dfe056931696b9e0e30463 (patch)
treef0a50600978fc6eadcee150345a7ebb534b4c644 /drivers/acpi/acpica/tbdata.c
parentf9d472ee3214cf8fc3e4b418b376869799adaf67 (diff)
downloadlinux-19df56bdf0833a8ad9dfe056931696b9e0e30463.tar.xz
ACPICA: Tables: Add deferred table verification support
ACPICA commit 2dd6c151d5d5e76dacba8f7db9e259fc72982d17 ACPICA commit ffddee6638aced83be18b8bc88569586c1a43e03 This patch allows tables not verified in early stage verfied in acpi_reallocate_root_table(). This is useful for OSPMs like linux where tables cannot be verified in early stage due to early ioremp limitations on some architectures. Reported by Hans de Geode, fixed by Lv Zheng. Link: https://github.com/acpica/acpica/commit/2dd6c151 Link: https://github.com/acpica/acpica/commit/ffddee66 Reported-by: Hans de Goede <hdegoede@redhat.com> Signed-off-by: Lv Zheng <lv.zheng@intel.com> Signed-off-by: Bob Moore <robert.moore@intel.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Diffstat (limited to 'drivers/acpi/acpica/tbdata.c')
-rw-r--r--drivers/acpi/acpica/tbdata.c34
1 files changed, 28 insertions, 6 deletions
diff --git a/drivers/acpi/acpica/tbdata.c b/drivers/acpi/acpica/tbdata.c
index 577361b05ea9..b19a2f0ea331 100644
--- a/drivers/acpi/acpica/tbdata.c
+++ b/drivers/acpi/acpica/tbdata.c
@@ -432,6 +432,15 @@ acpi_tb_check_duplication(struct acpi_table_desc *table_desc, u32 *table_index)
/* Check if table is already registered */
for (i = 0; i < acpi_gbl_root_table_list.current_table_count; ++i) {
+
+ /* Do not compare with unverified tables */
+
+ if (!
+ (acpi_gbl_root_table_list.tables[i].
+ flags & ACPI_TABLE_IS_VERIFIED)) {
+ continue;
+ }
+
/*
* Check for a table match on the entire table length,
* not just the header.
@@ -483,6 +492,8 @@ acpi_tb_check_duplication(struct acpi_table_desc *table_desc, u32 *table_index)
*
* DESCRIPTION: This function is called to validate and verify the table, the
* returned table descriptor is in "VALIDATED" state.
+ * Note that 'TableIndex' is required to be set to !NULL to
+ * enable duplication check.
*
*****************************************************************************/
@@ -554,6 +565,8 @@ acpi_tb_verify_temp_table(struct acpi_table_desc *table_desc,
goto invalidate_and_exit;
}
}
+
+ table_desc->flags |= ACPI_TABLE_IS_VERIFIED;
}
return_ACPI_STATUS(status);
@@ -579,6 +592,8 @@ acpi_status acpi_tb_resize_root_table_list(void)
{
struct acpi_table_desc *tables;
u32 table_count;
+ u32 current_table_count, max_table_count;
+ u32 i;
ACPI_FUNCTION_TRACE(tb_resize_root_table_list);
@@ -598,8 +613,8 @@ acpi_status acpi_tb_resize_root_table_list(void)
table_count = acpi_gbl_root_table_list.current_table_count;
}
- tables = ACPI_ALLOCATE_ZEROED(((acpi_size)table_count +
- ACPI_ROOT_TABLE_SIZE_INCREMENT) *
+ max_table_count = table_count + ACPI_ROOT_TABLE_SIZE_INCREMENT;
+ tables = ACPI_ALLOCATE_ZEROED(((acpi_size)max_table_count) *
sizeof(struct acpi_table_desc));
if (!tables) {
ACPI_ERROR((AE_INFO,
@@ -609,9 +624,16 @@ acpi_status acpi_tb_resize_root_table_list(void)
/* Copy and free the previous table array */
+ current_table_count = 0;
if (acpi_gbl_root_table_list.tables) {
- memcpy(tables, acpi_gbl_root_table_list.tables,
- (acpi_size)table_count * sizeof(struct acpi_table_desc));
+ for (i = 0; i < table_count; i++) {
+ if (acpi_gbl_root_table_list.tables[i].address) {
+ memcpy(tables + current_table_count,
+ acpi_gbl_root_table_list.tables + i,
+ sizeof(struct acpi_table_desc));
+ current_table_count++;
+ }
+ }
if (acpi_gbl_root_table_list.flags & ACPI_ROOT_ORIGIN_ALLOCATED) {
ACPI_FREE(acpi_gbl_root_table_list.tables);
@@ -619,8 +641,8 @@ acpi_status acpi_tb_resize_root_table_list(void)
}
acpi_gbl_root_table_list.tables = tables;
- acpi_gbl_root_table_list.max_table_count =
- table_count + ACPI_ROOT_TABLE_SIZE_INCREMENT;
+ acpi_gbl_root_table_list.max_table_count = max_table_count;
+ acpi_gbl_root_table_list.current_table_count = current_table_count;
acpi_gbl_root_table_list.flags |= ACPI_ROOT_ORIGIN_ALLOCATED;
return_ACPI_STATUS(AE_OK);