linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/2] ACPI / OSL: Improve initrd override mechanism
@ 2016-03-02  6:16 Lv Zheng
  2016-03-02  6:16 ` [PATCH 1/2] ACPI / OSL: Cleanup initrd table override code Lv Zheng
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: Lv Zheng @ 2016-03-02  6:16 UTC (permalink / raw)
  To: Rafael J. Wysocki, Rafael J. Wysocki, Len Brown
  Cc: Lv Zheng, Lv Zheng, linux-kernel, linux-acpi

This patchset improves initrd override mechanism.

Lv Zheng (2):
  ACPI / OSL: Cleanup initrd table override code
  ACPI / OSL: Add support to install tables via initrd

 drivers/acpi/internal.h |    1 +
 drivers/acpi/osl.c      |  158 +++++++++++++++++++++++++++++------------------
 drivers/acpi/tables.c   |    2 +
 3 files changed, 101 insertions(+), 60 deletions(-)

-- 
1.7.10

^ permalink raw reply	[flat|nested] 4+ messages in thread

* [PATCH 1/2] ACPI / OSL: Cleanup initrd table override code
  2016-03-02  6:16 [PATCH 0/2] ACPI / OSL: Improve initrd override mechanism Lv Zheng
@ 2016-03-02  6:16 ` Lv Zheng
  2016-03-02  6:16 ` [PATCH 2/2] ACPI / OSL: Add support to install tables via initrd Lv Zheng
  2016-03-10 23:44 ` [PATCH 0/2] ACPI / OSL: Improve initrd override mechanism Rafael J. Wysocki
  2 siblings, 0 replies; 4+ messages in thread
From: Lv Zheng @ 2016-03-02  6:16 UTC (permalink / raw)
  To: Rafael J. Wysocki, Rafael J. Wysocki, Len Brown
  Cc: Lv Zheng, Lv Zheng, linux-kernel, linux-acpi

This patch cleans up initrd table override code, merging redundant logics
and re-ordering code blocks. No functional changes.

Signed-off-by: Lv Zheng <lv.zheng@intel.com>
---
 drivers/acpi/osl.c |  114 ++++++++++++++++++++++++----------------------------
 1 file changed, 52 insertions(+), 62 deletions(-)

diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c
index 67da6fb..a8c417c 100644
--- a/drivers/acpi/osl.c
+++ b/drivers/acpi/osl.c
@@ -602,6 +602,14 @@ acpi_os_predefined_override(const struct acpi_predefined_names *init_val,
 	return AE_OK;
 }
 
+static void acpi_table_taint(struct acpi_table_header *table)
+{
+	pr_warn(PREFIX
+		"Override [%4.4s-%8.8s], this is unsafe: tainting kernel\n",
+		table->signature, table->oem_table_id);
+	add_taint(TAINT_OVERRIDDEN_ACPI_TABLE, LOCKDEP_NOW_UNRELIABLE);
+}
+
 #ifdef CONFIG_ACPI_INITRD_TABLE_OVERRIDE
 #include <linux/earlycpio.h>
 #include <linux/memblock.h>
@@ -746,96 +754,78 @@ void __init acpi_initrd_override(void *data, size_t size)
 		}
 	}
 }
