]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
ACPICA: Tables: Add deferred table verification support
authorLv Zheng <lv.zheng@intel.com>
Mon, 10 Jul 2017 07:23:56 +0000 (15:23 +0800)
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>
Thu, 20 Jul 2017 14:38:25 +0000 (16:38 +0200)
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>
drivers/acpi/acpica/tbdata.c
drivers/acpi/acpica/tbxface.c
include/acpi/actbl.h

index 577361b05ea93a5c04c644f120292778f4a7b994..b19a2f0ea331dbb7a544651fae8f6fe7eee6d8dc 100644 (file)
@@ -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);
index 38c01049afd5a0d559d76b6e6557f1b49899f366..26ad596c973e9309d8fb961c26100eae2d650d1b 100644 (file)
@@ -167,7 +167,8 @@ ACPI_EXPORT_SYMBOL_INIT(acpi_initialize_tables)
 acpi_status ACPI_INIT_FUNCTION acpi_reallocate_root_table(void)
 {
        acpi_status status;
-       u32 i;
+       struct acpi_table_desc *table_desc;
+       u32 i, j;
 
        ACPI_FUNCTION_TRACE(acpi_reallocate_root_table);
 
@@ -179,6 +180,8 @@ acpi_status ACPI_INIT_FUNCTION acpi_reallocate_root_table(void)
                return_ACPI_STATUS(AE_SUPPORT);
        }
 
+       (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
+
        /*
         * Ensure OS early boot logic, which is required by some hosts. If the
         * table state is reported to be wrong, developers should fix the
@@ -186,11 +189,11 @@ acpi_status ACPI_INIT_FUNCTION acpi_reallocate_root_table(void)
         * early stage.
         */
        for (i = 0; i < acpi_gbl_root_table_list.current_table_count; ++i) {
-               if (acpi_gbl_root_table_list.tables[i].pointer) {
+               table_desc = &acpi_gbl_root_table_list.tables[i];
+               if (table_desc->pointer) {
                        ACPI_ERROR((AE_INFO,
                                    "Table [%4.4s] is not invalidated during early boot stage",
-                                   acpi_gbl_root_table_list.tables[i].
-                                   signature.ascii));
+                                   table_desc->signature.ascii));
                }
        }
 
@@ -200,11 +203,25 @@ acpi_status ACPI_INIT_FUNCTION acpi_reallocate_root_table(void)
                 * table initilization here once the flag is set.
                 */
                acpi_gbl_enable_table_validation = TRUE;
+               for (i = 0; i < acpi_gbl_root_table_list.current_table_count;
+                    ++i) {
+                       table_desc = &acpi_gbl_root_table_list.tables[i];
+                       if (!(table_desc->flags & ACPI_TABLE_IS_VERIFIED)) {
+                               status =
+                                   acpi_tb_verify_temp_table(table_desc, NULL,
+                                                             &j);
+                               if (ACPI_FAILURE(status)) {
+                                       acpi_tb_uninstall_table(table_desc);
+                               }
+                       }
+               }
        }
 
        acpi_gbl_root_table_list.flags |= ACPI_ROOT_ALLOW_RESIZE;
-
        status = acpi_tb_resize_root_table_list();
+       acpi_gbl_root_table_list.flags |= ACPI_ROOT_ORIGIN_ALLOCATED;
+
+       (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
        return_ACPI_STATUS(status);
 }
 
index bdc55c0da19cd06c65e589d9071f65c2eb5c2332..89509b86cb54bd04351bdd7cd0da2251dc2f4214 100644 (file)
@@ -394,6 +394,7 @@ struct acpi_table_desc {
 #define ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL (1)        /* Physical address, internally mapped */
 #define ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL  (2)        /* Virtual address, internallly allocated */
 #define ACPI_TABLE_ORIGIN_MASK              (3)
+#define ACPI_TABLE_IS_VERIFIED              (4)
 #define ACPI_TABLE_IS_LOADED                (8)
 
 /*