-#endif /* CONFIG_ACPI_INITRD_TABLE_OVERRIDE */
-
-static void acpi_table_taint(struct acpi_table_header *table)
-{
-	pr_warn(PREFIX
-		"Override [%4.4s-%8.8s], this is unsafe: tainting kernel\n",
-		table->signature, table->oem_table_id);
-	add_taint(TAINT_OVERRIDDEN_ACPI_TABLE, LOCKDEP_NOW_UNRELIABLE);
-}
-
-
-acpi_status
-acpi_os_table_override(struct acpi_table_header * existing_table,
-		       struct acpi_table_header ** new_table)
-{
-	if (!existing_table || !new_table)
-		return AE_BAD_PARAMETER;
-
-	*new_table = NULL;
-
-#ifdef CONFIG_ACPI_CUSTOM_DSDT
-	if (strncmp(existing_table->signature, "DSDT", 4) == 0)
-		*new_table = (struct acpi_table_header *)AmlCode;
-#endif
-	if (*new_table != NULL)
-		acpi_table_taint(existing_table);
-	return AE_OK;
-}
 
 acpi_status
 acpi_os_physical_table_override(struct acpi_table_header *existing_table,
-				acpi_physical_address *address,
-				u32 *table_length)
+				acpi_physical_address *address, u32 *length)
 {
-#ifndef CONFIG_ACPI_INITRD_TABLE_OVERRIDE
-	*table_length = 0;
-	*address = 0;
-	return AE_OK;
-#else
 	int table_offset = 0;
 	struct acpi_table_header *table;
+	u32 table_length;
 
-	*table_length = 0;
+	*length = 0;
 	*address = 0;
-
 	if (!acpi_tables_addr)
 		return AE_OK;
 
-	do {
-		if (table_offset + ACPI_HEADER_SIZE > all_tables_size) {
-			WARN_ON(1);
-			return AE_OK;
-		}
-
+	while (table_offset + ACPI_HEADER_SIZE <= all_tables_size) {
 		table = acpi_os_map_memory(acpi_tables_addr + table_offset,
 					   ACPI_HEADER_SIZE);
-
 		if (table_offset + table->length > all_tables_size) {
 			acpi_os_unmap_memory(table, ACPI_HEADER_SIZE);
 			WARN_ON(1);
 			return AE_OK;
 		}
 
-		table_offset += table->length;
+		table_length = table->length;
 
-		if (memcmp(existing_table->signature, table->signature, 4)) {
-			acpi_os_unmap_memory(table,
-				     ACPI_HEADER_SIZE);
-			continue;
-		}
-
-		/* Only override tables with matching oem id */
-		if (memcmp(table->oem_table_id, existing_table->oem_table_id,
+		/* Only override tables matched */
+		if (memcmp(existing_table->signature, table->signature, 4) ||
+		    memcmp(table->oem_table_id, existing_table->oem_table_id,
 			   ACPI_OEM_TABLE_ID_SIZE)) {
-			acpi_os_unmap_memory(table,
-				     ACPI_HEADER_SIZE);
-			continue;
+			acpi_os_unmap_memory(table, ACPI_HEADER_SIZE);
+			goto next_table;
 		}
 
-		table_offset -= table->length;
-		*table_length = table->length;
-		acpi_os_unmap_memory(table, ACPI_HEADER_SIZE);
+		*length = table_length;
 		*address = acpi_tables_addr + table_offset;
+		acpi_table_taint(existing_table);
+		acpi_os_unmap_memory(table, ACPI_HEADER_SIZE);
 		break;
-	} while (table_offset + ACPI_HEADER_SIZE < all_tables_size);
 
-	if (*address != 0)
-		acpi_table_taint(existing_table);
+next_table:
+		table_offset += table_length;
+	}
 	return AE_OK;
+}
+#else
+acpi_status
+acpi_os_physical_table_override(struct acpi_table_header *existing_table,
+				acpi_physical_address *address,
+				u32 *table_length)
+{
+	*table_length = 0;
+	*address = 0;
+	return AE_OK;
+}
+#endif /* CONFIG_ACPI_INITRD_TABLE_OVERRIDE */
+
+acpi_status
+acpi_os_table_override(struct acpi_table_header *existing_table,
+		       struct acpi_table_header **new_table)
+{
+	if (!existing_table || !new_table)
+		return AE_BAD_PARAMETER;
+
+	*new_table = NULL;
+
+#ifdef CONFIG_ACPI_CUSTOM_DSDT
+	if (strncmp(existing_table->signature, "DSDT", 4) == 0)
+		*new_table = (struct acpi_table_header *)AmlCode;
 #endif
+	if (*new_table != NULL)
+		acpi_table_taint(existing_table);
+	return AE_OK;
 }
 
 static irqreturn_t acpi_irq(int irq, void *dev_id)
-- 
1.7.10

^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [PATCH 2/2] ACPI / OSL: Add support to install tables via initrd
  2016-03-02  6:16 [PATCH 0/2] ACPI / OSL: Improve initrd override mechanism Lv Zheng
  2016-03-02  6:16 ` [PATCH 1/2] ACPI / OSL: Cleanup initrd table override code Lv Zheng
@ 2016-03-02  6:16 ` Lv Zheng
  2016-03-10 23:44 ` [PATCH 0/2] ACPI / OSL: Improve initrd override mechanism Rafael J. Wysocki
  2 siblings, 0 replies; 4+ messages in thread
From: Lv Zheng @ 2016-03-02  6:16 UTC (permalink / raw)
  To: Rafael J. Wysocki, Rafael J. Wysocki, Len Brown
  Cc: Lv Zheng, Lv Zheng, linux-kernel, linux-acpi

This patch adds support to install tables from initrd.

If a table in the initrd wasn't used by the override mechanism, the table
would be installed after initializing all RSDT/XSDT tables.

Reference: https://lkml.org/lkml/2014/2/28/368
Reported-by: Thomas Renninger <trenn@suse.de>
Signed-off-by: Lv Zheng <lv.zheng@intel.com>
---
 drivers/acpi/internal.h |    1 +
 drivers/acpi/osl.c      |   50 ++++++++++++++++++++++++++++++++++++++++++++++-
 drivers/acpi/tables.c   |    2 ++
 3 files changed, 52 insertions(+), 1 deletion(-)

diff --git a/drivers/acpi/internal.h b/drivers/acpi/internal.h
index 9860df0..a37508e 100644
--- a/drivers/acpi/internal.h
+++ b/drivers/acpi/internal.h
@@ -20,6 +20,7 @@
 
 #define PREFIX "ACPI: "
 
+void acpi_initrd_initialize_tables(void);
 acpi_status acpi_os_initialize1(void);
 void init_acpi_device_notify(void);
 int acpi_scan_init(void);
diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c
index a8c417c..814d5f8 100644
--- a/drivers/acpi/osl.c
+++ b/drivers/acpi/osl.c
@@ -644,6 +644,7 @@ static const char * const table_sigs[] = {
 
 #define ACPI_OVERRIDE_TABLES 64
 static struct cpio_data __initdata acpi_initrd_files[ACPI_OVERRIDE_TABLES];
+static DECLARE_BITMAP(acpi_initrd_installed, ACPI_OVERRIDE_TABLES);
 
 #define MAP_CHUNK_SIZE   (NR_FIX_BTMAPS << PAGE_SHIFT)
 
@@ -760,6 +761,7 @@ acpi_os_physical_table_override(struct acpi_table_header *existing_table,
 				acpi_physical_address *address, u32 *length)
 {
 	int table_offset = 0;
+	int table_index = 0;
 	struct acpi_table_header *table;
 	u32 table_length;
 
@@ -780,7 +782,8 @@ acpi_os_physical_table_override(struct acpi_table_header *existing_table,
 		table_length = table->length;
 
 		/* Only override tables matched */
-		if (memcmp(existing_table->signature, table->signature, 4) ||
+		if (test_bit(table_index, acpi_initrd_installed) ||
+		    memcmp(existing_table->signature, table->signature, 4) ||
 		    memcmp(table->oem_table_id, existing_table->oem_table_id,
 			   ACPI_OEM_TABLE_ID_SIZE)) {
 			acpi_os_unmap_memory(table, ACPI_HEADER_SIZE);
@@ -791,13 +794,54 @@ acpi_os_physical_table_override(struct acpi_table_header *existing_table,
 		*address = acpi_tables_addr + table_offset;
 		acpi_table_taint(existing_table);
 		acpi_os_unmap_memory(table, ACPI_HEADER_SIZE);
+		set_bit(table_index, acpi_initrd_installed);
 		break;
 
 next_table:
 		table_offset += table_length;
+		table_index++;
 	}
 	return AE_OK;
 }
+
+void __init acpi_initrd_initialize_tables(void)
+{
+	int table_offset = 0;
+	int table_index = 0;
+	u32 table_length;
+	struct acpi_table_header *table;
+
+	if (!acpi_tables_addr)
+		return;
+
+	while (table_offset + ACPI_HEADER_SIZE <= all_tables_size) {
+		table = acpi_os_map_memory(acpi_tables_addr + table_offset,
+					   ACPI_HEADER_SIZE);
+		if (table_offset + table->length > all_tables_size) {
+			acpi_os_unmap_memory(table, ACPI_HEADER_SIZE);
+			WARN_ON(1);
+			return;
+		}
+
+		table_length = table->length;
+
+		/* Skip RSDT/XSDT which should only be used for override */
+		if (test_bit(table_index, acpi_initrd_installed) ||
+		    ACPI_COMPARE_NAME(table->signature, ACPI_SIG_RSDT) ||
+		    ACPI_COMPARE_NAME(table->signature, ACPI_SIG_XSDT)) {
+			acpi_os_unmap_memory(table, ACPI_HEADER_SIZE);
+			goto next_table;
+		}
+
+		acpi_table_taint(table);
+		acpi_os_unmap_memory(table, ACPI_HEADER_SIZE);
+		acpi_install_table(acpi_tables_addr + table_offset, TRUE);
+		set_bit(table_index, acpi_initrd_installed);
+next_table:
+		table_offset += table_length;
+		table_index++;
+	}
+}
 #else
 acpi_status
 acpi_os_physical_table_override(struct acpi_table_header *existing_table,
@@ -808,6 +852,10 @@ acpi_os_physical_table_override(struct acpi_table_header *existing_table,
 	*address = 0;
 	return AE_OK;
 }
+
+void __init acpi_initrd_initialize_tables(void)
+{
+}
 #endif /* CONFIG_ACPI_INITRD_TABLE_OVERRIDE */
 
 acpi_status
diff --git a/drivers/acpi/tables.c b/drivers/acpi/tables.c
index ebdf564..f49c024 100644
--- a/drivers/acpi/tables.c
+++ b/drivers/acpi/tables.c
@@ -32,6 +32,7 @@
 #include <linux/errno.h>
 #include <linux/acpi.h>
 #include <linux/bootmem.h>
+#include "internal.h"
 
 #define ACPI_MAX_TABLES		128
 
@@ -456,6 +457,7 @@ int __init acpi_table_init(void)
 	status = acpi_initialize_tables(initial_tables, ACPI_MAX_TABLES, 0);
 	if (ACPI_FAILURE(status))
 		return -EINVAL;
+	acpi_initrd_initialize_tables();
 
 	check_multiple_madt();
 	return 0;
-- 
1.7.10

^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [PATCH 0/2] ACPI / OSL: Improve initrd override mechanism
  2016-03-02  6:16 [PATCH 0/2] ACPI / OSL: Improve initrd override mechanism Lv Zheng
  2016-03-02  6:16 ` [PATCH 1/2] ACPI / OSL: Cleanup initrd table override code Lv Zheng
  2016-03-02  6:16 ` [PATCH 2/2] ACPI / OSL: Add support to install tables via initrd Lv Zheng
@ 2016-03-10 23:44 ` Rafael J. Wysocki
  2 siblings, 0 replies; 4+ messages in thread
From: Rafael J. Wysocki @ 2016-03-10 23:44 UTC (permalink / raw)
  To: Lv Zheng; +Cc: Rafael J. Wysocki, Len Brown, Lv Zheng, linux-kernel, linux-acpi

On Wednesday, March 02, 2016 02:16:02 PM Lv Zheng wrote:
> This patchset improves initrd override mechanism.
> 
> Lv Zheng (2):
>   ACPI / OSL: Cleanup initrd table override code
>   ACPI / OSL: Add support to install tables via initrd
> 
>  drivers/acpi/internal.h |    1 +
>  drivers/acpi/osl.c      |  158 +++++++++++++++++++++++++++++------------------
>  drivers/acpi/tables.c   |    2 +
>  3 files changed, 101 insertions(+), 60 deletions(-)

Both applied, thanks!

Rafael

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2016-03-10 23:42 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-03-02  6:16 [PATCH 0/2] ACPI / OSL: Improve initrd override mechanism Lv Zheng
2016-03-02  6:16 ` [PATCH 1/2] ACPI / OSL: Cleanup initrd table override code Lv Zheng
2016-03-02  6:16 ` [PATCH 2/2] ACPI / OSL: Add support to install tables via initrd Lv Zheng
2016-03-10 23:44 ` [PATCH 0/2] ACPI / OSL: Improve initrd override mechanism Rafael J. Wysocki

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).